mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 09:07:54 +01:00
fix #2290
This commit is contained in:
parent
a927725bd9
commit
a303c7800e
3 changed files with 77 additions and 124 deletions
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
uBlock Origin - a browser extension to block requests.
|
||||||
Copyright (C) 2014-2016 The uBlock Origin authors
|
Copyright (C) 2014-2017 The uBlock Origin authors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -161,7 +161,7 @@ var contentObserver = {
|
||||||
popupMessageName: hostName + ':shouldLoadPopup',
|
popupMessageName: hostName + ':shouldLoadPopup',
|
||||||
ignoredPopups: new WeakMap(),
|
ignoredPopups: new WeakMap(),
|
||||||
uniqueSandboxId: 1,
|
uniqueSandboxId: 1,
|
||||||
canE10S: Services.vc.compare(Services.appinfo.platformVersion, '44') > 0,
|
modernFirefox: Services.vc.compare(Services.appinfo.platformVersion, '44') > 0,
|
||||||
|
|
||||||
get componentRegistrar() {
|
get componentRegistrar() {
|
||||||
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||||
|
@ -189,31 +189,40 @@ var contentObserver = {
|
||||||
|
|
||||||
register: function() {
|
register: function() {
|
||||||
Services.obs.addObserver(this, 'document-element-inserted', true);
|
Services.obs.addObserver(this, 'document-element-inserted', true);
|
||||||
|
Services.obs.addObserver(this, 'content-document-global-created', true);
|
||||||
|
|
||||||
this.componentRegistrar.registerFactory(
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1232354
|
||||||
this.classID,
|
// For modern versions of Firefox, the frameId/parentFrameId
|
||||||
this.classDescription,
|
// information can be found in channel.loadInfo of the HTTP observer.
|
||||||
this.contractID,
|
if ( this.modernFirefox !== true ) {
|
||||||
this
|
this.componentRegistrar.registerFactory(
|
||||||
);
|
this.classID,
|
||||||
this.categoryManager.addCategoryEntry(
|
this.classDescription,
|
||||||
'content-policy',
|
this.contractID,
|
||||||
this.contractID,
|
this
|
||||||
this.contractID,
|
);
|
||||||
false,
|
this.categoryManager.addCategoryEntry(
|
||||||
true
|
'content-policy',
|
||||||
);
|
this.contractID,
|
||||||
|
this.contractID,
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
unregister: function() {
|
unregister: function() {
|
||||||
Services.obs.removeObserver(this, 'document-element-inserted');
|
Services.obs.removeObserver(this, 'document-element-inserted');
|
||||||
|
Services.obs.removeObserver(this, 'content-document-global-created');
|
||||||
|
|
||||||
this.componentRegistrar.unregisterFactory(this.classID, this);
|
if ( this.modernFirefox !== true ) {
|
||||||
this.categoryManager.deleteCategoryEntry(
|
this.componentRegistrar.unregisterFactory(this.classID, this);
|
||||||
'content-policy',
|
this.categoryManager.deleteCategoryEntry(
|
||||||
this.contractID,
|
'content-policy',
|
||||||
false
|
this.contractID,
|
||||||
);
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getFrameId: function(win) {
|
getFrameId: function(win) {
|
||||||
|
@ -223,48 +232,6 @@ var contentObserver = {
|
||||||
.outerWindowID;
|
.outerWindowID;
|
||||||
},
|
},
|
||||||
|
|
||||||
handlePopup: function(location, origin, context) {
|
|
||||||
let openeeContext = context.contentWindow || context;
|
|
||||||
if (
|
|
||||||
typeof openeeContext.opener !== 'object' ||
|
|
||||||
openeeContext.opener === null ||
|
|
||||||
openeeContext.opener === context ||
|
|
||||||
this.ignoredPopups.has(openeeContext)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// https://github.com/gorhill/uBlock/issues/452
|
|
||||||
// Use location of top window, not that of a frame, as this
|
|
||||||
// would cause tab id lookup (necessary for popup blocking) to
|
|
||||||
// always fail.
|
|
||||||
// https://github.com/gorhill/uBlock/issues/1305
|
|
||||||
// Opener could be a dead object, using it would cause a throw.
|
|
||||||
// Repro case:
|
|
||||||
// - Open http://delishows.to/show/chicago-med/season/1/episode/6
|
|
||||||
// - Click anywhere in the background
|
|
||||||
let openerURL = null;
|
|
||||||
try {
|
|
||||||
let opener = openeeContext.opener.top || openeeContext.opener;
|
|
||||||
openerURL = opener.location && opener.location.href;
|
|
||||||
} catch(ex) {
|
|
||||||
}
|
|
||||||
// If no valid opener URL found, use the origin URL.
|
|
||||||
if ( openerURL === null ) {
|
|
||||||
openerURL = origin.asciiSpec;
|
|
||||||
}
|
|
||||||
let messageManager = getMessageManager(openeeContext);
|
|
||||||
if ( messageManager === null ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( typeof messageManager.sendRpcMessage === 'function' ) {
|
|
||||||
// https://bugzil.la/1092216
|
|
||||||
messageManager.sendRpcMessage(this.popupMessageName, openerURL);
|
|
||||||
} else {
|
|
||||||
// Compatibility for older versions
|
|
||||||
messageManager.sendSyncMessage(this.popupMessageName, openerURL);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// https://bugzil.la/612921
|
// https://bugzil.la/612921
|
||||||
shouldLoad: function(type, location, origin, context) {
|
shouldLoad: function(type, location, origin, context) {
|
||||||
// For whatever reason, sometimes the global scope is completely
|
// For whatever reason, sometimes the global scope is completely
|
||||||
|
@ -278,17 +245,6 @@ var contentObserver = {
|
||||||
return this.ACCEPT;
|
return this.ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( type === this.MAIN_FRAME ) {
|
|
||||||
this.handlePopup(location, origin, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1232354
|
|
||||||
// For modern versions of Firefox, the frameId/parentFrameId
|
|
||||||
// information can be found in channel.loadInfo of the HTTP observer.
|
|
||||||
if ( this.canE10S ) {
|
|
||||||
return this.ACCEPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !location.schemeIs('http') && !location.schemeIs('https') ) {
|
if ( !location.schemeIs('http') && !location.schemeIs('https') ) {
|
||||||
return this.ACCEPT;
|
return this.ACCEPT;
|
||||||
}
|
}
|
||||||
|
@ -504,17 +460,44 @@ var contentObserver = {
|
||||||
},
|
},
|
||||||
|
|
||||||
ignorePopup: function(e) {
|
ignorePopup: function(e) {
|
||||||
if ( e.isTrusted === false ) {
|
if ( e.isTrusted === false ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let contObs = contentObserver;
|
let contObs = contentObserver;
|
||||||
contObs.ignoredPopups.set(this, true);
|
contObs.ignoredPopups.set(this, true);
|
||||||
this.removeEventListener('keydown', contObs.ignorePopup, true);
|
this.removeEventListener('keydown', contObs.ignorePopup, true);
|
||||||
this.removeEventListener('mousedown', contObs.ignorePopup, true);
|
this.removeEventListener('mousedown', contObs.ignorePopup, true);
|
||||||
},
|
},
|
||||||
|
lookupPopupOpenerURL: function(popup) {
|
||||||
|
var opener, openerURL;
|
||||||
|
for (;;) {
|
||||||
|
opener = popup.opener;
|
||||||
|
if ( !opener ) { break; }
|
||||||
|
if ( opener.top ) { opener = opener.top; }
|
||||||
|
if ( opener === popup ) { break; }
|
||||||
|
if ( !opener.location ) { break; }
|
||||||
|
if ( !this.reGoodPopupURLs.test(opener.location.href) ) { break; }
|
||||||
|
openerURL = opener.location.href;
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/255
|
||||||
|
// - Mind chained about:blank popups.
|
||||||
|
if ( openerURL !== 'about:blank' ) { break; }
|
||||||
|
popup = opener;
|
||||||
|
}
|
||||||
|
return openerURL;
|
||||||
|
},
|
||||||
|
reGoodPopupURLs: /^(?:about:blank|blob:|data:|https?:|javascript:)/,
|
||||||
|
|
||||||
|
observe: function(subject, topic) {
|
||||||
|
// https://github.com/gorhill/uBlock/issues/2290
|
||||||
|
if ( topic === 'content-document-global-created' ) {
|
||||||
|
if ( subject !== subject.top ) { return; }
|
||||||
|
if ( this.ignoredPopups.has(subject) ) { return; }
|
||||||
|
let openerURL = this.lookupPopupOpenerURL(subject);
|
||||||
|
if ( !openerURL ) { return; }
|
||||||
|
let messager = getMessageManager(subject);
|
||||||
|
if ( !messager ) { return; }
|
||||||
|
messager.sendAsyncMessage(this.popupMessageName, openerURL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
observe: function(doc) {
|
|
||||||
// For whatever reason, sometimes the global scope is completely
|
// For whatever reason, sometimes the global scope is completely
|
||||||
// uninitialized at this point. Repro steps:
|
// uninitialized at this point. Repro steps:
|
||||||
// - Launch FF with uBlock enabled
|
// - Launch FF with uBlock enabled
|
||||||
|
@ -522,14 +505,11 @@ var contentObserver = {
|
||||||
// - Enable uBlock
|
// - Enable uBlock
|
||||||
// - Services and all other global variables are undefined
|
// - Services and all other global variables are undefined
|
||||||
// Hopefully will eventually understand why this happens.
|
// Hopefully will eventually understand why this happens.
|
||||||
if ( Services === undefined ) {
|
if ( Services === undefined ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let doc = subject;
|
||||||
let win = doc.defaultView || null;
|
let win = doc.defaultView || null;
|
||||||
if ( win === null ) {
|
if ( win === null ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( win.opener && this.ignoredPopups.has(win) === false ) {
|
if ( win.opener && this.ignoredPopups.has(win) === false ) {
|
||||||
win.addEventListener('keydown', this.ignorePopup, true);
|
win.addEventListener('keydown', this.ignorePopup, true);
|
||||||
|
@ -543,17 +523,13 @@ var contentObserver = {
|
||||||
// TODO: We may have to exclude more types, for now let's be
|
// TODO: We may have to exclude more types, for now let's be
|
||||||
// conservative and focus only on the one issue reported, i.e. let's
|
// conservative and focus only on the one issue reported, i.e. let's
|
||||||
// not test against 'text/html'.
|
// not test against 'text/html'.
|
||||||
if ( doc.contentType.startsWith('image/') ) {
|
if ( doc.contentType.startsWith('image/') ) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let loc = win.location;
|
let loc = win.location;
|
||||||
|
|
||||||
if ( loc.protocol !== 'http:' && loc.protocol !== 'https:' && loc.protocol !== 'file:' ) {
|
if ( loc.protocol !== 'http:' && loc.protocol !== 'https:' && loc.protocol !== 'file:' ) {
|
||||||
if ( loc.protocol === 'chrome:' && loc.host === hostName ) {
|
if ( loc.protocol === 'chrome:' && loc.host === hostName ) {
|
||||||
this.initContentScripts(win);
|
this.initContentScripts(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
// What about data: and about:blank?
|
// What about data: and about:blank?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
uBlock Origin - a browser extension to block requests.
|
||||||
Copyright (C) 2014-2106 The uBlock Origin authors
|
Copyright (C) 2014-2107 The uBlock Origin authors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -2361,26 +2361,14 @@ vAPI.net.registerListeners = function() {
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var shouldLoadPopupListenerMessageName = location.host + ':shouldLoadPopup',
|
var shouldLoadPopupListenerMessageName = location.host + ':shouldLoadPopup';
|
||||||
shouldLoadPopupListenerMap = new Map(),
|
var shouldLoadPopupListener = function(e) {
|
||||||
shouldLoadPopupListenerMapToD = 0;
|
if ( typeof vAPI.tabs.onPopupCreated !== 'function' ) { return; }
|
||||||
var shouldLoadPopupListener = function(openerURL, target) {
|
var target = e.target,
|
||||||
var popupTabId = tabWatcher.tabIdFromTarget(target),
|
openerURL = e.data,
|
||||||
popupURL = target.currentURI && target.currentURI.asciiSpec || '',
|
popupTabId = tabWatcher.tabIdFromTarget(target),
|
||||||
openerTabId,
|
openerTabId,
|
||||||
uri;
|
uri;
|
||||||
if ( shouldLoadPopupListenerMapToD > Date.now() ) {
|
|
||||||
openerTabId = shouldLoadPopupListenerMap.get(popupURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/uBlockOrigin/uAssets/issues/255
|
|
||||||
// Handle chained popups.
|
|
||||||
if ( openerTabId !== undefined ) {
|
|
||||||
shouldLoadPopupListenerMap.set(popupURL, openerTabId);
|
|
||||||
shouldLoadPopupListenerMapToD = Date.now() + 10000;
|
|
||||||
vAPI.tabs.onPopupCreated(popupTabId, openerTabId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( var browser of tabWatcher.browsers() ) {
|
for ( var browser of tabWatcher.browsers() ) {
|
||||||
uri = browser.currentURI;
|
uri = browser.currentURI;
|
||||||
|
@ -2398,24 +2386,14 @@ vAPI.net.registerListeners = function() {
|
||||||
openerTabId = tabWatcher.tabIdFromTarget(browser);
|
openerTabId = tabWatcher.tabIdFromTarget(browser);
|
||||||
if ( openerTabId === popupTabId ) { continue; }
|
if ( openerTabId === popupTabId ) { continue; }
|
||||||
|
|
||||||
shouldLoadPopupListenerMap = new Map();
|
|
||||||
shouldLoadPopupListenerMapToD = Date.now() + 10000;
|
|
||||||
shouldLoadPopupListenerMap.set(popupURL, openerTabId);
|
|
||||||
vAPI.tabs.onPopupCreated(popupTabId, openerTabId);
|
vAPI.tabs.onPopupCreated(popupTabId, openerTabId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var shouldLoadPopupListenerAsync = function(e) {
|
|
||||||
if ( typeof vAPI.tabs.onPopupCreated !== 'function' ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// We are handling a synchronous message: do not block.
|
|
||||||
vAPI.setTimeout(shouldLoadPopupListener.bind(null, e.data, e.target), 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
vAPI.messaging.globalMessageManager.addMessageListener(
|
vAPI.messaging.globalMessageManager.addMessageListener(
|
||||||
shouldLoadPopupListenerMessageName,
|
shouldLoadPopupListenerMessageName,
|
||||||
shouldLoadPopupListenerAsync
|
shouldLoadPopupListener
|
||||||
);
|
);
|
||||||
|
|
||||||
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
||||||
|
@ -2501,7 +2479,7 @@ vAPI.net.registerListeners = function() {
|
||||||
cleanupTasks.push(function() {
|
cleanupTasks.push(function() {
|
||||||
vAPI.messaging.globalMessageManager.removeMessageListener(
|
vAPI.messaging.globalMessageManager.removeMessageListener(
|
||||||
shouldLoadPopupListenerMessageName,
|
shouldLoadPopupListenerMessageName,
|
||||||
shouldLoadPopupListenerAsync
|
shouldLoadPopupListener
|
||||||
);
|
);
|
||||||
|
|
||||||
vAPI.messaging.globalMessageManager.removeMessageListener(
|
vAPI.messaging.globalMessageManager.removeMessageListener(
|
||||||
|
|
|
@ -174,10 +174,9 @@ housekeep itself.
|
||||||
|
|
||||||
vAPI.tabs.onPopupCreated = function(targetTabId, openerTabId) {
|
vAPI.tabs.onPopupCreated = function(targetTabId, openerTabId) {
|
||||||
var popup = popupCandidates[targetTabId];
|
var popup = popupCandidates[targetTabId];
|
||||||
if ( popup !== undefined ) {
|
if ( popup === undefined ) {
|
||||||
return;
|
popupCandidates[targetTabId] = new PopupCandidate(targetTabId, openerTabId);
|
||||||
}
|
}
|
||||||
popupCandidates[targetTabId] = new PopupCandidate(targetTabId, openerTabId);
|
|
||||||
popupCandidateTest(targetTabId);
|
popupCandidateTest(targetTabId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue