@@ -235,7 +235,7 @@ const CosmeticFilteringEngine = function() {
235235 } ) ;
236236
237237 // specific filters
238- this . specificFilters = new StaticExtFilteringHostnameDB ( 2 ) ;
238+ this . specificFilters = new StaticExtFilteringHostnameDB ( ) ;
239239
240240 // low generic cosmetic filters: map of hash => stringified selector list
241241 this . lowlyGeneric = new Map ( ) ;
@@ -254,16 +254,6 @@ const CosmeticFilteringEngine = function() {
254254 str : '' ,
255255 mru : new MRUCache ( 16 )
256256 } ;
257-
258- // Short-lived: content is valid only during one function call. These
259- // is to prevent repeated allocation/deallocation overheads -- the
260- // constructors/destructors of javascript Set/Map is assumed to be costlier
261- // than just calling clear() on these.
262- this . $specificSet = new Set ( ) ;
263- this . $exceptionSet = new Set ( ) ;
264- this . $proceduralSet = new Set ( ) ;
265- this . $dummySet = new Set ( ) ;
266-
267257 this . reset ( ) ;
268258} ;
269259
@@ -429,7 +419,7 @@ CosmeticFilteringEngine.prototype.compileGenericUnhideSelector = function(
429419 // hostnames). No distinction is made between declarative and
430420 // procedural selectors, since they really exist only to cancel
431421 // out other cosmetic filters.
432- writer . push ( [ 8 , '' , 0b001 , compiled ] ) ;
422+ writer . push ( [ 8 , '' , `- ${ compiled } ` ] ) ;
433423} ;
434424
435425/******************************************************************************/
@@ -452,23 +442,8 @@ CosmeticFilteringEngine.prototype.compileSpecificSelector = function(
452442 }
453443
454444 writer . select ( 'COSMETIC_FILTERS:SPECIFIC' ) ;
455-
456- // https://github.com/chrisaljoudi/uBlock/issues/145
457- let unhide = exception ? 1 : 0 ;
458- if ( not ) { unhide ^= 1 ; }
459-
460- let kind = 0 ;
461- if ( unhide === 1 ) {
462- kind |= 0b001 ; // Exception
463- }
464- if ( compiled . charCodeAt ( 0 ) === 0x7B /* '{' */ ) {
465- kind |= 0b010 ; // Procedural
466- }
467- if ( hostname === '*' ) {
468- kind |= 0b100 ; // Applies everywhere
469- }
470-
471- writer . push ( [ 8 , hostname , kind , compiled ] ) ;
445+ const prefix = ( ( exception ? 1 : 0 ) ^ ( not ? 1 : 0 ) ) ? '-' : '+' ;
446+ writer . push ( [ 8 , hostname , `${ prefix } ${ compiled } ` ] ) ;
472447} ;
473448
474449/******************************************************************************/
@@ -500,15 +475,16 @@ CosmeticFilteringEngine.prototype.fromCompiledContent = function(reader, options
500475 // not to be injected conditionally through the DOM surveyor.
501476 // hash, *, .promoted-tweet
502477 case 8 :
503- if ( args [ 2 ] === 0b100 ) {
504- if ( this . reSimpleHighGeneric . test ( args [ 3 ] ) )
505- this . highlyGeneric . simple . dict . add ( args [ 3 ] ) ;
478+ if ( args [ 1 ] === '*' ) {
479+ const selector = args [ 2 ] . slice ( 1 ) ;
480+ if ( this . reSimpleHighGeneric . test ( selector ) )
481+ this . highlyGeneric . simple . dict . add ( selector ) ;
506482 else {
507- this . highlyGeneric . complex . dict . add ( args [ 3 ] ) ;
483+ this . highlyGeneric . complex . dict . add ( selector ) ;
508484 }
509485 break ;
510486 }
511- this . specificFilters . store ( args [ 1 ] , args [ 2 ] & 0b011 , args [ 3 ] ) ;
487+ this . specificFilters . store ( args [ 1 ] , args [ 2 ] ) ;
512488 break ;
513489 default :
514490 this . discardedCount += 1 ;
@@ -590,9 +566,7 @@ CosmeticFilteringEngine.prototype.toSelfie = function() {
590566
591567CosmeticFilteringEngine . prototype . fromSelfie = function ( selfie ) {
592568 if ( selfie . version !== this . selfieVersion ) {
593- throw new Error (
594- `cosmeticFilteringEngine: mismatched selfie version, ${ selfie . version } , expected ${ this . selfieVersion } `
595- ) ;
569+ throw new TypeError ( 'Bad selfie' ) ;
596570 }
597571 this . acceptedCount = selfie . acceptedCount ;
598572 this . discardedCount = selfie . discardedCount ;
@@ -630,16 +604,11 @@ CosmeticFilteringEngine.prototype.removeFromSelectorCache = function(
630604 type = undefined
631605) {
632606 const targetHostnameLength = targetHostname . length ;
633- for ( let entry of this . selectorCache ) {
634- let hostname = entry [ 0 ] ;
635- let item = entry [ 1 ] ;
607+ for ( const [ hostname , item ] of this . selectorCache ) {
636608 if ( targetHostname !== '*' ) {
637609 if ( hostname . endsWith ( targetHostname ) === false ) { continue ; }
638- if (
639- hostname . length !== targetHostnameLength &&
640- hostname . charAt ( hostname . length - targetHostnameLength - 1 ) !== '.'
641- ) {
642- continue ;
610+ if ( hostname . length !== targetHostnameLength ) {
611+ if ( hostname . at ( - 1 ) !== '.' ) { continue ; }
643612 }
644613 }
645614 item . remove ( type ) ;
@@ -791,48 +760,39 @@ CosmeticFilteringEngine.prototype.retrieveSpecificSelectors = function(
791760 options . noSpecificCosmeticFiltering !== true ||
792761 options . noGenericCosmeticFiltering !== true
793762 ) {
794- const specificSet = this . $specificSet ;
795- const proceduralSet = this . $proceduralSet ;
796- const exceptionSet = this . $exceptionSet ;
797- const dummySet = this . $dummySet ;
798-
799763 // Cached cosmetic filters: these are always declarative.
764+ const specificSet = new Set ( ) ;
800765 if ( cacheEntry !== undefined ) {
801766 cacheEntry . retrieveCosmetic ( specificSet , out . genericCosmeticHashes = [ ] ) ;
802767 if ( cacheEntry . disableSurveyor ) {
803768 out . disableSurveyor = true ;
804769 }
805770 }
806771
772+ const allSet = new Set ( ) ;
807773 // Retrieve filters with a non-empty hostname
808- const retrieveSets = [ specificSet , exceptionSet , proceduralSet , exceptionSet ] ;
809- const discardSets = [ dummySet , exceptionSet ] ;
810- this . specificFilters . retrieve (
811- hostname ,
812- options . noSpecificCosmeticFiltering ? discardSets : retrieveSets ,
813- 1
814- ) ;
815- // Retrieve filters with a regex-based hostname value
816- this . specificFilters . retrieve (
817- hostname ,
818- options . noSpecificCosmeticFiltering ? discardSets : retrieveSets ,
819- 3
820- ) ;
774+ this . specificFilters . retrieveSpecifics ( allSet , hostname ) ;
821775 // Retrieve filters with a entity-based hostname value
822776 const entity = entityFromHostname ( hostname , request . domain ) ;
823- if ( entity !== '' ) {
824- this . specificFilters . retrieve (
825- entity ,
826- options . noSpecificCosmeticFiltering ? discardSets : retrieveSets ,
827- 1
828- ) ;
829- }
777+ this . specificFilters . retrieveSpecifics ( allSet , entity ) ;
778+ // Retrieve filters with a regex-based hostname value
779+ this . specificFilters . retrieveSpecificsByRegex ( allSet , hostname , request . url ) ;
830780 // Retrieve filters with an empty hostname
831- this . specificFilters . retrieve (
832- hostname ,
833- options . noGenericCosmeticFiltering ? discardSets : retrieveSets ,
834- 2
835- ) ;
781+ this . specificFilters . retrieveGenerics ( allSet ) ;
782+
783+ // Split filters in different groups
784+ const proceduralSet = new Set ( ) ;
785+ const exceptionSet = new Set ( ) ;
786+ for ( const s of allSet ) {
787+ const selector = s . slice ( 1 ) ;
788+ if ( s . charCodeAt ( 0 ) === 0x2D /* - */ ) {
789+ exceptionSet . add ( selector ) ;
790+ } else if ( selector . charCodeAt ( 0 ) === 0x7B /* { */ ) {
791+ proceduralSet . add ( selector ) ;
792+ } else {
793+ specificSet . add ( selector ) ;
794+ }
795+ }
836796
837797 // Apply exceptions to specific filterset
838798 if ( exceptionSet . size !== 0 ) {
@@ -855,12 +815,12 @@ CosmeticFilteringEngine.prototype.retrieveSpecificSelectors = function(
855815 // filters, so we extract and inject them immediately.
856816 if ( proceduralSet . size !== 0 ) {
857817 for ( const json of proceduralSet ) {
858- const pfilter = JSON . parse ( json ) ;
859818 if ( exceptionSet . has ( json ) ) {
860819 proceduralSet . delete ( json ) ;
861820 out . exceptedFilters . push ( json ) ;
862821 continue ;
863822 }
823+ const pfilter = JSON . parse ( json ) ;
864824 if ( exceptionSet . has ( pfilter . raw ) ) {
865825 proceduralSet . delete ( json ) ;
866826 out . exceptedFilters . push ( pfilter . raw ) ;
@@ -914,12 +874,6 @@ CosmeticFilteringEngine.prototype.retrieveSpecificSelectors = function(
914874 }
915875 }
916876 }
917-
918- // Important: always clear used registers before leaving.
919- specificSet . clear ( ) ;
920- proceduralSet . clear ( ) ;
921- exceptionSet . clear ( ) ;
922- dummySet . clear ( ) ;
923877 }
924878
925879 const details = {
0 commit comments