summaryrefslogtreecommitdiffstats
path: root/addon-sdk/source/lib/sdk/tabs
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2018-02-09 06:46:43 -0500
committerMatt A. Tobin <email@mattatobin.com>2018-02-09 06:46:43 -0500
commitac46df8daea09899ce30dc8fd70986e258c746bf (patch)
tree2750d3125fc253fd5b0671e4bd268eff1fd97296 /addon-sdk/source/lib/sdk/tabs
parent8cecf8d5208f3945b35f879bba3015bb1a11bec6 (diff)
downloadUXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar
UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.gz
UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.lz
UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.tar.xz
UXP-ac46df8daea09899ce30dc8fd70986e258c746bf.zip
Move Add-on SDK source to toolkit/jetpack
Diffstat (limited to 'addon-sdk/source/lib/sdk/tabs')
-rw-r--r--addon-sdk/source/lib/sdk/tabs/common.js34
-rw-r--r--addon-sdk/source/lib/sdk/tabs/events.js39
-rw-r--r--addon-sdk/source/lib/sdk/tabs/helpers.js22
-rw-r--r--addon-sdk/source/lib/sdk/tabs/namespace.js10
-rw-r--r--addon-sdk/source/lib/sdk/tabs/observer.js113
-rw-r--r--addon-sdk/source/lib/sdk/tabs/tab-fennec.js249
-rw-r--r--addon-sdk/source/lib/sdk/tabs/tab-firefox.js353
-rw-r--r--addon-sdk/source/lib/sdk/tabs/tab.js24
-rw-r--r--addon-sdk/source/lib/sdk/tabs/tabs-firefox.js135
-rw-r--r--addon-sdk/source/lib/sdk/tabs/utils.js370
-rw-r--r--addon-sdk/source/lib/sdk/tabs/worker.js17
11 files changed, 0 insertions, 1366 deletions
diff --git a/addon-sdk/source/lib/sdk/tabs/common.js b/addon-sdk/source/lib/sdk/tabs/common.js
deleted file mode 100644
index 9ee512a7b..000000000
--- a/addon-sdk/source/lib/sdk/tabs/common.js
+++ /dev/null
@@ -1,34 +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 { validateOptions } = require("../deprecated/api-utils");
-const { data } = require("../self");
-
-function Options(options) {
- if ('string' === typeof options)
- options = { url: options };
-
- return validateOptions(options, {
- url: {
- is: ["string"],
- map: (v) => v ? data.url(v) : v
- },
- inBackground: {
- map: Boolean,
- is: ["undefined", "boolean"]
- },
- isPinned: { is: ["undefined", "boolean"] },
- isPrivate: { is: ["undefined", "boolean"] },
- inNewWindow: { is: ["undefined", "boolean"] },
- onOpen: { is: ["undefined", "function"] },
- onClose: { is: ["undefined", "function"] },
- onReady: { is: ["undefined", "function"] },
- onLoad: { is: ["undefined", "function"] },
- onPageShow: { is: ["undefined", "function"] },
- onActivate: { is: ["undefined", "function"] },
- onDeactivate: { is: ["undefined", "function"] }
- });
-}
-exports.Options = Options;
diff --git a/addon-sdk/source/lib/sdk/tabs/events.js b/addon-sdk/source/lib/sdk/tabs/events.js
deleted file mode 100644
index 65650f9dc..000000000
--- a/addon-sdk/source/lib/sdk/tabs/events.js
+++ /dev/null
@@ -1,39 +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";
-
-module.metadata = {
- "stability": "unstable"
-};
-
-const ON_PREFIX = "on";
-const TAB_PREFIX = "Tab";
-
-const EVENTS = {
- ready: "DOMContentLoaded",
- load: "load", // Used for non-HTML content
- pageshow: "pageshow", // Used for cached content
- open: "TabOpen",
- close: "TabClose",
- activate: "TabSelect",
- deactivate: null,
- pinned: "TabPinned",
- unpinned: "TabUnpinned"
-}
-exports.EVENTS = EVENTS;
-
-Object.keys(EVENTS).forEach(function(name) {
- EVENTS[name] = {
- name: name,
- listener: createListenerName(name),
- dom: EVENTS[name]
- }
-});
-
-function createListenerName (name) {
- if (name === 'pageshow')
- return 'onPageShow';
- else
- return ON_PREFIX + name.charAt(0).toUpperCase() + name.substr(1);
-}
diff --git a/addon-sdk/source/lib/sdk/tabs/helpers.js b/addon-sdk/source/lib/sdk/tabs/helpers.js
deleted file mode 100644
index b2c8aa013..000000000
--- a/addon-sdk/source/lib/sdk/tabs/helpers.js
+++ /dev/null
@@ -1,22 +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';
-
-module.metadata = {
- 'stability': 'unstable'
-};
-
-
-// NOTE: This file should only export Tab instances
-
-
-const { getTabForBrowser: getRawTabForBrowser } = require('./utils');
-const { modelFor } = require('../model/core');
-
-exports.getTabForRawTab = modelFor;
-
-function getTabForBrowser(browser) {
- return modelFor(getRawTabForBrowser(browser)) || null;
-}
-exports.getTabForBrowser = getTabForBrowser;
diff --git a/addon-sdk/source/lib/sdk/tabs/namespace.js b/addon-sdk/source/lib/sdk/tabs/namespace.js
deleted file mode 100644
index 3553b1a99..000000000
--- a/addon-sdk/source/lib/sdk/tabs/namespace.js
+++ /dev/null
@@ -1,10 +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';
-
-var { ns } = require('../core/namespace');
-
-exports.tabsNS = ns();
-exports.tabNS = ns();
-exports.rawTabNS = ns();
diff --git a/addon-sdk/source/lib/sdk/tabs/observer.js b/addon-sdk/source/lib/sdk/tabs/observer.js
deleted file mode 100644
index 4e935cd62..000000000
--- a/addon-sdk/source/lib/sdk/tabs/observer.js
+++ /dev/null
@@ -1,113 +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';
-
-module.metadata = {
- "stability": "unstable"
-};
-
-const { EventTarget } = require("../event/target");
-const { emit } = require("../event/core");
-const { DOMEventAssembler } = require("../deprecated/events/assembler");
-const { Class } = require("../core/heritage");
-const { getActiveTab, getTabs } = require("./utils");
-const { browserWindowIterator } = require("../deprecated/window-utils");
-const { isBrowser, windows, getMostRecentBrowserWindow } = require("../window/utils");
-const { observer: windowObserver } = require("../windows/observer");
-const { when } = require("../system/unload");
-
-const EVENTS = {
- "TabOpen": "open",
- "TabClose": "close",
- "TabSelect": "select",
- "TabMove": "move",
- "TabPinned": "pinned",
- "TabUnpinned": "unpinned"
-};
-
-const selectedTab = Symbol("observer/state/selectedTab");
-
-// Event emitter objects used to register listeners and emit events on them
-// when they occur.
-const Observer = Class({
- implements: [EventTarget, DOMEventAssembler],
- initialize() {
- this[selectedTab] = null;
- // Currently Gecko does not dispatch any event on the previously selected
- // tab before / after "TabSelect" is dispatched. In order to work around this
- // limitation we keep track of selected tab and emit "deactivate" event with
- // that before emitting "activate" on selected tab.
- this.on("select", tab => {
- const selected = this[selectedTab];
- if (selected !== tab) {
- if (selected) {
- emit(this, 'deactivate', selected);
- }
-
- if (tab) {
- this[selectedTab] = tab;
- emit(this, 'activate', this[selectedTab]);
- }
- }
- });
-
-
- // We also observe opening / closing windows in order to add / remove it's
- // containers to the observed list.
- windowObserver.on("open", chromeWindow => {
- if (isBrowser(chromeWindow)) {
- this.observe(chromeWindow);
- }
- });
-
- windowObserver.on("close", chromeWindow => {
- if (isBrowser(chromeWindow)) {
- // Bug 751546: Emit `deactivate` event on window close immediatly
- // Otherwise we are going to face "dead object" exception on `select` event
- if (getActiveTab(chromeWindow) === this[selectedTab]) {
- emit(this, "deactivate", this[selectedTab]);
- this[selectedTab] = null;
- }
- this.ignore(chromeWindow);
- }
- });
-
-
- // Currently gecko does not dispatches "TabSelect" events when different
- // window gets activated. To work around this limitation we emulate "select"
- // event for this case.
- windowObserver.on("activate", chromeWindow => {
- if (isBrowser(chromeWindow)) {
- emit(this, "select", getActiveTab(chromeWindow));
- }
- });
-
- // We should synchronize state, since probably we already have at least one
- // window open.
- for (let chromeWindow of browserWindowIterator()) {
- this.observe(chromeWindow);
- }
-
- when(_ => {
- // Don't dispatch a deactivate event during unload.
- this[selectedTab] = null;
- });
- },
- /**
- * Events that are supported and emitted by the module.
- */
- supportedEventsTypes: Object.keys(EVENTS),
- /**
- * Function handles all the supported events on all the windows that are
- * observed. Method is used to proxy events to the listeners registered on
- * this event emitter.
- * @param {Event} event
- * Keyboard event being emitted.
- */
- handleEvent: function handleEvent(event) {
- emit(this, EVENTS[event.type], event.target, event);
- }
-});
-
-exports.observer = new Observer();
diff --git a/addon-sdk/source/lib/sdk/tabs/tab-fennec.js b/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
deleted file mode 100644
index 3927337f6..000000000
--- a/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
+++ /dev/null
@@ -1,249 +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 { Cc, Ci } = require('chrome');
-const { Class } = require('../core/heritage');
-const { tabNS, rawTabNS } = require('./namespace');
-const { EventTarget } = require('../event/target');
-const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL,
- getTabContentWindow, getTabForBrowser, setTabURL, getOwnerWindow,
- getTabContentDocument, getTabContentType, getTabId, isTab } = require('./utils');
-const { emit } = require('../event/core');
-const { isPrivate } = require('../private-browsing/utils');
-const { isWindowPrivate } = require('../window/utils');
-const { when: unload } = require('../system/unload');
-const { BLANK } = require('../content/thumbnail');
-const { viewFor } = require('../view/core');
-const { EVENTS } = require('./events');
-const { modelFor } = require('../model/core');
-
-const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec';
-
-const Tab = Class({
- extends: EventTarget,
- initialize: function initialize(options) {
- options = options.tab ? options : { tab: options };
- let tab = options.tab;
-
- EventTarget.prototype.initialize.call(this, options);
- let tabInternals = tabNS(this);
- rawTabNS(tab).tab = this;
-
- let window = tabInternals.window = options.window || getOwnerWindow(tab);
- tabInternals.tab = tab;
-
- // TabReady
- let onReady = tabInternals.onReady = onTabReady.bind(this);
- tab.browser.addEventListener(EVENTS.ready.dom, onReady, false);
-
- // TabPageShow
- let onPageShow = tabInternals.onPageShow = onTabPageShow.bind(this);
- tab.browser.addEventListener(EVENTS.pageshow.dom, onPageShow, false);
-
- // TabLoad
- let onLoad = tabInternals.onLoad = onTabLoad.bind(this);
- tab.browser.addEventListener(EVENTS.load.dom, onLoad, true);
-
- // TabClose
- let onClose = tabInternals.onClose = onTabClose.bind(this);
- window.BrowserApp.deck.addEventListener(EVENTS.close.dom, onClose, false);
-
- unload(cleanupTab.bind(null, this));
- },
-
- /**
- * The title of the page currently loaded in the tab.
- * Changing this property changes an actual title.
- * @type {String}
- */
- get title() {
- return getTabTitle(tabNS(this).tab);
- },
- set title(title) {
- setTabTitle(tabNS(this).tab, title);
- },
-
- /**
- * Location of the page currently loaded in this tab.
- * Changing this property will loads page under under the specified location.
- * @type {String}
- */
- get url() {
- return tabNS(this).closed ? undefined : getTabURL(tabNS(this).tab);
- },
- set url(url) {
- setTabURL(tabNS(this).tab, url);
- },
-
- getThumbnail: function() {
- // TODO: implement!
- console.error(ERR_FENNEC_MSG);
-
- // return 80x45 blank default
- return BLANK;
- },
-
- /**
- * tab's document readyState, or 'uninitialized' if it doesn't even exist yet.
- */
- get readyState() {
- let doc = getTabContentDocument(tabNS(this).tab);
- return doc && doc.readyState || 'uninitialized';
- },
-
- get id() {
- return getTabId(tabNS(this).tab);
- },
-
- /**
- * The index of the tab relative to other tabs in the application window.
- * Changing this property will change order of the actual position of the tab.
- * @type {Number}
- */
- get index() {
- if (tabNS(this).closed) return undefined;
-
- let tabs = tabNS(this).window.BrowserApp.tabs;
- let tab = tabNS(this).tab;
- for (var i = tabs.length; i >= 0; i--) {
- if (tabs[i] === tab)
- return i;
- }
- return null;
- },
- set index(value) {
- console.error(ERR_FENNEC_MSG); // TODO
- },
-
- /**
- * Whether or not tab is pinned (Is an app-tab).
- * @type {Boolean}
- */
- get isPinned() {
- console.error(ERR_FENNEC_MSG); // TODO
- return false; // TODO
- },
- pin: function pin() {
- console.error(ERR_FENNEC_MSG); // TODO
- },
- unpin: function unpin() {
- console.error(ERR_FENNEC_MSG); // TODO
- },
-
- /**
- * Returns the MIME type that the document loaded in the tab is being
- * rendered as.
- * @type {String}
- */
- get contentType() {
- return getTabContentType(tabNS(this).tab);
- },
-
- /**
- * Create a worker for this tab, first argument is options given to Worker.
- * @type {Worker}
- */
- attach: function attach(options) {
- // BUG 792946 https://bugzilla.mozilla.org/show_bug.cgi?id=792946
- // TODO: fix this circular dependency
- let { Worker } = require('./worker');
- return Worker(options, getTabContentWindow(tabNS(this).tab));
- },
-
- /**
- * Make this tab active.
- */
- activate: function activate() {
- activateTab(tabNS(this).tab, tabNS(this).window);
- },
-
- /**
- * Close the tab
- */
- close: function close(callback) {
- let tab = this;
- this.once(EVENTS.close.name, function () {
- tabNS(tab).closed = true;
- if (callback) callback();
- });
-
- closeTab(tabNS(this).tab);
- },
-
- /**
- * Reload the tab
- */
- reload: function reload() {
- tabNS(this).tab.browser.reload();
- }
-});
-exports.Tab = Tab;
-
-// Implement `viewFor` polymorphic function for the Tab
-// instances.
-viewFor.define(Tab, x => tabNS(x).tab);
-
-function cleanupTab(tab) {
- let tabInternals = tabNS(tab);
- if (!tabInternals.tab)
- return;
-
- if (tabInternals.tab.browser) {
- tabInternals.tab.browser.removeEventListener(EVENTS.ready.dom, tabInternals.onReady, false);
- tabInternals.tab.browser.removeEventListener(EVENTS.pageshow.dom, tabInternals.onPageShow, false);
- tabInternals.tab.browser.removeEventListener(EVENTS.load.dom, tabInternals.onLoad, true);
- }
- tabInternals.onReady = null;
- tabInternals.onPageShow = null;
- tabInternals.onLoad = null;
- tabInternals.window.BrowserApp.deck.removeEventListener(EVENTS.close.dom, tabInternals.onClose, false);
- tabInternals.onClose = null;
- rawTabNS(tabInternals.tab).tab = null;
- tabInternals.tab = null;
- tabInternals.window = null;
-}
-
-function onTabReady(event) {
- let win = event.target.defaultView;
-
- // ignore frames
- if (win === win.top) {
- emit(this, 'ready', this);
- }
-}
-
-function onTabLoad (event) {
- let win = event.target.defaultView;
-
- // ignore frames
- if (win === win.top) {
- emit(this, 'load', this);
- }
-}
-
-function onTabPageShow(event) {
- let win = event.target.defaultView;
- if (win === win.top)
- emit(this, 'pageshow', this, event.persisted);
-}
-
-// TabClose
-function onTabClose(event) {
- let rawTab = getTabForBrowser(event.target);
- if (tabNS(this).tab !== rawTab)
- return;
-
- emit(this, EVENTS.close.name, this);
- cleanupTab(this);
-};
-
-isPrivate.implement(Tab, tab => {
- return isWindowPrivate(getTabContentWindow(tabNS(tab).tab));
-});
-
-// Implement `modelFor` function for the Tab instances.
-modelFor.when(isTab, rawTab => {
- return rawTabNS(rawTab).tab;
-});
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);
-});
diff --git a/addon-sdk/source/lib/sdk/tabs/tab.js b/addon-sdk/source/lib/sdk/tabs/tab.js
deleted file mode 100644
index fa2272494..000000000
--- a/addon-sdk/source/lib/sdk/tabs/tab.js
+++ /dev/null
@@ -1,24 +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';
-
-module.metadata = {
- 'stability': 'unstable'
-};
-
-const { getTargetWindow } = require("../content/mod");
-const { getTabContentWindow, isTab } = require("./utils");
-const { viewFor } = require("../view/core");
-
-if (require('../system/xul-app').name == 'Fennec') {
- module.exports = require('./tab-fennec');
-}
-else {
- module.exports = require('./tab-firefox');
-}
-
-getTargetWindow.when(isTab, tab => getTabContentWindow(tab));
-
-getTargetWindow.when(x => x instanceof module.exports.Tab,
- tab => getTabContentWindow(viewFor(tab)));
diff --git a/addon-sdk/source/lib/sdk/tabs/tabs-firefox.js b/addon-sdk/source/lib/sdk/tabs/tabs-firefox.js
deleted file mode 100644
index 1eefecb4c..000000000
--- a/addon-sdk/source/lib/sdk/tabs/tabs-firefox.js
+++ /dev/null
@@ -1,135 +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 { 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);
- }
-});
diff --git a/addon-sdk/source/lib/sdk/tabs/utils.js b/addon-sdk/source/lib/sdk/tabs/utils.js
deleted file mode 100644
index eae3d41fe..000000000
--- a/addon-sdk/source/lib/sdk/tabs/utils.js
+++ /dev/null
@@ -1,370 +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';
-
-module.metadata = {
- 'stability': 'unstable'
-};
-
-
-// NOTE: This file should only deal with xul/native tabs
-
-
-const { Ci, Cu } = require('chrome');
-const { defer } = require("../lang/functional");
-const { windows, isBrowser } = require('../window/utils');
-const { isPrivateBrowsingSupported } = require('../self');
-const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
-
-// Bug 834961: ignore private windows when they are not supported
-function getWindows() {
- return windows(null, { includePrivate: isPrivateBrowsingSupported });
-}
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-// Define predicate functions that can be used to detech weather
-// we deal with fennec tabs or firefox tabs.
-
-// Predicate to detect whether tab is XUL "Tab" node.
-const isXULTab = tab =>
- tab instanceof Ci.nsIDOMNode &&
- tab.nodeName === "tab" &&
- tab.namespaceURI === XUL_NS;
-exports.isXULTab = isXULTab;
-
-// Predicate to detecet whether given tab is a fettec tab.
-// Unfortunately we have to guess via duck typinng of:
-// http://mxr.mozilla.org/mozilla-central/source/mobile/android/chrome/content/browser.js#2583
-const isFennecTab = tab =>
- tab &&
- tab.QueryInterface &&
- Ci.nsIBrowserTab &&
- tab.QueryInterface(Ci.nsIBrowserTab) === tab;
-exports.isFennecTab = isFennecTab;
-
-const isTab = x => isXULTab(x) || isFennecTab(x);
-exports.isTab = isTab;
-
-function activateTab(tab, window) {
- let gBrowser = getTabBrowserForTab(tab);
-
- // normal case
- if (gBrowser) {
- gBrowser.selectedTab = tab;
- }
- // fennec ?
- else if (window && window.BrowserApp) {
- window.BrowserApp.selectTab(tab);
- }
- return null;
-}
-exports.activateTab = activateTab;
-
-function getTabBrowser(window) {
- // bug 1009938 - may be null in SeaMonkey
- return window.gBrowser || window.getBrowser();
-}
-exports.getTabBrowser = getTabBrowser;
-
-function getTabContainer(window) {
- return getTabBrowser(window).tabContainer;
-}
-exports.getTabContainer = getTabContainer;
-
-/**
- * Returns the tabs for the `window` if given, or the tabs
- * across all the browser's windows otherwise.
- *
- * @param {nsIWindow} [window]
- * A reference to a window
- *
- * @returns {Array} an array of Tab objects
- */
-function getTabs(window) {
- if (arguments.length === 0) {
- return getWindows().
- filter(isBrowser).
- reduce((tabs, window) => tabs.concat(getTabs(window)), []);
- }
-
- // fennec
- if (window.BrowserApp)
- return window.BrowserApp.tabs;
-
- // firefox - default
- return Array.filter(getTabContainer(window).children, t => !t.closing);
-}
-exports.getTabs = getTabs;
-
-function getActiveTab(window) {
- return getSelectedTab(window);
-}
-exports.getActiveTab = getActiveTab;
-
-function getOwnerWindow(tab) {
- // normal case
- if (tab.ownerDocument)
- return tab.ownerDocument.defaultView;
-
- // try fennec case
- return getWindowHoldingTab(tab);
-}
-exports.getOwnerWindow = getOwnerWindow;
-
-// fennec
-function getWindowHoldingTab(rawTab) {
- for (let window of getWindows()) {
- // this function may be called when not using fennec,
- // but BrowserApp is only defined on Fennec
- if (!window.BrowserApp)
- continue;
-
- for (let tab of window.BrowserApp.tabs) {
- if (tab === rawTab)
- return window;
- }
- }
-
- return null;
-}
-
-function openTab(window, url, options) {
- options = options || {};
-
- // fennec?
- if (window.BrowserApp) {
- return window.BrowserApp.addTab(url, {
- selected: options.inBackground ? false : true,
- pinned: options.isPinned || false,
- isPrivate: options.isPrivate || false,
- parentId: window.BrowserApp.selectedTab.id
- });
- }
-
- // firefox
- let newTab = window.gBrowser.addTab(url);
- if (!options.inBackground) {
- activateTab(newTab);
- }
- return newTab;
-};
-exports.openTab = openTab;
-
-function isTabOpen(tab) {
- // try normal case then fennec case
- return !!((tab.linkedBrowser) || getWindowHoldingTab(tab));
-}
-exports.isTabOpen = isTabOpen;
-
-function closeTab(tab) {
- let gBrowser = getTabBrowserForTab(tab);
- // normal case?
- if (gBrowser) {
- // Bug 699450: the tab may already have been detached
- if (!tab.parentNode)
- return;
- return gBrowser.removeTab(tab);
- }
-
- let window = getWindowHoldingTab(tab);
- // fennec?
- if (window && window.BrowserApp) {
- // Bug 699450: the tab may already have been detached
- if (!tab.browser)
- return;
- return window.BrowserApp.closeTab(tab);
- }
- return null;
-}
-exports.closeTab = closeTab;
-
-function getURI(tab) {
- if (tab.browser) // fennec
- return tab.browser.currentURI.spec;
- return tab.linkedBrowser.currentURI.spec;
-}
-exports.getURI = getURI;
-
-function getTabBrowserForTab(tab) {
- let outerWin = getOwnerWindow(tab);
- if (outerWin)
- return getOwnerWindow(tab).gBrowser;
- return null;
-}
-exports.getTabBrowserForTab = getTabBrowserForTab;
-
-function getBrowserForTab(tab) {
- if (tab.browser) // fennec
- return tab.browser;
-
- return tab.linkedBrowser;
-}
-exports.getBrowserForTab = getBrowserForTab;
-
-function getTabId(tab) {
- if (tab.browser) // fennec
- return tab.id
-
- return String.split(tab.linkedPanel, 'panel').pop();
-}
-exports.getTabId = getTabId;
-
-function getTabForId(id) {
- return getTabs().find(tab => getTabId(tab) === id) || null;
-}
-exports.getTabForId = getTabForId;
-
-function getTabTitle(tab) {
- return getBrowserForTab(tab).contentTitle || tab.label || "";
-}
-exports.getTabTitle = getTabTitle;
-
-function setTabTitle(tab, title) {
- title = String(title);
- if (tab.browser) {
- // Fennec
- tab.browser.contentDocument.title = title;
- }
- else {
- let browser = getBrowserForTab(tab);
- // Note that we aren't actually setting the document title in e10s, just
- // the title the browser thinks the content has
- if (browser.isRemoteBrowser)
- browser._contentTitle = title;
- else
- browser.contentDocument.title = title;
- }
- tab.label = String(title);
-}
-exports.setTabTitle = setTabTitle;
-
-function getTabContentDocument(tab) {
- return getBrowserForTab(tab).contentDocument;
-}
-exports.getTabContentDocument = getTabContentDocument;
-
-function getTabContentWindow(tab) {
- return getBrowserForTab(tab).contentWindow;
-}
-exports.getTabContentWindow = getTabContentWindow;
-
-/**
- * Returns all tabs' content windows across all the browsers' windows
- */
-function getAllTabContentWindows() {
- return getTabs().map(getTabContentWindow);
-}
-exports.getAllTabContentWindows = getAllTabContentWindows;
-
-// gets the tab containing the provided window
-function getTabForContentWindow(window) {
- return getTabs().find(tab => getTabContentWindow(tab) === window.top) || null;
-}
-exports.getTabForContentWindow = getTabForContentWindow;
-
-// only sdk/selection.js is relying on shims
-function getTabForContentWindowNoShim(window) {
- function getTabContentWindowNoShim(tab) {
- let browser = getBrowserForTab(tab);
- return ShimWaiver.getProperty(browser, "contentWindow");
- }
- return getTabs().find(tab => getTabContentWindowNoShim(tab) === window.top) || null;
-}
-exports.getTabForContentWindowNoShim = getTabForContentWindowNoShim;
-
-function getTabURL(tab) {
- return String(getBrowserForTab(tab).currentURI.spec);
-}
-exports.getTabURL = getTabURL;
-
-function setTabURL(tab, url) {
- let browser = getBrowserForTab(tab);
- browser.loadURI(String(url));
-}
-// "TabOpen" event is fired when it's still "about:blank" is loaded in the
-// changing `location` property of the `contentDocument` has no effect since
-// seems to be either ignored or overridden by internal listener, there for
-// location change is enqueued for the next turn of event loop.
-exports.setTabURL = defer(setTabURL);
-
-function getTabContentType(tab) {
- return getBrowserForTab(tab).contentDocument.contentType;
-}
-exports.getTabContentType = getTabContentType;
-
-function getSelectedTab(window) {
- if (window.BrowserApp) // fennec?
- return window.BrowserApp.selectedTab;
- if (window.gBrowser)
- return window.gBrowser.selectedTab;
- return null;
-}
-exports.getSelectedTab = getSelectedTab;
-
-
-function getTabForBrowser(browser) {
- for (let window of getWindows()) {
- // this function may be called when not using fennec
- if (!window.BrowserApp)
- continue;
-
- for (let tab of window.BrowserApp.tabs) {
- if (tab.browser === browser)
- return tab;
- }
- }
-
- let tabbrowser = browser.getTabBrowser && browser.getTabBrowser()
- return !!tabbrowser && tabbrowser.getTabForBrowser(browser);
-}
-exports.getTabForBrowser = getTabForBrowser;
-
-function pin(tab) {
- let gBrowser = getTabBrowserForTab(tab);
- // TODO: Implement Fennec support
- if (gBrowser) gBrowser.pinTab(tab);
-}
-exports.pin = pin;
-
-function unpin(tab) {
- let gBrowser = getTabBrowserForTab(tab);
- // TODO: Implement Fennec support
- if (gBrowser) gBrowser.unpinTab(tab);
-}
-exports.unpin = unpin;
-
-function isPinned(tab) {
- return !!tab.pinned;
-}
-exports.isPinned = isPinned;
-
-function reload(tab) {
- getBrowserForTab(tab).reload();
-}
-exports.reload = reload
-
-function getIndex(tab) {
- let gBrowser = getTabBrowserForTab(tab);
- // Firefox
- if (gBrowser) {
- return tab._tPos;
- }
- // Fennec
- else {
- let window = getWindowHoldingTab(tab)
- let tabs = window.BrowserApp.tabs;
- for (let i = tabs.length; i >= 0; i--)
- if (tabs[i] === tab) return i;
- }
-}
-exports.getIndex = getIndex;
-
-function move(tab, index) {
- let gBrowser = getTabBrowserForTab(tab);
- // Firefox
- if (gBrowser) gBrowser.moveTabTo(tab, index);
- // TODO: Implement fennec support
-}
-exports.move = move;
diff --git a/addon-sdk/source/lib/sdk/tabs/worker.js b/addon-sdk/source/lib/sdk/tabs/worker.js
deleted file mode 100644
index d2ba33696..000000000
--- a/addon-sdk/source/lib/sdk/tabs/worker.js
+++ /dev/null
@@ -1,17 +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 ContentWorker = require('../content/worker').Worker;
-
-function Worker(options, window) {
- options.window = window;
-
- let worker = ContentWorker(options);
- worker.once("detach", function detach() {
- worker.destroy();
- });
- return worker;
-}
-exports.Worker = Worker; \ No newline at end of file