1717* Another example querySelectorAllDeep('#downloads-list div#title-area + a');
1818e.g.
1919*/
20- export function querySelectorAllDeep ( selector , root = document ) {
21- return _querySelectorDeep ( selector , true , root ) ;
20+ export function querySelectorAllDeep ( selector , root = document , allElements = null ) {
21+ return _querySelectorDeep ( selector , true , root , allElements ) ;
2222}
2323
24- export function querySelectorDeep ( selector , root = document ) {
25- return _querySelectorDeep ( selector , false , root ) ;
24+ export function querySelectorDeep ( selector , root = document , allElements = null ) {
25+ return _querySelectorDeep ( selector , false , root , allElements ) ;
2626}
2727
28- function _querySelectorDeep ( selector , findMany , root ) {
28+ function _querySelectorDeep ( selector , findMany , root , allElements = null ) {
2929 selector = normalizeSelector ( selector )
3030 let lightElement = root . querySelector ( selector ) ;
3131
@@ -48,10 +48,14 @@ function _querySelectorDeep(selector, findMany, root) {
4848 //remove white space at start of selector
4949 . replace ( / ^ \s + / g, '' )
5050 . replace ( / \s * ( [ > + ~ ] + ) \s * / g, '$1' ) , ' ' )
51- // filter out entry white selectors
52- . filter ( ( entry ) => ! ! entry ) ;
51+ // filter out entry white selectors
52+ . filter ( ( entry ) => ! ! entry )
53+ // convert "a > b" to ["a", "b"]
54+ . map ( ( entry ) => splitByCharacterUnlessQuoted ( entry , '>' ) ) ;
55+
5356 const possibleElementsIndex = splitSelector . length - 1 ;
54- const possibleElements = collectAllElementsDeep ( splitSelector [ possibleElementsIndex ] , root ) ;
57+ const lastSplitPart = splitSelector [ possibleElementsIndex ] [ splitSelector [ possibleElementsIndex ] . length - 1 ]
58+ const possibleElements = collectAllElementsDeep ( lastSplitPart , root , allElements ) ;
5559 const findElements = findMatchingElement ( splitSelector , possibleElementsIndex , root ) ;
5660 if ( findMany ) {
5761 acc = acc . concat ( possibleElements . filter ( findElements ) ) ;
@@ -79,7 +83,23 @@ function findMatchingElement(splitSelector, possibleElementsIndex, root) {
7983 let parent = element ;
8084 let foundElement = false ;
8185 while ( parent && ! isDocumentNode ( parent ) ) {
82- const foundMatch = parent . matches ( splitSelector [ position ] ) ;
86+ let foundMatch = true
87+ if ( splitSelector [ position ] . length === 1 ) {
88+ foundMatch = parent . matches ( splitSelector [ position ] ) ;
89+ } else {
90+ // selector is in the format "a > b"
91+ // make sure a few parents match in order
92+ const reversedParts = ( [ ] ) . concat ( splitSelector [ position ] ) . reverse ( )
93+ let newParent = parent
94+ for ( const part of reversedParts ) {
95+ if ( ! newParent || ! newParent . matches ( part ) ) {
96+ foundMatch = false
97+ break
98+ }
99+ newParent = findParentOrHost ( newParent , root ) ;
100+ }
101+ }
102+
83103 if ( foundMatch && position === 0 ) {
84104 foundElement = true ;
85105 break ;
@@ -133,27 +153,30 @@ function findParentOrHost(element, root) {
133153 * @author ebidel@ (Eric Bidelman)
134154 * License Apache-2.0
135155 */
136- function collectAllElementsDeep ( selector = null , root ) {
137- const allElements = [ ] ;
138-
139- const findAllElements = function ( nodes ) {
140- for ( let i = 0 , el ; el = nodes [ i ] ; ++ i ) {
141- allElements . push ( el ) ;
142- // If the element has a shadow root, dig deeper.
143- if ( el . shadowRoot ) {
144- findAllElements ( el . shadowRoot . querySelectorAll ( '*' ) ) ;
156+ export function collectAllElementsDeep ( selector = null , root , cachedElements = null ) {
157+ let allElements = [ ] ;
158+
159+ if ( cachedElements ) {
160+ allElements = cachedElements ;
161+ } else {
162+ const findAllElements = function ( nodes ) {
163+ for ( let i = 0 , el ; el = nodes [ i ] ; ++ i ) {
164+ allElements . push ( el ) ;
165+ // If the element has a shadow root, dig deeper.
166+ if ( el . shadowRoot ) {
167+ findAllElements ( el . shadowRoot . querySelectorAll ( '*' ) ) ;
168+ }
145169 }
146170 }
147- } ;
148- if ( root . shadowRoot ) {
149- findAllElements ( root . shadowRoot . querySelectorAll ( '*' ) ) ;
171+ if ( root . shadowRoot ) {
172+ findAllElements ( root . shadowRoot . querySelectorAll ( '*' ) ) ;
173+ }
174+ findAllElements ( root . querySelectorAll ( '*' ) ) ;
150175 }
151- findAllElements ( root . querySelectorAll ( '*' ) ) ;
152176
153177 return allElements . filter ( el => el . matches ( selector ) ) ;
154178}
155179
156-
157180// normalize-selector-rev-02.js
158181/*
159182 author: kyle simpson (@getify)
0 commit comments