diff options
author | awy <awy@awy.one> | 2025-08-15 03:01:21 +0300 |
---|---|---|
committer | awy <awy@awy.one> | 2025-08-15 03:01:21 +0300 |
commit | a9370a08517668b3e98cc1d0bd42df407a76c220 (patch) | |
tree | 37e7bdb0e76f5495f798e077e45d377c0c3870c0 /data/extensions/uBlock0@raymondhill.net/js/document-blocked.js | |
parent | b73acfe395ea849fcd15c9886a7f4631f2b6f82b (diff) |
Diffstat (limited to 'data/extensions/uBlock0@raymondhill.net/js/document-blocked.js')
-rw-r--r-- | data/extensions/uBlock0@raymondhill.net/js/document-blocked.js | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/data/extensions/uBlock0@raymondhill.net/js/document-blocked.js b/data/extensions/uBlock0@raymondhill.net/js/document-blocked.js new file mode 100644 index 0000000..561c224 --- /dev/null +++ b/data/extensions/uBlock0@raymondhill.net/js/document-blocked.js @@ -0,0 +1,288 @@ +/******************************************************************************* + + uBlock Origin - a comprehensive, efficient content blocker + Copyright (C) 2015-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, i18n$ } from './i18n.js'; +import { faIconsInit } from './fa-icons.js'; + +/******************************************************************************/ + +const messaging = vAPI.messaging; +const details = {}; + +{ + const matches = /details=([^&]+)/.exec(window.location.search); + if ( matches !== null ) { + Object.assign(details, JSON.parse(decodeURIComponent(matches[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(details.url)); + +/******************************************************************************/ + +const lookupFilterLists = async ( ) => { + const response = await messaging.send('documentBlocked', { + what: 'listsFromNetFilter', + rawFilter: details.fs, + }); + if ( response instanceof Object === false ) { return; } + let lists; + for ( const rawFilter in response ) { + if ( Object.hasOwn(response, rawFilter) ) { + lists = response[rawFilter]; + break; + } + } + return lists; +}; + +/******************************************************************************/ + +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 = details.to; + dom.cl.add(link, 'code'); + link.append(urlToFragment(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 +// 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 { + 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'), details.url) === 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', ( ) => { + messaging.send('documentBlocked', { + what: 'closeThisTab', + }); + }); + qs$('#back').style.display = 'none'; +} + +/******************************************************************************/ + +const proceedToURL = function() { + window.location.replace(details.url); +}; + +const proceedTemporary = async function() { + await messaging.send('documentBlocked', { + what: 'temporarilyWhitelistDocument', + hostname: details.hn, + }); + proceedToURL(); +}; + +const proceedPermanent = async function() { + await messaging.send('documentBlocked', { + what: 'toggleHostnameSwitch', + name: 'no-strict-blocking', + hostname: details.hn, + 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(); + } +}); + +lookupFilterLists().then((lists = []) => { + let reason = details.reason; + if ( Boolean(reason) === false ) { + reason = lists.reduce((a, b) => a || b.reason, undefined); + } + if ( reason ) { + const msg = i18n$(`docblockedReason${reason.charAt(0).toUpperCase()}${reason.slice(1)}`); + if ( msg ) { reason = msg }; + } + const why = qs$(reason ? 'template.why-reason' : 'template.why') + .content + .cloneNode(true); + i18n.render(why); + dom.text(qs$(why, '.why'), details.fs); + if ( reason ) { + dom.text(qs$(why, 'summary'), `Reason: ${reason}`); + } + qs$('#why').append(why); + dom.cl.remove(dom.body, 'loading'); + + if ( lists.length === 0 ) { return; } + + const whyExtra = qs$('template.why-extra').content.cloneNode(true); + i18n.render(whyExtra); + + const listTemplate = qs$('template.filterList'); + const parent = qs$(whyExtra, '.why-extra'); + let separator = ''; + for ( const list of lists ) { + const listElem = listTemplate.content.cloneNode(true); + const sourceElem = qs$(listElem, '.filterListSource'); + sourceElem.href += encodeURIComponent(list.assetKey); + sourceElem.append(i18n.patchUnicodeFlags(list.title)); + if ( typeof list.supportURL === 'string' && list.supportURL !== '' ) { + const supportElem = qs$(listElem, '.filterListSupport'); + dom.attr(supportElem, 'href', list.supportURL); + dom.cl.remove(supportElem, 'hidden'); + } + parent.append(separator, listElem); + separator = '\u00A0\u2022\u00A0'; + } + faIconsInit(whyExtra); + qs$('#why .why').after(whyExtra); +}); + +/******************************************************************************/ |