-
Notifications
You must be signed in to change notification settings - Fork 791
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
feat: ARIA supported checks #1254
Conversation
Logic is duplicated in check
lib/checks/aria/unsupportedattr.js
Outdated
let unsupported; | ||
if (node.hasAttributes()) { | ||
unsupported = [].slice | ||
.call(node.attributes) |
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 could use `Array.from(node.attributes) to simplify this a bit.
lib/checks/aria/unsupportedattr.js
Outdated
.call(node.attributes) | ||
.filter(candidate => { | ||
// skip non-ARIA attributes | ||
if (/aria-/.test(candidate.name)) { |
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 probably don't need to do this if statement. Just rely on aria.validateAttr to sort that out for you. That way you also always return. It's a little nicer to read a filter if it always returns a boolean.
if (!attrDefinition || (flagUnsupported && isAttrUnsupported)) { | ||
return false; | ||
} | ||
return !!attrDefinition; |
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 function is a little difficult to read, with all the logic operations going on. This may be simpler:
const attrDefinition = aria.lookupTable.attributes[att];
if (flagUnsupported && attrDefinition) {
return !!attrDefinition.unsupported
}
return !!attrDefinition
@@ -10,177 +10,232 @@ var aria = (commons.aria = {}), | |||
lookupTable.attributes = { | |||
'aria-activedescendant': { | |||
type: 'idref', | |||
allowEmpty: true | |||
allowEmpty: true, | |||
unsupported: 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.
I know we did this for all the roles too, but do we really need to set these explicitly? I think that's the virtue of using unsupported
over supported
, you don't have to specify it to be falsey. I'd have a slight preference for only setting it if it's true.
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.
Leaving them off and using falsey values instead sounds fine to me!
allowEmpty: true, | ||
unsupported: false | ||
}, | ||
'aria-describedat': { |
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 is one of the attributes that was proposed for ARIA but never made it into the spec. Did you mean to add a non-standard attribute in here? I can see a use case for including attributes that were at one point proposed but never made it into the spec. We would have to be explicit about it though, and we'd have to put some sort of "unstandardised" flag on it. That's probably out of scope for 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.
I can leave it off, I only added it because it was mentioned in the aria-supported diff. But if we did include it, if someone tried to use it they'd see it was unsupported. I like the idea of an "unstandardized" flag in here.
let attrs = node.attributes; | ||
for (let i = 0, l = attrs.length; i < l; i++) { | ||
if (aria.test(attrs[i].name)) { | ||
return true; |
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.
We can simplify this quite a bit. There's also no reason for this hasAttributes thing. There is no performance benefit to using DOM has
methods. Only use them if you're not interested in the actual content of the attribute.
return Array.from(node.attributes)
.some(({ name }) => /^aria-/.test(name))
lib/rules/aria-allowed-attr.json
Outdated
@@ -7,6 +7,6 @@ | |||
"help": "Elements must only use allowed ARIA attributes" | |||
}, | |||
"all": [], | |||
"any": ["aria-allowed-attr"], | |||
"any": ["aria-allowed-attr", "aria-unsupported-attr"], |
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.
What's the reasoning behind adding this to aria-allowed-attr
instead of to aria-valid-attr
? I haven't quite figured out which place I think is best, so I'd like to know your reasoning for it.
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.
It's a really fine line. I went for "allowed" because technically these attributes are valid, but we're recommending they not be used because of support purposes. Both aria-allowed-attr
and aria-valid-attr
use the same commons method to validate, except aria-allowed-attr
has some more logic to check the role. The new unsupported check could go in either rule, really.
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 still believe that the correct rule for this behavior is aria-allowed-attr
rather than aria-valid-attr
, so we can get the correct messaging. I'm going to move forward with the change to the matches function so we can keep this rolling.
this.data(unsupported); | ||
return true; | ||
} | ||
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.
I'm not sure the logic works here. Shouldn't you return true
when this passes? I would also think that this needs to be in all
instead of any
in the rule. That decision may be why you used this strange logic.
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.
@WilcoFiers the aria-roles
unsupported stuff works on none
. I would actually think that should be the case here as well.
This is ready for another review. Test failure on CircleCI is unrelated:
|
@@ -40,7 +40,6 @@ describe('description', function() { | |||
shadow.innerHTML = '<video><slot></slot></video>'; | |||
|
|||
var checkArgs = checkSetup(node, {}, 'video'); | |||
axe.log(checkArgs); |
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 commit should have test
in the scope, and is unrelated to this PR. But it kept irritating me when running tests.
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.
Only small stuff left.
if (node.hasAttributes()) { | ||
let attrs = node.attributes; | ||
for (let i = 0, l = attrs.length; i < l; i++) { | ||
if (aria.test(attrs[i].name)) { |
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.
Sorry, should have noticed this in my first review. It seems like you're not filtering out elements with only invalid ARIA attributes:
<input aria-invalidattr="foo" />
This element shouldn't be applicable to this rule. It's a pretty minor bug, so I'll leave it for you to decide if you want to bother with it. The fix is to use axe.commons.aria.validateAttr
in the if statement here.
This branch adds a new check to report unsupported ARIA attributes to the user. We have to make a decision on how to modify the rule to support it, which you can find discussed in #918.
Closes issue: #918
Reviewer checks
Required fields, to be filled out by PR reviewer(s)