mirror of https://github.com/gorhill/uBlock.git
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:
parent
6aa9391c8d
commit
20b54185fa
|
@ -1193,6 +1193,10 @@
|
||||||
"message": "Proceed",
|
"message": "Proceed",
|
||||||
"description": "Button text to navigate to the blocked page"
|
"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": {
|
"cloudPush": {
|
||||||
"message": "Export to cloud storage",
|
"message": "Export to cloud storage",
|
||||||
"description": "tooltip"
|
"description": "tooltip"
|
||||||
|
|
|
@ -28,12 +28,18 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#rootContainer {
|
#rootContainer {
|
||||||
width: min(100vw, 640px);
|
width: min(100%, 640px);
|
||||||
}
|
}
|
||||||
#rootContainer > * {
|
#rootContainer > * {
|
||||||
margin: 0 0 var(--default-gap-xxlarge) 0;
|
margin: 0 0 var(--default-gap-xxlarge) 0;
|
||||||
}
|
}
|
||||||
|
:root.mobile #rootContainer > * {
|
||||||
|
margin-bottom: var(--default-gap-xlarge);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@ -45,8 +51,12 @@ a {
|
||||||
color: var(--accent-surface-1);
|
color: var(--accent-surface-1);
|
||||||
fill: var(--accent-surface-1);
|
fill: var(--accent-surface-1);
|
||||||
font-size: 96px;
|
font-size: 96px;
|
||||||
|
line-height: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
:root.mobile #warningSign {
|
||||||
|
font-size: 64px;
|
||||||
|
}
|
||||||
#theURL {
|
#theURL {
|
||||||
color: var(--ink-2);
|
color: var(--ink-2);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -120,6 +130,13 @@ body[dir="rtl"] #toggleParse {
|
||||||
padding-inline-start: var(--default-gap-xsmall);
|
padding-inline-start: var(--default-gap-xsmall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#urlskip a {
|
||||||
|
display: block;
|
||||||
|
overflow-x: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
#actionContainer {
|
#actionContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="urlskip" hidden>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="li">
|
<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>
|
<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>
|
</div>
|
||||||
|
@ -42,13 +45,12 @@
|
||||||
<button id="bye" data-i18n="docblockedClose" type="button">_<span class="hover"></span></button>
|
<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>
|
<button id="proceed" class="preferred" data-i18n="docblockedDisable" type="button"><span class="hover"></span></button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div id="templates" style="display: none;">
|
<div id="templates" style="display: none;">
|
||||||
<li class="filterList">
|
<li class="filterList">
|
||||||
<a class="filterListSource" href="asset-viewer.html?url=" target="_blank"></a> <!--
|
<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>
|
--><a class="fa-icon filterListSupport hidden" href="#" target="_blank" rel="noopener noreferrer">home</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="lib/hsluv/hsluv-0.1.0.min.js"></script>
|
<script src="lib/hsluv/hsluv-0.1.0.min.js"></script>
|
||||||
|
|
|
@ -19,10 +19,8 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { i18n, i18n$ } from './i18n.js';
|
|
||||||
import { dom, qs$ } from './dom.js';
|
import { dom, qs$ } from './dom.js';
|
||||||
|
import { i18n, i18n$ } from './i18n.js';
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -47,7 +45,7 @@ let details = {};
|
||||||
|
|
||||||
let lists;
|
let lists;
|
||||||
for ( const rawFilter in response ) {
|
for ( const rawFilter in response ) {
|
||||||
if ( response.hasOwnProperty(rawFilter) ) {
|
if ( Object.prototype.hasOwnProperty.call(response, rawFilter) ) {
|
||||||
lists = response[rawFilter];
|
lists = response[rawFilter];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +78,24 @@ let details = {};
|
||||||
dom.text('#theURL > p > span:first-of-type', details.url);
|
dom.text('#theURL > p > span:first-of-type', details.url);
|
||||||
dom.text('#why', details.fs);
|
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
|
// https://github.com/gorhill/uBlock/issues/691
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const i18n =
|
const i18n =
|
||||||
|
@ -168,14 +166,14 @@ if ( isBackgroundProcess !== true ) {
|
||||||
const re = /\{\{\w+\}\}/g;
|
const re = /\{\{\w+\}\}/g;
|
||||||
let textout = '';
|
let textout = '';
|
||||||
for (;;) {
|
for (;;) {
|
||||||
let match = re.exec(textin);
|
const match = re.exec(textin);
|
||||||
if ( match === null ) {
|
if ( match === null ) {
|
||||||
textout += textin;
|
textout += textin;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
textout += textin.slice(0, match.index);
|
textout += textin.slice(0, match.index);
|
||||||
let prop = match[0].slice(2, -2);
|
let prop = match[0].slice(2, -2);
|
||||||
if ( dict.hasOwnProperty(prop) ) {
|
if ( Object.prototype.hasOwnProperty.call(dict, prop) ) {
|
||||||
textout += dict[prop].replace(/</g, '<')
|
textout += dict[prop].replace(/</g, '<')
|
||||||
.replace(/>/g, '>');
|
.replace(/>/g, '>');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -955,8 +955,8 @@ const PageStore = class {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
skipMainDocument(fctxt) {
|
skipMainDocument(fctxt, blocked) {
|
||||||
const directives = staticNetFilteringEngine.urlSkip(fctxt);
|
const directives = staticNetFilteringEngine.urlSkip(fctxt, blocked);
|
||||||
if ( directives === undefined ) { return; }
|
if ( directives === undefined ) { return; }
|
||||||
if ( logger.enabled !== true ) { return; }
|
if ( logger.enabled !== true ) { return; }
|
||||||
fctxt.pushFilters(directives.map(a => a.logData()));
|
fctxt.pushFilters(directives.map(a => a.logData()));
|
||||||
|
|
|
@ -197,7 +197,7 @@ const onBeforeRootFrameRequest = function(fctxt) {
|
||||||
if ( result !== 1 ) {
|
if ( result !== 1 ) {
|
||||||
pageStore.redirectNonBlockedRequest(fctxt);
|
pageStore.redirectNonBlockedRequest(fctxt);
|
||||||
} else {
|
} else {
|
||||||
pageStore.skipMainDocument(fctxt);
|
pageStore.skipMainDocument(fctxt, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,16 +216,20 @@ const onBeforeRootFrameRequest = function(fctxt) {
|
||||||
if ( result !== 1 ) { return; }
|
if ( result !== 1 ) { return; }
|
||||||
|
|
||||||
// No log data means no strict blocking (because we need to report why
|
// No log data means no strict blocking (because we need to report why
|
||||||
// the blocking occurs.
|
// the blocking occurs
|
||||||
if ( logData === undefined ) { return; }
|
if ( logData === undefined ) { return; }
|
||||||
|
|
||||||
// Blocked
|
// Blocked
|
||||||
|
|
||||||
|
// Find out the URL navigated to should the document not be strict-blocked
|
||||||
|
pageStore.skipMainDocument(fctxt, false);
|
||||||
|
|
||||||
const query = encodeURIComponent(JSON.stringify({
|
const query = encodeURIComponent(JSON.stringify({
|
||||||
url: requestURL,
|
url: requestURL,
|
||||||
hn: requestHostname,
|
|
||||||
dn: fctxt.getDomain() || requestHostname,
|
dn: fctxt.getDomain() || requestHostname,
|
||||||
fs: logData.raw
|
fs: logData.raw,
|
||||||
|
hn: requestHostname,
|
||||||
|
to: fctxt.redirectURL || '',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vAPI.tabs.replace(
|
vAPI.tabs.replace(
|
||||||
|
|
Loading…
Reference in New Issue