mirror of
https://github.com/gorhill/uBlock.git
synced 2024-10-06 09:37:12 +02:00
fix #2290
This commit is contained in:
parent
a927725bd9
commit
a303c7800e
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -161,7 +161,7 @@ var contentObserver = {
|
||||
popupMessageName: hostName + ':shouldLoadPopup',
|
||||
ignoredPopups: new WeakMap(),
|
||||
uniqueSandboxId: 1,
|
||||
canE10S: Services.vc.compare(Services.appinfo.platformVersion, '44') > 0,
|
||||
modernFirefox: Services.vc.compare(Services.appinfo.platformVersion, '44') > 0,
|
||||
|
||||
get componentRegistrar() {
|
||||
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
@ -189,7 +189,12 @@ var contentObserver = {
|
||||
|
||||
register: function() {
|
||||
Services.obs.addObserver(this, 'document-element-inserted', true);
|
||||
Services.obs.addObserver(this, 'content-document-global-created', true);
|
||||
|
||||
// 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.modernFirefox !== true ) {
|
||||
this.componentRegistrar.registerFactory(
|
||||
this.classID,
|
||||
this.classDescription,
|
||||
@ -203,17 +208,21 @@ var contentObserver = {
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
unregister: function() {
|
||||
Services.obs.removeObserver(this, 'document-element-inserted');
|
||||
Services.obs.removeObserver(this, 'content-document-global-created');
|
||||
|
||||
if ( this.modernFirefox !== true ) {
|
||||
this.componentRegistrar.unregisterFactory(this.classID, this);
|
||||
this.categoryManager.deleteCategoryEntry(
|
||||
'content-policy',
|
||||
this.contractID,
|
||||
false
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
getFrameId: function(win) {
|
||||
@ -223,48 +232,6 @@ var contentObserver = {
|
||||
.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
|
||||
shouldLoad: function(type, location, origin, context) {
|
||||
// For whatever reason, sometimes the global scope is completely
|
||||
@ -278,17 +245,6 @@ var contentObserver = {
|
||||
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') ) {
|
||||
return this.ACCEPT;
|
||||
}
|
||||
@ -504,17 +460,44 @@ var contentObserver = {
|
||||
},
|
||||
|
||||
ignorePopup: function(e) {
|
||||
if ( e.isTrusted === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( e.isTrusted === false ) { return; }
|
||||
let contObs = contentObserver;
|
||||
contObs.ignoredPopups.set(this, true);
|
||||
this.removeEventListener('keydown', 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
|
||||
// uninitialized at this point. Repro steps:
|
||||
// - Launch FF with uBlock enabled
|
||||
@ -522,14 +505,11 @@ var contentObserver = {
|
||||
// - Enable uBlock
|
||||
// - Services and all other global variables are undefined
|
||||
// Hopefully will eventually understand why this happens.
|
||||
if ( Services === undefined ) {
|
||||
return;
|
||||
}
|
||||
if ( Services === undefined ) { return; }
|
||||
|
||||
let doc = subject;
|
||||
let win = doc.defaultView || null;
|
||||
if ( win === null ) {
|
||||
return;
|
||||
}
|
||||
if ( win === null ) { return; }
|
||||
|
||||
if ( win.opener && this.ignoredPopups.has(win) === false ) {
|
||||
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
|
||||
// conservative and focus only on the one issue reported, i.e. let's
|
||||
// not test against 'text/html'.
|
||||
if ( doc.contentType.startsWith('image/') ) {
|
||||
return;
|
||||
}
|
||||
if ( doc.contentType.startsWith('image/') ) { return; }
|
||||
|
||||
let loc = win.location;
|
||||
|
||||
if ( loc.protocol !== 'http:' && loc.protocol !== 'https:' && loc.protocol !== 'file:' ) {
|
||||
if ( loc.protocol === 'chrome:' && loc.host === hostName ) {
|
||||
this.initContentScripts(win);
|
||||
}
|
||||
|
||||
// What about data: and about:blank?
|
||||
return;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -2361,26 +2361,14 @@ vAPI.net.registerListeners = function() {
|
||||
null;
|
||||
}
|
||||
|
||||
var shouldLoadPopupListenerMessageName = location.host + ':shouldLoadPopup',
|
||||
shouldLoadPopupListenerMap = new Map(),
|
||||
shouldLoadPopupListenerMapToD = 0;
|
||||
var shouldLoadPopupListener = function(openerURL, target) {
|
||||
var popupTabId = tabWatcher.tabIdFromTarget(target),
|
||||
popupURL = target.currentURI && target.currentURI.asciiSpec || '',
|
||||
var shouldLoadPopupListenerMessageName = location.host + ':shouldLoadPopup';
|
||||
var shouldLoadPopupListener = function(e) {
|
||||
if ( typeof vAPI.tabs.onPopupCreated !== 'function' ) { return; }
|
||||
var target = e.target,
|
||||
openerURL = e.data,
|
||||
popupTabId = tabWatcher.tabIdFromTarget(target),
|
||||
openerTabId,
|
||||
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() ) {
|
||||
uri = browser.currentURI;
|
||||
@ -2398,24 +2386,14 @@ vAPI.net.registerListeners = function() {
|
||||
openerTabId = tabWatcher.tabIdFromTarget(browser);
|
||||
if ( openerTabId === popupTabId ) { continue; }
|
||||
|
||||
shouldLoadPopupListenerMap = new Map();
|
||||
shouldLoadPopupListenerMapToD = Date.now() + 10000;
|
||||
shouldLoadPopupListenerMap.set(popupURL, openerTabId);
|
||||
vAPI.tabs.onPopupCreated(popupTabId, openerTabId);
|
||||
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(
|
||||
shouldLoadPopupListenerMessageName,
|
||||
shouldLoadPopupListenerAsync
|
||||
shouldLoadPopupListener
|
||||
);
|
||||
|
||||
var shouldLoadListenerMessageName = location.host + ':shouldLoad';
|
||||
@ -2501,7 +2479,7 @@ vAPI.net.registerListeners = function() {
|
||||
cleanupTasks.push(function() {
|
||||
vAPI.messaging.globalMessageManager.removeMessageListener(
|
||||
shouldLoadPopupListenerMessageName,
|
||||
shouldLoadPopupListenerAsync
|
||||
shouldLoadPopupListener
|
||||
);
|
||||
|
||||
vAPI.messaging.globalMessageManager.removeMessageListener(
|
||||
|
@ -174,10 +174,9 @@ housekeep itself.
|
||||
|
||||
vAPI.tabs.onPopupCreated = function(targetTabId, openerTabId) {
|
||||
var popup = popupCandidates[targetTabId];
|
||||
if ( popup !== undefined ) {
|
||||
return;
|
||||
}
|
||||
if ( popup === undefined ) {
|
||||
popupCandidates[targetTabId] = new PopupCandidate(targetTabId, openerTabId);
|
||||
}
|
||||
popupCandidateTest(targetTabId);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user