-
Notifications
You must be signed in to change notification settings - Fork 914
Add HTML rule and hint+fix for missing alt attribute for tag img, applet and area #4485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
I also thought to not hardcode the supported tags, but to use the validator rule for this, but this was to much for me. If this is wanted I can try to add this too, so this will be a bit more generic if other HTML tags are coming with the same validator rule. |
...beans/modules/html/editor/hints/other/AddMissingAltAttribute/AddMissingAltAttributeHint.java
Outdated
Show resolved
Hide resolved
|
Now I removed the rule and hint from the HintsProvider and add it to the layer.xml. The new rule extends now HtmlRule and runs the Hint by itself. |
14399b1 to
db09843
Compare
|
Do I need to worry about the failing travis stuff? A quick look seems not related to my stuff anyway. |
I just restarted them. Looks good so far. You don't have a restart button? |
matthiasblaesing
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ide/html.editor/src/org/netbeans/modules/html/editor/hints/HtmlHintsProvider.java
Outdated
Show resolved
Hide resolved
|
|
||
| if (project == null) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx for the hint, yeah I didn't test an HTML file w/o having a project :).
|
|
||
| if (file == null) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the file checked - it is not used.
I had, but I didn't want to create some noice. But next time, I will try this first :). Thx for the info. |
Thx @matthiasblaesing you are right and I already tried a bit but the offset and searching logic for tokens (Tag open, tag open symbol, tag closing, etc.) drives me crazy. Will try to fix this. |
|
@matthiasblaesing after long thinking about this again I would disagree with the consistency. The warning/error/hint is really just for the tag img. In my little example you can see that the img tag is highlighted when a div is surrounded. So the hint shows it exactly for
I really don't want to have the fix inside the div which is correct on this position. So the fix should be really inside of the img tag not anywhere else. Maybe the problem here is that the hint on the sidebar has an other expectation for the user. Here are some other things:
So all in all, I think how NetBeans treats and shows warnings, is not optimal but this is not what I want to fix here. I also changed from warning to suggestion on current line, but the problem here is the highlight disappears too and the "suggestion" is just seen in the statusbar BUT it just appears also on the img, not on the whitespace tokens before the tag_open_symbol. Hope that explains a bit more. I will just fix also a multi line img which makes sense to have the fix there too but not for the whole line. This will be a hole new topic IMHO. |
|
@Chris2011 something went wrong here. There is a massive set of changes where and you have conflict with master. This needs to be redone. |
|
@matthiasblaesing thx for the info, will have a look soon. |
7065b3e to
db09843
Compare
|
@matthiasblaesing I think I got it now :). I did the pull and rebase from within NetBeans and it had some conflicts, that I thought I fixed them but unfortunately not correct, sry for that. I reset everything to my last commit. So now we can focus again on the initial task and my thoughts to it. |
matthiasblaesing
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a second pass over the changes. Please recheck the inline comments.
|
|
||
| /** | ||
| * | ||
| * @author Chris |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to either replace this with something more distinctive (there are multiple instances of Chris) or remove it (history holds the full author information).
| } | ||
|
|
||
| //the joined ts is moved to the from offset and a token already selected (moveNext/Previous() == true) | ||
| //seek for all tag's attributes with css embedding representing an inlined style |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this comment looks as if it does not match.
| } | ||
|
|
||
| //the joined ts is moved to the from offset and a token already selected (moveNext/Previous() == true) | ||
| //seek for all tag's attributes with css embedding representing an inlined style |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks to complex to find the alt Attribute. The variables here indicate extraction of class, alt, id - is this copied from somewhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, also as you can see the comments, it was copied from the method findInlineStyle of class ExtractInlinedStyleRule. I started to copy stuff around, test some stuff and didn't fix code that much what was already there. Sry for that. I just wanted to get it working first. I will try to find anouther solution maybe with that what I already used for the HtmlCompletionProvider LexerUtils.followsToken(....
| * | ||
| * @author Chris | ||
| */ | ||
| @NbBundle.Messages("AddMissingAltAttributeRuleName=Insert required 'alt' attribute") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message key should be AddMissingAltAttributeRule - you can then drop the implementation of getDisplayName as the superclass already implements it:
netbeans/ide/html.editor/src/org/netbeans/modules/html/editor/hints/HtmlRule.java
Lines 86 to 89 in a8edf3b
| @Override | |
| public String getDisplayName() { | |
| return NbBundle.getMessage(HtmlRule.class, getId()); | |
| } |
with
netbeans/ide/html.editor/src/org/netbeans/modules/html/editor/hints/HtmlRule.java
Lines 60 to 63 in a8edf3b
| @Override | |
| public String getId() { | |
| return getClass().getSimpleName(); | |
| } |
You also need to define a message named AddMissingAltAttributeRule_Desc (you get an exception when you click on the hint in the option panel):
netbeans/ide/html.editor/src/org/netbeans/modules/html/editor/hints/HtmlRule.java
Lines 65 to 68 in a8edf3b
| @Override | |
| public String getDescription() { | |
| return NbBundle.getMessage(HtmlRule.class, String.format("%s_Desc", getId())); | |
| } |
I suggest to use : Provide Text Alternatives for the display name (to get it more in line with the rest of the entries) and Find img/applet/area elements where no alt attribute is provided. (for the description)
This can be ignored, as there are two hints/rules active here:
When I deactivate the corresponding "All Other" category, I get the desired behavior, so is ok. |
|
@matthiasblaesing thx for your comments, will fix them :) |
|
@Chris2011 NB18 is coming nearer. Shall this stay on the NB18 milestone, then an update would be good now (branch happens in 8 days) or moving to NB 19 should be considered. |
ide/html.editor/src/org/netbeans/modules/html/editor/utils/HtmlTagContextUtils.java
Outdated
Show resolved
Hide resolved
We should remove the label completely. I have one bug there when it is a warning instead of a suggestion and I need to figure that out first. I had a look into my other PRs and I wanted to focus on another one first. Step by step. @matthiasblaesing thx for catching this up again :) |
...html.editor/src/org/netbeans/modules/html/editor/hints/other/AddMissingAltAttributeHint.java
Outdated
Show resolved
Hide resolved
ide/html.editor/src/org/netbeans/modules/html/editor/hints/other/AltAttributeVisitor.java
Outdated
Show resolved
Hide resolved
ide/html.editor/src/org/netbeans/modules/html/editor/hints/other/AltAttributeVisitor.java
Outdated
Show resolved
Hide resolved
ide/html.editor/src/org/netbeans/modules/html/editor/hints/other/AltAttributeVisitor.java
Outdated
Show resolved
Hide resolved
ide/html.editor/src/org/netbeans/modules/html/editor/hints/other/AltAttributeVisitor.java
Outdated
Show resolved
Hide resolved
ide/html.editor/src/org/netbeans/modules/html/editor/utils/HtmlTagContextUtils.java
Outdated
Show resolved
Hide resolved
ide/html.editor/src/org/netbeans/modules/html/editor/utils/HtmlTagContextUtils.java
Show resolved
Hide resolved
|
Please write an example code to verify this in the description. Please add unit tests. ( |
Thx, I was searching for this. Will check it out. |
|
Tests still missing, I'm on it. Thx for all the information. |
|
|
||
| source.getDocument(false).insertString(adjustContextRange.getEnd(), " alt=\"\"", null); // NOI18N | ||
| } catch (BadLocationException ex) { | ||
| LOGGER.log(Level.SEVERE, ex.getMessage()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| LOGGER.log(Level.SEVERE, ex.getMessage()); | |
| LOGGER.log(Level.WARNING, "Invalid offset: {0}", ex.offsetRequested()); // NOI18N |
| */ | ||
| public class AddMissingAltAttributeRule extends HtmlRule { | ||
|
|
||
| public static AddMissingAltAttributeRule SINGLETON = new AddMissingAltAttributeRule(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| public static AddMissingAltAttributeRule SINGLETON = new AddMissingAltAttributeRule(); | |
| private static AddMissingAltAttributeRule INSTANCE = new AddMissingAltAttributeRule(); | |
| private AddMissingAltAttributeRule() { | |
| } | |
| public static AddMissingAltAttributeRule getInstance() { | |
| return INSTANCE; | |
| } |
BTW, Please note that we have to make it thread-safe if we make this class singleton.
| protected void run(HtmlRuleContext context, List<Hint> result) { | ||
| try { | ||
| HtmlParserResult parserResult = context.getHtmlParserResult(); | ||
| AltAttributeVisitor visitor = new AltAttributeVisitor(this, context, result, "img|applet|area"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// NOI18N
matthiasblaesing
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I missing something obvious here? The Rule/Hint is not registered anywhere and running a build under debugger and having a break point inside them, they are not hit. So I'm not sure what I should be seeing.
This:
Is generated in the html validator module, in the ProblemHandler:
With this change applied:
--- a/ide/html.editor/src/org/netbeans/modules/html/editor/resources/layer.xml
+++ b/ide/html.editor/src/org/netbeans/modules/html/editor/resources/layer.xml
@@ -534,6 +534,9 @@
<file name="org-netbeans-modules-html-editor-hints-NotValidatedContent.instance">
<attr name="position" intvalue="190"/>
</file>
+ <file name="org-netbeans-modules-html-editor-hints-other-AddMissingAltAttributeRule.instance">
+ <attr name="position" intvalue="200"/>
+ </file>
<!-- the following hint 'Other' must be last in the hints list!!! -->
<file name="org-netbeans-modules-html-editor-hints-Other.instance">
<attr name="position" intvalue="99999"/> I get two matches, one from the html validator, one from this new hint (with the fix):
With the full parser result available the visitor can be simplified to (range now includes "/>", but that can be accounted for), at least I'm missing an argument to redo the scanning the parser already did.
public class AltAttributeVisitor implements ElementVisitor {
private static final String ALT_ATTR = "alt"; // NOI18N
private final HtmlRuleContext context;
private final List<Hint> hints;
public AltAttributeVisitor(Rule rule, HtmlRuleContext context, List<Hint> hints) throws IOException {
this.context = context;
this.hints = hints;
}
@Override
public void visit(Element node) {
// We should only be invoked for opening tags
if(! (node instanceof OpenTag)) {
return;
}
// We are only interested in img, area, applet elements
String lowerCaseTag = node.id().toString().toLowerCase();
if(! (lowerCaseTag.equals("img") || lowerCaseTag.equals("area") || lowerCaseTag.equals("applet"))) {
return;
}
OpenTag ot = (OpenTag) node;
if(ot.getAttribute(ALT_ATTR) == null) {
hints.add(new AddMissingAltAttributeHint(context, new OffsetRange(node.from(), node.to())));
}
}
}I also notice, that the fix should check, if new whitespace needs to be inserted. If you have this case <img src="..." /> this fix will change it to <img src="..." alt=""/> (there are now two spaces)
|
Thx for your review @matthiasblaesing. Yes I already encountered the missing xml part but this was done by a merge because I already had it. I didn't have a merge conflict but it was removed accidentally. And indeed this is why we need tests for this. So I changed this now back to draft, because I already created the first test but it is still red due to not triggering the warning/suggestion handled as a error. After this I will change this back to normal. Also I will have a look into the part that you wrote with the visit method change and the new added empty space. Thx. |
…alt-attribute-hint-fix
…alt-attribute-hint-fix
…ests area failing
…alt-attribute-hint-fix
|
It is still in draft mode but can please someone have a look into my test impl? @junichi11 or @matthiasblaesing. For checkHints I needed to make a change in the CslTestBase but I'm not 100% sure whether I needed to do this or not. w/o my change the problem was that the hint was never triggered due to not writing the correct property for hints/suggestions (L4387: https://github.com/apache/netbeans/pull/4485/files#diff-afbe604d62e2e9bec89e4ed0e712ad047106ed77e63c2c4030e76a54d762941fR4387). For the applyHint test, I also needed to change code within the CslTestBase in the method findApplicableFix (L4624: https://github.com/apache/netbeans/pull/4485/files#diff-afbe604d62e2e9bec89e4ed0e712ad047106ed77e63c2c4030e76a54d762941fR4624) from text == null to text != null. I'm also not 100% sure but the code makes more sense for me now. Otherwise it will always return null which breaks the code in applyHint (assertNotNull(fix))- This test is also funny, often it fails with that the expectation of the result is not the correct one but when I debug 1min or so with F8 to jump over the code, etc. it says that the test is green and I don't know what's wrong here. I also added a check for Error and Warning which was missing, because if Current_line_warning is false it is not that the rest is always an error or an warning. computeHints maybe is missnamed here. It will just check for html version, nothing else. So all in all the code is often very frustrating to check and I needed days for debugging and yes it could be that I don't understand the code 100% that's why I'm asking for a bit of help please. Thanks all. |
|
Unfortunately I see that my changes break some PHP tests. Will dig into it again and would be happy to have someone that helps me break it down what I missed. |
|
My gut feeling is, that the HtmlHintsProvider and the expectations of the CslTestBase/GsfHintsManager don't match. It seems suggestions were never really supported. It might be worthy looking into JS/CSS whether there are suggestions being checked. I'm not sure, that modifying CslTestBase is really a good idea. General comments:
|
Hey @matthiasblaesing thx for your info and hint. I'm definitely with you, I will check the JS stuff, because CSS has also no real hints/fixes (just basic stuff) as I have. I also thought that this was never tried before. Lemme check more what I can do. For the invokeLater, thx for the hint with the change, I got this from ExtractInlinedStyleHint but due to I not doing extrem things like opening a new UI, it is not needed here. I just add stuff into the editor. |
Revert change inside the CslTestBase for findApplicableFix
|
@matthiasblaesing so another research here:
Fazit: It seems PHP and maybe JS are better implemented in their *HintsProvider and I need to change the whole logik of the HtmlHintsProvider but JS also lacks of tests and suggestions are also not a big player for JS (not yet). Should this be part of this ticket? I guess not. I also think that we should make this somehow consistent for all CSL languages as good as possible. PHP uses Classes for like SuggestionRule, HintRule and ErrorRule, which just set the severity to the correct one and so on. I think I ran into a rabbithole and yes, it is not your business but the code is a big mess and I want to rework it and hope to not break more than before. Any other thoughts/suggestions/hints? :D |
| */ | ||
| package org.netbeans.modules.html.editor.hints.other; | ||
|
|
||
| import java.awt.EventQueue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary import
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
| import javax.swing.text.BadLocationException; | ||
| import javax.swing.text.Document; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary import
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean, they are unnecessary, when I change the logik, right? Because atm I need them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, those three are correct marked as not used, but your both other comments have different lines. That's why I'm asking. It was about the matcher, pattern, the exception, etc. That's why I was confused about it.
| import org.netbeans.modules.csl.api.OffsetRange; | ||
| import org.netbeans.modules.html.editor.hints.HtmlRuleContext; | ||
| import org.netbeans.modules.html.editor.utils.HtmlTagContextUtils; | ||
| import org.netbeans.modules.parsing.api.Source; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary import
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
| HtmlRuleContext context; | ||
| OffsetRange range; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can be private and final
| Matcher closingTagMatcher = closingTagPattern.matcher(tagContent); | ||
|
|
||
| if (closingTagMatcher.find()) { | ||
| int altInsertPosition = adjustedRange.getStart() + closingTagMatcher.start(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might lead to wrong results. Consider PHP with embedded HTML. The document could look like this:
<img src='demo.png' alt='<?php echo htmlspecialchars('x > y');?>' />I would use the HTML token stream and either use the start of the closing token or, if that does not exist, the start of the last HTML token + length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, I didn't try PHP yet, will do it too. Thx for the hint. If I guess it correct, your example will not trigger the hint, because you already have the alt attribute. But yes It would be better to take the HTML token instead of just looking for the closing tag symbol with an regex.
| provider.computeSuggestions(manager, context, hints, caretOffset); | ||
| } else if(HintsSettings.getSeverity(manager, ucr) == HintSeverity.ERROR || HintsSettings.getSeverity(manager, ucr) == HintSeverity.WARNING) { | ||
| manager.setTestingRules(null, testHints, testHints, null); | ||
| provider.computeErrors(manager, context, hints, new ArrayList<Error>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you test, that all current tests invoking computeHints, potentially transitively, still work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, not yet. I just thought that the pipes will show me the result and I just saw some failing tests of Latte. PHP where not triggert here at github inside my branch. I will just revert this change as you said and will try to implement a better logic into the HtmlHintsProvider as similiar as for PHP and JS.
…alt-attribute-hint-fix










This PR adds a new HTML Rule, Hint and HintFix for a missing "alt" attribute for following tags: img, applet, area.
I copied over some code from existing ExtractInlinedStyleRule and ExtractInlinedStyleHint and checked it, how it works. Fun fact, atm ExtractInlinedStyleHintFix is not working atm, it will throw an NPE, but this is not broken due to my changes. I will try to fix this later, in a seperate PR. Please have a look into the code. I will handle this as a draft and I will change some things like to add the rule/hint to the layers.xml instead of the HtmlHintsProvider as mentioned in the comment.
Also I changed a private method which gives you the exact offset of the tag
<tag></tag> or <img />problem here is that I need to add the attribute before the closing token and the adjustOffset gave me the offset after the closing tag so I added a bool to change this behaviour just for my and future needs. The rest is still working as before.I also wanted try to add tests for the hint, but there are atm no tests at all.
I also notied the extra space before my " alt=""" when it is a closing tag. I can also try to fix this to check for token WS but it is the same behaviour as for WebStorm. It is better than nothing IMHO.