@@ -62,8 +62,8 @@ const SelectorCacheEntry = class {
62
62
}
63
63
64
64
addCosmetic ( details ) {
65
- let selectors = details . selectors ,
66
- i = selectors . length || 0 ;
65
+ const selectors = details . selectors ;
66
+ let i = selectors . length || 0 ;
67
67
// https://github.com/gorhill/uBlock/issues/2011
68
68
// Avoiding seemingly pointless surveys only if they appear costly.
69
69
if ( details . first && i === 0 ) {
@@ -90,8 +90,8 @@ const SelectorCacheEntry = class {
90
90
if ( this . net . size < SelectorCacheEntry . netHighWaterMark ) {
91
91
return ;
92
92
}
93
- let dict = this . net ;
94
- let keys = Array . from ( dict . keys ( ) ) . sort ( function ( a , b ) {
93
+ const dict = this . net ;
94
+ const keys = Array . from ( dict . keys ( ) ) . sort ( function ( a , b ) {
95
95
return dict . get ( b ) - dict . get ( a ) ;
96
96
} ) . slice ( SelectorCacheEntry . netLowWaterMark ) ;
97
97
let i = keys . length ;
@@ -146,7 +146,7 @@ const SelectorCacheEntry = class {
146
146
147
147
retrieve ( type , out ) {
148
148
this . lastAccessTime = Date . now ( ) ;
149
- let iterator = type === 'cosmetic' ? this . cosmetic : this . net . keys ( ) ;
149
+ const iterator = type === 'cosmetic' ? this . cosmetic : this . net . keys ( ) ;
150
150
if ( Array . isArray ( out ) ) {
151
151
this . retrieveToArray ( iterator , out ) ;
152
152
} else {
@@ -201,9 +201,6 @@ const FilterContainer = function() {
201
201
this . netSelectorCacheCountMax = SelectorCacheEntry . netHighWaterMark ;
202
202
this . selectorCacheTimer = null ;
203
203
204
- // generic exception filters
205
- this . genericDonthideSet = new Set ( ) ;
206
-
207
204
// specific filters
208
205
this . specificFilters = new µb . staticExtFilteringEngine . HostnameBasedDB ( 2 ) ;
209
206
@@ -269,9 +266,6 @@ FilterContainer.prototype.reset = function() {
269
266
// generic filters
270
267
this . hasGenericHide = false ;
271
268
272
- // generic exception filters
273
- this . genericDonthideSet . clear ( ) ;
274
-
275
269
// hostname, entity-based filters
276
270
this . specificFilters . clear ( ) ;
277
271
@@ -312,7 +306,6 @@ FilterContainer.prototype.freeze = function() {
312
306
this . frozen = true ;
313
307
} ;
314
308
315
-
316
309
/******************************************************************************/
317
310
318
311
// https://github.com/gorhill/uBlock/issues/1668
@@ -429,11 +422,17 @@ FilterContainer.prototype.compileGenericHideSelector = function(
429
422
// https://github.com/uBlockOrigin/uBlock-issues/issues/464
430
423
// Pseudoclass-based selectors can be compiled, but are also valid
431
424
// plain selectors.
425
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/131
426
+ // Support generic procedural filters as per advanced settings.
427
+ // TODO: prevent double compilation.
432
428
if (
433
429
compiled === undefined ||
434
430
compiled !== selector &&
435
431
µb . staticExtFilteringEngine . compileSelector . pseudoclass !== true
436
432
) {
433
+ if ( µb . hiddenSettings . allowGenericProceduralFilters === true ) {
434
+ return this . compileSpecificSelector ( '' , parsed , writer ) ;
435
+ }
437
436
const who = writer . properties . get ( 'assetKey' ) || '?' ;
438
437
µb . logger . writeOne ( {
439
438
realm : 'message' ,
@@ -450,8 +449,8 @@ FilterContainer.prototype.compileGenericHideSelector = function(
450
449
writer . push ( [
451
450
type === 0x23 /* '#' */ ? 1 : 3 ,
452
451
key . slice ( 1 ) ,
453
- selector ]
454
- ) ;
452
+ selector
453
+ ] ) ;
455
454
return ;
456
455
}
457
456
@@ -493,7 +492,7 @@ FilterContainer.prototype.compileGenericUnhideSelector = function(
493
492
writer
494
493
) {
495
494
// Procedural cosmetic filters are acceptable as generic exception filters.
496
- let compiled = µb . staticExtFilteringEngine . compileSelector ( parsed . suffix ) ;
495
+ const compiled = µb . staticExtFilteringEngine . compileSelector ( parsed . suffix ) ;
497
496
if ( compiled === undefined ) {
498
497
const who = writer . properties . get ( 'assetKey' ) || '?' ;
499
498
µb . logger . writeOne ( {
@@ -505,9 +504,12 @@ FilterContainer.prototype.compileGenericUnhideSelector = function(
505
504
}
506
505
507
506
// https://github.com/chrisaljoudi/uBlock/issues/497
508
- // All generic exception filters are put in the same bucket: they are
509
- // expected to be very rare.
510
- writer . push ( [ 7 /* g1 */ , compiled ] ) ;
507
+ // All generic exception filters are stored as hostname-based filter
508
+ // whereas the hostname is the empty string (which matches all
509
+ // hostnames). No distinction is made between declarative and
510
+ // procedural selectors, since they really exist only to cancel
511
+ // out other cosmetic filters.
512
+ writer . push ( [ 8 , '' , 0b01 , compiled ] ) ;
511
513
} ;
512
514
513
515
/******************************************************************************/
@@ -622,13 +624,6 @@ FilterContainer.prototype.fromCompiledContent = function(reader, options) {
622
624
this . highlyGeneric . complex . dict . add ( args [ 1 ] ) ;
623
625
break ;
624
626
625
- // https://github.com/chrisaljoudi/uBlock/issues/497
626
- // Generic exception filters: expected to be a rare occurrence.
627
- // #@#.tweet
628
- case 7 :
629
- this . genericDonthideSet . add ( args [ 1 ] ) ;
630
- break ;
631
-
632
627
// hash, example.com, .promoted-tweet
633
628
// hash, example.*, .promoted-tweet
634
629
case 8 :
@@ -660,13 +655,6 @@ FilterContainer.prototype.skipGenericCompiledContent = function(reader) {
660
655
661
656
switch ( args [ 0 ] ) {
662
657
663
- // https://github.com/chrisaljoudi/uBlock/issues/497
664
- // Generic exception filters: expected to be a rare occurrence.
665
- case 7 :
666
- this . duplicateBuster . add ( fingerprint ) ;
667
- this . genericDonthideSet . add ( args [ 1 ] ) ;
668
- break ;
669
-
670
658
// hash, example.com, .promoted-tweet
671
659
// hash, example.*, .promoted-tweet
672
660
case 8 :
@@ -707,7 +695,6 @@ FilterContainer.prototype.toSelfie = function() {
707
695
lowlyGenericCCL : Array . from ( this . lowlyGeneric . cl . complex ) ,
708
696
highSimpleGenericHideArray : Array . from ( this . highlyGeneric . simple . dict ) ,
709
697
highComplexGenericHideArray : Array . from ( this . highlyGeneric . complex . dict ) ,
710
- genericDonthideArray : Array . from ( this . genericDonthideSet )
711
698
} ;
712
699
} ;
713
700
@@ -726,7 +713,6 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
726
713
this . highlyGeneric . simple . str = selfie . highSimpleGenericHideArray . join ( ',\n' ) ;
727
714
this . highlyGeneric . complex . dict = new Set ( selfie . highComplexGenericHideArray ) ;
728
715
this . highlyGeneric . complex . str = selfie . highComplexGenericHideArray . join ( ',\n' ) ;
729
- this . genericDonthideSet = new Set ( selfie . genericDonthideArray ) ;
730
716
this . frozen = true ;
731
717
} ;
732
718
@@ -989,13 +975,6 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
989
975
} ;
990
976
991
977
if ( options . noCosmeticFiltering !== true ) {
992
- // Exception cosmetic filters: prime with generic exception filters.
993
- const exceptionSet = this . setRegister0 ;
994
- // Genetic exceptions (should be extremely rare).
995
- for ( let exception of this . genericDonthideSet ) {
996
- exceptionSet . add ( exception ) ;
997
- }
998
-
999
978
const specificSet = this . setRegister1 ;
1000
979
// Cached cosmetic filters: these are always declarative.
1001
980
if ( cacheEntry !== undefined ) {
@@ -1006,6 +985,7 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
1006
985
}
1007
986
}
1008
987
988
+ const exceptionSet = this . setRegister0 ;
1009
989
const proceduralSet = this . setRegister2 ;
1010
990
1011
991
this . specificFilters . retrieve (
0 commit comments