@@ -275,87 +275,67 @@ export function _isBlockedElement(
275275 return false ;
276276}
277277
278+ function elementClassMatchesRegex ( el : HTMLElement , regex : RegExp ) : boolean {
279+ for ( let eIndex = el . classList . length ; eIndex -- ; ) {
280+ const className = el . classList [ eIndex ] ;
281+ if ( regex . test ( className ) ) {
282+ return true ;
283+ }
284+ }
285+ return false ;
286+ }
287+
278288export function classMatchesRegex (
279289 node : Node | null ,
280290 regex : RegExp ,
281291 checkAncestors : boolean ,
282292) : boolean {
283- return distanceToClassRegexMatch ( node , regex , checkAncestors ) >= 0 ;
293+ if ( ! node ) return false ;
294+ if ( checkAncestors ) {
295+ return (
296+ distanceToMatch ( node , ( node ) =>
297+ elementClassMatchesRegex ( node as HTMLElement , regex ) ,
298+ ) >= 0
299+ ) ;
300+ } else if ( node . nodeType === node . ELEMENT_NODE ) {
301+ return elementClassMatchesRegex ( node as HTMLElement , regex ) ;
302+ }
303+ return false ;
284304}
285305
286- function distanceToClassRegexMatch (
306+ function distanceToMatch (
287307 node : Node | null ,
288- regex : RegExp ,
289- checkAncestors : boolean ,
308+ matchPredicate : ( node : Node ) => boolean ,
309+ limit = Infinity ,
290310 distance = 0 ,
291311) : number {
292312 if ( ! node ) return - 1 ;
293- if ( node . nodeType !== node . ELEMENT_NODE ) {
294- if ( ! checkAncestors ) return - 1 ;
295- return distanceToClassRegexMatch ( node . parentNode , regex , checkAncestors ) ;
296- }
297-
298- for ( let eIndex = ( node as HTMLElement ) . classList . length ; eIndex -- ; ) {
299- const className = ( node as HTMLElement ) . classList [ eIndex ] ;
300- if ( regex . test ( className ) ) {
301- return distance ;
302- }
303- }
304- if ( ! checkAncestors ) return - 1 ;
305- return distanceToClassRegexMatch (
306- node . parentNode ,
307- regex ,
308- checkAncestors ,
309- distance + 1 ,
310- ) ;
313+ if ( node . nodeType !== node . ELEMENT_NODE ) return - 1 ;
314+ if ( distance > limit ) return - 1 ;
315+ if ( matchPredicate ( node ) ) return distance ;
316+ return distanceToMatch ( node . parentNode , matchPredicate , limit , distance + 1 ) ;
311317}
312318
313- function distanceToSelectorMatch ( el : HTMLElement , selector : string ) : number {
314- if ( ! el ) return - 1 ;
315- if ( el . matches ( selector ) ) return 0 ;
316- const closestParent = el . closest ( selector ) ;
317- if ( closestParent ) {
318- let current = el ;
319- let distance = 0 ;
320- while ( current && current !== closestParent ) {
321- current = current . parentNode as HTMLElement ;
322- if ( ! current ) {
323- return - 1 ;
324- }
325- distance ++ ;
326- }
327- return distance ;
328- }
329- return - 1 ;
330- }
331-
332- function distanceToMatch (
333- el : HTMLElement ,
319+ function createMatchPredicate (
334320 className : string | RegExp | null ,
335321 selector : string | null ,
336- ) : number {
337- let classDistance = - 1 ;
338- let selectorDistance = - 1 ;
339-
340- if ( className ) {
341- if ( typeof className === 'string' ) {
342- classDistance = distanceToSelectorMatch ( el , `.${ className } ` ) ;
343- } else {
344- classDistance = distanceToClassRegexMatch ( el , className , true ) ;
322+ ) : ( node : Node ) => boolean {
323+ return ( node : Node ) => {
324+ const el = node as HTMLElement ;
325+ if ( el === null ) return false ;
326+
327+ if ( className ) {
328+ if ( typeof className === 'string' ) {
329+ if ( el . matches ( `.${ className } ` ) ) return true ;
330+ } else if ( elementClassMatchesRegex ( el , className ) ) {
331+ return true ;
332+ }
345333 }
346- }
347334
348- if ( selector ) {
349- selectorDistance = distanceToSelectorMatch ( el , selector ) ;
350- }
335+ if ( selector && el . matches ( selector ) ) return true ;
351336
352- return selectorDistance >= 0
353- ? classDistance >= 0
354- ? Math . min ( classDistance , selectorDistance )
355- : selectorDistance
356- : classDistance >= 0
357- ? classDistance
358- : - 1 ;
337+ return false ;
338+ } ;
359339}
360340
361341export function needMaskingText (
@@ -374,16 +354,19 @@ export function needMaskingText(
374354
375355 const unmaskDistance = distanceToMatch (
376356 el ,
377- unmaskTextClass ,
378- unmaskTextSelector ,
357+ createMatchPredicate ( unmaskTextClass , unmaskTextSelector ) ,
379358 ) ;
380-
359+
381360 let maskDistance = - 1 ;
382361 if ( maskAllText && unmaskDistance < 0 ) {
383362 return true ;
384363 }
385364
386- maskDistance = distanceToMatch ( el , maskTextClass , maskTextSelector ) ;
365+ maskDistance = distanceToMatch (
366+ el ,
367+ createMatchPredicate ( maskTextClass , maskTextSelector ) ,
368+ unmaskDistance >= 0 ? unmaskDistance : Infinity ,
369+ ) ;
387370
388371 return maskDistance >= 0
389372 ? unmaskDistance >= 0
0 commit comments