mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 01:02:08 +01:00
Add ability to lookup effective context from store of frames
Content scripts can't properly look up effective context for sandboxed frames. This commit add ability to extract effective context from already existing store of frames used for each tab.
This commit is contained in:
parent
37c9f966ac
commit
114012ae11
5 changed files with 58 additions and 27 deletions
|
@ -1735,7 +1735,6 @@ vAPI.injectScriptlet = function(doc, text) {
|
|||
vAPI.messaging.send('contentscript', {
|
||||
what: 'retrieveContentScriptParameters',
|
||||
url: vAPI.effectiveSelf.location.href,
|
||||
charset: document.characterSet,
|
||||
}).then(response => {
|
||||
bootstrapPhase1(response);
|
||||
});
|
||||
|
|
|
@ -557,6 +557,13 @@ const retrieveContentScriptParameters = function(sender, request) {
|
|||
return;
|
||||
}
|
||||
|
||||
// A content script may not always be able to successfully look up the
|
||||
// effective context, hence in such case we try again to look up here
|
||||
// using cached information about embedded frames.
|
||||
if ( frameId !== 0 && request.url.startsWith('about:') ) {
|
||||
request.url = pageStore.getEffectiveFrameURL(sender);
|
||||
}
|
||||
|
||||
const noCosmeticFiltering = pageStore.noCosmeticFiltering === true;
|
||||
|
||||
const response = {
|
||||
|
|
|
@ -181,12 +181,13 @@ const frameStoreJunkyard = [];
|
|||
const frameStoreJunkyardMax = 50;
|
||||
|
||||
const FrameStore = class {
|
||||
constructor(frameURL) {
|
||||
this.init(frameURL);
|
||||
constructor(frameURL, parentId) {
|
||||
this.init(frameURL, parentId);
|
||||
}
|
||||
|
||||
init(frameURL) {
|
||||
init(frameURL, parentId) {
|
||||
this.t0 = Date.now();
|
||||
this.parentId = parentId;
|
||||
this.exceptCname = undefined;
|
||||
this.clickToLoad = false;
|
||||
this.rawURL = frameURL;
|
||||
|
@ -199,7 +200,6 @@ const FrameStore = class {
|
|||
}
|
||||
|
||||
dispose() {
|
||||
this.exceptCname = undefined;
|
||||
this.rawURL = this.hostname = this.domain = '';
|
||||
if ( frameStoreJunkyard.length < frameStoreJunkyardMax ) {
|
||||
frameStoreJunkyard.push(this);
|
||||
|
@ -207,12 +207,12 @@ const FrameStore = class {
|
|||
return null;
|
||||
}
|
||||
|
||||
static factory(frameURL) {
|
||||
static factory(frameURL, parentId = -1) {
|
||||
const entry = frameStoreJunkyard.pop();
|
||||
if ( entry === undefined ) {
|
||||
return new FrameStore(frameURL);
|
||||
return new FrameStore(frameURL, parentId);
|
||||
}
|
||||
return entry.init(frameURL);
|
||||
return entry.init(frameURL, parentId);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -277,7 +277,7 @@ const PageStore = class {
|
|||
|
||||
this.frameAddCount = 0;
|
||||
this.frames = new Map();
|
||||
this.setFrameURL(0, tabContext.rawURL);
|
||||
this.setFrameURL({ url: tabContext.rawURL });
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/314
|
||||
const masterSwitch = tabContext.getNetFilteringSwitch();
|
||||
|
@ -324,7 +324,7 @@ const PageStore = class {
|
|||
// As part of https://github.com/chrisaljoudi/uBlock/issues/405
|
||||
// URL changed, force a re-evaluation of filtering switch
|
||||
this.rawURL = tabContext.rawURL;
|
||||
this.setFrameURL(0, this.rawURL);
|
||||
this.setFrameURL({ url: this.rawURL });
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -375,14 +375,20 @@ const PageStore = class {
|
|||
return this.frames.get(frameId) || null;
|
||||
}
|
||||
|
||||
setFrameURL(frameId, frameURL) {
|
||||
setFrameURL(details) {
|
||||
let { frameId, url, parentFrameId } = details;
|
||||
if ( frameId === undefined ) { frameId = 0; }
|
||||
if ( parentFrameId === undefined ) { parentFrameId = -1; }
|
||||
let frameStore = this.frames.get(frameId);
|
||||
if ( frameStore !== undefined ) {
|
||||
return frameURL === frameStore.rawURL
|
||||
? frameStore
|
||||
: frameStore.init(frameURL);
|
||||
if ( url === frameStore.rawURL ) {
|
||||
frameStore.parentId = parentFrameId;
|
||||
} else {
|
||||
frameStore.init(url, parentFrameId);
|
||||
}
|
||||
frameStore = FrameStore.factory(frameURL);
|
||||
return frameStore;
|
||||
}
|
||||
frameStore = FrameStore.factory(url, parentFrameId);
|
||||
this.frames.set(frameId, frameStore);
|
||||
this.frameAddCount += 1;
|
||||
if ( (this.frameAddCount & 0b111111) === 0 ) {
|
||||
|
@ -391,6 +397,20 @@ const PageStore = class {
|
|||
return frameStore;
|
||||
}
|
||||
|
||||
getEffectiveFrameURL(sender) {
|
||||
let { frameId } = sender;
|
||||
for (;;) {
|
||||
const frameStore = this.getFrameStore(frameId);
|
||||
if ( frameStore === null ) { break; }
|
||||
if ( frameStore.rawURL.startsWith('about:') === false ) {
|
||||
return frameStore.rawURL;
|
||||
}
|
||||
frameId = frameStore.parentId;
|
||||
if ( frameId === -1 ) { break; }
|
||||
}
|
||||
return sender.frameURL;
|
||||
}
|
||||
|
||||
// There is no event to tell us a specific subframe has been removed from
|
||||
// the main document. The code below will remove subframes which are no
|
||||
// longer present in the root document. Removing obsolete subframes is
|
||||
|
@ -851,7 +871,7 @@ const PageStore = class {
|
|||
clickToLoad(frameId, frameURL) {
|
||||
let frameStore = this.getFrameStore(frameId);
|
||||
if ( frameStore === null ) {
|
||||
frameStore = this.setFrameURL(frameId, frameURL);
|
||||
frameStore = this.setFrameURL({ frameId, url: frameURL });
|
||||
}
|
||||
this.netFilteringCache.forgetResult(
|
||||
this.tabHostname,
|
||||
|
|
|
@ -875,20 +875,25 @@ vAPI.Tabs = class extends vAPI.Tabs {
|
|||
onNavigation(details) {
|
||||
super.onNavigation(details);
|
||||
const µb = µBlock;
|
||||
if ( details.frameId === 0 ) {
|
||||
µb.tabContextManager.commit(details.tabId, details.url);
|
||||
let pageStore = µb.bindTabToPageStore(details.tabId, 'tabCommitted');
|
||||
if ( pageStore ) {
|
||||
pageStore.journalAddRootFrame('committed', details.url);
|
||||
const { frameId, tabId, url } = details;
|
||||
if ( frameId === 0 ) {
|
||||
µb.tabContextManager.commit(tabId, url);
|
||||
const pageStore = µb.bindTabToPageStore(tabId, 'tabCommitted');
|
||||
if ( pageStore !== null ) {
|
||||
pageStore.journalAddRootFrame('committed', url);
|
||||
}
|
||||
}
|
||||
if ( µb.canInjectScriptletsNow && µb.URI.isNetworkURI(details.url) ) {
|
||||
const pageStore = µb.pageStoreFromTabId(details.tabId);
|
||||
if ( pageStore !== null && pageStore.getNetFilteringSwitch() ) {
|
||||
const pageStore = µb.pageStoreFromTabId(tabId);
|
||||
if ( pageStore === null ) { return; }
|
||||
pageStore.setFrameURL(details);
|
||||
if (
|
||||
µb.canInjectScriptletsNow &&
|
||||
µb.URI.isNetworkURI(url) &&
|
||||
pageStore.getNetFilteringSwitch()
|
||||
) {
|
||||
µb.scriptletFilteringEngine.injectNow(details);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It may happen the URL in the tab changes, while the page's document
|
||||
// stays the same (for instance, Google Maps). Without this listener,
|
||||
|
|
|
@ -113,7 +113,7 @@ const onBeforeRequest = function(details) {
|
|||
details.parentFrameId !== -1 &&
|
||||
details.aliasURL === undefined
|
||||
) {
|
||||
pageStore.setFrameURL(details.frameId, details.url);
|
||||
pageStore.setFrameURL(details);
|
||||
}
|
||||
|
||||
if ( result === 2 ) {
|
||||
|
|
Loading…
Reference in a new issue