From 20b54185fac6f56ea871cc81554ee7ce8521d606 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sun, 27 Oct 2024 14:24:08 -0400 Subject: [PATCH] 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. --- src/_locales/en/messages.json | 4 ++++ src/css/document-blocked.css | 19 ++++++++++++++++++- src/document-blocked.html | 16 +++++++++------- src/js/document-blocked.js | 24 ++++++++++++++++++++---- src/js/i18n.js | 6 ++---- src/js/pagestore.js | 4 ++-- src/js/traffic.js | 12 ++++++++---- 7 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 433ff6077..de0a8af15 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -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" diff --git a/src/css/document-blocked.css b/src/css/document-blocked.css index 62d49216a..e0504230a 100644 --- a/src/css/document-blocked.css +++ b/src/css/document-blocked.css @@ -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; diff --git a/src/document-blocked.html b/src/document-blocked.html index 80a45461a..56d6a95a4 100644 --- a/src/document-blocked.html +++ b/src/document-blocked.html @@ -33,6 +33,9 @@ + +
@@ -42,13 +45,12 @@ - - + + diff --git a/src/js/document-blocked.js b/src/js/document-blocked.js index 59a6bc85a..82511436c 100644 --- a/src/js/document-blocked.js +++ b/src/js/document-blocked.js @@ -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 diff --git a/src/js/i18n.js b/src/js/i18n.js index 18c7e1456..6ce3b5f96 100644 --- a/src/js/i18n.js +++ b/src/js/i18n.js @@ -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, '>'); } else { diff --git a/src/js/pagestore.js b/src/js/pagestore.js index e6ca91f9a..4b19f3975 100644 --- a/src/js/pagestore.js +++ b/src/js/pagestore.js @@ -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())); diff --git a/src/js/traffic.js b/src/js/traffic.js index eab93be74..894554a80 100644 --- a/src/js/traffic.js +++ b/src/js/traffic.js @@ -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(