-
Notifications
You must be signed in to change notification settings - Fork 101
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
Check for missing alt attributes on img tags #70
Conversation
include LinterRegistry | ||
|
||
def visit_tag(node) | ||
if node.tag_name == 'img' && !node.has_hash_attribute?(:alt) |
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.
Are img
tags the only tags that are applicable here? That seems surprising.
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 technique is specifically related to img
tags (http://www.w3.org/TR/2014/NOTE-WCAG20-TECHS-20140916/H37). There are other requirements to meet the guideline I linked to in the PR, but this is an easy test that moves towards that goal. I can make the guideline name more specific, like ImgAltText
if that's more clear.
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.
The name is fine. I guess I was just expecting a list of different tags, so code more along the lines of:
TAGS_REQUIRING_ALT = %w[img ...]
...
if TAGS_REQUIRING_ALT.include?(node.tag_name) && ...
...
end
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.
@sds the only tag that explicitly requires the attribute is img
. area
tags require them when using an href
, and applet
tags don't need them if they have fallback content in the tag body.
Thanks for the pull request, @ckundo. I've left some feedback inline. Main concern is around the use of |
1466667
to
2f0e714
Compare
# @return [true,false] | ||
def has_hash_attribute?(attribute) | ||
hash_attributes? && | ||
hash_attributes_source.scan(/(#{attribute})\W/).any? |
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.
@sds the parser gem does not give access to the hash keys as nodes, so I went with a regex. I'll refine this matcher, but is it an ok direction from your standpoint?
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 don't think I understand what you mean by the parser
gem not giving access to hash keys as nodes. If you look at the implementation at https://github.com/causes/haml-lint/blob/master/lib/haml_lint/linter/class_attribute_with_static_value.rb#L43 you can see we're checking to see if a key is a string or symbol.
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.
Yep, you're right I misunderstood. I've updated the commit.
2f0e714
to
ed0bdec
Compare
- Introduces a new method to check if an attribute exists in a tag nodes hash attributes - Required for followup commit to check for missing alt attributes [sds#69]
- alternative text is required for non text content - http://www.w3.org/TR/2008/REC-WCAG20-20081211/#text-equiv-all [sds#69]
ed0bdec
to
e22d5a3
Compare
private | ||
|
||
def parsed_attributes | ||
HamlLint::RubyParser.new.parse(hash_attributes_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.
Seems like there can be some additional modeling/extraction done around the parser, but I wasn't sure how far to take it. Open to suggestions.
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 is a parse_ruby
helper defined on the Linter
class which you can use instead.
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.
@sds saw that, though it's a private method. I can promote it to public.
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.
also, the parse_ruby
method is an instance method on Linter
. Should I create a corresponding class method? It seems like adding code to the Linter
class for the sake of TagNode
is a smell. Should they be interacting in that way? What about putting that helper in a module?
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.
Ah, I forgot we were in the TagNode
. Sounds like we should define a parse_ruby
helper on the Node
class, since I see this being something more heavily used in node helpers going forward.
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.
How about a module/mixin? That would avoid code duplication.
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.
Yup, that works.
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.
Hi @sds, I spiked on creating a mixin but it felt a little forced. It's less code to reuse the class here, and it's easier to test the parser object as a class vs module.
What do you think about keeping this line as is? I think that's the only thing blocking this PR.
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.
Here's the spike I was talking about. Do you think this a better approach? ckundo@f74eaf6
This introduces a check that aligns with the W3C WCAG 2.0 guideline 1.1.1, which states:
http://www.w3.org/TR/2008/REC-WCAG20-20081211/#text-equiv-all
[closes #69]