mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
draft
This commit is contained in:
parent
d7df6cda4a
commit
0eb7d70b7d
9 changed files with 563 additions and 39 deletions
|
|
@ -25,7 +25,7 @@
|
|||
"128": "img/icon_128.png"
|
||||
},
|
||||
"manifest_version": 3,
|
||||
"minimum_chrome_version": "119.0",
|
||||
"minimum_chrome_version": "122.0",
|
||||
"name": "__MSG_extName__",
|
||||
"options_page": "dashboard.html",
|
||||
"optional_host_permissions": [
|
||||
|
|
|
|||
|
|
@ -234,5 +234,29 @@
|
|||
"findListsPlaceholder": {
|
||||
"message": "Find lists",
|
||||
"description": "Placeholder for the input field used to find lists"
|
||||
},
|
||||
"strictblockTitle": {
|
||||
"message": "Page blocked",
|
||||
"description": "Webpage title for the strict-blocked page"
|
||||
},
|
||||
"strictblockSentence1": {
|
||||
"message": "uBO Lite has prevented the following page from loading:",
|
||||
"description": "Sentence used in the strict-blocked page"
|
||||
},
|
||||
"strictblockBack": {
|
||||
"message": "Go back",
|
||||
"description": "A button to go back to the previous webpage"
|
||||
},
|
||||
"strictblockClose": {
|
||||
"message": "Close this window",
|
||||
"description": "A button to close the current tab"
|
||||
},
|
||||
"strictblockDontWarn": {
|
||||
"message": "Don't warn me again about this site",
|
||||
"description": "Label for checkbox in document-blocked page"
|
||||
},
|
||||
"strictblockProceed": {
|
||||
"message": "Proceed",
|
||||
"description": "A button to navigate to the blocked page"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
147
platform/mv3/extension/css/strict-block.css
Normal file
147
platform/mv3/extension/css/strict-block.css
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2018-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
|
||||
*/
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
padding: var(--default-gap-xxlarge) var(--default-gap-small);
|
||||
justify-content: center;
|
||||
}
|
||||
:root.mobile body {
|
||||
padding: var(--default-gap-small);
|
||||
}
|
||||
|
||||
#rootContainer {
|
||||
width: min(100%, 640px);
|
||||
}
|
||||
#rootContainer > * {
|
||||
margin: 0 0 var(--default-gap-xxlarge) 0;
|
||||
}
|
||||
:root.mobile #rootContainer > * {
|
||||
margin-bottom: var(--default-gap-xlarge);
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.code {
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
}
|
||||
#warningSign {
|
||||
color: var(--accent-surface-1);
|
||||
fill: var(--accent-surface-1);
|
||||
font-size: 96px;
|
||||
line-height: 1;
|
||||
width: 100%;
|
||||
}
|
||||
:root.mobile #warningSign {
|
||||
font-size: 64px;
|
||||
}
|
||||
#theURL {
|
||||
color: var(--ink-2);
|
||||
padding: 0;
|
||||
}
|
||||
#theURL > * {
|
||||
margin: 0;
|
||||
}
|
||||
#theURL > p {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
#theURL > p > span:first-of-type {
|
||||
display: block;
|
||||
max-height: 6lh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
:root.mobile #theURL > p > span:first-of-type {
|
||||
max-height: 3lh;
|
||||
}
|
||||
#theURL #toggleParse {
|
||||
background-color: transparent;
|
||||
top: 100%;
|
||||
box-sizing: border-box;
|
||||
color: var(--ink-3);
|
||||
fill: var(--ink-3);
|
||||
cursor: pointer;
|
||||
font-size: 1.2rem;
|
||||
padding: var(--default-gap-xxsmall);
|
||||
position: absolute;
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
#theURL:not(.collapsed) #toggleParse > span:first-of-type {
|
||||
display: none;
|
||||
}
|
||||
#theURL.collapsed #toggleParse > span:last-of-type {
|
||||
display: none;
|
||||
}
|
||||
body[dir="ltr"] #toggleParse {
|
||||
right: 0;
|
||||
}
|
||||
body[dir="rtl"] #toggleParse {
|
||||
left: 0;
|
||||
}
|
||||
#theURL > p:hover #toggleParse {
|
||||
transform: translate(0, -50%) scale(1.15);
|
||||
}
|
||||
#parsed {
|
||||
background-color: var(--surface-1);
|
||||
border: 4px solid var(--surface-2);
|
||||
font-size: small;
|
||||
overflow-x: auto;
|
||||
padding: var(--default-gap-xxsmall);
|
||||
text-align: initial;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
#theURL.collapsed > #parsed {
|
||||
display: none;
|
||||
}
|
||||
#parsed ul, #parsed li {
|
||||
list-style-type: none;
|
||||
}
|
||||
#parsed li {
|
||||
white-space: nowrap;
|
||||
}
|
||||
#parsed span {
|
||||
display: inline-block;
|
||||
}
|
||||
#parsed span:first-of-type {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#actionContainer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
:root.mobile #actionContainer {
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#actionContainer > button {
|
||||
margin-bottom: 2rem
|
||||
}
|
||||
|
||||
/* Small-screen devices */
|
||||
:root.mobile button {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ import {
|
|||
browser,
|
||||
dnr,
|
||||
i18n,
|
||||
runtime,
|
||||
} from './ext.js';
|
||||
|
||||
import { fetchJSON } from './fetch.js';
|
||||
|
|
@ -40,6 +41,7 @@ const REDIRECT_REALM_START = REMOVEPARAMS_REALM_END;
|
|||
const REDIRECT_REALM_END = REDIRECT_REALM_START + RULE_REALM_SIZE;
|
||||
const MODIFYHEADERS_REALM_START = REDIRECT_REALM_END;
|
||||
const MODIFYHEADERS_REALM_END = MODIFYHEADERS_REALM_START + RULE_REALM_SIZE;
|
||||
const STRICTBLOCK_REALM_START = MODIFYHEADERS_REALM_END;
|
||||
const TRUSTED_DIRECTIVE_BASE_RULE_ID = 8000000;
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
@ -60,74 +62,70 @@ function getRulesetDetails() {
|
|||
/******************************************************************************/
|
||||
|
||||
function getDynamicRules() {
|
||||
if ( getDynamicRules.dynamicRuleMapPromise !== undefined ) {
|
||||
return getDynamicRules.dynamicRuleMapPromise;
|
||||
if ( getDynamicRules.promise !== undefined ) {
|
||||
return getDynamicRules.promise;
|
||||
}
|
||||
getDynamicRules.dynamicRuleMapPromise = dnr.getDynamicRules().then(rules => {
|
||||
getDynamicRules.promise = dnr.getDynamicRules().then(rules => {
|
||||
const rulesMap = new Map(rules.map(rule => [ rule.id, rule ]));
|
||||
ubolLog(`Dynamic rule count: ${rulesMap.size}`);
|
||||
ubolLog(`Available dynamic rule count: ${dnr.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES - rulesMap.size}`);
|
||||
return rulesMap;
|
||||
});
|
||||
return getDynamicRules.dynamicRuleMapPromise;
|
||||
return getDynamicRules.promise;
|
||||
}
|
||||
|
||||
function getDynamicRuleIds() {
|
||||
if ( getDynamicRuleIds.promise !== undefined ) {
|
||||
return getDynamicRuleIds.promise;
|
||||
}
|
||||
getDynamicRuleIds.promise = dnr.getDynamicRules().then(rules => {
|
||||
return rules.map(rule => rule.id);
|
||||
});
|
||||
return getDynamicRuleIds.promise;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
async function pruneInvalidRegexRules(realm, rulesIn) {
|
||||
// Avoid testing already tested regexes
|
||||
const dynamicRules = await dnr.getDynamicRules();
|
||||
const validRegexSet = new Set(
|
||||
dynamicRules.filter(rule =>
|
||||
rule.condition?.regexFilter && true || false
|
||||
).map(rule =>
|
||||
rule.condition.regexFilter
|
||||
)
|
||||
);
|
||||
const rejectedRegexRules = [];
|
||||
|
||||
const validateRegex = regex => {
|
||||
return dnr.isRegexSupported({ regex, isCaseSensitive: false }).then(result => {
|
||||
const isSupported = result?.isSupported || false;
|
||||
pruneInvalidRegexRules.validated.set(regex, isSupported);
|
||||
if ( isSupported ) { return true; }
|
||||
rejectedRegexRules.push(`\t${regex} ${result?.reason}`);
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
// Validate regex-based rules
|
||||
const toCheck = [];
|
||||
const rejectedRegexRules = [];
|
||||
for ( const rule of rulesIn ) {
|
||||
if ( rule.condition?.regexFilter === undefined ) {
|
||||
toCheck.push(true);
|
||||
continue;
|
||||
}
|
||||
const {
|
||||
regexFilter: regex,
|
||||
isUrlFilterCaseSensitive: isCaseSensitive
|
||||
} = rule.condition;
|
||||
if ( validRegexSet.has(regex) ) {
|
||||
toCheck.push(true);
|
||||
const { regexFilter } = rule.condition;
|
||||
if ( pruneInvalidRegexRules.validated.has(regexFilter) ) {
|
||||
toCheck.push(pruneInvalidRegexRules.validated.get(regexFilter));
|
||||
continue;
|
||||
}
|
||||
if ( pruneInvalidRegexRules.invalidRegexes.has(regex) ) {
|
||||
toCheck.push(false);
|
||||
continue;
|
||||
}
|
||||
toCheck.push(
|
||||
dnr.isRegexSupported({ regex, isCaseSensitive }).then(result => {
|
||||
if ( result.isSupported ) { return true; }
|
||||
pruneInvalidRegexRules.invalidRegexes.add(regex);
|
||||
rejectedRegexRules.push(`\t${regex} ${result.reason}`);
|
||||
return false;
|
||||
})
|
||||
);
|
||||
toCheck.push(validateRegex(regexFilter));
|
||||
}
|
||||
|
||||
// Collate results
|
||||
const isValid = await Promise.all(toCheck);
|
||||
|
||||
if ( rejectedRegexRules.length !== 0 ) {
|
||||
ubolLog(
|
||||
`${realm} realm: rejected regexes:\n`,
|
||||
ubolLog(`${realm} realm: rejected regexes:\n`,
|
||||
rejectedRegexRules.join('\n')
|
||||
);
|
||||
}
|
||||
|
||||
return rulesIn.filter((v, i) => isValid[i]);
|
||||
}
|
||||
pruneInvalidRegexRules.invalidRegexes = new Set();
|
||||
pruneInvalidRegexRules.validated = new Map();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
@ -426,14 +424,88 @@ async function updateModifyHeadersRules() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
async function updateStrictBlockRules() {
|
||||
const [
|
||||
hasOmnipotence,
|
||||
rulesetDetails,
|
||||
dynamicRuleMap,
|
||||
] = await Promise.all([
|
||||
browser.permissions.contains({ origins: [ '<all_urls>' ] }),
|
||||
getEnabledRulesetsDetails(),
|
||||
getDynamicRules(),
|
||||
]);
|
||||
|
||||
// Fetch strick-block hostnames
|
||||
const toFetch = [];
|
||||
for ( const details of rulesetDetails ) {
|
||||
if ( details.rules.strictBlock === 0 ) { continue; }
|
||||
toFetch.push(fetchJSON(`/rulesets/strict-block/${details.id}`));
|
||||
}
|
||||
const strictBlockRulesets = await Promise.all(toFetch);
|
||||
|
||||
// Strict-block rules can only be enforced with omnipotence
|
||||
let toStrictBlock = new Set();
|
||||
if ( hasOmnipotence ) {
|
||||
for ( const hostnames of strictBlockRulesets ) {
|
||||
if ( Array.isArray(hostnames) === false ) { continue; }
|
||||
toStrictBlock = toStrictBlock.union(new Set(hostnames));
|
||||
}
|
||||
}
|
||||
|
||||
const addRules = [];
|
||||
const removeRuleIds = [];
|
||||
|
||||
if ( dynamicRuleMap.has(STRICTBLOCK_REALM_START) ) {
|
||||
removeRuleIds.push(STRICTBLOCK_REALM_START);
|
||||
dynamicRuleMap.delete(STRICTBLOCK_REALM_START);
|
||||
}
|
||||
|
||||
if ( toStrictBlock.size !== 0 ) {
|
||||
const ubolOrigin = runtime.getURL('').replace(/\/$/, '');
|
||||
addRules.push({
|
||||
id: STRICTBLOCK_REALM_START,
|
||||
action: {
|
||||
type: 'redirect',
|
||||
redirect: {
|
||||
regexSubstitution: `${ubolOrigin}/strict-block.html#\\0`,
|
||||
},
|
||||
},
|
||||
condition: {
|
||||
regexFilter: '^.+$',
|
||||
requestDomains: Array.from(toStrictBlock),
|
||||
resourceTypes: [ 'main_frame' ],
|
||||
},
|
||||
priority: 19,
|
||||
});
|
||||
dynamicRuleMap.set(STRICTBLOCK_REALM_START, addRules[0]);
|
||||
}
|
||||
|
||||
if ( addRules.length === 0 && removeRuleIds.length === 0 ) { return; }
|
||||
|
||||
if ( removeRuleIds.length !== 0 ) {
|
||||
ubolLog(`Remove ${removeRuleIds.length} DNR strict-block rules`);
|
||||
}
|
||||
if ( addRules.length !== 0 ) {
|
||||
ubolLog(`Add ${addRules.length} DNR strict-block rules`);
|
||||
}
|
||||
|
||||
return dnr.updateDynamicRules({ addRules, removeRuleIds }).catch(reason => {
|
||||
console.error(`updateStrictBlockRules() / ${reason}`);
|
||||
});
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// TODO: group all omnipotence-related rules into one realm.
|
||||
|
||||
async function updateDynamicRules() {
|
||||
ubolLog('Called updateDynamicRules()');
|
||||
return Promise.all([
|
||||
updateRegexRules(),
|
||||
updateRemoveparamRules(),
|
||||
updateRedirectRules(),
|
||||
updateModifyHeadersRules(),
|
||||
updateStrictBlockRules(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
207
platform/mv3/extension/js/strict-block.js
Normal file
207
platform/mv3/extension/js/strict-block.js
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a comprehensive, efficient content blocker
|
||||
Copyright (C) 2024-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 { dom, qs$ } from './dom.js';
|
||||
import { i18n$ } from './i18n.js';
|
||||
import { sendMessage } from './ext.js';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const toURL = new URL('about:blank');
|
||||
|
||||
function setURL(url) {
|
||||
try {
|
||||
toURL.href = url;
|
||||
} catch(_) {
|
||||
}
|
||||
}
|
||||
|
||||
setURL(self.location.hash.slice(1));
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const urlToFragment = raw => {
|
||||
try {
|
||||
const fragment = new DocumentFragment();
|
||||
const url = new URL(raw);
|
||||
const hn = url.hostname;
|
||||
const i = raw.indexOf(hn);
|
||||
const b = document.createElement('b');
|
||||
b.append(hn);
|
||||
fragment.append(raw.slice(0,i), b, raw.slice(i+hn.length));
|
||||
return fragment;
|
||||
} catch(_) {
|
||||
}
|
||||
return raw;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
dom.clear('#theURL > p > span:first-of-type');
|
||||
qs$('#theURL > p > span:first-of-type').append(urlToFragment(toURL));
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/691
|
||||
// Parse URL to extract as much useful information as possible. This is
|
||||
// useful to assist the user in deciding whether to navigate to the web page.
|
||||
(( ) => {
|
||||
if ( typeof URL !== 'function' ) { return; }
|
||||
|
||||
const reURL = /^https?:\/\//;
|
||||
|
||||
const liFromParam = function(name, value) {
|
||||
if ( value === '' ) {
|
||||
value = name;
|
||||
name = '';
|
||||
}
|
||||
const li = dom.create('li');
|
||||
let span = dom.create('span');
|
||||
dom.text(span, name);
|
||||
li.appendChild(span);
|
||||
if ( name !== '' && value !== '' ) {
|
||||
li.appendChild(document.createTextNode(' = '));
|
||||
}
|
||||
span = dom.create('span');
|
||||
if ( reURL.test(value) ) {
|
||||
const a = dom.create('a');
|
||||
dom.attr(a, 'href', value);
|
||||
dom.text(a, value);
|
||||
span.appendChild(a);
|
||||
} else {
|
||||
dom.text(span, value);
|
||||
}
|
||||
li.appendChild(span);
|
||||
return li;
|
||||
};
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/1649
|
||||
// Limit recursion.
|
||||
const renderParams = function(parentNode, rawURL, depth = 0) {
|
||||
let url;
|
||||
try {
|
||||
url = new URL(rawURL);
|
||||
} catch(ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const search = url.search.slice(1);
|
||||
if ( search === '' ) { return false; }
|
||||
|
||||
url.search = '';
|
||||
const li = liFromParam(i18n$('docblockedNoParamsPrompt'), url.href);
|
||||
parentNode.appendChild(li);
|
||||
|
||||
const params = new self.URLSearchParams(search);
|
||||
for ( const [ name, value ] of params ) {
|
||||
const li = liFromParam(name, value);
|
||||
if ( depth < 2 && reURL.test(value) ) {
|
||||
const ul = dom.create('ul');
|
||||
renderParams(ul, value, depth + 1);
|
||||
li.appendChild(ul);
|
||||
}
|
||||
parentNode.appendChild(li);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if ( renderParams(qs$('#parsed'), toURL) === false ) { return; }
|
||||
|
||||
dom.cl.remove('#toggleParse', 'hidden');
|
||||
|
||||
dom.on('#toggleParse', 'click', ( ) => {
|
||||
dom.cl.toggle('#theURL', 'collapsed');
|
||||
vAPI.localStorage.setItem(
|
||||
'document-blocked-expand-url',
|
||||
(dom.cl.has('#theURL', 'collapsed') === false).toString()
|
||||
);
|
||||
});
|
||||
|
||||
vAPI.localStorage.getItemAsync('document-blocked-expand-url').then(value => {
|
||||
dom.cl.toggle('#theURL', 'collapsed', value !== 'true' && value !== true);
|
||||
});
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://www.reddit.com/r/uBlockOrigin/comments/breeux/close_this_window_doesnt_work_on_firefox/
|
||||
|
||||
if ( window.history.length > 1 ) {
|
||||
dom.on('#back', 'click', ( ) => {
|
||||
window.history.back();
|
||||
});
|
||||
qs$('#bye').style.display = 'none';
|
||||
} else {
|
||||
dom.on('#bye', 'click', ( ) => {
|
||||
sendMessage({
|
||||
what: 'closeThisTab',
|
||||
});
|
||||
});
|
||||
qs$('#back').style.display = 'none';
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const getTargetHostname = function() {
|
||||
const url = new URL(toURL);
|
||||
return url.hostname;
|
||||
};
|
||||
|
||||
const proceedToURL = function() {
|
||||
window.location.replace(toURL);
|
||||
};
|
||||
|
||||
const proceedTemporary = async function() {
|
||||
await sendMessage({
|
||||
what: 'temporarilyWhitelistDocument',
|
||||
hostname: getTargetHostname(),
|
||||
});
|
||||
proceedToURL();
|
||||
};
|
||||
|
||||
const proceedPermanent = async function() {
|
||||
await sendMessage({
|
||||
what: 'toggleHostnameSwitch',
|
||||
name: 'no-strict-blocking',
|
||||
hostname: getTargetHostname(),
|
||||
deep: true,
|
||||
state: true,
|
||||
persist: true,
|
||||
});
|
||||
proceedToURL();
|
||||
};
|
||||
|
||||
dom.on('#disableWarning', 'change', ev => {
|
||||
const checked = ev.target.checked;
|
||||
dom.cl.toggle('[data-i18n="docblockedBack"]', 'disabled', checked);
|
||||
dom.cl.toggle('[data-i18n="docblockedClose"]', 'disabled', checked);
|
||||
});
|
||||
|
||||
dom.on('#proceed', 'click', ( ) => {
|
||||
if ( qs$('#disableWarning').checked ) {
|
||||
proceedPermanent();
|
||||
} else {
|
||||
proceedTemporary();
|
||||
}
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
43
platform/mv3/extension/strict-block.html
Normal file
43
platform/mv3/extension/strict-block.html
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1 user-scalable=yes">
|
||||
<title data-i18n="strictblockTitle"></title>
|
||||
<link rel="stylesheet" href="css/default.css">
|
||||
<link rel="stylesheet" href="css/common.css">
|
||||
<link rel="stylesheet" href="css/fa-icons.css">
|
||||
<link rel="stylesheet" href="css/strict-block.css">
|
||||
<link rel="shortcut icon" type="image/png" href="img/icon_64.png"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="rootContainer">
|
||||
<div id="warningSign">
|
||||
<a class="fa-icon" href="https://github.com/gorhill/uBlock/wiki/Strict-blocking" target="_blank" rel="noopener noreferrer">exclamation-triangle</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p data-i18n="strictblockSentence1">_</p>
|
||||
<div id="theURL" class="collapsed">
|
||||
<p class="code"><span> </span><span id="toggleParse" class="hidden"><span class="fa-icon">zoom-in</span><span class="fa-icon">zoom-out</span></span></p>
|
||||
<ul id="parsed"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="li">
|
||||
<label><span class="input checkbox"><input type="checkbox" id="disableWarning"><svg viewBox="0 0 24 24"><path d="M1.73,12.91 8.1,19.28 22.79,4.59"/></svg></span><span data-i18n="strictblockDontWarn">_</span></label>
|
||||
</div>
|
||||
|
||||
<div id="actionContainer">
|
||||
<button id="back" data-i18n="strictblockBack" type="button">_<span class="hover"></span></button>
|
||||
<button id="bye" data-i18n="strictblockClose" type="button">_<span class="hover"></span></button>
|
||||
<button id="proceed" class="preferred" data-i18n="strictblockProceed" type="button"><span class="hover"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="js/theme.js" type="module"></script>
|
||||
<script src="js/fa-icons.js" type="module"></script>
|
||||
<script src="js/i18n.js" type="module"></script>
|
||||
<script src="js/strict-block.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -16,10 +16,10 @@
|
|||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "uBOLite@raymondhill.net",
|
||||
"strict_min_version": "114.0"
|
||||
"strict_min_version": "127.0"
|
||||
},
|
||||
"gecko_android": {
|
||||
"strict_min_version": "114.0"
|
||||
"strict_min_version": "127.0"
|
||||
}
|
||||
},
|
||||
"declarative_net_request": {
|
||||
|
|
|
|||
|
|
@ -433,6 +433,33 @@ async function processNetworkFilters(assetDetails, network) {
|
|||
);
|
||||
}
|
||||
|
||||
const strictBlocked = new Set();
|
||||
for ( const rule of plainGood ) {
|
||||
if ( rule.action.type !== 'block' ) { continue; }
|
||||
if ( rule.condition.domainType ) { continue; }
|
||||
if ( rule.condition.regexFilter ) { continue; }
|
||||
if ( rule.condition.urlFilter ) { continue; }
|
||||
if ( rule.condition.requestMethods ) { continue; }
|
||||
if ( rule.condition.excludedRequestMethods ) { continue; }
|
||||
if ( rule.condition.resourceTypes ) { continue; }
|
||||
if ( rule.condition.excludedResourceTypes ) { continue; }
|
||||
if ( rule.condition.responseHeaders ) { continue; }
|
||||
if ( rule.condition.excludedResponseHeaders ) { continue; }
|
||||
if ( rule.condition.initiatorDomains ) { continue; }
|
||||
if ( rule.condition.excludedInitiatorDomains ) { continue; }
|
||||
if ( rule.condition.requestDomains === undefined ) { continue; }
|
||||
if ( rule.condition.excludedRequestDomains ) { continue; }
|
||||
for ( const hn of rule.condition.requestDomains ) {
|
||||
strictBlocked.add(hn);
|
||||
}
|
||||
}
|
||||
if ( strictBlocked.size !== 0 ) {
|
||||
writeFile(
|
||||
`${rulesetDir}/strict-block/${assetDetails.id}.json`,
|
||||
toJSONRuleset(Array.from(strictBlocked))
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
total: rules.length,
|
||||
plain: plainGood.length,
|
||||
|
|
@ -442,6 +469,7 @@ async function processNetworkFilters(assetDetails, network) {
|
|||
removeparam: removeparamsGood.length,
|
||||
redirect: redirects.length,
|
||||
modifyHeaders: modifyHeaders.length,
|
||||
strictBlock: strictBlocked.size,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1085,6 +1113,7 @@ async function rulesetFromURLs(assetDetails) {
|
|||
removeparam: netStats.removeparam,
|
||||
redirect: netStats.redirect,
|
||||
modifyHeaders: netStats.modifyHeaders,
|
||||
strictBlock: netStats.strictBlock,
|
||||
discarded: netStats.discarded,
|
||||
rejected: netStats.rejected,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -47,10 +47,12 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="templates" style="display: none;">
|
||||
<ul>
|
||||
<li class="filterList">
|
||||
<a class="filterListSource" href="asset-viewer.html?url=" target="_blank"></a> <!--
|
||||
--><a class="fa-icon filterListSupport hidden" href="#" target="_blank" rel="noopener noreferrer">home</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<script src="lib/hsluv/hsluv-0.1.0.min.js"></script>
|
||||
|
|
|
|||
Loading…
Reference in a new issue