diff options
author | Matt A. Tobin <email@mattatobin.com> | 2018-02-10 02:51:36 -0500 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2018-02-10 02:51:36 -0500 |
commit | 37d5300335d81cecbecc99812747a657588c63eb (patch) | |
tree | 765efa3b6a56bb715d9813a8697473e120436278 /toolkit/jetpack/sdk/tabs/tabs-firefox.js | |
parent | b2bdac20c02b12f2057b9ef70b0a946113a00e00 (diff) | |
parent | 4fb11cd5966461bccc3ed1599b808237be6b0de9 (diff) | |
download | UXP-37d5300335d81cecbecc99812747a657588c63eb.tar UXP-37d5300335d81cecbecc99812747a657588c63eb.tar.gz UXP-37d5300335d81cecbecc99812747a657588c63eb.tar.lz UXP-37d5300335d81cecbecc99812747a657588c63eb.tar.xz UXP-37d5300335d81cecbecc99812747a657588c63eb.zip |
Merge branch 'ext-work'
Diffstat (limited to 'toolkit/jetpack/sdk/tabs/tabs-firefox.js')
-rw-r--r-- | toolkit/jetpack/sdk/tabs/tabs-firefox.js | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/toolkit/jetpack/sdk/tabs/tabs-firefox.js b/toolkit/jetpack/sdk/tabs/tabs-firefox.js new file mode 100644 index 000000000..1eefecb4c --- /dev/null +++ b/toolkit/jetpack/sdk/tabs/tabs-firefox.js @@ -0,0 +1,135 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +const { Class } = require('../core/heritage'); +const { Tab, tabEvents } = require('./tab'); +const { EventTarget } = require('../event/target'); +const { emit, setListeners } = require('../event/core'); +const { pipe } = require('../event/utils'); +const { observer: windowObserver } = require('../windows/observer'); +const { List, addListItem, removeListItem } = require('../util/list'); +const { modelFor } = require('../model/core'); +const { viewFor } = require('../view/core'); +const { getTabs, getSelectedTab } = require('./utils'); +const { getMostRecentBrowserWindow, isBrowser } = require('../window/utils'); +const { Options } = require('./common'); +const { isPrivate } = require('../private-browsing'); +const { ignoreWindow, isWindowPBSupported } = require('../private-browsing/utils') +const { isPrivateBrowsingSupported } = require('sdk/self'); + +const supportPrivateTabs = isPrivateBrowsingSupported && isWindowPBSupported; + +const Tabs = Class({ + implements: [EventTarget], + extends: List, + initialize: function() { + List.prototype.initialize.call(this); + + // We must do the list manipulation here where the object is extensible + this.on("open", tab => { + addListItem(this, tab); + }); + + this.on("close", tab => { + removeListItem(this, tab); + }); + }, + + get activeTab() { + let activeDomWin = getMostRecentBrowserWindow(); + if (!activeDomWin) + return null; + return modelFor(getSelectedTab(activeDomWin)); + }, + + open: function(options) { + options = Options(options); + + // TODO: Remove the dependency on the windows module: bug 792670 + let windows = require('../windows').browserWindows; + let activeWindow = windows.activeWindow; + + let privateState = supportPrivateTabs && options.isPrivate; + // When no isPrivate option was passed use the private state of the active + // window + if (activeWindow && privateState === undefined) + privateState = isPrivate(activeWindow); + + function getWindow(privateState) { + for (let window of windows) { + if (privateState === isPrivate(window)) { + return window; + } + } + return null; + } + + function openNewWindowWithTab() { + windows.open({ + url: options.url, + isPrivate: privateState, + onOpen: function(newWindow) { + let tab = newWindow.tabs[0]; + setListeners(tab, options); + + if (options.isPinned) + tab.pin(); + + // We don't emit the open event for the first tab in a new window so + // do it now the listeners are attached + emit(tab, "open", tab); + } + }); + } + + if (options.inNewWindow) + return openNewWindowWithTab(); + + // if the active window is in the state that we need then use it + if (activeWindow && (privateState === isPrivate(activeWindow))) + return activeWindow.tabs.open(options); + + // find a window in the state that we need + let window = getWindow(privateState); + if (window) + return window.tabs.open(options); + + return openNewWindowWithTab(); + } +}); + +const allTabs = new Tabs(); +// Export a new object with allTabs as the prototype, otherwise allTabs becomes +// frozen and addListItem and removeListItem don't work correctly. +module.exports = Object.create(allTabs); +pipe(tabEvents, module.exports); + +function addWindowTab(window, tabElement) { + let tab = new Tab(tabElement); + if (window) + addListItem(window.tabs, tab); + addListItem(allTabs, tab); + emit(allTabs, "open", tab); +} + +// Find tabs in already open windows +for (let tabElement of getTabs()) + addWindowTab(null, tabElement); + +// Detect tabs in new windows +windowObserver.on('open', domWindow => { + if (!isBrowser(domWindow) || ignoreWindow(domWindow)) + return; + + let window = null; + try { + modelFor(domWindow); + } + catch (e) { } + + for (let tabElement of getTabs(domWindow)) { + addWindowTab(window, tabElement); + } +}); |