mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
[mv3] Fix equality test between two rulesets
Related issue: https://github.com/uBlockOrigin/uBOL-home/issues/591
This commit is contained in:
parent
61f30ea1fb
commit
222f4fbbc1
7 changed files with 133 additions and 90 deletions
|
|
@ -55,8 +55,6 @@ import {
|
|||
|
||||
import {
|
||||
broadcastMessage,
|
||||
gotoURL,
|
||||
hasBroadHostPermissions,
|
||||
hostnameFromMatch,
|
||||
hostnamesFromMatches,
|
||||
} from './utils.js';
|
||||
|
|
@ -101,6 +99,11 @@ import {
|
|||
ubolLog,
|
||||
} from './debug.js';
|
||||
|
||||
import {
|
||||
gotoURL,
|
||||
hasBroadHostPermissions,
|
||||
} from './ext-utils.js';
|
||||
|
||||
import { dnr } from './ext-compat.js';
|
||||
import { toggleToolbarIcon } from './action.js';
|
||||
|
||||
|
|
@ -662,12 +665,14 @@ async function startSession() {
|
|||
}
|
||||
|
||||
// Permissions may have been removed while the extension was disabled
|
||||
await syncWithBrowserPermissions();
|
||||
const permissionsUpdated = await syncWithBrowserPermissions();
|
||||
|
||||
// Unsure whether the browser remembers correctly registered css/scripts
|
||||
// after we quit the browser. For now uBOL will check unconditionally at
|
||||
// launch time whether content css/scripts are properly registered.
|
||||
registerInjectables();
|
||||
if ( isNewVersion || permissionsUpdated ) {
|
||||
registerInjectables();
|
||||
}
|
||||
|
||||
// Cosmetic filtering-related content scripts cache fitlering data in
|
||||
// session storage.
|
||||
|
|
|
|||
|
|
@ -19,21 +19,13 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
import { deepEquals } from './utils.js';
|
||||
|
||||
export const webext = self.browser || self.chrome;
|
||||
export const dnr = webext.declarativeNetRequest || {};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const ruleCompare = (a, b) => a.id - b.id;
|
||||
|
||||
const isSameRules = (a, b) => {
|
||||
a.sort(ruleCompare);
|
||||
b.sort(ruleCompare);
|
||||
return JSON.stringify(a) === JSON.stringify(b);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
export function normalizeDNRRules(rules, ruleIds) {
|
||||
if ( Array.isArray(rules) === false ) { return rules; }
|
||||
return Array.isArray(ruleIds)
|
||||
|
|
@ -85,19 +77,23 @@ dnr.setAllowAllRules = async function(id, allowed, notAllowed, reverse, priority
|
|||
}
|
||||
addSessionRules.push(rule1);
|
||||
}
|
||||
if ( isSameRules(addDynamicRules, beforeDynamicRules) ) { return false; }
|
||||
return Promise.all([
|
||||
dnr.updateDynamicRules({
|
||||
addRules: addDynamicRules,
|
||||
removeRuleIds: beforeDynamicRules.map(r => r.id),
|
||||
}),
|
||||
dnr.updateSessionRules({
|
||||
addRules: addSessionRules,
|
||||
removeRuleIds: beforeSessionRules.map(r => r.id),
|
||||
}),
|
||||
]).then(( ) =>
|
||||
true
|
||||
).catch(( ) =>
|
||||
false
|
||||
);
|
||||
const promises = [];
|
||||
const modified = deepEquals(addDynamicRules, beforeDynamicRules) === false;
|
||||
if ( modified ) {
|
||||
promises.push(
|
||||
dnr.updateDynamicRules({
|
||||
addRules: addDynamicRules,
|
||||
removeRuleIds: beforeDynamicRules.map(r => r.id),
|
||||
})
|
||||
);
|
||||
}
|
||||
if ( deepEquals(addSessionRules, beforeSessionRules) === false ) {
|
||||
promises.push(
|
||||
dnr.updateSessionRules({
|
||||
addRules: addSessionRules,
|
||||
removeRuleIds: beforeSessionRules.map(r => r.id),
|
||||
})
|
||||
);
|
||||
}
|
||||
return Promise.all(promises).then(( ) => modified).catch(( ) => false);
|
||||
};
|
||||
|
|
|
|||
68
platform/mv3/extension/js/ext-utils.js
Normal file
68
platform/mv3/extension/js/ext-utils.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock Origin Lite - a comprehensive, MV3-compliant content blocker
|
||||
Copyright (C) 2022-present Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
import {
|
||||
browser,
|
||||
runtime,
|
||||
} from './ext.js';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions#requested_permissions_and_user_prompts
|
||||
// "Users can grant or revoke host permissions on an ad hoc basis. Therefore,
|
||||
// most browsers treat host_permissions as optional."
|
||||
|
||||
export async function hasBroadHostPermissions() {
|
||||
return browser.permissions.getAll().then(permissions =>
|
||||
permissions.origins.includes('<all_urls>') ||
|
||||
permissions.origins.includes('*://*/*')
|
||||
).catch(( ) => false);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
export async function gotoURL(url, type) {
|
||||
const pageURL = new URL(url, runtime.getURL('/'));
|
||||
const tabs = await browser.tabs.query({
|
||||
url: pageURL.href,
|
||||
windowType: type !== 'popup' ? 'normal' : 'popup'
|
||||
});
|
||||
|
||||
if ( Array.isArray(tabs) && tabs.length !== 0 ) {
|
||||
const { windowId, id } = tabs[0];
|
||||
return Promise.all([
|
||||
browser.windows.update(windowId, { focused: true }),
|
||||
browser.tabs.update(id, { active: true }),
|
||||
]);
|
||||
}
|
||||
|
||||
if ( type === 'popup' ) {
|
||||
return browser.windows.create({
|
||||
type: 'popup',
|
||||
url: pageURL.href,
|
||||
});
|
||||
}
|
||||
|
||||
return browser.tabs.create({
|
||||
active: true,
|
||||
url: pageURL.href,
|
||||
});
|
||||
}
|
||||
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
import {
|
||||
broadcastMessage,
|
||||
hasBroadHostPermissions,
|
||||
hostnamesFromMatches,
|
||||
isDescendantHostnameOfIter,
|
||||
toBroaderHostname,
|
||||
|
|
@ -40,6 +39,8 @@ import {
|
|||
|
||||
import { adminReadEx } from './admin.js';
|
||||
import { filteringModesToDNR } from './ruleset-manager.js';
|
||||
import { hasBroadHostPermissions } from './ext-utils.js';
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import { ubolErr, ubolLog } from './debug.js';
|
|||
import { dnr } from './ext-compat.js';
|
||||
import { fetchJSON } from './fetch.js';
|
||||
import { getAdminRulesets } from './admin.js';
|
||||
import { hasBroadHostPermissions } from './utils.js';
|
||||
import { hasBroadHostPermissions } from './ext-utils.js';
|
||||
import { rulesFromText } from './dnr-parser.js';
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -19,11 +19,6 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
import {
|
||||
browser,
|
||||
runtime,
|
||||
} from './ext.js';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function parsedURLromOrigin(origin) {
|
||||
|
|
@ -135,53 +130,40 @@ export const hostnamesFromMatches = origins => {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
const broadcastMessage = message => {
|
||||
const bc = new self.BroadcastChannel('uBOL');
|
||||
bc.postMessage(message);
|
||||
export const deepEquals = (a, b) => {
|
||||
switch ( typeof a ) {
|
||||
case 'undefined':
|
||||
case 'boolean':
|
||||
case 'number':
|
||||
case 'string':
|
||||
return a === b;
|
||||
}
|
||||
// case 'object':
|
||||
if ( typeof b !== 'object' ) { return false; }
|
||||
if ( a === null || b === null ) { return a === b; }
|
||||
if ( Array.isArray(a) || Array.isArray(b) ) {
|
||||
if ( Array.isArray(a) === false || Array.isArray(b) === false ) { return false; }
|
||||
if ( a.length !== b.length ) { return false; }
|
||||
for ( let i = 0; i < a.length; i++ ) {
|
||||
if ( deepEquals(a[i], b[i]) === false ) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const akeys = Object.keys(a);
|
||||
const bkeys = Object.keys(b);
|
||||
if ( akeys.length !== bkeys.length ) { return false; }
|
||||
for ( const k of akeys ) {
|
||||
if ( deepEquals(a[k], b[k]) === false ) { return false; }
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions#requested_permissions_and_user_prompts
|
||||
// "Users can grant or revoke host permissions on an ad hoc basis. Therefore,
|
||||
// most browsers treat host_permissions as optional."
|
||||
|
||||
async function hasBroadHostPermissions() {
|
||||
return browser.permissions.getAll().then(permissions =>
|
||||
permissions.origins.includes('<all_urls>') ||
|
||||
permissions.origins.includes('*://*/*')
|
||||
).catch(( ) => false);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
async function gotoURL(url, type) {
|
||||
const pageURL = new URL(url, runtime.getURL('/'));
|
||||
const tabs = await browser.tabs.query({
|
||||
url: pageURL.href,
|
||||
windowType: type !== 'popup' ? 'normal' : 'popup'
|
||||
});
|
||||
|
||||
if ( Array.isArray(tabs) && tabs.length !== 0 ) {
|
||||
const { windowId, id } = tabs[0];
|
||||
return Promise.all([
|
||||
browser.windows.update(windowId, { focused: true }),
|
||||
browser.tabs.update(id, { active: true }),
|
||||
]);
|
||||
}
|
||||
|
||||
if ( type === 'popup' ) {
|
||||
return browser.windows.create({
|
||||
type: 'popup',
|
||||
url: pageURL.href,
|
||||
});
|
||||
}
|
||||
|
||||
return browser.tabs.create({
|
||||
active: true,
|
||||
url: pageURL.href,
|
||||
});
|
||||
}
|
||||
const broadcastMessage = message => {
|
||||
const bc = new self.BroadcastChannel('uBOL');
|
||||
bc.postMessage(message);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
@ -220,7 +202,5 @@ export {
|
|||
isDescendantHostnameOfIter,
|
||||
intersectHostnameIters,
|
||||
subtractHostnameIters,
|
||||
hasBroadHostPermissions,
|
||||
gotoURL,
|
||||
strArrayEq,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
import { deepEquals } from './utils.js';
|
||||
|
||||
export const webext = self.browser;
|
||||
|
||||
|
|
@ -114,14 +115,6 @@ const prepareUpdateRules = optionsBefore => {
|
|||
return optionsAfter;
|
||||
};
|
||||
|
||||
const ruleCompare = (a, b) => a.id - b.id;
|
||||
|
||||
const isSameRules = (a, b) => {
|
||||
a.sort(ruleCompare);
|
||||
b.sort(ruleCompare);
|
||||
return JSON.stringify(a) === JSON.stringify(b);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
export function normalizeDNRRules(rules, ruleIds) {
|
||||
|
|
@ -209,7 +202,7 @@ export const dnr = {
|
|||
}
|
||||
addRules.push(rule0);
|
||||
}
|
||||
if ( isSameRules(addRules, beforeRules) ) { return false; }
|
||||
if ( deepEquals(addRules, beforeRules) ) { return false; }
|
||||
return this.updateDynamicRules({
|
||||
addRules,
|
||||
removeRuleIds: beforeRules.map(r => r.id),
|
||||
|
|
|
|||
Loading…
Reference in a new issue