8000 [mv3] Improve generic cosmetic filtering · gorhill/uBlock@a009623 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit a009623

Browse files
committed
[mv3] Improve generic cosmetic filtering
Specifically, properly exclude generic cosmetic filters according to specific cosmetic exceptions. Related issue: uBlockOrigin/uBOL-home#181
1 parent 22fdf8f commit a009623

12 files changed

+415
-416
lines changed

platform/mv3/extension/js/scripting-manager.js

+4
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ function registerGeneric(context, genericDetails) {
179179

180180
if ( js.length === 0 ) { return; }
181181

182+
js.unshift('/js/scripting/isolated-api.js');
182183
js.push('/js/scripting/css-generic.js');
183184

184185
const { none, basic, optimal, complete } = filteringModeDetails;
@@ -252,6 +253,7 @@ function registerProcedural(context 1E11 ) {
252253
];
253254
if ( matches.length === 0 ) { return; }
254255

256+
js.unshift('/js/scripting/isolated-api.js');
255257
js.push('/js/scripting/css-procedural.js');
256258

257259
const excludeMatches = [];
@@ -311,6 +313,7 @@ function registerDeclarative(context) {
311313
];
312314
if ( matches.length === 0 ) { return; }
313315

316+
js.unshift('/js/scripting/isolated-api.js');
314317
js.push('/js/scripting/css-declarative.js');
315318

316319
const excludeMatches = [];
@@ -370,6 +373,7 @@ function registerSpecific(context) {
370373
];
371374
if ( matches.length === 0 ) { return; }
372375

376+
js.unshift('/js/scripting/isolated-api.js');
373377
js.push('/js/scripting/css-specific.js');
374378

375379
const excludeMatches = [];

platform/mv3/extension/js/scripting/css-declarative.js

+31-62
Original file line numberDiff line numberDiff line change
@@ -27,73 +27,41 @@
2727

2828
const declarativeImports = self.declarativeImports || [];
2929
self.declarativeImports = undefined;
30-
delete self.declarativeImports;
3130

3231
/******************************************************************************/
3332

34-
const hnParts = [];
35-
try { hnParts.push(...document.location.hostname.split('.')); }
36-
catch { }
37-
const hnpartslen = hnParts.length;
38-
if ( hnpartslen === 0 ) { return; }
39-
4033
const selectors = [];
41-
42-
for ( const { argsList, exceptionsMap, hostnamesMap, entitiesMap } of declarativeImports ) {
43-
const todoIndices = new Set();
44-
const tonotdoIndices = [];
45-
// Exceptions
46-
if ( exceptionsMap.size !== 0 ) {
47-
for ( let i = 0; i < hnpartslen; i++ ) {
48-
const hn = hnParts.slice(i).join('.');
49-
const excepted = exceptionsMap.get(hn);
50-
if ( excepted ) { tonotdoIndices.push(...excepted); }
51-
}
52-
exceptionsMap.clear();
53-
}
54-
// Hostname-based
55-
if ( hostnamesMap.size !== 0 ) {
56-
const collectArgIndices = hn => {
57-
let argsIndices = hostnamesMap.get(hn);
58-
if ( argsIndices === undefined ) { return; }
59-
if ( typeof argsIndices === 'number' ) { argsIndices = [ argsIndices ]; }
60-
for ( const argsIndex of argsIndices ) {
61-
if ( tonotdoIndices.includes(argsIndex) ) { continue; }
62-
todoIndices.add(argsIndex);
63-
}
64-
};
65-
for ( let i = 0; i < hnpartslen; i++ ) {
66-
const hn = hnParts.slice(i).join('.');
67-
collectArgIndices(hn);
68-
}
69-
collectArgIndices('*');
70-
hostnamesMap.clear();
71-
}
72-
// Entity-based
73-
10000 if ( entitiesMap.size !== 0 ) {
74-
const n = hnpartslen - 1;
75-
for ( let i = 0; i < n; i++ ) {
76-
for ( let j = n; j > i; j-- ) {
77-
const en = hnParts.slice(i,j).join('.');
78-
let argsIndices = entitiesMap.get(en);
79-
if ( argsIndices === undefined ) { continue; }
80-
if ( typeof argsIndices === 'number' ) { argsIndices = [ argsIndices ]; }
81-
for ( const argsIndex of argsIndices ) {
82-
if ( tonotdoIndices.includes(argsIndex) ) { continue; }
83-
todoIndices.add(argsIndex);
84-
}
85-
}
86-
}
87-
entitiesMap.clear();
34+
const exceptions = [];
35+
36+
const lookupHostname = (hostname, details, out) => {
37+
let seqi = details.hostnamesMap.get(hostname);
38+
if ( seqi === undefined ) { return; }
39+
const { argsList, argsSeqs } = details;
40+
for (;;) {
41+
const argi = argsSeqs[seqi++];
42+
const done = argi > 0;
43+
out.push(...argsList[done ? argi : -argi].split('\n'));
44+
if ( done ) { break; }
8845
}
89-
for ( const i of todoIndices ) {
90-
selectors.push(...argsList[i].map(json => JSON.parse(json)));
46+
};
47+
48+
const lookupAll = hostname => {
49+
for ( const details of declarativeImports ) {
50+
lookupHostname(hostname, details, selectors);
51+
lookupHostname(`~${hostname}`, details, exceptions);
9152
}
92-
argsList.length = 0;
93-
}
53+
};
54+
55+
self.isolatedAPI.forEachHostname(lookupAll, {
56+
hasEntities: declarativeImports.some(a => a.hasEntities)
57+
});
58+
9459
declarativeImports.length = 0;
9560

96-
if ( selectors.length === 0 ) { return; }
61+
const exceptedSelectors = exceptions.length !== 0
62+
? selectors.filter(a => exceptions.includes(a) === false)
63+
: selectors;
64+
if ( exceptedSelectors.length === 0 ) { return; }
9765

9866
/******************************************************************************/
9967

@@ -126,8 +94,9 @@ const cssRuleFromProcedural = details => {
12694
};
12795

12896
const sheetText = [];
129-
for ( const selector of selectors ) {
130-
const ruleText = cssRuleFromProcedural(selector);
97+
for ( const selector of exceptedSelectors ) {
98+
const details = JSON.parse(selector);
99+
const ruleText = cssRuleFromProcedural(details);
131100
if ( ruleText === undefined ) { continue; }
132101
sheetText.push(ruleText);
133102
}
@@ -138,7 +107,7 @@ if ( sheetText.length === 0 ) { return; }
138107
chrome.runtime.sendMessage({ what: 'insertCSS', css }).catch(( ) => {
139108
count -= 1;
140109
if ( count === 0 ) { return; }
141-
uBOL_injectCSS(css, count - 1);
110+
uBOL_injectCSS(css, count);
142111
});
143112
})(sheetText.join('\n'));
144113

platform/mv3/extension/js/scripting/css-generic.js

+30-17
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
(function uBOL_cssGeneric() {
2727

2828
const genericSelectorMap = self.genericSelectorMap || new Map();
29-
delete self.genericSelectorMap;
30-
29+
self.genericSelectorMap = undefined;
3130
if ( genericSelectorMap.size === 0 ) { return; }
3231

32+
const genericExceptionMap = self.genericExceptionMap || new Map();
33+
self.genericExceptionMap = undefined;
34+
3335
/******************************************************************************/
3436

3537
const maxSurveyTimeSlice = 4;
@@ -76,6 +78,7 @@ const uBOL_idFromNode = (node, out) => {
7678
const selectorList = genericSelectorMap.get(hash);
7779
if ( selectorList === undefined ) { return; }
7880
genericSelectorMap.delete(hash);
81+
if ( isExcepted(hash) ) { return; }
7982
out.push(selectorList);
8083
};
8184

@@ -96,10 +99,20 @@ const uBOL_classesFromNode = (node, out) => {
9699
const selectorList = genericSelectorMap.get(hash);
97100
if ( selectorList === undefined ) { continue; }
98101
genericSelectorMap.delete(hash);
102+
if ( isExcepted(hash) ) { continue; }
99103
out.push(selectorList);
100104
}
101105
};
102106

107+
const isExcepted = hash => {
108+
const hostnames = genericExceptionMap.get(hash);
109+
if ( hostnames === undefined ) { return; }
110+
const hasEntities = hostnames.includes('.*');
111+
return self.isolatedAPI.forEachHostname((hostname) => {
112+
if ( hostnames.includes(` ${hostname} `) ) { return true; }
113+
}, { hasEntities });
114+
}
115+
103116
/******************************************************************************/
104117

105118
const pendingNodes = {
@@ -191,12 +204,26 @@ const uBOL_injectCSS = (css, count = 10) => {
191204
chrome.runtime.sendMessage({ what: 'insertCSS', css }).catch(( ) => {
192205
count -= 1;
193206
if ( count === 0 ) { return; }
194-
uBOL_injectCSS(css, count - 1);
207+
uBOL_injectCSS(css, count);
195208
});
196209
};
197210

198211
/******************************************************************************/
199212

213+
const stopAll = reason => {
214+
if ( domChangeTimer !== undefined ) {
215+
self.clearTimeout(domChangeTimer);
216+
domChangeTimer = undefined;
217+
}
218+
domMutationObserver.disconnect();
219+
domMutationObserver.takeRecords();
220+
domMutationObserver = undefined;
221+
genericSelectorMap.clear();
222+
console.info(`uBOL: Generic cosmetic filtering stopped because ${reason}`);
223+
};
224+
225+
/******************************************************************************/
226+
200227
pendingNodes.add(document);
201228
uBOL_processNodes();
202229

@@ -219,20 +246,6 @@ needDomChangeObserver();
219246

220247
/******************************************************************************/
221248

222-
const stopAll = reason => {
223-
if ( domChangeTimer !== undefined ) {
224-
self.clearTimeout(domChangeTimer);
225-
domChangeTimer = undefined;
226-
}
227-
domMutationObserver.disconnect();
228-
domMutationObserver.takeRecords();
229-
domMutationObserver = undefined;
230-
genericSelectorMap.clear();
231-
console.info(`uBOL: Generic cosmetic filtering stopped because ${reason}`);
232-
};
233-
234-
/******************************************************************************/
235-
236249
})();
237250

238251
/******************************************************************************/

platform/mv3/extension/js/scripting/css-procedural.js

+32-62
Original file line numberDiff line numberDiff line change
@@ -27,81 +27,49 @@
2727

2828
const proceduralImports = self.proceduralImports || [];
2929
self.proceduralImports = undefined;
30-
delete self.proceduralImports;
3130

3231
/******************************************************************************/
3332

34-
const hnParts = [];
35-
try { hnParts.push(...document.location.hostname.split('.')); }
36-
catch { }
37-
const hnpartslen = hnParts.length;
38-
if ( hnpartslen === 0 ) { return; }
39-
4033
const selectors = [];
41-
42-
for ( const { argsList, exceptionsMap, hostnamesMap, entitiesMap } of proceduralImports ) {
43-
const todoIndices = new Set();
44-
const tonotdoIndices = [];
45-
// Exceptions
46-
if ( exceptionsMap.size !== 0 ) {
47-
for ( let i = 0; i < hnpartslen; i++ ) {
48-
const hn = hnParts.slice(i).join('.');
49-
const excepted = exceptionsMap.get(hn);
50-
if ( excepted ) { tonotdoIndices.push(...excepted); }
51-
}
52-
exceptionsMap.clear();
53-
}
54-
// Hostname-based
55-
if ( hostnamesMap.size !== 0 ) {
56-
const collectArgIndices = hn => {
57-
let argsIndices = hostnamesMap.get(hn);
58-
if ( argsIndices === undefined ) { return; }
59-
if ( typeof argsIndices === 'number' ) { argsIndices = [ argsIndices ]; }
60-
for ( const argsIndex of argsIndices ) {
61-
if ( tonotdoIndices.includes(argsIndex) ) { continue; }
62-
todoIndices.add(argsIndex);
63-
}
64-
};
65-
for ( let i = 0; i < hnpartslen; i++ ) {
66-
const hn = hnParts.slice(i).join('.');
67-
collectArgIndices(hn);
68-
}
69-
collectArgIndices('*');
70-
hostnamesMap.clear();
71-
}
72-
// Entity-based
73-
if ( entitiesMap.size !== 0 ) {
74-
const n = hnpartslen - 1;
75-
for ( let i = 0; i < n; i++ ) {
76-
for ( let j = n; j > i; j-- ) {
77-
const en = hnParts.slice(i,j).join('.');
78-
let argsIndices = entitiesMap.get(en);
79-
if ( argsIndices === undefined ) { continue; }
80-
if ( typeof argsIndices === 'number' ) { argsIndices = [ argsIndices ]; }
81-
for ( const argsIndex of argsIndices ) {
82-
if ( tonotdoIndices.includes(argsIndex) ) { continue; }
83-
todoIndices.add(argsIndex);
84-
}
85-
}
86-
}
87-
entitiesMap.clear();
34+
const exceptions = [];
35+
36+
const lookupHostname = (hostname, details, out) => {
37+
let seqi = details.hostnamesMap.get(hostname);
38+
if ( seqi === undefined ) { return; }
39+
const { argsList, argsSeqs } = details;
40+
for (;;) {
41+
const argi = argsSeqs[seqi++];
42+
const done = argi > 0;
43+
out.push(...argsList[done ? argi : -argi]);
44+
if ( done ) { break; }
8845
}
89-
for ( const i of todoIndices ) {
90-
selectors.push(...argsList[i].map(json => JSON.parse(json)));
46+
};
47+
48+
const lookupAll = hostname => {
49+
for ( const details of proceduralImports ) {
50+
lookupHostname(hostname, details, selectors);
51+
lookupHostname(`~${hostname}`, details, exceptions);
9152
}
92-
argsList.length = 0;
93-
}
53+
};
54+
55+
self.isolatedAPI.forEachHostname(lookupAll, {
56+
hasEntities: proceduralImports.some(a => a.hasEntities)
57+
});
58+
9459
proceduralImports.length = 0;
9560

96-
if ( selectors.length === 0 ) { return; }
61+
const exceptedSelectors = exceptions.length !== 0
62+
? selectors.filter(a => exceptions.includes(a) === false)
63+
: selectors;
64+
if ( exceptedSelectors.length === 0 ) { return; }
9765

9866
/******************************************************************************/
9967

10068
const uBOL_injectCSS = (css, count = 10) => {
10169
chrome.runtime.sendMessage({ what: 'insertCSS', css }).catch(( ) => {
10270
count -= 1;
10371
if ( count === 0 ) { return; }
104-
uBOL_injectCSS(css, count - 1);
72+
uBOL_injectCSS(css, count);
10573
});
10674
};
10775

@@ -646,7 +614,7 @@ class ProceduralFilterer {
646614
this.uBOL_commitNow();
647615
}
648616

649-
addSelectors() {
617+
addSelectors(selectors) {
650618
for ( const selector of selectors ) {
651619
const pselector = new PSelectorRoot(selector);
652620
this.primeProceduralSelector(pselector);
@@ -787,7 +755,9 @@ class ProceduralFilterer {
787755

788756
/******************************************************************************/
789757

790-
const proceduralFilterer = new ProceduralFilterer(selectors);
758+
const proceduralFilterer = new ProceduralFilterer(
759+
exceptedSelectors.map(a => JSON.parse(a))
760+
);
791761

792762
const observer = new MutationObserver(mutations => {
793763
let domChanged = false;

0 commit comments

Comments
 (0)
0