Last active
July 10, 2018 15:22
-
-
Save garlicnation/7ecc2b7ad317816ddf642b3193fc0c90 to your computer and use it in GitHub Desktop.
Select inside shadow roots
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Find all elements inside `root` that match `selector`, even inside shadow roots. | |
*/ | |
function qsAllDom(root, selector, results){ | |
if (!results) { | |
results = [] | |
} | |
var newResults = root.querySelectorAll(selector); | |
for (var result of newResults) { | |
results.push(result); | |
} | |
var roots = root.getElementsByTagName('*'); | |
for (var i = 0; i < roots.length; i++) { | |
var shadow = roots[i].shadowRoot; | |
if (!shadow) { | |
continue; | |
} | |
for (var j = 0; j < shadow.children.length; j++) { | |
qsAllDom(shadow.children[j], selector, results); | |
} | |
} | |
return results; | |
} | |
/** | |
* Find all elements inside `root` that match `selector`, even inside shadow roots. | |
* Fastest method as of 12/20/16. | |
*/ | |
function qsAllDomNoRecursion(root, selector, results){ | |
if (!results) { | |
results = [] | |
} | |
var queue = [root]; | |
var elements = []; | |
for (var i = 0; i <= elements.length; i++) { | |
if (i === elements.length) { | |
if (queue.length === 0) { | |
break; | |
} | |
let next = queue.pop(); | |
elements = next.getElementsByTagName('*'); | |
i = -1; | |
continue; | |
} | |
var element = elements[i]; | |
if (element.matches && element.matches(selector)) { | |
results.push(element); | |
} | |
var shadow = element.shadowRoot; | |
if (shadow) { | |
for (var j = 0; j < shadow.children.length; j++) { | |
queue.push(shadow.children[j]); | |
} | |
} | |
} | |
return results; | |
} | |
/** | |
* Find all elements inside `root` that match `selector`, even inside shadow roots. | |
*/ | |
function qsAllDomTreeWalker(root, selector, results){ | |
if (!results) { | |
results = [] | |
} | |
var queue = []; | |
const newWalker = (root) => document.createTreeWalker( | |
root, | |
NodeFilter.SHOW_ELEMENT | |
); | |
var walker = newWalker(root); | |
var candidate = walker.nextNode(); | |
while (candidate) { | |
if (candidate.matches && candidate.matches(selector)) { | |
results.push(walker.currentNode); | |
} | |
if (candidate.shadowRoot) { | |
queue.push(candidate.shadowRoot); | |
} | |
candidate = walker.nextNode(); | |
while (!candidate && queue.length > 0) { | |
walker = newWalker(queue.pop()); | |
candidate = walker.nextNode(); | |
} | |
} | |
return results; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment