diff options
Diffstat (limited to 'addon-sdk/source/lib/sdk/tabs/tab-firefox.js')
-rw-r--r-- | addon-sdk/source/lib/sdk/tabs/tab-firefox.js | 353 |
1 files changed, 0 insertions, 353 deletions
diff --git a/addon-sdk/source/lib/sdk/tabs/tab-firefox.js b/addon-sdk/source/lib/sdk/tabs/tab-firefox.js deleted file mode 100644 index f1da92379..000000000 --- a/addon-sdk/source/lib/sdk/tabs/tab-firefox.js +++ /dev/null @@ -1,353 +0,0 @@ -/* 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 { observer } = require('./observer'); -const { observer: windowObserver } = require('../windows/observer'); -const { addListItem, removeListItem } = require('../util/list'); -const { viewFor } = require('../view/core'); -const { modelFor } = require('../model/core'); -const { emit, setListeners } = require('../event/core'); -const { EventTarget } = require('../event/target'); -const { getBrowserForTab, setTabURL, getTabId, getTabURL, getTabForBrowser, - getTabs, getTabTitle, setTabTitle, getIndex, closeTab, reload, move, - activateTab, pin, unpin, isTab } = require('./utils'); -const { isBrowser, getInnerId, isWindowPrivate } = require('../window/utils'); -const { getThumbnailURIForWindow, BLANK } = require("../content/thumbnail"); -const { when } = require('../system/unload'); -const { ignoreWindow, isPrivate } = require('../private-browsing/utils') -const { defer } = require('../lang/functional'); -const { getURL } = require('../url/utils'); -const { frames, remoteRequire } = require('../remote/parent'); -remoteRequire('sdk/content/tab-events'); - -const modelsFor = new WeakMap(); -const viewsFor = new WeakMap(); -const destroyed = new WeakMap(); - -const tabEvents = {}; -exports.tabEvents = tabEvents; - -function browser(tab) { - return getBrowserForTab(viewsFor.get(tab)); -} - -function isDestroyed(tab) { - return destroyed.has(tab); -} - -function isClosed(tab) { - if (!viewsFor.has(tab)) - return true; - return viewsFor.get(tab).closing; -} - -// private tab attribute where the remote cached value is stored -const remoteReadyStateCached = Symbol("remoteReadyStateCached"); - -const Tab = Class({ - implements: [EventTarget], - initialize: function(tabElement, options = null) { - modelsFor.set(tabElement, this); - viewsFor.set(this, tabElement); - - if (options) { - EventTarget.prototype.initialize.call(this, options); - - if (options.isPinned) - this.pin(); - - // Note that activate is defered and so will run after any open event - // is sent out - if (!options.inBackground) - this.activate(); - } - - getURL.implement(this, tab => tab.url); - isPrivate.implement(this, tab => { - return isWindowPrivate(viewsFor.get(tab).ownerDocument.defaultView); - }); - }, - - get id() { - return isDestroyed(this) ? undefined : getTabId(viewsFor.get(this)); - }, - - get title() { - return isDestroyed(this) ? undefined : getTabTitle(viewsFor.get(this)); - }, - - set title(val) { - if (isDestroyed(this)) - return; - - setTabTitle(viewsFor.get(this), val); - }, - - get url() { - return isDestroyed(this) ? undefined : getTabURL(viewsFor.get(this)); - }, - - set url(val) { - if (isDestroyed(this)) - return; - - setTabURL(viewsFor.get(this), val); - }, - - get contentType() { - return isDestroyed(this) ? undefined : browser(this).documentContentType; - }, - - get index() { - return isDestroyed(this) ? undefined : getIndex(viewsFor.get(this)); - }, - - set index(val) { - if (isDestroyed(this)) - return; - - move(viewsFor.get(this), val); - }, - - get isPinned() { - return isDestroyed(this) ? undefined : viewsFor.get(this).pinned; - }, - - get window() { - if (isClosed(this)) - return undefined; - - // TODO: Remove the dependency on the windows module, see bug 792670 - require('../windows'); - let tabElement = viewsFor.get(this); - let domWindow = tabElement.ownerDocument.defaultView; - return modelFor(domWindow); - }, - - get readyState() { - return isDestroyed(this) ? undefined : this[remoteReadyStateCached] || "uninitialized"; - }, - - pin: function() { - if (isDestroyed(this)) - return; - - pin(viewsFor.get(this)); - }, - - unpin: function() { - if (isDestroyed(this)) - return; - - unpin(viewsFor.get(this)); - }, - - close: function(callback) { - let tabElement = viewsFor.get(this); - - if (isDestroyed(this) || !tabElement || !tabElement.parentNode) { - if (callback) - callback(); - return; - } - - this.once('close', () => { - this.destroy(); - if (callback) - callback(); - }); - - closeTab(tabElement); - }, - - reload: function() { - if (isDestroyed(this)) - return; - - reload(viewsFor.get(this)); - }, - - activate: defer(function() { - if (isDestroyed(this)) - return; - - activateTab(viewsFor.get(this)); - }), - - getThumbnail: function() { - if (isDestroyed(this)) - return BLANK; - - // TODO: This is unimplemented in e10s: bug 1148601 - if (browser(this).isRemoteBrowser) { - console.error('This method is not supported with E10S'); - return BLANK; - } - return getThumbnailURIForWindow(browser(this).contentWindow); - }, - - attach: function(options) { - if (isDestroyed(this)) - return; - - let { Worker } = require('../content/worker'); - let { connect, makeChildOptions } = require('../content/utils'); - - let worker = Worker(options); - worker.once("detach", () => { - worker.destroy(); - }); - - let attach = frame => { - let childOptions = makeChildOptions(options); - frame.port.emit("sdk/tab/attach", childOptions); - connect(worker, frame, { id: childOptions.id, url: this.url }); - }; - - // Do this synchronously if possible - let frame = frames.getFrameForBrowser(browser(this)); - if (frame) { - attach(frame); - } - else { - let listener = (frame) => { - if (frame.frameElement != browser(this)) - return; - - frames.off("attach", listener); - attach(frame); - }; - frames.on("attach", listener); - } - - return worker; - }, - - destroy: function() { - if (isDestroyed(this)) - return; - - destroyed.set(this, true); - } -}); -exports.Tab = Tab; - -viewFor.define(Tab, tab => viewsFor.get(tab)); - -// Returns the high-level window for this DOM window if the windows module has -// ever been loaded otherwise returns null -function maybeWindowFor(domWindow) { - try { - return modelFor(domWindow); - } - catch (e) { - return null; - } -} - -function tabEmit(tab, event, ...args) { - // Don't emit events for destroyed tabs - if (isDestroyed(tab)) - return; - - // If the windows module was never loaded this will return null. We don't need - // to emit to the window.tabs object in this case as nothing can be listening. - let tabElement = viewsFor.get(tab); - let window = maybeWindowFor(tabElement.ownerDocument.defaultView); - if (window) - emit(window.tabs, event, tab, ...args); - - emit(tabEvents, event, tab, ...args); - emit(tab, event, tab, ...args); -} - -function windowClosed(domWindow) { - if (!isBrowser(domWindow)) - return; - - for (let tabElement of getTabs(domWindow)) { - tabEventListener("close", tabElement); - } -} -windowObserver.on('close', windowClosed); - -// Don't want to send close events after unloaded -when(_ => { - windowObserver.off('close', windowClosed); -}); - -// Listen for tabbrowser events -function tabEventListener(event, tabElement, ...args) { - let domWindow = tabElement.ownerDocument.defaultView; - - if (ignoreWindow(domWindow)) - return; - - // Don't send events for tabs that are already closing - if (event != "close" && (tabElement.closing || !tabElement.parentNode)) - return; - - let tab = modelsFor.get(tabElement); - if (!tab) - tab = new Tab(tabElement); - - let window = maybeWindowFor(domWindow); - - if (event == "open") { - // Note, add to the window tabs first because if this is the first access to - // window.tabs it will be prefilling itself with everything from tabs - if (window) - addListItem(window.tabs, tab); - // The tabs module will take care of adding to its internal list - } - else if (event == "close") { - if (window) - removeListItem(window.tabs, tab); - // The tabs module will take care of removing from its internal list - } - else if (event == "init" || event == "create" || event == "ready" || event == "load") { - // Ignore load events from before browser windows have fully loaded, these - // are for about:blank in the initial tab - if (isBrowser(domWindow) && !domWindow.gBrowserInit.delayedStartupFinished) - return; - - // update the cached remote readyState value - let { readyState } = args[0] || {}; - tab[remoteReadyStateCached] = readyState; - } - - if (event == "init") { - // Do not emit events for the detected existent tabs, we only need to cache - // their current document.readyState value. - return; - } - - tabEmit(tab, event, ...args); - - // The tab object shouldn't be reachable after closed - if (event == "close") { - viewsFor.delete(tab); - modelsFor.delete(tabElement); - } -} -observer.on('*', tabEventListener); - -// Listen for tab events from content -frames.port.on('sdk/tab/event', (frame, event, ...args) => { - if (!frame.isTab) - return; - - let tabElement = getTabForBrowser(frame.frameElement); - if (!tabElement) - return; - - tabEventListener(event, tabElement, ...args); -}); - -// Implement `modelFor` function for the Tab instances.. -modelFor.when(isTab, view => { - return modelsFor.get(view); -}); |