Skip to content

Commit

Permalink
fix: Correct flattened tree algorithm to include the shadow host (#405)
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanb authored and WilcoFiers committed Jul 5, 2017
1 parent fea3b30 commit 70985b0
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 16 deletions.
4 changes: 3 additions & 1 deletion lib/core/utils/flattened-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ axe.utils.getFlattenedTree = function (node, shadowId) {
if (node.shadowRoot && nodeName !== 'marquee') {
// generate an ID for this shadow root and overwrite the current
// closure shadowId with this value so that it cascades down the tree
retVal = virtualDOMfromNode(node, shadowId);
shadowId = 'a' + Math.random().toString().substring(2);
realArray = Array.from(node.shadowRoot.childNodes);
return realArray.reduce(reduceShadowDOM, []);
retVal.children = realArray.reduce(reduceShadowDOM, []);
return [retVal];
} else {
if (nodeName === 'content') {
realArray = Array.from(node.getDistributedNodes());
Expand Down
2 changes: 1 addition & 1 deletion test/core/utils/contains.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ describe('axe.utils.contains', function () {
if (document.body && typeof document.body.attachShadow === 'function') {
fixture.innerHTML = '<div></div>';
makeShadowTree(fixture.firstChild);
tree = axe.utils.getFlattenedTree(fixture.firstChild);
tree = axe.utils.getFlattenedTree(fixture.firstChild)[0].children;
node1 = axe.utils.querySelectorAll(tree, '#target')[0];
node2 = axe.utils.querySelectorAll(tree, 'a')[0];
assert.isTrue(axe.utils.contains(node1, node2));
Expand Down
33 changes: 19 additions & 14 deletions test/core/utils/flattened-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ function flattenedTreeAssertions () {
'use strict';

var virtualDOM = axe.utils.getFlattenedTree(fixture.firstChild);
assert.equal(virtualDOM.length, 1); // host
assert.equal(virtualDOM[0].actualNode.nodeName, 'DIV');

virtualDOM = virtualDOM[0].children;
assert.equal(virtualDOM.length, 3);
assert.equal(virtualDOM[0].actualNode.nodeName, 'STYLE');

Expand Down Expand Up @@ -44,19 +48,20 @@ function shadowIdAssertions () {
'use strict';

var virtualDOM = axe.utils.getFlattenedTree(fixture);
assert.isUndefined(virtualDOM[0].shadowId);
assert.isDefined(virtualDOM[0].children[0].shadowId);
assert.isDefined(virtualDOM[0].children[1].shadowId);
assert.isDefined(virtualDOM[0].children[4].shadowId);
assert.isUndefined(virtualDOM[0].shadowId); //fixture
assert.isUndefined(virtualDOM[0].children[0].shadowId); //host
assert.isDefined(virtualDOM[0].children[0].children[0].shadowId);
assert.isDefined(virtualDOM[0].children[0].children[1].shadowId);
assert.isDefined(virtualDOM[0].children[1].children[0].shadowId);
// shadow IDs in the same shadowRoot must be the same
assert.equal(virtualDOM[0].children[0].shadowId,
virtualDOM[0].children[1].shadowId);
assert.equal(virtualDOM[0].children[0].children[0].shadowId,
virtualDOM[0].children[0].children[1].shadowId);
// should cascade
assert.equal(virtualDOM[0].children[1].shadowId,
virtualDOM[0].children[1].children[0].shadowId);
assert.equal(virtualDOM[0].children[0].children[1].shadowId,
virtualDOM[0].children[0].children[1].children[0].shadowId);
// shadow IDs in different shadowRoots must be different
assert.notEqual(virtualDOM[0].children[0].shadowId,
virtualDOM[0].children[4].shadowId);
assert.notEqual(virtualDOM[0].children[0].children[0].shadowId,
virtualDOM[0].children[1].children[0].shadowId);

}

Expand Down Expand Up @@ -143,10 +148,10 @@ if (document.body && typeof document.body.attachShadow === 'function') {
it('getFlattenedTree\'s virtual DOM should give an ID to the shadow DOM', shadowIdAssertions);
it('getFlattenedTree\'s virtual DOM should have the fallback content', function () {
var virtualDOM = axe.utils.getFlattenedTree(fixture);
assert.isTrue(virtualDOM[0].children[7].children[0].children.length === 2);
assert.isTrue(virtualDOM[0].children[7].children[0].children[0].actualNode.nodeType === 3);
assert.isTrue(virtualDOM[0].children[7].children[0].children[0].actualNode.textContent === 'fallback content');
assert.isTrue(virtualDOM[0].children[7].children[0].children[1].actualNode.nodeName === 'LI');
assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children.length === 2);
assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[0].actualNode.nodeType === 3);
assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[0].actualNode.textContent === 'fallback content');
assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[1].actualNode.nodeName === 'LI');
});
});
describe('flattened-tree shadow DOM v1: boxed slots', function () {
Expand Down

0 comments on commit 70985b0

Please sign in to comment.