From 4bd3ab16f5ffbfa573a4f0d065b50e014807319a Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 6 May 2019 12:32:34 -0500 Subject: [PATCH 1/3] feat(rule): add additional elements to check for incomplete with required children --- lib/checks/aria/required-children.js | 22 +++++++++++++------ lib/checks/aria/required-children.json | 13 ++++++++++- lib/commons/aria/index.js | 12 +++++++--- .../aria-required-children.html | 19 ++++++++++++---- .../aria-required-children.json | 15 +++++++++++-- 5 files changed, 64 insertions(+), 17 deletions(-) diff --git a/lib/checks/aria/required-children.js b/lib/checks/aria/required-children.js index 0ae3aada6a..afbf76f822 100644 --- a/lib/checks/aria/required-children.js +++ b/lib/checks/aria/required-children.js @@ -39,20 +39,23 @@ function ariaOwns(nodes, role) { } function missingRequiredChildren(node, childRoles, all, role) { - var i, - l = childRoles.length, + var index, + length = childRoles.length, missing = [], ownedElements = idrefs(node, 'aria-owns'); - for (i = 0; i < l; i++) { - var r = childRoles[i]; - if (owns(node, virtualNode, r) || ariaOwns(ownedElements, r)) { + for (index = 0; index < length; index++) { + var childRole = childRoles[index]; + if ( + owns(node, virtualNode, childRole) || + ariaOwns(ownedElements, childRole) + ) { if (!all) { return null; } } else { if (all) { - missing.push(r); + missing.push(childRole); } } } @@ -109,7 +112,12 @@ if (!missing) { this.data(missing); -if (reviewEmpty.includes(role)) { +// Only review empty nodes when a node is both empty and does not have an aria-owns relationship +if ( + reviewEmpty.includes(role) && + node.children.length === 0 && + idrefs(node, 'aria-owns').length === 0 +) { return undefined; } else { return false; diff --git a/lib/checks/aria/required-children.json b/lib/checks/aria/required-children.json index 4ad80cdf12..6f4fd8a8fa 100644 --- a/lib/checks/aria/required-children.json +++ b/lib/checks/aria/required-children.json @@ -2,7 +2,18 @@ "id": "aria-required-children", "evaluate": "required-children.js", "options": { - "reviewEmpty": ["listbox"] + "reviewEmpty": [ + "doc-bibliography", + "doc-endnotes", + "grid", + "list", + "listbox", + "table", + "tablist", + "tree", + "treegrid", + "rowgroup" + ] }, "metadata": { "impact": "critical", diff --git a/lib/commons/aria/index.js b/lib/commons/aria/index.js index ab3fa350b2..f97e4829ac 100644 --- a/lib/commons/aria/index.js +++ b/lib/commons/aria/index.js @@ -624,7 +624,9 @@ lookupTable.role = { attributes: { allowed: ['aria-expanded', 'aria-errormessage'] }, - owned: null, + owned: { + one: ['doc-biblioentry'] + }, nameFrom: ['author'], context: null, unsupported: false, @@ -746,7 +748,9 @@ lookupTable.role = { attributes: { allowed: ['aria-expanded', 'aria-errormessage'] }, - owned: ['doc-endnote'], + owned: { + one: ['doc-endnote'] + }, namefrom: ['author'], context: null, unsupported: false, @@ -1280,7 +1284,9 @@ lookupTable.role = { 'aria-errormessage' ] }, - owned: null, + owned: { + one: ['menuitem', 'menuitemradio', 'menuitemcheckbox'] + }, nameFrom: ['author'], context: null, unsupported: false, diff --git a/test/integration/rules/aria-required-children/aria-required-children.html b/test/integration/rules/aria-required-children/aria-required-children.html index e830d9fc5d..857677e604 100644 --- a/test/integration/rules/aria-required-children/aria-required-children.html +++ b/test/integration/rules/aria-required-children/aria-required-children.html @@ -1,10 +1,21 @@
Item 1
-
-
-
+
+
+ + +
-
+
+
+
+
+
+
+
+
+
+
diff --git a/test/integration/rules/aria-required-children/aria-required-children.json b/test/integration/rules/aria-required-children/aria-required-children.json index c80233831c..509b38c072 100644 --- a/test/integration/rules/aria-required-children/aria-required-children.json +++ b/test/integration/rules/aria-required-children/aria-required-children.json @@ -1,7 +1,7 @@ { "description": "aria-required-children test", "rule": "aria-required-children", - "violations": [["#fail1"], ["#fail2"], ["#fail3"]], + "violations": [["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"], ["#fail5"]], "passes": [ ["#pass1"], ["#pass2"], @@ -12,5 +12,16 @@ ["#pass7"], ["#pass8"] ], - "incomplete": [["#incomplete1"]] + "incomplete": [ + ["#incomplete1"], + ["#incomplete2"], + ["#incomplete3"], + ["#incomplete4"], + ["#incomplete5"], + ["#incomplete6"], + ["#incomplete7"], + ["#incomplete8"], + ["#incomplete9"], + ["#incomplete10"] + ] } From 5580699654334efaf4ed89e30b24ccc9ed41cdcb Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 13 May 2019 11:34:47 -0500 Subject: [PATCH 2/3] add check test --- test/checks/aria/required-children.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/checks/aria/required-children.js b/test/checks/aria/required-children.js index 7ebb0dbefc..54914657bf 100644 --- a/test/checks/aria/required-children.js +++ b/test/checks/aria/required-children.js @@ -103,6 +103,25 @@ describe('aria-required-children', function() { ); }); + it('should return undefined when element is empty and is in reviewEmpty options', function() { + var params = checkSetup('
', { + reviewEmpty: ['list'] + }); + assert.isUndefined( + checks['aria-required-children'].evaluate.apply(checkContext, params) + ); + }); + + it('should return false when children do not have correct role and is in reviewEmpty options', function() { + var params = checkSetup( + '
', + { reviewEmpty: ['list'] } + ); + assert.isFalse( + checks['aria-required-children'].evaluate.apply(checkContext, params) + ); + }); + (shadowSupported ? it : xit)( 'should pass all existing required children in shadow tree when all required', function() { From 10429ca432f8d36295c862b98242f7ee934fb0bc Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 13 May 2019 11:37:06 -0500 Subject: [PATCH 3/3] add owned child check --- test/checks/aria/required-children.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/checks/aria/required-children.js b/test/checks/aria/required-children.js index 54914657bf..cc6bfe00ad 100644 --- a/test/checks/aria/required-children.js +++ b/test/checks/aria/required-children.js @@ -122,6 +122,16 @@ describe('aria-required-children', function() { ); }); + it('should return false when owned children do not have correct role and is in reviewEmpty options', function() { + var params = checkSetup( + '
', + { reviewEmpty: ['list'] } + ); + assert.isFalse( + checks['aria-required-children'].evaluate.apply(checkContext, params) + ); + }); + (shadowSupported ? it : xit)( 'should pass all existing required children in shadow tree when all required', function() {