mirror of https://github.com/gorhill/uBlock.git
161 lines
4.9 KiB
JavaScript
161 lines
4.9 KiB
JavaScript
|
/*******************************************************************************
|
||
|
|
||
|
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 */
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
import { dnr } from './ext.js';
|
||
|
|
||
|
import {
|
||
|
parsedURLromOrigin,
|
||
|
toBroaderHostname,
|
||
|
} from './utils.js';
|
||
|
|
||
|
import {
|
||
|
TRUSTED_DIRECTIVE_BASE_RULE_ID,
|
||
|
getDynamicRules
|
||
|
} from './ruleset-manager.js';
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
async function matchesTrustedSiteDirective(details) {
|
||
|
const hostname =
|
||
|
details.hostname ||
|
||
|
parsedURLromOrigin(details.origin)?.hostname ||
|
||
|
undefined;
|
||
|
if ( hostname === undefined ) { return false; }
|
||
|
|
||
|
const dynamicRuleMap = await getDynamicRules();
|
||
|
let rule = dynamicRuleMap.get(TRUSTED_DIRECTIVE_BASE_RULE_ID);
|
||
|
if ( rule === undefined ) { return false; }
|
||
|
|
||
|
const domainSet = new Set(rule.condition.requestDomains);
|
||
|
let hn = hostname;
|
||
|
while ( hn ) {
|
||
|
if ( domainSet.has(hn) ) { return true; }
|
||
|
hn = toBroaderHostname(hn);
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
async function addTrustedSiteDirective(details) {
|
||
|
const url = parsedURLromOrigin(details.origin);
|
||
|
if ( url === undefined ) { return false; }
|
||
|
|
||
|
const dynamicRuleMap = await getDynamicRules();
|
||
|
let rule = dynamicRuleMap.get(TRUSTED_DIRECTIVE_BASE_RULE_ID);
|
||
|
if ( rule !== undefined ) {
|
||
|
rule.condition.initiatorDomains = undefined;
|
||
|
if ( Array.isArray(rule.condition.requestDomains) === false ) {
|
||
|
rule.condition.requestDomains = [];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( rule === undefined ) {
|
||
|
rule = {
|
||
|
id: TRUSTED_DIRECTIVE_BASE_RULE_ID,
|
||
|
action: {
|
||
|
type: 'allowAllRequests',
|
||
|
},
|
||
|
condition: {
|
||
|
requestDomains: [ url.hostname ],
|
||
|
resourceTypes: [ 'main_frame' ],
|
||
|
},
|
||
|
priority: TRUSTED_DIRECTIVE_BASE_RULE_ID,
|
||
|
};
|
||
|
dynamicRuleMap.set(TRUSTED_DIRECTIVE_BASE_RULE_ID, rule);
|
||
|
} else if ( rule.condition.requestDomains.includes(url.hostname) === false ) {
|
||
|
rule.condition.requestDomains.push(url.hostname);
|
||
|
}
|
||
|
|
||
|
await dnr.updateDynamicRules({
|
||
|
addRules: [ rule ],
|
||
|
removeRuleIds: [ TRUSTED_DIRECTIVE_BASE_RULE_ID ],
|
||
|
});
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
async function removeTrustedSiteDirective(details) {
|
||
|
const url = parsedURLromOrigin(details.origin);
|
||
|
if ( url === undefined ) { return false; }
|
||
|
|
||
|
const dynamicRuleMap = await getDynamicRules();
|
||
|
let rule = dynamicRuleMap.get(TRUSTED_DIRECTIVE_BASE_RULE_ID);
|
||
|
if ( rule === undefined ) { return false; }
|
||
|
rule.condition.initiatorDomains = undefined;
|
||
|
if ( Array.isArray(rule.condition.requestDomains) === false ) {
|
||
|
rule.condition.requestDomains = [];
|
||
|
}
|
||
|
|
||
|
const domainSet = new Set(rule.condition.requestDomains);
|
||
|
const beforeCount = domainSet.size;
|
||
|
let hostname = url.hostname;
|
||
|
for (;;) {
|
||
|
domainSet.delete(hostname);
|
||
|
const pos = hostname.indexOf('.');
|
||
|
if ( pos === -1 ) { break; }
|
||
|
hostname = hostname.slice(pos+1);
|
||
|
}
|
||
|
|
||
|
if ( domainSet.size === beforeCount ) { return false; }
|
||
|
|
||
|
if ( domainSet.size === 0 ) {
|
||
|
dynamicRuleMap.delete(TRUSTED_DIRECTIVE_BASE_RULE_ID);
|
||
|
await dnr.updateDynamicRules({
|
||
|
removeRuleIds: [ TRUSTED_DIRECTIVE_BASE_RULE_ID ]
|
||
|
});
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
rule.condition.requestDomains = Array.from(domainSet);
|
||
|
|
||
|
await dnr.updateDynamicRules({
|
||
|
addRules: [ rule ],
|
||
|
removeRuleIds: [ TRUSTED_DIRECTIVE_BASE_RULE_ID ],
|
||
|
});
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
async function toggleTrustedSiteDirective(details) {
|
||
|
return details.state
|
||
|
? removeTrustedSiteDirective(details)
|
||
|
: addTrustedSiteDirective(details);
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
export {
|
||
|
matchesTrustedSiteDirective,
|
||
|
toggleTrustedSiteDirective,
|
||
|
};
|