2022-09-13 15:44:24 -06:00
|
|
|
/*******************************************************************************
|
|
|
|
|
|
|
|
uBlock Origin - a browser extension to block requests.
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* jshint esversion:11 */
|
|
|
|
|
2022-09-07 08:15:36 -06:00
|
|
|
'use strict';
|
|
|
|
|
2022-09-13 15:44:24 -06:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2022-09-20 06:24:01 -06:00
|
|
|
import {
|
|
|
|
browser,
|
|
|
|
dnr,
|
|
|
|
runtime,
|
|
|
|
} from './ext.js';
|
|
|
|
|
|
|
|
import {
|
|
|
|
CURRENT_CONFIG_BASE_RULE_ID,
|
|
|
|
getRulesetDetails,
|
|
|
|
getDynamicRules,
|
|
|
|
defaultRulesetsFromLanguage,
|
|
|
|
enableRulesets,
|
2022-09-29 17:51:33 -06:00
|
|
|
getEnabledRulesetsDetails,
|
|
|
|
updateDynamicRules,
|
2022-09-20 06:24:01 -06:00
|
|
|
} from './ruleset-manager.js';
|
|
|
|
|
|
|
|
import {
|
|
|
|
getInjectableCount,
|
2022-09-27 17:51:38 -06:00
|
|
|
registerInjectables,
|
2022-09-20 06:24:01 -06:00
|
|
|
} from './scripting-manager.js';
|
|
|
|
|
|
|
|
import {
|
|
|
|
matchesTrustedSiteDirective,
|
|
|
|
toggleTrustedSiteDirective,
|
|
|
|
} from './trusted-sites.js';
|
2022-09-07 08:15:36 -06:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2022-09-13 15:44:24 -06:00
|
|
|
const rulesetConfig = {
|
|
|
|
version: '',
|
|
|
|
enabledRulesets: [],
|
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
function getCurrentVersion() {
|
|
|
|
return runtime.getManifest().version;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function loadRulesetConfig() {
|
2022-09-16 13:56:35 -06:00
|
|
|
const dynamicRuleMap = await getDynamicRules();
|
2022-09-13 15:44:24 -06:00
|
|
|
const configRule = dynamicRuleMap.get(CURRENT_CONFIG_BASE_RULE_ID);
|
|
|
|
if ( configRule === undefined ) {
|
|
|
|
rulesetConfig.enabledRulesets = await defaultRulesetsFromLanguage();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-09-27 05:46:24 -06:00
|
|
|
const match = /^\|\|(?:example|ubolite)\.invalid\/([^\/]+)\/(?:([^\/]+)\/)?/.exec(
|
2022-09-13 15:44:24 -06:00
|
|
|
configRule.condition.urlFilter
|
|
|
|
);
|
|
|
|
if ( match === null ) { return; }
|
|
|
|
|
|
|
|
rulesetConfig.version = match[1];
|
|
|
|
if ( match[2] ) {
|
|
|
|
rulesetConfig.enabledRulesets =
|
|
|
|
decodeURIComponent(match[2] || '').split(' ');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function saveRulesetConfig() {
|
2022-09-16 13:56:35 -06:00
|
|
|
const dynamicRuleMap = await getDynamicRules();
|
2022-09-13 15:44:24 -06:00
|
|
|
let configRule = dynamicRuleMap.get(CURRENT_CONFIG_BASE_RULE_ID);
|
|
|
|
if ( configRule === undefined ) {
|
|
|
|
configRule = {
|
|
|
|
id: CURRENT_CONFIG_BASE_RULE_ID,
|
|
|
|
action: {
|
|
|
|
type: 'allow',
|
|
|
|
},
|
|
|
|
condition: {
|
|
|
|
urlFilter: '',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
const version = rulesetConfig.version;
|
|
|
|
const enabledRulesets = encodeURIComponent(rulesetConfig.enabledRulesets.join(' '));
|
2022-09-27 05:46:24 -06:00
|
|
|
const urlFilter = `||ubolite.invalid/${version}/${enabledRulesets}/`;
|
2022-09-13 15:44:24 -06:00
|
|
|
if ( urlFilter === configRule.condition.urlFilter ) { return; }
|
|
|
|
configRule.condition.urlFilter = urlFilter;
|
|
|
|
|
|
|
|
return dnr.updateDynamicRules({
|
|
|
|
addRules: [ configRule ],
|
|
|
|
removeRuleIds: [ CURRENT_CONFIG_BASE_RULE_ID ],
|
|
|
|
});
|
|
|
|
}
|
2022-09-07 08:15:36 -06:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2022-09-29 17:51:33 -06:00
|
|
|
async function hasGreatPowers(origin) {
|
|
|
|
if ( /^https?:\/\//.test(origin) === false ) { return false; }
|
2022-09-15 11:14:08 -06:00
|
|
|
return browser.permissions.contains({
|
2022-09-27 05:46:24 -06:00
|
|
|
origins: [ `${origin}/*` ],
|
2022-09-13 15:44:24 -06:00
|
|
|
});
|
2022-09-15 11:14:08 -06:00
|
|
|
}
|
2022-09-13 15:44:24 -06:00
|
|
|
|
2022-09-27 17:51:38 -06:00
|
|
|
function hasOmnipotence() {
|
|
|
|
return browser.permissions.contains({
|
|
|
|
origins: [ '<all_urls>' ],
|
2022-09-07 08:15:36 -06:00
|
|
|
});
|
2022-09-15 11:14:08 -06:00
|
|
|
}
|
2022-09-07 08:15:36 -06:00
|
|
|
|
2022-09-27 17:51:38 -06:00
|
|
|
function onPermissionsAdded(permissions) {
|
2022-09-29 17:51:33 -06:00
|
|
|
if ( permissions.origins?.includes('<all_urls>') ) {
|
|
|
|
updateDynamicRules();
|
|
|
|
}
|
2022-09-27 17:51:38 -06:00
|
|
|
registerInjectables(permissions.origins);
|
2022-09-13 15:44:24 -06:00
|
|
|
}
|
2022-09-07 08:15:36 -06:00
|
|
|
|
2022-09-27 17:51:38 -06:00
|
|
|
function onPermissionsRemoved(permissions) {
|
2022-09-29 17:51:33 -06:00
|
|
|
if ( permissions.origins?.includes('<all_urls>') ) {
|
|
|
|
updateDynamicRules();
|
|
|
|
}
|
2022-09-27 17:51:38 -06:00
|
|
|
registerInjectables(permissions.origins);
|
2022-09-27 05:46:24 -06:00
|
|
|
}
|
|
|
|
|
2022-09-13 15:44:24 -06:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2022-09-15 11:14:08 -06:00
|
|
|
function onMessage(request, sender, callback) {
|
2022-09-13 15:44:24 -06:00
|
|
|
switch ( request.what ) {
|
|
|
|
|
2022-09-15 11:14:08 -06:00
|
|
|
case 'applyRulesets': {
|
|
|
|
enableRulesets(request.enabledRulesets).then(( ) => {
|
|
|
|
rulesetConfig.enabledRulesets = request.enabledRulesets;
|
2022-09-28 08:20:57 -06:00
|
|
|
return saveRulesetConfig();
|
2022-09-15 11:14:08 -06:00
|
|
|
}).then(( ) => {
|
2022-09-28 08:20:57 -06:00
|
|
|
registerInjectables();
|
2022-09-15 11:14:08 -06:00
|
|
|
callback();
|
|
|
|
});
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-09-13 15:44:24 -06:00
|
|
|
case 'getRulesetData': {
|
2022-09-16 13:56:35 -06:00
|
|
|
Promise.all([
|
|
|
|
getRulesetDetails(),
|
|
|
|
dnr.getEnabledRulesets(),
|
2022-09-27 17:51:38 -06:00
|
|
|
hasOmnipotence(),
|
2022-09-16 13:56:35 -06:00
|
|
|
]).then(results => {
|
2022-09-27 17:51:38 -06:00
|
|
|
const [ rulesetDetails, enabledRulesets, hasOmnipotence ] = results;
|
2022-09-13 15:44:24 -06:00
|
|
|
callback({
|
|
|
|
enabledRulesets,
|
|
|
|
rulesetDetails: Array.from(rulesetDetails.values()),
|
2022-09-27 17:51:38 -06:00
|
|
|
hasOmnipotence,
|
2022-09-07 08:15:36 -06:00
|
|
|
});
|
2022-09-13 15:44:24 -06:00
|
|
|
});
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 'popupPanelData': {
|
|
|
|
Promise.all([
|
|
|
|
matchesTrustedSiteDirective(request),
|
2022-09-27 17:51:38 -06:00
|
|
|
hasOmnipotence(),
|
2022-09-15 11:14:08 -06:00
|
|
|
hasGreatPowers(request.origin),
|
2022-09-29 17:51:33 -06:00
|
|
|
getEnabledRulesetsDetails(),
|
2022-09-17 06:26:41 -06:00
|
|
|
getInjectableCount(request.origin),
|
2022-09-13 15:44:24 -06:00
|
|
|
]).then(results => {
|
|
|
|
callback({
|
|
|
|
isTrusted: results[0],
|
2022-09-27 17:51:38 -06:00
|
|
|
hasOmnipotence: results[1],
|
|
|
|
hasGreatPowers: results[2],
|
|
|
|
rulesetDetails: results[3],
|
|
|
|
injectableCount: results[4],
|
2022-09-07 08:15:36 -06:00
|
|
|
});
|
2022-09-13 15:44:24 -06:00
|
|
|
});
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 'toggleTrustedSiteDirective': {
|
|
|
|
toggleTrustedSiteDirective(request).then(response => {
|
2022-09-28 08:20:57 -06:00
|
|
|
registerInjectables();
|
|
|
|
callback(response);
|
2022-09-13 15:44:24 -06:00
|
|
|
});
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2022-09-15 11:14:08 -06:00
|
|
|
async function start() {
|
|
|
|
await loadRulesetConfig();
|
|
|
|
await enableRulesets(rulesetConfig.enabledRulesets);
|
|
|
|
|
|
|
|
// We need to update the regex rules only when ruleset version changes.
|
|
|
|
const currentVersion = getCurrentVersion();
|
|
|
|
if ( currentVersion !== rulesetConfig.version ) {
|
|
|
|
console.log(`Version change: ${rulesetConfig.version} => ${currentVersion}`);
|
2022-09-29 17:51:33 -06:00
|
|
|
updateDynamicRules().then(( ) => {
|
2022-09-18 07:31:44 -06:00
|
|
|
rulesetConfig.version = currentVersion;
|
|
|
|
saveRulesetConfig();
|
|
|
|
});
|
2022-09-15 11:14:08 -06:00
|
|
|
}
|
|
|
|
|
2022-09-18 07:31:44 -06:00
|
|
|
// 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.
|
2022-09-27 17:51:38 -06:00
|
|
|
registerInjectables();
|
2022-09-18 07:31:44 -06:00
|
|
|
|
2022-09-15 11:14:08 -06:00
|
|
|
const enabledRulesets = await dnr.getEnabledRulesets();
|
|
|
|
console.log(`Enabled rulesets: ${enabledRulesets}`);
|
|
|
|
|
|
|
|
dnr.getAvailableStaticRuleCount().then(count => {
|
|
|
|
console.log(`Available static rule count: ${count}`);
|
|
|
|
});
|
|
|
|
|
|
|
|
dnr.setExtensionActionOptions({ displayActionCountAsBadgeText: true });
|
|
|
|
}
|
|
|
|
|
2022-09-13 15:44:24 -06:00
|
|
|
(async ( ) => {
|
|
|
|
await start();
|
|
|
|
|
2022-09-15 11:14:08 -06:00
|
|
|
runtime.onMessage.addListener(onMessage);
|
|
|
|
|
2022-09-27 17:51:38 -06:00
|
|
|
browser.permissions.onAdded.addListener(onPermissionsAdded);
|
|
|
|
browser.permissions.onRemoved.addListener(onPermissionsRemoved);
|
2022-09-07 08:15:36 -06:00
|
|
|
})();
|