Skip to content

Commit 0252218

Browse files
committed
fix: Let findUp work on shadow root children
1 parent 9ddfc0f commit 0252218

File tree

2 files changed

+44
-33
lines changed

2 files changed

+44
-33
lines changed

lib/commons/dom/find-up.js

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,24 @@
99
* @return {HTMLElement|null} Either the matching HTMLElement or `null` if there was no match
1010
*/
1111
dom.findUp = function (element, target) {
12-
'use strict';
13-
/*jslint browser:true*/
12+
let doc, matches,
13+
parent = element;
1414

15-
var parent,
16-
doc = axe.commons.dom.getRootNode(element),
17-
matches;
18-
19-
matches = doc.querySelectorAll(target);
20-
matches = axe.utils.toArray(matches);
21-
if (doc === document && !matches.length) {
22-
return null;
23-
}
24-
25-
// recursively walk up the DOM, checking each parent node
26-
parent = dom.getComposedParent(element);
27-
while (parent && matches.indexOf(parent) === -1) {
28-
parent = (parent.assignedSlot) ? parent.assignedSlot : parent.parentNode;
15+
do {// recursively walk up the DOM, checking each parent node
16+
parent = (parent.assignedSlot ? parent.assignedSlot : parent.parentNode);
2917
if (parent && parent.nodeType === 11) {
18+
matches = null;
3019
parent = parent.host;
20+
}
21+
if (!matches) {
3122
doc = axe.commons.dom.getRootNode(parent);
3223
matches = doc.querySelectorAll(target);
3324
matches = axe.utils.toArray(matches);
3425
if (doc === document && !matches.length) {
3526
return null;
3627
}
3728
}
38-
}
29+
} while (parent && !matches.includes(parent));
3930

4031
return parent;
4132
};

test/commons/dom/find-up.js

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,18 @@ describe('dom.findUp', function () {
7474
assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild);
7575
});
7676

77-
it('should walk up the assigned slot', function () {
77+
(shadowSupport.v0 ? it : xit)('should work on shadow root children', function () {
78+
fixture.innerHTML = '<div role="list"><div id="something"></div></div>';
79+
var shadow = fixture.querySelector('#something').createShadowRoot();
80+
81+
shadow.innerHTML = '<div role="listitem">item 1</div>';
82+
var listItem = shadow.querySelector('[role=listitem]');
83+
84+
assert.equal(axe.commons.dom.findUp(listItem, '[role=list]'),
85+
fixture.firstChild);
86+
});
87+
88+
(shadowSupport.v1 ? it : xit)('should walk up the assigned slot', function () {
7889
function createContentSlotted() {
7990
var group = document.createElement('div');
8091
group.innerHTML = '<div id="target" style="display:none;">Stuff<slot></slot></div>';
@@ -86,16 +97,15 @@ describe('dom.findUp', function () {
8697
root.appendChild(div);
8798
div.appendChild(createContentSlotted());
8899
}
89-
if (shadowSupport.v1) {
90-
fixture.innerHTML = '<label><div><p><a>hello</a></p></div></label>';
91-
makeShadowTree(fixture.querySelector('div'));
92-
var tree = axe.utils.getFlattenedTree(fixture.firstChild);
93-
var el = axe.utils.querySelectorAll(tree, 'a')[0];
94-
assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild);
95-
}
100+
101+
fixture.innerHTML = '<label><div><p><a>hello</a></p></div></label>';
102+
makeShadowTree(fixture.querySelector('div'));
103+
var tree = axe.utils.getFlattenedTree(fixture.firstChild);
104+
var el = axe.utils.querySelectorAll(tree, 'a')[0];
105+
assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild);
96106
});
97107

98-
it('should walk up the shadow DOM', function () {
108+
(shadowSupport.v1 ? it : xit)('should walk up the shadow DOM', function () {
99109
function createContent() {
100110
var group = document.createElement('div');
101111
group.innerHTML = '<a>thing</a>';
@@ -107,12 +117,22 @@ describe('dom.findUp', function () {
107117
root.appendChild(div);
108118
div.appendChild(createContent());
109119
}
110-
if (shadowSupport.v1) {
111-
fixture.innerHTML = '<label><div></div></label>';
112-
makeShadowTree(fixture.querySelector('div'));
113-
var tree = axe.utils.getFlattenedTree(fixture.firstChild);
114-
var el = axe.utils.querySelectorAll(tree, 'a')[0];
115-
assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild);
116-
}
120+
121+
fixture.innerHTML = '<label><div></div></label>';
122+
makeShadowTree(fixture.querySelector('div'));
123+
var tree = axe.utils.getFlattenedTree(fixture.firstChild);
124+
var el = axe.utils.querySelectorAll(tree, 'a')[0];
125+
assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild);
126+
});
127+
128+
(shadowSupport.v1 ? it : xit)('should work on shadow root children', function () {
129+
fixture.innerHTML = '<div role="list"><div id="something"></div></div>';
130+
var shadow = fixture.querySelector('#something').attachShadow({ mode: 'open' });
131+
132+
shadow.innerHTML = '<div role="listitem">item 1</div>';
133+
var listItem = shadow.querySelector('[role=listitem]');
134+
135+
assert.equal(axe.commons.dom.findUp(listItem, '[role=list]'),
136+
fixture.firstChild);
117137
});
118138
});

0 commit comments

Comments
 (0)