diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index 170ffd7..c296ea0 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -19,11 +19,13 @@ Home: https://github.com/gorhill/uMatrix */ +/* global Components */ + 'use strict'; /******************************************************************************/ -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); @@ -236,6 +238,41 @@ const contentObserver = { /******************************************************************************/ +const locationChangedMessageName = hostName + ':locationChanged'; + +const LocationChangeListener = function(docShell) { + if ( !docShell ) { + return; + } + + var requestor = docShell.QueryInterface(Ci.nsIInterfaceRequestor); + var ds = requestor.getInterface(Ci.nsIWebProgress); + var mm = requestor.getInterface(Ci.nsIContentFrameMessageManager); + + if ( ds && mm && typeof mm.sendAsyncMessage === 'function' ) { + this.docShell = ds; + this.messageManager = mm; + ds.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_LOCATION); + } +}; + +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 949d945..d2f9f70 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,15 @@ let onLoadCompleted = function() { addMessageListener('umatrix-load-completed', onLoadCompleted); +if ( docShell ) { + let Ci = Components.interfaces; + let wp = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress); + let dw = wp.DOMWindow; + if ( dw === dw.top ) { + locationChangeListener = new LocationChangeListener(docShell); + } +} + /******************************************************************************/ })(); diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 1df334e..187964d 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -890,6 +890,45 @@ var tabWatcher = (function() { vAPI.setIcon(tabIdFromTarget(target), getOwnerWindow(target)); }; + var locationChangedMessageName = location.host + ':locationChanged'; + + var onLocationChanged = function(e) { + var vapi = vAPI; + var details = e.data; + + // Ignore notifications related to our popup + if ( details.url.lastIndexOf(vapi.getURL('popup.html'), 0) === 0 ) { + return; + } + + var browser = e.target; + var tabId = tabIdFromTarget(browser); + + if ( tabId === vapi.noTabId ) { + return; + } + + //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/chrisaljoudi/uBlock/issues/105 + // Allow any kind of pages + vapi.tabs.onNavigation({ + frameId: 0, + tabId: tabId, + url: details.url, + }); + }; + var onWindowLoad = function(ev) { if ( ev ) { this.removeEventListener(ev.type, onWindowLoad); @@ -899,19 +938,16 @@ var tabWatcher = (function() { if ( wintype !== 'navigator:browser' ) { return; } - var tabBrowser = getTabBrowser(this); if ( !tabBrowser ) { return; } - - var tabContainer; - if ( tabBrowser.tabContainer ) { - tabContainer = tabBrowser.tabContainer; - vAPI.contextMenu.register(this.document); - } else { + var tabContainer = tabBrowser.tabContainer; + if ( !tabContainer ) { return; } + + vAPI.contextMenu.register(this.document); tabContainer.addEventListener('TabOpen', onOpen); tabContainer.addEventListener('TabShow', onShow); tabContainer.addEventListener('TabClose', onClose); @@ -991,10 +1027,20 @@ var tabWatcher = (function() { } } + vAPI.messaging.globalMessageManager.addMessageListener( + locationChangedMessageName, + onLocationChanged + ); + Services.ww.registerNotification(windowWatcher); }; var stop = function() { + vAPI.messaging.globalMessageManager.removeMessageListener( + locationChangedMessageName, + onLocationChanged + ); + Services.ww.unregisterNotification(windowWatcher); for ( var win of vAPI.tabs.getWindows() ) {