Offer ability to skip redirects in strict-blocked page

Related discussion:
https://github.com/uBlockOrigin/uBlock-issues/issues/3206#issuecomment-2439639215

If a strict-blocked page matches a `urlskip=` filter, the page
will show the user the destination URL as a result of applying the
`urlskip` filter should they choose to proceed with the
navigation.
This commit is contained in:
Raymond Hill 2024-10-27 14:24:08 -04:00
parent 6aa9391c8d
commit 20b54185fa
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
7 changed files with 63 additions and 22 deletions

View File

@ -1193,6 +1193,10 @@
"message": "Proceed",
"description": "Button text to navigate to the blocked page"
},
"docblockedRedirectPrompt": {
"message": "The blocked page wants to redirect to another site. If you choose to proceed, you will navigate directly to: {{url}}",
"description": "Text warning about an incoming redirect"
},
"cloudPush": {
"message": "Export to cloud storage",
"description": "tooltip"

View File

@ -28,12 +28,18 @@ body {
}
#rootContainer {
width: min(100vw, 640px);
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;
}
@ -45,8 +51,12 @@ a {
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;
@ -120,6 +130,13 @@ body[dir="rtl"] #toggleParse {
padding-inline-start: var(--default-gap-xsmall);
}
#urlskip a {
display: block;
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#actionContainer {
display: flex;
justify-content: space-between;

View File

@ -33,6 +33,9 @@
</div>
</div>
<div id="urlskip" hidden>
</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="docblockedDontWarn">_</span></label>
</div>
@ -42,13 +45,12 @@
<button id="bye" data-i18n="docblockedClose" type="button">_<span class="hover"></span></button>
<button id="proceed" class="preferred" data-i18n="docblockedDisable" type="button"><span class="hover"></span></button>
</div>
<div id="templates" style="display: none;">
<li class="filterList">
<a class="filterListSource" href="asset-viewer.html?url=" target="_blank"></a>&nbsp;<!--
--><a class="fa-icon filterListSupport hidden" href="#" target="_blank" rel="noopener noreferrer">home</a>
</span>
</div>
</div>
<div id="templates" style="display: none;">
<li class="filterList">
<a class="filterListSource" href="asset-viewer.html?url=" target="_blank"></a>&nbsp;<!--
--><a class="fa-icon filterListSupport hidden" href="#" target="_blank" rel="noopener noreferrer">home</a>
</span>
</div>
<script src="lib/hsluv/hsluv-0.1.0.min.js"></script>

View File

@ -19,10 +19,8 @@
Home: https://github.com/gorhill/uBlock
*/
'use strict';
import { i18n, i18n$ } from './i18n.js';
import { dom, qs$ } from './dom.js';
import { i18n, i18n$ } from './i18n.js';
/******************************************************************************/
@ -47,7 +45,7 @@ let details = {};
let lists;
for ( const rawFilter in response ) {
if ( response.hasOwnProperty(rawFilter) ) {
if ( Object.prototype.hasOwnProperty.call(response, rawFilter) ) {
lists = response[rawFilter];
break;
}
@ -80,6 +78,24 @@ let details = {};
dom.text('#theURL > p > span:first-of-type', details.url);
dom.text('#why', details.fs);
if ( typeof details.to === 'string' && details.to.length !== 0 ) {
const fragment = new DocumentFragment();
const text = i18n$('docblockedRedirectPrompt');
const linkPlaceholder = '{{url}}';
let pos = text.indexOf(linkPlaceholder);
if ( pos !== -1 ) {
const link = document.createElement('a');
link.href = link.textContent = details.to;
fragment.append(
text.slice(0, pos),
link,
text.slice(pos + linkPlaceholder.length)
);
qs$('#urlskip').append(fragment);
dom.attr('#urlskip', 'hidden', null);
}
}
/******************************************************************************/
// https://github.com/gorhill/uBlock/issues/691

View File

@ -19,8 +19,6 @@
Home: https://github.com/gorhill/uBlock
*/
'use strict';
/******************************************************************************/
const i18n =
@ -168,14 +166,14 @@ if ( isBackgroundProcess !== true ) {
const re = /\{\{\w+\}\}/g;
let textout = '';
for (;;) {
let match = re.exec(textin);
const match = re.exec(textin);
if ( match === null ) {
textout += textin;
break;
}
textout += textin.slice(0, match.index);
let prop = match[0].slice(2, -2);
if ( dict.hasOwnProperty(prop) ) {
if ( Object.prototype.hasOwnProperty.call(dict, prop) ) {
textout += dict[prop].replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
} else {

View File

@ -955,8 +955,8 @@ const PageStore = class {
});
}
skipMainDocument(fctxt) {
const directives = staticNetFilteringEngine.urlSkip(fctxt);
skipMainDocument(fctxt, blocked) {
const directives = staticNetFilteringEngine.urlSkip(fctxt, blocked);
if ( directives === undefined ) { return; }
if ( logger.enabled !== true ) { return; }
fctxt.pushFilters(directives.map(a => a.logData()));

View File

@ -197,7 +197,7 @@ const onBeforeRootFrameRequest = function(fctxt) {
if ( result !== 1 ) {
pageStore.redirectNonBlockedRequest(fctxt);
} else {
pageStore.skipMainDocument(fctxt);
pageStore.skipMainDocument(fctxt, true);
}
}
@ -216,16 +216,20 @@ const onBeforeRootFrameRequest = function(fctxt) {
if ( result !== 1 ) { return; }
// No log data means no strict blocking (because we need to report why
// the blocking occurs.
// the blocking occurs
if ( logData === undefined ) { return; }
// Blocked
// Find out the URL navigated to should the document not be strict-blocked
pageStore.skipMainDocument(fctxt, false);
const query = encodeURIComponent(JSON.stringify({
url: requestURL,
hn: requestHostname,
dn: fctxt.getDomain() || requestHostname,
fs: logData.raw
fs: logData.raw,
hn: requestHostname,
to: fctxt.redirectURL || '',
}));
vAPI.tabs.replace(