Skip to content

Commit 70985b0

Browse files
dylanbWilcoFiers
authored andcommitted
fix: Correct flattened tree algorithm to include the shadow host (#405)
1 parent fea3b30 commit 70985b0

File tree

3 files changed

+23
-16
lines changed

3 files changed

+23
-16
lines changed

lib/core/utils/flattened-tree.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ axe.utils.getFlattenedTree = function (node, shadowId) {
8080
if (node.shadowRoot && nodeName !== 'marquee') {
8181
// generate an ID for this shadow root and overwrite the current
8282
// closure shadowId with this value so that it cascades down the tree
83+
retVal = virtualDOMfromNode(node, shadowId);
8384
shadowId = 'a' + Math.random().toString().substring(2);
8485
realArray = Array.from(node.shadowRoot.childNodes);
85-
return realArray.reduce(reduceShadowDOM, []);
86+
retVal.children = realArray.reduce(reduceShadowDOM, []);
87+
return [retVal];
8688
} else {
8789
if (nodeName === 'content') {
8890
realArray = Array.from(node.getDistributedNodes());

test/core/utils/contains.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ describe('axe.utils.contains', function () {
104104
if (document.body && typeof document.body.attachShadow === 'function') {
105105
fixture.innerHTML = '<div></div>';
106106
makeShadowTree(fixture.firstChild);
107-
tree = axe.utils.getFlattenedTree(fixture.firstChild);
107+
tree = axe.utils.getFlattenedTree(fixture.firstChild)[0].children;
108108
node1 = axe.utils.querySelectorAll(tree, '#target')[0];
109109
node2 = axe.utils.querySelectorAll(tree, 'a')[0];
110110
assert.isTrue(axe.utils.contains(node1, node2));

test/core/utils/flattened-tree.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ function flattenedTreeAssertions () {
1414
'use strict';
1515

1616
var virtualDOM = axe.utils.getFlattenedTree(fixture.firstChild);
17+
assert.equal(virtualDOM.length, 1); // host
18+
assert.equal(virtualDOM[0].actualNode.nodeName, 'DIV');
19+
20+
virtualDOM = virtualDOM[0].children;
1721
assert.equal(virtualDOM.length, 3);
1822
assert.equal(virtualDOM[0].actualNode.nodeName, 'STYLE');
1923

@@ -44,19 +48,20 @@ function shadowIdAssertions () {
4448
'use strict';
4549

4650
var virtualDOM = axe.utils.getFlattenedTree(fixture);
47-
assert.isUndefined(virtualDOM[0].shadowId);
48-
assert.isDefined(virtualDOM[0].children[0].shadowId);
49-
assert.isDefined(virtualDOM[0].children[1].shadowId);
50-
assert.isDefined(virtualDOM[0].children[4].shadowId);
51+
assert.isUndefined(virtualDOM[0].shadowId); //fixture
52+
assert.isUndefined(virtualDOM[0].children[0].shadowId); //host
53+
assert.isDefined(virtualDOM[0].children[0].children[0].shadowId);
54+
assert.isDefined(virtualDOM[0].children[0].children[1].shadowId);
55+
assert.isDefined(virtualDOM[0].children[1].children[0].shadowId);
5156
// shadow IDs in the same shadowRoot must be the same
52-
assert.equal(virtualDOM[0].children[0].shadowId,
53-
virtualDOM[0].children[1].shadowId);
57+
assert.equal(virtualDOM[0].children[0].children[0].shadowId,
58+
virtualDOM[0].children[0].children[1].shadowId);
5459
// should cascade
55-
assert.equal(virtualDOM[0].children[1].shadowId,
56-
virtualDOM[0].children[1].children[0].shadowId);
60+
assert.equal(virtualDOM[0].children[0].children[1].shadowId,
61+
virtualDOM[0].children[0].children[1].children[0].shadowId);
5762
// shadow IDs in different shadowRoots must be different
58-
assert.notEqual(virtualDOM[0].children[0].shadowId,
59-
virtualDOM[0].children[4].shadowId);
63+
assert.notEqual(virtualDOM[0].children[0].children[0].shadowId,
64+
virtualDOM[0].children[1].children[0].shadowId);
6065

6166
}
6267

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

0 commit comments

Comments
 (0)