diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index d960c8f0d..a42174924 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -2361,9 +2361,27 @@ vAPI.net.registerListeners = function() { null; } - var shouldLoadPopupListenerMessageName = location.host + ':shouldLoadPopup'; - var shouldLoadPopupListener = function(openerURL, popupTabId) { - var uri, openerTabId; + 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 || '', + 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(target.currentURI.asciiSpec, openerTabId); + shouldLoadPopupListenerMapToD = Date.now() + 10000; + vAPI.tabs.onPopupCreated(popupTabId, openerTabId); + return; + } + for ( var browser of tabWatcher.browsers() ) { uri = browser.currentURI; @@ -2375,15 +2393,16 @@ vAPI.net.registerListeners = function() { // believe this may have to do with those very temporary // browser objects created when opening a new tab, i.e. related // to https://github.com/gorhill/uBlock/issues/212 - if ( !uri || uri.spec !== openerURL ) { - continue; - } + if ( !uri || uri.spec !== openerURL ) { continue; } openerTabId = tabWatcher.tabIdFromTarget(browser); - if ( openerTabId !== popupTabId ) { - vAPI.tabs.onPopupCreated(popupTabId, openerTabId); - break; - } + 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) { @@ -2391,10 +2410,7 @@ vAPI.net.registerListeners = function() { return; } // We are handling a synchronous message: do not block. - vAPI.setTimeout( - shouldLoadPopupListener.bind(null, e.data, tabWatcher.tabIdFromTarget(e.target)), - 1 - ); + vAPI.setTimeout(shouldLoadPopupListener.bind(null, e.data, e.target), 1); }; vAPI.messaging.globalMessageManager.addMessageListener( diff --git a/src/js/tab.js b/src/js/tab.js index ffad7a4df..af8c68a63 100644 --- a/src/js/tab.js +++ b/src/js/tab.js @@ -568,22 +568,25 @@ vAPI.tabs.onPopupUpdated = (function() { // URL. // https://github.com/gorhill/uBlock/issues/1735 // Do not bail out on `data:` URI, they are commonly used for popups. + // https://github.com/uBlockOrigin/uAssets/issues/255 + // Do not bail out on `about:blank`: an `about:blank` popup can be + // opened, with the sole purpose to serve as an intermediary in + // a sequence of chained popups. if ( context.requestHostname === '' && - targetURL.startsWith('data:') === false + targetURL.startsWith('data:') === false && + targetURL !== 'about:blank' ) { return ''; } // Dynamic filtering makes sense only when we have a valid hostname. if ( openerHostname !== '' ) { - // Check user switch first - if ( - typeof clickedURL === 'string' && - areDifferentURLs(targetURL, clickedURL) && - µb.hnSwitches.evaluateZ('no-popups', openerHostname) - ) { - return 'ub:no-popups: ' + µb.hnSwitches.z + ' true'; + // Check per-site switch first + if ( µb.hnSwitches.evaluateZ('no-popups', openerHostname) ) { + if ( typeof clickedURL !== 'string' || areDifferentURLs(targetURL, clickedURL) ) { + return 'ub:no-popups: ' + µb.hnSwitches.z + ' true'; + } } // https://github.com/gorhill/uBlock/issues/581