Skip to content

Commit a23561d

Browse files
committed
[mv3] Bypass cosmetic filtering when top context is set to no-filtering
Related issue: uBlockOrigin/uBOL-home#20 Specific cosmetic filtering will be bypassed when hostname of top context matches an entry in the no-filtering set. This doesn't completely solve the issue: - The browser platform must support `document.location.ancestorOrigins` - This solution can't be applied to scriptlets
1 parent 92737bf commit a23561d

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

platform/mv3/extension/js/scripting/isolated-api.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
}).filter(a => a !== undefined);
4444
})();
4545

46+
isolatedAPI.topHostname = hostnameStack.at(-1)?.hnparts.join('.') ?? '';
47+
4648
const forEachHostname = (entry, callback, details) => {
4749
const hnparts = entry.hnparts;
4850
const hnpartslen = hnparts.length;
@@ -81,6 +83,9 @@
8183
if ( typeof api === 'object' ) { return; }
8284

8385
const cosmeticAPI = self.cosmeticAPI = {};
86+
const { isolatedAPI } = self;
87+
const { topHostname } = isolatedAPI;
88+
const thisHostname = document.location.hostname || '';
8489

8590
const sessionRead = async function(key) {
8691
try {
@@ -145,18 +150,29 @@
145150
const data = await localRead(`css.${realm}.${rulesetId}`);
146151
if ( typeof data !== 'object' || data === null ) { return; }
147152
data.result = result;
148-
self.isolatedAPI.forEachHostname(lookupHostname, data);
153+
isolatedAPI.forEachHostname(lookupHostname, data);
149154
};
150155

151156
const fillCache = async function(realm, rulesetIds) {
152157
const selectors = new Set();
153158
const exceptions = new Set();
154159
const result = { selectors, exceptions };
155-
await Promise.all(rulesetIds.map(a => selectorsFromRuleset(realm, a, result)));
160+
const [ filteringModeDetails ] = await Promise.all([
161+
localRead('filteringModeDetails'),
162+
...rulesetIds.map(a => selectorsFromRuleset(realm, a, result)),
163+
]);
164+
const skip = filteringModeDetails?.none.some(a => {
165+
if ( topHostname.endsWith(a) === false ) { return false; }
166+
const n = a.length;
167+
return topHostname.length === n || topHostname.at(-n-1) === '.';
168+
});
156169
for ( const selector of exceptions ) {
157170
selectors.delete(selector);
158171
}
159-
cacheEntry[cacheSlots[realm]] = Array.from(selectors).map(a =>
172+
if ( skip ) {
173+
selectors.clear();
174+
}
175+
cacheEntry[realm.charAt(0)] = Array.from(selectors).map(a =>
160176
a.startsWith('{') ? JSON.parse(a) : a
161177
);
162178
};
@@ -165,14 +181,14 @@
165181
cacheEntry = await sessionRead(cacheKey) || {};
166182
};
167183

168-
const cacheSlots = { 'specific': 's', 'procedural': 'p' };
169-
const cacheKey = `cache.css.${document.location.hostname || ''}`;
184+
const cacheKey =
185+
`cache.css.${thisHostname || ''}${topHostname !== thisHostname ? `/${topHostname}` : ''}`;
170186
let clientCount = 0;
171187
let cacheEntry;
172188

173189
cosmeticAPI.getSelectors = async function(realm, rulesetIds) {
174190
clientCount += 1;
175-
const slot = cacheSlots[realm];
191+
const slot = realm.charAt(0);
176192
if ( cacheEntry === undefined ) {
177193
cacheEntry = readCache();
178194
}

0 commit comments

Comments
 (0)