Skip to content

Commit 23c4c80

Browse files
committed
Add support for elemhide (through specifichide)
Related documentation: - https://help.eyeo.com/en/adblockplus/how-to-write-filters#element-hiding Related feedback/discussion: - https://www.reddit.com/r/uBlockOrigin/comments/d6vxzj/ The `elemhide` filter option as per ABP semantic is now supported. Previously uBO would consider `elemhide` to be an alias of `generichide`. The support of `elemhide` is through the convenient conversion of `elemhide` option into existing `generichide` option and new `specifichide` option. The purpose of the new `specifichide` filter option is to disable all specific cosmetic filters, i.e. those who target a specific site. Additionally, for convenience purpose, the filter options `generichide`, `specifichide` and `elemhide` can be aliased using the shorter forms `ghide`, `shide` and `ehide` respectively.
1 parent 6033ebf commit 23c4c80

File tree

9 files changed

+269
-141
lines changed

9 files changed

+269
-141
lines changed

‎src/js/background.js‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ if ( vAPI.webextFlavor === undefined ) {
3333

3434
/******************************************************************************/
3535

36-
const µBlock = (function() { // jshint ignore:line
36+
const µBlock = (( ) => { // jshint ignore:line
3737

3838
const hiddenSettingsDefault = {
3939
allowGenericProceduralFilters: false,
@@ -84,7 +84,7 @@ const µBlock = (function() { // jshint ignore:line
8484
requestLogMaxEntries: 1000,
8585
showIconBadge: true,
8686
tooltipsDisabled: false,
87-
webrtcIPAddressHidden: false
87+
webrtcIPAddressHidden: false,
8888
},
8989

9090
hiddenSettingsDefault: hiddenSettingsDefault,
@@ -133,22 +133,22 @@ const µBlock = (function() { // jshint ignore:line
133133

134134
localSettings: {
135135
blockedRequestCount: 0,
136-
allowedRequestCount: 0
136+
allowedRequestCount: 0,
137137
},
138138
localSettingsLastModified: 0,
139139
localSettingsLastSaved: 0,
140140

141141
// Read-only
142142
systemSettings: {
143-
compiledMagic: 18, // Increase when compiled format changes
144-
selfieMagic: 18 // Increase when selfie format changes
143+
compiledMagic: 19, // Increase when compiled format changes
144+
selfieMagic: 19, // Increase when selfie format changes
145145
},
146146

147147
restoreBackupSettings: {
148148
lastRestoreFile: '',
149149
lastRestoreTime: 0,
150150
lastBackupFile: '',
151-
lastBackupTime: 0
151+
lastBackupTime: 0,
152152
},
153153

154154
commandShortcuts: new Map(),

‎src/js/cosmetic-filtering.js‎

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/******************************************************************************/
2525

26-
µBlock.cosmeticFilteringEngine = (function(){
26+
µBlock.cosmeticFilteringEngine = (( ) => {
2727

2828
/******************************************************************************/
2929

@@ -238,10 +238,12 @@ const FilterContainer = function() {
238238
// is to prevent repeated allocation/deallocation overheads -- the
239239
// constructors/destructors of javascript Set/Map is assumed to be costlier
240240
// than just calling clear() on these.
241-
this.setRegister0 = new Set();
242-
this.setRegister1 = new Set();
243-
this.setRegister2 = new Set();
244-
this.mapRegister0 = new Map();
241+
this.simpleSet$ = new Set();
242+
this.complexSet$ = new Set();
243+
this.specificSet$ = new Set();
244+
this.exceptionSet$ = new Set();
245+
this.proceduralSet$ = new Set();
246+
this.dummySet$ = new Set();
245247

246248
this.reset();
247249
};
@@ -830,11 +832,11 @@ FilterContainer.prototype.retrieveGenericSelectors = function(request) {
830832

831833
//console.time('cosmeticFilteringEngine.retrieveGenericSelectors');
832834

833-
const simpleSelectors = this.setRegister0;
834-
const complexSelectors = this.setRegister1;
835+
const simpleSelectors = this.simpleSet$;
836+
const complexSelectors = this.complexSet$;
835837

836838
const cacheEntry = this.selectorCache.get(request.hostname);
837-
const previousHits = cacheEntry && cacheEntry.cosmetic || this.setRegister2;
839+
const previousHits = cacheEntry && cacheEntry.cosmetic || this.dummySet$;
838840

839841
for ( const type in this.lowlyGeneric ) {
840842
const entry = this.lowlyGeneric[type];
@@ -891,6 +893,10 @@ FilterContainer.prototype.retrieveGenericSelectors = function(request) {
891893
excepted,
892894
};
893895

896+
// Important: always clear used registers before leaving.
897+
simpleSelectors.clear();
898+
complexSelectors.clear();
899+
894900
// Cache and inject (if user stylesheets supported) looked-up low generic
895901
// cosmetic filters.
896902
if (
@@ -931,10 +937,6 @@ FilterContainer.prototype.retrieveGenericSelectors = function(request) {
931937
});
932938
}
933939

934-
// Important: always clear used registers before leaving.
935-
this.setRegister0.clear();
936-
this.setRegister1.clear();
937-
938940
//console.timeEnd('cosmeticFilteringEngine.retrieveGenericSelectors');
939941

940942
return out;
@@ -946,8 +948,6 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
946948
request,
947949
options
948950
) {
949-
//console.time('cosmeticFilteringEngine.retrieveSpecificSelectors');
950-
951951
const hostname = request.hostname;
952952
const cacheEntry = this.selectorCache.get(hostname);
953953

@@ -976,7 +976,11 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
976976
};
977977

978978
if ( options.noCosmeticFiltering !== true ) {
979-
const specificSet = this.setRegister1;
979+
const specificSet = this.specificSet$;
980+
const proceduralSet = this.proceduralSet$;
981+
const exceptionSet = this.exceptionSet$;
982+
const dummySet = this.dummySet$;
983+
980984
// Cached cosmetic filters: these are always declarative.
981985
if ( cacheEntry !== undefined ) {
982986
cacheEntry.retrieve('cosmetic', specificSet);
@@ -986,17 +990,30 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
986990
}
987991
}
988992

989-
const exceptionSet = this.setRegister0;
990-
const proceduralSet = this.setRegister2;
991-
993+
// Retrieve filters with a non-empty hostname
992994
this.specificFilters.retrieve(
993995
hostname,
994-
[ specificSet, exceptionSet, proceduralSet, exceptionSet ]
996+
options.noSpecificCosmeticFiltering !== true
997+
? [ specificSet, exceptionSet, proceduralSet, exceptionSet ]
998+
: [ dummySet, exceptionSet, dummySet, exceptionSet ],
999+
1
9951000
);
1001+
// Retrieve filters with an empty hostname
1002+
this.specificFilters.retrieve(
1003+
hostname,
1004+
options.noGenericCosmeticFiltering !== true
1005+
? [ specificSet, exceptionSet, proceduralSet, exceptionSet ]
1006+
: [ dummySet, exceptionSet, dummySet, exceptionSet ],
1007+
2
1008+
);
1009+
// Retrieve filters with a non-empty entity
9961010
if ( request.entity !== '' ) {
9971011
this.specificFilters.retrieve(
9981012
`${hostname.slice(0, -request.domain.length)}${request.entity}`,
999-
[ specificSet, exceptionSet, proceduralSet, exceptionSet ]
1013+
options.noSpecificCosmeticFiltering !== true
1014+
? [ specificSet, exceptionSet, proceduralSet, exceptionSet ]
1015+
: [ dummySet, exceptionSet, dummySet, exceptionSet ],
1016+
1
10001017
);
10011018
}
10021019

@@ -1060,9 +1077,10 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
10601077
}
10611078

10621079
// Important: always clear used registers before leaving.
1063-
this.setRegister0.clear();
1064-
this.setRegister1.clear();
1065-
this.setRegister2.clear();
1080+
specificSet.clear();
1081+
proceduralSet.clear();
1082+
exceptionSet.clear();
1083+
dummySet.clear();
10661084
}
10671085

10681086
// CSS selectors for collapsible blocked elements
@@ -1115,8 +1133,6 @@ FilterContainer.prototype.retrieveSpecificSelectors = function(
11151133
}
11161134
}
11171135

1118-
//console.timeEnd('cosmeticFilteringEngine.retrieveSpecificSelectors');
1119-
11201136
return out;
11211137
};
11221138

0 commit comments

Comments
 (0)