Last active
October 8, 2024 09:48
-
-
Save heyMP/8ef3912847dcc93304652a412981caca to your computer and use it in GitHub Desktop.
Recursively find elements through multiple layers of shadow dom.
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
/** | |
* Example usage: | |
* const hotspots = findAllDeep(element, `[slot*="hotspot"]`, 10); | |
*/ | |
const findAllDeep = (parent, selectors, depth = null) => { | |
let nodes = new Set(); | |
let currentDepth = 1; | |
const recordResult = (nodesArray) => { | |
for (const node of nodesArray) { | |
nodes.add(node) | |
} | |
} | |
const recursiveSeek = _parent => { | |
// check for selectors in lightdom | |
recordResult(_parent.querySelectorAll(selectors)); | |
if (_parent.shadowRoot) { | |
// check for selectors in shadowRoot | |
recordResult(_parent.shadowRoot.querySelectorAll(selectors)); | |
// look for nested components with shadowRoots | |
for (let child of [..._parent.shadowRoot.querySelectorAll('*')].filter(i => i.shadowRoot)) { | |
// make sure we haven't hit our depth limit | |
if (depth === null || currentDepth < depth) { | |
recursiveSeek(child); | |
} | |
} | |
} | |
}; | |
recursiveSeek(parent); | |
return nodes; | |
}; |
I completely reworked that to get the first matching nested element:
`
const findDeep = (parent, selectors, depth = null) => {
let currentDepth = 0;
let result = null;
const recursiveSeek = _parent => {
currentDepth++;
// check for selectors in lightdom
result = _parent.querySelector(selectors);
if(result)
return result;
// check for selectors in shadowRoot
if (_parent.shadowRoot) {
result = _parent.shadowRoot.querySelector(selectors);
if(result)
return result;
}
// look for nested components with shadowRoots
let children = _parent.querySelectorAll('*');
let childrenWithShadowRoot = [...children].filter(i => i.shadowRoot)
for (let child of childrenWithShadowRoot) {
if (depth === null || currentDepth < depth) {
result = recursiveSeek(child.shadowRoot);
if(result)
return result;
}
}
currentDepth--;
return null;
};
return recursiveSeek(parent);
};
`
Usage:
let el = findDeep(document, '[style*="grid-area: main;"]', 100);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey :) Thanks for this code. Could you add a license? I want to create a small npm package. I created a version that not just iterates over direct children shadow root, but instead the shadow roots can be everywhere as descendants. Also I removed some iterations you did in line 20 and I also added TypesScript.
By the way I don't think your "currentDepth" is working as expected. It is never incremented.