Skip to content
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

fix: check for role changes in lists and list items #518

Closed

Conversation

AlmeroSteyn
Copy link

@AlmeroSteyn AlmeroSteyn commented Sep 10, 2017

Change function of dlitem, listitem, only-dlitems and only-listitems checks to take into account role changes to either parent elements or child list item elements. Previously changing the role of either elements did not trigger the correct symantic markup errors.

Closes #463

The following additions have been made to the current checks:

  1. Changing the role of the parent <ul> or <ol> will have the child <li> tags report that they are not part of a list.
  2. Changing the role of the parent <dl> will have the child <dd> or <dt> tags report that they are not part of a list.
  3. Changing the role of a <li> tag will mean that it will get ignored by the check if the list contains any other valid content.
  4. Filling a list with ONLY <li> tags with a different role will trigger an invalid content error.

change function of dlitem, listitem, only-dlitems and only-listitems checks to take into account role changes to either parent elements or child list item elements. Previously changing the role of either elements did not trigger the correct symantic markup errors.

closes dequelabs#463
@CLAassistant
Copy link

CLAassistant commented Sep 10, 2017

CLA assistant check
All committers have signed the CLA.

@@ -1,2 +1,3 @@
var parent = axe.commons.dom.getComposedParent(node);
return parent.nodeName.toUpperCase() === 'DL';
return parent.nodeName.toUpperCase() === 'DL' && !parent.getAttribute('role');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this allow <dl role="list">?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which would say it's okay to overload a <dl> with an ARIA role. Is that something we want to encourage? Wouldn't that also depend on the child items having role="listitem"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

var isListRole = parentRole === 'list';

return (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't follow our spacing convention. It's also a little hard to read. Can you reformat?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WilcoFiers which spacing convention are you referring to?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

bad.push(actualNode);

if (actualNode.nodeType === 1 && permitted.indexOf(nodeName) === -1) {
var role = (actualNode.getAttribute('role') || '').toLowerCase();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should allow role=definition and role=term, possibly also role=list?

if (actualNode.nodeType === 1 && permitted.indexOf(nodeName) === -1) {
var role = (actualNode.getAttribute('role') || '').toLowerCase();
isListItemRole = role === 'listitem' || (nodeName === 'LI' && !role);
hasListItem = hasListItem || (nodeName === 'LI' && isListItemRole) || isListItemRole;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs either a comment, or it needs to be cleared up a bit, because it's not immediately obvious what the if statements in this block do.

@@ -21,6 +21,12 @@ describe('dlitem', function () {
assert.isFalse(checks.dlitem.evaluate.apply(null, checkArgs));
});

it('should fail if the dlitem has a parent <dl> with a changed role', function(){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be "should fail if the dt element has a parent

with a changed role"

it('should return false if <meta> is used along side dt', function () {
var checkArgs = checkSetup('<dl id="target"><meta name="description" content=""><dt>A list</dt></dl>');

assert.isFalse(checks['only-dlitems'].evaluate.apply(checkContext, checkArgs));
});

it('should return true if <meta> is used along side dt with its role changed', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test seems unnecessary, and so do the new tests below this one.

});

it('should return false if the list has at least one li while others have their roles changed', function () {
var checkArgs = checkSetup('<ol id="target"><li >A list item</li><li role="menuitem">Not a list item</li></ol>');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dylanb I remember you suggesting this should be a violation? My initial thought about these was that there might be roles we should allow. separator for instance would be one I think is very reasonable. Menuitem itself would fail here because it isn't owned by a menu, so that's its own error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this example does not represent a violation IMO

it('should return false if <meta> is used along side li', function () {
var checkArgs = checkSetup('<ol id="target"><meta name="description" content=""><li>A list</li></ol>');

assert.isFalse(checks['only-listitems'].evaluate.apply(checkContext, checkArgs));
});

it('should return true if <meta> is used along side only li items with their roles changed', function () {
var checkArgs = checkSetup('<ol id="target"><meta name="description" content=""><li role="menuitem">Not a list item</li></ol>');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one doesn't seem useful, and neither do tests added below this one.

@@ -60,43 +66,97 @@ describe('only-listitems', function () {
assert.isFalse(checks['only-listitems'].evaluate.apply(checkContext, checkArgs));
});

it('should return false if the list has only an element with role listitem', function () {
var checkArgs = checkSetup('<ol id="target"><div role="listitem">A list</div></ol>');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add tests for multiple listitem elms, and for mixing li and listitem.

@marcysutton
Copy link
Contributor

Hi @AlmeroSteyn, just checking in to see if you plan to address Wilco's feedback on this PR? We'd love to get this updated and merged.

@WilcoFiers
Copy link
Contributor

@marcysutton I heard from Almero that he wasn't. We need to sort this one out ourselves.

@WilcoFiers WilcoFiers added the help wanted We welcome PRs or discussions for issues marked as help wanted label Dec 9, 2017
if (actualNode.nodeType === 1 && permitted.indexOf(nodeName) === -1) {
var role = (actualNode.getAttribute('role') || '').toLowerCase();
isListItemRole = role === 'listitem' || (nodeName === 'LI' && !role);
hasListItem = hasListItem || (nodeName === 'LI' && isListItemRole) || isListItemRole;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also seems a little redundant:
hasListItem = hasListItem || (nodeName === 'LI' && isListItemRole) || isListItemRole;
The code checks the nodeName for 'LI' and a role more than once, and then checks against itself again a few times. I wonder if we can simplify.

@jeeyyy
Copy link
Contributor

jeeyyy commented Jun 8, 2018

@AlmeroSteyn - cheers for the work.
I have circled up all comments on here and re-worked it in to this PR - #949

Hence closing it.

@jeeyyy jeeyyy closed this Jun 8, 2018
WilcoFiers pushed a commit that referenced this pull request Jul 18, 2018
This rule updates list(items) to cater to role changes to either parent or child list elements.

This rule is a taken over PR from the community contribution (PR: #518 @AlmeroSteyn - thanks for the initial work).

Closes issue:
- #463

## Reviewer checks

**Required fields, to be filled out by PR reviewer(s)**
- [x] Follows the commit message policy, appropriate for next version
- [x] Has documentation updated, a DU ticket, or requires no documentation change
- [x] Includes new tests, or was unnecessary
- [x] Code is reviewed for security by: @WilcoFiers
mrtnvh pushed a commit to mrtnvh/axe-core that referenced this pull request Nov 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted We welcome PRs or discussions for issues marked as help wanted
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants