Skip to content

Instantly share code, notes, and snippets.

@Spencer-Doak
Created May 8, 2021 21:25
Show Gist options
  • Save Spencer-Doak/9954daae8a859337a08f0022293313a6 to your computer and use it in GitHub Desktop.
Save Spencer-Doak/9954daae8a859337a08f0022293313a6 to your computer and use it in GitHub Desktop.
Recursively find all shadow roots in a page.
/**
* Recursive depth-first search to find all shadow roots within a webpage.
*
* Example usage: let's imagine you come across a page that has a bunch of
* expandable information sections, and you would like to expand all of those
* info sections for the sake of printing to a PDF or for the ease of
* performing a simple `CTRL+F` search across the information. Let's assume
* those expanding buttons are buried within Shadow DOM. (Perhaps the site is
* using Angular or something of the sort & the buttons are separate
* components, thus by default they end up in a Shadow DOM whenever included.)
* Of course, you're not going click 30 different buttons like some mortal, but
* Shadow DOM prevents you from simply saying:
* `document.body.querySelectorAll('button.btn-expand-more-details')`
*
* This is where the `findRoots` function can help you out. Instead of
* resorting to clicking each button by hand, you can "Search in the Shadows"
* by leveraging the `findRoots(...)` function to locate all shadow document
* fragments. You can then execute `querySelectorAll('...')` across all
* document fragments to locate the buttons you want to click. Your code might
* read:
*
* ```javascript
* [
* document.body,
* ...findRoots(document.body)
* ].flatMap(
* e=>e.querySelectorAll('button.btn-expand-more-details')
* ).forEach(e=>e.click())
* ```
*
* @param {Node} ele - An element that we should search for ShadowRoots within.
* @returns {Array<ShadowRoot>} Array of ShadowRoots found below/contained
* within the given node, `ele`.
*/
function findRoots(ele) {
return [
ele,
...ele.querySelectorAll('*')
].filter(e => !!e.shadowRoot)
.flatMap(e => [e.shadowRoot, ...findRoots(e.shadowRoot)])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment