mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-07 03:12:33 +01:00
Add support for click-to-load of embedded frames
Additionally, as a requirement to support click-to-load feature, redirected resources will from now on no longer be collapsed. Related issues: - https://github.com/gorhill/uBlock/issues/2688 - https://github.com/gorhill/uBlock/issues/3619 - https://github.com/gorhill/uBlock/issues/1899 This new feature should considered in its draft stage and it needs to be fine-tuned as per feedback. Important: Only embedded frames can be converted into click-to-load widgets, as only these can be properly shieded from access by page content. Examples of usage: ||youtube.com/embed/$3p,frame,redirect=clicktoload ||scribd.com/embeds/$3p,frame,redirect=clicktoload ||player.vimeo.com/video/$3p,frame,redirect=clicktoload
This commit is contained in:
parent
ba0b62ec97
commit
5916920985
48
src/css/click-to-load.css
Normal file
48
src/css/click-to-load.css
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
uBlock Origin - a browser extension to block requests.
|
||||||
|
Copyright (C) 2014-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 {
|
||||||
|
align-items: center;
|
||||||
|
background-color: var(--default-surface);
|
||||||
|
border: 1px solid var(--ubo-red);
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
left: 0;
|
||||||
|
padding: 2px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#frameURL {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 90%;
|
||||||
|
overflow: hidden;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clickToLoad {
|
||||||
|
cursor: default;
|
||||||
|
}
|
@ -74,6 +74,8 @@
|
|||||||
:root {
|
:root {
|
||||||
--font-size: 14px;
|
--font-size: 14px;
|
||||||
|
|
||||||
|
--ubo-red: #800000;
|
||||||
|
|
||||||
--default-ink: var(--ink-80);
|
--default-ink: var(--ink-80);
|
||||||
--default-ink-a4: var(--ink-80-a4);
|
--default-ink-a4: var(--ink-80-a4);
|
||||||
--default-ink-a50: var(--ink-80-a50);
|
--default-ink-a50: var(--ink-80-a50);
|
||||||
|
63
src/js/click-to-load.js
Normal file
63
src/js/click-to-load.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
uBlock Origin - a browser extension to block requests.
|
||||||
|
Copyright (C) 2014-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
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
(( ) => {
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
if ( typeof vAPI !== 'object' ) { return; }
|
||||||
|
|
||||||
|
const url = new URL(self.location.href);
|
||||||
|
const frameURL = url.searchParams.get('url');
|
||||||
|
const frameURLElem = document.getElementById('frameURL');
|
||||||
|
|
||||||
|
frameURLElem.textContent = frameURL;
|
||||||
|
|
||||||
|
const onWindowResize = function() {
|
||||||
|
document.body.style.width = `${self.innerWidth}px`;
|
||||||
|
document.body.style.height = `${self.innerHeight}px`;
|
||||||
|
};
|
||||||
|
|
||||||
|
onWindowResize();
|
||||||
|
|
||||||
|
self.addEventListener('resize', onWindowResize);
|
||||||
|
|
||||||
|
document.body.addEventListener('click', ev => {
|
||||||
|
if ( ev.isTrusted === false ) { return; }
|
||||||
|
//if ( ev.target === frameURLElem ) { return; }
|
||||||
|
vAPI.messaging.send('default', {
|
||||||
|
what: 'clickToLoad',
|
||||||
|
frameURL,
|
||||||
|
}).then(ok => {
|
||||||
|
if ( ok ) {
|
||||||
|
self.location.replace(frameURL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
})();
|
@ -35,7 +35,8 @@
|
|||||||
this.aliasURL = undefined;
|
this.aliasURL = undefined;
|
||||||
this.hostname = undefined;
|
this.hostname = undefined;
|
||||||
this.domain = undefined;
|
this.domain = undefined;
|
||||||
this.docId = undefined;
|
this.docId = -1;
|
||||||
|
this.frameId = -1;
|
||||||
this.docOrigin = undefined;
|
this.docOrigin = undefined;
|
||||||
this.docHostname = undefined;
|
this.docHostname = undefined;
|
||||||
this.docDomain = undefined;
|
this.docDomain = undefined;
|
||||||
@ -69,9 +70,13 @@
|
|||||||
this.type = details.type;
|
this.type = details.type;
|
||||||
this.setURL(details.url);
|
this.setURL(details.url);
|
||||||
this.aliasURL = details.aliasURL || undefined;
|
this.aliasURL = details.aliasURL || undefined;
|
||||||
this.docId = details.type !== 'sub_frame'
|
if ( details.type !== 'sub_frame' ) {
|
||||||
? details.frameId
|
this.docId = details.frameId;
|
||||||
: details.parentFrameId;
|
this.frameId = -1;
|
||||||
|
} else {
|
||||||
|
this.docId = details.parentFrameId;
|
||||||
|
this.frameId = details.frameId;
|
||||||
|
}
|
||||||
if ( this.tabId > 0 ) {
|
if ( this.tabId > 0 ) {
|
||||||
if ( this.docId === 0 ) {
|
if ( this.docId === 0 ) {
|
||||||
this.docOrigin = this.tabOrigin;
|
this.docOrigin = this.tabOrigin;
|
||||||
@ -81,7 +86,7 @@
|
|||||||
this.setDocOriginFromURL(details.documentUrl);
|
this.setDocOriginFromURL(details.documentUrl);
|
||||||
} else {
|
} else {
|
||||||
const pageStore = µBlock.pageStoreFromTabId(this.tabId);
|
const pageStore = µBlock.pageStoreFromTabId(this.tabId);
|
||||||
const docStore = pageStore && pageStore.getFrame(this.docId);
|
const docStore = pageStore && pageStore.getFrameStore(this.docId);
|
||||||
if ( docStore ) {
|
if ( docStore ) {
|
||||||
this.setDocOriginFromURL(docStore.rawURL);
|
this.setDocOriginFromURL(docStore.rawURL);
|
||||||
} else {
|
} else {
|
||||||
@ -109,6 +114,7 @@
|
|||||||
this.hostname = other.hostname;
|
this.hostname = other.hostname;
|
||||||
this.domain = other.domain;
|
this.domain = other.domain;
|
||||||
this.docId = other.docId;
|
this.docId = other.docId;
|
||||||
|
this.frameId = other.frameId;
|
||||||
this.docOrigin = other.docOrigin;
|
this.docOrigin = other.docOrigin;
|
||||||
this.docHostname = other.docHostname;
|
this.docHostname = other.docHostname;
|
||||||
this.docDomain = other.docDomain;
|
this.docDomain = other.docDomain;
|
||||||
|
@ -41,6 +41,15 @@
|
|||||||
|
|
||||||
const µb = µBlock;
|
const µb = µBlock;
|
||||||
|
|
||||||
|
const clickToLoad = function(request, sender) {
|
||||||
|
const { tabId, frameId } = µb.getMessageSenderDetails(sender);
|
||||||
|
if ( tabId === undefined || frameId === undefined ) { return false; }
|
||||||
|
const pageStore = µb.pageStoreFromTabId(tabId);
|
||||||
|
if ( pageStore === null ) { return false; }
|
||||||
|
pageStore.clickToLoad(frameId, request.frameURL);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const getDomainNames = function(targets) {
|
const getDomainNames = function(targets) {
|
||||||
const µburi = µb.URI;
|
const µburi = µb.URI;
|
||||||
return targets.map(target => {
|
return targets.map(target => {
|
||||||
@ -93,13 +102,17 @@ const onMessage = function(request, sender, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
var response;
|
let response;
|
||||||
|
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
case 'applyFilterListSelection':
|
case 'applyFilterListSelection':
|
||||||
response = µb.applyFilterListSelection(request);
|
response = µb.applyFilterListSelection(request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'clickToLoad':
|
||||||
|
response = clickToLoad(request, sender);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'createUserFilter':
|
case 'createUserFilter':
|
||||||
µb.createUserFilters(request);
|
µb.createUserFilters(request);
|
||||||
break;
|
break;
|
||||||
|
@ -84,6 +84,12 @@ const NetFilteringResultCache = class {
|
|||||||
this.hash = now;
|
this.hash = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forgetResult(fctxt) {
|
||||||
|
const key = `${fctxt.getDocHostname()} ${fctxt.type} ${fctxt.url}`;
|
||||||
|
this.results.delete(key);
|
||||||
|
this.blocked.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
empty() {
|
empty() {
|
||||||
this.blocked.clear();
|
this.blocked.clear();
|
||||||
this.results.clear();
|
this.results.clear();
|
||||||
@ -165,6 +171,7 @@ const FrameStore = class {
|
|||||||
init(frameURL) {
|
init(frameURL) {
|
||||||
this.t0 = Date.now();
|
this.t0 = Date.now();
|
||||||
this.exceptCname = undefined;
|
this.exceptCname = undefined;
|
||||||
|
this.clickToLoad = 0;
|
||||||
this.rawURL = frameURL;
|
this.rawURL = frameURL;
|
||||||
if ( frameURL !== undefined ) {
|
if ( frameURL !== undefined ) {
|
||||||
this.hostname = vAPI.hostnameFromURI(frameURL);
|
this.hostname = vAPI.hostnameFromURI(frameURL);
|
||||||
@ -253,7 +260,7 @@ const PageStore = class {
|
|||||||
|
|
||||||
this.frameAddCount = 0;
|
this.frameAddCount = 0;
|
||||||
this.frames = new Map();
|
this.frames = new Map();
|
||||||
this.setFrame(0, tabContext.rawURL);
|
this.setFrameURL(0, tabContext.rawURL);
|
||||||
|
|
||||||
// The current filtering context is cloned because:
|
// The current filtering context is cloned because:
|
||||||
// - We may be called with or without the current context having been
|
// - We may be called with or without the current context having been
|
||||||
@ -308,7 +315,7 @@ const PageStore = class {
|
|||||||
// As part of https://github.com/chrisaljoudi/uBlock/issues/405
|
// As part of https://github.com/chrisaljoudi/uBlock/issues/405
|
||||||
// URL changed, force a re-evaluation of filtering switch
|
// URL changed, force a re-evaluation of filtering switch
|
||||||
this.rawURL = tabContext.rawURL;
|
this.rawURL = tabContext.rawURL;
|
||||||
this.setFrame(0, this.rawURL);
|
this.setFrameURL(0, this.rawURL);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,20 +360,23 @@ const PageStore = class {
|
|||||||
this.frames.clear();
|
this.frames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
getFrame(frameId) {
|
getFrameStore(frameId) {
|
||||||
return this.frames.get(frameId) || null;
|
return this.frames.get(frameId) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
setFrame(frameId, frameURL) {
|
setFrameURL(frameId, frameURL) {
|
||||||
const frameStore = this.frames.get(frameId);
|
let frameStore = this.frames.get(frameId);
|
||||||
if ( frameStore !== undefined ) {
|
if ( frameStore !== undefined ) {
|
||||||
frameStore.init(frameURL);
|
frameStore.init(frameURL);
|
||||||
return;
|
} else {
|
||||||
|
frameStore = FrameStore.factory(frameURL);
|
||||||
|
this.frames.set(frameId, frameStore);
|
||||||
|
this.frameAddCount += 1;
|
||||||
|
if ( (this.frameAddCount & 0b111111) === 0 ) {
|
||||||
|
this.pruneFrames();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.frames.set(frameId, FrameStore.factory(frameURL));
|
return frameStore;
|
||||||
this.frameAddCount += 1;
|
|
||||||
if ( (this.frameAddCount & 0b111111) !== 0 ) { return; }
|
|
||||||
this.pruneFrames();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is no event to tell us a specific subframe has been removed from
|
// There is no event to tell us a specific subframe has been removed from
|
||||||
@ -597,6 +607,22 @@ const PageStore = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Click-to-load:
|
||||||
|
// When frameId is not -1, the resource is always sub_frame.
|
||||||
|
if ( result === 1 && fctxt.frameId !== -1 ) {
|
||||||
|
const docStore = this.getFrameStore(fctxt.frameId);
|
||||||
|
if ( docStore !== null && docStore.clickToLoad !== 0 ) {
|
||||||
|
result = 2;
|
||||||
|
if ( µb.logger.enabled ) {
|
||||||
|
fctxt.setFilter({
|
||||||
|
result,
|
||||||
|
source: 'network',
|
||||||
|
raw: 'click-to-load',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( cacheableResult ) {
|
if ( cacheableResult ) {
|
||||||
this.netFilteringCache.rememberResult(fctxt, result);
|
this.netFilteringCache.rememberResult(fctxt, result);
|
||||||
} else if (
|
} else if (
|
||||||
@ -696,11 +722,19 @@ const PageStore = class {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clickToLoad(frameId, frameURL) {
|
||||||
|
let frameStore = this.getFrameStore(frameId);
|
||||||
|
if ( frameStore === null ) {
|
||||||
|
frameStore = this.setFrameURL(frameId, frameURL);
|
||||||
|
}
|
||||||
|
frameStore.clickToLoad = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
shouldExceptCname(fctxt) {
|
shouldExceptCname(fctxt) {
|
||||||
let exceptCname;
|
let exceptCname;
|
||||||
let frameStore;
|
let frameStore;
|
||||||
if ( fctxt.docId !== undefined ) {
|
if ( fctxt.docId !== undefined ) {
|
||||||
frameStore = this.getFrame(fctxt.docId);
|
frameStore = this.getFrameStore(fctxt.docId);
|
||||||
if ( frameStore instanceof Object ) {
|
if ( frameStore instanceof Object ) {
|
||||||
exceptCname = frameStore.exceptCname;
|
exceptCname = frameStore.exceptCname;
|
||||||
}
|
}
|
||||||
@ -742,10 +776,12 @@ const PageStore = class {
|
|||||||
// content script-side (i.e. `iframes` -- unlike `img`).
|
// content script-side (i.e. `iframes` -- unlike `img`).
|
||||||
if ( Array.isArray(resources) && resources.length !== 0 ) {
|
if ( Array.isArray(resources) && resources.length !== 0 ) {
|
||||||
for ( const resource of resources ) {
|
for ( const resource of resources ) {
|
||||||
this.filterRequest(
|
const result = this.filterRequest(
|
||||||
fctxt.setType(resource.type)
|
fctxt.setType(resource.type).setURL(resource.url)
|
||||||
.setURL(resource.url)
|
|
||||||
);
|
);
|
||||||
|
if ( result === 1 && µb.redirectEngine.toURL(fctxt) ) {
|
||||||
|
this.forgetBlockedResource(fctxt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( this.netFilteringCache.hash === response.hash ) { return; }
|
if ( this.netFilteringCache.hash === response.hash ) { return; }
|
||||||
@ -753,6 +789,11 @@ const PageStore = class {
|
|||||||
response.blockedResources =
|
response.blockedResources =
|
||||||
this.netFilteringCache.lookupAllBlocked(fctxt.getDocHostname());
|
this.netFilteringCache.lookupAllBlocked(fctxt.getDocHostname());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forgetBlockedResource(fctxt) {
|
||||||
|
if ( this.collapsibleResources.has(fctxt.type) === false ) { return; }
|
||||||
|
this.netFilteringCache.forgetResult(fctxt);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PageStore.prototype.cacheableResults = new Set([
|
PageStore.prototype.cacheableResults = new Set([
|
||||||
|
@ -67,6 +67,10 @@ const redirectableResources = new Map([
|
|||||||
[ 'chartbeat.js', {
|
[ 'chartbeat.js', {
|
||||||
alias: 'static.chartbeat.com/chartbeat.js',
|
alias: 'static.chartbeat.com/chartbeat.js',
|
||||||
} ],
|
} ],
|
||||||
|
[ 'click-to-load.html', {
|
||||||
|
alias: 'clicktoload',
|
||||||
|
params: [ 'url' ],
|
||||||
|
} ],
|
||||||
[ 'doubleclick_instream_ad_status.js', {
|
[ 'doubleclick_instream_ad_status.js', {
|
||||||
alias: 'doubleclick.net/instream/ad_status.js',
|
alias: 'doubleclick.net/instream/ad_status.js',
|
||||||
} ],
|
} ],
|
||||||
@ -191,6 +195,7 @@ const RedirectEntry = class {
|
|||||||
this.mime = '';
|
this.mime = '';
|
||||||
this.data = '';
|
this.data = '';
|
||||||
this.warURL = undefined;
|
this.warURL = undefined;
|
||||||
|
this.params = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent redirection to web accessible resources when the request is
|
// Prevent redirection to web accessible resources when the request is
|
||||||
@ -208,7 +213,15 @@ const RedirectEntry = class {
|
|||||||
fctxt instanceof Object &&
|
fctxt instanceof Object &&
|
||||||
fctxt.type !== 'xmlhttprequest'
|
fctxt.type !== 'xmlhttprequest'
|
||||||
) {
|
) {
|
||||||
return `${this.warURL}${vAPI.warSecret()}`;
|
let url = `${this.warURL}${vAPI.warSecret()}`;
|
||||||
|
if ( this.params !== undefined ) {
|
||||||
|
for ( const name of this.params ) {
|
||||||
|
const value = fctxt[name];
|
||||||
|
if ( value === undefined ) { continue; }
|
||||||
|
url += `&${name}=${encodeURIComponent(value)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
}
|
}
|
||||||
if ( this.data === undefined ) { return; }
|
if ( this.data === undefined ) { return; }
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/701
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/701
|
||||||
@ -251,6 +264,7 @@ const RedirectEntry = class {
|
|||||||
r.mime = selfie.mime;
|
r.mime = selfie.mime;
|
||||||
r.data = selfie.data;
|
r.data = selfie.data;
|
||||||
r.warURL = selfie.warURL;
|
r.warURL = selfie.warURL;
|
||||||
|
r.params = selfie.params;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -721,6 +735,7 @@ RedirectEngine.prototype.loadBuiltinResources = function() {
|
|||||||
mime: mimeFromName(name),
|
mime: mimeFromName(name),
|
||||||
data,
|
data,
|
||||||
warURL: vAPI.getURL(`/web_accessible_resources/${name}`),
|
warURL: vAPI.getURL(`/web_accessible_resources/${name}`),
|
||||||
|
params: details.params,
|
||||||
});
|
});
|
||||||
this.resources.set(name, entry);
|
this.resources.set(name, entry);
|
||||||
if ( details.alias !== undefined ) {
|
if ( details.alias !== undefined ) {
|
||||||
|
@ -101,7 +101,7 @@ const onBeforeRequest = function(details) {
|
|||||||
details.type === 'sub_frame' &&
|
details.type === 'sub_frame' &&
|
||||||
details.aliasURL === undefined
|
details.aliasURL === undefined
|
||||||
) {
|
) {
|
||||||
pageStore.setFrame(details.frameId, details.url);
|
pageStore.setFrameURL(details.frameId, details.url);
|
||||||
}
|
}
|
||||||
if ( result === 2 ) {
|
if ( result === 2 ) {
|
||||||
return { cancel: false };
|
return { cancel: false };
|
||||||
@ -113,10 +113,13 @@ const onBeforeRequest = function(details) {
|
|||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/949
|
// https://github.com/gorhill/uBlock/issues/949
|
||||||
// Redirect blocked request?
|
// Redirect blocked request?
|
||||||
|
// https://github.com/gorhill/uBlock/issues/3619
|
||||||
|
// Don't collapse redirected resources
|
||||||
if ( µb.hiddenSettings.ignoreRedirectFilters !== true ) {
|
if ( µb.hiddenSettings.ignoreRedirectFilters !== true ) {
|
||||||
const url = µb.redirectEngine.toURL(fctxt);
|
const url = µb.redirectEngine.toURL(fctxt);
|
||||||
if ( url !== undefined ) {
|
if ( url !== undefined ) {
|
||||||
pageStore.internalRedirectionCount += 1;
|
pageStore.internalRedirectionCount += 1;
|
||||||
|
pageStore.forgetBlockedResource(fctxt);
|
||||||
if ( µb.logger.enabled ) {
|
if ( µb.logger.enabled ) {
|
||||||
fctxt.setRealm('redirect')
|
fctxt.setRealm('redirect')
|
||||||
.setFilter({ source: 'redirect', raw: µb.redirectEngine.resourceNameRegister })
|
.setFilter({ source: 'redirect', raw: µb.redirectEngine.resourceNameRegister })
|
||||||
|
25
src/web_accessible_resources/click-to-load.html
Normal file
25
src/web_accessible_resources/click-to-load.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html id="ublock0-clicktoload">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>uBlock Origin Click-to-Load</title>
|
||||||
|
<link rel="stylesheet" href="../css/themes/default.css">
|
||||||
|
<link rel="stylesheet" href="../css/common.css">
|
||||||
|
<link rel="stylesheet" href="../css/click-to-load.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<span class="logo"><img src="../img/ublock.svg"></span>
|
||||||
|
<span id="clickToLoad">Click to load</span>
|
||||||
|
<div id="frameURL"></div>
|
||||||
|
|
||||||
|
<script src="../js/vapi.js"></script>
|
||||||
|
<script src="../js/vapi-common.js"></script>
|
||||||
|
<script src="../js/vapi-client.js"></script>
|
||||||
|
<script src="../js/i18n.js"></script>
|
||||||
|
<script src="../js/click-to-load.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user