@@ -191,7 +191,7 @@ const FilterContainer = function() {
191191 this . rePlainSelectorEscaped = / ^ [ # . ] (?: \\ [ 0 - 9 A - F a - f ] + | \\ .| \w | - ) + / ;
192192 this . rePlainSelectorEx = / ^ [ ^ # . \[ ( ] + ( [ # . ] [ \w - ] + ) | ( [ # . ] [ \w - ] + ) $ / ;
193193 this . reEscapeSequence = / \\ ( [ 0 - 9 A - F a - f ] + | .) / g;
194- this . reSimpleHighGeneric1 = / ^ [ a - z ] * \[ [ ^ [ ] + ] $ / ;
194+ this . reSimpleHighGeneric = / ^ (?: [ a - z ] * \[ [ ^ \] ] + \] | \S + ) $ / ;
195195 this . reHighMedium = / ^ \[ h r e f \^ = " h t t p s ? : \/ \/ ( [ ^ " ] { 8 } ) [ ^ " ] * " \] $ / ;
196196
197197 this . selectorCache = new Map ( ) ;
@@ -274,8 +274,8 @@ FilterContainer.prototype.reset = function() {
274274 this . selectorCacheTimer = null ;
275275 }
276276
277- // generic filters
278- this . hasGenericHide = false ;
277+ // whether there is at least one surveyor-based filter
278+ this . needDOMSurveyor = false ;
279279
280280 // hostname, entity-based filters
281281 this . specificFilters . clear ( ) ;
@@ -301,13 +301,11 @@ FilterContainer.prototype.freeze = function() {
301301 this . duplicateBuster . clear ( ) ;
302302 this . specificFilters . collectGarbage ( ) ;
303303
304- this . hasGenericHide =
304+ this . needDOMSurveyor =
305305 this . lowlyGeneric . id . simple . size !== 0 ||
306306 this . lowlyGeneric . id . complex . size !== 0 ||
307307 this . lowlyGeneric . cl . simple . size !== 0 ||
308- this . lowlyGeneric . cl . complex . size !== 0 ||
309- this . highlyGeneric . simple . dict . size !== 0 ||
310- this . highlyGeneric . complex . dict . size !== 0 ;
308+ this . lowlyGeneric . cl . complex . size !== 0 ;
311309
312310 this . highlyGeneric . simple . str = Array . from ( this . highlyGeneric . simple . dict ) . join ( ',\n' ) ;
313311 this . highlyGeneric . simple . mru . reset ( ) ;
@@ -333,8 +331,8 @@ FilterContainer.prototype.keyFromSelector = function(selector) {
333331 matches = this . rePlainSelectorEscaped . exec ( selector ) ;
334332 if ( matches === null ) { return ; }
335333 key = '' ;
336- let escaped = matches [ 0 ] ,
337- beg = 0 ;
334+ const escaped = matches [ 0 ] ;
335+ let beg = 0 ;
338336 this . reEscapeSequence . lastIndex = 0 ;
339337 for ( ; ; ) {
340338 matches = this . reEscapeSequence . exec ( escaped ) ;
@@ -402,22 +400,19 @@ FilterContainer.prototype.compileGenericHideSelector = function(
402400 const type = selector . charCodeAt ( 0 ) ;
403401 let key ;
404402
403+ // Simple selector-based CSS rule: no need to test for whether the
404+ // selector is valid, the regex took care of this. Most generic selector
405+ // falls into that category:
406+ // - ###ad-bigbox
407+ // - ##.ads-bigbox
405408 if ( type === 0x23 /* '#' */ ) {
406409 key = this . keyFromSelector ( selector ) ;
407- // Simple selector-based CSS rule: no need to test for whether the
408- // selector is valid, the regex took care of this. Most generic
409- // selector falls into that category.
410- // - ###ad-bigbox
411410 if ( key === selector ) {
412411 writer . push ( [ 0 , key . slice ( 1 ) ] ) ;
413412 return ;
414413 }
415414 } else if ( type === 0x2E /* '.' */ ) {
416415 key = this . keyFromSelector ( selector ) ;
417- // Simple selector-based CSS rule: no need to test for whether the
418- // selector is valid, the regex took care of this. Most generic
419- // selector falls into that category.
420- // - ##.ads-bigbox
421416 if ( key === selector ) {
422417 writer . push ( [ 2 , key . slice ( 1 ) ] ) ;
423418 return ;
@@ -484,12 +479,7 @@ FilterContainer.prototype.compileGenericHideSelector = function(
484479 // For efficiency purpose, we will distinguish between simple and complex
485480 // selectors.
486481
487- if ( this . reSimpleHighGeneric1 . test ( selector ) ) {
488- writer . push ( [ 4 /* simple */ , selector ] ) ;
489- return ;
490- }
491-
492- if ( selector . indexOf ( ' ' ) === - 1 ) {
482+ if ( this . reSimpleHighGeneric . test ( selector ) ) {
493483 writer . push ( [ 4 /* simple */ , selector ] ) ;
494484 } else {
495485 writer . push ( [ 5 /* complex */ , selector ] ) ;
@@ -551,10 +541,13 @@ FilterContainer.prototype.compileSpecificSelector = function(
551541
552542 let kind = 0 ;
553543 if ( unhide === 1 ) {
554- kind |= 0b01 ; // Exception
544+ kind |= 0b001 ; // Exception
555545 }
556546 if ( compiled . charCodeAt ( 0 ) === 0x7B /* '{' */ ) {
557- kind |= 0b10 ; // Procedural
547+ kind |= 0b010 ; // Procedural
548+ }
549+ if ( hostname === '*' ) {
550+ kind |= 0b100 ; // Applies everywhere
558551 }
559552
560553 writer . push ( [ 8 , hostname , kind , compiled ] ) ;
@@ -637,8 +630,21 @@ FilterContainer.prototype.fromCompiledContent = function(reader, options) {
637630
638631 // hash, example.com, .promoted-tweet
639632 // hash, example.*, .promoted-tweet
633+ //
634+ // https://github.com/uBlockOrigin/uBlock-issues/issues/803
635+ // Handle specific filters meant to apply everywhere, i.e. selectors
636+ // not to be injected conditionally through the DOM surveyor.
637+ // hash, *, .promoted-tweet
640638 case 8 :
641- this . specificFilters . store ( args [ 1 ] , args [ 2 ] , args [ 3 ] ) ;
639+ if ( args [ 2 ] === 0b100 ) {
640+ if ( this . reSimpleHighGeneric . test ( args [ 3 ] ) )
641+ this . highlyGeneric . simple . dict . add ( args [ 3 ] ) ;
642+ else {
643+ this . highlyGeneric . complex . dict . add ( args [ 3 ] ) ;
644+ }
645+ break ;
646+ }
647+ this . specificFilters . store ( args [ 1 ] , args [ 2 ] & 0b011 , args [ 3 ] ) ;
642648 break ;
643649
644650 default :
@@ -666,11 +672,21 @@ FilterContainer.prototype.skipGenericCompiledContent = function(reader) {
666672
667673 switch ( args [ 0 ] ) {
668674
669- // hash, example.com, .promoted-tweet
670- // hash, example.*, .promoted-tweet
675+ // https://github.com/uBlockOrigin/uBlock-issues/issues/803
676+ // Handle specific filters meant to apply everywhere, i.e. selectors
677+ // not to be injected conditionally through the DOM surveyor.
678+ // hash, *, .promoted-tweet
671679 case 8 :
672680 this . duplicateBuster . add ( fingerprint ) ;
673- this . specificFilters . store ( args [ 1 ] , args [ 2 ] , args [ 3 ] ) ;
681+ if ( args [ 2 ] === 0b100 ) {
682+ if ( this . reSimpleHighGeneric . test ( args [ 3 ] ) )
683+ this . highlyGeneric . simple . dict . add ( args [ 3 ] ) ;
684+ else {
685+ this . highlyGeneric . complex . dict . add ( args [ 3 ] ) ;
686+ }
687+ break ;
688+ }
689+ this . specificFilters . store ( args [ 1 ] , args [ 2 ] & 0b011 , args [ 3 ] ) ;
674690 break ;
675691
676692 default :
@@ -699,7 +715,6 @@ FilterContainer.prototype.toSelfie = function() {
699715 acceptedCount : this . acceptedCount ,
700716 discardedCount : this . discardedCount ,
701717 specificFilters : this . specificFilters . toSelfie ( ) ,
702- hasGenericHide : this . hasGenericHide ,
703718 lowlyGenericSID : Array . from ( this . lowlyGeneric . id . simple ) ,
704719 lowlyGenericCID : Array . from ( this . lowlyGeneric . id . complex ) ,
705720 lowlyGenericSCL : Array . from ( this . lowlyGeneric . cl . simple ) ,
@@ -715,7 +730,6 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
715730 this . acceptedCount = selfie . acceptedCount ;
716731 this . discardedCount = selfie . discardedCount ;
717732 this . specificFilters . fromSelfie ( selfie . specificFilters ) ;
718- this . hasGenericHide = selfie . hasGenericHide ;
719733 this . lowlyGeneric . id . simple = new Set ( selfie . lowlyGenericSID ) ;
720734 this . lowlyGeneric . id . complex = new Map ( selfie . lowlyGenericCID ) ;
721735 this . lowlyGeneric . cl . simple = new Set ( selfie . lowlyGenericSCL ) ;
@@ -724,6 +738,11 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
724738 this . highlyGeneric . simple . str = selfie . highSimpleGenericHideArray . join ( ',\n' ) ;
725739 this . highlyGeneric . complex . dict = new Set ( selfie . highComplexGenericHideArray ) ;
726740 this . highlyGeneric . complex . str = selfie . highComplexGenericHideArray . join ( ',\n' ) ;
741+ this . needDOMSurveyor =
742+ selfie . lowlyGenericSID . length !== 0 ||
743+ selfie . lowlyGenericCID . length !== 0 ||
744+ selfie . lowlyGenericSCL . length !== 0 ||
745+ selfie . lowlyGenericCCL . length !== 0 ;
727746 this . frozen = true ;
728747} ;
729748
@@ -986,7 +1005,7 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
9861005 highGenericHideComplex : '' ,
9871006 injectedHideFilters : '' ,
9881007 networkFilters : '' ,
989- noDOMSurveying : this . hasGenericHide === false ,
1008+ noDOMSurveying : this . needDOMSurveyor === false ,
9901009 proceduralFilters : [ ]
9911010 } ;
9921011
0 commit comments