From 6123335c519222174bb4520a7fd109f30b832e96 Mon Sep 17 00:00:00 2001 From: AlexVallat Date: Thu, 26 Mar 2015 21:00:56 +0000 Subject: [PATCH 1/3] Use a nsIWebProgressListener instead of a tabsProgressListener for location change monitoring --- platform/firefox/frameModule.js | 42 +++++++++++++--- platform/firefox/frameScript.js | 6 ++- platform/firefox/vapi-background.js | 75 ++++++++++++++--------------- 3 files changed, 77 insertions(+), 46 deletions(-) diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index f33154cf2..78915ca6b 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -23,10 +23,12 @@ /******************************************************************************/ -this.EXPORTED_SYMBOLS = ['contentObserver']; +this.EXPORTED_SYMBOLS = ['contentObserver', 'LocationChangeListener']; const {interfaces: Ci, utils: Cu} = Components; const {Services} = Cu.import('resource://gre/modules/Services.jsm', null); +const {XPCOMUtils} = Cu.import('resource://gre/modules/XPCOMUtils.jsm', null); + const hostName = Services.io.newURI(Components.stack.filename, null, null).host; // Cu.import('resource://gre/modules/devtools/Console.jsm'); @@ -65,16 +67,12 @@ const contentObserver = { .getService(Ci.nsICategoryManager); }, - QueryInterface: (function() { - let {XPCOMUtils} = Cu.import('resource://gre/modules/XPCOMUtils.jsm', null); - - return XPCOMUtils.generateQI([ + QueryInterface: XPCOMUtils.generateQI([ Ci.nsIFactory, Ci.nsIObserver, Ci.nsIContentPolicy, Ci.nsISupportsWeakReference - ]); - })(), + ]), createInstance: function(outer, iid) { if ( outer ) { @@ -309,6 +307,36 @@ const contentObserver = { /******************************************************************************/ +const locationChangedMessageName = hostName + ':locationChanged'; + +const LocationChangeListener = function(docShell) { + if (docShell) { + docShell.QueryInterface(Ci.nsIInterfaceRequestor); + + this.docShell = docShell.getInterface(Ci.nsIWebProgress); + this.messageManager = docShell.getInterface(Ci.nsIContentFrameMessageManager); + + if (this.messageManager && typeof this.messageManager.sendAsyncMessage === 'function') { + this.docShell.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL); + } + } +} + +LocationChangeListener.prototype.QueryInterface = XPCOMUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]); + +LocationChangeListener.prototype.onLocationChange = function(webProgress, request, location, flags) { + if ( !webProgress.isTopLevel ) { + return; + } + + this.messageManager.sendAsyncMessage(locationChangedMessageName, { + url: location.asciiSpec, + flags: flags, + }); +}; + +/******************************************************************************/ + contentObserver.register(); /******************************************************************************/ diff --git a/platform/firefox/frameScript.js b/platform/firefox/frameScript.js index bb5f898cd..e8c3cba41 100644 --- a/platform/firefox/frameScript.js +++ b/platform/firefox/frameScript.js @@ -21,13 +21,15 @@ /******************************************************************************/ +var locationChangeListener; // Keep alive while frameScript is alive + (function() { 'use strict'; /******************************************************************************/ -let {contentObserver} = Components.utils.import( +let {contentObserver, LocationChangeListener} = Components.utils.import( Components.stack.filename.replace('Script', 'Module'), null ); @@ -54,6 +56,8 @@ let onLoadCompleted = function() { addMessageListener('ublock-load-completed', onLoadCompleted); +locationChangeListener = new LocationChangeListener(docShell); + /******************************************************************************/ })(); diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 0bd5c23b4..bc1ca6710 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -298,7 +298,6 @@ var windowWatcher = { } else if ( tabBrowser.tabContainer ) { // desktop Firefox tabContainer = tabBrowser.tabContainer; - tabBrowser.addTabsProgressListener(tabWatcher); vAPI.contextMenu.register(this.document); } else { return; @@ -320,8 +319,6 @@ var windowWatcher = { /******************************************************************************/ var tabWatcher = { - SAME_DOCUMENT: Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT, - onTabClose: function({target}) { // target is tab in Firefox, browser in Fennec var tabId = vAPI.tabs.getTabId(target); @@ -349,32 +346,6 @@ var tabWatcher = { }); } }, - - onLocationChange: function(browser, webProgress, request, location, flags) { - if ( !webProgress.isTopLevel ) { - return; - } - - var tabId = vAPI.tabs.getTabId(browser); - - // LOCATION_CHANGE_SAME_DOCUMENT = "did not load a new document" - if ( flags & this.SAME_DOCUMENT ) { - vAPI.tabs.onUpdated(tabId, {url: location.asciiSpec}, { - frameId: 0, - tabId: tabId, - url: browser.currentURI.asciiSpec - }); - return; - } - - // https://github.com/gorhill/uBlock/issues/105 - // Allow any kind of pages - vAPI.tabs.onNavigation({ - frameId: 0, - tabId: tabId, - url: location.asciiSpec - }); - }, }; /******************************************************************************/ @@ -426,7 +397,6 @@ vAPI.tabs = {}; /******************************************************************************/ vAPI.tabs.registerListeners = function() { - // onNavigation and onUpdated handled with tabWatcher.onLocationChange // onClosed - handled in tabWatcher.onTabClose // onPopup - handled in httpObserver.handlePopup @@ -1232,14 +1202,6 @@ var httpObserver = { return; } - if ( vAPI.fennec && lastRequest.type === this.MAIN_FRAME ) { - vAPI.tabs.onNavigation({ - frameId: 0, - tabId: lastRequest.tabId, - url: URI.asciiSpec - }); - } - // If request is not handled we may use the data in on-modify-request if ( channel instanceof Ci.nsIWritablePropertyBag ) { channel.setProperty(this.REQDATAKEY, [ @@ -1361,6 +1323,38 @@ vAPI.net.registerListeners = function() { shouldLoadListener ); + var locationChangedListenerMessageName = location.host + ':locationChanged'; + var locationChangedListener = function(e) { + var details = e.data; + var browser = e.target; + var tabId = vAPI.tabs.getTabId(browser); + + //console.debug("nsIWebProgressListener: onLocationChange: " + details.url + " (" + details.flags + ")"); + + // LOCATION_CHANGE_SAME_DOCUMENT = "did not load a new document" + if ( details.flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT ) { + vAPI.tabs.onUpdated(tabId, {url: details.url}, { + frameId: 0, + tabId: tabId, + url: browser.currentURI.asciiSpec + }); + return; + } + + // https://github.com/gorhill/uBlock/issues/105 + // Allow any kind of pages + vAPI.tabs.onNavigation({ + frameId: 0, + tabId: tabId, + url: details.url, + }); + } + + vAPI.messaging.globalMessageManager.addMessageListener( + locationChangedListenerMessageName, + locationChangedListener + ); + httpObserver.register(); cleanupTasks.push(function() { @@ -1369,6 +1363,11 @@ vAPI.net.registerListeners = function() { shouldLoadListener ); + vAPI.messaging.globalMessageManager.removeMessageListener( + locationChangedListenerMessageName, + locationChangedListener + ); + httpObserver.unregister(); }); }; From 7ec717d3fe6224bbc6dd5d0ddf3db805f7434f64 Mon Sep 17 00:00:00 2001 From: AlexVallat Date: Thu, 26 Mar 2015 21:11:54 +0000 Subject: [PATCH 2/3] More restrictive monitoring. Probably doesn't make a difference, but at least theoretically more efficient. --- platform/firefox/frameModule.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index 78915ca6b..5b90d5dd5 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -317,7 +317,7 @@ const LocationChangeListener = function(docShell) { this.messageManager = docShell.getInterface(Ci.nsIContentFrameMessageManager); if (this.messageManager && typeof this.messageManager.sendAsyncMessage === 'function') { - this.docShell.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL); + this.docShell.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_LOCATION); } } } From 726325ea0ddf7404fde58587a57cc8a1288fb3f1 Mon Sep 17 00:00:00 2001 From: AlexVallat Date: Mon, 30 Mar 2015 18:35:18 +0100 Subject: [PATCH 3/3] Remove onNavigation from onTabSelect, as mentioned in #1125 --- platform/firefox/vapi-background.js | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index bc1ca6710..a5b5baf53 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -327,24 +327,8 @@ var tabWatcher = { }, onTabSelect: function({target}) { - // target is tab in Firefox, browser in Fennec - var browser = (target.linkedBrowser || target); - var URI = browser.currentURI; - var aboutPath = URI.schemeIs('about') && URI.path; - var tabId = vAPI.tabs.getTabId(target); - - if ( !aboutPath || (aboutPath !== 'blank' && aboutPath !== 'newtab') ) { - vAPI.setIcon(tabId, getOwnerWindow(target)); - return; - } - - if ( browser.webNavigation.busyFlags === 0 /*BUSY_FLAGS_NONE*/ ) { - vAPI.tabs.onNavigation({ - frameId: 0, - tabId: tabId, - url: URI.asciiSpec - }); - } + vAPI.setIcon(vAPI.tabs.getTabId(target), getOwnerWindow(target)); + return; }, };