From 3b0d3e3330b9455c11b89e3f499bab8bf25d6510 Mon Sep 17 00:00:00 2001 From: gorhill Date: Sun, 8 Jan 2017 17:52:38 -0500 Subject: [PATCH] code review: saner way to find a popup's opener tab id --- platform/firefox/frameModule.js | 42 +++++++++++++-------- platform/firefox/vapi-background.js | 57 ++++++++++++++++++----------- 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index 19997ffa9..5777c4703 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -160,6 +160,7 @@ var contentObserver = { cpMessageName: hostName + ':shouldLoad', popupMessageName: hostName + ':shouldLoadPopup', ignoredPopups: new WeakMap(), + uniquePopupEventId: 1, uniqueSandboxId: 1, modernFirefox: Services.vc.compare(Services.appinfo.platformVersion, '44') > 0, @@ -466,35 +467,44 @@ var contentObserver = { this.removeEventListener('keydown', contObs.ignorePopup, true); this.removeEventListener('mousedown', contObs.ignorePopup, true); }, - lookupPopupOpenerURL: function(popup) { - var opener, openerURL; + lookupPopupOpener: function(popup) { for (;;) { - opener = popup.opener; - if ( !opener ) { break; } + let opener = popup.opener; + if ( !opener ) { return; } 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; + if ( opener === popup ) { return; } + if ( !opener.location ) { return; } + if ( this.reValidPopups.test(opener.location.protocol) ) { + return opener; + } // https://github.com/uBlockOrigin/uAssets/issues/255 // - Mind chained about:blank popups. - if ( openerURL !== 'about:blank' ) { break; } + if ( opener.location.href !== 'about:blank' ) { return; } popup = opener; } - return openerURL; }, - reGoodPopupURLs: /^(?:about:blank|blob:|data:|https?:|javascript:)/, + reValidPopups: /^(?: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); + let opener = this.lookupPopupOpener(subject); + if ( !opener ) { return; } + let popupMessager = getMessageManager(subject); + if ( !popupMessager ) { return; } + let openerMessager = getMessageManager(opener); + if ( !openerMessager ) { return; } + popupMessager.sendAsyncMessage(this.popupMessageName, { + id: this.uniquePopupEventId, + popup: true + }); + openerMessager.sendAsyncMessage(this.popupMessageName, { + id: this.uniquePopupEventId, + opener: true + }); + this.uniquePopupEventId += 1; return; } diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 9024583de..742a99258 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -2362,32 +2362,45 @@ vAPI.net.registerListeners = function() { } var shouldLoadPopupListenerMessageName = location.host + ':shouldLoadPopup'; + var shouldLoadPopupListenerEntries = []; var shouldLoadPopupListener = function(e) { if ( typeof vAPI.tabs.onPopupCreated !== 'function' ) { return; } + var target = e.target, - openerURL = e.data, - popupTabId = tabWatcher.tabIdFromTarget(target), - openerTabId, - uri; + data = e.data, + now = Date.now(), + entries = shouldLoadPopupListenerEntries, + entry; - for ( var browser of tabWatcher.browsers() ) { - uri = browser.currentURI; - - // Probably isn't the best method to identify the source tab. - - // https://github.com/gorhill/uBlock/issues/450 - // Skip entry if no valid URI available. - // Apparently URI can be undefined under some circumstances: I - // 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; } - - openerTabId = tabWatcher.tabIdFromTarget(browser); - if ( openerTabId === popupTabId ) { continue; } - - vAPI.tabs.onPopupCreated(popupTabId, openerTabId); - break; + var i = entries.length; + while ( i-- ) { + entry = entries[i]; + if ( entry.id === data.id ) { + entries.splice(i, 1); + break; + } + if ( entry.expire <= now ) { + entries.splice(i, 1); + } + entry = undefined; + } + if ( !entry ) { + entry = { + id: data.id, + popupTabId: undefined, + openerTabId: undefined, + expire: now + 10000 + }; + entries.push(entry); + } + var tabId = tabWatcher.tabIdFromTarget(target); + if ( data.popup ) { + entry.popupTabId = tabId; + } else /* if ( data.opener ) */ { + entry.openerTabId = tabId; + } + if ( entry.popupTabId && entry.openerTabId ) { + vAPI.tabs.onPopupCreated(entry.popupTabId, entry.openerTabId); } };