Skip to content

Commit

Permalink
feat(duplicate-id): Add shadow DOM support
Browse files Browse the repository at this point in the history
  • Loading branch information
WilcoFiers committed Aug 1, 2017
1 parent 9df8c9c commit 439bc71
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 17 deletions.
24 changes: 10 additions & 14 deletions lib/checks/shared/duplicate-id.js
@@ -1,21 +1,17 @@
const id = node.getAttribute('id').trim();
// Since empty ID's are not meaningful and are ignored by Edge, we'll
// let those pass.
if (!node.getAttribute('id').trim()) {
if (!id) {
return true;
}
const root = axe.commons.dom.getRootNode(node);
const matchingNodes = Array.from(root.querySelectorAll(
`[id="${ axe.commons.utils.escapeSelector(id) }"]`
)).filter(foundNode => foundNode !== node);

const id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
var matchingNodes = document.querySelectorAll(`[id="${id}"]`);
var related = [];

for (var i = 0; i < matchingNodes.length; i++) {
if (matchingNodes[i] !== node) {
related.push(matchingNodes[i]);
}
}
if (related.length) {
this.relatedNodes(related);
if (matchingNodes.length) {
this.relatedNodes(matchingNodes);
}
this.data(node.getAttribute('id'));
this.data(id);

return (matchingNodes.length <= 1);
return (matchingNodes.length === 0);
54 changes: 51 additions & 3 deletions test/checks/shared/duplicate-id.js
Expand Up @@ -2,7 +2,7 @@ describe('duplicate-id', function () {
'use strict';

var fixture = document.getElementById('fixture');

var shadowSupport = axe.testUtils.shadowSupport;

var checkContext = {
_relatedNodes: [],
Expand All @@ -27,7 +27,6 @@ describe('duplicate-id', function () {
assert.isTrue(checks['duplicate-id'].evaluate.call(checkContext, node));
assert.equal(checkContext._data, node.id);
assert.deepEqual(checkContext._relatedNodes, []);

});

it('should return false if there are multiple elements with an ID', function () {
Expand All @@ -39,7 +38,8 @@ describe('duplicate-id', function () {
});

it('should return remove duplicates', function () {
assert.deepEqual(checks['duplicate-id'].after([{data: 'a'}, {data: 'b'}, {data: 'b'}]), [{data: 'a'}, {data: 'b'}]);
assert.deepEqual(checks['duplicate-id'].after([
{data: 'a'}, {data: 'b'}, {data: 'b'}]), [{data: 'a'}, {data: 'b'}]);
});

it('should ignore empty ids', function () {
Expand All @@ -58,4 +58,52 @@ describe('duplicate-id', function () {
assert.isTrue(checks['duplicate-id'].evaluate.call(checkContext, node));
});

(shadowSupport.v1 ? it : xit)('should find duplicate IDs in shadow trees', function () {
var div = document.createElement('div');
div.id = 'target';
var shadow = div.attachShadow({ mode: 'open' });
shadow.innerHTML = '<span id="target"></span><p id="target">text</p>';
var node = shadow.querySelector('span');
fixture.appendChild(div);

assert.isFalse(checks['duplicate-id'].evaluate.call(checkContext, node));
assert.lengthOf(checkContext._relatedNodes, 1);
assert.deepEqual(checkContext._relatedNodes, [shadow.querySelector('p')]);
});

(shadowSupport.v1 ? it : xit)('should ignore same IDs in shadow trees', function () {
var node = document.createElement('div');
node.id = 'target';
var shadow = node.attachShadow({ mode: 'open' });
shadow.innerHTML = '<span id="target"></span>';
fixture.appendChild(node);

assert.isTrue(checks['duplicate-id'].evaluate.call(checkContext, node));
assert.lengthOf(checkContext._relatedNodes, 0);
});

(shadowSupport.v1 ? it : xit)('should ignore same IDs outside shadow trees', function () {
var div = document.createElement('div');
div.id = 'target';
var shadow = div.attachShadow({ mode: 'open' });
shadow.innerHTML = '<span id="target"></span>';
var node = shadow.querySelector('#target');
fixture.appendChild(div);

assert.isTrue(checks['duplicate-id'].evaluate.call(checkContext, node));
assert.lengthOf(checkContext._relatedNodes, 0);
});

(shadowSupport.v1 ? it : xit)('should not ignore slotted elements', function () {
var node = document.createElement('div');
node.id = 'target';
node.innerHTML = '<p id="target">text</p>';
var shadow = node.attachShadow({ mode: 'open' });
shadow.innerHTML = '<span id="target"><slot></slot></span>';
fixture.appendChild(node);

assert.isFalse(checks['duplicate-id'].evaluate.call(checkContext, node));
assert.lengthOf(checkContext._relatedNodes, 1);
assert.deepEqual(checkContext._relatedNodes, [node.querySelector('p')]);
});
});

0 comments on commit 439bc71

Please sign in to comment.