diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 907bafd..7272b8e 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -295,9 +295,11 @@ var windowWatcher = { if ( tabBrowser.deck ) { // Fennec tabContainer = tabBrowser.deck; + tabContainer.addEventListener('DOMTitleChanged', tabWatcher.onFennecLocationChange); } else if ( tabBrowser.tabContainer ) { // desktop Firefox tabContainer = tabBrowser.tabContainer; + tabBrowser.addTabsProgressListener(tabWatcher); vAPI.contextMenu.register(this.document); } else { return; @@ -319,6 +321,8 @@ 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); @@ -347,6 +351,49 @@ 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 + }); + }, + + onFennecLocationChange: function({target: doc}) { + // Fennec "equivalent" to onLocationChange + // note that DOMTitleChanged is selected as it fires very early + // (before DOMContentLoaded), and it does fire even if there is no title + var win = doc.defaultView; + if ( win !== win.top ) { + return; + } + + vAPI.tabs.onNavigation({ + frameId: 0, + tabId: vAPI.tabs.getTabId(getOwnerWindow(win).BrowserApp.getTabForWindow(win)), + url: Services.io.newURI(win.location.href, null, null).asciiSpec + }); + } + }; /******************************************************************************/ @@ -398,6 +445,7 @@ vAPI.tabs = {}; /******************************************************************************/ vAPI.tabs.registerListeners = function() { + // onNavigation and onUpdated handled with tabWatcher.onLocationChange // onClosed - handled in tabWatcher.onTabClose // onPopup - handled in httpObserver.handlePopup @@ -423,6 +471,7 @@ vAPI.tabs.registerListeners = function() { if ( tabBrowser.deck ) { // Fennec tabContainer = tabBrowser.deck; + tabContainer.removeEventListener('DOMTitleChanged', tabWatcher.onFennecLocationChange); } else if ( tabBrowser.tabContainer ) { tabContainer = tabBrowser.tabContainer; tabBrowser.removeTabsProgressListener(tabWatcher); @@ -662,6 +711,24 @@ vAPI.tabs.open = function(details) { /******************************************************************************/ +// Replace the URL of a tab. Noop if the tab does not exist. + +vAPI.tabs.replace = function(tabId, url) { + var targetURL = url; + + // extension pages + if ( /^[\w-]{2,}:/.test(targetURL) !== true ) { + targetURL = vAPI.getURL(targetURL); + } + + var tab = this.getTabsForIds(tabId); + if ( tab ) { + getBrowserForTab(tab).loadURI(targetURL); + } +}; + +/******************************************************************************/ + vAPI.tabs._remove = function(tab, tabBrowser) { if ( vAPI.fennec ) { tabBrowser.closeTab(tab); @@ -1090,18 +1157,13 @@ var httpObserver = { return true; } - if ( result.redirectUrl ) { - if ( type === 'main_frame' ) { - channel.cancel(this.ABORT); - vAPI.tabs.open({ tabId: details.tabId, url: result.redirectUrl }); - return true; - } - /*channel.redirectionLimit = 1; + /*if ( result.redirectUrl ) { + channel.redirectionLimit = 1; channel.redirectTo( Services.io.newURI(result.redirectUrl, null, null) ); - return true;*/ - } + return true; + }*/ return false; }, @@ -1203,6 +1265,14 @@ 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, [ @@ -1317,6 +1387,9 @@ vAPI.net.registerListeners = function() { type: details.type, url: details.url }; + if ( details.attrSrc !== undefined ) { + lastRequest[0].attrSrc = details.attrSrc; + } }; vAPI.messaging.globalMessageManager.addMessageListener( @@ -1324,38 +1397,6 @@ 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() { @@ -1364,11 +1405,6 @@ vAPI.net.registerListeners = function() { shouldLoadListener ); - vAPI.messaging.globalMessageManager.removeMessageListener( - locationChangedListenerMessageName, - locationChangedListener - ); - httpObserver.unregister(); }); };