@@ -26,12 +26,9 @@ import { DomUtils, parseDocument } from 'htmlparser2'
2626
2727type ParsedDocument = ReturnType < typeof parseDocument >
2828
29- let classCache : null | Set < string > = null
30- let idCache : null | Set < string > = null
31-
32- function buildCache ( container : Node | HTMLDocument ) {
33- classCache = new Set ( )
34- idCache = new Set ( )
29+ function buildCache ( container : Node ) {
30+ container . _classCache = new Set ( )
31+ container . _idCache = new Set ( )
3532 const queue = [ container ]
3633
3734 while ( queue . length ) {
@@ -40,17 +37,17 @@ function buildCache(container: Node | HTMLDocument) {
4037 if ( node . hasAttribute ?.( 'class' ) ) {
4138 const classList = node . getAttribute ( 'class' ) . trim ( ) . split ( ' ' )
4239 classList . forEach ( ( cls ) => {
43- classCache ! . add ( cls )
40+ container . _classCache ! . add ( cls )
4441 } )
4542 }
4643
4744 if ( node . hasAttribute ?.( 'id' ) ) {
4845 const id = node . getAttribute ( 'id' ) . trim ( )
49- idCache . add ( id )
46+ container . _idCache ! . add ( id )
5047 }
5148
5249 if ( 'children' in node ) {
53- queue . push ( ...node . children . filter ( child => child . type === 'tag' ) )
50+ queue . push ( ...( node as NodeWithChildren ) . children . filter ( child => child . type === 'tag' ) )
5451 }
5552 }
5653}
@@ -112,6 +109,8 @@ declare module 'domhandler' {
112109 $$name ?: string
113110 $$reduce ?: boolean
114111 $$links ?: ChildNode [ ]
112+ _classCache ?: Set < string >
113+ _idCache ?: Set < string >
115114 }
116115}
117116
@@ -346,23 +345,23 @@ function extendDocument(document: ParsedDocument): asserts document is HTMLDocum
346345// so that it's disposed with it.
347346const selectorTokensCache = new Map < string , null | AttributeSelector [ ] > ( )
348347
349- function cachedQuerySelector ( sel : string , node : Node | Node [ ] ) {
348+ function cachedQuerySelector ( sel : string , node : Node ) {
350349 let selectorTokens = selectorTokensCache . get ( sel )
351350 if ( selectorTokens === undefined ) {
352351 selectorTokens = parseRelevantSelectors ( sel )
353352 selectorTokensCache . set ( sel , selectorTokens )
354353 }
355354
356- if ( selectorTokens ) {
355+ if ( selectorTokens && node . _classCache && node . _idCache ) {
357356 for ( const token of selectorTokens ) {
358- // Check if the selector is a class selector
359- if ( token . name === 'class' ) {
360- return classCache ! . has ( token . value )
357+ if ( token . name === 'class' && ! node . _classCache . has ( token . value ) ) {
358+ return false
361359 }
362- if ( token . name === 'id' ) {
363- return idCache ! . has ( token . value )
360+ if ( token . name === 'id' && ! node . _idCache . has ( token . value ) ) {
361+ return false
364362 }
365363 }
364+ return true
366365 }
367366
368367 return ! ! selectOne ( sel , node )
@@ -375,7 +374,7 @@ function parseRelevantSelectors(sel: string): AttributeSelector[] | null {
375374 for ( let i = 0 ; i < tokens . length ; i ++ ) {
376375 const tokenGroup = tokens [ i ]
377376 if ( tokenGroup ?. length !== 1 ) {
378- continue
377+ return null
379378 }
380379
381380 const token = tokenGroup [ 0 ]
0 commit comments