mirror of
https://github.com/gorhill/uBlock.git
synced 2024-09-03 17:49:39 +02:00
parent
b084d796b5
commit
6470216530
@ -69,9 +69,13 @@ var cleanupTasks = [];
|
|||||||
// Fixed by github.com/AlexVallat:
|
// Fixed by github.com/AlexVallat:
|
||||||
// https://github.com/AlexVallat/uBlock/commit/7b781248f00cbe3d61b1cc367c440db80fa06049
|
// https://github.com/AlexVallat/uBlock/commit/7b781248f00cbe3d61b1cc367c440db80fa06049
|
||||||
// 7 instances of cleanupTasks.push, but one is unique to fennec, and one to desktop.
|
// 7 instances of cleanupTasks.push, but one is unique to fennec, and one to desktop.
|
||||||
var expectedNumberOfCleanups = 7;
|
var expectedNumberOfCleanups = 6;
|
||||||
|
|
||||||
window.addEventListener('unload', function() {
|
window.addEventListener('unload', function() {
|
||||||
|
if ( typeof vAPI.app.onShutdown === 'function' ) {
|
||||||
|
vAPI.app.onShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
for ( var cleanup of cleanupTasks ) {
|
for ( var cleanup of cleanupTasks ) {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
@ -362,15 +366,6 @@ var getTabBrowser = function(win) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var getBrowserForTab = function(tab) {
|
|
||||||
if ( !tab ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return vAPI.fennec && tab.browser || tab.linkedBrowser || null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var getOwnerWindow = function(target) {
|
var getOwnerWindow = function(target) {
|
||||||
if ( target.ownerDocument ) {
|
if ( target.ownerDocument ) {
|
||||||
return target.ownerDocument.defaultView;
|
return target.ownerDocument.defaultView;
|
||||||
@ -403,100 +398,67 @@ vAPI.tabs = {};
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.tabs.registerListeners = function() {
|
vAPI.tabs.registerListeners = function() {
|
||||||
// onClosed - handled in tabWatcher.onTabClose
|
tabWatcher.start();
|
||||||
// onPopup - handled in httpObserver.handlePopup
|
|
||||||
|
|
||||||
for ( var win of this.getWindows() ) {
|
|
||||||
windowWatcher.onReady.call(win);
|
|
||||||
}
|
|
||||||
|
|
||||||
Services.ww.registerNotification(windowWatcher);
|
|
||||||
|
|
||||||
cleanupTasks.push(function() {
|
|
||||||
Services.ww.unregisterNotification(windowWatcher);
|
|
||||||
|
|
||||||
for ( var win of vAPI.tabs.getWindows() ) {
|
|
||||||
vAPI.contextMenu.unregister(win.document);
|
|
||||||
win.removeEventListener('DOMContentLoaded', windowWatcher.onReady);
|
|
||||||
|
|
||||||
var tabContainer;
|
|
||||||
var tabBrowser = getTabBrowser(win);
|
|
||||||
if ( !tabBrowser ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( tabBrowser.deck ) {
|
|
||||||
// Fennec
|
|
||||||
tabContainer = tabBrowser.deck;
|
|
||||||
} else if ( tabBrowser.tabContainer ) {
|
|
||||||
tabContainer = tabBrowser.tabContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
tabContainer.removeEventListener('TabOpen', tabWatcher.onOpen);
|
|
||||||
tabContainer.removeEventListener('TabShow', tabWatcher.onShow);
|
|
||||||
tabContainer.removeEventListener('TabClose', tabWatcher.onClose);
|
|
||||||
tabContainer.removeEventListener('TabSelect', tabWatcher.onSelect);
|
|
||||||
|
|
||||||
// Close extension tabs
|
|
||||||
for ( var tab of tabBrowser.tabs ) {
|
|
||||||
var browser = getBrowserForTab(tab);
|
|
||||||
if ( browser === null ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var URI = browser.currentURI;
|
|
||||||
if ( URI.schemeIs('chrome') && URI.host === location.host ) {
|
|
||||||
vAPI.tabs._remove(tab, getTabBrowser(win));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Firefox:
|
||||||
|
//
|
||||||
|
// browser --> ownerDocument --> defaultView --> gBrowser --> browsers --+
|
||||||
|
// ^ |
|
||||||
|
// | |
|
||||||
|
// +-------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// browser (browser)
|
||||||
|
// contentTitle
|
||||||
|
// currentURI
|
||||||
|
// ownerDocument (XULDocument)
|
||||||
|
// defaultView (ChromeWindow)
|
||||||
|
// gBrowser (tabbrowser)
|
||||||
|
// browsers (browser)
|
||||||
|
// selectedBrowser
|
||||||
|
// selectedTab
|
||||||
|
// tabs (tab.tabbrowser-tab)
|
||||||
|
//
|
||||||
|
// Fennec:
|
||||||
|
//
|
||||||
|
// ???
|
||||||
|
|
||||||
vAPI.tabs.get = function(tabId, callback) {
|
vAPI.tabs.get = function(tabId, callback) {
|
||||||
var tab, win;
|
var win, browser;
|
||||||
|
|
||||||
if ( tabId === null ) {
|
if ( tabId === null ) {
|
||||||
win = Services.wm.getMostRecentWindow('navigator:browser');
|
win = Services.wm.getMostRecentWindow('navigator:browser');
|
||||||
tab = getTabBrowser(win).selectedTab;
|
browser = tabWatcher.browserFromTarget(getTabBrowser(win).selectedTab);
|
||||||
tabId = tabWatcher.tabIdFromTab(tab);
|
tabId = tabWatcher.tabIdFromTarget(browser);
|
||||||
} else {
|
} else {
|
||||||
tab = tabWatcher.tabFromTabId(tabId);
|
browser = tabWatcher.browserFromTabId(tabId);
|
||||||
if ( tab ) {
|
if ( browser ) {
|
||||||
win = getOwnerWindow(tab);
|
win = getOwnerWindow(browser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For internal use
|
// For internal use
|
||||||
if ( typeof callback !== 'function' ) {
|
if ( typeof callback !== 'function' ) {
|
||||||
return tab;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !tab ) {
|
if ( !browser ) {
|
||||||
callback();
|
callback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var windows = this.getWindows();
|
var windows = this.getWindows();
|
||||||
var browser = getBrowserForTab(tab);
|
|
||||||
var tabBrowser = getTabBrowser(win);
|
var tabBrowser = getTabBrowser(win);
|
||||||
var tabIndex, tabTitle;
|
|
||||||
if ( vAPI.fennec ) {
|
|
||||||
tabIndex = tabBrowser.tabs.indexOf(tab);
|
|
||||||
tabTitle = browser.contentTitle;
|
|
||||||
} else {
|
|
||||||
tabIndex = tabBrowser.browsers.indexOf(browser);
|
|
||||||
tabTitle = tab.label;
|
|
||||||
}
|
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
id: tabId,
|
id: tabId,
|
||||||
index: tabIndex,
|
index: tabWatcher.indexFromTarget(browser),
|
||||||
windowId: windows.indexOf(win),
|
windowId: windows.indexOf(win),
|
||||||
active: tab === tabBrowser.selectedTab,
|
active: browser === tabBrowser.selectedBrowser,
|
||||||
url: browser.currentURI.asciiSpec,
|
url: browser.currentURI.asciiSpec,
|
||||||
title: tabTitle
|
title: browser.contentTitle
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -517,9 +479,6 @@ vAPI.tabs.getAll = function(window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for ( tab of tabBrowser.tabs ) {
|
for ( tab of tabBrowser.tabs ) {
|
||||||
if ( !vAPI.fennec && tab.hasAttribute('pending') ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tabs.push(tab);
|
tabs.push(tab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -568,7 +527,7 @@ vAPI.tabs.open = function(details) {
|
|||||||
var URI = Services.io.newURI(details.url, null, null);
|
var URI = Services.io.newURI(details.url, null, null);
|
||||||
|
|
||||||
for ( tab of this.getAll() ) {
|
for ( tab of this.getAll() ) {
|
||||||
var browser = getBrowserForTab(tab);
|
var browser = tabWatcher.browserFromTarget(tab);
|
||||||
|
|
||||||
// Or simply .equals if we care about the fragment
|
// Or simply .equals if we care about the fragment
|
||||||
if ( URI.equalsExceptRef(browser.currentURI) === false ) {
|
if ( URI.equalsExceptRef(browser.currentURI) === false ) {
|
||||||
@ -585,9 +544,9 @@ vAPI.tabs.open = function(details) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( details.tabId ) {
|
if ( details.tabId ) {
|
||||||
tab = tabWatcher.tabFromTabId(details.tabId);
|
tab = tabWatcher.browserFromTabId(details.tabId);
|
||||||
if ( tab ) {
|
if ( tab ) {
|
||||||
getBrowserForTab(tab).loadURI(details.url);
|
tabWatcher.browserFromTarget(tab).loadURI(details.url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -624,9 +583,9 @@ vAPI.tabs.replace = function(tabId, url) {
|
|||||||
targetURL = vAPI.getURL(targetURL);
|
targetURL = vAPI.getURL(targetURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tab = tabWatcher.tabFromTabId(tabId);
|
var tab = tabWatcher.browserFromTabId(tabId);
|
||||||
if ( tab ) {
|
if ( tab ) {
|
||||||
getBrowserForTab(tab).loadURI(targetURL);
|
tabWatcher.browserFromTarget(tab).loadURI(targetURL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -643,7 +602,7 @@ vAPI.tabs._remove = function(tab, tabBrowser) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.tabs.remove = function(tabId) {
|
vAPI.tabs.remove = function(tabId) {
|
||||||
var tabs = tabWatcher.tabFromTabId(tabId);
|
var tabs = tabWatcher.browserFromTabId(tabId);
|
||||||
if ( tabs.length === 0 ) {
|
if ( tabs.length === 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -661,7 +620,7 @@ vAPI.tabs.reload = function(tabId) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getBrowserForTab(tab).webNavigation.reload(
|
tabWatcher.browserFromTarget(tab).webNavigation.reload(
|
||||||
Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE
|
Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -698,7 +657,7 @@ vAPI.tabs.injectScript = function(tabId, details, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
details.file = vAPI.getURL(details.file);
|
details.file = vAPI.getURL(details.file);
|
||||||
getBrowserForTab(tab).messageManager.sendAsyncMessage(
|
tabWatcher.browserFromTarget(tab).messageManager.sendAsyncMessage(
|
||||||
location.host + ':broadcast',
|
location.host + ':broadcast',
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
broadcast: true,
|
broadcast: true,
|
||||||
@ -717,25 +676,130 @@ vAPI.tabs.injectScript = function(tabId, details, callback) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var windowWatcher = {
|
var tabWatcher = (function() {
|
||||||
onReady: function(e) {
|
// TODO: find out whether we need a janitor to take care of stale entries.
|
||||||
if ( e ) {
|
var browserToTabIdMap = new Map();
|
||||||
this.removeEventListener(e.type, windowWatcher.onReady);
|
var tabIdToBrowserMap = new Map();
|
||||||
|
var tabIdGenerator = 1;
|
||||||
|
|
||||||
|
var indexFromBrowser = function(browser) {
|
||||||
|
var win = getOwnerWindow(browser);
|
||||||
|
if ( !win ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
var tabbrowser = getTabBrowser(win);
|
||||||
|
if ( !tabbrowser ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return vAPI.fennec ?
|
||||||
|
tabbrowser.tabs.indexOf(browser) :
|
||||||
|
tabbrowser.browsers.indexOf(browser);
|
||||||
|
};
|
||||||
|
|
||||||
|
var indexFromTarget = function(target) {
|
||||||
|
return indexFromBrowser(browserFromTarget(target));
|
||||||
|
};
|
||||||
|
|
||||||
|
var browserFromTarget = function(target) {
|
||||||
|
if ( !target ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ( vAPI.fennec ) {
|
||||||
|
if ( target.browser ) { // target is a tab
|
||||||
|
target = target.browser;
|
||||||
|
}
|
||||||
|
} else if ( target.linkedPanel ) { // target is a tab
|
||||||
|
target = target.linkedBrowser;
|
||||||
|
}
|
||||||
|
if ( target.localName !== 'browser' ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
|
||||||
|
var tabIdFromTarget = function(target) {
|
||||||
|
var browser = browserFromTarget(target);
|
||||||
|
if ( browser === null ) {
|
||||||
|
return vAPI.noTabId;
|
||||||
|
}
|
||||||
|
var tabId = browserToTabIdMap.get(browser);
|
||||||
|
if ( tabId === undefined ) {
|
||||||
|
tabId = 't' + tabIdGenerator++;
|
||||||
|
browserToTabIdMap.set(browser, tabId);
|
||||||
|
tabIdToBrowserMap.set(tabId, browser);
|
||||||
|
}
|
||||||
|
return tabId;
|
||||||
|
};
|
||||||
|
|
||||||
|
var browserFromTabId = function(tabId) {
|
||||||
|
var browser = tabIdToBrowserMap.get(tabId);
|
||||||
|
if ( browser === undefined ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Verify that the browser is still live
|
||||||
|
if ( indexFromBrowser(browser) !== -1 ) {
|
||||||
|
return browser;
|
||||||
|
}
|
||||||
|
removeBrowserEntry(tabId, browser);
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
var removeBrowserEntry = function(tabId, browser) {
|
||||||
|
if ( tabId && tabId !== vAPI.noTabId ) {
|
||||||
|
vAPI.tabs.onClosed(tabId);
|
||||||
|
delete vAPI.toolbarButton.tabs[tabId];
|
||||||
|
tabIdToBrowserMap.delete(tabId);
|
||||||
|
}
|
||||||
|
if ( browser ) {
|
||||||
|
browserToTabIdMap.delete(browser);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/Events/TabOpen
|
||||||
|
var onOpen = function({target}) {
|
||||||
|
var tabId = tabIdFromTarget(target);
|
||||||
|
var browser = browserFromTabId(tabId);
|
||||||
|
vAPI.tabs.onNavigation({
|
||||||
|
frameId: 0,
|
||||||
|
tabId: tabId,
|
||||||
|
url: browser.currentURI.asciiSpec,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/Events/TabShow
|
||||||
|
var onShow = function({target}) {
|
||||||
|
tabIdFromTarget(target);
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/Events/TabClose
|
||||||
|
var onClose = function({target}) {
|
||||||
|
// target is tab in Firefox, browser in Fennec
|
||||||
|
var browser = browserFromTarget(target);
|
||||||
|
var tabId = browserToTabIdMap.get(browser);
|
||||||
|
removeBrowserEntry(tabId, browser);
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/Events/TabSelect
|
||||||
|
var onSelect = function({target}) {
|
||||||
|
vAPI.setIcon(tabIdFromTarget(target), getOwnerWindow(target));
|
||||||
|
};
|
||||||
|
|
||||||
|
var onWindowLoad = function(ev) {
|
||||||
|
if ( ev ) {
|
||||||
|
this.removeEventListener(ev.type, onWindowLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
var wintype = this.document.documentElement.getAttribute('windowtype');
|
var wintype = this.document.documentElement.getAttribute('windowtype');
|
||||||
|
|
||||||
if ( wintype !== 'navigator:browser' ) {
|
if ( wintype !== 'navigator:browser' ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabContainer;
|
|
||||||
var tabBrowser = getTabBrowser(this);
|
var tabBrowser = getTabBrowser(this);
|
||||||
|
|
||||||
if ( !tabBrowser ) {
|
if ( !tabBrowser ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tabContainer;
|
||||||
if ( tabBrowser.deck ) {
|
if ( tabBrowser.deck ) {
|
||||||
// Fennec
|
// Fennec
|
||||||
tabContainer = tabBrowser.deck;
|
tabContainer = tabBrowser.deck;
|
||||||
@ -746,118 +810,105 @@ var windowWatcher = {
|
|||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
tabContainer.addEventListener('TabOpen', onOpen);
|
||||||
tabContainer.addEventListener('TabOpen', tabWatcher.onOpen);
|
tabContainer.addEventListener('TabShow', onShow);
|
||||||
tabContainer.addEventListener('TabShow', tabWatcher.onShow);
|
tabContainer.addEventListener('TabClose', onClose);
|
||||||
tabContainer.addEventListener('TabClose', tabWatcher.onClose);
|
tabContainer.addEventListener('TabSelect', onSelect);
|
||||||
tabContainer.addEventListener('TabSelect', tabWatcher.onSelect);
|
|
||||||
|
|
||||||
// when new window is opened TabSelect doesn't run on the selected tab?
|
// when new window is opened TabSelect doesn't run on the selected tab?
|
||||||
},
|
|
||||||
|
|
||||||
observe: function(win, topic) {
|
|
||||||
if ( topic === 'domwindowopened' ) {
|
|
||||||
win.addEventListener('DOMContentLoaded', this.onReady);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var tabWatcher = (function() {
|
|
||||||
var knownTabs = new Set();
|
|
||||||
var stack = new WeakMap();
|
|
||||||
var stackId = 1;
|
|
||||||
// If needed, we can optimize further by having a matching tabid->tab map.
|
|
||||||
|
|
||||||
var tabIdFromTab = function(target) {
|
|
||||||
if ( !target ) {
|
|
||||||
return vAPI.noTabId;
|
|
||||||
}
|
|
||||||
if ( vAPI.fennec ) {
|
|
||||||
if ( target.browser ) {
|
|
||||||
// target is a tab
|
|
||||||
target = target.browser;
|
|
||||||
}
|
|
||||||
} else if ( target.linkedPanel ) {
|
|
||||||
// target is a tab
|
|
||||||
target = target.linkedBrowser;
|
|
||||||
}
|
|
||||||
if ( target.localName !== 'browser' ) {
|
|
||||||
return vAPI.noTabId;
|
|
||||||
}
|
|
||||||
var tabId = stack.get(target);
|
|
||||||
if ( !tabId ) {
|
|
||||||
tabId = '' + stackId++;
|
|
||||||
stack.set(target, tabId);
|
|
||||||
}
|
|
||||||
return tabId;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var tabFromTabId = function(tabId) {
|
var onWindowUnload = function() {
|
||||||
for ( var tab of knownTabs ) {
|
vAPI.contextMenu.unregister(this.document);
|
||||||
if ( tabIdFromTab(tab) === tabId ) {
|
this.removeEventListener('DOMContentLoaded', onWindowLoad);
|
||||||
return tab;
|
|
||||||
|
var tabBrowser = getTabBrowser(this);
|
||||||
|
if ( !tabBrowser ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tabContainer = null;
|
||||||
|
if ( tabBrowser.deck ) {
|
||||||
|
// Fennec
|
||||||
|
tabContainer = tabBrowser.deck;
|
||||||
|
} else if ( tabBrowser.tabContainer ) {
|
||||||
|
tabContainer = tabBrowser.tabContainer;
|
||||||
|
}
|
||||||
|
if ( tabContainer ) {
|
||||||
|
tabContainer.removeEventListener('TabOpen', onOpen);
|
||||||
|
tabContainer.removeEventListener('TabShow', onShow);
|
||||||
|
tabContainer.removeEventListener('TabClose', onClose);
|
||||||
|
tabContainer.removeEventListener('TabSelect', onSelect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close extension tabs
|
||||||
|
var browser, URI, tabId;
|
||||||
|
for ( var tab of tabBrowser.tabs ) {
|
||||||
|
browser = tabWatcher.browserFromTarget(tab);
|
||||||
|
if ( browser === null ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
URI = browser.currentURI;
|
||||||
|
if ( URI.schemeIs('chrome') && URI.host === location.host ) {
|
||||||
|
vAPI.tabs._remove(tab, getTabBrowser(this));
|
||||||
|
}
|
||||||
|
browser = browserFromTarget(tab);
|
||||||
|
tabId = browserToTabIdMap.get(browser);
|
||||||
|
if ( tabId !== undefined ) {
|
||||||
|
tabIdToBrowserMap.delete(tabId);
|
||||||
|
}
|
||||||
|
browserToTabIdMap.delete(browser);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWindowWatcher
|
||||||
|
var windowWatcher = {
|
||||||
|
observe: function(win, topic) {
|
||||||
|
if ( topic === 'domwindowopened' ) {
|
||||||
|
win.addEventListener('DOMContentLoaded', onWindowLoad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize map with existing active tabs
|
// Initialize map with existing active tabs
|
||||||
var tabBrowser;
|
var start = function() {
|
||||||
for ( var win of vAPI.tabs.getWindows() ) {
|
var tabBrowser, tab;
|
||||||
tabBrowser = getTabBrowser(win);
|
for ( var win of vAPI.tabs.getWindows() ) {
|
||||||
if ( tabBrowser === null ) {
|
onWindowLoad.call(win);
|
||||||
continue;
|
tabBrowser = getTabBrowser(win);
|
||||||
}
|
if ( tabBrowser === null ) {
|
||||||
for ( var tab of tabBrowser.tabs ) {
|
|
||||||
if ( !vAPI.fennec && tab.hasAttribute('pending') ) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
knownTabs.add(tab, true);
|
for ( tab of tabBrowser.tabs ) {
|
||||||
tabIdFromTab(tab);
|
if ( vAPI.fennec || !tab.hasAttribute('pending') ) {
|
||||||
|
tabIdFromTarget(tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
cleanupTasks.push(function() {
|
Services.ww.registerNotification(windowWatcher);
|
||||||
knownTabs.clear();
|
|
||||||
});
|
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/Events/TabOpen
|
|
||||||
var onOpen = function({target}) {
|
|
||||||
knownTabs.add(target, true);
|
|
||||||
tabIdFromTab(tab);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/Events/TabShow
|
var stop = function() {
|
||||||
var onShow = function({target}) {
|
Services.ww.unregisterNotification(windowWatcher);
|
||||||
knownTabs.add(target, true);
|
|
||||||
tabIdFromTab(tab);
|
for ( var win of vAPI.tabs.getWindows() ) {
|
||||||
|
onWindowUnload.call(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
browserToTabIdMap.clear();
|
||||||
|
tabIdToBrowserMap.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/Events/TabClose
|
cleanupTasks.push(stop);
|
||||||
var onClose = function({target}) {
|
|
||||||
// target is tab in Firefox, browser in Fennec
|
|
||||||
var tabId = tabIdFromTab(target);
|
|
||||||
vAPI.tabs.onClosed(tabId);
|
|
||||||
delete vAPI.toolbarButton.tabs[tabId];
|
|
||||||
knownTabs.delete(target);
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/Events/TabSelect
|
|
||||||
var onSelect = function({target}) {
|
|
||||||
knownTabs.add(target, true);
|
|
||||||
vAPI.setIcon(tabIdFromTab(target), getOwnerWindow(target));
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onOpen: onOpen,
|
start: start,
|
||||||
onShow: onShow,
|
browserFromTarget: browserFromTarget,
|
||||||
onClose: onClose,
|
tabs: function() { return browserToTabIdMap.keys(); },
|
||||||
onSelect: onSelect,
|
tabIdFromTarget: tabIdFromTarget,
|
||||||
tabs: knownTabs,
|
browserFromTabId: browserFromTabId,
|
||||||
tabIdFromTab: tabIdFromTab,
|
indexFromTarget: indexFromTarget
|
||||||
tabFromTabId: tabFromTabId
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -868,7 +919,7 @@ vAPI.setIcon = function(tabId, iconStatus, badge) {
|
|||||||
var win = badge === undefined
|
var win = badge === undefined
|
||||||
? iconStatus
|
? iconStatus
|
||||||
: Services.wm.getMostRecentWindow('navigator:browser');
|
: Services.wm.getMostRecentWindow('navigator:browser');
|
||||||
var curTabId = tabWatcher.tabIdFromTab(getTabBrowser(win).selectedTab);
|
var curTabId = tabWatcher.tabIdFromTarget(getTabBrowser(win).selectedTab);
|
||||||
var tb = vAPI.toolbarButton;
|
var tb = vAPI.toolbarButton;
|
||||||
|
|
||||||
// from 'TabSelect' event
|
// from 'TabSelect' event
|
||||||
@ -932,7 +983,7 @@ vAPI.messaging.onMessage = function({target, data}) {
|
|||||||
|
|
||||||
var sender = {
|
var sender = {
|
||||||
tab: {
|
tab: {
|
||||||
id: tabWatcher.tabIdFromTab(target)
|
id: tabWatcher.tabIdFromTarget(target)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -988,6 +1039,8 @@ vAPI.messaging.setup = function(defaultHandler) {
|
|||||||
location.host + ':background',
|
location.host + ':background',
|
||||||
vAPI.messaging.onMessage
|
vAPI.messaging.onMessage
|
||||||
);
|
);
|
||||||
|
|
||||||
|
vAPI.messaging.defaultHandler = null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1444,20 +1497,20 @@ vAPI.net.registerListeners = function() {
|
|||||||
// a request would end up being categorized as a behind-the-scene
|
// a request would end up being categorized as a behind-the-scene
|
||||||
// requests.
|
// requests.
|
||||||
var details = e.data;
|
var details = e.data;
|
||||||
var tabId = tabWatcher.tabIdFromTab(e.target);
|
var tabId = tabWatcher.tabIdFromTarget(e.target);
|
||||||
var sourceTabId = null;
|
var sourceTabId = null;
|
||||||
|
|
||||||
// Popup candidate
|
// Popup candidate
|
||||||
if ( details.openerURL ) {
|
if ( details.openerURL ) {
|
||||||
for ( var tab of tabWatcher.tabs ) {
|
for ( var tab of tabWatcher.tabs() ) {
|
||||||
var URI = getBrowserForTab(tab).currentURI;
|
var URI = tab.currentURI;
|
||||||
|
|
||||||
// Probably isn't the best method to identify the source tab
|
// Probably isn't the best method to identify the source tab
|
||||||
if ( URI.spec !== details.openerURL ) {
|
if ( URI.spec !== details.openerURL ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceTabId = tabWatcher.tabIdFromTab(tab);
|
sourceTabId = tabWatcher.tabIdFromTarget(tab);
|
||||||
|
|
||||||
if ( sourceTabId === tabId ) {
|
if ( sourceTabId === tabId ) {
|
||||||
sourceTabId = null;
|
sourceTabId = null;
|
||||||
@ -1493,7 +1546,7 @@ vAPI.net.registerListeners = function() {
|
|||||||
var locationChangedListener = function(e) {
|
var locationChangedListener = function(e) {
|
||||||
var details = e.data;
|
var details = e.data;
|
||||||
var browser = e.target;
|
var browser = e.target;
|
||||||
var tabId = tabWatcher.tabIdFromTab(browser);
|
var tabId = tabWatcher.tabIdFromTarget(browser);
|
||||||
|
|
||||||
// Ignore notifications related to our popup
|
// Ignore notifications related to our popup
|
||||||
if ( details.url.lastIndexOf(vAPI.getURL('popup.html'), 0) === 0 ) {
|
if ( details.url.lastIndexOf(vAPI.getURL('popup.html'), 0) === 0 ) {
|
||||||
@ -1586,7 +1639,7 @@ vAPI.toolbarButton.init = function() {
|
|||||||
|
|
||||||
tb.onClick = function() {
|
tb.onClick = function() {
|
||||||
var win = Services.wm.getMostRecentWindow('navigator:browser');
|
var win = Services.wm.getMostRecentWindow('navigator:browser');
|
||||||
var curTabId = tabWatcher.tabIdFromTab(getTabBrowser(win).selectedTab);
|
var curTabId = tabWatcher.tabIdFromTarget(getTabBrowser(win).selectedTab);
|
||||||
vAPI.tabs.open({
|
vAPI.tabs.open({
|
||||||
url: 'popup.html?tabId=' + curTabId,
|
url: 'popup.html?tabId=' + curTabId,
|
||||||
index: -1,
|
index: -1,
|
||||||
@ -2021,7 +2074,7 @@ vAPI.contextMenu.create = function(details, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
callback(details, {
|
callback(details, {
|
||||||
id: tabWatcher.tabIdFromTab(gContextMenu.browser),
|
id: tabWatcher.tabIdFromTarget(gContextMenu.browser),
|
||||||
url: gContextMenu.browser.currentURI.asciiSpec
|
url: gContextMenu.browser.currentURI.asciiSpec
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -2053,7 +2106,7 @@ var optionsObserver = {
|
|||||||
Services.obs.addObserver(this, 'addon-options-displayed', false);
|
Services.obs.addObserver(this, 'addon-options-displayed', false);
|
||||||
cleanupTasks.push(this.unregister.bind(this));
|
cleanupTasks.push(this.unregister.bind(this));
|
||||||
|
|
||||||
var browser = getBrowserForTab(vAPI.tabs.get(null));
|
var browser = tabWatcher.browserFromTarget(vAPI.tabs.get(null));
|
||||||
if ( browser && browser.currentURI && browser.currentURI.spec === 'about:addons' ) {
|
if ( browser && browser.currentURI && browser.currentURI.spec === 'about:addons' ) {
|
||||||
this.observe(browser.contentDocument, 'addon-enabled', this.addonId);
|
this.observe(browser.contentDocument, 'addon-enabled', this.addonId);
|
||||||
}
|
}
|
||||||
@ -2101,12 +2154,12 @@ vAPI.lastError = function() {
|
|||||||
|
|
||||||
vAPI.onLoadAllCompleted = function() {
|
vAPI.onLoadAllCompleted = function() {
|
||||||
var µb = µBlock;
|
var µb = µBlock;
|
||||||
for ( var tab of tabWatcher.tabs ) {
|
var tabId;
|
||||||
var tabId = tabWatcher.tabIdFromTab(tab);
|
for ( var tab of tabWatcher.tabs() ) {
|
||||||
var browser = getBrowserForTab(tab);
|
tabId = tabWatcher.tabIdFromTarget(tab);
|
||||||
µb.tabContextManager.commit(tabId, browser.currentURI.asciiSpec);
|
µb.tabContextManager.commit(tabId, tab.currentURI.asciiSpec);
|
||||||
µb.bindTabToPageStats(tabId);
|
µb.bindTabToPageStats(tabId);
|
||||||
browser.messageManager.sendAsyncMessage(
|
tab.messageManager.sendAsyncMessage(
|
||||||
location.host + '-load-completed'
|
location.host + '-load-completed'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user