From 025221818b184cacdefa06e995e3659b11263bf3 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Tue, 18 Jul 2017 11:46:49 +0200 Subject: [PATCH] fix: Let findUp work on shadow root children --- lib/commons/dom/find-up.js | 25 ++++++------------ test/commons/dom/find-up.js | 52 +++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/lib/commons/dom/find-up.js b/lib/commons/dom/find-up.js index 06e20ffe05..8f2db7f8f9 100644 --- a/lib/commons/dom/find-up.js +++ b/lib/commons/dom/find-up.js @@ -9,25 +9,16 @@ * @return {HTMLElement|null} Either the matching HTMLElement or `null` if there was no match */ dom.findUp = function (element, target) { - 'use strict'; - /*jslint browser:true*/ + let doc, matches, + parent = element; - var parent, - doc = axe.commons.dom.getRootNode(element), - matches; - - matches = doc.querySelectorAll(target); - matches = axe.utils.toArray(matches); - if (doc === document && !matches.length) { - return null; - } - - // recursively walk up the DOM, checking each parent node - parent = dom.getComposedParent(element); - while (parent && matches.indexOf(parent) === -1) { - parent = (parent.assignedSlot) ? parent.assignedSlot : parent.parentNode; + do {// recursively walk up the DOM, checking each parent node + parent = (parent.assignedSlot ? parent.assignedSlot : parent.parentNode); if (parent && parent.nodeType === 11) { + matches = null; parent = parent.host; + } + if (!matches) { doc = axe.commons.dom.getRootNode(parent); matches = doc.querySelectorAll(target); matches = axe.utils.toArray(matches); @@ -35,7 +26,7 @@ dom.findUp = function (element, target) { return null; } } - } + } while (parent && !matches.includes(parent)); return parent; }; diff --git a/test/commons/dom/find-up.js b/test/commons/dom/find-up.js index e96f4983ed..8db3436d3e 100644 --- a/test/commons/dom/find-up.js +++ b/test/commons/dom/find-up.js @@ -74,7 +74,18 @@ describe('dom.findUp', function () { assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild); }); - it('should walk up the assigned slot', function () { + (shadowSupport.v0 ? it : xit)('should work on shadow root children', function () { + fixture.innerHTML = '
'; + var shadow = fixture.querySelector('#something').createShadowRoot(); + + shadow.innerHTML = '
item 1
'; + var listItem = shadow.querySelector('[role=listitem]'); + + assert.equal(axe.commons.dom.findUp(listItem, '[role=list]'), + fixture.firstChild); + }); + + (shadowSupport.v1 ? it : xit)('should walk up the assigned slot', function () { function createContentSlotted() { var group = document.createElement('div'); group.innerHTML = ''; @@ -86,16 +97,15 @@ describe('dom.findUp', function () { root.appendChild(div); div.appendChild(createContentSlotted()); } - if (shadowSupport.v1) { - fixture.innerHTML = ''; - makeShadowTree(fixture.querySelector('div')); - var tree = axe.utils.getFlattenedTree(fixture.firstChild); - var el = axe.utils.querySelectorAll(tree, 'a')[0]; - assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild); - } + + fixture.innerHTML = ''; + makeShadowTree(fixture.querySelector('div')); + var tree = axe.utils.getFlattenedTree(fixture.firstChild); + var el = axe.utils.querySelectorAll(tree, 'a')[0]; + assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild); }); - it('should walk up the shadow DOM', function () { + (shadowSupport.v1 ? it : xit)('should walk up the shadow DOM', function () { function createContent() { var group = document.createElement('div'); group.innerHTML = 'thing'; @@ -107,12 +117,22 @@ describe('dom.findUp', function () { root.appendChild(div); div.appendChild(createContent()); } - if (shadowSupport.v1) { - fixture.innerHTML = ''; - makeShadowTree(fixture.querySelector('div')); - var tree = axe.utils.getFlattenedTree(fixture.firstChild); - var el = axe.utils.querySelectorAll(tree, 'a')[0]; - assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild); - } + + fixture.innerHTML = ''; + makeShadowTree(fixture.querySelector('div')); + var tree = axe.utils.getFlattenedTree(fixture.firstChild); + var el = axe.utils.querySelectorAll(tree, 'a')[0]; + assert.equal(axe.commons.dom.findUp(el.actualNode, 'label'), fixture.firstChild); + }); + + (shadowSupport.v1 ? it : xit)('should work on shadow root children', function () { + fixture.innerHTML = '
'; + var shadow = fixture.querySelector('#something').attachShadow({ mode: 'open' }); + + shadow.innerHTML = '
item 1
'; + var listItem = shadow.querySelector('[role=listitem]'); + + assert.equal(axe.commons.dom.findUp(listItem, '[role=list]'), + fixture.firstChild); }); }); \ No newline at end of file