aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.12/lib
diff options
context:
space:
mode:
Diffstat (limited to 'tools/addon-sdk-1.12/lib')
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/addon-page.js38
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/addon/installer.js106
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/addon/runner.js153
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/base64.js41
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/clipboard.js333
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/console/plain-text.js88
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/console/traceback.js118
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/content-proxy.js870
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/content-worker.js308
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/content.js15
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/loader.js204
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/symbiont.js197
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/thumbnail.js46
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/worker.js582
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/context-menu.js1494
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/core/heritage.js146
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/core/namespace.js43
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/core/promise.js230
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/api-utils.js158
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/app-strings.js67
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/cortex.js113
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/errors.js64
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/events.js182
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/events/assembler.js53
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/light-traits.js600
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/list.js118
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/memory.js118
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/observer-service.js134
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/tab-browser.js731
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/traits.js187
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/traits/core.js322
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/unit-test-finder.js71
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/unit-test.js451
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/deprecated/window-utils.js201
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/dom/events.js140
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/dom/events/keys.js64
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/event/core.js152
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/event/target.js80
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/frame/hidden-frame.js181
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/frame/utils.js63
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/hotkeys.js41
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/io/byte-streams.js106
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/io/data.js84
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/io/file.js196
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/io/text-streams.js244
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/keyboard/hotkeys.js111
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/keyboard/observer.js58
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/keyboard/utils.js190
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/l10n.js83
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/l10n/core.js35
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/l10n/html.js93
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/l10n/loader.js71
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/l10n/locale.js126
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/l10n/plural-rules.js403
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/l10n/prefs.js44
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/lang/functional.js163
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/lang/type.js344
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/loader/cuddlefish.js78
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/loader/sandbox.js50
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/net/url.js108
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/net/xhr.js154
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/notifications.js83
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/page-mod.js380
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/page-mod/match-pattern.js108
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/page-worker.js71
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/panel.js403
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/passwords.js62
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/passwords/utils.js105
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/platform/xpcom.js229
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/preferences/event-target.js60
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/preferences/service.js174
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/private-browsing.js36
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/private-browsing/utils.js74
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/querystring.js121
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/request.js213
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/selection.js481
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/self.js36
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/simple-prefs.js32
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/simple-storage.js237
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/system.js155
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/system/environment.js58
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/system/events.js113
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/system/globals.js54
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/system/runtime.js19
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/system/unload.js82
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/system/xul-app.js67
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs.js10
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/common.js23
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/events.js30
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/helpers.js17
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/namespace.js9
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/observer.js99
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/tab-fennec.js141
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/tab-firefox.js201
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/tab.js21
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/tabs-firefox.js26
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/tabs.js21
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/utils.js222
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/tabs/worker.js17
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/test.js112
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/test/assert.js349
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/test/harness.js327
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/test/httpd.js5174
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/test/loader.js28
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/test/runner.js150
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/test/tmp-file.js73
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/timers.js53
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/url.js236
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/util/array.js89
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/util/collection.js112
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/util/deprecate.js27
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/util/list.js78
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/util/object.js57
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/util/registry.js61
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/util/uuid.js17
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/widget.js938
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/window/browser.js41
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/window/namespace.js6
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/window/utils.js205
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/windows.js21
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/windows/dom.js33
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/windows/fennec.js84
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/windows/firefox.js241
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/windows/loader.js120
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/windows/observer.js52
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/windows/tabs-fennec.js190
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/windows/tabs-firefox.js188
-rw-r--r--tools/addon-sdk-1.12/lib/toolkit/loader.js400
128 files changed, 0 insertions, 25796 deletions
diff --git a/tools/addon-sdk-1.12/lib/sdk/addon-page.js b/tools/addon-sdk-1.12/lib/sdk/addon-page.js
deleted file mode 100644
index 6440b25..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/addon-page.js
+++ /dev/null
@@ -1,38 +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': 'experimental'
-};
-
-const { WindowTracker } = require('./deprecated/window-utils');
-const { isXULBrowser } = require('./window/utils');
-const { add, remove } = require('./util/array');
-const { getTabs, closeTab, getURI } = require('./tabs/utils');
-const { data } = require('./self');
-
-const addonURL = data.url('index.html');
-
-WindowTracker({
- onTrack: function onTrack(window) {
- if (isXULBrowser(window))
- add(window.XULBrowserWindow.inContentWhitelist, addonURL);
- },
- onUntrack: function onUntrack(window) {
- if (isXULBrowser(window))
- getTabs(window).filter(tabFilter).forEach(untrackTab.bind(null, window));
- }
-});
-
-function tabFilter(tab) {
- return getURI(tab) === addonURL;
-}
-
-function untrackTab(window, tab) {
- // Note: `onUntrack` will be called for all windows on add-on unloads,
- // so we want to clean them up from these URLs.
- remove(window.XULBrowserWindow.inContentWhitelist, addonURL);
- closeTab(tab);
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/addon/installer.js b/tools/addon-sdk-1.12/lib/sdk/addon/installer.js
deleted file mode 100644
index f72b21e..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/addon/installer.js
+++ /dev/null
@@ -1,106 +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/. */
-
-module.metadata = {
- "stability": "experimental"
-};
-
-const { Cc, Ci, Cu } = require("chrome");
-const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm");
-const { defer } = require("../core/promise");
-const { setTimeout } = require("../timers");
-
-/**
- * `install` method error codes:
- *
- * https://developer.mozilla.org/en/Addons/Add-on_Manager/AddonManager#AddonInstall_errors
- */
-exports.ERROR_NETWORK_FAILURE = AddonManager.ERROR_NETWORK_FAILURE;
-exports.ERROR_INCORRECT_HASH = AddonManager.ERROR_INCORRECT_HASH;
-exports.ERROR_CORRUPT_FILE = AddonManager.ERROR_CORRUPT_FILE;
-exports.ERROR_FILE_ACCESS = AddonManager.ERROR_FILE_ACCESS;
-
-/**
- * Immediatly install an addon.
- *
- * @param {String} xpiPath
- * file path to an xpi file to install
- * @return {Promise}
- * A promise resolved when the addon is finally installed.
- * Resolved with addon id as value or rejected with an error code.
- */
-exports.install = function install(xpiPath) {
- let { promise, resolve, reject } = defer();
-
- // Create nsIFile for the xpi file
- let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
- try {
- file.initWithPath(xpiPath);
- }
- catch(e) {
- reject(exports.ERROR_FILE_ACCESS);
- return promise;
- }
-
- // Listen for installation end
- let listener = {
- onInstallEnded: function(aInstall, aAddon) {
- aInstall.removeListener(listener);
- // Bug 749745: on FF14+, onInstallEnded is called just before `startup()`
- // is called, but we expect to resolve the promise only after it.
- // As startup is called synchronously just after onInstallEnded,
- // a simple setTimeout(0) is enough
- setTimeout(resolve, 0, aAddon.id);
- },
- onInstallFailed: function (aInstall) {
- console.log("failed");
- aInstall.removeListener(listener);
- reject(aInstall.error);
- },
- onDownloadFailed: function(aInstall) {
- this.onInstallFailed(aInstall);
- }
- };
-
- // Order AddonManager to install the addon
- AddonManager.getInstallForFile(file, function(install) {
- install.addListener(listener);
- install.install();
- });
-
- return promise;
-};
-
-exports.uninstall = function uninstall(addonId) {
- let { promise, resolve, reject } = defer();
-
- // Listen for uninstallation end
- let listener = {
- onUninstalled: function onUninstalled(aAddon) {
- if (aAddon.id != addonId)
- return;
- AddonManager.removeAddonListener(listener);
- resolve();
- }
- };
- AddonManager.addAddonListener(listener);
-
- // Order Addonmanager to uninstall the addon
- AddonManager.getAddonByID(addonId, function (addon) {
- addon.uninstall();
- });
-
- return promise;
-};
-
-exports.disable = function disable(addonId) {
- let { promise, resolve, reject } = defer();
-
- AddonManager.getAddonByID(addonId, function (addon) {
- addon.userDisabled = true;
- resolve();
- });
-
- return promise;
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/addon/runner.js b/tools/addon-sdk-1.12/lib/sdk/addon/runner.js
deleted file mode 100644
index 0552de2..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/addon/runner.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 expandtab */
-/* 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/.
- */
-
-module.metadata = {
- "stability": "experimental"
-};
-
-const { Cc, Ci } = require('chrome');
-const { descriptor, Sandbox, evaluate, main, resolveURI } = require('toolkit/loader');
-const { once } = require('../system/events');
-const { exit, env, staticArgs, name } = require('../system');
-const { when: unload } = require('../system/unload');
-const { loadReason } = require('../self');
-const { rootURI } = require("@loader/options");
-const globals = require('../system/globals');
-
-const NAME2TOPIC = {
- 'Firefox': 'sessionstore-windows-restored',
- 'Fennec': 'sessionstore-windows-restored',
- 'SeaMonkey': 'sessionstore-windows-restored',
- 'Thunderbird': 'mail-startup-done',
- '*': 'final-ui-startup'
-};
-
-// Gets the topic that fit best as application startup event, in according with
-// the current application (e.g. Firefox, Fennec, Thunderbird...)
-const APP_STARTUP = NAME2TOPIC[name] || NAME2TOPIC['*'];
-
-// Initializes default preferences
-function setDefaultPrefs(prefsURI) {
- const prefs = Cc['@mozilla.org/preferences-service;1'].
- getService(Ci.nsIPrefService).
- QueryInterface(Ci.nsIPrefBranch2);
- const branch = prefs.getDefaultBranch('');
- const sandbox = Sandbox({
- name: prefsURI,
- prototype: {
- pref: function(key, val) {
- switch (typeof val) {
- case 'boolean':
- branch.setBoolPref(key, val);
- break;
- case 'number':
- if (val % 1 == 0) // number must be a integer, otherwise ignore it
- branch.setIntPref(key, val);
- break;
- case 'string':
- branch.setCharPref(key, val);
- break;
- }
- }
- }
- });
- // load preferences.
- evaluate(sandbox, prefsURI);
-}
-
-function definePseudo(loader, id, exports) {
- let uri = resolveURI(id, loader.mapping);
- loader.modules[uri] = { exports: exports };
-}
-
-function wait(reason, options) {
- once(APP_STARTUP, function() {
- startup(null, options);
- });
-}
-
-function startup(reason, options) {
- if (reason === 'startup')
- return wait(reason, options);
-
- // Inject globals ASAP in order to have console API working ASAP
- Object.defineProperties(options.loader.globals, descriptor(globals));
-
- // Load localization manifest and .properties files.
- // Run the addon even in case of error (best effort approach)
- require('../l10n/loader').
- load(rootURI).
- then(null, function failure(error) {
- console.info("Error while loading localization: " + error.message);
- }).
- then(function onLocalizationReady(data) {
- // Exports data to a pseudo module so that api-utils/l10n/core
- // can get access to it
- if (data)
- definePseudo(options.loader, '@l10n/data', data);
- run(options);
- });
-}
-
-function run(options) {
- try {
- // Try initializing HTML localization before running main module. Just print
- // an exception in case of error, instead of preventing addon to be run.
- try {
- // Do not enable HTML localization while running test as it is hard to
- // disable. Because unit tests are evaluated in a another Loader who
- // doesn't have access to this current loader.
- if (options.main !== 'test-harness/run-tests')
- require('../l10n/html').enable();
- }
- catch(error) {
- console.exception(error);
- }
- // Initialize inline options localization, without preventing addon to be
- // run in case of error
- try {
- require('../l10n/prefs');
- }
- catch(error) {
- console.exception(error);
- }
-
- // TODO: When bug 564675 is implemented this will no longer be needed
- // Always set the default prefs, because they disappear on restart
- setDefaultPrefs(options.prefsURI);
-
- // this is where the addon's main.js finally run.
- let program = main(options.loader, options.main);
-
- if (typeof(program.onUnload) === 'function')
- unload(program.onUnload);
-
- if (typeof(program.main) === 'function') {
-
- program.main({
- loadReason: loadReason,
- staticArgs: staticArgs
- }, {
- print: function print(_) { dump(_ + '\n') },
- quit: exit
- });
- }
- } catch (error) {
- console.exception(error);
- throw error;
- }
-}
-exports.startup = startup;
-
-// If add-on is lunched via `cfx run` we need to use `system.exit` to let
-// cfx know we're done (`cfx test` will take care of exit so we don't do
-// anything here).
-if (env.CFX_COMMAND === 'run') {
- unload(function(reason) {
- if (reason === 'shutdown')
- exit(0);
- });
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/base64.js b/tools/addon-sdk-1.12/lib/sdk/base64.js
deleted file mode 100644
index 42fea57..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/base64.js
+++ /dev/null
@@ -1,41 +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 { Cu } = require("chrome");
-
-// If an object is not given as second argument, the JavaScript Module scope is
-// returned, so we can obtain from it the `atob` and `btoa` functions
-const { atob, btoa } = Cu.import("resource://gre/modules/Services.jsm");
-
-function isUTF8(charset) {
- let type = typeof charset;
-
- if (type === "undefined")
- return false;
-
- if (type === "string" && charset.toLowerCase() === "utf-8")
- return true;
-
- throw new Error("The charset argument can be only 'utf-8'");
-}
-
-exports.decode = function (data, charset) {
- if (isUTF8(charset))
- return decodeURIComponent(escape(atob(data)))
-
- return atob(data);
-}
-
-exports.encode = function (data, charset) {
- if (isUTF8(charset))
- return btoa(unescape(encodeURIComponent(data)))
-
- return btoa(data);
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/clipboard.js b/tools/addon-sdk-1.12/lib/sdk/clipboard.js
deleted file mode 100644
index 58a3d7e..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/clipboard.js
+++ /dev/null
@@ -1,333 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "stable"
-};
-
-const { Cc, Ci } = require("chrome");
-const { DataURL } = require("./url");
-const errors = require("./deprecated/errors");
-const apiUtils = require("./deprecated/api-utils");
-/*
-While these data flavors resemble Internet media types, they do
-no directly map to them.
-*/
-const kAllowableFlavors = [
- "text/unicode",
- "text/html",
- "image/png"
- /* CURRENTLY UNSUPPORTED FLAVORS
- "text/plain",
- "image/jpg",
- "image/jpeg",
- "image/gif",
- "text/x-moz-text-internal",
- "AOLMAIL",
- "application/x-moz-file",
- "text/x-moz-url",
- "text/x-moz-url-data",
- "text/x-moz-url-desc",
- "text/x-moz-url-priv",
- "application/x-moz-nativeimage",
- "application/x-moz-nativehtml",
- "application/x-moz-file-promise-url",
- "application/x-moz-file-promise-dest-filename",
- "application/x-moz-file-promise",
- "application/x-moz-file-promise-dir"
- */
-];
-
-/*
-Aliases for common flavors. Not all flavors will
-get an alias. New aliases must be approved by a
-Jetpack API druid.
-*/
-const kFlavorMap = [
- { short: "text", long: "text/unicode" },
- { short: "html", long: "text/html" },
- { short: "image", long: "image/png" }
-];
-
-let clipboardService = Cc["@mozilla.org/widget/clipboard;1"].
- getService(Ci.nsIClipboard);
-
-let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
- getService(Ci.nsIClipboardHelper);
-
-let imageTools = Cc["@mozilla.org/image/tools;1"].
- getService(Ci.imgITools);
-
-exports.set = function(aData, aDataType) {
-
- let options = {
- data: aData,
- datatype: aDataType || "text"
- };
-
- // If `aDataType` is not given or if it's "image", the data is parsed as
- // data URL to detect a better datatype
- if (aData && (!aDataType || aDataType === "image")) {
- try {
- let dataURL = new DataURL(aData);
-
- options.datatype = dataURL.mimeType;
- options.data = dataURL.data;
- }
- catch (e if e.name === "URIError") {
- // Not a valid Data URL
- }
- }
-
- options = apiUtils.validateOptions(options, {
- data: {
- is: ["string"]
- },
- datatype: {
- is: ["string"]
- }
- });
-
- let flavor = fromJetpackFlavor(options.datatype);
-
- if (!flavor)
- throw new Error("Invalid flavor for " + options.datatype);
-
- // Additional checks for using the simple case
- if (flavor == "text/unicode") {
- clipboardHelper.copyString(options.data);
- return true;
- }
-
- // Below are the more complex cases where we actually have to work with a
- // nsITransferable object
- var xferable = Cc["@mozilla.org/widget/transferable;1"].
- createInstance(Ci.nsITransferable);
- if (!xferable)
- throw new Error("Couldn't set the clipboard due to an internal error " +
- "(couldn't create a Transferable object).");
- // Bug 769440: Starting with FF16, transferable have to be inited
- if ("init" in xferable)
- xferable.init(null);
-
- switch (flavor) {
- case "text/html":
- // add text/html flavor
- let (str = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString))
- {
- str.data = options.data;
- xferable.addDataFlavor(flavor);
- xferable.setTransferData(flavor, str, str.data.length * 2);
- }
-
- // add a text/unicode flavor (html converted to plain text)
- let (str = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString),
- converter = Cc["@mozilla.org/feed-textconstruct;1"].
- createInstance(Ci.nsIFeedTextConstruct))
- {
- converter.type = "html";
- converter.text = options.data;
- str.data = converter.plainText();
- xferable.addDataFlavor("text/unicode");
- xferable.setTransferData("text/unicode", str, str.data.length * 2);
- }
- break;
-
- // Set images to the clipboard is not straightforward, to have an idea how
- // it works on platform side, see:
- // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsCopySupport.cpp?rev=7857c5bff017#530
- case "image/png":
- let image = options.data;
-
- let container = {};
-
- try {
- let input = Cc["@mozilla.org/io/string-input-stream;1"].
- createInstance(Ci.nsIStringInputStream);
-
- input.setData(image, image.length);
-
- imageTools.decodeImageData(input, flavor, container);
- }
- catch (e) {
- throw new Error("Unable to decode data given in a valid image.");
- }
-
- // Store directly the input stream makes the cliboard's data available
- // for Firefox but not to the others application or to the OS. Therefore,
- // a `nsISupportsInterfacePointer` object that reference an `imgIContainer`
- // with the image is needed.
- var imgPtr = Cc["@mozilla.org/supports-interface-pointer;1"].
- createInstance(Ci.nsISupportsInterfacePointer);
-
- imgPtr.data = container.value;
-
- xferable.addDataFlavor(flavor);
- xferable.setTransferData(flavor, imgPtr, -1);
-
- break;
- default:
- throw new Error("Unable to handle the flavor " + flavor + ".");
- }
-
- // TODO: Not sure if this will ever actually throw. -zpao
- try {
- clipboardService.setData(
- xferable,
- null,
- clipboardService.kGlobalClipboard
- );
- } catch (e) {
- throw new Error("Couldn't set clipboard data due to an internal error: " + e);
- }
- return true;
-};
-
-
-exports.get = function(aDataType) {
- let options = {
- datatype: aDataType
- };
-
- // Figure out the best data type for the clipboard's data, if omitted
- if (!aDataType) {
- if (~currentFlavors().indexOf("image"))
- options.datatype = "image";
- else
- options.datatype = "text";
- }
-
- options = apiUtils.validateOptions(options, {
- datatype: {
- is: ["string"]
- }
- });
-
- var xferable = Cc["@mozilla.org/widget/transferable;1"].
- createInstance(Ci.nsITransferable);
- if (!xferable)
- throw new Error("Couldn't set the clipboard due to an internal error " +
- "(couldn't create a Transferable object).");
- // Bug 769440: Starting with FF16, transferable have to be inited
- if ("init" in xferable)
- xferable.init(null);
-
- var flavor = fromJetpackFlavor(options.datatype);
-
- // Ensure that the user hasn't requested a flavor that we don't support.
- if (!flavor)
- throw new Error("Getting the clipboard with the flavor '" + flavor +
- "' is not supported.");
-
- // TODO: Check for matching flavor first? Probably not worth it.
-
- xferable.addDataFlavor(flavor);
- // Get the data into our transferable.
- clipboardService.getData(
- xferable,
- clipboardService.kGlobalClipboard
- );
-
- var data = {};
- var dataLen = {};
- try {
- xferable.getTransferData(flavor, data, dataLen);
- } catch (e) {
- // Clipboard doesn't contain data in flavor, return null.
- return null;
- }
-
- // There's no data available, return.
- if (data.value === null)
- return null;
-
- // TODO: Add flavors here as we support more in kAllowableFlavors.
- switch (flavor) {
- case "text/unicode":
- case "text/html":
- data = data.value.QueryInterface(Ci.nsISupportsString).data;
- break;
- case "image/png":
- let dataURL = new DataURL();
-
- dataURL.mimeType = flavor;
- dataURL.base64 = true;
-
- let image = data.value;
-
- // Due to the differences in how images could be stored in the clipboard
- // the checks below are needed. The clipboard could already provide the
- // image as byte streams, but also as pointer, or as image container.
- // If it's not possible obtain a byte stream, the function returns `null`.
- if (image instanceof Ci.nsISupportsInterfacePointer)
- image = image.data;
-
- if (image instanceof Ci.imgIContainer)
- image = imageTools.encodeImage(image, flavor);
-
- if (image instanceof Ci.nsIInputStream) {
- let binaryStream = Cc["@mozilla.org/binaryinputstream;1"].
- createInstance(Ci.nsIBinaryInputStream);
-
- binaryStream.setInputStream(image);
-
- dataURL.data = binaryStream.readBytes(binaryStream.available());
-
- data = dataURL.toString();
- }
- else
- data = null;
-
- break;
- default:
- data = null;
- }
-
- return data;
-};
-
-function currentFlavors() {
- // Loop over kAllowableFlavors, calling hasDataMatchingFlavors for each.
- // This doesn't seem like the most efficient way, but we can't get
- // confirmation for specific flavors any other way. This is supposed to be
- // an inexpensive call, so performance shouldn't be impacted (much).
- var currentFlavors = [];
- for each (var flavor in kAllowableFlavors) {
- var matches = clipboardService.hasDataMatchingFlavors(
- [flavor],
- 1,
- clipboardService.kGlobalClipboard
- );
- if (matches)
- currentFlavors.push(toJetpackFlavor(flavor));
- }
- return currentFlavors;
-};
-
-Object.defineProperty(exports, "currentFlavors", { get : currentFlavors });
-
-// SUPPORT FUNCTIONS ////////////////////////////////////////////////////////
-
-function toJetpackFlavor(aFlavor) {
- for each (let flavorMap in kFlavorMap)
- if (flavorMap.long == aFlavor)
- return flavorMap.short;
- // Return null in the case where we don't match
- return null;
-}
-
-function fromJetpackFlavor(aJetpackFlavor) {
- // TODO: Handle proper flavors better
- for each (let flavorMap in kFlavorMap)
- if (flavorMap.short == aJetpackFlavor || flavorMap.long == aJetpackFlavor)
- return flavorMap.long;
- // Return null in the case where we don't match.
- return null;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/console/plain-text.js b/tools/addon-sdk-1.12/lib/sdk/console/plain-text.js
deleted file mode 100644
index 9e3b748..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/console/plain-text.js
+++ /dev/null
@@ -1,88 +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 {Cc,Ci} = require("chrome");
-const self = require("../self");
-
-function stringify(arg) {
- try {
- return String(arg);
- }
- catch(ex) {
- return "<toString() error>";
- }
-}
-
-function stringifyArgs(args) {
- return Array.map(args, stringify).join(" ");
-}
-
-function message(print, level, args, name) {
- print(level + ": " + name + ": " +
- stringifyArgs(args) + "\n", level);
-}
-
-var Console = exports.PlainTextConsole = function PlainTextConsole(print) {
- if (!print)
- print = dump;
- if (print === dump) {
- // If we're just using dump(), auto-enable preferences so
- // that the developer actually sees the console output.
- var prefs = Cc["@mozilla.org/preferences-service;1"]
- .getService(Ci.nsIPrefBranch);
- prefs.setBoolPref("browser.dom.window.dump.enabled", true);
- }
- this.print = print;
-
- // Binding all the public methods to an instance so that they can be used
- // as callback / listener functions straightaway.
- this.log = this.log.bind(this);
- this.info = this.info.bind(this);
- this.warn = this.warn.bind(this);
- this.error = this.error.bind(this);
- this.debug = this.debug.bind(this);
- this.exception = this.exception.bind(this);
- this.trace = this.trace.bind(this);
-};
-
-Console.prototype = {
- log: function log() {
- message(this.print, "info", arguments, self.name);
- },
-
- info: function info() {
- message(this.print, "info", arguments, self.name);
- },
-
- warn: function warn() {
- message(this.print, "warning", arguments, self.name);
- },
-
- error: function error() {
- message(this.print, "error", arguments, self.name);
- },
-
- debug: function debug() {
- message(this.print, "debug", arguments, self.name);
- },
-
- exception: function exception(e) {
- var fullString = ("An exception occurred.\n" +
- require("./traceback").format(e) + "\n" + e);
- this.error(fullString);
- },
-
- trace: function trace() {
- var traceback = require("./traceback");
- var stack = traceback.get();
- stack.splice(-1, 1);
- message(this.print, "info", [traceback.format(stack)], self.name);
- }
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/console/traceback.js b/tools/addon-sdk-1.12/lib/sdk/console/traceback.js
deleted file mode 100644
index 6b23be1..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/console/traceback.js
+++ /dev/null
@@ -1,118 +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": "experimental"
-};
-
-const { Cc, Ci, components } = require("chrome");
-const { readURISync } = require("../net/url");
-
-// Undo the auto-parentification of URLs done in bug 418356.
-function deParentifyURL(url) {
- return url ? url.split(" -> ").slice(-1)[0] : url;
-}
-
-function safeGetFileLine(path, line) {
- try {
- var scheme = require("../url").URL(path).scheme;
- // TODO: There should be an easier, more accurate way to figure out
- // what's the case here.
- if (!(scheme == "http" || scheme == "https"))
- return readURISync(path).split("\n")[line - 1];
- } catch (e) {}
- return null;
-}
-
-function errorStackToJSON(stack) {
- var lines = stack.split("\n");
-
- var frames = [];
- lines.forEach(
- function(line) {
- if (!line)
- return;
- var atIndex = line.indexOf("@");
- var colonIndex = line.lastIndexOf(":");
- var filename = deParentifyURL(line.slice(atIndex + 1, colonIndex));
- var lineNo = parseInt(line.slice(colonIndex + 1));
- var funcSig = line.slice(0, atIndex);
- var endFuncName = funcSig.indexOf("(");
- // Bug 751149: FF15 changed function signature
- // Instead of: runTest([object Object])
- // We now have: runTest
- var funcName = endFuncName != -1
- ? funcSig.slice(0, endFuncName)
- : funcSig;
- frames.unshift({filename: filename,
- funcName: funcName,
- lineNo: lineNo});
- });
-
- return frames;
-};
-
-function nsIStackFramesToJSON(frame) {
- var stack = [];
-
- while (frame) {
- if (frame.filename) {
- var filename = deParentifyURL(frame.filename);
- stack.splice(0, 0, {filename: filename,
- lineNo: frame.lineNumber,
- funcName: frame.name});
- }
- frame = frame.caller;
- }
-
- return stack;
-};
-
-var fromException = exports.fromException = function fromException(e) {
- if (e instanceof Ci.nsIException)
- return nsIStackFramesToJSON(e.location);
- if (e.stack && e.stack.length)
- return errorStackToJSON(e.stack);
- if (e.fileName && typeof(e.lineNumber == "number"))
- return [{filename: deParentifyURL(e.fileName),
- lineNo: e.lineNumber,
- funcName: null}];
- return [];
-};
-
-var get = exports.get = function get() {
- return nsIStackFramesToJSON(components.stack.caller);
-};
-
-var format = exports.format = function format(tbOrException) {
- if (tbOrException === undefined) {
- tbOrException = get();
- tbOrException.splice(-1, 1);
- }
-
- var tb;
- if (typeof(tbOrException) == "object" &&
- tbOrException.constructor.name == "Array")
- tb = tbOrException;
- else
- tb = fromException(tbOrException);
-
- var lines = ["Traceback (most recent call last):"];
-
- tb.forEach(
- function(frame) {
- if (!(frame.filename || frame.lineNo || frame.funcName))
- return;
-
- lines.push(' File "' + frame.filename + '", line ' +
- frame.lineNo + ', in ' + frame.funcName);
- var sourceLine = safeGetFileLine(frame.filename, frame.lineNo);
- if (sourceLine)
- lines.push(' ' + sourceLine.trim());
- });
-
- return lines.join("\n");
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/content-proxy.js b/tools/addon-sdk-1.12/lib/sdk/content/content-proxy.js
deleted file mode 100644
index 76df7f6..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/content-proxy.js
+++ /dev/null
@@ -1,870 +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";
-
-/* Trick the linker in order to avoid error on `Components.interfaces` usage.
- We are tricking the linker with `require('./content-proxy.js')` from
- worjer.js in order to ensure shipping this file! But then the linker think
- that this file is going to be used as a CommonJS module where we forbid usage
- of `Components`.
-*/
-let Ci = Components['interfaces'];
-
-/**
- * Access key that allows privileged code to unwrap proxy wrappers through
- * valueOf:
- * let xpcWrapper = proxyWrapper.valueOf(UNWRAP_ACCESS_KEY);
- * This key should only be used by proxy unit test.
- */
- const UNWRAP_ACCESS_KEY = {};
-
-
- /**
- * Returns a closure that wraps arguments before calling the given function,
- * which can be given to native functions that accept a function, such that when
- * the closure is called, the given function is called with wrapped arguments.
- *
- * @param fun {Function}
- * the function for which to create a closure wrapping its arguments
- * @param obj {Object}
- * target object from which `fun` comes from
- * (optional, for debugging purpose)
- * @param name {String}
- * name of the attribute from which `fun` is binded on `obj`
- * (optional, for debugging purpose)
- *
- * Example:
- * function contentScriptListener(event) {}
- * let wrapper = ContentScriptFunctionWrapper(contentScriptListener);
- * xray.addEventListener("...", wrapper, false);
- * -> Allow to `event` to be wrapped
- */
-function ContentScriptFunctionWrapper(fun, obj, name) {
- if ("___proxy" in fun && typeof fun.___proxy == "function")
- return fun.___proxy;
-
- let wrappedFun = function () {
- let args = [];
- for (let i = 0, l = arguments.length; i < l; i++)
- args.push(wrap(arguments[i]));
-
- //console.log("Called from native :"+obj+"."+name);
- //console.log(">args "+arguments.length);
- //console.log(fun);
-
- // Native code can execute this callback with `this` being the wrapped
- // function. For example, window.mozRequestAnimationFrame.
- if (this == wrappedFun)
- return fun.apply(fun, args);
-
- return fun.apply(wrap(this), args);
- };
-
- Object.defineProperty(fun, "___proxy", {value : wrappedFun,
- writable : false,
- enumerable : false,
- configurable : false});
-
- return wrappedFun;
-}
-
-/**
- * Returns a closure that unwraps arguments before calling the `fun` function,
- * which can be used to build a wrapper for a native function that accepts
- * wrapped arguments, since native function only accept unwrapped arguments.
- *
- * @param fun {Function}
- * the function to wrap
- * @param originalObject {Object}
- * target object from which `fun` comes from
- * (optional, for debugging purpose)
- * @param name {String}
- * name of the attribute from which `fun` is binded on `originalObject`
- * (optional, for debugging purpose)
- *
- * Example:
- * wrapper.appendChild = NativeFunctionWrapper(xray.appendChild, xray);
- * wrapper.appendChild(anotherWrapper);
- * -> Allow to call xray.appendChild with unwrapped version of anotherWrapper
- */
-function NativeFunctionWrapper(fun, originalObject, name) {
- return function () {
- let args = [];
- let obj = this && typeof this.valueOf == "function" ?
- this.valueOf(UNWRAP_ACCESS_KEY) : this;
-
- for (let i = 0, l = arguments.length; i < l; i++)
- args.push( unwrap(arguments[i], obj, name) );
-
- //if (name != "toString")
- //console.log(">>calling native ["+(name?name:'#closure#')+"]: \n"+fun.apply+"\n"+obj+"\n("+args.join(', ')+")\nthis :"+obj+"from:"+originalObject+"\n");
-
- // Need to use Function.prototype.apply.apply because XMLHttpRequest
- // is a function (typeof return 'function') and fun.apply is null :/
- let unwrapResult = Function.prototype.apply.apply(fun, [obj, args]);
- let result = wrap(unwrapResult, obj, name);
-
- //console.log("<< "+rr+" -> "+r);
-
- return result;
- };
-}
-
-/*
- * Unwrap a JS value that comes from the content script.
- * Mainly converts proxy wrapper to XPCNativeWrapper.
- */
-function unwrap(value, obj, name) {
- //console.log("unwrap : "+value+" ("+name+")");
- if (!value)
- return value;
- let type = typeof value;
-
- // In case of proxy, unwrap them recursively
- // (it should not be recursive, just in case of)
- if (["object", "function"].indexOf(type) !== -1 &&
- "__isWrappedProxy" in value) {
- while("__isWrappedProxy" in value)
- value = value.valueOf(UNWRAP_ACCESS_KEY);
- return value;
- }
-
- // In case of functions we need to return a wrapper that converts native
- // arguments applied to this function into proxies.
- if (type == "function")
- return ContentScriptFunctionWrapper(value, obj, name);
-
- // We must wrap objects coming from content script too, as they may have
- // a function that will be called by a native method.
- // For example:
- // addEventListener(..., { handleEvent: function(event) {} }, ...);
- if (type == "object")
- return ContentScriptObjectWrapper(value);
-
- if (["string", "number", "boolean"].indexOf(type) !== -1)
- return value;
- //console.log("return non-wrapped to native : "+typeof value+" -- "+value);
- return value;
-}
-
-/**
- * Returns an XrayWrapper proxy object that allow to wrap any of its function
- * though `ContentScriptFunctionWrapper`. These proxies are given to
- * XrayWrappers in order to automatically wrap values when they call a method
- * of these proxies. So that they are only used internaly and content script,
- * nor web page have ever access to them. As a conclusion, we can consider
- * this code as being safe regarding web pages overload.
- *
- *
- * @param obj {Object}
- * object coming from content script context to wrap
- *
- * Example:
- * let myListener = { handleEvent: function (event) {} };
- * node.addEventListener("click", myListener, false);
- * `event` has to be wrapped, so handleEvent has to be wrapped using
- * `ContentScriptFunctionWrapper` function.
- * In order to do so, we build this new kind of proxies.
- */
-function ContentScriptObjectWrapper(obj) {
- if ("___proxy" in obj && typeof obj.___proxy == "object")
- return obj.___proxy;
-
- function valueOf(key) {
- if (key === UNWRAP_ACCESS_KEY)
- return obj;
- return this;
- }
-
- let proxy = Proxy.create({
- // Fundamental traps
- getPropertyDescriptor: function(name) {
- return Object.getOwnPropertyDescriptor(obj, name);
- },
- defineProperty: function(name, desc) {
- return Object.defineProperty(obj, name, desc);
- },
- getOwnPropertyNames: function () {
- return Object.getOwnPropertyNames(obj);
- },
- delete: function(name) {
- return delete obj[name];
- },
- // derived traps
- has: function(name) {
- return name === "__isXrayWrapperProxy" ||
- name in obj;
- },
- hasOwn: function(name) {
- return Object.prototype.hasOwnProperty.call(obj, name);
- },
- get: function(receiver, name) {
- if (name == "valueOf")
- return valueOf;
- let value = obj[name];
- if (!value)
- return value;
-
- return unwrap(value);
- },
- set: function(receiver, name, val) {
- obj[name] = val;
- return true;
- },
- enumerate: function() {
- var result = [];
- for each (let name in obj) {
- result.push(name);
- };
- return result;
- },
- keys: function() {
- return Object.keys(obj);
- }
- });
-
- Object.defineProperty(obj, "___proxy", {value : proxy,
- writable : false,
- enumerable : false,
- configurable : false});
-
- return proxy;
-}
-
-// List of all existing typed arrays.
-// Can be found here:
-// http://mxr.mozilla.org/mozilla-central/source/js/src/jsapi.cpp#1790
-const typedArraysCtor = [
- ArrayBuffer,
- Int8Array,
- Uint8Array,
- Int16Array,
- Uint16Array,
- Int32Array,
- Uint32Array,
- Float32Array,
- Float64Array,
- Uint8ClampedArray
-];
-
-/*
- * Wrap a JS value coming from the document by building a proxy wrapper.
- */
-function wrap(value, obj, name, debug) {
- if (!value)
- return value;
- let type = typeof value;
- if (type == "object") {
- // Bug 671016: Typed arrays don't need to be proxified.
- // We avoid checking the whole constructor list on all objects
- // by doing this check only on non-extensible objects:
- if (!Object.isExtensible(value) &&
- typedArraysCtor.indexOf(value.constructor) !== -1)
- return value;
-
- // Bug 715755: do not proxify COW wrappers
- // These wrappers throw an exception when trying to access
- // any attribute that is not in a white list
- try {
- ("nonExistantAttribute" in value);
- }
- catch(e) {
- if (e.message.indexOf("Permission denied to access property") !== -1)
- return value;
- }
-
- // We may have a XrayWrapper proxy.
- // For example:
- // let myListener = { handleEvent: function () {} };
- // node.addEventListener("click", myListener, false);
- // When native code want to call handleEvent,
- // we go though ContentScriptFunctionWrapper that calls `wrap(this)`
- // `this` is the XrayWrapper proxy of myListener.
- // We return this object without building a CS proxy as it is already
- // a value coming from the CS.
- if ("__isXrayWrapperProxy" in value)
- return value.valueOf(UNWRAP_ACCESS_KEY);
-
- // Unwrap object before wrapping it.
- // It should not happen with CS proxy objects.
- while("__isWrappedProxy" in value) {
- value = value.valueOf(UNWRAP_ACCESS_KEY);
- }
-
- if (XPCNativeWrapper.unwrap(value) !== value)
- return getProxyForObject(value);
- // In case of Event, HTMLCollection or NodeList or ???
- // XPCNativeWrapper.unwrap(value) === value
- // but it's still a XrayWrapper so let's build a proxy
- return getProxyForObject(value);
- }
- if (type == "function") {
- if (XPCNativeWrapper.unwrap(value) !== value
- || (typeof value.toString === "function" &&
- value.toString().match(/\[native code\]/))) {
- return getProxyForFunction(value, NativeFunctionWrapper(value, obj, name));
- }
- return value;
- }
- if (type == "string")
- return value;
- if (type == "number")
- return value;
- if (type == "boolean")
- return value;
- //console.log("return non-wrapped to wrapped : "+value);
- return value;
-}
-
-/*
- * Wrap an object from the document to a proxy wrapper
- */
-function getProxyForObject(obj) {
- if (typeof obj != "object") {
- let msg = "tried to proxify something other than an object: " + typeof obj;
- console.warn(msg);
- throw msg;
- }
- if ("__isWrappedProxy" in obj) {
- return obj;
- }
- // Check if there is a proxy cached on this wrapper,
- // but take care of prototype ___proxy attribute inheritance!
- if (obj && obj.___proxy && obj.___proxy.valueOf(UNWRAP_ACCESS_KEY) === obj) {
- return obj.___proxy;
- }
-
- let proxy = Proxy.create(handlerMaker(obj));
-
- Object.defineProperty(obj, "___proxy", {value : proxy,
- writable : false,
- enumerable : false,
- configurable : false});
- return proxy;
-}
-
-/*
- * Wrap a function from the document to a proxy wrapper
- */
-function getProxyForFunction(fun, callTrap) {
- if (typeof fun != "function") {
- let msg = "tried to proxify something other than a function: " + typeof fun;
- console.warn(msg);
- throw msg;
- }
- if ("__isWrappedProxy" in fun)
- return obj;
- if ("___proxy" in fun)
- return fun.___proxy;
-
- let proxy = Proxy.createFunction(handlerMaker(fun), callTrap);
-
- Object.defineProperty(fun, "___proxy", {value : proxy,
- writable : false,
- enumerable : false,
- configurable : false});
-
- return proxy;
-}
-
-/*
- * Check if a DOM attribute name is an event name.
- */
-function isEventName(id) {
- if (id.indexOf("on") != 0 || id.length == 2)
- return false;
- // Taken from:
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#7616
- switch (id[2]) {
- case 'a' :
- return (id == "onabort" ||
- id == "onafterscriptexecute" ||
- id == "onafterprint");
- case 'b' :
- return (id == "onbeforeunload" ||
- id == "onbeforescriptexecute" ||
- id == "onblur" ||
- id == "onbeforeprint");
- case 'c' :
- return (id == "onchange" ||
- id == "onclick" ||
- id == "oncontextmenu" ||
- id == "oncopy" ||
- id == "oncut" ||
- id == "oncanplay" ||
- id == "oncanplaythrough");
- case 'd' :
- return (id == "ondblclick" ||
- id == "ondrag" ||
- id == "ondragend" ||
- id == "ondragenter" ||
- id == "ondragleave" ||
- id == "ondragover" ||
- id == "ondragstart" ||
- id == "ondrop" ||
- id == "ondurationchange");
- case 'e' :
- return (id == "onerror" ||
- id == "onemptied" ||
- id == "onended");
- case 'f' :
- return id == "onfocus";
- case 'h' :
- return id == "onhashchange";
- case 'i' :
- return (id == "oninput" ||
- id == "oninvalid");
- case 'k' :
- return (id == "onkeydown" ||
- id == "onkeypress" ||
- id == "onkeyup");
- case 'l' :
- return (id == "onload" ||
- id == "onloadeddata" ||
- id == "onloadedmetadata" ||
- id == "onloadstart");
- case 'm' :
- return (id == "onmousemove" ||
- id == "onmouseout" ||
- id == "onmouseover" ||
- id == "onmouseup" ||
- id == "onmousedown" ||
- id == "onmessage");
- case 'p' :
- return (id == "onpaint" ||
- id == "onpageshow" ||
- id == "onpagehide" ||
- id == "onpaste" ||
- id == "onpopstate" ||
- id == "onpause" ||
- id == "onplay" ||
- id == "onplaying" ||
- id == "onprogress");
- case 'r' :
- return (id == "onreadystatechange" ||
- id == "onreset" ||
- id == "onresize" ||
- id == "onratechange");
- case 's' :
- return (id == "onscroll" ||
- id == "onselect" ||
- id == "onsubmit" ||
- id == "onseeked" ||
- id == "onseeking" ||
- id == "onstalled" ||
- id == "onsuspend");
- case 't':
- return id == "ontimeupdate"
- /*
- // TODO: Make it work for mobile version
- ||
- (nsDOMTouchEvent::PrefEnabled() &&
- (id == "ontouchstart" ||
- id == "ontouchend" ||
- id == "ontouchmove" ||
- id == "ontouchenter" ||
- id == "ontouchleave" ||
- id == "ontouchcancel"))*/;
-
- case 'u' :
- return id == "onunload";
- case 'v':
- return id == "onvolumechange";
- case 'w':
- return id == "onwaiting";
- }
-
- return false;
-}
-
-// XrayWrappers miss some attributes.
-// Here is a list of functions that return a value when it detects a miss:
-const NODES_INDEXED_BY_NAME = ["IMG", "FORM", "APPLET", "EMBED", "OBJECT"];
-const xRayWrappersMissFixes = [
-
- // Fix bug with XPCNativeWrapper on HTMLCollection
- // We can only access array item once, then it's undefined :o
- function (obj, name) {
- let i = parseInt(name);
- if (obj.toString().match(/HTMLCollection|NodeList/) &&
- i >= 0 && i < obj.length) {
- return wrap(XPCNativeWrapper(obj.wrappedJSObject[name]), obj, name);
- }
- return null;
- },
-
- // Trap access to document["form name"]
- // that may refer to an existing form node
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#9285
- function (obj, name) {
- if ("nodeType" in obj && obj.nodeType == 9) {
- let node = obj.wrappedJSObject[name];
- // List of supported tag:
- // http://mxr.mozilla.org/mozilla-central/source/content/html/content/src/nsGenericHTMLElement.cpp#1267
- if (node && NODES_INDEXED_BY_NAME.indexOf(node.tagName) != -1)
- return wrap(XPCNativeWrapper(node));
- }
- return null;
- },
-
- // Trap access to window["frame name"] and window.frames[i]
- // that refer to an (i)frame internal window object
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#6824
- function (obj, name) {
- if (typeof obj == "object" && "document" in obj) {
- // Ensure that we are on a window object
- try {
- obj.QueryInterface(Ci.nsIDOMWindow);
- }
- catch(e) {
- return null;
- }
-
- // Integer case:
- let i = parseInt(name);
- if (i >= 0 && i in obj) {
- return wrap(XPCNativeWrapper(obj[i]));
- }
-
- // String name case:
- if (name in obj.wrappedJSObject) {
- let win = obj.wrappedJSObject[name];
- let nodes = obj.document.getElementsByName(name);
- for (let i = 0, l = nodes.length; i < l; i++) {
- let node = nodes[i];
- if ("contentWindow" in node && node.contentWindow == win)
- return wrap(node.contentWindow);
- }
- }
- }
- return null;
- },
-
- // Trap access to form["node name"]
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#9477
- function (obj, name) {
- if (typeof obj == "object" && "tagName" in obj && obj.tagName == "FORM") {
- let match = obj.wrappedJSObject[name];
- let nodes = obj.ownerDocument.getElementsByName(name);
- for (let i = 0, l = nodes.length; i < l; i++) {
- let node = nodes[i];
- if (node == match)
- return wrap(node);
- }
- }
- return null;
- }
-
-];
-
-// XrayWrappers have some buggy methods.
-// Here is the list of them with functions returning some replacement
-// for a given object `obj`:
-const xRayWrappersMethodsFixes = {
- // postMessage method is checking the Javascript global
- // and it expects it to be a window object.
- // But in our case, the global object is our sandbox global object.
- // See nsGlobalWindow::CallerInnerWindow():
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsGlobalWindow.cpp#5893
- // nsCOMPtr<nsPIDOMWindow> win = do_QueryWrappedNative(wrapper);
- // win is null
- postMessage: function (obj) {
- // Ensure that we are on a window object
- try {
- obj.QueryInterface(Ci.nsIDOMWindow);
- }
- catch(e) {
- return null;
- }
-
- // Create a wrapper that is going to call `postMessage` through `eval`
- let f = function postMessage(message, targetOrigin) {
- let jscode = "this.postMessage(";
- if (typeof message != "string")
- jscode += JSON.stringify(message);
- else
- jscode += "'" + message.toString().replace(/['\\]/g,"\\$&") + "'";
-
- targetOrigin = targetOrigin.toString().replace(/['\\]/g,"\\$&");
-
- jscode += ", '" + targetOrigin + "')";
- return this.wrappedJSObject.eval(jscode);
- };
- return getProxyForFunction(f, NativeFunctionWrapper(f));
- },
-
- // Fix mozMatchesSelector uses that is broken on XrayWrappers
- // when we use document.documentElement.mozMatchesSelector.call(node, expr)
- // It's only working if we call mozMatchesSelector on the node itself.
- // SEE BUG 658909: mozMatchesSelector returns incorrect results with XrayWrappers
- mozMatchesSelector: function (obj) {
- // Ensure that we are on an object to expose this buggy method
- try {
- // Bug 707576 removed nsIDOMNSElement.
- // Can be simplified as soon as Firefox 11 become the minversion
- obj.QueryInterface("nsIDOMElement" in Ci ? Ci.nsIDOMElement :
- Ci.nsIDOMNSElement);
- }
- catch(e) {
- return null;
- }
- // We can't use `wrap` function as `f` is not a native function,
- // so wrap it manually:
- let f = function mozMatchesSelector(selectors) {
- return this.mozMatchesSelector(selectors);
- };
-
- return getProxyForFunction(f, NativeFunctionWrapper(f));
- },
-
- // Bug 679054: History API doesn't work with Proxy objects. We have to pass
- // regular JS objects on `pushState` and `replaceState` methods.
- // In addition, the first argument has to come from the same compartment.
- pushState: function (obj) {
- // Ensure that we are on an object that expose History API
- try {
- obj.QueryInterface(Ci.nsIDOMHistory);
- }
- catch(e) {
- return null;
- }
- let f = function fix() {
- // Call native method with JSON objects
- // (need to convert `arguments` to an array via `slice`)
- return this.pushState.apply(this, JSON.parse(JSON.stringify(Array.slice(arguments))));
- };
-
- return getProxyForFunction(f, NativeFunctionWrapper(f));
- },
- replaceState: function (obj) {
- // Ensure that we are on an object that expose History API
- try {
- obj.QueryInterface(Ci.nsIDOMHistory);
- }
- catch(e) {
- return null;
- }
- let f = function fix() {
- // Call native method with JSON objects
- // (need to convert `arguments` to an array via `slice`)
- return this.replaceState.apply(this, JSON.parse(JSON.stringify(Array.slice(arguments))));
- };
-
- return getProxyForFunction(f, NativeFunctionWrapper(f));
- },
-
- // Bug 769006: nsIDOMMutationObserver.observe fails with proxy as options
- // attributes
- observe: function observe(obj) {
- // Ensure that we are on a DOMMutation object
- try {
- // nsIDOMMutationObserver starts with FF14
- if ("nsIDOMMutationObserver" in Ci)
- obj.QueryInterface(Ci.nsIDOMMutationObserver);
- else
- return null;
- }
- catch(e) {
- return null;
- }
- return function nsIDOMMutationObserverObserveFix(target, options) {
- // Gets native/unwrapped this
- let self = this && typeof this.valueOf == "function" ?
- this.valueOf(UNWRAP_ACCESS_KEY) : this;
- // Unwrap the xraywrapper target out of JS proxy
- let targetXray = unwrap(target);
- // But do not wrap `options` through ContentScriptObjectWrapper
- let result = wrap(self.observe(targetXray, options));
- // Finally wrap result into JS proxies
- return wrap(result);
- };
- }
-};
-
-/*
- * Generate handler for proxy wrapper
- */
-function handlerMaker(obj) {
- // Overloaded attributes dictionary
- let overload = {};
- // Expando attributes dictionary (i.e. onclick, onfocus, on* ...)
- let expando = {};
- // Cache of methods overloaded to fix XrayWrapper bug
- let methodFixes = {};
- return {
- // Fundamental traps
- getPropertyDescriptor: function(name) {
- return Object.getOwnPropertyDescriptor(obj, name);
- },
- defineProperty: function(name, desc) {
- return Object.defineProperty(obj, name, desc);
- },
- getOwnPropertyNames: function () {
- return Object.getOwnPropertyNames(obj);
- },
- delete: function(name) {
- delete expando[name];
- delete overload[name];
- return delete obj[name];
- },
-
- // derived traps
- has: function(name) {
- if (name == "___proxy") return false;
- if (isEventName(name)) {
- // XrayWrappers throw exception when we try to access expando attributes
- // even on "name in wrapper". So avoid doing it!
- return name in expando;
- }
- return name in obj || name in overload || name == "__isWrappedProxy" ||
- undefined !== this.get(null, name);
- },
- hasOwn: function(name) {
- return Object.prototype.hasOwnProperty.call(obj, name);
- },
- get: function(receiver, name) {
- if (name == "___proxy")
- return undefined;
-
- // Overload toString in order to avoid returning "[XrayWrapper [object HTMLElement]]"
- // or "[object Function]" for function's Proxy
- if (name == "toString") {
- // Bug 714778: we should not pass obj.wrappedJSObject.toString
- // in order to avoid sharing its proxy between two contents scripts.
- // (not that `unwrappedObj` can be equal to `obj` when `obj` isn't
- // an xraywrapper)
- let unwrappedObj = XPCNativeWrapper.unwrap(obj);
- return wrap(function () {
- return unwrappedObj.toString.call(
- this.valueOf(UNWRAP_ACCESS_KEY), arguments);
- }, obj, name);
- }
-
- // Offer a way to retrieve XrayWrapper from a proxified node through `valueOf`
- if (name == "valueOf")
- return function (key) {
- if (key === UNWRAP_ACCESS_KEY)
- return obj;
- return this;
- };
-
- // Return overloaded value if there is one.
- // It allows to overload native methods like addEventListener that
- // are not saved, even on the wrapper itself.
- // (And avoid some methods like toSource from being returned here! [__proto__ test])
- if (name in overload &&
- overload[name] != Object.getPrototypeOf(overload)[name] &&
- name != "__proto__") {
- return overload[name];
- }
-
- // Catch exceptions thrown by XrayWrappers when we try to access on*
- // attributes like onclick, onfocus, ...
- if (isEventName(name)) {
- //console.log("expando:"+obj+" - "+obj.nodeType);
- return name in expando ? expando[name].original : undefined;
- }
-
- // Overload some XrayWrappers method in order to fix its bugs
- if (name in methodFixes &&
- methodFixes[name] != Object.getPrototypeOf(methodFixes)[name] &&
- name != "__proto__")
- return methodFixes[name];
- if (Object.keys(xRayWrappersMethodsFixes).indexOf(name) !== -1) {
- let fix = xRayWrappersMethodsFixes[name](obj);
- if (fix)
- return methodFixes[name] = fix;
- }
-
- let o = obj[name];
-
- // XrayWrapper miss some attributes, try to catch these and return a value
- if (!o) {
- for each(let atttributeFixer in xRayWrappersMissFixes) {
- let fix = atttributeFixer(obj, name);
- if (fix)
- return fix;
- }
- }
-
- // Generic case
- return wrap(o, obj, name);
-
- },
-
- set: function(receiver, name, val) {
-
- if (isEventName(name)) {
- //console.log("SET on* attribute : " + name + " / " + val + "/" + obj);
- let shortName = name.replace(/^on/,"");
-
- // Unregister previously set listener
- if (expando[name]) {
- obj.removeEventListener(shortName, expando[name], true);
- delete expando[name];
- }
-
- // Only accept functions
- if (typeof val != "function")
- return false;
-
- // Register a new listener
- let original = val;
- val = ContentScriptFunctionWrapper(val);
- expando[name] = val;
- val.original = original;
- obj.addEventListener(name.replace(/^on/, ""), val, true);
- return true;
- }
-
- obj[name] = val;
-
- // Handle native method not overloaded on XrayWrappers:
- // obj.addEventListener = val; -> obj.addEventlistener = native method
- // And, XPCNativeWrapper bug where nested values appear to be wrapped:
- // obj.customNestedAttribute = val -> obj.customNestedAttribute !== val
- // obj.customNestedAttribute = "waive wrapper something"
- // SEE BUG 658560: Fix identity problem with CrossOriginWrappers
- // TODO: check that DOM can't be updated by the document itself and so overloaded value becomes wrong
- // but I think such behavior is limited to primitive type
- if ((typeof val == "function" || typeof val == "object") && name) {
- overload[name] = val;
- }
-
- return true;
- },
-
- enumerate: function() {
- var result = [];
- for each (let name in Object.keys(obj)) {
- result.push(name);
- };
- return result;
- },
-
- keys: function() {
- return Object.keys(obj);
- }
- };
-};
-
-
-/*
- * Wrap an object from the document to a proxy wrapper.
- */
-function create(object) {
- if ("wrappedJSObject" in object)
- object = object.wrappedJSObject;
- let xpcWrapper = XPCNativeWrapper(object);
- // If we can't build an XPCNativeWrapper, it doesn't make sense to build
- // a proxy. All proxy code is based on having such wrapper that store
- // different JS attributes set.
- // (we can't build XPCNativeWrapper when object is from the same
- // principal/domain)
- if (object === xpcWrapper) {
- return object;
- }
- return getProxyForObject(xpcWrapper);
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/content-worker.js b/tools/addon-sdk-1.12/lib/sdk/content/content-worker.js
deleted file mode 100644
index 8cf9c5c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/content-worker.js
+++ /dev/null
@@ -1,308 +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/. */
-
-const ContentWorker = Object.freeze({
- // TODO: Bug 727854 Use same implementation than common JS modules,
- // i.e. EventEmitter module
-
- /**
- * Create an EventEmitter instance.
- */
- createEventEmitter: function createEventEmitter(emit) {
- let listeners = Object.create(null);
- let eventEmitter = Object.freeze({
- emit: emit,
- on: function on(name, callback) {
- if (typeof callback !== "function")
- return this;
- if (!(name in listeners))
- listeners[name] = [];
- listeners[name].push(callback);
- return this;
- },
- once: function once(name, callback) {
- eventEmitter.on(name, function onceCallback() {
- eventEmitter.removeListener(name, onceCallback);
- callback.apply(callback, arguments);
- });
- },
- removeListener: function removeListener(name, callback) {
- if (!(name in listeners))
- return;
- let index = listeners[name].indexOf(callback);
- if (index == -1)
- return;
- listeners[name].splice(index, 1);
- }
- });
- function onEvent(name) {
- if (!(name in listeners))
- return [];
- let args = Array.slice(arguments, 1);
- let results = [];
- for each (let callback in listeners[name]) {
- results.push(callback.apply(null, args));
- }
- return results;
- }
- function hasListenerFor(name) {
- if (!(name in listeners))
- return false;
- return listeners[name].length > 0;
- }
- return {
- eventEmitter: eventEmitter,
- emit: onEvent,
- hasListenerFor: hasListenerFor
- };
- },
-
- /**
- * Create an EventEmitter instance to communicate with chrome module
- * by passing only strings between compartments.
- * This function expects `emitToChrome` function, that allows to send
- * events to the chrome module. It returns the EventEmitter as `pipe`
- * attribute, and, `onChromeEvent` a function that allows chrome module
- * to send event into the EventEmitter.
- *
- * pipe.emit --> emitToChrome
- * onChromeEvent --> callback registered through pipe.on
- */
- createPipe: function createPipe(emitToChrome) {
- function onEvent() {
- // Convert to real array
- let args = Array.slice(arguments);
- // JSON.stringify is buggy with cross-sandbox values,
- // it may return "{}" on functions. Use a replacer to match them correctly.
- function replacer(k, v) {
- return typeof v === "function" ? undefined : v;
- }
- let str = JSON.stringify(args, replacer);
- emitToChrome(str);
- }
-
- let { eventEmitter, emit, hasListenerFor } =
- ContentWorker.createEventEmitter(onEvent);
-
- return {
- pipe: eventEmitter,
- onChromeEvent: function onChromeEvent(array) {
- // We either receive a stringified array, or a real array.
- // We still allow to pass an array of objects, in WorkerSandbox.emitSync
- // in order to allow sending DOM node reference between content script
- // and modules (only used for context-menu API)
- let args = typeof array == "string" ? JSON.parse(array) : array;
- return emit.apply(null, args);
- },
- hasListenerFor: hasListenerFor
- };
- },
-
- injectConsole: function injectConsole(exports, pipe) {
- exports.console = Object.freeze({
- log: pipe.emit.bind(null, "console", "log"),
- info: pipe.emit.bind(null, "console", "info"),
- warn: pipe.emit.bind(null, "console", "warn"),
- error: pipe.emit.bind(null, "console", "error"),
- debug: pipe.emit.bind(null, "console", "debug"),
- exception: pipe.emit.bind(null, "console", "exception"),
- trace: pipe.emit.bind(null, "console", "trace")
- });
- },
-
- injectTimers: function injectTimers(exports, chromeAPI, pipe, console) {
- // wrapped functions from `'timer'` module.
- // Wrapper adds `try catch` blocks to the callbacks in order to
- // emit `error` event on a symbiont if exception is thrown in
- // the Worker global scope.
- // @see http://www.w3.org/TR/workers/#workerutils
-
- // List of all living timeouts/intervals
- let _timers = Object.create(null);
-
- // Keep a reference to original timeout functions
- let {
- setTimeout: chromeSetTimeout,
- setInterval: chromeSetInterval,
- clearTimeout: chromeClearTimeout,
- clearInterval: chromeClearInterval
- } = chromeAPI.timers;
-
- function registerTimer(timer) {
- let registerMethod = null;
- if (timer.kind == "timeout")
- registerMethod = chromeSetTimeout;
- else if (timer.kind == "interval")
- registerMethod = chromeSetInterval;
- else
- throw new Error("Unknown timer kind: " + timer.kind);
- let id = registerMethod(onFire, timer.delay);
- function onFire() {
- try {
- if (timer.kind == "timeout")
- delete _timers[id];
- timer.fun.apply(null, timer.args);
- } catch(e) {
- console.exception(e);
- }
- }
- _timers[id] = timer;
- return id;
- }
-
- function unregisterTimer(id) {
- if (!(id in _timers))
- return;
- let { kind } = _timers[id];
- delete _timers[id];
- if (kind == "timeout")
- chromeClearTimeout(id);
- else if (kind == "interval")
- chromeClearInterval(id);
- else
- throw new Error("Unknown timer kind: " + kind);
- }
-
- function disableAllTimers() {
- Object.keys(_timers).forEach(unregisterTimer);
- }
-
- exports.setTimeout = function ContentScriptSetTimeout(callback, delay) {
- return registerTimer({
- kind: "timeout",
- fun: callback,
- delay: delay,
- args: Array.slice(arguments, 2)
- });
- };
- exports.clearTimeout = function ContentScriptClearTimeout(id) {
- unregisterTimer(id);
- };
-
- exports.setInterval = function ContentScriptSetInterval(callback, delay) {
- return registerTimer({
- kind: "interval",
- fun: callback,
- delay: delay,
- args: Array.slice(arguments, 2)
- });
- };
- exports.clearInterval = function ContentScriptClearInterval(id) {
- unregisterTimer(id);
- };
-
- // On page-hide, save a list of all existing timers before disabling them,
- // in order to be able to restore them on page-show.
- // These events are fired when the page goes in/out of bfcache.
- // https://developer.mozilla.org/En/Working_with_BFCache
- let frozenTimers = [];
- pipe.on("pageshow", function onPageShow() {
- frozenTimers.forEach(registerTimer);
- });
- pipe.on("pagehide", function onPageHide() {
- frozenTimers = [];
- for (let id in _timers)
- frozenTimers.push(_timers[id]);
- disableAllTimers();
- // Some other pagehide listeners may register some timers that won't be
- // frozen as this particular pagehide listener is called first.
- // So freeze these timers on next cycle.
- chromeSetTimeout(function () {
- for (let id in _timers)
- frozenTimers.push(_timers[id]);
- disableAllTimers();
- }, 0);
- });
-
- // Unregister all timers when the page is destroyed
- // (i.e. when it is removed from bfcache)
- pipe.on("detach", function clearTimeouts() {
- disableAllTimers();
- _timers = {};
- frozenTimers = [];
- });
- },
-
- injectMessageAPI: function injectMessageAPI(exports, pipe) {
-
- let { eventEmitter: port, emit : portEmit } =
- ContentWorker.createEventEmitter(pipe.emit.bind(null, "event"));
- pipe.on("event", portEmit);
-
- let self = {
- port: port,
- postMessage: pipe.emit.bind(null, "message"),
- on: pipe.on.bind(null),
- once: pipe.once.bind(null),
- removeListener: pipe.removeListener.bind(null),
- };
- Object.defineProperty(exports, "self", {
- value: self
- });
-
- // Deprecated use of on/postMessage from globals
- exports.postMessage = function deprecatedPostMessage() {
- console.error("DEPRECATED: The global `postMessage()` function in " +
- "content scripts is deprecated in favor of the " +
- "`self.postMessage()` function, which works the same. " +
- "Replace calls to `postMessage()` with calls to " +
- "`self.postMessage()`." +
- "For more info on `self.on`, see " +
- "<https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/addon-development/web-content.html>.");
- return self.postMessage.apply(null, arguments);
- };
- exports.on = function deprecatedOn() {
- console.error("DEPRECATED: The global `on()` function in content " +
- "scripts is deprecated in favor of the `self.on()` " +
- "function, which works the same. Replace calls to `on()` " +
- "with calls to `self.on()`" +
- "For more info on `self.on`, see " +
- "<https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/addon-development/web-content.html>.");
- return self.on.apply(null, arguments);
- };
-
- // Deprecated use of `onMessage` from globals
- let onMessage = null;
- Object.defineProperty(exports, "onMessage", {
- get: function () onMessage,
- set: function (v) {
- if (onMessage)
- self.removeListener("message", onMessage);
- console.error("DEPRECATED: The global `onMessage` function in content" +
- "scripts is deprecated in favor of the `self.on()` " +
- "function. Replace `onMessage = function (data){}` " +
- "definitions with calls to `self.on('message', " +
- "function (data){})`. " +
- "For more info on `self.on`, see " +
- "<https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/addon-development/web-content.html>.");
- onMessage = v;
- if (typeof onMessage == "function")
- self.on("message", onMessage);
- }
- });
- },
-
- injectOptions: function (exports, options) {
- Object.defineProperty( exports.self, "options", { value: JSON.parse( options ) });
- },
-
- inject: function (exports, chromeAPI, emitToChrome, options) {
- let { pipe, onChromeEvent, hasListenerFor } =
- ContentWorker.createPipe(emitToChrome);
-
- ContentWorker.injectConsole(exports, pipe);
- ContentWorker.injectTimers(exports, chromeAPI, pipe, exports.console);
- ContentWorker.injectMessageAPI(exports, pipe);
- if ( options !== undefined ) {
- ContentWorker.injectOptions(exports, options);
- }
-
- Object.freeze( exports.self );
-
- return {
- emitToContent: onChromeEvent,
- hasListenerFor: hasListenerFor
- };
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/content.js b/tools/addon-sdk-1.12/lib/sdk/content/content.js
deleted file mode 100644
index 4bffd45..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/content.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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"
-};
-
-exports.Loader = require('./loader').Loader;
-exports.Symbiont = require('./symbiont').Symbiont;
-exports.Worker = require('./worker').Worker;
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/loader.js b/tools/addon-sdk-1.12/lib/sdk/content/loader.js
deleted file mode 100644
index b01675c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/loader.js
+++ /dev/null
@@ -1,204 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { EventEmitter } = require('../deprecated/events');
-const { validateOptions } = require('../deprecated/api-utils');
-const { URL } = require('../url');
-const file = require('../io/file');
-
-const LOCAL_URI_SCHEMES = ['resource', 'data'];
-
-// Returns `null` if `value` is `null` or `undefined`, otherwise `value`.
-function ensureNull(value) {
- return value == null ? null : value;
-}
-
-// map of property validations
-const valid = {
- contentURL: {
- ok: function (value) {
- try {
- URL(value);
- }
- catch(e) {
- return false;
- }
- return true;
- },
- msg: 'The `contentURL` option must be a valid URL.'
- },
- contentScriptFile: {
- is: ['undefined', 'null', 'string', 'array'],
- map: ensureNull,
- ok: function(value) {
- if (value === null)
- return true;
-
- value = [].concat(value);
-
- // Make sure every item is a local file URL.
- return value.every(function (item) {
- try {
- return ~LOCAL_URI_SCHEMES.indexOf(URL(item).scheme);
- }
- catch(e) {
- return false;
- }
- });
-
- },
- msg: 'The `contentScriptFile` option must be a local URL or an array of URLs.'
- },
- contentScript: {
- is: ['undefined', 'null', 'string', 'array'],
- map: ensureNull,
- ok: function(value) {
- return !Array.isArray(value) || value.every(
- function(item) { return typeof item === 'string' }
- );
- },
- msg: 'The `contentScript` option must be a string or an array of strings.'
- },
- contentScriptWhen: {
- is: ['string'],
- ok: function(value) { return ~['start', 'ready', 'end'].indexOf(value) },
- map: function(value) {
- return value || 'end';
- },
- msg: 'The `contentScriptWhen` option must be either "start", "ready" or "end".'
- },
- contentScriptOptions: {
- ok: function(value) {
- if ( value === undefined ) { return true; }
- try { JSON.parse( JSON.stringify( value ) ); } catch(e) { return false; }
- return true;
- },
- map: function(value) 'undefined' === getTypeOf(value) ? null : value,
- msg: 'The contentScriptOptions should be a jsonable value.'
- }
-};
-exports.validationAttributes = valid;
-
-/**
- * Shortcut function to validate property with validation.
- * @param {Object|Number|String} suspect
- * value to validate
- * @param {Object} validation
- * validation rule passed to `api-utils`
- */
-function validate(suspect, validation) validateOptions(
- { $: suspect },
- { $: validation }
-).$
-
-function Allow(script) ({
- get script() script,
- set script(value) script = !!value
-})
-
-/**
- * Trait is intended to be used in some composition. It provides set of core
- * properties and bounded validations to them. Trait is useful for all the
- * compositions providing high level APIs for interaction with content.
- * Property changes emit `"propertyChange"` events on instances.
- */
-const Loader = EventEmitter.compose({
- /**
- * Permissions for the content, with the following keys:
- * @property {Object} [allow = { script: true }]
- * @property {Boolean} [allow.script = true]
- * Whether or not to execute script in the content. Defaults to true.
- */
- get allow() this._allow || (this._allow = Allow(true)),
- set allow(value) this.allow.script = value && value.script,
- _allow: null,
- /**
- * The content to load. Either a string of HTML or a URL.
- * @type {String}
- */
- get contentURL() this._contentURL,
- set contentURL(value) {
- value = validate(value, valid.contentURL);
- if (this._contentURL != value) {
- this._emit('propertyChange', {
- contentURL: this._contentURL = value
- });
- }
- },
- _contentURL: null,
- /**
- * When to load the content scripts.
- * Possible values are "end" (default), which loads them once all page
- * contents have been loaded, "ready", which loads them once DOM nodes are
- * ready (ie like DOMContentLoaded event), and "start", which loads them once
- * the `window` object for the page has been created, but before any scripts
- * specified by the page have been loaded.
- * Property change emits `propertyChange` event on instance with this key
- * and new value.
- * @type {'start'|'ready'|'end'}
- */
- get contentScriptWhen() this._contentScriptWhen,
- set contentScriptWhen(value) {
- value = validate(value, valid.contentScriptWhen);
- if (value !== this._contentScriptWhen) {
- this._emit('propertyChange', {
- contentScriptWhen: this._contentScriptWhen = value
- });
- }
- },
- _contentScriptWhen: 'end',
- /**
- * Options avalaible from the content script as `self.options`.
- * The value of options can be of any type (object, array, string, etc.)
- * but only jsonable values will be available as frozen objects from the
- * content script.
- * Property change emits `propertyChange` event on instance with this key
- * and new value.
- * @type {Object}
- */
- get contentScriptOptions() this._contentScriptOptions,
- set contentScriptOptions(value) this._contentScriptOptions = value,
- _contentScriptOptions: null,
- /**
- * The URLs of content scripts.
- * Property change emits `propertyChange` event on instance with this key
- * and new value.
- * @type {String[]}
- */
- get contentScriptFile() this._contentScriptFile,
- set contentScriptFile(value) {
- value = validate(value, valid.contentScriptFile);
- if (value != this._contentScriptFile) {
- this._emit('propertyChange', {
- contentScriptFile: this._contentScriptFile = value
- });
- }
- },
- _contentScriptFile: null,
- /**
- * The texts of content script.
- * Property change emits `propertyChange` event on instance with this key
- * and new value.
- * @type {String|undefined}
- */
- get contentScript() this._contentScript,
- set contentScript(value) {
- value = validate(value, valid.contentScript);
- if (value != this._contentScript) {
- this._emit('propertyChange', {
- contentScript: this._contentScript = value
- });
- }
- },
- _contentScript: null
-});
-exports.Loader = Loader;
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/symbiont.js b/tools/addon-sdk-1.12/lib/sdk/content/symbiont.js
deleted file mode 100644
index 186e9d3..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/symbiont.js
+++ /dev/null
@@ -1,197 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { Worker } = require('./worker');
-const { Loader } = require('./loader');
-const hiddenFrames = require('../frame/hidden-frame');
-const observers = require('../deprecated/observer-service');
-const unload = require('../system/unload');
-
-const assetsURI = require('../self').data.url();
-
-/**
- * This trait is layered on top of `Worker` and in contrast to symbiont
- * Worker constructor requires `content` option that represents content
- * that will be loaded in the provided frame, if frame is not provided
- * Worker will create hidden one.
- */
-const Symbiont = Worker.resolve({
- constructor: '_initWorker',
- destroy: '_workerDestroy'
- }).compose(Loader, {
-
- /**
- * The constructor requires all the options that are required by
- * `require('content').Worker` with the difference that the `frame` option
- * is optional. If `frame` is not provided, `contentURL` is expected.
- * @param {Object} options
- * @param {String} options.contentURL
- * URL of a content to load into `this._frame` and create worker for.
- * @param {Element} [options.frame]
- * iframe element that is used to load `options.contentURL` into.
- * if frame is not provided hidden iframe will be created.
- */
- constructor: function Symbiont(options) {
- options = options || {};
-
- if ('contentURL' in options)
- this.contentURL = options.contentURL;
- if ('contentScriptWhen' in options)
- this.contentScriptWhen = options.contentScriptWhen;
- if ('contentScriptOptions' in options)
- this.contentScriptOptions = options.contentScriptOptions;
- if ('contentScriptFile' in options)
- this.contentScriptFile = options.contentScriptFile;
- if ('contentScript' in options)
- this.contentScript = options.contentScript;
- if ('allow' in options)
- this.allow = options.allow;
- if ('onError' in options)
- this.on('error', options.onError);
- if ('onMessage' in options)
- this.on('message', options.onMessage);
- if ('frame' in options) {
- this._initFrame(options.frame);
- }
- else {
- let self = this;
- this._hiddenFrame = hiddenFrames.HiddenFrame({
- onReady: function onFrame() {
- self._initFrame(this.element);
- },
- onUnload: function onUnload() {
- // Bug 751211: Remove reference to _frame when hidden frame is
- // automatically removed on unload, otherwise we are going to face
- // "dead object" exception
- self.destroy();
- }
- });
- hiddenFrames.add(this._hiddenFrame);
- }
-
- unload.ensure(this._public, "destroy");
- },
-
- destroy: function destroy() {
- this._workerDestroy();
- this._unregisterListener();
- this._frame = null;
- if (this._hiddenFrame) {
- hiddenFrames.remove(this._hiddenFrame);
- this._hiddenFrame = null;
- }
- },
-
- /**
- * XUL iframe or browser elements with attribute `type` being `content`.
- * Used to create `ContentSymbiont` from.
- * @type {nsIFrame|nsIBrowser}
- */
- _frame: null,
-
- /**
- * Listener to the `'frameReady"` event (emitted when `iframe` is ready).
- * Removes listener, sets right permissions to the frame and loads content.
- */
- _initFrame: function _initFrame(frame) {
- if (this._loadListener)
- this._unregisterListener();
-
- this._frame = frame;
- frame.docShell.allowJavascript = this.allow.script;
- frame.setAttribute("src", this._contentURL);
-
- // Inject `addon` object in document if we load a document from
- // one of our addon folder and if no content script are defined. bug 612726
- let isDataResource =
- typeof this._contentURL == "string" &&
- this._contentURL.indexOf(assetsURI) == 0;
- let hasContentScript =
- (Array.isArray(this.contentScript) ? this.contentScript.length > 0
- : !!this.contentScript) ||
- (Array.isArray(this.contentScriptFile) ? this.contentScriptFile.length > 0
- : !!this.contentScriptFile);
- // If we have to inject `addon` we have to do it before document
- // script execution, so during `start`:
- this._injectInDocument = isDataResource && !hasContentScript;
- if (this._injectInDocument)
- this.contentScriptWhen = "start";
-
- if ((frame.contentDocument.readyState == "complete" ||
- (frame.contentDocument.readyState == "interactive" &&
- this.contentScriptWhen != 'end' )) &&
- frame.contentDocument.location == this._contentURL) {
- // In some cases src doesn't change and document is already ready
- // (for ex: when the user moves a widget while customizing toolbars.)
- this._onInit();
- return;
- }
-
- let self = this;
-
- if ('start' == this.contentScriptWhen) {
- this._loadEvent = 'start';
- observers.add('document-element-inserted',
- this._loadListener = function onStart(doc) {
-
- let window = doc.defaultView;
- if (window && window == frame.contentWindow) {
- self._unregisterListener();
- self._onInit();
- }
-
- });
- return;
- }
-
- let eventName = 'end' == this.contentScriptWhen ? 'load' : 'DOMContentLoaded';
- let self = this;
- this._loadEvent = eventName;
- frame.addEventListener(eventName,
- this._loadListener = function _onReady(event) {
-
- if (event.target != frame.contentDocument)
- return;
- self._unregisterListener();
-
- self._onInit();
-
- }, true);
-
- },
-
- /**
- * Unregister listener that watchs for document being ready to be injected.
- * This listener is registered in `Symbiont._initFrame`.
- */
- _unregisterListener: function _unregisterListener() {
- if (!this._loadListener)
- return;
- if (this._loadEvent == "start") {
- observers.remove('document-element-inserted', this._loadListener);
- }
- else {
- this._frame.removeEventListener(this._loadEvent, this._loadListener,
- true);
- }
- this._loadListener = null;
- },
-
- /**
- * Called by Symbiont itself when the frame is ready to load
- * content scripts according to contentScriptWhen. Overloaded by Panel.
- */
- _onInit: function () {
- this._initWorker({ window: this._frame.contentWindow });
- }
-
-});
-exports.Symbiont = Symbiont;
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/thumbnail.js b/tools/addon-sdk-1.12/lib/sdk/content/thumbnail.js
deleted file mode 100644
index 9e57274..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/thumbnail.js
+++ /dev/null
@@ -1,46 +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 { Cc, Ci, Cu } = require('chrome');
-const AppShellService = Cc['@mozilla.org/appshell/appShellService;1'].
- getService(Ci.nsIAppShellService);
-
-const NS = 'http://www.w3.org/1999/xhtml';
-const COLOR = 'rgb(255,255,255)';
-
-/**
- * Creates canvas element with a thumbnail of the passed window.
- * @param {Window} window
- * @returns {Element}
- */
-function getThumbnailCanvasForWindow(window) {
- let aspectRatio = 0.5625; // 16:9
- let thumbnail = AppShellService.hiddenDOMWindow.document
- .createElementNS(NS, 'canvas');
- thumbnail.mozOpaque = true;
- thumbnail.width = Math.ceil(window.screen.availWidth / 5.75);
- thumbnail.height = Math.round(thumbnail.width * aspectRatio);
- let ctx = thumbnail.getContext('2d');
- let snippetWidth = window.innerWidth * .6;
- let scale = thumbnail.width / snippetWidth;
- ctx.scale(scale, scale);
- ctx.drawWindow(window, window.scrollX, window.scrollY, snippetWidth,
- snippetWidth * aspectRatio, COLOR);
- return thumbnail;
-}
-exports.getThumbnailCanvasForWindow = getThumbnailCanvasForWindow;
-
-/**
- * Creates Base64 encoded data URI of the thumbnail for the passed window.
- * @param {Window} window
- * @returns {String}
- */
-exports.getThumbnailURIForWindow = function getThumbnailURIForWindow(window) {
- return getThumbnailCanvasForWindow(window).toDataURL()
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/worker.js b/tools/addon-sdk-1.12/lib/sdk/content/worker.js
deleted file mode 100644
index b2f204c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/worker.js
+++ /dev/null
@@ -1,582 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { Trait } = require('../deprecated/traits');
-const { EventEmitter, EventEmitterTrait } = require('../deprecated/events');
-const { Ci, Cu, Cc } = require('chrome');
-const timer = require('../timers');
-const { URL } = require('../url');
-const unload = require('../system/unload');
-const observers = require('../deprecated/observer-service');
-const { Cortex } = require('../deprecated/cortex');
-const { sandbox, evaluate, load } = require("../loader/sandbox");
-const { merge } = require('../util/object');
-const xulApp = require("../system/xul-app");
-const USE_JS_PROXIES = !xulApp.versionInRange(xulApp.platformVersion,
- "17.0a2", "*");
-const { getTabForWindow } = require('../tabs/helpers');
-
-/* Trick the linker in order to ensure shipping these files in the XPI.
- require('./content-proxy.js');
- require('./content-worker.js');
- Then, retrieve URL of these files in the XPI:
-*/
-let prefix = module.uri.split('worker.js')[0];
-const CONTENT_PROXY_URL = prefix + 'content-proxy.js';
-const CONTENT_WORKER_URL = prefix + 'content-worker.js';
-
-const JS_VERSION = '1.8';
-
-const ERR_DESTROYED =
- "Couldn't find the worker to receive this message. " +
- "The script may not be initialized yet, or may already have been unloaded.";
-
-const ERR_FROZEN = "The page is currently hidden and can no longer be used " +
- "until it is visible again.";
-
-/**
- * This key is not exported and should only be used for proxy tests.
- * The following `PRIVATE_KEY` is used in addon module scope in order to tell
- * Worker API to expose `UNWRAP_ACCESS_KEY` in content script.
- * This key allows test-content-proxy.js to unwrap proxy with valueOf:
- * let xpcWrapper = proxyWrapper.valueOf(UNWRAP_ACCESS_KEY);
- */
-const PRIVATE_KEY = {};
-
-
-const WorkerSandbox = EventEmitter.compose({
-
- /**
- * Emit a message to the worker content sandbox
- */
- emit: function emit() {
- // First ensure having a regular array
- // (otherwise, `arguments` would be mapped to an object by `stringify`)
- let array = Array.slice(arguments);
- // JSON.stringify is buggy with cross-sandbox values,
- // it may return "{}" on functions. Use a replacer to match them correctly.
- function replacer(k, v) {
- return typeof v === "function" ? undefined : v;
- }
- // Ensure having an asynchronous behavior
- let self = this;
- timer.setTimeout(function () {
- self._emitToContent(JSON.stringify(array, replacer));
- }, 0);
- },
-
- /**
- * Synchronous version of `emit`.
- * /!\ Should only be used when it is strictly mandatory /!\
- * Doesn't ensure passing only JSON values.
- * Mainly used by context-menu in order to avoid breaking it.
- */
- emitSync: function emitSync() {
- let args = Array.slice(arguments);
- // Bug 732716: Ensure wrapping xrays sent to the content script
- // otherwise it will have access to raw xraywrappers and content script
- // will assume it is an user object coming from the content script sandbox
- if ("_wrap" in this)
- args = args.map(this._wrap);
- return this._emitToContent(args);
- },
-
- /**
- * Tells if content script has at least one listener registered for one event,
- * through `self.on('xxx', ...)`.
- * /!\ Shouldn't be used. Implemented to avoid breaking context-menu API.
- */
- hasListenerFor: function hasListenerFor(name) {
- return this._hasListenerFor(name);
- },
-
- /**
- * Method called by the worker sandbox when it needs to send a message
- */
- _onContentEvent: function onContentEvent(args) {
- // As `emit`, we ensure having an asynchronous behavior
- let self = this;
- timer.setTimeout(function () {
- // We emit event to chrome/addon listeners
- self._emit.apply(self, JSON.parse(args));
- }, 0);
- },
-
- /**
- * Configures sandbox and loads content scripts into it.
- * @param {Worker} worker
- * content worker
- */
- constructor: function WorkerSandbox(worker) {
- this._addonWorker = worker;
-
- // Ensure that `emit` has always the right `this`
- this.emit = this.emit.bind(this);
- this.emitSync = this.emitSync.bind(this);
-
- // We receive a wrapped window, that may be an xraywrapper if it's content
- let window = worker._window;
- let proto = window;
-
- // Instantiate trusted code in another Sandbox in order to prevent content
- // script from messing with standard classes used by proxy and API code.
- let apiSandbox = sandbox(window, { wantXrays: true });
-
- // Build content proxies only if the document has a non-system principal
- // And only on old firefox versions that doesn't ship bug 738244
- if (USE_JS_PROXIES && XPCNativeWrapper.unwrap(window) !== window) {
- apiSandbox.console = console;
- // Execute the proxy code
- load(apiSandbox, CONTENT_PROXY_URL);
- // Get a reference of the window's proxy
- proto = apiSandbox.create(window);
- // Keep a reference to `wrap` function for `emitSync` usage
- this._wrap = apiSandbox.wrap;
- }
-
- // Create the sandbox and bind it to window in order for content scripts to
- // have access to all standard globals (window, document, ...)
- let content = this._sandbox = sandbox(window, {
- sandboxPrototype: proto,
- wantXrays: true
- });
- // We have to ensure that window.top and window.parent are the exact same
- // object than window object, i.e. the sandbox global object. But not
- // always, in case of iframes, top and parent are another window object.
- let top = window.top === window ? content : content.top;
- let parent = window.parent === window ? content : content.parent;
- merge(content, {
- // We need "this === window === top" to be true in toplevel scope:
- get window() content,
- get top() top,
- get parent() parent,
- // Use the Greasemonkey naming convention to provide access to the
- // unwrapped window object so the content script can access document
- // JavaScript values.
- // NOTE: this functionality is experimental and may change or go away
- // at any time!
- get unsafeWindow() window.wrappedJSObject
- });
-
- // Load trusted code that will inject content script API.
- // We need to expose JS objects defined in same principal in order to
- // avoid having any kind of wrapper.
- load(apiSandbox, CONTENT_WORKER_URL);
-
- // prepare a clean `self.options`
- let options = 'contentScriptOptions' in worker ?
- JSON.stringify( worker.contentScriptOptions ) :
- undefined;
-
- // Then call `inject` method and communicate with this script
- // by trading two methods that allow to send events to the other side:
- // - `onEvent` called by content script
- // - `result.emitToContent` called by addon script
- // Bug 758203: We have to explicitely define `__exposedProps__` in order
- // to allow access to these chrome object attributes from this sandbox with
- // content priviledges
- // https://developer.mozilla.org/en/XPConnect_wrappers#Other_security_wrappers
- let chromeAPI = {
- timers: {
- setTimeout: timer.setTimeout,
- setInterval: timer.setInterval,
- clearTimeout: timer.clearTimeout,
- clearInterval: timer.clearInterval,
- __exposedProps__: {
- setTimeout: 'r',
- setInterval: 'r',
- clearTimeout: 'r',
- clearInterval: 'r'
- }
- },
- __exposedProps__: {
- timers: 'r'
- }
- };
- let onEvent = this._onContentEvent.bind(this);
- // `ContentWorker` is defined in CONTENT_WORKER_URL file
- let result = apiSandbox.ContentWorker.inject(content, chromeAPI, onEvent, options);
- this._emitToContent = result.emitToContent;
- this._hasListenerFor = result.hasListenerFor;
-
- // Handle messages send by this script:
- let self = this;
- // console.xxx calls
- this.on("console", function consoleListener(kind) {
- console[kind].apply(console, Array.slice(arguments, 1));
- });
-
- // self.postMessage calls
- this.on("message", function postMessage(data) {
- // destroyed?
- if (self._addonWorker)
- self._addonWorker._emit('message', data);
- });
-
- // self.port.emit calls
- this.on("event", function portEmit(name, args) {
- // destroyed?
- if (self._addonWorker)
- self._addonWorker._onContentScriptEvent.apply(self._addonWorker, arguments);
- });
-
- // Internal feature that is only used by SDK tests:
- // Expose unlock key to content script context.
- // See `PRIVATE_KEY` definition for more information.
- if (apiSandbox && worker._expose_key)
- content.UNWRAP_ACCESS_KEY = apiSandbox.UNWRAP_ACCESS_KEY;
-
- // Inject `addon` global into target document if document is trusted,
- // `addon` in document is equivalent to `self` in content script.
- if (worker._injectInDocument) {
- let win = window.wrappedJSObject ? window.wrappedJSObject : window;
- Object.defineProperty(win, "addon", {
- value: content.self
- }
- );
- }
-
- // The order of `contentScriptFile` and `contentScript` evaluation is
- // intentional, so programs can load libraries like jQuery from script URLs
- // and use them in scripts.
- let contentScriptFile = ('contentScriptFile' in worker) ? worker.contentScriptFile
- : null,
- contentScript = ('contentScript' in worker) ? worker.contentScript : null;
-
- if (contentScriptFile) {
- if (Array.isArray(contentScriptFile))
- this._importScripts.apply(this, contentScriptFile);
- else
- this._importScripts(contentScriptFile);
- }
- if (contentScript) {
- this._evaluate(
- Array.isArray(contentScript) ? contentScript.join(';\n') : contentScript
- );
- }
- },
- destroy: function destroy() {
- this.emitSync("detach");
- this._sandbox = null;
- this._addonWorker = null;
- this._wrap = null;
- },
-
- /**
- * JavaScript sandbox where all the content scripts are evaluated.
- * {Sandbox}
- */
- _sandbox: null,
-
- /**
- * Reference to the addon side of the worker.
- * @type {Worker}
- */
- _addonWorker: null,
-
- /**
- * Evaluates code in the sandbox.
- * @param {String} code
- * JavaScript source to evaluate.
- * @param {String} [filename='javascript:' + code]
- * Name of the file
- */
- _evaluate: function(code, filename) {
- try {
- evaluate(this._sandbox, code, filename || 'javascript:' + code);
- }
- catch(e) {
- this._addonWorker._emit('error', e);
- }
- },
- /**
- * Imports scripts to the sandbox by reading files under urls and
- * evaluating its source. If exception occurs during evaluation
- * `"error"` event is emitted on the worker.
- * This is actually an analog to the `importScript` method in web
- * workers but in our case it's not exposed even though content
- * scripts may be able to do it synchronously since IO operation
- * takes place in the UI process.
- */
- _importScripts: function _importScripts(url) {
- let urls = Array.slice(arguments, 0);
- for each (let contentScriptFile in urls) {
- try {
- let uri = URL(contentScriptFile);
- if (uri.scheme === 'resource')
- load(this._sandbox, String(uri));
- else
- throw Error("Unsupported `contentScriptFile` url: " + String(uri));
- }
- catch(e) {
- this._addonWorker._emit('error', e);
- }
- }
- }
-});
-
-/**
- * Message-passing facility for communication between code running
- * in the content and add-on process.
- * @see https://jetpack.mozillalabs.com/sdk/latest/docs/#module/api-utils/content/worker
- */
-const Worker = EventEmitter.compose({
- on: Trait.required,
- _removeAllListeners: Trait.required,
-
- /**
- * Sends a message to the worker's global scope. Method takes single
- * argument, which represents data to be sent to the worker. The data may
- * be any primitive type value or `JSON`. Call of this method asynchronously
- * emits `message` event with data value in the global scope of this
- * symbiont.
- *
- * `message` event listeners can be set either by calling
- * `self.on` with a first argument string `"message"` or by
- * implementing `onMessage` function in the global scope of this worker.
- * @param {Number|String|JSON} data
- */
- postMessage: function postMessage(data) {
- if (!this._contentWorker)
- throw new Error(ERR_DESTROYED);
- if (this._frozen)
- throw new Error(ERR_FROZEN);
-
- this._contentWorker.emit("message", data);
- },
-
- /**
- * EventEmitter, that behaves (calls listeners) asynchronously.
- * A way to send customized messages to / from the worker.
- * Events from in the worker can be observed / emitted via
- * worker.on / worker.emit.
- */
- get port() {
- // We generate dynamically this attribute as it needs to be accessible
- // before Worker.constructor gets called. (For ex: Panel)
-
- // create an event emitter that receive and send events from/to the worker
- let self = this;
- this._port = EventEmitterTrait.create({
- emit: function () self._emitEventToContent(Array.slice(arguments))
- });
-
- // expose wrapped port, that exposes only public properties:
- // We need to destroy this getter in order to be able to set the
- // final value. We need to update only public port attribute as we never
- // try to access port attribute from private API.
- delete this._public.port;
- this._public.port = Cortex(this._port);
- // Replicate public port to the private object
- delete this.port;
- this.port = this._public.port;
-
- return this._port;
- },
-
- /**
- * Same object than this.port but private API.
- * Allow access to _emit, in order to send event to port.
- */
- _port: null,
-
- /**
- * Emit a custom event to the content script,
- * i.e. emit this event on `self.port`
- */
- _emitEventToContent: function _emitEventToContent(args) {
- // We need to save events that are emitted before the worker is
- // initialized
- if (!this._inited) {
- this._earlyEvents.push(args);
- return;
- }
-
- if (this._frozen)
- throw new Error(ERR_FROZEN);
-
- // We throw exception when the worker has been destroyed
- if (!this._contentWorker) {
- throw new Error(ERR_DESTROYED);
- }
-
- // Forward the event to the WorkerSandbox object
- this._contentWorker.emit.apply(null, ["event"].concat(args));
- },
-
- // Is worker connected to the content worker sandbox ?
- _inited: false,
-
- // Is worker being frozen? i.e related document is frozen in bfcache.
- // Content script should not be reachable if frozen.
- _frozen: true,
-
- // List of custom events fired before worker is initialized
- get _earlyEvents() {
- delete this._earlyEvents;
- this._earlyEvents = [];
- return this._earlyEvents;
- },
-
- constructor: function Worker(options) {
- options = options || {};
-
- if ('window' in options)
- this._window = options.window;
- if ('contentScriptFile' in options)
- this.contentScriptFile = options.contentScriptFile;
- if ('contentScriptOptions' in options)
- this.contentScriptOptions = options.contentScriptOptions;
- if ('contentScript' in options)
- this.contentScript = options.contentScript;
- if ('onError' in options)
- this.on('error', options.onError);
- if ('onMessage' in options)
- this.on('message', options.onMessage);
- if ('onDetach' in options)
- this.on('detach', options.onDetach);
-
- // Internal feature that is only used by SDK unit tests.
- // See `PRIVATE_KEY` definition for more information.
- if ('exposeUnlockKey' in options && options.exposeUnlockKey === PRIVATE_KEY)
- this._expose_key = true;
-
- // Track document unload to destroy this worker.
- // We can't watch for unload event on page's window object as it
- // prevents bfcache from working:
- // https://developer.mozilla.org/En/Working_with_BFCache
- this._windowID = this._window.
- QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils).
- currentInnerWindowID;
- observers.add("inner-window-destroyed",
- this._documentUnload = this._documentUnload.bind(this));
-
- // Listen to pagehide event in order to freeze the content script
- // while the document is frozen in bfcache:
- this._window.addEventListener("pageshow",
- this._pageShow = this._pageShow.bind(this),
- true);
- this._window.addEventListener("pagehide",
- this._pageHide = this._pageHide.bind(this),
- true);
-
- unload.ensure(this._public, "destroy");
-
- // Ensure that worker._port is initialized for contentWorker to be able
- // to send use event during WorkerSandbox(this)
- this.port;
-
- // will set this._contentWorker pointing to the private API:
- this._contentWorker = WorkerSandbox(this);
-
- // Mainly enable worker.port.emit to send event to the content worker
- this._inited = true;
- this._frozen = false;
-
- // Flush all events that have been fired before the worker is initialized.
- this._earlyEvents.forEach((function (args) this._emitEventToContent(args)).
- bind(this));
- },
-
- _documentUnload: function _documentUnload(subject, topic, data) {
- let innerWinID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
- if (innerWinID != this._windowID) return false;
- this._workerCleanup();
- return true;
- },
-
- _pageShow: function _pageShow() {
- this._contentWorker.emitSync("pageshow");
- this._emit("pageshow");
- this._frozen = false;
- },
-
- _pageHide: function _pageHide() {
- this._contentWorker.emitSync("pagehide");
- this._emit("pagehide");
- this._frozen = true;
- },
-
- get url() {
- // this._window will be null after detach
- return this._window ? this._window.document.location.href : null;
- },
-
- get tab() {
- // this._window will be null after detach
- if (this._window)
- return getTabForWindow(this._window);
- return null;
- },
-
- /**
- * Tells content worker to unload itself and
- * removes all the references from itself.
- */
- destroy: function destroy() {
- this._workerCleanup();
- this._removeAllListeners();
- },
-
- /**
- * Remove all internal references to the attached document
- * Tells _port to unload itself and removes all the references from itself.
- */
- _workerCleanup: function _workerCleanup() {
- // maybe unloaded before content side is created
- // As Symbiont call worker.constructor on document load
- if (this._contentWorker)
- this._contentWorker.destroy();
- this._contentWorker = null;
- if (this._window) {
- this._window.removeEventListener("pageshow", this._pageShow, true);
- this._window.removeEventListener("pagehide", this._pageHide, true);
- }
- this._window = null;
- // This method may be called multiple times,
- // avoid dispatching `detach` event more than once
- if (this._windowID) {
- this._windowID = null;
- observers.remove("inner-window-destroyed", this._documentUnload);
- this._earlyEvents.slice(0, this._earlyEvents.length);
- this._emit("detach");
- }
- },
-
- /**
- * Receive an event from the content script that need to be sent to
- * worker.port. Provide a way for composed object to catch all events.
- */
- _onContentScriptEvent: function _onContentScriptEvent() {
- this._port._emit.apply(this._port, arguments);
- },
-
- /**
- * Reference to the content side of the worker.
- * @type {WorkerGlobalScope}
- */
- _contentWorker: null,
-
- /**
- * Reference to the window that is accessible from
- * the content scripts.
- * @type {Object}
- */
- _window: null,
-
- /**
- * Flag to enable `addon` object injection in document. (bug 612726)
- * @type {Boolean}
- */
- _injectInDocument: false
-});
-exports.Worker = Worker;
diff --git a/tools/addon-sdk-1.12/lib/sdk/context-menu.js b/tools/addon-sdk-1.12/lib/sdk/context-menu.js
deleted file mode 100644
index 9d20f0b..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/context-menu.js
+++ /dev/null
@@ -1,1494 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "stable"
-};
-
-const {Ci} = require("chrome");
-
-if (!require("./system/xul-app").is("Firefox")) {
- throw new Error([
- "The context-menu module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=560716 for more information."
- ].join(""));
-}
-
-const apiUtils = require("./deprecated/api-utils");
-const collection = require("./util/collection");
-const { Worker } = require("./content/worker");
-const { URL } = require("./url");
-const { MatchPattern } = require("./page-mod/match-pattern");
-const { EventEmitterTrait: EventEmitter } = require("./deprecated/events");
-const observerServ = require("./deprecated/observer-service");
-const jpSelf = require("./self");
-const { WindowTracker } = require("./deprecated/window-utils");
-const { getInnerId, isBrowser } = require("./window/utils");
-const { Trait } = require("./deprecated/light-traits");
-const { Cortex } = require("./deprecated/cortex");
-const timer = require("./timers");
-
-// All user items we add have this class name.
-const ITEM_CLASS = "jetpack-context-menu-item";
-
-// Items in the top-level context menu also have this class.
-const TOPLEVEL_ITEM_CLASS = "jetpack-context-menu-item-toplevel";
-
-// Items in the overflow submenu also have this class.
-const OVERFLOW_ITEM_CLASS = "jetpack-context-menu-item-overflow";
-
-// The ID of the menu separator that separates standard context menu items from
-// our user items.
-const SEPARATOR_ID = "jetpack-context-menu-separator";
-
-// If more than this number of items are added to the context menu, all items
-// overflow into a "Jetpack" submenu.
-const OVERFLOW_THRESH_DEFAULT = 10;
-const OVERFLOW_THRESH_PREF =
- "extensions.addon-sdk.context-menu.overflowThreshold";
-
-// The label of the overflow sub-xul:menu.
-//
-// TODO: Localize this.
-const OVERFLOW_MENU_LABEL = "Add-ons";
-
-// The ID of the overflow sub-xul:menu.
-const OVERFLOW_MENU_ID = "jetpack-content-menu-overflow-menu";
-
-// The ID of the overflow submenu's xul:menupopup.
-const OVERFLOW_POPUP_ID = "jetpack-content-menu-overflow-popup";
-
-// These are used by PageContext.isCurrent below. If the popupNode or any of
-// its ancestors is one of these, Firefox uses a tailored context menu, and so
-// the page context doesn't apply.
-const NON_PAGE_CONTEXT_ELTS = [
- Ci.nsIDOMHTMLAnchorElement,
- Ci.nsIDOMHTMLAppletElement,
- Ci.nsIDOMHTMLAreaElement,
- Ci.nsIDOMHTMLButtonElement,
- Ci.nsIDOMHTMLCanvasElement,
- Ci.nsIDOMHTMLEmbedElement,
- Ci.nsIDOMHTMLImageElement,
- Ci.nsIDOMHTMLInputElement,
- Ci.nsIDOMHTMLMapElement,
- Ci.nsIDOMHTMLMediaElement,
- Ci.nsIDOMHTMLMenuElement,
- Ci.nsIDOMHTMLObjectElement,
- Ci.nsIDOMHTMLOptionElement,
- Ci.nsIDOMHTMLSelectElement,
- Ci.nsIDOMHTMLTextAreaElement,
-];
-
-// This is used to access private properties of Item and Menu instances.
-const PRIVATE_PROPS_KEY = {
- valueOf: function valueOf() "private properties key"
-};
-
-// Used as an internal ID for items and as part of a public ID for item DOM
-// elements. Careful: This number is not necessarily unique to any one instance
-// of the module. For each module instance, when the first item is created this
-// number will be 0, when the second is created it will be 1, and so on.
-let nextItemID = 0;
-
-// The number of items that haven't finished initializing yet. See
-// AIT__finishActiveItemInit().
-let numItemsWithUnfinishedInit = 0;
-
-exports.Item = Item;
-exports.Menu = Menu;
-exports.Separator = Separator;
-
-
-// A word about traits and privates. `this` inside of traits methods is an
-// object private to the implementation. It should never be publicly leaked.
-// We use Cortex in the exported menu item constructors to create public
-// reflections of the private objects that hide private properties -- those
-// prefixed with an underscore. Public reflections are attached to the private
-// objects via the `_public` property.
-//
-// All item objects passed into the implementation by the client will be public
-// reflections, not private objects. Likewise, all item objects passed out of
-// the implementation to the client must be public, not private. Mixing up
-// public and private is bad and easy to do, so not only are private objects
-// restricted to the implementation, but as much as possible we try to restrict
-// them to the Item, Menu, and Separator traits and constructors. Everybody
-// else in the implementation should expect to be passed public reflections, and
-// they must specifically request private objects via privateItem().
-
-// Item, Menu, and Separator are composed of this trait.
-const ItemBaseTrait = Trait({
-
- _initBase: function IBT__initBase(opts, optRules, optsToNotSet) {
- this._optRules = optRules;
- for (let optName in optRules)
- if (optsToNotSet.indexOf(optName) < 0)
- this[optName] = opts[optName];
- optsToNotSet.forEach(function (opt) validateOpt(opts[opt], optRules[opt]));
- this._isInited = true;
-
- this._id = nextItemID++;
- this._parentMenu = null;
-
- // This makes the private properties accessible to anyone with access to
- // PRIVATE_PROPS_KEY. Barring loader tricks, only this file has has access
- // to it, so only this file has access to the private properties.
- const self = this;
- this.valueOf = function IBT_valueOf(key) {
- return key === PRIVATE_PROPS_KEY ? self : self._public;
- };
- },
-
- destroy: function IBT_destroy() {
- if (this._wasDestroyed)
- return;
- if (this.parentMenu)
- this.parentMenu.removeItem(this._public);
- else if (!(this instanceof Separator) && this._hasFinishedInit)
- browserManager.removeTopLevelItem(this._public);
- browserManager.unregisterItem(this._public);
- this._wasDestroyed = true;
- },
-
- get parentMenu() {
- return this._parentMenu;
- },
-
- set parentMenu(val) {
- throw new Error("The 'parentMenu' property is not intended to be set. " +
- "Use menu.addItem(item) instead.");
- },
-
- set _isTopLevel(val) {
- if (val)
- this._workerReg = new WorkerRegistry(this._public);
- else {
- this._workerReg.destroy();
- delete this._workerReg;
- }
- },
-
- get _topLevelItem() {
- let topLevelItem = this._public;
- let parentMenu = this.parentMenu;
- while (parentMenu) {
- topLevelItem = parentMenu;
- parentMenu = parentMenu.parentMenu;
- }
- return topLevelItem;
- }
-});
-
-// Item and Menu are composed of this trait.
-const ActiveItemTrait = Trait.compose(ItemBaseTrait, EventEmitter, Trait({
-
- _initActiveItem: function AIT__initActiveItem(opts, optRules, optsToNotSet) {
- this._initBase(opts, optRules,
- optsToNotSet.concat(["onMessage", "context"]));
-
- if ("onMessage" in opts)
- this.on("message", opts.onMessage);
-
- // When a URL context is removed (by calling context.remove(urlContext)), we
- // may need to create workers for windows containing pages that the item now
- // matches. Likewise, when a URL context is added, we need to destroy
- // workers for windows containing pages that the item now does not match.
- //
- // collection doesn't provide a way to listen for removals. utils/registry
- // does, but it doesn't allow its elements to be enumerated. So as a hack,
- // use a collection for item.context and replace its add and remove methods.
- collection.addCollectionProperty(this, "context");
- if (opts.context)
- this.context.add(opts.context);
-
- const self = this;
-
- let add = this.context.add;
- this.context.add = function itemContextAdd() {
- let args = Array.slice(arguments);
- add.apply(self.context, args);
- if (self._workerReg && args.some(function (a) a instanceof URLContext))
- self._workerReg.destroyUnneededWorkers();
- };
-
- let remove = this.context.remove;
- this.context.remove = function itemContextRemove() {
- let args = Array.slice(arguments);
- remove.apply(self.context, args);
- if (self._workerReg && args.some(function (a) a instanceof URLContext))
- self._workerReg.createNeededWorkers();
- };
- },
-
- // Workers are only created for top-level menu items. When a top-level item
- // is later added to a Menu, its workers are destroyed. Well, all items start
- // out as top-level because there is, unfortunately, no contextMenu.add(). So
- // when an item is created and immediately added to a Menu, workers for it are
- // needlessly created and destroyed. The point of this timeout is to avoid
- // that. Items that are created and added to Menus in the same turn of the
- // event loop won't have workers created for them.
- _finishActiveItemInit: function AIT__finishActiveItemInit() {
- numItemsWithUnfinishedInit++;
- const self = this;
- timer.setTimeout(function AIT__finishActiveItemInitTimeout() {
- if (!self.parentMenu && !self._wasDestroyed)
- browserManager.addTopLevelItem(self._public);
- self._hasFinishedInit = true;
- numItemsWithUnfinishedInit--;
- }, 0);
- },
-
- get label() {
- return this._label;
- },
-
- set label(val) {
- this._label = validateOpt(val, this._optRules.label);
- if (this._isInited)
- browserManager.setItemLabel(this, this._label);
- return this._label;
- },
-
- get image() {
- return this._image;
- },
-
- set image(val) {
- this._image = validateOpt(val, this._optRules.image);
- if (this._isInited)
- browserManager.setItemImage(this, this._image);
- return this._image;
- },
-
- get contentScript() {
- return this._contentScript;
- },
-
- set contentScript(val) {
- this._contentScript = validateOpt(val, this._optRules.contentScript);
- return this._contentScript;
- },
-
- get contentScriptFile() {
- return this._contentScriptFile;
- },
-
- set contentScriptFile(val) {
- this._contentScriptFile =
- validateOpt(val, this._optRules.contentScriptFile);
- return this._contentScriptFile;
- }
-}));
-
-// Item is composed of this trait.
-const ItemTrait = Trait.compose(ActiveItemTrait, Trait({
-
- _initItem: function IT__initItem(opts, optRules) {
- this._initActiveItem(opts, optRules, []);
- },
-
- get data() {
- return this._data;
- },
-
- set data(val) {
- this._data = validateOpt(val, this._optRules.data);
- if (this._isInited)
- browserManager.setItemData(this, this._data);
- return this._data;
- },
-
- toString: function IT_toString() {
- return '[object Item "' + this.label + '"]';
- }
-}));
-
-// The exported Item constructor.
-function Item(options) {
- let optRules = optionsRules();
- optRules.data = {
- map: function (v) v.toString(),
- is: ["string", "undefined"]
- };
-
- let item = ItemTrait.create(Item.prototype);
- item._initItem(options, optRules);
-
- item._public = Cortex(item);
- browserManager.registerItem(item._public);
- item._finishActiveItemInit();
-
- return item._public;
-}
-
-// Menu is composed of this trait.
-const MenuTrait = Trait.compose(
- ActiveItemTrait.resolve({ destroy: "_destroyThisItem" }),
- Trait({
-
- _initMenu: function MT__initMenu(opts, optRules, optsToNotSet) {
- this._items = [];
- this._initActiveItem(opts, optRules, optsToNotSet);
- },
-
- destroy: function MT_destroy() {
- while (this.items.length)
- this.items[0].destroy();
- this._destroyThisItem();
- },
-
- get items() {
- return this._items;
- },
-
- set items(val) {
- let newItems = validateOpt(val, this._optRules.items);
- while (this.items.length)
- this.items[0].destroy();
- newItems.forEach(function (i) this.addItem(i), this);
- return newItems;
- },
-
- addItem: function MT_addItem(item) {
- // First, remove the item from its current parent.
- let privates = privateItem(item);
- if (item.parentMenu)
- item.parentMenu.removeItem(item);
- else if (!(item instanceof Separator) && privates._hasFinishedInit)
- browserManager.removeTopLevelItem(item);
-
- // Now add the item to this menu.
- this._items.push(item);
- privates._parentMenu = this._public;
- browserManager.addItemToMenu(item, this._public);
- },
-
- removeItem: function MT_removeItem(item) {
- let idx = this._items.indexOf(item);
- if (idx < 0)
- return;
- this._items.splice(idx, 1);
- privateItem(item)._parentMenu = null;
- browserManager.removeItemFromMenu(item, this._public);
- },
-
- toString: function MT_toString() {
- return '[object Menu "' + this.label + '"]';
- }
-}));
-
-// The exported Menu constructor.
-function Menu(options) {
- let optRules = optionsRules();
- optRules.items = {
- is: ["array"],
- ok: function (v) {
- return v.every(function (item) {
- return (item instanceof Item) ||
- (item instanceof Menu) ||
- (item instanceof Separator);
- });
- },
- msg: "items must be an array, and each element in the array must be an " +
- "Item, Menu, or Separator."
- };
-
- let menu = MenuTrait.create(Menu.prototype);
-
- // We can't rely on _initBase to set the `items` property, because the menu
- // needs to be registered with and added to the browserManager before any
- // child items are added to it.
- menu._initMenu(options, optRules, ["items"]);
-
- menu._public = Cortex(menu);
- browserManager.registerItem(menu._public);
- menu.items = options.items;
- menu._finishActiveItemInit();
-
- return menu._public;
-}
-
-// The exported Separator constructor.
-function Separator() {
- let sep = ItemBaseTrait.create(Separator.prototype);
- sep._initBase({}, {}, []);
-
- sep._public = Cortex(sep);
- browserManager.registerItem(sep._public);
- sep._hasFinishedInit = true;
- return sep._public;
-}
-
-
-function Context() {}
-
-function PageContext() {
- this.isCurrent = function PageContext_isCurrent(popupNode) {
- let win = popupNode.ownerDocument.defaultView;
- if (win && !win.getSelection().isCollapsed)
- return false;
-
- let cursor = popupNode;
- while (cursor && !(cursor instanceof Ci.nsIDOMHTMLHtmlElement)) {
- if (NON_PAGE_CONTEXT_ELTS.some(function (iface) cursor instanceof iface))
- return false;
- cursor = cursor.parentNode;
- }
- return true;
- };
-}
-
-PageContext.prototype = new Context();
-
-function SelectorContext(selector) {
- let opts = apiUtils.validateOptions({ selector: selector }, {
- selector: {
- is: ["string"],
- msg: "selector must be a string."
- }
- });
-
- this.adjustPopupNode = function SelectorContext_adjustPopupNode(node) {
- return closestMatchingAncestor(node);
- };
-
- this.isCurrent = function SelectorContext_isCurrent(popupNode) {
- return !!closestMatchingAncestor(popupNode);
- };
-
- // Returns node if it matches selector, or the closest ancestor of node that
- // matches, or null if node and none of its ancestors matches.
- function closestMatchingAncestor(node) {
- let cursor = node;
- while (cursor) {
- if (cursor.mozMatchesSelector(selector))
- return cursor;
- if (cursor instanceof Ci.nsIDOMHTMLHtmlElement)
- break;
- cursor = cursor.parentNode;
- }
- return null;
- }
-}
-
-SelectorContext.prototype = new Context();
-
-function SelectionContext() {
- this.isCurrent = function SelectionContext_isCurrent(popupNode) {
- let win = popupNode.ownerDocument.defaultView;
- if (!win)
- return false;
-
- let hasSelection = !win.getSelection().isCollapsed;
- if (!hasSelection) {
- // window.getSelection doesn't return a selection for text selected in a
- // form field (see bug 85686), so before returning false we want to check
- // if the popupNode is a text field.
- let { selectionStart, selectionEnd } = popupNode;
- hasSelection = !isNaN(selectionStart) &&
- !isNaN(selectionEnd) &&
- selectionStart !== selectionEnd;
- }
- return hasSelection;
- };
-}
-
-SelectionContext.prototype = new Context();
-
-function URLContext(patterns) {
- let opts = apiUtils.validateOptions({ patterns: patterns }, {
- patterns: {
- map: function (v) apiUtils.getTypeOf(v) === "array" ? v : [v],
- ok: function (v) v.every(function (p) typeof(p) === "string"),
- msg: "patterns must be a string or an array of strings."
- }
- });
- try {
- patterns = opts.patterns.map(function (p) new MatchPattern(p));
- }
- catch (err) {
- console.error("Error creating URLContext match pattern:");
- throw err;
- }
-
- const self = this;
-
- this.isCurrent = function URLContext_isCurrent(popupNode) {
- return self.isCurrentForURL(popupNode.ownerDocument.URL);
- };
-
- this.isCurrentForURL = function URLContext_isCurrentForURL(url) {
- return patterns.some(function (p) p.test(url));
- };
-}
-
-URLContext.prototype = new Context();
-
-exports.PageContext = apiUtils.publicConstructor(PageContext);
-exports.SelectorContext = apiUtils.publicConstructor(SelectorContext);
-exports.SelectionContext = apiUtils.publicConstructor(SelectionContext);
-exports.URLContext = apiUtils.publicConstructor(URLContext);
-
-
-// Returns a version of opt validated against the given rule.
-function validateOpt(opt, rule) {
- return apiUtils.validateOptions({ opt: opt }, { opt: rule }).opt;
-}
-
-// Returns rules for apiUtils.validateOptions() common to Item and Menu.
-function optionsRules() {
- return {
- context: {
- is: ["undefined", "object", "array"],
- ok: function (v) {
- if (!v)
- return true;
- let arr = apiUtils.getTypeOf(v) === "array" ? v : [v];
- return arr.every(function (o) o instanceof Context);
- },
- msg: "The 'context' option must be a Context object or an array of " +
- "Context objects."
- },
- label: {
- map: function (v) v.toString(),
- is: ["string"],
- ok: function (v) !!v,
- msg: "The item must have a non-empty string label."
- },
- image: {
- map: function (v) v.toString(),
- is: ["string", "undefined", "null"]
- },
- contentScript: {
- is: ["string", "array", "undefined"],
- ok: function (v) {
- return apiUtils.getTypeOf(v) !== "array" ||
- v.every(function (s) typeof(s) === "string");
- }
- },
- contentScriptFile: {
- is: ["string", "array", "undefined"],
- ok: function (v) {
- if (!v)
- return true;
- let arr = apiUtils.getTypeOf(v) === "array" ? v : [v];
- try {
- return arr.every(function (s) {
- return apiUtils.getTypeOf(s) === "string" &&
- URL(s).scheme === 'resource';
- });
- }
- catch (err) {}
- return false;
- },
- msg: "The 'contentScriptFile' option must be a local file URL or " +
- "an array of local file URLs."
- },
- onMessage: {
- is: ["function", "undefined"]
- }
- };
-}
-
-// Does a binary search on elts, a NodeList, and returns the DOM element
-// before which an item with targetLabel should be inserted. null is returned
-// if the new item should be inserted at the end.
-function insertionPoint(targetLabel, elts) {
- let from = 0;
- let to = elts.length - 1;
-
- while (from <= to) {
- let i = Math.floor((from + to) / 2);
- let comp = targetLabel.localeCompare(elts[i].getAttribute("label"));
- if (comp < 0)
- to = i - 1;
- else if (comp > 0)
- from = i + 1;
- else
- return elts[i];
- }
- return elts[from] || null;
-}
-
-// Builds an ID suitable for a DOM element from the given item ID.
-// isInOverflowSubtree should be true if the returned element will be inserted
-// into the DOM subtree rooted at the overflow menu.
-function domEltIDFromItemID(itemID, isInOverflowSubtree) {
- let suffix = isInOverflowSubtree ? "-overflow" : "";
- return jpSelf.id + "-context-menu-item-" + itemID + suffix;
-}
-
-// Parses the item ID out of the given DOM element ID and returns it. If the
-// element's ID is malformed or it indicates that the element was not created by
-// the instance of the module calling this function, returns -1.
-function itemIDFromDOMEltID(domEltID) {
- let match = /^(.+?)-context-menu-item-([0-9]+)[-a-z]*$/.exec(domEltID);
- return !match || match[1] !== jpSelf.id ? -1 : match[2];
-}
-
-// Returns the private version of the given public reflection.
-function privateItem(publicItem) {
- return publicItem.valueOf(PRIVATE_PROPS_KEY);
-}
-
-
-// A type of Worker tailored to our uses.
-const ContextMenuWorker = Worker.compose({
- destroy: Worker.required,
-
- // Returns true if any context listeners are defined in the worker's port.
- anyContextListeners: function CMW_anyContextListeners() {
- return this._contentWorker.hasListenerFor("context");
- },
-
- // Returns the first string or truthy value returned by a context listener in
- // the worker's port. If none return a string or truthy value or if there are
- // no context listeners, returns false. popupNode is the node that was
- // context-clicked.
- isAnyContextCurrent: function CMW_isAnyContextCurrent(popupNode) {
- let results = this._contentWorker.emitSync("context", popupNode);
- for (let i = 0; i < results.length; i++) {
- let val = results[i];
- if (typeof val === "string" || val)
- return val;
- }
- return false;
- },
-
- // Emits a click event in the worker's port. popupNode is the node that was
- // context-clicked, and clickedItemData is the data of the item that was
- // clicked.
- fireClick: function CMW_fireClick(popupNode, clickedItemData) {
- this._contentWorker.emitSync("click", popupNode, clickedItemData);
- }
-});
-
-
-// This class creates and stores content workers for pairs of menu items and
-// content windows. Use one instance for each item. Not all pairs need a
-// worker: if an item has a URL context that does not match a window's page,
-// then no worker is created for the pair.
-function WorkerRegistry(item) {
- this.item = item;
-
- // inner window ID => { win, worker }
- this.winWorkers = {};
-
- // inner window ID => content window
- this.winsWithoutWorkers = {};
-}
-
-WorkerRegistry.prototype = {
-
- // Registers a content window, creating a worker for it if it needs one.
- registerContentWin: function WR_registerContentWin(win) {
- let innerWinID = getInnerId(win);
- if ((innerWinID in this.winWorkers) ||
- (innerWinID in this.winsWithoutWorkers))
- return;
- if (this._doesURLNeedWorker(win.document.URL))
- this.winWorkers[innerWinID] = { win: win, worker: this._makeWorker(win) };
- else
- this.winsWithoutWorkers[innerWinID] = win;
- },
-
- // Unregisters a content window, destroying its related worker if it has one.
- unregisterContentWin: function WR_unregisterContentWin(innerWinID) {
- if (innerWinID in this.winWorkers) {
- let winWorker = this.winWorkers[innerWinID];
- winWorker.worker.destroy();
- delete winWorker.worker;
- delete winWorker.win;
- delete this.winWorkers[innerWinID];
- }
- else
- delete this.winsWithoutWorkers[innerWinID];
- },
-
- // Creates a worker for each window that needs a worker but doesn't have one.
- createNeededWorkers: function WR_createNeededWorkers() {
- for (let innerWinID in this.winsWithoutWorkers) {
- let win = this.winsWithoutWorkers[innerWinID]
- delete this.winsWithoutWorkers[innerWinID];
- this.registerContentWin(win);
- }
- },
-
- // Destroys the worker for each window that has a worker but doesn't need it.
- destroyUnneededWorkers: function WR_destroyUnneededWorkers() {
- for (let innerWinID in this.winWorkers) {
- let winWorker = this.winWorkers[innerWinID];
- if (!this._doesURLNeedWorker(winWorker.win.document.URL)) {
- this.unregisterContentWin(innerWinID);
- this.winsWithoutWorkers[innerWinID] = winWorker.win;
- }
- }
- },
-
- // Returns the worker for the item-window pair or null if none exists.
- find: function WR_find(contentWin) {
- let innerWinID = getInnerId(contentWin);
- return (innerWinID in this.winWorkers) ?
- this.winWorkers[innerWinID].worker :
- null;
- },
-
- // Unregisters all content windows from the registry, which destroys all
- // workers.
- destroy: function WR_destroy() {
- for (let innerWinID in this.winWorkers)
- this.unregisterContentWin(innerWinID);
- for (let innerWinID in this.winsWithoutWorkers)
- this.unregisterContentWin(innerWinID);
- },
-
- // Returns false if the item has a URL context that does not match the given
- // URL.
- _doesURLNeedWorker: function WR__doesURLNeedWorker(url) {
- for (let ctxt in this.item.context)
- if ((ctxt instanceof URLContext) && !ctxt.isCurrentForURL(url))
- return false;
- return true;
- },
-
- _makeWorker: function WR__makeWorker(win) {
- let worker = ContextMenuWorker({
- window: win,
- contentScript: this.item.contentScript,
- contentScriptFile: this.item.contentScriptFile,
- onError: function (err) console.exception(err)
- });
- let item = this.item;
- worker.on("message", function workerOnMessage(msg) {
- try {
- privateItem(item)._emitOnObject(item, "message", msg);
- }
- catch (err) {
- console.exception(err);
- }
- });
- return worker;
- }
-};
-
-
-// Mirrors state across all browser windows. Also responsible for detecting
-// all content window loads and unloads.
-let browserManager = {
- topLevelItems: [],
- browserWins: [],
-
- // inner window ID => content window
- contentWins: {},
-
- // Call this when a new item is created, top-level or not.
- registerItem: function BM_registerItem(item) {
- this.browserWins.forEach(function (w) w.registerItem(item));
- },
-
- // Call this when an item is destroyed and won't be used again, top-level or
- // not.
- unregisterItem: function BM_unregisterItem(item) {
- this.browserWins.forEach(function (w) w.unregisterItem(item));
- },
-
- addTopLevelItem: function BM_addTopLevelItem(item) {
- this.topLevelItems.push(item);
- this.browserWins.forEach(function (w) w.addTopLevelItem(item));
-
- // Create the item's worker registry and register all currently loaded
- // content windows with it.
- let privates = privateItem(item);
- privates._isTopLevel = true;
- for each (let win in this.contentWins)
- privates._workerReg.registerContentWin(win);
- },
-
- removeTopLevelItem: function BM_removeTopLevelItem(item) {
- let idx = this.topLevelItems.indexOf(item);
- if (idx < 0)
- throw new Error("Internal error: item not in top-level menu: " + item);
- this.topLevelItems.splice(idx, 1);
- this.browserWins.forEach(function (w) w.removeTopLevelItem(item));
- privateItem(item)._isTopLevel = false;
- },
-
- addItemToMenu: function BM_addItemToMenu(item, parentMenu) {
- this.browserWins.forEach(function (w) w.addItemToMenu(item, parentMenu));
- },
-
- removeItemFromMenu: function BM_removeItemFromMenu(item, parentMenu) {
- this.browserWins.forEach(function (w) w.removeItemFromMenu(item,
- parentMenu));
- },
-
- setItemLabel: function BM_setItemLabel(item, label) {
- this.browserWins.forEach(function (w) w.setItemLabel(item, label));
- },
-
- setItemImage: function BM_setItemImage(item, imageURL) {
- this.browserWins.forEach(function (w) w.setItemImage(item, imageURL));
- },
-
- setItemData: function BM_setItemData(item, data) {
- this.browserWins.forEach(function (w) w.setItemData(item, data));
- },
-
- // Note that calling this method will cause onTrack to be called immediately
- // for each currently open browser window.
- init: function BM_init() {
- require("./system/unload").ensure(this);
- let windowTracker = WindowTracker(this);
-
- // Register content windows on content-document-global-created and
- // unregister them on inner-window-destroyed. For rationale, see bug 667957
- // for the former and bug 642004 for the latter.
- observerServ.add("content-document-global-created",
- this._onDocGlobalCreated, this);
- observerServ.add("inner-window-destroyed",
- this._onInnerWinDestroyed, this);
- },
-
- _onDocGlobalCreated: function BM__onDocGlobalCreated(contentWin) {
- let doc = contentWin.document;
- if (doc.readyState == "loading") {
- const self = this;
- doc.addEventListener("readystatechange", function onReadyStateChange(e) {
- if (e.target != doc || doc.readyState != "complete")
- return;
- doc.removeEventListener("readystatechange", onReadyStateChange, false);
- self._registerContentWin(contentWin);
- }, false);
- }
- else if (doc.readyState == "complete")
- this._registerContentWin(contentWin);
- },
-
- _onInnerWinDestroyed: function BM__onInnerWinDestroyed(subj) {
- this._unregisterContentWin(
- subj.QueryInterface(Ci.nsISupportsPRUint64).data);
- },
-
- // Stores the given content window with the manager and registers it with each
- // top-level item's worker registry.
- _registerContentWin: function BM__registerContentWin(win) {
- let innerID = getInnerId(win);
-
- // It's an error to call this method for the same window more than once, but
- // we allow it in one case: when onTrack races _onDocGlobalCreated. (See
- // the comment in onTrack.) Make sure the window is registered only once.
- if (innerID in this.contentWins)
- return;
-
- this.contentWins[innerID] = win;
- this.topLevelItems.forEach(function (item) {
- privateItem(item)._workerReg.registerContentWin(win);
- });
- },
-
- // Removes the given content window from the manager and unregisters it from
- // each top-level item's worker registry.
- _unregisterContentWin: function BM__unregisterContentWin(innerID) {
- delete this.contentWins[innerID];
- this.topLevelItems.forEach(function (item) {
- privateItem(item)._workerReg.unregisterContentWin(innerID);
- });
- },
-
- unload: function BM_unload() {
- // The window tracker is unloaded at the same time this method is called,
- // which causes onUntrack to be called for each open browser window, so
- // there's no need to clean up browser windows here.
-
- while (this.topLevelItems.length) {
- let item = this.topLevelItems[0];
- this.removeTopLevelItem(item);
- this.unregisterItem(item);
- }
- delete this.contentWins;
- },
-
- // Registers a browser window with the manager. This is a WindowTracker
- // callback. Note that this is called in two cases: for each newly opened
- // chrome window, and for each chrome window that is open when the loader
- // loads this module.
- onTrack: function BM_onTrack(window) {
- if (!isBrowser(window))
- return;
-
- let browserWin = new BrowserWindow(window);
- this.browserWins.push(browserWin);
-
- // Register all loaded content windows in the browser window. Be sure to
- // include frames and iframes. If onTrack is called as a result of a new
- // browser window being opened, as opposed to the module being loaded, then
- // this will race the content-document-global-created notification. That's
- // OK, since _registerContentWin will not register the same content window
- // more than once.
- window.gBrowser.browsers.forEach(function (browser) {
- let topContentWin = browser.contentWindow;
- let allContentWins = Array.slice(topContentWin.frames);
- allContentWins.push(topContentWin);
- allContentWins.forEach(function (contentWin) {
- if (contentWin.document.readyState == "complete")
- this._registerContentWin(contentWin);
- }, this);
- }, this);
-
- // Add all top-level items and, recursively, their child items to the new
- // browser window.
- function addItemTree(item, parentMenu) {
- browserWin.registerItem(item);
- if (parentMenu)
- browserWin.addItemToMenu(item, parentMenu);
- else
- browserWin.addTopLevelItem(item);
- if (item instanceof Menu)
- item.items.forEach(function (subitem) addItemTree(subitem, item));
- }
- this.topLevelItems.forEach(function (item) addItemTree(item, null));
- },
-
- // Unregisters a browser window from the manager. This is a WindowTracker
- // callback. Note that this is called in two cases: for each newly closed
- // chrome window, and for each chrome window that is open when this module is
- // unloaded.
- onUntrack: function BM_onUntrack(window) {
- if (!isBrowser(window))
- return;
-
- // Remove the window from the window list.
- let idx = 0;
- for (; idx < this.browserWins.length; idx++)
- if (this.browserWins[idx].window == window)
- break;
- if (idx == this.browserWins.length)
- throw new Error("Internal error: browser window not found");
- let browserWin = this.browserWins.splice(idx, 1)[0];
-
- // Remove all top-level items from the window.
- this.topLevelItems.forEach(function (i) browserWin.removeTopLevelItem(i));
- browserWin.destroy();
- }
-};
-
-
-// Responsible for creating and managing context menu item DOM elements for a
-// browser window. Also responsible for providing a description of the window's
-// current context and determining whether an item matches the current context.
-//
-// TODO: If other apps besides Firefox want to support the context menu in
-// whatever way is appropriate for them, plugging in a substitute for or an
-// adapter to this class should be the way to do it. Make it easy for them.
-// See bug 560716.
-function BrowserWindow(window) {
- this.window = window;
- this.doc = window.document;
-
- let popupDOMElt = this.doc.getElementById("contentAreaContextMenu");
- if (!popupDOMElt)
- throw new Error("Internal error: Context menu popup not found.");
- this.contextMenuPopup = new ContextMenuPopup(popupDOMElt, this);
-
- // item ID => { item, domElt, overflowDOMElt, popup, overflowPopup }
- // item may or may not be top-level. domElt is the item's DOM element
- // contained in the subtree rooted in the top-level context menu.
- // overflowDOMElt is the item's DOM element contained in the subtree rooted in
- // the overflow submenu. popup and overflowPopup are only defined if the item
- // is a Menu; they're the Popup instances containing the Menu's child items,
- // with the aforementioned distinction between top-level and overflow
- // subtrees.
- this.items = {};
-}
-
-BrowserWindow.prototype = {
-
- // Creates and stores DOM elements for the given item, top-level or not.
- registerItem: function BW_registerItem(item) {
- // this.items[id] is referenced by _makeMenu, so it needs to be defined
- // before _makeDOMElt is called.
- let props = { item: item };
- this.items[privateItem(item)._id] = props;
- props.domElt = this._makeDOMElt(item, false);
- props.overflowDOMElt = this._makeDOMElt(item, true);
- },
-
- // Removes the given item's DOM elements from the store.
- unregisterItem: function BW_unregisterItem(item) {
- delete this.items[privateItem(item)._id];
- },
-
- addTopLevelItem: function BW_addTopLevelItem(item) {
- this.contextMenuPopup.addItem(item);
- },
-
- removeTopLevelItem: function BW_removeTopLevelItem(item) {
- this.contextMenuPopup.removeItem(item);
- },
-
- addItemToMenu: function BW_addItemToMenu(item, parentMenu) {
- let { popup, overflowPopup } = this.items[privateItem(parentMenu)._id];
- popup.addItem(item);
- overflowPopup.addItem(item);
- },
-
- removeItemFromMenu: function BW_removeItemFromMenu(item, parentMenu) {
- let { popup, overflowPopup } = this.items[privateItem(parentMenu)._id];
- popup.removeItem(item);
- overflowPopup.removeItem(item);
- },
-
- setItemLabel: function BW_setItemLabel(item, label) {
- let privates = privateItem(item);
- let { domElt, overflowDOMElt } = this.items[privates._id];
- this._setDOMEltLabel(domElt, label);
- this._setDOMEltLabel(overflowDOMElt, label);
- if (!item.parentMenu && privates._hasFinishedInit)
- this.contextMenuPopup.itemLabelDidChange(item);
- },
-
- _setDOMEltLabel: function BW__setDOMEltLabel(domElt, label) {
- domElt.setAttribute("label", label);
- },
-
- setItemImage: function BW_setItemImage(item, imageURL) {
- let { domElt, overflowDOMElt } = this.items[privateItem(item)._id];
- let isMenu = item instanceof Menu;
- this._setDOMEltImage(domElt, imageURL, isMenu);
- this._setDOMEltImage(overflowDOMElt, imageURL, isMenu);
- },
-
- _setDOMEltImage: function BW__setDOMEltImage(domElt, imageURL, isMenu) {
- if (!imageURL) {
- domElt.removeAttribute("image");
- domElt.classList.remove("menu-iconic");
- domElt.classList.remove("menuitem-iconic");
- }
- else {
- domElt.setAttribute("image", imageURL);
- domElt.classList.add(isMenu ? "menu-iconic" : "menuitem-iconic");
- }
- },
-
- setItemData: function BW_setItemData(item, data) {
- let { domElt, overflowDOMElt } = this.items[privateItem(item)._id];
- this._setDOMEltData(domElt, data);
- this._setDOMEltData(overflowDOMElt, data);
- },
-
- _setDOMEltData: function BW__setDOMEltData(domElt, data) {
- domElt.setAttribute("value", data);
- },
-
- // The context specified for a top-level item may not match exactly the real
- // context that triggers it. For example, if the user context-clicks a span
- // inside an anchor, we want items that specify an anchor context to be
- // triggered, but the real context will indicate that the span was clicked,
- // not the anchor. Where the real context and an item's context conflict,
- // clients should be given the item's context, and this method can be used to
- // make such adjustments. Returns an adjusted popupNode.
- adjustPopupNode: function BW_adjustPopupNode(popupNode, topLevelItem) {
- for (let ctxt in topLevelItem.context) {
- if (typeof(ctxt.adjustPopupNode) === "function") {
- let ctxtNode = ctxt.adjustPopupNode(popupNode);
- if (ctxtNode) {
- popupNode = ctxtNode;
- break;
- }
- }
- }
- return popupNode;
- },
-
- // Returns true if all of item's contexts are current in the window.
- areAllContextsCurrent: function BW_areAllContextsCurrent(item, popupNode) {
- let win = popupNode.ownerDocument.defaultView;
- let worker = privateItem(item)._workerReg.find(win);
-
- // If the worker for the item-window pair doesn't exist (e.g., because the
- // page hasn't loaded yet), we can't really make a good decision since the
- // content script may have a context listener. So just don't show the item
- // at all.
- if (!worker)
- return false;
-
- // If there are no contexts given at all, the page context applies.
- let hasContentContext = worker.anyContextListeners();
- if (!hasContentContext && !item.context.length)
- return new PageContext().isCurrent(popupNode);
-
- // Otherwise, determine if all given contexts are current. Evaluate the
- // declarative contexts first and the worker's context listeners last. That
- // way the listener might be able to avoid some work.
- let curr = true;
- for (let ctxt in item.context) {
- curr = curr && ctxt.isCurrent(popupNode);
- if (!curr)
- return false;
- }
- return !hasContentContext || worker.isAnyContextCurrent(popupNode);
- },
-
- // Returns the node the user context-clicked to invoke the context menu.
- // For Gecko 2.0 and later, triggerNode is this node;
- // if it's falsey, document.popupNode is used.
- capturePopupNode: function BW_capturePopupNode(triggerNode) {
- var popupNode = triggerNode || this.doc.popupNode;
- if (!popupNode)
- console.warn("popupNode is null.");
- return popupNode;
- },
-
- destroy: function BW_destroy() {
- this.contextMenuPopup.destroy();
- delete this.window;
- delete this.doc;
- delete this.items;
- },
-
- // Emits a click event in the port of the content worker related to given top-
- // level item and popupNode's content window. Listeners will be passed
- // popupNode and clickedItemData.
- fireClick: function BW_fireClick(topLevelItem, popupNode, clickedItemData) {
- let win = popupNode.ownerDocument.defaultView;
- let worker = privateItem(topLevelItem)._workerReg.find(win);
- if (worker)
- worker.fireClick(popupNode, clickedItemData);
- },
-
- _makeDOMElt: function BW__makeDOMElt(item, isInOverflowSubtree) {
- let elt = item instanceof Item ? this._makeMenuitem(item) :
- item instanceof Menu ? this._makeMenu(item, isInOverflowSubtree) :
- item instanceof Separator ? this._makeSeparator() :
- null;
- if (!elt)
- throw new Error("Internal error: can't make element, unknown item type");
-
- elt.id = domEltIDFromItemID(privateItem(item)._id, isInOverflowSubtree);
- elt.classList.add(ITEM_CLASS);
- return elt;
- },
-
- // Returns a new xul:menu representing the menu.
- _makeMenu: function BW__makeMenu(menu, isInOverflowSubtree) {
- let menuElt = this.doc.createElement("menu");
- this._setDOMEltLabel(menuElt, menu.label);
- if (menu.image)
- this._setDOMEltImage(menuElt, menu.image, true);
- let popupElt = this.doc.createElement("menupopup");
- menuElt.appendChild(popupElt);
-
- let popup = new Popup(popupElt, this, isInOverflowSubtree);
- let props = this.items[privateItem(menu)._id];
- if (isInOverflowSubtree)
- props.overflowPopup = popup;
- else
- props.popup = popup;
-
- return menuElt;
- },
-
- // Returns a new xul:menuitem representing the item.
- _makeMenuitem: function BW__makeMenuitem(item) {
- let elt = this.doc.createElement("menuitem");
- this._setDOMEltLabel(elt, item.label);
- if (item.image)
- this._setDOMEltImage(elt, item.image, false);
- if (item.data)
- this._setDOMEltData(elt, item.data);
- return elt;
- },
-
- // Returns a new xul:menuseparator.
- _makeSeparator: function BW__makeSeparator() {
- return this.doc.createElement("menuseparator");
- }
-};
-
-
-// Responsible for adding DOM elements to and removing them from poupDOMElt.
-function Popup(popupDOMElt, browserWin, isInOverflowSubtree) {
- this.popupDOMElt = popupDOMElt;
- this.browserWin = browserWin;
- this.isInOverflowSubtree = isInOverflowSubtree;
-}
-
-Popup.prototype = {
-
- addItem: function Popup_addItem(item) {
- let props = this.browserWin.items[privateItem(item)._id];
- let elt = this.isInOverflowSubtree ? props.overflowDOMElt : props.domElt;
- this.popupDOMElt.appendChild(elt);
- },
-
- removeItem: function Popup_removeItem(item) {
- let props = this.browserWin.items[privateItem(item)._id];
- let elt = this.isInOverflowSubtree ? props.overflowDOMElt : props.domElt;
- this.popupDOMElt.removeChild(elt);
- }
-};
-
-
-// Represents a browser window's context menu popup. Responsible for hiding and
-// showing items according to the browser window's current context and for
-// handling item clicks.
-function ContextMenuPopup(popupDOMElt, browserWin) {
- this.popupDOMElt = popupDOMElt;
- this.browserWin = browserWin;
- this.doc = popupDOMElt.ownerDocument;
-
- // item ID => item
- // Calling this variable "topLevelItems" is redundant, since Popup and
- // ContextMenuPopup are only responsible for their child items, not all their
- // descendant items. But calling it "items" might encourage one to believe
- // otherwise, so topLevelItems it is.
- this.topLevelItems = {};
-
- popupDOMElt.addEventListener("popupshowing", this, false);
- popupDOMElt.addEventListener("command", this, false);
-}
-
-ContextMenuPopup.prototype = {
-
- addItem: function CMP_addItem(item) {
- this._ensureStaticEltsExist();
- let itemID = privateItem(item)._id;
- this.topLevelItems[itemID] = item;
- let props = this.browserWin.items[itemID];
- props.domElt.classList.add(TOPLEVEL_ITEM_CLASS);
- props.overflowDOMElt.classList.add(OVERFLOW_ITEM_CLASS);
- this._insertItemInSortedOrder(item);
- },
-
- removeItem: function CMP_removeItem(item) {
- let itemID = privateItem(item)._id;
- delete this.topLevelItems[itemID];
- let { domElt, overflowDOMElt } = this.browserWin.items[itemID];
- domElt.classList.remove(TOPLEVEL_ITEM_CLASS);
- overflowDOMElt.classList.remove(OVERFLOW_ITEM_CLASS);
- this.popupDOMElt.removeChild(domElt);
- this._overflowPopup.removeChild(overflowDOMElt);
- },
-
- // Call this after the item's label changes. This re-inserts the item into
- // the popup so that it remains in sorted order.
- itemLabelDidChange: function CMP_itemLabelDidChange(item) {
- let itemID = privateItem(item)._id;
- let { domElt, overflowDOMElt } = this.browserWin.items[itemID];
- this.popupDOMElt.removeChild(domElt);
- this._overflowPopup.removeChild(overflowDOMElt);
- this._insertItemInSortedOrder(item);
- },
-
- destroy: function CMP_destroy() {
- // If there are no more items from any instance of the module, remove the
- // separator and overflow submenu, if they exist.
- let elts = this._topLevelElts;
- if (!elts.length) {
- let submenu = this._overflowMenu;
- if (submenu)
- this.popupDOMElt.removeChild(submenu);
-
- let sep = this._separator;
- if (sep)
- this.popupDOMElt.removeChild(sep);
- }
-
- this.popupDOMElt.removeEventListener("popupshowing", this, false);
- this.popupDOMElt.removeEventListener("command", this, false);
- },
-
- handleEvent: function CMP_handleEvent(event) {
- try {
- if (event.type === "command")
- this._handleClick(event.target);
- else if (event.type === "popupshowing" &&
- event.target === this.popupDOMElt)
- this._handlePopupShowing();
- }
- catch (err) {
- console.exception(err);
- }
- },
-
- // command events bubble to the context menu's top-level xul:menupopup and are
- // caught here.
- _handleClick: function CMP__handleClick(clickedDOMElt) {
- if (!clickedDOMElt.classList.contains(ITEM_CLASS))
- return;
- let itemID = itemIDFromDOMEltID(clickedDOMElt.id);
- if (itemID < 0)
- return;
- let { item, domElt, overflowDOMElt } = this.browserWin.items[itemID];
-
- // Bail if the DOM element was not created by this module instance. In
- // real-world add-ons, the itemID < 0 check above is sufficient, but for the
- // unit test the JID never changes, making this necessary.
- if (clickedDOMElt != domElt && clickedDOMElt != overflowDOMElt)
- return;
-
- let topLevelItem = privateItem(item)._topLevelItem;
- let popupNode = this.browserWin.adjustPopupNode(this._getPopupNode(),
- topLevelItem);
- this.browserWin.fireClick(topLevelItem, popupNode, item.data);
- },
-
- _getPopupNode: function CMP__getPopupNode() {
- // popupDOMElt.triggerNode was added in Gecko 2.0 by bug 383930. The || is
- // to avoid a Spidermonkey strict warning on earlier versions.
- let triggerNode = this.popupDOMElt.triggerNode || undefined;
- return this.browserWin.capturePopupNode(triggerNode);
- },
-
- // popupshowing is used to show top-level items that match the browser
- // window's current context and hide items that don't. Each module instance
- // is responsible for showing and hiding the items it owns.
- _handlePopupShowing: function CMP__handlePopupShowing() {
-
- // If there are items queued up to finish initializing, let them go first.
- // Otherwise the overflow submenu and menu separator may end up in an
- // inappropriate state when those items are later added to the menu.
- if (numItemsWithUnfinishedInit) {
- const self = this;
- timer.setTimeout(function popupShowingTryAgain() {
- self._handlePopupShowing();
- }, 0);
- return;
- }
-
- let popupNode = this._getPopupNode();
- // Show and hide items. Set a "jetpackContextCurrent" property on the
- // DOM elements to signal which of our items match the current context.
- for (let itemID in this.topLevelItems) {
- let item = this.topLevelItems[itemID]
- let areContextsCurr =
- this.browserWin.areAllContextsCurrent(item, popupNode);
-
- // Change the item's label if the return value was a string.
- if (typeof(areContextsCurr) === "string") {
- item.label = areContextsCurr;
- areContextsCurr = true;
- }
-
- let { domElt, overflowDOMElt } = this.browserWin.items[itemID];
- domElt.jetpackContextCurrent = areContextsCurr;
- domElt.hidden = !areContextsCurr;
- overflowDOMElt.jetpackContextCurrent = areContextsCurr;
- overflowDOMElt.hidden = !areContextsCurr;
- }
-
- // Get the total number of items that match the current context. It's a
- // little tricky: There may be other instances of this module loaded,
- // each hiding and showing their items. So we can't base this number on
- // only our items, or on the hidden state of items. That's why we set
- // the jetpackContextCurrent property above. The last instance to run
- // will leave the menupopup in the correct state.
- let elts = this._topLevelElts;
- let numShown = Array.reduce(elts, function (total, elt) {
- return total + (elt.jetpackContextCurrent ? 1 : 0);
- }, 0);
-
- // If too many items are shown, show the submenu and hide the top-level
- // items. Otherwise, hide the submenu and show the top-level items.
- let overflow = numShown > this._overflowThreshold;
- if (overflow)
- Array.forEach(elts, function (e) e.hidden = true);
-
- let submenu = this._overflowMenu;
- if (submenu)
- submenu.hidden = !overflow;
-
- // If no items are shown, hide the menu separator.
- let sep = this._separator;
- if (sep)
- sep.hidden = numShown === 0;
- },
-
- // Adds the menu separator and overflow submenu if they don't exist.
- _ensureStaticEltsExist: function CMP__ensureStaticEltsExist() {
- let sep = this._separator;
- if (!sep) {
- sep = this._makeSeparator();
- this.popupDOMElt.appendChild(sep);
- }
-
- let submenu = this._overflowMenu;
- if (!submenu) {
- submenu = this._makeOverflowMenu();
- submenu.hidden = true;
- this.popupDOMElt.insertBefore(submenu, sep.nextSibling);
- }
- },
-
- // Inserts the given item's DOM element into the popup in sorted order.
- _insertItemInSortedOrder: function CMP__insertItemInSortedOrder(item) {
- let props = this.browserWin.items[privateItem(item)._id];
- this.popupDOMElt.insertBefore(
- props.domElt, insertionPoint(item.label, this._topLevelElts));
- this._overflowPopup.insertBefore(
- props.overflowDOMElt, insertionPoint(item.label, this._overflowElts));
- },
-
- // Creates and returns the xul:menu that's shown when too many items are added
- // to the popup.
- _makeOverflowMenu: function CMP__makeOverflowMenu() {
- let submenu = this.doc.createElement("menu");
- submenu.id = OVERFLOW_MENU_ID;
- submenu.setAttribute("label", OVERFLOW_MENU_LABEL);
- let popup = this.doc.createElement("menupopup");
- popup.id = OVERFLOW_POPUP_ID;
- submenu.appendChild(popup);
- return submenu;
- },
-
- // Creates and returns the xul:menuseparator that separates the standard
- // context menu items from our items.
- _makeSeparator: function CMP__makeSeparator() {
- let elt = this.doc.createElement("menuseparator");
- elt.id = SEPARATOR_ID;
- return elt;
- },
-
- // Returns the item elements contained in the overflow menu, a NodeList.
- get _overflowElts() {
- return this._overflowPopup.getElementsByClassName(OVERFLOW_ITEM_CLASS);
- },
-
- // Returns the overflow xul:menu.
- get _overflowMenu() {
- return this.doc.getElementById(OVERFLOW_MENU_ID);
- },
-
- // Returns the overflow xul:menupopup.
- get _overflowPopup() {
- return this.doc.getElementById(OVERFLOW_POPUP_ID);
- },
-
- // Returns the OVERFLOW_THRESH_PREF pref value if it exists or
- // OVERFLOW_THRESH_DEFAULT if it doesn't.
- get _overflowThreshold() {
- let prefs = require("./preferences/service");
- return prefs.get(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
- },
-
- // Returns the xul:menuseparator.
- get _separator() {
- return this.doc.getElementById(SEPARATOR_ID);
- },
-
- // Returns the item elements contained in the top-level menu, a NodeList.
- get _topLevelElts() {
- return this.popupDOMElt.getElementsByClassName(TOPLEVEL_ITEM_CLASS);
- }
-};
-
-
-// Init the browserManager only after setting prototypes and such above, because
-// it will cause browserManager.onTrack to be called immediately if there are
-// open windows.
-browserManager.init();
diff --git a/tools/addon-sdk-1.12/lib/sdk/core/heritage.js b/tools/addon-sdk-1.12/lib/sdk/core/heritage.js
deleted file mode 100644
index 1c62e6c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/core/heritage.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 expandtab */
-/* 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"
-};
-
-var getPrototypeOf = Object.getPrototypeOf;
-var getNames = Object.getOwnPropertyNames;
-var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
-var create = Object.create;
-var freeze = Object.freeze;
-var unbind = Function.call.bind(Function.bind, Function.call);
-
-// This shortcut makes sure that we do perform desired operations, even if
-// associated methods have being overridden on the used object.
-var owns = unbind(Object.prototype.hasOwnProperty);
-var apply = unbind(Function.prototype.apply);
-var slice = Array.slice || unbind(Array.prototype.slice);
-var reduce = Array.reduce || unbind(Array.prototype.reduce);
-var map = Array.map || unbind(Array.prototype.map);
-var concat = Array.concat || unbind(Array.prototype.concat);
-
-// Utility function to get own properties descriptor map.
-function getOwnPropertyDescriptors(object) {
- return reduce(getNames(object), function(descriptor, name) {
- descriptor[name] = getOwnPropertyDescriptor(object, name);
- return descriptor;
- }, {});
-}
-
-/**
- * Takes `source` object as an argument and returns identical object
- * with the difference that all own properties will be non-enumerable
- */
-function obscure(source) {
- var descriptor = reduce(getNames(source), function(descriptor, name) {
- var property = getOwnPropertyDescriptor(source, name);
- property.enumerable = false;
- descriptor[name] = property;
- return descriptor;
- }, {});
- return create(getPrototypeOf(source), descriptor);
-}
-exports.obscure = obscure;
-
-/**
- * Takes arbitrary number of source objects and returns fresh one, that
- * inherits from the same prototype as a first argument and implements all
- * own properties of all argument objects. If two or more argument objects
- * have own properties with the same name, the property is overridden, with
- * precedence from right to left, implying, that properties of the object on
- * the left are overridden by a same named property of the object on the right.
- */
-var mix = function(source) {
- var descriptor = reduce(slice(arguments), function(descriptor, source) {
- return reduce(getNames(source), function(descriptor, name) {
- descriptor[name] = getOwnPropertyDescriptor(source, name);
- return descriptor;
- }, descriptor);
- }, {});
-
- return create(getPrototypeOf(source), descriptor);
-};
-exports.mix = mix;
-
-/**
- * Returns a frozen object with that inherits from the given `prototype` and
- * implements all own properties of the given `properties` object.
- */
-function extend(prototype, properties) {
- return freeze(create(prototype, getOwnPropertyDescriptors(properties)));
-}
-exports.extend = extend;
-
-/**
- * Returns a constructor function with a proper `prototype` setup. Returned
- * constructor's `prototype` inherits from a given `options.extends` or
- * `Class.prototype` if omitted and implements all the properties of the
- * given `option`. If `options.implemens` array is passed, it's elements
- * will be mixed into prototype as well. Also, `options.extends` can be
- * a function or a prototype. If function than it's prototype is used as
- * an ancestor of the prototype, if it's an object that it's used directly.
- * Also `options.implements` may contain functions or objects, in case of
- * functions their prototypes are used for mixing.
- */
-var Class = new function() {
- function prototypeOf(input) {
- return typeof(input) === 'function' ? input.prototype : input;
- }
- var none = freeze([]);
-
- return function Class(options) {
- // Create descriptor with normalized `options.extends` and
- // `options.implements`.
- var descriptor = {
- // Normalize extends property of `options.extends` to a prototype object
- // in case it's constructor. If property is missing that fallback to
- // `Type.prototype`.
- extends: owns(options, 'extends') ?
- prototypeOf(options.extends) : Class.prototype,
- // Normalize `options.implements` to make sure that it's array of
- // prototype objects instead of constructor functions.
- implements: owns(options, 'implements') ?
- freeze(map(options.implements, prototypeOf)) : none
- };
-
- // Create array of property descriptors who's properties will be defined
- // on the resulting prototype. Note: Using reflection `concat` instead of
- // method as it may be overridden.
- var descriptors = concat(descriptor.implements, options, descriptor);
- // Create `prototype` that inherits from given ancestor passed as
- // `options.extends`, falling back to `Type.prototype`, implementing all
- // properties of given `options.implements` and `options` itself.
- var prototype = extend(descriptor.extends, mix.apply(mix, descriptors));
-
- // Note: we use reflection `apply` in the constructor instead of method
- // call since later may be overridden.
- function constructor() {
- return apply(prototype.constructor, create(prototype), arguments);
- }
- constructor.prototype = prototype;
- return freeze(constructor);
- };
-}
-Class.prototype = extend(null, obscure({
- constructor: function constructor() {
- this.initialize.apply(this, arguments);
- return this;
- },
- initialize: function initialize() {
- // Do your initialization logic here
- },
- // Copy useful properties from `Object.prototype`.
- toString: Object.prototype.toString,
- toLocaleString: Object.prototype.toLocaleString,
- toSource: Object.prototype.toSource,
- valueOf: Object.prototype.valueOf,
- isPrototypeOf: Object.prototype.isPrototypeOf
-}));
-exports.Class = freeze(Class);
diff --git a/tools/addon-sdk-1.12/lib/sdk/core/namespace.js b/tools/addon-sdk-1.12/lib/sdk/core/namespace.js
deleted file mode 100644
index 3ceb73b..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/core/namespace.js
+++ /dev/null
@@ -1,43 +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 create = Object.create;
-const prototypeOf = Object.getPrototypeOf;
-
-/**
- * Returns a new namespace, function that may can be used to access an
- * namespaced object of the argument argument. Namespaced object are associated
- * with owner objects via weak references. Namespaced objects inherit from the
- * owners ancestor namespaced object. If owner's ancestor is `null` then
- * namespaced object inherits from given `prototype`. Namespaces can be used
- * to define internal APIs that can be shared via enclosing `namespace`
- * function.
- * @examples
- * const internals = ns();
- * internals(object).secret = secret;
- */
-function ns() {
- const map = new WeakMap();
- return function namespace(target) {
- if (!target) // If `target` is not an object return `target` itself.
- return target;
- // If target has no namespaced object yet, create one that inherits from
- // the target prototype's namespaced object.
- if (!map.has(target))
- map.set(target, create(namespace(prototypeOf(target) || null)));
-
- return map.get(target);
- };
-};
-
-// `Namespace` is a e4x function in the scope, so we export the function also as
-// `ns` as alias to avoid clashing.
-exports.ns = ns;
-exports.Namespace = ns;
diff --git a/tools/addon-sdk-1.12/lib/sdk/core/promise.js b/tools/addon-sdk-1.12/lib/sdk/core/promise.js
deleted file mode 100644
index 2506c80..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/core/promise.js
+++ /dev/null
@@ -1,230 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 expandtab */
-/*jshint asi: true undef: true es5: true node: true browser: true devel: true
- forin: true latedef: false */
-/*global define: true, Cu: true, __URI__: true */
-;(function(id, factory) { // Module boilerplate :(
- if (typeof(define) === 'function') { // RequireJS
- define(factory);
- } else if (typeof(require) === 'function') { // CommonJS
- factory.call(this, require, exports, module);
- } else if (~String(this).indexOf('BackstagePass')) { // JSM
- factory(function require(uri) {
- var imports = {};
- this['Components'].utils.import(uri, imports);
- return imports;
- }, this, { uri: __URI__, id: id });
- this.EXPORTED_SYMBOLS = Object.keys(this);
- } else { // Browser or alike
- var globals = this
- factory(function require(id) {
- return globals[id];
- }, (globals[id] = {}), { uri: document.location.href + '#' + id, id: id });
- }
-}).call(this, 'loader', function(require, exports, module) {
-
-'use strict';
-
-module.metadata = {
- "stability": "unstable"
-};
-
-function resolution(value) {
- /**
- Returns non-standard compliant (`then` does not returns a promise) promise
- that resolves to a given `value`. Used just internally only.
- **/
- return { then: function then(resolve) { resolve(value) } }
-}
-
-function rejection(reason) {
- /**
- Returns non-standard compliant promise (`then` does not returns a promise)
- that rejects with a given `reason`. This is used internally only.
- **/
- return { then: function then(resolve, reject) { reject(reason) } }
-}
-
-function attempt(f) {
- /**
- Returns wrapper function that delegates to `f`. If `f` throws then captures
- error and returns promise that rejects with a thrown error. Otherwise returns
- return value. (Internal utility)
- **/
- return function effort(options) {
- try { return f(options) }
- catch(error) { return rejection(error) }
- }
-}
-
-function isPromise(value) {
- /**
- Returns true if given `value` is promise. Value is assumed to be promise if
- it implements `then` method.
- **/
- return value && typeof(value.then) === 'function'
-}
-
-function defer(prototype) {
- /**
- Returns object containing following properties:
- - `promise` Eventual value representation implementing CommonJS [Promises/A]
- (http://wiki.commonjs.org/wiki/Promises/A) API.
- - `resolve` Single shot function that resolves returned `promise` with a given
- `value` argument.
- - `reject` Single shot function that rejects returned `promise` with a given
- `reason` argument.
-
- Given `prototype` argument is used as a prototype of the returned `promise`
- allowing one to implement additional API. If prototype is not passed then
- it falls back to `Object.prototype`.
-
- ## Examples
-
- // Simple usage.
- var deferred = defer()
- deferred.promise.then(console.log, console.error)
- deferred.resolve(value)
-
- // Advanced usage
- var prototype = {
- get: function get(name) {
- return this.then(function(value) {
- return value[name];
- })
- }
- }
-
- var foo = defer(prototype)
- deferred.promise.get('name').then(console.log)
- deferred.resolve({ name: 'Foo' })
- //=> 'Foo'
- */
- var pending = [], result
- prototype = (prototype || prototype === null) ? prototype : Object.prototype
-
- // Create an object implementing promise API.
- var promise = Object.create(prototype, {
- then: { value: function then(resolve, reject) {
- // create a new deferred using a same `prototype`.
- var deferred = defer(prototype)
- // If `resolve / reject` callbacks are not provided.
- resolve = resolve ? attempt(resolve) : resolution
- reject = reject ? attempt(reject) : rejection
-
- // Create a listeners for a enclosed promise resolution / rejection that
- // delegate to an actual callbacks and resolve / reject returned promise.
- function resolved(value) { deferred.resolve(resolve(value)) }
- function rejected(reason) { deferred.resolve(reject(reason)) }
-
- // If promise is pending register listeners. Otherwise forward them to
- // resulting resolution.
- if (pending) pending.push([ resolved, rejected ])
- else result.then(resolved, rejected)
-
- return deferred.promise
- }}
- })
-
- var deferred = {
- promise: promise,
- resolve: function resolve(value) {
- /**
- Resolves associated `promise` to a given `value`, unless it's already
- resolved or rejected.
- **/
- if (pending) {
- // store resolution `value` as a promise (`value` itself may be a
- // promise), so that all subsequent listeners can be forwarded to it,
- // which either resolves immediately or forwards if `value` is
- // a promise.
- result = isPromise(value) ? value : resolution(value)
- // forward all pending observers.
- while (pending.length) result.then.apply(result, pending.shift())
- // mark promise as resolved.
- pending = null
- }
- },
- reject: function reject(reason) {
- /**
- Rejects associated `promise` with a given `reason`, unless it's already
- resolved / rejected.
- **/
- deferred.resolve(rejection(reason))
- }
- }
-
- return deferred
-}
-exports.defer = defer
-
-function resolve(value, prototype) {
- /**
- Returns a promise resolved to a given `value`. Optionally second `prototype`
- arguments my be provided to be used as a prototype for a returned promise.
- **/
- var deferred = defer(prototype)
- deferred.resolve(value)
- return deferred.promise
-}
-exports.resolve = resolve
-
-function reject(reason, prototype) {
- /**
- Returns a promise that is rejected with a given `reason`. Optionally second
- `prototype` arguments my be provided to be used as a prototype for a returned
- promise.
- **/
- var deferred = defer(prototype)
- deferred.reject(reason)
- return deferred.promise
-}
-exports.reject = reject
-
-var promised = (function() {
- // Note: Define shortcuts and utility functions here in order to avoid
- // slower property accesses and unnecessary closure creations on each
- // call of this popular function.
-
- var call = Function.call
- var concat = Array.prototype.concat
-
- // Utility function that does following:
- // execute([ f, self, args...]) => f.apply(self, args)
- function execute(args) { return call.apply(call, args) }
-
- // Utility function that takes promise of `a` array and maybe promise `b`
- // as arguments and returns promise for `a.concat(b)`.
- function promisedConcat(promises, unknown) {
- return promises.then(function(values) {
- return resolve(unknown).then(function(value) {
- return values.concat([ value ])
- })
- })
- }
-
- return function promised(f, prototype) {
- /**
- Returns a wrapped `f`, which when called returns a promise that resolves to
- `f(...)` passing all the given arguments to it, which by the way may be
- promises. Optionally second `prototype` argument may be provided to be used
- a prototype for a returned promise.
-
- ## Example
-
- var promise = promised(Array)(1, promise(2), promise(3))
- promise.then(console.log) // => [ 1, 2, 3 ]
- **/
-
- return function promised() {
- // create array of [ f, this, args... ]
- return concat.apply([ f, this ], arguments).
- // reduce it via `promisedConcat` to get promised array of fulfillments
- reduce(promisedConcat, resolve([], prototype)).
- // finally map that to promise of `f.apply(this, args...)`
- then(execute)
- }
- }
-})()
-exports.promised = promised
-
-})
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/api-utils.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/api-utils.js
deleted file mode 100644
index 521ad6e..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/api-utils.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "deprecated"
-};
-
-const memory = require("./memory");
-// The possible return values of getTypeOf.
-const VALID_TYPES = [
- "array",
- "boolean",
- "function",
- "null",
- "number",
- "object",
- "string",
- "undefined",
-];
-
-/**
- * Returns a function C that creates instances of privateCtor. C may be called
- * with or without the new keyword. The prototype of each instance returned
- * from C is C.prototype, and C.prototype is an object whose prototype is
- * privateCtor.prototype. Instances returned from C will therefore be instances
- * of both C and privateCtor. Additionally, the constructor of each instance
- * returned from C is C.
- *
- * @param privateCtor
- * A constructor.
- * @return A function that makes new instances of privateCtor.
- */
-exports.publicConstructor = function publicConstructor(privateCtor) {
- function PublicCtor() {
- let obj = { constructor: PublicCtor, __proto__: PublicCtor.prototype };
- memory.track(obj, privateCtor.name);
- privateCtor.apply(obj, arguments);
- return obj;
- }
- PublicCtor.prototype = { __proto__: privateCtor.prototype };
- return PublicCtor;
-};
-
-/**
- * Returns a validated options dictionary given some requirements. If any of
- * the requirements are not met, an exception is thrown.
- *
- * @param options
- * An object, the options dictionary to validate. It's not modified.
- * If it's null or otherwise falsey, an empty object is assumed.
- * @param requirements
- * An object whose keys are the expected keys in options. Any key in
- * options that is not present in requirements is ignored. Each value
- * in requirements is itself an object describing the requirements of
- * its key. There are four optional keys in this object:
- * map: A function that's passed the value of the key in options.
- * map's return value is taken as the key's value in the final
- * validated options, is, and ok. If map throws an exception
- * it's caught and discarded, and the key's value is its value in
- * options.
- * is: An array containing any number of the typeof type names. If
- * the key's value is none of these types, it fails validation.
- * Arrays and null are identified by the special type names
- * "array" and "null"; "object" will not match either. No type
- * coercion is done.
- * ok: A function that's passed the key's value. If it returns
- * false, the value fails validation.
- * msg: If the key's value fails validation, an exception is thrown.
- * This string will be used as its message. If undefined, a
- * generic message is used, unless is is defined, in which case
- * the message will state that the value needs to be one of the
- * given types.
- * @return An object whose keys are those keys in requirements that are also in
- * options and whose values are the corresponding return values of map
- * or the corresponding values in options. Note that any keys not
- * shared by both requirements and options are not in the returned
- * object.
- */
-exports.validateOptions = function validateOptions(options, requirements) {
- options = options || {};
- let validatedOptions = {};
- let mapThrew = false;
-
- for (let key in requirements) {
- let req = requirements[key];
- let [optsVal, keyInOpts] = (key in options) ?
- [options[key], true] :
- [undefined, false];
- if (req.map) {
- try {
- optsVal = req.map(optsVal);
- }
- catch (err) {
- mapThrew = true;
- }
- }
- if (req.is) {
- // Sanity check the caller's type names.
- req.is.forEach(function (typ) {
- if (VALID_TYPES.indexOf(typ) < 0) {
- let msg = 'Internal error: invalid requirement type "' + typ + '".';
- throw new Error(msg);
- }
- });
- if (req.is.indexOf(getTypeOf(optsVal)) < 0)
- throw requirementError(key, req);
- }
- if (req.ok && !req.ok(optsVal))
- throw requirementError(key, req);
-
- if (keyInOpts || (req.map && !mapThrew))
- validatedOptions[key] = optsVal;
- }
-
- return validatedOptions;
-};
-
-exports.addIterator = function addIterator(obj, keysValsGenerator) {
- obj.__iterator__ = function(keysOnly, keysVals) {
- let keysValsIterator = keysValsGenerator.call(this);
-
- // "for (.. in ..)" gets only keys, "for each (.. in ..)" gets values,
- // and "for (.. in Iterator(..))" gets [key, value] pairs.
- let index = keysOnly ? 0 : 1;
- while (true)
- yield keysVals ? keysValsIterator.next() : keysValsIterator.next()[index];
- };
-};
-
-// Similar to typeof, except arrays and null are identified by "array" and
-// "null", not "object".
-let getTypeOf = exports.getTypeOf = function getTypeOf(val) {
- let typ = typeof(val);
- if (typ === "object") {
- if (!val)
- return "null";
- if (Array.isArray(val))
- return "array";
- }
- return typ;
-}
-
-// Returns a new Error with a nice message.
-function requirementError(key, requirement) {
- let msg = requirement.msg;
- if (!msg) {
- msg = 'The option "' + key + '" ';
- msg += requirement.is ?
- "must be one of the following types: " + requirement.is.join(", ") :
- "is invalid.";
- }
- return new Error(msg);
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/app-strings.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/app-strings.js
deleted file mode 100644
index e09f79e..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/app-strings.js
+++ /dev/null
@@ -1,67 +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": "deprecated"
-};
-
-const {Cc,Ci} = require("chrome");
-const apiUtils = require("./api-utils");
-
-/**
- * A bundle of strings.
- *
- * @param url {String}
- * the URL of the string bundle
- */
-exports.StringBundle = apiUtils.publicConstructor(function StringBundle(url) {
-
- let stringBundle = Cc["@mozilla.org/intl/stringbundle;1"].
- getService(Ci.nsIStringBundleService).
- createBundle(url);
-
- this.__defineGetter__("url", function () url);
-
- /**
- * Get a string from the bundle.
- *
- * @param name {String}
- * the name of the string to get
- * @param args {array} [optional]
- * an array of arguments that replace occurrences of %S in the string
- *
- * @returns {String} the value of the string
- */
- this.get = function strings_get(name, args) {
- try {
- if (args)
- return stringBundle.formatStringFromName(name, args, args.length);
- else
- return stringBundle.GetStringFromName(name);
- }
- catch(ex) {
- // f.e. "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)
- // [nsIStringBundle.GetStringFromName]"
- throw new Error("String '" + name + "' could not be retrieved from the " +
- "bundle due to an unknown error (it doesn't exist?).");
- }
- },
-
- /**
- * Iterate the strings in the bundle.
- *
- */
- apiUtils.addIterator(
- this,
- function keysValsGen() {
- let enumerator = stringBundle.getSimpleEnumeration();
- while (enumerator.hasMoreElements()) {
- let elem = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
- yield [elem.key, elem.value];
- }
- }
- );
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/cortex.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/cortex.js
deleted file mode 100644
index 8eef91c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/cortex.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2
- * 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": "deprecated"
-};
-
-// `var` is being used in the module in order to make it reusable in
-// environments in which `let` and `const` is not yet supported.
-
-// Returns `object`'s property value, where `name` is a name of the property.
-function get(object, name) {
- return object[name];
-}
-
-// Assigns `value` to the `object`'s property, where `name` is the name of the
-// property.
-function set(object, name, value) {
- return object[name] = value;
-}
-
-/**
- * Given an `object` containing a property with the given `name`, create
- * a property descriptor that can be used to define alias/proxy properties
- * on other objects. A change in the value of an alias will propagate
- * to the aliased property and vice versa.
- */
-function createAliasProperty(object, name) {
- // Getting own property descriptor of an `object` for the given `name` as
- // we are going to create proxy analog.
- var property = Object.getOwnPropertyDescriptor(object, name);
- var descriptor = {
- configurable: property.configurable,
- enumerable: property.enumerable,
- alias: true
- };
-
- // If the original property has a getter and/or setter, bind a
- // corresponding getter/setter in the alias descriptor to the original
- // object, so the `this` object in the getter/setter is the original object
- // rather than the alias.
- if ("get" in property && property.get)
- descriptor.get = property.get.bind(object);
- if ("set" in property && property.set)
- descriptor.set = property.set.bind(object);
-
- // If original property was a value property.
- if ("value" in property) {
- // If original property is a method using it's `object` bounded copy.
- if (typeof property.value === "function") {
- descriptor.value = property.value.bind(object);
- // Also preserving writability of the original property.
- descriptor.writable = property.writable;
- }
-
- // If the original property was just a data property, we create proxy
- // accessors using our custom get/set functions to propagate changes to the
- // original `object` and vice versa.
- else {
- descriptor.get = get.bind(null, object, name);
- descriptor.set = set.bind(null, object, name);
- }
- }
- return descriptor;
-}
-
-// Defines property on `object` object with a name `alias` if given if not
-// defaults to `name` that represents an alias of `source[name]`. If aliased
-// property was an assessor or a method `this` pseudo-variable will be `source`
-// when invoked. If aliased property was a data property changes on any of the
-// aliases will propagate to the `source[name]` and also other way round.
-function defineAlias(source, target, name, alias) {
- return Object.defineProperty(target, alias || name,
- createAliasProperty(source, name));
-}
-
-/**
- * Function takes any `object` and returns a proxy for its own public
- * properties. By default properties are considered to be public if they don't
- * start with `"_"`, but default behavior can be overridden if needed, by
- * passing array of public property `names` as a second argument. By default
- * returned object will be direct decedent of the given `object`'s prototype,
- * but this can be overridden by passing third optional argument, that will be
- * used as `prototype` instead.
- * @param {Object} object
- * Object to create cortex for.
- * @param {String[]} [names]
- * Optional array of public property names.
- * @param {Object} [prototype]
- * Optional argument that will be used as `prototype` of the returned object,
- * if not provided `Object.getPrototypeOf(object)` is used instead.
- */
-exports.Cortex = function Cortex(object, names, prototype) {
- // Creating a cortex object from the given `prototype`, if one was not
- // provided then `prototype` of a given `object` is used. This allows
- // consumer to define expected behavior `instanceof`. In common case
- // `prototype` argument can be omitted to preserve same behavior of
- // `instanceof` as on original `object`.
- var cortex = Object.create(prototype || Object.getPrototypeOf(object));
- // Creating alias properties on the `cortex` object for all the own
- // properties of the original `object` that are contained in `names` array.
- // If `names` array is not provided then all the properties that don't
- // start with `"_"` are aliased.
- Object.getOwnPropertyNames(object).forEach(function (name) {
- if ((!names && "_" !== name.charAt(0)) || (names && ~names.indexOf(name)))
- defineAlias(object, cortex, name);
- });
- return cortex;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/errors.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/errors.js
deleted file mode 100644
index b640d05..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/errors.js
+++ /dev/null
@@ -1,64 +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": "deprecated"
-};
-
-function logToConsole(e) {
- console.exception(e);
-}
-
-var catchAndLog = exports.catchAndLog = function(callback,
- defaultResponse,
- logException) {
- if (!logException)
- logException = logToConsole;
-
- return function() {
- try {
- return callback.apply(this, arguments);
- } catch (e) {
- logException(e);
- return defaultResponse;
- }
- };
-};
-
-exports.catchAndLogProps = function catchAndLogProps(object,
- props,
- defaultResponse,
- logException) {
- if (typeof(props) == "string")
- props = [props];
- props.forEach(
- function(property) {
- object[property] = catchAndLog(object[property],
- defaultResponse,
- logException);
- });
-};
-
-/**
- * Catch and return an exception while calling the callback. If the callback
- * doesn't throw, return the return value of the callback in a way that makes it
- * possible to distinguish between a return value and an exception.
- *
- * This function is useful when you need to pass the result of a call across
- * a process boundary (across which exceptions don't propagate). It probably
- * doesn't need to be factored out into this module, since it is only used by
- * a single caller, but putting it here works around bug 625560.
- */
-exports.catchAndReturn = function(callback) {
- return function() {
- try {
- return { returnValue: callback.apply(this, arguments) };
- }
- catch (exception) {
- return { exception: exception };
- }
- };
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/events.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/events.js
deleted file mode 100644
index 0c28a1a..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/events.js
+++ /dev/null
@@ -1,182 +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": "deprecated"
-};
-
-const ERROR_TYPE = 'error',
- UNCAUGHT_ERROR = 'An error event was dispatched for which there was'
- + ' no listener.',
- BAD_LISTENER = 'The event listener must be a function.';
-/**
- * This object is used to create an `EventEmitter` that, useful for composing
- * objects that emit events. It implements an interface like `EventTarget` from
- * DOM Level 2, which is implemented by Node objects in implementations that
- * support the DOM Event Model.
- * @see http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget
- * @see http://nodejs.org/api.html#EventEmitter
- * @see http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/EventDispatcher.html
- */
-const eventEmitter = {
- /**
- * Registers an event `listener` that is called every time events of
- * specified `type` are emitted.
- * @param {String} type
- * The type of event.
- * @param {Function} listener
- * The listener function that processes the event.
- * @example
- * worker.on('message', function (data) {
- * console.log('data received: ' + data)
- * })
- */
- on: function on(type, listener) {
- if ('function' !== typeof listener)
- throw new Error(BAD_LISTENER);
- let listeners = this._listeners(type);
- if (0 > listeners.indexOf(listener))
- listeners.push(listener);
- // Use of `_public` is required by the legacy traits code that will go away
- // once bug-637633 is fixed.
- return this._public || this;
- },
-
- /**
- * Registers an event `listener` that is called once the next time an event
- * of the specified `type` is emitted.
- * @param {String} type
- * The type of the event.
- * @param {Function} listener
- * The listener function that processes the event.
- */
- once: function once(type, listener) {
- this.on(type, function selfRemovableListener() {
- this.removeListener(type, selfRemovableListener);
- listener.apply(this, arguments);
- });
- },
-
- /**
- * Unregister `listener` for the specified event type.
- * @param {String} type
- * The type of event.
- * @param {Function} listener
- * The listener function that processes the event.
- */
- removeListener: function removeListener(type, listener) {
- if ('function' !== typeof listener)
- throw new Error(BAD_LISTENER);
- let listeners = this._listeners(type),
- index = listeners.indexOf(listener);
- if (0 <= index)
- listeners.splice(index, 1);
- // Use of `_public` is required by the legacy traits code, that will go away
- // once bug-637633 is fixed.
- return this._public || this;
- },
-
- /**
- * Hash of listeners on this EventEmitter.
- */
- _events: null,
-
- /**
- * Returns an array of listeners for the specified event `type`. This array
- * can be manipulated, e.g. to remove listeners.
- * @param {String} type
- * The type of event.
- */
- _listeners: function listeners(type) {
- let events = this._events || (this._events = {});
- return events[type] || (events[type] = []);
- },
-
- /**
- * Execute each of the listeners in order with the supplied arguments.
- * Returns `true` if listener for this event was called, `false` if there are
- * no listeners for this event `type`.
- *
- * All the exceptions that are thrown by listeners during the emit
- * are caught and can be handled by listeners of 'error' event. Thrown
- * exceptions are passed as an argument to an 'error' event listener.
- * If no 'error' listener is registered exception will propagate to a
- * caller of this method.
- *
- * **It's recommended to have a default 'error' listener in all the complete
- * composition that in worst case may dump errors to the console.**
- *
- * @param {String} type
- * The type of event.
- * @params {Object|Number|String|Boolean}
- * Arguments that will be passed to listeners.
- * @returns {Boolean}
- */
- _emit: function _emit(type, event) {
- let args = Array.slice(arguments);
- // Use of `_public` is required by the legacy traits code that will go away
- // once bug-637633 is fixed.
- args.unshift(this._public || this);
- return this._emitOnObject.apply(this, args);
- },
-
- /**
- * A version of _emit that lets you specify the object on which listeners are
- * called. This is a hack that is sometimes necessary when such an object
- * (exports, for example) cannot be an EventEmitter for some reason, but other
- * object(s) managing events for the object are EventEmitters. Once bug
- * 577782 is fixed, this method shouldn't be necessary.
- *
- * @param {object} targetObj
- * The object on which listeners will be called.
- * @param {string} type
- * The event name.
- * @param {value} event
- * The first argument to pass to listeners.
- * @param {value} ...
- * More arguments to pass to listeners.
- * @returns {boolean}
- */
- _emitOnObject: function _emitOnObject(targetObj, type, event /* , ... */) {
- let listeners = this._listeners(type).slice(0);
- // If there is no 'error' event listener then throw.
- if (type === ERROR_TYPE && !listeners.length)
- console.exception(event);
- if (!listeners.length)
- return false;
- let params = Array.slice(arguments, 2);
- for each (let listener in listeners) {
- try {
- listener.apply(targetObj, params);
- } catch(e) {
- // Bug 726967: Ignore exceptions being throws while notifying the error
- // in order to avoid infinite loops.
- if (type !== ERROR_TYPE)
- this._emit(ERROR_TYPE, e);
- else
- console.exception("Exception in error event listener " + e);
- }
- }
- return true;
- },
-
- /**
- * Removes all the event listeners for the specified event `type`.
- * @param {String} type
- * The type of event.
- */
- _removeAllListeners: function _removeAllListeners(type) {
- if (typeof type == "undefined") {
- this._events = null;
- return this;
- }
-
- this._listeners(type).splice(0);
- return this;
- }
-};
-exports.EventEmitter = require("./traits").Trait.compose(eventEmitter);
-exports.EventEmitterTrait = require('./light-traits').Trait(eventEmitter);
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/events/assembler.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/events/assembler.js
deleted file mode 100644
index fcde1e3..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/events/assembler.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { Trait } = require("../light-traits");
-const { removeListener, on } = require("../../dom/events");
-
-/**
- * Trait may be used for building objects / composing traits that wish to handle
- * multiple dom events from multiple event targets in one place. Event targets
- * can be added / removed by calling `observe / ignore` methods. Composer should
- * provide array of event types it wishes to handle as property
- * `supportedEventsTypes` and function for handling all those events as
- * `handleEvent` property.
- */
-exports.DOMEventAssembler = Trait({
- /**
- * Function that is supposed to handle all the supported events (that are
- * present in the `supportedEventsTypes`) from all the observed
- * `eventTargets`.
- * @param {Event} event
- * Event being dispatched.
- */
- handleEvent: Trait.required,
- /**
- * Array of supported event names.
- * @type {String[]}
- */
- supportedEventsTypes: Trait.required,
- /**
- * Adds `eventTarget` to the list of observed `eventTarget`s. Listeners for
- * supported events will be registered on the given `eventTarget`.
- * @param {EventTarget} eventTarget
- */
- observe: function observe(eventTarget) {
- this.supportedEventsTypes.forEach(function(eventType) {
- on(eventTarget, eventType, this);
- }, this);
- },
- /**
- * Removes `eventTarget` from the list of observed `eventTarget`s. Listeners
- * for all supported events will be unregistered from the given `eventTarget`.
- * @param {EventTarget} eventTarget
- */
- ignore: function ignore(eventTarget) {
- this.supportedEventsTypes.forEach(function(eventType) {
- removeListener(eventTarget, eventType, this);
- }, this);
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/light-traits.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/light-traits.js
deleted file mode 100644
index b18dccb..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/light-traits.js
+++ /dev/null
@@ -1,600 +0,0 @@
-/* vim:ts=2:sts=2:sw=2:
- * 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": "deprecated"
-};
-
-// `var` is being used in the module in order to make it reusable in
-// environments in which `let` is not yet supported.
-
-// Shortcut to `Object.prototype.hasOwnProperty.call`.
-// owns(object, name) would be the same as
-// Object.prototype.hasOwnProperty.call(object, name);
-var owns = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
-
-/**
- * Whether or not given property descriptors are equivalent. They are
- * equivalent either if both are marked as 'conflict' or 'required' property
- * or if all the properties of descriptors are equal.
- * @param {Object} actual
- * @param {Object} expected
- */
-function equivalentDescriptors(actual, expected) {
- return (actual.conflict && expected.conflict) ||
- (actual.required && expected.required) ||
- equalDescriptors(actual, expected);
-}
-/**
- * Whether or not given property descriptors define equal properties.
- */
-function equalDescriptors(actual, expected) {
- return actual.get === expected.get &&
- actual.set === expected.set &&
- actual.value === expected.value &&
- !!actual.enumerable === !!expected.enumerable &&
- !!actual.configurable === !!expected.configurable &&
- !!actual.writable === !!expected.writable;
-}
-
-// Utilities that throwing exceptions for a properties that are marked
-// as "required" or "conflict" properties.
-function throwConflictPropertyError(name) {
- throw new Error("Remaining conflicting property: `" + name + "`");
-}
-function throwRequiredPropertyError(name) {
- throw new Error("Missing required property: `" + name + "`");
-}
-
-/**
- * Generates custom **required** property descriptor. Descriptor contains
- * non-standard property `required` that is equal to `true`.
- * @param {String} name
- * property name to generate descriptor for.
- * @returns {Object}
- * custom property descriptor
- */
-function RequiredPropertyDescriptor(name) {
- // Creating function by binding first argument to a property `name` on the
- // `throwConflictPropertyError` function. Created function is used as a
- // getter & setter of the created property descriptor. This way we ensure
- // that we throw exception late (on property access) if object with
- // `required` property was instantiated using built-in `Object.create`.
- var accessor = throwRequiredPropertyError.bind(null, name);
- return { get: accessor, set: accessor, required: true };
-}
-
-/**
- * Generates custom **conflicting** property descriptor. Descriptor contains
- * non-standard property `conflict` that is equal to `true`.
- * @param {String} name
- * property name to generate descriptor for.
- * @returns {Object}
- * custom property descriptor
- */
-function ConflictPropertyDescriptor(name) {
- // For details see `RequiredPropertyDescriptor` since idea is same.
- var accessor = throwConflictPropertyError.bind(null, name);
- return { get: accessor, set: accessor, conflict: true };
-}
-
-/**
- * Tests if property is marked as `required` property.
- */
-function isRequiredProperty(object, name) {
- return !!object[name].required;
-}
-
-/**
- * Tests if property is marked as `conflict` property.
- */
-function isConflictProperty(object, name) {
- return !!object[name].conflict;
-}
-
-/**
- * Function tests whether or not method of the `source` object with a given
- * `name` is inherited from `Object.prototype`.
- */
-function isBuiltInMethod(name, source) {
- var target = Object.prototype[name];
-
- // If methods are equal then we know it's `true`.
- return target == source ||
- // If `source` object comes form a different sandbox `==` will evaluate
- // to `false`, in that case we check if functions names and sources match.
- (String(target) === String(source) && target.name === source.name);
-}
-
-/**
- * Function overrides `toString` and `constructor` methods of a given `target`
- * object with a same-named methods of a given `source` if methods of `target`
- * object are inherited / copied from `Object.prototype`.
- * @see create
- */
-function overrideBuiltInMethods(target, source) {
- if (isBuiltInMethod("toString", target.toString)) {
- Object.defineProperty(target, "toString", {
- value: source.toString,
- configurable: true,
- enumerable: false
- });
- }
-
- if (isBuiltInMethod("constructor", target.constructor)) {
- Object.defineProperty(target, "constructor", {
- value: source.constructor,
- configurable: true,
- enumerable: false
- });
- }
-}
-
-/**
- * Composes new trait with the same own properties as the original trait,
- * except that all property names appearing in the first argument are replaced
- * by "required" property descriptors.
- * @param {String[]} keys
- * Array of strings property names.
- * @param {Object} trait
- * A trait some properties of which should be excluded.
- * @returns {Object}
- * @example
- * var newTrait = exclude(["name", ...], trait)
- */
-function exclude(names, trait) {
- var map = {};
-
- Object.keys(trait).forEach(function(name) {
-
- // If property is not excluded (the array of names does not contain it),
- // or it is a "required" property, copy it to the property descriptor `map`
- // that will be used for creation of resulting trait.
- if (!~names.indexOf(name) || isRequiredProperty(trait, name))
- map[name] = { value: trait[name], enumerable: true };
-
- // For all the `names` in the exclude name array we create required
- // property descriptors and copy them to the `map`.
- else
- map[name] = { value: RequiredPropertyDescriptor(name), enumerable: true };
- });
-
- return Object.create(Trait.prototype, map);
-}
-
-/**
- * Composes new instance of `Trait` with a properties of a given `trait`,
- * except that all properties whose name is an own property of `renames` will
- * be renamed to `renames[name]` and a `"required"` property for name will be
- * added instead.
- *
- * For each renamed property, a required property is generated. If
- * the `renames` map two properties to the same name, a conflict is generated.
- * If the `renames` map a property to an existing unrenamed property, a
- * conflict is generated.
- *
- * @param {Object} renames
- * An object whose own properties serve as a mapping from old names to new
- * names.
- * @param {Object} trait
- * A new trait with renamed properties.
- * @returns {Object}
- * @example
- *
- * // Return trait with `bar` property equal to `trait.foo` and with
- * // `foo` and `baz` "required" properties.
- * var renamedTrait = rename({ foo: "bar", baz: null }), trait);
- *
- * // t1 and t2 are equivalent traits
- * var t1 = rename({a: "b"}, t);
- * var t2 = compose(exclude(["a"], t), { a: { required: true }, b: t[a] });
- */
-function rename(renames, trait) {
- var map = {};
-
- // Loop over all the properties of the given `trait` and copy them to a
- // property descriptor `map` that will be used for the creation of the
- // resulting trait. Also, rename properties in the `map` as specified by
- // `renames`.
- Object.keys(trait).forEach(function(name) {
- var alias;
-
- // If the property is in the `renames` map, and it isn't a "required"
- // property (which should never need to be aliased because "required"
- // properties never conflict), then we must try to rename it.
- if (owns(renames, name) && !isRequiredProperty(trait, name)) {
- alias = renames[name];
-
- // If the `map` already has the `alias`, and it isn't a "required"
- // property, that means the `alias` conflicts with an existing name for a
- // provided trait (that can happen if >=2 properties are aliased to the
- // same name). In this case we mark it as a conflicting property.
- // Otherwise, everything is fine, and we copy property with an `alias`
- // name.
- if (owns(map, alias) && !map[alias].value.required) {
- map[alias] = {
- value: ConflictPropertyDescriptor(alias),
- enumerable: true
- };
- }
- else {
- map[alias] = {
- value: trait[name],
- enumerable: true
- };
- }
-
- // Regardless of whether or not the rename was successful, we check to
- // see if the original `name` exists in the map (such a property
- // could exist if previous another property was aliased to this `name`).
- // If it isn't, we mark it as "required", to make sure the caller
- // provides another value for the old name, which methods of the trait
- // might continue to reference.
- if (!owns(map, name)) {
- map[name] = {
- value: RequiredPropertyDescriptor(name),
- enumerable: true
- };
- }
- }
-
- // Otherwise, either the property isn't in the `renames` map (thus the
- // caller is not trying to rename it) or it is a "required" property.
- // Either way, we don't have to alias the property, we just have to copy it
- // to the map.
- else {
- // The property isn't in the map yet, so we copy it over.
- if (!owns(map, name)) {
- map[name] = { value: trait[name], enumerable: true };
- }
-
- // The property is already in the map (that means another property was
- // aliased with this `name`, which creates a conflict if the property is
- // not marked as "required"), so we have to mark it as a "conflict"
- // property.
- else if (!isRequiredProperty(trait, name)) {
- map[name] = {
- value: ConflictPropertyDescriptor(name),
- enumerable: true
- };
- }
- }
- });
- return Object.create(Trait.prototype, map);
-}
-
-/**
- * Composes new resolved trait, with all the same properties as the original
- * `trait`, except that all properties whose name is an own property of
- * `resolutions` will be renamed to `resolutions[name]`.
- *
- * If `resolutions[name]` is `null`, the value is mapped to a property
- * descriptor that is marked as a "required" property.
- */
-function resolve(resolutions, trait) {
- var renames = {};
- var exclusions = [];
-
- // Go through each mapping in `resolutions` object and distribute it either
- // to `renames` or `exclusions`.
- Object.keys(resolutions).forEach(function(name) {
-
- // If `resolutions[name]` is a truthy value then it's a mapping old -> new
- // so we copy it to `renames` map.
- if (resolutions[name])
- renames[name] = resolutions[name];
-
- // Otherwise it's not a mapping but an exclusion instead in which case we
- // add it to the `exclusions` array.
- else
- exclusions.push(name);
- });
-
- // First `exclude` **then** `rename` and order is important since
- // `exclude` and `rename` are not associative.
- return rename(renames, exclude(exclusions, trait));
-}
-
-/**
- * Create a Trait (a custom property descriptor map) that represents the given
- * `object`'s own properties. Property descriptor map is a "custom", because it
- * inherits from `Trait.prototype` and it's property descriptors may contain
- * two attributes that is not part of the ES5 specification:
- *
- * - "required" (this property must be provided by another trait
- * before an instance of this trait can be created)
- * - "conflict" (when the trait is composed with another trait,
- * a unique value for this property is provided by two or more traits)
- *
- * Data properties bound to the `Trait.required` singleton exported by
- * this module will be marked as "required" properties.
- *
- * @param {Object} object
- * Map of properties to compose trait from.
- * @returns {Trait}
- * Trait / Property descriptor map containing all the own properties of the
- * given argument.
- */
-function trait(object) {
- var map;
- var trait = object;
-
- if (!(object instanceof Trait)) {
- // If the passed `object` is not already an instance of `Trait`, we create
- // a property descriptor `map` containing descriptors for the own properties
- // of the given `object`. `map` is then used to create a `Trait` instance
- // after all properties are mapped. Note that we can't create a trait and
- // then just copy properties into it since that will fail for inherited
- // read-only properties.
- map = {};
-
- // Each own property of the given `object` is mapped to a data property
- // whose value is a property descriptor.
- Object.keys(object).forEach(function (name) {
-
- // If property of an `object` is equal to a `Trait.required`, it means
- // that it was marked as "required" property, in which case we map it
- // to "required" property.
- if (Trait.required ==
- Object.getOwnPropertyDescriptor(object, name).value) {
- map[name] = {
- value: RequiredPropertyDescriptor(name),
- enumerable: true
- };
- }
- // Otherwise property is mapped to it's property descriptor.
- else {
- map[name] = {
- value: Object.getOwnPropertyDescriptor(object, name),
- enumerable: true
- };
- }
- });
-
- trait = Object.create(Trait.prototype, map);
- }
- return trait;
-}
-
-/**
- * Compose a property descriptor map that inherits from `Trait.prototype` and
- * contains property descriptors for all the own properties of the passed
- * traits.
- *
- * If two or more traits have own properties with the same name, the returned
- * trait will contain a "conflict" property for that name. Composition is a
- * commutative and associative operation, and the order of its arguments is
- * irrelevant.
- */
-function compose(trait1, trait2/*, ...*/) {
- // Create a new property descriptor `map` to which all the own properties
- // of the passed traits are copied. This map will be used to create a `Trait`
- // instance that will be the result of this composition.
- var map = {};
-
- // Properties of each passed trait are copied to the composition.
- Array.prototype.forEach.call(arguments, function(trait) {
- // Copying each property of the given trait.
- Object.keys(trait).forEach(function(name) {
-
- // If `map` already owns a property with the `name` and it is not
- // marked "required".
- if (owns(map, name) && !map[name].value.required) {
-
- // If the source trait's property with the `name` is marked as
- // "required", we do nothing, as the requirement was already resolved
- // by a property in the `map` (because it already contains a
- // non-required property with that `name`). But if properties are just
- // different, we have a name clash and we substitute it with a property
- // that is marked "conflict".
- if (!isRequiredProperty(trait, name) &&
- !equivalentDescriptors(map[name].value, trait[name])
- ) {
- map[name] = {
- value: ConflictPropertyDescriptor(name),
- enumerable: true
- };
- }
- }
-
- // Otherwise, the `map` does not have an own property with the `name`, or
- // it is marked "required". Either way, the trait's property is copied to
- // the map (if the property of the `map` is marked "required", it is going
- // to be resolved by the property that is being copied).
- else {
- map[name] = { value: trait[name], enumerable: true };
- }
- });
- });
-
- return Object.create(Trait.prototype, map);
-}
-
-/**
- * `defineProperties` is like `Object.defineProperties`, except that it
- * ensures that:
- * - An exception is thrown if any property in a given `properties` map
- * is marked as "required" property and same named property is not
- * found in a given `prototype`.
- * - An exception is thrown if any property in a given `properties` map
- * is marked as "conflict" property.
- * @param {Object} object
- * Object to define properties on.
- * @param {Object} properties
- * Properties descriptor map.
- * @returns {Object}
- * `object` that was passed as a first argument.
- */
-function defineProperties(object, properties) {
-
- // Create a map into which we will copy each verified property from the given
- // `properties` description map. We use it to verify that none of the
- // provided properties is marked as a "conflict" property and that all
- // "required" properties are resolved by a property of an `object`, so we
- // can throw an exception before mutating object if that isn't the case.
- var verifiedProperties = {};
-
- // Coping each property from a given `properties` descriptor map to a
- // verified map of property descriptors.
- Object.keys(properties).forEach(function(name) {
-
- // If property is marked as "required" property and we don't have a same
- // named property in a given `object` we throw an exception. If `object`
- // has same named property just skip this property since required property
- // is was inherited and there for requirement was satisfied.
- if (isRequiredProperty(properties, name)) {
- if (!(name in object))
- throwRequiredPropertyError(name);
- }
-
- // If property is marked as "conflict" property we throw an exception.
- else if (isConflictProperty(properties, name)) {
- throwConflictPropertyError(name);
- }
-
- // If property is not marked neither as "required" nor "conflict" property
- // we copy it to verified properties map.
- else {
- verifiedProperties[name] = properties[name];
- }
- });
-
- // If no exceptions were thrown yet, we know that our verified property
- // descriptor map has no properties marked as "conflict" or "required",
- // so we just delegate to the built-in `Object.defineProperties`.
- return Object.defineProperties(object, verifiedProperties);
-}
-
-/**
- * `create` is like `Object.create`, except that it ensures that:
- * - An exception is thrown if any property in a given `properties` map
- * is marked as "required" property and same named property is not
- * found in a given `prototype`.
- * - An exception is thrown if any property in a given `properties` map
- * is marked as "conflict" property.
- * @param {Object} prototype
- * prototype of the composed object
- * @param {Object} properties
- * Properties descriptor map.
- * @returns {Object}
- * An object that inherits form a given `prototype` and implements all the
- * properties defined by a given `properties` descriptor map.
- */
-function create(prototype, properties) {
-
- // Creating an instance of the given `prototype`.
- var object = Object.create(prototype);
-
- // Overriding `toString`, `constructor` methods if they are just inherited
- // from `Object.prototype` with a same named methods of the `Trait.prototype`
- // that will have more relevant behavior.
- overrideBuiltInMethods(object, Trait.prototype);
-
- // Trying to define given `properties` on the `object`. We use our custom
- // `defineProperties` function instead of build-in `Object.defineProperties`
- // that behaves exactly the same, except that it will throw if any
- // property in the given `properties` descriptor is marked as "required" or
- // "conflict" property.
- return defineProperties(object, properties);
-}
-
-/**
- * Composes new trait. If two or more traits have own properties with the
- * same name, the new trait will contain a "conflict" property for that name.
- * "compose" is a commutative and associative operation, and the order of its
- * arguments is not significant.
- *
- * **Note:** Use `Trait.compose` instead of calling this function with more
- * than one argument. The multiple-argument functionality is strictly for
- * backward compatibility.
- *
- * @params {Object} trait
- * Takes traits as an arguments
- * @returns {Object}
- * New trait containing the combined own properties of all the traits.
- * @example
- * var newTrait = compose(trait_1, trait_2, ..., trait_N)
- */
-function Trait(trait1, trait2) {
-
- // If the function was called with one argument, the argument should be
- // an object whose properties are mapped to property descriptors on a new
- // instance of Trait, so we delegate to the trait function.
- // If the function was called with more than one argument, those arguments
- // should be instances of Trait or plain property descriptor maps
- // whose properties should be mixed into a new instance of Trait,
- // so we delegate to the compose function.
-
- return trait2 === undefined ? trait(trait1) : compose.apply(null, arguments);
-}
-
-Object.freeze(Object.defineProperties(Trait.prototype, {
- toString: {
- value: function toString() {
- return "[object " + this.constructor.name + "]";
- }
- },
-
- /**
- * `create` is like `Object.create`, except that it ensures that:
- * - An exception is thrown if this trait defines a property that is
- * marked as required property and same named property is not
- * found in a given `prototype`.
- * - An exception is thrown if this trait contains property that is
- * marked as "conflict" property.
- * @param {Object}
- * prototype of the compared object
- * @returns {Object}
- * An object with all of the properties described by the trait.
- */
- create: {
- value: function createTrait(prototype) {
- return create(undefined === prototype ? Object.prototype : prototype,
- this);
- },
- enumerable: true
- },
-
- /**
- * Composes a new resolved trait, with all the same properties as the original
- * trait, except that all properties whose name is an own property of
- * `resolutions` will be renamed to the value of `resolutions[name]`. If
- * `resolutions[name]` is `null`, the property is marked as "required".
- * @param {Object} resolutions
- * An object whose own properties serve as a mapping from old names to new
- * names, or to `null` if the property should be excluded.
- * @returns {Object}
- * New trait with the same own properties as the original trait but renamed.
- */
- resolve: {
- value: function resolveTrait(resolutions) {
- return resolve(resolutions, this);
- },
- enumerable: true
- }
-}));
-
-/**
- * @see compose
- */
-Trait.compose = Object.freeze(compose);
-Object.freeze(compose.prototype);
-
-/**
- * Constant singleton, representing placeholder for required properties.
- * @type {Object}
- */
-Trait.required = Object.freeze(Object.create(Object.prototype, {
- toString: {
- value: Object.freeze(function toString() {
- return "<Trait.required>";
- })
- }
-}));
-Object.freeze(Trait.required.toString.prototype);
-
-exports.Trait = Object.freeze(Trait);
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/list.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/list.js
deleted file mode 100644
index 5de69e7..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/list.js
+++ /dev/null
@@ -1,118 +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": "experimental"
-};
-
-const { Trait } = require('../deprecated/traits');
-
-/**
- * @see https://jetpack.mozillalabs.com/sdk/latest/docs/#module/api-utils/list
- */
-const Iterable = Trait.compose({
- /**
- * Hash map of key-values to iterate over.
- * Note: That this property can be a getter if you need dynamic behavior.
- * @type {Object}
- */
- _keyValueMap: Trait.required,
- /**
- * Custom iterator providing `Iterable`s enumeration behavior.
- * @param {Boolean} onKeys
- */
- __iterator__: function __iterator__(onKeys, onKeyValue) {
- let map = this._keyValueMap;
- for (let key in map)
- yield onKeyValue ? [key, map[key]] : onKeys ? key : map[key];
- }
-});
-exports.Iterable = Iterable;
-
-/**
- * An ordered collection (also known as a sequence) disallowing duplicate
- * elements. List is composed out of `Iterable` there for it provides custom
- * enumeration behavior that is similar to array (enumerates only on the
- * elements of the list). List is a base trait and is meant to be a part of
- * composition, since all of it's API is private except length property.
- */
-const List = Trait.resolve({ toString: null }).compose({
- _keyValueMap: null,
- /**
- * List constructor can take any number of element to populate itself.
- * @params {Object|String|Number} element
- * @example
- * List(1,2,3).length == 3 // true
- */
- constructor: function List() {
- this._keyValueMap = [];
- for (let i = 0, ii = arguments.length; i < ii; i++)
- this._add(arguments[i]);
- },
- /**
- * Number of elements in this list.
- * @type {Number}
- */
- get length() this._keyValueMap.length,
- /**
- * Returns a string representing this list.
- * @returns {String}
- */
- toString: function toString() 'List(' + this._keyValueMap + ')',
- /**
- * Returns `true` if this list contains the specified `element`.
- * @param {Object|Number|String} element
- * @returns {Boolean}
- */
- _has: function _has(element) 0 <= this._keyValueMap.indexOf(element),
- /**
- * Appends the specified `element` to the end of this list, if it doesn't
- * contains it. Ignores the call if `element` is already contained.
- * @param {Object|Number|String} element
- */
- _add: function _add(element) {
- let list = this._keyValueMap,
- index = list.indexOf(element);
- if (0 > index)
- list.push(this._public[list.length] = element);
- },
- /**
- * Removes specified `element` from this list, if it contains it.
- * Ignores the call if `element` is not contained.
- * @param {Object|Number|String} element
- */
- _remove: function _remove(element) {
- let list = this._keyValueMap,
- index = list.indexOf(element);
- if (0 <= index) {
- delete this._public[list.length - 1];
- list.splice(index, 1);
- for (let length = list.length; index < length; index++)
- this._public[index] = list[index];
- }
- },
- /**
- * Removes all of the elements from this list.
- */
- _clear: function _clear() {
- for (let i = 0, ii = this._keyValueMap.length; i < ii; i ++)
- delete this._public[i];
- this._keyValueMap.splice(0);
- },
- /**
- * Custom iterator providing `List`s enumeration behavior.
- * We cant reuse `_iterator` that is defined by `Iterable` since it provides
- * iteration in an arbitrary order.
- * @see https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in
- * @param {Boolean} onKeys
- */
- __iterator__: function __iterator__(onKeys, onKeyValue) {
- let array = this._keyValueMap.slice(0),
- i = -1;
- for each(let element in array)
- yield onKeyValue ? [++i, element] : onKeys ? ++i : element;
- }
-});
-exports.List = List;
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/memory.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/memory.js
deleted file mode 100644
index 70bcffc..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/memory.js
+++ /dev/null
@@ -1,118 +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": "deprecated"
-};
-
-const {Cc,Ci,Cu,components} = require("chrome");
-var trackedObjects = {};
-
-var Compacter = {
- INTERVAL: 5000,
- notify: function(timer) {
- var newTrackedObjects = {};
- for (let name in trackedObjects) {
- var oldBin = trackedObjects[name];
- var newBin = [];
- var strongRefs = [];
- for (var i = 0; i < oldBin.length; i++) {
- var strongRef = oldBin[i].weakref.get();
- if (strongRef && strongRefs.indexOf(strongRef) == -1) {
- strongRefs.push(strongRef);
- newBin.push(oldBin[i]);
- }
- }
- if (newBin.length)
- newTrackedObjects[name] = newBin;
- }
- trackedObjects = newTrackedObjects;
- }
-};
-
-var timer = Cc["@mozilla.org/timer;1"]
- .createInstance(Ci.nsITimer);
-
-timer.initWithCallback(Compacter,
- Compacter.INTERVAL,
- Ci.nsITimer.TYPE_REPEATING_SLACK);
-
-var track = exports.track = function track(object, bin, stackFrameNumber) {
- var frame = components.stack.caller;
- var weakref = Cu.getWeakReference(object);
- if (!bin && 'constructor' in object)
- bin = object.constructor.name;
- if (bin == "Object")
- bin = frame.name;
- if (!bin)
- bin = "generic";
- if (!(bin in trackedObjects))
- trackedObjects[bin] = [];
-
- if (stackFrameNumber > 0)
- for (var i = 0; i < stackFrameNumber; i++)
- frame = frame.caller;
-
- trackedObjects[bin].push({weakref: weakref,
- created: new Date(),
- filename: frame.filename,
- lineNo: frame.lineNumber,
- bin: bin});
-};
-
-var getBins = exports.getBins = function getBins() {
- var names = [];
- for (let name in trackedObjects)
- names.push(name);
- return names;
-};
-
-var getObjects = exports.getObjects = function getObjects(bin) {
- function getLiveObjectsInBin(bin, array) {
- for (var i = 0; i < bin.length; i++) {
- var object = bin[i].weakref.get();
- if (object)
- array.push(bin[i]);
- }
- }
-
- var results = [];
- if (bin) {
- if (bin in trackedObjects)
- getLiveObjectsInBin(trackedObjects[bin], results);
- } else
- for (let name in trackedObjects)
- getLiveObjectsInBin(trackedObjects[name], results);
- return results;
-};
-
-var gc = exports.gc = function gc() {
- // Components.utils.forceGC() doesn't currently perform
- // cycle collection, which means that e.g. DOM elements
- // won't be collected by it. Fortunately, there are
- // other ways...
-
- var window = Cc["@mozilla.org/appshell/appShellService;1"]
- .getService(Ci.nsIAppShellService)
- .hiddenDOMWindow;
- var test_utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- test_utils.garbageCollect();
- Compacter.notify();
-
- // Not sure why, but sometimes it appears that we don't get
- // them all with just one CC, so let's do it again.
- test_utils.garbageCollect();
-};
-
-require("../system/unload").when(
- function() {
- trackedObjects = {};
- if (timer) {
- timer.cancel();
- timer = null;
- }
- });
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/observer-service.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/observer-service.js
deleted file mode 100644
index 6a25109..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/observer-service.js
+++ /dev/null
@@ -1,134 +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": "deprecated"
-};
-
-const { Cc, Ci } = require("chrome");
-const { when: unload } = require("../system/unload");
-const { ns } = require("../core/namespace");
-const { on, off, emit, once } = require("../system/events");
-const { id } = require("../self");
-
-const subscribers = ns();
-const cache = [];
-
-/**
- * Topics specifically available to Jetpack-generated extensions.
- *
- * Using these predefined consts instead of the platform strings is good:
- * - allows us to scope topics specifically for Jetpacks
- * - addons aren't dependent on strings nor behavior of core platform topics
- * - the core platform topics are not clearly named
- *
- */
-exports.topics = {
- /**
- * A topic indicating that the application is in a state usable
- * by add-ons.
- */
- APPLICATION_READY: id + "_APPLICATION_READY"
-};
-
-function Listener(callback, target) {
- return function listener({ subject, data }) {
- callback.call(target || callback, subject, data);
- }
-}
-
-/**
- * Register the given callback as an observer of the given topic.
- *
- * @param topic {String}
- * the topic to observe
- *
- * @param callback {Object}
- * the callback; an Object that implements nsIObserver or a Function
- * that gets called when the notification occurs
- *
- * @param target {Object} [optional]
- * the object to use as |this| when calling a Function callback
- *
- * @returns the observer
- */
-function add(topic, callback, target) {
- let listeners = subscribers(callback);
- if (!(topic in listeners)) {
- let listener = Listener(callback, target);
- listeners[topic] = listener;
-
- // Cache callback unless it's already cached.
- if (!~cache.indexOf(callback))
- cache.push(callback);
-
- on(topic, listener);
- }
-};
-exports.add = add;
-
-/**
- * Unregister the given callback as an observer of the given topic.
- *
- * @param topic {String}
- * the topic being observed
- *
- * @param callback {Object}
- * the callback doing the observing
- *
- * @param target {Object} [optional]
- * the object being used as |this| when calling a Function callback
- */
-function remove(topic, callback, target) {
- let listeners = subscribers(callback);
- if (topic in listeners) {
- let listener = listeners[topic];
- delete listeners[topic];
-
- // If no more observers are registered and callback is still in cache
- // then remove it.
- let index = cache.indexOf(callback);
- if (~index && !Object.keys(listeners).length)
- cache.splice(index, 1)
-
- off(topic, listener);
- }
-};
-exports.remove = remove;
-
-/**
- * Notify observers about something.
- *
- * @param topic {String}
- * the topic to notify observers about
- *
- * @param subject {Object} [optional]
- * some information about the topic; can be any JS object or primitive
- *
- * @param data {String} [optional] [deprecated]
- * some more information about the topic; deprecated as the subject
- * is sufficient to pass all needed information to the JS observers
- * that this module targets; if you have multiple values to pass to
- * the observer, wrap them in an object and pass them via the subject
- * parameter (i.e.: { foo: 1, bar: "some string", baz: myObject })
- */
-function notify(topic, subject, data) {
- emit(topic, {
- subject: subject === undefined ? null : subject,
- data: data === undefined ? null : data
- });
-}
-exports.notify = notify;
-
-unload(function() {
- // Make a copy of cache first, since cache will be changing as we
- // iterate through it.
- cache.slice().forEach(function(callback) {
- Object.keys(subscribers(callback)).forEach(function(topic) {
- remove(topic, callback);
- });
- });
-})
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/tab-browser.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/tab-browser.js
deleted file mode 100644
index 068471c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/tab-browser.js
+++ /dev/null
@@ -1,731 +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': 'deprecated'
-};
-
-const {Cc,Ci,Cu} = require('chrome');
-var NetUtil = {};
-Cu.import('resource://gre/modules/NetUtil.jsm', NetUtil);
-NetUtil = NetUtil.NetUtil;
-const errors = require('./errors');
-const windowUtils = require('./window-utils');
-const apiUtils = require('./api-utils');
-const collection = require('../util/collection');
-const { getMostRecentBrowserWindow } = require('../window/utils');
-const { getSelectedTab } = require('../tabs/utils');
-
-// TODO: The hard-coding of app-specific info here isn't very nice;
-// ideally such app-specific info should be more decoupled, and the
-// module should be extensible, allowing for support of new apps at
-// runtime, perhaps by inspecting supported packages (e.g. via
-// dynamically-named modules or package-defined extension points).
-
-if (!require("../system/xul-app").is("Firefox")) {
- throw new Error([
- "The tab-browser module currently supports only Firefox. In the future ",
- "it will support other applications. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=560716 for more information."
- ].join(""));
-}
-
-function onBrowserLoad(callback, event) {
- if (event.target && event.target.defaultView == this) {
- this.removeEventListener("load", onBrowserLoad, true);
- try {
- require("../timers").setTimeout(function () {
- callback(event);
- }, 10);
- } catch (e) { console.exception(e); }
- }
-}
-
-// Utility function to open a new browser window.
-function openBrowserWindow(callback, url) {
- let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Ci.nsIWindowWatcher);
- let urlString = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- urlString.data = url;
- let window = ww.openWindow(null, "chrome://browser/content/browser.xul",
- "_blank", "chrome,all,dialog=no", urlString);
- if (callback)
- window.addEventListener("load", onBrowserLoad.bind(window, callback), true);
-
- return window;
-}
-
-// Open a URL in a new tab
-exports.addTab = function addTab(url, options) {
- if (!options)
- options = {};
- options.url = url;
-
- options = apiUtils.validateOptions(options, {
- // TODO: take URL object instead of string (bug 564524)
- url: {
- is: ["string"],
- ok: function (v) !!v,
- msg: "The url parameter must have be a non-empty string."
- },
- inNewWindow: {
- is: ["undefined", "null", "boolean"]
- },
- inBackground: {
- is: ["undefined", "null", "boolean"]
- },
- onLoad: {
- is: ["undefined", "null", "function"]
- },
- isPinned: {
- is: ["undefined", "boolean"]
- }
- });
-
- var win = getMostRecentBrowserWindow();
- if (!win || options.inNewWindow) {
- openBrowserWindow(function(e) {
- if(options.isPinned) {
- //get the active tab in the recently created window
- let mainWindow = e.target.defaultView;
- mainWindow.gBrowser.pinTab(getSelectedTab(mainWindow));
- }
- require("./errors").catchAndLog(function(e) options.onLoad(e))(e);
- }, options.url);
- }
- else {
- let tab = win.gBrowser.addTab(options.url);
- if (!options.inBackground)
- win.gBrowser.selectedTab = tab;
- if (options.onLoad) {
- let tabBrowser = win.gBrowser.getBrowserForTab(tab);
- tabBrowser.addEventListener("load", function onLoad(e) {
- if (e.target.defaultView.content.location == "about:blank")
- return;
- // remove event handler from addTab - don't want notified
- // for subsequent loads in same tab.
- tabBrowser.removeEventListener("load", onLoad, true);
- require("./errors").catchAndLog(function(e) options.onLoad(e))(e);
- }, true);
- }
- }
-}
-
-// Iterate over a window's tabbrowsers
-function tabBrowserIterator(window) {
- var browsers = window.document.querySelectorAll("tabbrowser");
- for (var i = 0; i < browsers.length; i++)
- yield browsers[i];
-}
-
-// Iterate over a tabbrowser's tabs
-function tabIterator(tabbrowser) {
- var tabs = tabbrowser.tabContainer;
- for (var i = 0; i < tabs.children.length; i++) {
- yield tabs.children[i];
- }
-}
-
-// Tracker for all tabbrowsers across all windows,
-// or a single tabbrowser if the window is given.
-function Tracker(delegate, window) {
- this._delegate = delegate;
- this._browsers = [];
- this._window = window;
- this._windowTracker = windowUtils.WindowTracker(this);
-
- require("../system/unload").ensure(this);
-}
-Tracker.prototype = {
- __iterator__: function __iterator__() {
- for (var i = 0; i < this._browsers.length; i++)
- yield this._browsers[i];
- },
- get: function get(index) {
- return this._browsers[index];
- },
- onTrack: function onTrack(window) {
- if (this._window && window != this._window)
- return;
-
- for (let browser in tabBrowserIterator(window))
- this._browsers.push(browser);
- if (this._delegate)
- for (let browser in tabBrowserIterator(window))
- this._delegate.onTrack(browser);
- },
- onUntrack: function onUntrack(window) {
- if (this._window && window != this._window)
- return;
-
- for (let browser in tabBrowserIterator(window)) {
- let index = this._browsers.indexOf(browser);
- if (index != -1)
- this._browsers.splice(index, 1);
- else
- console.error("internal error: browser tab not found");
- }
- if (this._delegate)
- for (let browser in tabBrowserIterator(window))
- this._delegate.onUntrack(browser);
- },
- get length() {
- return this._browsers.length;
- },
- unload: function unload() {
- this._windowTracker.unload();
- }
-};
-exports.Tracker = apiUtils.publicConstructor(Tracker);
-
-// Tracker for all tabs across all windows,
-// or a single window if it's given.
-function TabTracker(delegate, window) {
- this._delegate = delegate;
- this._tabs = [];
- this._tracker = new Tracker(this, window);
- require("../system/unload").ensure(this);
-}
-TabTracker.prototype = {
- _TAB_EVENTS: ["TabOpen", "TabClose"],
- _safeTrackTab: function safeTrackTab(tab) {
- this._tabs.push(tab);
- try {
- this._delegate.onTrack(tab);
- } catch (e) {
- console.exception(e);
- }
- },
- _safeUntrackTab: function safeUntrackTab(tab) {
- var index = this._tabs.indexOf(tab);
- if (index == -1)
- console.error("internal error: tab not found");
- this._tabs.splice(index, 1);
- try {
- this._delegate.onUntrack(tab);
- } catch (e) {
- console.exception(e);
- }
- },
- handleEvent: function handleEvent(event) {
- switch (event.type) {
- case "TabOpen":
- this._safeTrackTab(event.target);
- break;
- case "TabClose":
- this._safeUntrackTab(event.target);
- break;
- default:
- throw new Error("internal error: unknown event type: " +
- event.type);
- }
- },
- onTrack: function onTrack(tabbrowser) {
- for (let tab in tabIterator(tabbrowser))
- this._safeTrackTab(tab);
- var self = this;
- this._TAB_EVENTS.forEach(
- function(eventName) {
- tabbrowser.tabContainer.addEventListener(eventName, self, true);
- });
- },
- onUntrack: function onUntrack(tabbrowser) {
- for (let tab in tabIterator(tabbrowser))
- this._safeUntrackTab(tab);
- var self = this;
- this._TAB_EVENTS.forEach(
- function(eventName) {
- tabbrowser.tabContainer.removeEventListener(eventName, self, true);
- });
- },
- unload: function unload() {
- this._tracker.unload();
- }
-};
-exports.TabTracker = apiUtils.publicConstructor(TabTracker);
-
-exports.whenContentLoaded = function whenContentLoaded(callback) {
- var cb = require("./errors").catchAndLog(function eventHandler(event) {
- if (event.target && event.target.defaultView)
- callback(event.target.defaultView);
- });
-
- var tracker = new Tracker({
- onTrack: function(tabBrowser) {
- tabBrowser.addEventListener("DOMContentLoaded", cb, false);
- },
- onUntrack: function(tabBrowser) {
- tabBrowser.removeEventListener("DOMContentLoaded", cb, false);
- }
- });
-
- return tracker;
-};
-
-Object.defineProperty(exports, 'activeTab', {
- get: function() {
- return getSelectedTab(getMostRecentBrowserWindow());
- }
-});
-
-/******************* TabModule *********************/
-
-// Supported tab events
-const events = [
- "onActivate",
- "onDeactivate",
- "onOpen",
- "onClose",
- "onReady",
- "onLoad",
- "onPaint"
-];
-exports.tabEvents = events;
-
-/**
- * TabModule
- *
- * Constructor for a module that implements the tabs API
- */
-let TabModule = exports.TabModule = function TabModule(window) {
- let self = this;
- /**
- * Tab
- *
- * Safe object representing a tab.
- */
- let tabConstructor = apiUtils.publicConstructor(function(element) {
- if (!element)
- throw new Error("no tab element.");
- let win = element.ownerDocument.defaultView;
- if (!win)
- throw new Error("element has no window.");
- if (window && win != window)
- throw new Error("module's window and element's window don't match.");
- let browser = win.gBrowser.getBrowserForTab(element);
-
- this.__defineGetter__("title", function() browser.contentDocument.title);
- this.__defineGetter__("location", function() browser.contentDocument.location);
- this.__defineSetter__("location", function(val) browser.contentDocument.location = val);
- this.__defineGetter__("contentWindow", function() browser.contentWindow);
- this.__defineGetter__("contentDocument", function() browser.contentDocument);
- this.__defineGetter__("favicon", function() {
- let pageURI = NetUtil.newURI(browser.contentDocument.location);
- let fs = Cc["@mozilla.org/browser/favicon-service;1"].
- getService(Ci.nsIFaviconService);
- let faviconURL;
- try {
- let faviconURI = fs.getFaviconForPage(pageURI);
- faviconURL = fs.getFaviconDataAsDataURL(faviconURI);
- } catch(ex) {
- let data = getChromeURLContents("chrome://mozapps/skin/places/defaultFavicon.png");
- let encoded = browser.contentWindow.btoa(data);
- faviconURL = "data:image/png;base64," + encoded;
- }
- return faviconURL;
- });
- this.__defineGetter__("style", function() null); // TODO
- this.__defineGetter__("index", function() win.gBrowser.getBrowserIndexForDocument(browser.contentDocument));
- this.__defineGetter__("thumbnail", function() getThumbnailCanvasForTab(element, browser.contentWindow));
-
- this.close = function() win.gBrowser.removeTab(element);
- this.move = function(index) {
- win.gBrowser.moveTabTo(element, index);
- };
-
- this.__defineGetter__("isPinned", function() element.pinned);
- this.pin = function() win.gBrowser.pinTab(element);
- this.unpin = function() win.gBrowser.unpinTab(element);
-
- // Set up the event handlers
- let tab = this;
- events.filter(function(e) e != "onOpen").forEach(function(e) {
- // create a collection for each event
- collection.addCollectionProperty(tab, e);
- // make tabs setter for each event, for adding via property assignment
- tab.__defineSetter__(e, function(val) tab[e].add(val));
- });
-
- // listen for events, filtered on this tab
- eventsTabDelegate.addTabDelegate(this);
- });
-
- /**
- * tabs.activeTab
- */
- this.__defineGetter__("activeTab", function() {
- try {
- return window ? tabConstructor(getSelectedTab(window))
- : tabConstructor(exports.activeTab);
- }
- catch (e) { }
- return null;
- });
- this.__defineSetter__("activeTab", function(tab) {
- let [tabElement, win] = getElementAndWindowForTab(tab, window);
- if (tabElement) {
- // set as active tab
- win.gBrowser.selectedTab = tabElement;
- // focus the window
- win.focus();
- }
- });
-
- this.open = function TM_open(options) {
- open(options, tabConstructor, window);
- }
-
- // Set up the event handlers
- events.forEach(function(eventHandler) {
- // create a collection for each event
- collection.addCollectionProperty(self, eventHandler);
- // make tabs setter for each event, for adding via property assignment
- self.__defineSetter__(eventHandler, function(val) self[eventHandler].add(val));
- });
-
- // Tracker that listens for tab events, and proxies
- // them to registered event listeners.
- let eventsTabDelegate = {
- selectedTab: null,
- tabs: [],
- addTabDelegate: function TETT_addTabDelegate(tabObj) {
- this.tabs.push(tabObj);
- },
- pushTabEvent: function TETT_pushTabEvent(event, tab) {
- for (let callback in self[event]) {
- require("./errors").catchAndLog(function(tab) {
- callback(new tabConstructor(tab));
- })(tab);
- }
-
- if (event != "onOpen") {
- this.tabs.forEach(function(tabObj) {
- if (tabObj[event].length) {
- let [tabEl,] = getElementAndWindowForTab(tabObj, window);
- if (tabEl == tab) {
- for (let callback in tabObj[event])
- require("./errors").catchAndLog(function() callback())();
- }
- }
- // if being closed, remove the tab object from the cache
- // of tabs to notify about events.
- if (event == "onClose")
- this.tabs.splice(this.tabs.indexOf(tabObj), 1);
- }, this);
- }
- },
- unload: function() {
- this.selectedTab = null;
- this.tabs.splice(0);
- }
- };
- require("../system/unload").ensure(eventsTabDelegate);
-
- let eventsTabTracker = new ModuleTabTracker({
- onTrack: function TETT_onTrack(tab) {
- eventsTabDelegate.pushTabEvent("onOpen", tab);
- },
- onUntrack: function TETT_onUntrack(tab) {
- eventsTabDelegate.pushTabEvent("onClose", tab);
- },
- onSelect: function TETT_onSelect(tab) {
- if (eventsTabDelegate.selectedTab)
- eventsTabDelegate.pushTabEvent("onDeactivate", tab);
-
- eventsTabDelegate.selectedTab = new tabConstructor(tab);
-
- eventsTabDelegate.pushTabEvent("onActivate", tab);
- },
- onReady: function TETT_onReady(tab) {
- eventsTabDelegate.pushTabEvent("onReady", tab);
- },
- onLoad: function TETT_onLoad(tab) {
- eventsTabDelegate.pushTabEvent("onLoad", tab);
- },
- onPaint: function TETT_onPaint(tab) {
- eventsTabDelegate.pushTabEvent("onPaint", tab);
- }
- }, window);
- require("../system/unload").ensure(eventsTabTracker);
-
- // Iterator for all tabs
- this.__iterator__ = function tabsIterator() {
- for (let i = 0; i < eventsTabTracker._tabs.length; i++)
- yield tabConstructor(eventsTabTracker._tabs[i]);
- }
-
- this.__defineGetter__("length", function() eventsTabTracker._tabs.length);
-
- // Cleanup when unloaded
- this.unload = function TM_unload() {
- // Unregister tabs event listeners
- events.forEach(function(e) self[e] = []);
- }
- require("../system/unload").ensure(this);
-
-} // End of TabModule constructor
-
-/**
- * tabs.open - open a URL in a new tab
- */
-function open(options, tabConstructor, window) {
- if (typeof options === "string")
- options = { url: options };
-
- options = apiUtils.validateOptions(options, {
- url: {
- is: ["string"]
- },
- inNewWindow: {
- is: ["undefined", "boolean"]
- },
- inBackground: {
- is: ["undefined", "boolean"]
- },
- isPinned: {
- is: ["undefined", "boolean"]
- },
- onOpen: {
- is: ["undefined", "function"]
- }
- });
-
- if (window)
- options.inNewWindow = false;
-
- let win = window || require("./window-utils").activeBrowserWindow;
-
- if (!win || options.inNewWindow)
- openURLInNewWindow(options, tabConstructor);
- else
- openURLInNewTab(options, win, tabConstructor);
-}
-
-function openURLInNewWindow(options, tabConstructor) {
- let addTabOptions = {
- inNewWindow: true
- };
- if (options.onOpen) {
- addTabOptions.onLoad = function(e) {
- let win = e.target.defaultView;
- let tabEl = win.gBrowser.tabContainer.childNodes[0];
- let tabBrowser = win.gBrowser.getBrowserForTab(tabEl);
- tabBrowser.addEventListener("load", function onLoad(e) {
- tabBrowser.removeEventListener("load", onLoad, true);
- let tab = tabConstructor(tabEl);
- require("./errors").catchAndLog(function(e) options.onOpen(e))(tab);
- }, true);
- };
- }
- if (options.isPinned) {
- addTabOptions.isPinned = true;
- }
- exports.addTab(options.url.toString(), addTabOptions);
-}
-
-function openURLInNewTab(options, window, tabConstructor) {
- window.focus();
- let tabEl = window.gBrowser.addTab(options.url.toString());
- if (!options.inBackground)
- window.gBrowser.selectedTab = tabEl;
- if (options.isPinned)
- window.gBrowser.pinTab(tabEl);
- if (options.onOpen) {
- let tabBrowser = window.gBrowser.getBrowserForTab(tabEl);
- tabBrowser.addEventListener("load", function onLoad(e) {
- // remove event handler from addTab - don't want to be notified
- // for subsequent loads in same tab.
- tabBrowser.removeEventListener("load", onLoad, true);
- let tab = tabConstructor(tabEl);
- require("../timers").setTimeout(function() {
- require("./errors").catchAndLog(function(tab) options.onOpen(tab))(tab);
- }, 10);
- }, true);
- }
-}
-
-function getElementAndWindowForTab(tabObj, window) {
- // iterate over open windows, or use single window if provided
- let windowIterator = window ? function() { yield window; }
- : require("./window-utils").windowIterator;
- for (let win in windowIterator()) {
- if (win.gBrowser) {
- // find the tab element at tab.index
- let index = win.gBrowser.getBrowserIndexForDocument(tabObj.contentDocument);
- if (index > -1)
- return [win.gBrowser.tabContainer.getItemAtIndex(index), win];
- }
- }
- return [null, null];
-}
-
-// Tracker for all tabs across all windows
-// This is tab-browser.TabTracker, but with
-// support for additional events added.
-function ModuleTabTracker(delegate, window) {
- this._delegate = delegate;
- this._tabs = [];
- this._tracker = new Tracker(this, window);
- require("../system/unload").ensure(this);
-}
-ModuleTabTracker.prototype = {
- _TAB_EVENTS: ["TabOpen", "TabClose", "TabSelect", "DOMContentLoaded",
- "load", "MozAfterPaint"],
- _safeTrackTab: function safeTrackTab(tab) {
- tab.addEventListener("load", this, false);
- tab.linkedBrowser.addEventListener("MozAfterPaint", this, false);
- this._tabs.push(tab);
- try {
- this._delegate.onTrack(tab);
- } catch (e) {
- console.exception(e);
- }
- },
- _safeUntrackTab: function safeUntrackTab(tab) {
- tab.removeEventListener("load", this, false);
- tab.linkedBrowser.removeEventListener("MozAfterPaint", this, false);
- var index = this._tabs.indexOf(tab);
- if (index == -1)
- throw new Error("internal error: tab not found");
- this._tabs.splice(index, 1);
- try {
- this._delegate.onUntrack(tab);
- } catch (e) {
- console.exception(e);
- }
- },
- _safeSelectTab: function safeSelectTab(tab) {
- var index = this._tabs.indexOf(tab);
- if (index == -1)
- console.error("internal error: tab not found");
- try {
- if (this._delegate.onSelect)
- this._delegate.onSelect(tab);
- } catch (e) {
- console.exception(e);
- }
- },
- _safeDOMContentLoaded: function safeDOMContentLoaded(event) {
- let tabBrowser = event.currentTarget;
- let tabBrowserIndex = tabBrowser.getBrowserIndexForDocument(event.target);
- // TODO: I'm seeing this when loading data url images
- if (tabBrowserIndex == -1)
- return;
- let tab = tabBrowser.tabContainer.getItemAtIndex(tabBrowserIndex);
- let index = this._tabs.indexOf(tab);
- if (index == -1)
- console.error("internal error: tab not found");
- try {
- if (this._delegate.onReady)
- this._delegate.onReady(tab);
- } catch (e) {
- console.exception(e);
- }
- },
- _safeLoad: function safeLoad(event) {
- let tab = event.target;
- let index = this._tabs.indexOf(tab);
- if (index == -1)
- console.error("internal error: tab not found");
- try {
- if (this._delegate.onLoad)
- this._delegate.onLoad(tab);
- } catch (e) {
- console.exception(e);
- }
- },
- _safeMozAfterPaint: function safeMozAfterPaint(event) {
- let win = event.currentTarget.ownerDocument.defaultView;
- let tabIndex = win.gBrowser.getBrowserIndexForDocument(event.target.document);
- if (tabIndex == -1)
- return;
- let tab = win.gBrowser.tabContainer.getItemAtIndex(tabIndex);
- let index = this._tabs.indexOf(tab);
- if (index == -1)
- console.error("internal error: tab not found");
- try {
- if (this._delegate.onPaint)
- this._delegate.onPaint(tab);
- } catch (e) {
- console.exception(e);
- }
- },
- handleEvent: function handleEvent(event) {
- switch (event.type) {
- case "TabOpen":
- this._safeTrackTab(event.target);
- break;
- case "TabClose":
- this._safeUntrackTab(event.target);
- break;
- case "TabSelect":
- this._safeSelectTab(event.target);
- break;
- case "DOMContentLoaded":
- this._safeDOMContentLoaded(event);
- break;
- case "load":
- this._safeLoad(event);
- break;
- case "MozAfterPaint":
- this._safeMozAfterPaint(event);
- break;
- default:
- throw new Error("internal error: unknown event type: " +
- event.type);
- }
- },
- onTrack: function onTrack(tabbrowser) {
- for (let tab in tabIterator(tabbrowser))
- this._safeTrackTab(tab);
- tabbrowser.tabContainer.addEventListener("TabOpen", this, false);
- tabbrowser.tabContainer.addEventListener("TabClose", this, false);
- tabbrowser.tabContainer.addEventListener("TabSelect", this, false);
- tabbrowser.ownerDocument.defaultView.gBrowser.addEventListener("DOMContentLoaded", this, false);
- },
- onUntrack: function onUntrack(tabbrowser) {
- for (let tab in tabIterator(tabbrowser))
- this._safeUntrackTab(tab);
- tabbrowser.tabContainer.removeEventListener("TabOpen", this, false);
- tabbrowser.tabContainer.removeEventListener("TabClose", this, false);
- tabbrowser.tabContainer.removeEventListener("TabSelect", this, false);
- tabbrowser.ownerDocument.defaultView.gBrowser.removeEventListener("DOMContentLoaded", this, false);
- },
- unload: function unload() {
- this._tracker.unload();
- }
-};
-
-// Utility to get a thumbnail canvas from a tab object
-function getThumbnailCanvasForTab(tabEl, window) {
- var thumbnail = window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- thumbnail.mozOpaque = true;
- window = tabEl.linkedBrowser.contentWindow;
- thumbnail.width = Math.ceil(window.screen.availWidth / 5.75);
- var aspectRatio = 0.5625; // 16:9
- thumbnail.height = Math.round(thumbnail.width * aspectRatio);
- var ctx = thumbnail.getContext("2d");
- var snippetWidth = window.innerWidth * .6;
- var scale = thumbnail.width / snippetWidth;
- ctx.scale(scale, scale);
- ctx.drawWindow(window, window.scrollX, window.scrollY, snippetWidth, snippetWidth * aspectRatio, "rgb(255,255,255)");
- return thumbnail;
-}
-
-// Utility to return the contents of the target of a chrome URL
-function getChromeURLContents(chromeURL) {
- let io = Cc["@mozilla.org/network/io-service;1"].
- getService(Ci.nsIIOService);
- let channel = io.newChannel(chromeURL, null, null);
- let input = channel.open();
- let stream = Cc["@mozilla.org/binaryinputstream;1"].
- createInstance(Ci.nsIBinaryInputStream);
- stream.setInputStream(input);
- let str = stream.readBytes(input.available());
- stream.close();
- input.close();
- return str;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/traits.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/traits.js
deleted file mode 100644
index 30ae342..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/traits.js
+++ /dev/null
@@ -1,187 +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": "deprecated"
-};
-
-const {
- compose: _compose,
- override: _override,
- resolve: _resolve,
- trait: _trait,
- //create: _create,
- required,
-} = require('./traits/core');
-
-const defineProperties = Object.defineProperties,
- freeze = Object.freeze,
- create = Object.create;
-
-/**
- * Work around bug 608959 by defining the _create function here instead of
- * importing it from traits/core. For docs on this function, see the create
- * function in that module.
- *
- * FIXME: remove this workaround in favor of importing the function once that
- * bug has been fixed.
- */
-function _create(proto, trait) {
- let properties = {},
- keys = Object.getOwnPropertyNames(trait);
- for each(let key in keys) {
- let descriptor = trait[key];
- if (descriptor.required &&
- !Object.prototype.hasOwnProperty.call(proto, key))
- throw new Error('Missing required property: ' + key);
- else if (descriptor.conflict)
- throw new Error('Remaining conflicting property: ' + key);
- else
- properties[key] = descriptor;
- }
- return Object.create(proto, properties);
-}
-
-/**
- * Placeholder for `Trait.prototype`
- */
-let TraitProto = Object.prototype;
-
-function Get(key) this[key]
-function Set(key, value) this[key] = value
-
-/**
- * Creates anonymous trait descriptor from the passed argument, unless argument
- * is a trait constructor. In later case trait's already existing properties
- * descriptor is returned.
- * This is module's internal function and is used as a gateway to a trait's
- * internal properties descriptor.
- * @param {Function} $
- * Composed trait's constructor.
- * @returns {Object}
- * Private trait property of the composition.
- */
-function TraitDescriptor(object)
- (
- 'function' == typeof object &&
- (object.prototype == TraitProto || object.prototype instanceof Trait)
- ) ? object._trait(TraitDescriptor) : _trait(object)
-
-function Public(instance, trait) {
- let result = {},
- keys = Object.getOwnPropertyNames(trait);
- for each (let key in keys) {
- if ('_' === key.charAt(0) && '__iterator__' !== key )
- continue;
- let property = trait[key],
- descriptor = {
- configurable: property.configurable,
- enumerable: property.enumerable
- };
- if (property.get)
- descriptor.get = property.get.bind(instance);
- if (property.set)
- descriptor.set = property.set.bind(instance);
- if ('value' in property) {
- let value = property.value;
- if ('function' === typeof value) {
- descriptor.value = property.value.bind(instance);
- descriptor.writable = property.writable;
- } else {
- descriptor.get = Get.bind(instance, key);
- descriptor.set = Set.bind(instance, key);
- }
- }
- result[key] = descriptor;
- }
- return result;
-}
-
-/**
- * This is private function that composes new trait with privates.
- */
-function Composition(trait) {
- function Trait() {
- let self = _create({}, trait);
- self._public = create(Trait.prototype, Public(self, trait));
- delete self._public.constructor;
- if (Object === self.constructor)
- self.constructor = Trait;
- else
- return self.constructor.apply(self, arguments) || self._public;
- return self._public;
- }
- defineProperties(Trait, {
- prototype: { value: freeze(create(TraitProto, {
- constructor: { value: constructor, writable: true }
- }))}, // writable is `true` to avoid getters in custom ES5
- displayName: { value: (trait.constructor || constructor).name },
- compose: { value: compose, enumerable: true },
- override: { value: override, enumerable: true },
- resolve: { value: resolve, enumerable: true },
- required: { value: required, enumerable: true },
- _trait: { value: function _trait(caller)
- caller === TraitDescriptor ? trait : undefined
- }
- });
- return freeze(Trait);
-}
-
-/**
- * Composes new trait out of itself and traits / property maps passed as an
- * arguments. If two or more traits / property maps have properties with the
- * same name, the new trait will contain a "conflict" property for that name.
- * This is a commutative and associative operation, and the order of its
- * arguments is not significant.
- * @params {Object|Function}
- * List of Traits or property maps to create traits from.
- * @returns {Function}
- * New trait containing the combined properties of all the traits.
- */
-function compose() {
- let traits = Array.slice(arguments, 0);
- traits.push(this);
- return Composition(_compose.apply(null, traits.map(TraitDescriptor)));
-}
-
-/**
- * Composes a new trait with all of the combined properties of `this` and the
- * argument traits. In contrast to `compose`, `override` immediately resolves
- * all conflicts resulting from this composition by overriding the properties of
- * later traits. Trait priority is from left to right. I.e. the properties of
- * the leftmost trait are never overridden.
- * @params {Object} trait
- * @returns {Object}
- */
-function override() {
- let traits = Array.slice(arguments, 0);
- traits.push(this);
- return Composition(_override.apply(null, traits.map(TraitDescriptor)));
-}
-
-/**
- * Composes new resolved trait, with all the same properties as this
- * trait, except that all properties whose name is an own property of
- * `resolutions` will be renamed to `resolutions[name]`. If it is
- * `resolutions[name]` is `null` value is changed into a required property
- * descriptor.
- */
-function resolve(resolutions)
- Composition(_resolve(resolutions, TraitDescriptor(this)))
-
-/**
- * Base Trait, that all the traits are composed of.
- */
-const Trait = Composition({
- /**
- * Internal property holding public API of this instance.
- */
- _public: { value: null, configurable: true, writable: true },
- toString: { value: function() '[object ' + this.constructor.name + ']' }
-});
-TraitProto = Trait.prototype;
-exports.Trait = Trait;
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/traits/core.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/traits/core.js
deleted file mode 100644
index c08c38f..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/traits/core.js
+++ /dev/null
@@ -1,322 +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": "deprecated"
-};
-
-// Design inspired by: http://www.traitsjs.org/
-
-// shortcuts
-const getOwnPropertyNames = Object.getOwnPropertyNames,
- getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
- hasOwn = Object.prototype.hasOwnProperty,
- _create = Object.create;
-
-function doPropertiesMatch(object1, object2, name) {
- // If `object1` has property with the given `name`
- return name in object1 ?
- // then `object2` should have it with the same value.
- name in object2 && object1[name] === object2[name] :
- // otherwise `object2` should not have property with the given `name`.
- !(name in object2);
-}
-
-/**
- * Compares two trait custom property descriptors if they are the same. If
- * both are `conflict` or all the properties of descriptor are equal returned
- * value will be `true`, otherwise it will be `false`.
- * @param {Object} desc1
- * @param {Object} desc2
- */
-function areSame(desc1, desc2) {
- return ('conflict' in desc1 && desc1.conflict &&
- 'conflict' in desc2 && desc2.conflict) ||
- (doPropertiesMatch(desc1, desc2, 'get') &&
- doPropertiesMatch(desc1, desc2, 'set') &&
- doPropertiesMatch(desc1, desc2, 'value') &&
- doPropertiesMatch(desc1, desc2, 'enumerable') &&
- doPropertiesMatch(desc1, desc2, 'required') &&
- doPropertiesMatch(desc1, desc2, 'conflict'));
-}
-
-/**
- * Converts array to an object whose own property names represent
- * values of array.
- * @param {String[]} names
- * @returns {Object}
- * @example
- * Map(['foo', ...]) => { foo: true, ...}
- */
-function Map(names) {
- let map = {};
- for each (let name in names)
- map[name] = true;
- return map;
-}
-
-
-const ERR_CONFLICT = 'Remaining conflicting property: ',
- ERR_REQUIRED = 'Missing required property: ';
-/**
- * Constant singleton, representing placeholder for required properties.
- * @type {Object}
- */
-const required = { toString: function()'<Trait.required>' };
-exports.required = required;
-
-/**
- * Generates custom **required** property descriptor. Descriptor contains
- * non-standard property `required` that is equal to `true`.
- * @param {String} name
- * property name to generate descriptor for.
- * @returns {Object}
- * custom property descriptor
- */
-function Required(name) {
- function required() { throw new Error(ERR_REQUIRED + name) }
- return {
- get: required,
- set: required,
- required: true
- };
-}
-
-/**
- * Generates custom **conflicting** property descriptor. Descriptor contains
- * non-standard property `conflict` that is equal to `true`.
- * @param {String} name
- * property name to generate descriptor for.
- * @returns {Object}
- * custom property descriptor
- */
-function Conflict(name) {
- function conflict() { throw new Error(ERR_CONFLICT + name) }
- return {
- get: conflict,
- set: conflict,
- conflict: true
- };
-}
-
-/**
- * Function generates custom properties descriptor of the `object`s own
- * properties. All the inherited properties are going to be ignored.
- * Properties with values matching `required` singleton will be marked as
- * 'required' properties.
- * @param {Object} object
- * Set of properties to generate trait from.
- * @returns {Object}
- * Properties descriptor of all of the `object`'s own properties.
- */
-function trait(properties) {
- let result = {},
- keys = getOwnPropertyNames(properties);
- for each (let key in keys) {
- let descriptor = getOwnPropertyDescriptor(properties, key);
- result[key] = (required === descriptor.value) ? Required(key) : descriptor;
- }
- return result;
-}
-exports.Trait = exports.trait = trait;
-
-/**
- * Composes new trait. If two or more traits have own properties with the
- * same name, the new trait will contain a 'conflict' property for that name.
- * 'compose' is a commutative and associative operation, and the order of its
- * arguments is not significant.
- *
- * @params {Object} trait
- * Takes traits as an arguments
- * @returns {Object}
- * New trait containing the combined own properties of all the traits.
- * @example
- * var newTrait = compose(trait_1, trait_2, ..., trait_N);
- */
-function compose(trait1, trait2) {
- let traits = Array.slice(arguments, 0),
- result = {};
- for each (let trait in traits) {
- let keys = getOwnPropertyNames(trait);
- for each (let key in keys) {
- let descriptor = trait[key];
- // if property already exists and it's not a requirement
- if (hasOwn.call(result, key) && !result[key].required) {
- if (descriptor.required)
- continue;
- if (!areSame(descriptor, result[key]))
- result[key] = Conflict(key);
- } else {
- result[key] = descriptor;
- }
- }
- }
- return result;
-}
-exports.compose = compose;
-
-/**
- * Composes new trait with the same own properties as the original trait,
- * except that all property names appearing in the first argument are replaced
- * by 'required' property descriptors.
- * @param {String[]} keys
- * Array of strings property names.
- * @param {Object} trait
- * A trait some properties of which should be excluded.
- * @returns {Object}
- * @example
- * var newTrait = exclude(['name', ...], trait)
- */
-function exclude(keys, trait) {
- let exclusions = Map(keys),
- result = {};
-
- keys = getOwnPropertyNames(trait);
-
- for each (let key in keys) {
- if (!hasOwn.call(exclusions, key) || trait[key].required)
- result[key] = trait[key];
- else
- result[key] = Required(key);
- }
- return result;
-}
-
-/**
- * Composes a new trait with all of the combined properties of the argument
- * traits. In contrast to `compose`, `override` immediately resolves all
- * conflicts resulting from this composition by overriding the properties of
- * later traits. Trait priority is from left to right. I.e. the properties of
- * the leftmost trait are never overridden.
- * @params {Object} trait
- * @returns {Object}
- * @examples
- * // override is associative:
- * override(t1,t2,t3)
- * // is equivalent to
- * override(t1, override(t2, t3))
- * // or
- * to override(override(t1, t2), t3)
- *
- * // override is not commutative:
- * override(t1,t2)
- * // is not equivalent to
- * override(t2,t1)
- */
-function override() {
- let traits = Array.slice(arguments, 0),
- result = {};
- for each (let trait in traits) {
- let keys = getOwnPropertyNames(trait);
- for each(let key in keys) {
- let descriptor = trait[key];
- if (!hasOwn.call(result, key) || result[key].required)
- result[key] = descriptor;
- }
- }
- return result;
-}
-exports.override = override;
-
-/**
- * Composes a new trait with the same properties as the original trait, except
- * that all properties whose name is an own property of map will be renamed to
- * map[name], and a 'required' property for name will be added instead.
- * @param {Object} map
- * An object whose own properties serve as a mapping from old names to new
- * names.
- * @param {Object} trait
- * A trait object
- * @returns {Object}
- * @example
- * var newTrait = rename(map, trait);
- */
-function rename(map, trait) {
- let result = {},
- keys = getOwnPropertyNames(trait);
- for each(let key in keys) {
- // must be renamed & it's not requirement
- if (hasOwn.call(map, key) && !trait[key].required) {
- let alias = map[key];
- if (hasOwn.call(result, alias) && !result[alias].required)
- result[alias] = Conflict(alias);
- else
- result[alias] = trait[key];
- if (!hasOwn.call(result, key))
- result[key] = Required(key);
- } else { // must not be renamed or its a requirement
- // property is not in result trait yet
- if (!hasOwn.call(result, key))
- result[key] = trait[key];
- // property is already in resulted trait & it's not requirement
- else if (!trait[key].required)
- result[key] = Conflict(key);
- }
- }
- return result;
-}
-
-/**
-* Composes new resolved trait, with all the same properties as the original
-* trait, except that all properties whose name is an own property of
-* resolutions will be renamed to `resolutions[name]`. If it is
-* `resolutions[name]` is `null` value is changed into a required property
-* descriptor.
-* function can be implemented as `rename(map,exclude(exclusions, trait))`
-* where map is the subset of mappings from oldName to newName and exclusions
-* is an array of all the keys that map to `null`.
-* Note: it's important to **first** `exclude`, **then** `rename`, since
-* `exclude` and rename are not associative.
-* @param {Object} resolutions
-* An object whose own properties serve as a mapping from old names to new
-* names, or to `null` if the property should be excluded.
-* @param {Object} trait
-* A trait object
-* @returns {Object}
-* Resolved trait with the same own properties as the original trait.
-*/
-function resolve(resolutions, trait) {
- let renames = {},
- exclusions = [],
- keys = getOwnPropertyNames(resolutions);
- for each (let key in keys) { // pre-process renamed and excluded properties
- if (resolutions[key]) // old name -> new name
- renames[key] = resolutions[key];
- else // name -> undefined
- exclusions.push(key);
- }
- return rename(renames, exclude(exclusions, trait));
-}
-exports.resolve = resolve;
-
-/**
- * `create` is like `Object.create`, except that it ensures that:
- * - an exception is thrown if 'trait' still contains required properties
- * - an exception is thrown if 'trait' still contains conflicting
- * properties
- * @param {Object}
- * prototype of the completed object
- * @param {Object} trait
- * trait object to be turned into a complete object
- * @returns {Object}
- * An object with all of the properties described by the trait.
- */
-function create(proto, trait) {
- let properties = {},
- keys = getOwnPropertyNames(trait);
- for each(let key in keys) {
- let descriptor = trait[key];
- if (descriptor.required && !hasOwn.call(proto, key))
- throw new Error(ERR_REQUIRED + key);
- else if (descriptor.conflict)
- throw new Error(ERR_CONFLICT + key);
- else
- properties[key] = descriptor;
- }
- return _create(proto, properties);
-}
-exports.create = create;
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/unit-test-finder.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/unit-test-finder.js
deleted file mode 100644
index 880f554..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/unit-test-finder.js
+++ /dev/null
@@ -1,71 +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": "deprecated"
-};
-
-const file = require("../io/file");
-const memory = require('./memory');
-const suites = require('@test/options').allTestModules;
-
-
-const NOT_TESTS = ['setup', 'teardown'];
-
-var TestFinder = exports.TestFinder = function TestFinder(options) {
- memory.track(this);
- this.filter = options.filter;
- this.testInProcess = options.testInProcess === false ? false : true;
- this.testOutOfProcess = options.testOutOfProcess === true ? true : false;
-};
-
-TestFinder.prototype = {
- findTests: function findTests(cb) {
- var self = this;
- var tests = [];
- var filter;
- // A filter string is {fileNameRegex}[:{testNameRegex}] - ie, a colon
- // optionally separates a regex for the test fileName from a regex for the
- // testName.
- if (this.filter) {
- var colonPos = this.filter.indexOf(':');
- var filterFileRegex, filterNameRegex;
- if (colonPos === -1) {
- filterFileRegex = new RegExp(self.filter);
- } else {
- filterFileRegex = new RegExp(self.filter.substr(0, colonPos));
- filterNameRegex = new RegExp(self.filter.substr(colonPos + 1));
- }
- // This function will first be called with just the filename; if
- // it returns true the module will be loaded then the function
- // called again with both the filename and the testname.
- filter = function(filename, testname) {
- return filterFileRegex.test(filename) &&
- ((testname && filterNameRegex) ? filterNameRegex.test(testname)
- : true);
- };
- } else
- filter = function() {return true};
-
- suites.forEach(
- function(suite) {
- var module = require(suite);
- if (self.testInProcess)
- for each (let name in Object.keys(module).sort()) {
- if(NOT_TESTS.indexOf(name) === -1 && filter(suite, name)) {
- tests.push({
- setup: module.setup,
- teardown: module.teardown,
- testFunction: module[name],
- name: suite + "." + name
- });
- }
- }
- });
-
- cb(tests);
- }
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/unit-test.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/unit-test.js
deleted file mode 100644
index 6a8ac1b..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/unit-test.js
+++ /dev/null
@@ -1,451 +0,0 @@
-/* vim:st=2:sts=2:sw=2:
- * 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": "deprecated"
-};
-
-const memory = require('./memory');
-var timer = require("../timers");
-
-exports.findAndRunTests = function findAndRunTests(options) {
- var TestFinder = require("./unit-test-finder").TestFinder;
- var finder = new TestFinder({
- filter: options.filter,
- testInProcess: options.testInProcess,
- testOutOfProcess: options.testOutOfProcess
- });
- var runner = new TestRunner({fs: options.fs});
- finder.findTests(
- function (tests) {
- runner.startMany({tests: tests,
- stopOnError: options.stopOnError,
- onDone: options.onDone});
- });
-};
-
-var TestRunner = exports.TestRunner = function TestRunner(options) {
- if (options) {
- this.fs = options.fs;
- }
- this.console = (options && "console" in options) ? options.console : console;
- memory.track(this);
- this.passed = 0;
- this.failed = 0;
- this.testRunSummary = [];
- this.expectFailNesting = 0;
-};
-
-TestRunner.prototype = {
- toString: function toString() "[object TestRunner]",
-
- DEFAULT_PAUSE_TIMEOUT: 10000,
- PAUSE_DELAY: 500,
-
- _logTestFailed: function _logTestFailed(why) {
- if (!(why in this.test.errors))
- this.test.errors[why] = 0;
- this.test.errors[why]++;
- if (!this.testFailureLogged) {
- this.console.error("TEST FAILED: " + this.test.name + " (" + why + ")");
- this.testFailureLogged = true;
- }
- },
-
- pass: function pass(message) {
- if(!this.expectFailure) {
- this.console.info("pass:", message);
- this.passed++;
- this.test.passed++;
- }
- else {
- this.expectFailure = false;
- this.fail('Failure Expected: ' + message);
- }
- },
-
- fail: function fail(message) {
- if(!this.expectFailure) {
- this._logTestFailed("failure");
- this.console.error("fail:", message);
- this.console.trace();
- this.failed++;
- this.test.failed++;
- }
- else {
- this.expectFailure = false;
- this.pass(message);
- }
- },
-
- expectFail: function(callback) {
- this.expectFailure = true;
- callback();
- this.expectFailure = false;
- },
-
- exception: function exception(e) {
- this._logTestFailed("exception");
- this.console.exception(e);
- this.failed++;
- this.test.failed++;
- },
-
- assertMatches: function assertMatches(string, regexp, message) {
- if (regexp.test(string)) {
- if (!message)
- message = uneval(string) + " matches " + uneval(regexp);
- this.pass(message);
- } else {
- var no = uneval(string) + " doesn't match " + uneval(regexp);
- if (!message)
- message = no;
- else
- message = message + " (" + no + ")";
- this.fail(message);
- }
- },
-
- assertRaises: function assertRaises(func, predicate, message) {
- try {
- func();
- if (message)
- this.fail(message + " (no exception thrown)");
- else
- this.fail("function failed to throw exception");
- } catch (e) {
- var errorMessage;
- if (typeof(e) == "string")
- errorMessage = e;
- else
- errorMessage = e.message;
- if (typeof(predicate) == "string")
- this.assertEqual(errorMessage, predicate, message);
- else
- this.assertMatches(errorMessage, predicate, message);
- }
- },
-
- assert: function assert(a, message) {
- if (!a) {
- if (!message)
- message = "assertion failed, value is " + a;
- this.fail(message);
- } else
- this.pass(message || "assertion successful");
- },
-
- assertNotEqual: function assertNotEqual(a, b, message) {
- if (a != b) {
- if (!message)
- message = "a != b != " + uneval(a);
- this.pass(message);
- } else {
- var equality = uneval(a) + " == " + uneval(b);
- if (!message)
- message = equality;
- else
- message += " (" + equality + ")";
- this.fail(message);
- }
- },
-
- assertEqual: function assertEqual(a, b, message) {
- if (a == b) {
- if (!message)
- message = "a == b == " + uneval(a);
- this.pass(message);
- } else {
- var inequality = uneval(a) + " != " + uneval(b);
- if (!message)
- message = inequality;
- else
- message += " (" + inequality + ")";
- this.fail(message);
- }
- },
-
- assertNotStrictEqual: function assertNotStrictEqual(a, b, message) {
- if (a !== b) {
- if (!message)
- message = "a !== b !== " + uneval(a);
- this.pass(message);
- } else {
- var equality = uneval(a) + " === " + uneval(b);
- if (!message)
- message = equality;
- else
- message += " (" + equality + ")";
- this.fail(message);
- }
- },
-
- assertStrictEqual: function assertStrictEqual(a, b, message) {
- if (a === b) {
- if (!message)
- message = "a === b === " + uneval(a);
- this.pass(message);
- } else {
- var inequality = uneval(a) + " !== " + uneval(b);
- if (!message)
- message = inequality;
- else
- message += " (" + inequality + ")";
- this.fail(message);
- }
- },
-
- assertFunction: function assertFunction(a, message) {
- this.assertStrictEqual('function', typeof a, message);
- },
-
- assertUndefined: function(a, message) {
- this.assertStrictEqual('undefined', typeof a, message);
- },
-
- assertNotUndefined: function(a, message) {
- this.assertNotStrictEqual('undefined', typeof a, message);
- },
-
- assertNull: function(a, message) {
- this.assertStrictEqual(null, a, message);
- },
-
- assertNotNull: function(a, message) {
- this.assertNotStrictEqual(null, a, message);
- },
-
- assertObject: function(a, message) {
- this.assertStrictEqual('[object Object]', Object.prototype.toString.apply(a), message);
- },
-
- assertString: function(a, message) {
- this.assertStrictEqual('[object String]', Object.prototype.toString.apply(a), message);
- },
-
- assertArray: function(a, message) {
- this.assertStrictEqual('[object Array]', Object.prototype.toString.apply(a), message);
- },
-
- assertNumber: function(a, message) {
- this.assertStrictEqual('[object Number]', Object.prototype.toString.apply(a), message);
- },
-
- done: function done() {
- if (!this.isDone) {
- this.isDone = true;
- if(this.test.teardown) {
- this.test.teardown(this);
- }
- if (this.waitTimeout !== null) {
- timer.clearTimeout(this.waitTimeout);
- this.waitTimeout = null;
- }
- // Do not leave any callback set when calling to `waitUntil`
- this.waitUntilCallback = null;
- if (this.test.passed == 0 && this.test.failed == 0) {
- this._logTestFailed("empty test");
- this.failed++;
- this.test.failed++;
- }
-
- this.testRunSummary.push({
- name: this.test.name,
- passed: this.test.passed,
- failed: this.test.failed,
- errors: [error for (error in this.test.errors)].join(", ")
- });
-
- if (this.onDone !== null) {
- var onDone = this.onDone;
- var self = this;
- this.onDone = null;
- timer.setTimeout(function() { onDone(self); }, 0);
- }
- }
- },
-
- // Set of assertion functions to wait for an assertion to become true
- // These functions take the same arguments as the TestRunner.assert* methods.
- waitUntil: function waitUntil() {
- return this._waitUntil(this.assert, arguments);
- },
-
- waitUntilNotEqual: function waitUntilNotEqual() {
- return this._waitUntil(this.assertNotEqual, arguments);
- },
-
- waitUntilEqual: function waitUntilEqual() {
- return this._waitUntil(this.assertEqual, arguments);
- },
-
- waitUntilMatches: function waitUntilMatches() {
- return this._waitUntil(this.assertMatches, arguments);
- },
-
- /**
- * Internal function that waits for an assertion to become true.
- * @param {Function} assertionMethod
- * Reference to a TestRunner assertion method like test.assert,
- * test.assertEqual, ...
- * @param {Array} args
- * List of arguments to give to the previous assertion method.
- * All functions in this list are going to be called to retrieve current
- * assertion values.
- */
- _waitUntil: function waitUntil(assertionMethod, args) {
- let count = 0;
- let maxCount = this.DEFAULT_PAUSE_TIMEOUT / this.PAUSE_DELAY;
-
- // We need to ensure that test is asynchronous
- if (!this.waitTimeout)
- this.waitUntilDone(this.DEFAULT_PAUSE_TIMEOUT);
-
- let callback = null;
- let finished = false;
-
- let test = this;
-
- // capture a traceback before we go async.
- let traceback = require("../console/traceback");
- let stack = traceback.get();
- stack.splice(-2, 2);
- let currentWaitStack = traceback.format(stack);
- let timeout = null;
-
- function loop(stopIt) {
- timeout = null;
-
- // Build a mockup object to fake TestRunner API and intercept calls to
- // pass and fail methods, in order to retrieve nice error messages
- // and assertion result
- let mock = {
- pass: function (msg) {
- test.pass(msg);
- test.waitUntilCallback = null;
- if (callback && !stopIt)
- callback();
- finished = true;
- },
- fail: function (msg) {
- // If we are called on test timeout, we stop the loop
- // and print which test keeps failing:
- if (stopIt) {
- test.console.error("test assertion never became true:\n",
- msg + "\n",
- currentWaitStack);
- if (timeout)
- timer.clearTimeout(timeout);
- return;
- }
- timeout = timer.setTimeout(loop, test.PAUSE_DELAY);
- }
- };
-
- // Automatically call args closures in order to build arguments for
- // assertion function
- let appliedArgs = [];
- for (let i = 0, l = args.length; i < l; i++) {
- let a = args[i];
- if (typeof a == "function") {
- try {
- a = a();
- }
- catch(e) {
- test.fail("Exception when calling asynchronous assertion: " + e +
- "\n" + e.stack);
- finished = true;
- return;
- }
- }
- appliedArgs.push(a);
- }
-
- // Finally call assertion function with current assertion values
- assertionMethod.apply(mock, appliedArgs);
- }
- loop();
- this.waitUntilCallback = loop;
-
- // Return an object with `then` method, to offer a way to execute
- // some code when the assertion passed or failed
- return {
- then: function (c) {
- callback = c;
-
- // In case of immediate positive result, we need to execute callback
- // immediately here:
- if (finished)
- callback();
- }
- };
- },
-
- waitUntilDone: function waitUntilDone(ms) {
- if (ms === undefined)
- ms = this.DEFAULT_PAUSE_TIMEOUT;
-
- var self = this;
-
- function tiredOfWaiting() {
- self._logTestFailed("timed out");
- if (self.waitUntilCallback) {
- self.waitUntilCallback(true);
- self.waitUntilCallback = null;
- }
- self.failed++;
- self.test.failed++;
- self.done();
- }
-
- // We may already have registered a timeout callback
- if (this.waitTimeout)
- timer.clearTimeout(this.waitTimeout);
-
- this.waitTimeout = timer.setTimeout(tiredOfWaiting, ms);
- },
-
- startMany: function startMany(options) {
- function runNextTest(self) {
- var test = options.tests.shift();
- if (options.stopOnError && self.test && self.test.failed) {
- self.console.error("aborted: test failed and --stop-on-error was specified");
- options.onDone(self);
- } else if (test) {
- self.start({test: test, onDone: runNextTest});
- } else {
- options.onDone(self);
- }
- }
- runNextTest(this);
- },
-
- start: function start(options) {
- this.test = options.test;
- this.test.passed = 0;
- this.test.failed = 0;
- this.test.errors = {};
-
- this.isDone = false;
- this.onDone = options.onDone;
- this.waitTimeout = null;
- this.testFailureLogged = false;
-
- try {
- this.console.info("executing '" + this.test.name + "'");
-
- if(this.test.setup) {
- this.test.setup(this);
- }
- this.test.testFunction(this);
- } catch (e) {
- this.exception(e);
- }
- if (this.waitTimeout === null)
- this.done();
- }
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/deprecated/window-utils.js b/tools/addon-sdk-1.12/lib/sdk/deprecated/window-utils.js
deleted file mode 100644
index 66fcfba..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/deprecated/window-utils.js
+++ /dev/null
@@ -1,201 +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': 'deprecated'
-};
-
-const { Cc, Ci } = require('chrome');
-const { EventEmitter } = require('../deprecated/events');
-const { Trait } = require('../deprecated/traits');
-const { when } = require('../system/unload');
-const { getInnerId, getOuterId, windows, isDocumentLoaded, isBrowser,
- getMostRecentBrowserWindow } = require('../window/utils');
-const errors = require('../deprecated/errors');
-const { deprecateFunction } = require('../util/deprecate');
-
-const windowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1'].
- getService(Ci.nsIWindowWatcher);
-const appShellService = Cc['@mozilla.org/appshell/appShellService;1'].
- getService(Ci.nsIAppShellService);
-
-/**
- * An iterator for XUL windows currently in the application.
- *
- * @return A generator that yields XUL windows exposing the
- * nsIDOMWindow interface.
- */
-function windowIterator() {
- // Bug 752631: We only pass already loaded window in order to avoid
- // breaking XUL windows DOM. DOM is broken when some JS code try
- // to access DOM during "uninitialized" state of the related document.
- let list = windows().filter(isDocumentLoaded);
- for (let i = 0, l = list.length; i < l; i++) {
- yield list[i];
- }
-};
-exports.windowIterator = windowIterator;
-
-/**
- * An iterator for browser windows currently open in the application.
- * @returns {Function}
- * A generator that yields browser windows exposing the `nsIDOMWindow`
- * interface.
- */
-function browserWindowIterator() {
- for each (let window in windowIterator()) {
- if (isBrowser(window))
- yield window;
- }
-}
-exports.browserWindowIterator = browserWindowIterator;
-
-function WindowTracker(delegate) {
- if (!(this instanceof WindowTracker)) {
- return new WindowTracker(delegate);
- }
-
- this._delegate = delegate;
- this._loadingWindows = [];
-
- for each (let window in windows())
- this._regWindow(window);
- windowWatcher.registerNotification(this);
-
- require('../system/unload').ensure(this);
-
- return this;
-};
-
-WindowTracker.prototype = {
- _regLoadingWindow: function _regLoadingWindow(window) {
- this._loadingWindows.push(window);
- window.addEventListener('load', this, true);
- },
-
- _unregLoadingWindow: function _unregLoadingWindow(window) {
- var index = this._loadingWindows.indexOf(window);
-
- if (index != -1) {
- this._loadingWindows.splice(index, 1);
- window.removeEventListener('load', this, true);
- }
- },
-
- _regWindow: function _regWindow(window) {
- if (window.document.readyState == 'complete') {
- this._unregLoadingWindow(window);
- this._delegate.onTrack(window);
- } else
- this._regLoadingWindow(window);
- },
-
- _unregWindow: function _unregWindow(window) {
- if (window.document.readyState == 'complete') {
- if (this._delegate.onUntrack)
- this._delegate.onUntrack(window);
- } else {
- this._unregLoadingWindow(window);
- }
- },
-
- unload: function unload() {
- windowWatcher.unregisterNotification(this);
- for each (let window in windows())
- this._unregWindow(window);
- },
-
- handleEvent: errors.catchAndLog(function handleEvent(event) {
- if (event.type == 'load' && event.target) {
- var window = event.target.defaultView;
- if (window)
- this._regWindow(window);
- }
- }),
-
- observe: errors.catchAndLog(function observe(subject, topic, data) {
- var window = subject.QueryInterface(Ci.nsIDOMWindow);
- if (topic == 'domwindowopened')
- this._regWindow(window);
- else
- this._unregWindow(window);
- })
-};
-exports.WindowTracker = WindowTracker;
-
-const WindowTrackerTrait = Trait.compose({
- _onTrack: Trait.required,
- _onUntrack: Trait.required,
- constructor: function WindowTrackerTrait() {
- WindowTracker({
- onTrack: this._onTrack.bind(this),
- onUntrack: this._onUntrack.bind(this)
- });
- }
-});
-exports.WindowTrackerTrait = WindowTrackerTrait;
-
-var gDocsToClose = [];
-
-function onDocUnload(event) {
- var index = gDocsToClose.indexOf(event.target);
- if (index == -1)
- throw new Error('internal error: unloading document not found');
- var document = gDocsToClose.splice(index, 1)[0];
- // Just in case, let's remove the event listener too.
- document.defaultView.removeEventListener('unload', onDocUnload, false);
-}
-
-onDocUnload = require('./errors').catchAndLog(onDocUnload);
-
-exports.closeOnUnload = function closeOnUnload(window) {
- window.addEventListener('unload', onDocUnload, false);
- gDocsToClose.push(window.document);
-};
-
-Object.defineProperties(exports, {
- activeWindow: {
- enumerable: true,
- get: function() {
- return Cc['@mozilla.org/appshell/window-mediator;1']
- .getService(Ci.nsIWindowMediator)
- .getMostRecentWindow(null);
- },
- set: function(window) {
- try { window.focus(); } catch (e) { }
- }
- },
- activeBrowserWindow: {
- enumerable: true,
- get: getMostRecentBrowserWindow
- }
-});
-
-
-/**
- * Returns the ID of the window's current inner window.
- */
-exports.getInnerId = deprecateFunction(getInnerId,
- 'require("window-utils").getInnerId is deprecated, ' +
- 'please use require("window/utils").getInnerId instead'
-);
-
-exports.getOuterId = deprecateFunction(getOuterId,
- 'require("window-utils").getOuterId is deprecated, ' +
- 'please use require("window/utils").getOuterId instead'
-);
-
-exports.isBrowser = deprecateFunction(isBrowser,
- 'require("window-utils").isBrowser is deprecated, ' +
- 'please use require("window/utils").isBrowser instead'
-);
-
-exports.hiddenWindow = appShellService.hiddenDOMWindow;
-
-when(
- function() {
- gDocsToClose.slice().forEach(
- function(doc) { doc.defaultView.close(); });
- });
diff --git a/tools/addon-sdk-1.12/lib/sdk/dom/events.js b/tools/addon-sdk-1.12/lib/sdk/dom/events.js
deleted file mode 100644
index 3f2d21c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/dom/events.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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"
-};
-
-// Utility function that returns copy of the given `text` with last character
-// removed if it is `"s"`.
-function singularify(text) {
- return text[text.length - 1] === "s" ? text.substr(0, text.length - 1) : text;
-}
-
-// Utility function that takes event type, argument is passed to
-// `document.createEvent` and returns name of the initializer method of the
-// given event. Please note that there are some event types whose initializer
-// methods can't be guessed by this function. For more details see following
-// link: https://developer.mozilla.org/En/DOM/Document.createEvent
-function getInitializerName(category) {
- return "init" + singularify(category);
-}
-
-/**
- * Registers an event `listener` on a given `element`, that will be called
- * when events of specified `type` is dispatched on the `element`.
- * @param {Element} element
- * Dom element to register listener on.
- * @param {String} type
- * A string representing the
- * [event type](https://developer.mozilla.org/en/DOM/event.type) to
- * listen for.
- * @param {Function} listener
- * Function that is called whenever an event of the specified `type`
- * occurs.
- * @param {Boolean} capture
- * If true, indicates that the user wishes to initiate capture. After
- * initiating capture, all events of the specified type will be dispatched
- * to the registered listener before being dispatched to any `EventTarget`s
- * beneath it in the DOM tree. Events which are bubbling upward through
- * the tree will not trigger a listener designated to use capture.
- * See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow)
- * for a detailed explanation.
- */
-function on(element, type, listener, capture) {
- // `capture` defaults to `false`.
- capture = capture || false;
- element.addEventListener(type, listener, capture);
-}
-exports.on = on;
-
-/**
- * Registers an event `listener` on a given `element`, that will be called
- * only once, next time event of specified `type` is dispatched on the
- * `element`.
- * @param {Element} element
- * Dom element to register listener on.
- * @param {String} type
- * A string representing the
- * [event type](https://developer.mozilla.org/en/DOM/event.type) to
- * listen for.
- * @param {Function} listener
- * Function that is called whenever an event of the specified `type`
- * occurs.
- * @param {Boolean} capture
- * If true, indicates that the user wishes to initiate capture. After
- * initiating capture, all events of the specified type will be dispatched
- * to the registered listener before being dispatched to any `EventTarget`s
- * beneath it in the DOM tree. Events which are bubbling upward through
- * the tree will not trigger a listener designated to use capture.
- * See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow)
- * for a detailed explanation.
- */
-function once(element, type, listener, capture) {
- on(element, type, function selfRemovableListener(event) {
- removeListener(element, type, selfRemovableListener, capture);
- listener.apply(this, arguments);
- }, capture);
-}
-exports.once = once;
-
-/**
- * Unregisters an event `listener` on a given `element` for the events of the
- * specified `type`.
- *
- * @param {Element} element
- * Dom element to unregister listener from.
- * @param {String} type
- * A string representing the
- * [event type](https://developer.mozilla.org/en/DOM/event.type) to
- * listen for.
- * @param {Function} listener
- * Function that is called whenever an event of the specified `type`
- * occurs.
- * @param {Boolean} capture
- * If true, indicates that the user wishes to initiate capture. After
- * initiating capture, all events of the specified type will be dispatched
- * to the registered listener before being dispatched to any `EventTarget`s
- * beneath it in the DOM tree. Events which are bubbling upward through
- * the tree will not trigger a listener designated to use capture.
- * See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow)
- * for a detailed explanation.
- */
-function removeListener(element, type, listener, capture) {
- element.removeEventListener(type, listener, capture);
-}
-exports.removeListener = removeListener;
-
-/**
- * Emits event of the specified `type` and `category` on the given `element`.
- * Specified `settings` are used to initialize event before dispatching it.
- * @param {Element} element
- * Dom element to dispatch event on.
- * @param {String} type
- * A string representing the
- * [event type](https://developer.mozilla.org/en/DOM/event.type).
- * @param {Object} options
- * Options object containing following properties:
- * - `category`: String passed to the `document.createEvent`. Option is
- * optional and defaults to "UIEvents".
- * - `initializer`: If passed it will be used as name of the method used
- * to initialize event. If omitted name will be generated from the
- * `category` field by prefixing it with `"init"` and removing last
- * character if it matches `"s"`.
- * - `settings`: Array of settings that are forwarded to the event
- * initializer after firs `type` argument.
- * @see https://developer.mozilla.org/En/DOM/Document.createEvent
- */
-function emit(element, type, { category, initializer, settings }) {
- category = category || "UIEvents";
- initializer = initializer || getInitializerName(category);
- let document = element.ownerDocument;
- let event = document.createEvent(category);
- event[initializer].apply(event, [type].concat(settings));
- element.dispatchEvent(event);
-};
-exports.emit = emit;
diff --git a/tools/addon-sdk-1.12/lib/sdk/dom/events/keys.js b/tools/addon-sdk-1.12/lib/sdk/dom/events/keys.js
deleted file mode 100644
index 01e4a0d..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/dom/events/keys.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { emit } = require("../events");
-const { getCodeForKey, toJSON } = require("../../keyboard/utils");
-const { has } = require("../../util/array");
-const { isString } = require("../../lang/type");
-
-const INITIALIZER = "initKeyEvent";
-const CATEGORY = "KeyboardEvent";
-
-function Options(options) {
- if (!isString(options))
- return options;
-
- var { key, modifiers } = toJSON(options);
- return {
- key: key,
- control: has(modifiers, "control"),
- alt: has(modifiers, "alt"),
- shift: has(modifiers, "shift"),
- meta: has(modifiers, "meta")
- };
-}
-
-var keyEvent = exports.keyEvent = function keyEvent(element, type, options) {
-
- emit(element, type, {
- initializer: INITIALIZER,
- category: CATEGORY,
- settings: [
- !("bubbles" in options) || options.bubbles !== false,
- !("cancelable" in options) || options.cancelable !== false,
- "window" in options && options.window ? options.window : null,
- "control" in options && !!options.control,
- "alt" in options && !!options.alt,
- "shift" in options && !!options.shift,
- "meta" in options && !!options.meta,
- getCodeForKey(options.key) || 0,
- options.key.length === 1 ? options.key.charCodeAt(0) : 0
- ]
- });
-}
-
-exports.keyDown = function keyDown(element, options) {
- keyEvent(element, "keydown", Options(options));
-};
-
-exports.keyUp = function keyUp(element, options) {
- keyEvent(element, "keyup", Options(options));
-};
-
-exports.keyPress = function keyPress(element, options) {
- keyEvent(element, "keypress", Options(options));
-};
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/event/core.js b/tools/addon-sdk-1.12/lib/sdk/event/core.js
deleted file mode 100644
index e63e3b9..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/event/core.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 UNCAUGHT_ERROR = 'An error event was emitted for which there was no listener.';
-const BAD_LISTENER = 'The event listener must be a function.';
-
-const { ns } = require('../core/namespace');
-
-const event = ns();
-
-// Utility function to access given event `target` object's event listeners for
-// the specific event `type`. If listeners for this type does not exists they
-// will be created.
-const observers = function observers(target, type) {
- let listeners = event(target);
- return type in listeners ? listeners[type] : listeners[type] = [];
-};
-
-/**
- * Registers an event `listener` that is called every time events of
- * specified `type` is emitted on the given event `target`.
- * @param {Object} target
- * Event target object.
- * @param {String} type
- * The type of event.
- * @param {Function} listener
- * The listener function that processes the event.
- */
-function on(target, type, listener) {
- if (typeof(listener) !== 'function')
- throw new Error(BAD_LISTENER);
-
- let listeners = observers(target, type);
- if (!~listeners.indexOf(listener))
- listeners.push(listener);
-}
-exports.on = on;
-
-/**
- * Registers an event `listener` that is called only the next time an event
- * of the specified `type` is emitted on the given event `target`.
- * @param {Object} target
- * Event target object.
- * @param {String} type
- * The type of the event.
- * @param {Function} listener
- * The listener function that processes the event.
- */
-function once(target, type, listener) {
- on(target, type, function observer() {
- off(target, type, observer);
- listener.apply(target, arguments);
- });
-}
-exports.once = once;
-
-/**
- * Execute each of the listeners in order with the supplied arguments.
- * All the exceptions that are thrown by listeners during the emit
- * are caught and can be handled by listeners of 'error' event. Thrown
- * exceptions are passed as an argument to an 'error' event listener.
- * If no 'error' listener is registered exception will be logged into an
- * error console.
- * @param {Object} target
- * Event target object.
- * @param {String} type
- * The type of event.
- * @params {Object|Number|String|Boolean} message
- * First argument that will be passed to listeners.
- * @params {Object|Number|String|Boolean} ...
- * More arguments that will be passed to listeners.
- */
-function emit(target, type, message /*, ...*/) {
- for each (let item in emit.lazy.apply(emit.lazy, arguments)) {
- // We just iterate, iterator take care of emitting events.
- }
-}
-
-/**
- * This is very experimental feature that you should not use unless absolutely
- * need it. Also it may be removed at any point without any further notice.
- *
- * Creates lazy iterator of return values of listeners. You can think of it
- * as lazy array of return values of listeners for the `emit` with the given
- * arguments.
- */
-emit.lazy = function lazy(target, type, message /*, ...*/) {
- let args = Array.slice(arguments, 2)
- let listeners = observers(target, type).slice()
- while (listeners.length) {
- try {
- yield listeners.shift().apply(target, args);
- }
- catch (error) {
- // If exception is not thrown by a error listener and error listener is
- // registered emit `error` event. Otherwise dump exception to the console.
- if (type !== 'error' && observers(target, 'error').length)
- emit(target, 'error', error);
- else
- console.exception(error);
- }
- }
-}
-exports.emit = emit;
-
-/**
- * Removes an event `listener` for the given event `type` on the given event
- * `target`. If no `listener` is passed removes all listeners of the given
- * `type`. If `type` is not passed removes all the listeners of the given
- * event `target`.
- * @param {Object} target
- * The event target object.
- * @param {String} type
- * The type of event.
- * @param {Function} listener
- * The listener function that processes the event.
- */
-function off(target, type, listener) {
- let length = arguments.length;
- if (length === 3) {
- let listeners = observers(target, type);
- let index = listeners.indexOf(listener);
- if (~index)
- listeners.splice(index, 1);
- }
- else if (length === 2) {
- observers(target, type).splice(0);
- }
- else if (length === 1) {
- let listeners = event(target);
- Object.keys(listeners).forEach(function(type) delete listeners[type]);
- }
-}
-exports.off = off;
-
-/**
- * Returns a number of event listeners registered for the given event `type`
- * on the given event `target`.
- */
-function count(target, type) {
- return observers(target, type).length;
-}
-exports.count = count;
diff --git a/tools/addon-sdk-1.12/lib/sdk/event/target.js b/tools/addon-sdk-1.12/lib/sdk/event/target.js
deleted file mode 100644
index b8906c0..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/event/target.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "stable"
-};
-
-const { on, once, off } = require('./core');
-const { method } = require('../lang/functional');
-const { Class } = require('../core/heritage');
-
-const EVENT_TYPE_PATTERN = /^on([A-Z]\w+$)/;
-
-/**
- * `EventTarget` is an exemplar for creating an objects that can be used to
- * add / remove event listeners on them. Events on these objects may be emitted
- * via `emit` function exported by 'event/core' module.
- */
-const EventTarget = Class({
- /**
- * Method initializes `this` event source. It goes through properties of a
- * given `options` and registers listeners for the ones that look like an
- * event listeners.
- */
- initialize: function initialize(options) {
- options = options || {};
- // Go through each property and registers event listeners for those
- // that have a name matching following pattern (`onEventType`).
- Object.keys(options).forEach(function onEach(key) {
- let match = EVENT_TYPE_PATTERN.exec(key);
- let type = match && match[1].toLowerCase();
- let listener = options[key];
-
- if (type && typeof(listener) === 'function')
- this.on(type, listener);
- }, this);
- },
- /**
- * Registers an event `listener` that is called every time events of
- * specified `type` are emitted.
- * @param {String} type
- * The type of event.
- * @param {Function} listener
- * The listener function that processes the event.
- * @example
- * worker.on('message', function (data) {
- * console.log('data received: ' + data)
- * })
- */
- on: method(on),
- /**
- * Registers an event `listener` that is called once the next time an event
- * of the specified `type` is emitted.
- * @param {String} type
- * The type of the event.
- * @param {Function} listener
- * The listener function that processes the event.
- */
- once: method(once),
- /**
- * Removes an event `listener` for the given event `type`.
- * @param {String} type
- * The type of event.
- * @param {Function} listener
- * The listener function that processes the event.
- */
- removeListener: function removeListener(type, listener) {
- // Note: We can't just wrap `off` in `method` as we do it for other methods
- // cause skipping a second or third argument will behave very differently
- // than intended. This way we make sure all arguments are passed and only
- // one listener is removed at most.
- off(this, type, listener);
- }
-});
-exports.EventTarget = EventTarget;
diff --git a/tools/addon-sdk-1.12/lib/sdk/frame/hidden-frame.js b/tools/addon-sdk-1.12/lib/sdk/frame/hidden-frame.js
deleted file mode 100644
index 1bf51de..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/frame/hidden-frame.js
+++ /dev/null
@@ -1,181 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "experimental"
-};
-
-const {Cc, Ci} = require("chrome");
-const errors = require("../deprecated/errors");
-const apiUtils = require("../deprecated/api-utils");
-const timer = require("../timers");
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-let hostFrame, hostDocument, hiddenWindow, isHostFrameReady = false;
-
-if (!require("../system/xul-app").isOneOf(["Firefox", "Fennec", "Thunderbird"])) {
- throw new Error([
- "The hidden-frame module currently supports only Firefox and Thunderbird. ",
- "In the future, we would like it to support other applications, however. ",
- "Please see https://bugzilla.mozilla.org/show_bug.cgi?id=546740 for more ",
- "information."
- ].join(""));
-}
-
-let appShellService = Cc["@mozilla.org/appshell/appShellService;1"].
- getService(Ci.nsIAppShellService);
-hiddenWindow = appShellService.hiddenDOMWindow;
-
-if (!hiddenWindow) {
- throw new Error([
- "The hidden-frame module needs an app that supports a hidden window. ",
- "We would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=546740 for more information."
- ].join(""));
-}
-
-// Check if we can use the hidden window itself to host our iframes.
-// If it's not a suitable host, the hostFrame will be lazily created
-// by the first HiddenFrame instance.
-if (hiddenWindow.location.protocol == "chrome:" &&
- (hiddenWindow.document.contentType == "application/vnd.mozilla.xul+xml" ||
- hiddenWindow.document.contentType == "application/xhtml+xml")) {
- hostFrame = hiddenWindow;
- hostDocument = hiddenWindow.document;
- isHostFrameReady = true;
-}
-
-function setHostFrameReady() {
- hostDocument = hostFrame.contentDocument;
- hostFrame.removeEventListener("DOMContentLoaded", setHostFrameReady, false);
- isHostFrameReady = true;
-}
-
-// This cache is used to access friend properties between functions
-// without exposing them on the public API.
-let cache = [];
-
-exports.HiddenFrame = apiUtils.publicConstructor(HiddenFrame);
-
-function HiddenFrame(options) {
- options = options || {};
- let self = this;
- let validOptions = apiUtils.validateOptions(options, {
- onReady: {
- is: ["undefined", "function", "array"],
- ok: function(v) {
- if (apiUtils.getTypeOf(v) === "array") {
- // make sure every item is a function
- return v.every(function (item) typeof(item) === "function")
- }
- return true;
- }
- },
- onUnload: {
- is: ["undefined", "function"]
- }
- });
-
- for (let key in validOptions) {
- let val = validOptions[key];
- if (typeof(val) != "undefined")
- options[key] = val;
- }
-
- require("../util/collection").addCollectionProperty(this, "onReady");
- if (options.onReady)
- this.onReady.add(options.onReady);
- if (options.onUnload)
- this.onUnload = options.onUnload;
-
- if (!hostFrame) {
- hostFrame = hiddenWindow.document.createElement("iframe");
-
- // ugly ugly hack. This is the most lightweight chrome:// file I could find on the tree
- // This hack should be removed by proper platform support on bug 565388
- hostFrame.setAttribute("src", "chrome://global/content/mozilla.xhtml");
- hostFrame.addEventListener("DOMContentLoaded", setHostFrameReady, false);
-
- hiddenWindow.document.body.appendChild(hostFrame);
- }
-
- this.toString = function toString() "[object Frame]";
-}
-
-exports.add = function JP_SDK_Frame_add(frame) {
- if (!(frame instanceof HiddenFrame))
- throw new Error("The object to be added must be a HiddenFrame.");
-
- // This instance was already added.
- if (cache.filter(function (v) v.frame === frame)[0])
- return frame;
-
- function createElement() {
- hostFrame.removeEventListener("DOMContentLoaded", createElement, false);
-
- let element = hostDocument.createElementNS(XUL_NS, "iframe");
-
- element.setAttribute("type", "content");
- hostDocument.documentElement.appendChild(element);
-
- /* Public API: hiddenFrame.element */
- frame.__defineGetter__("element", function () element);
-
- // Notify consumers that the frame is ready.
- function onReadyListener(event) {
- element.removeEventListener("DOMContentLoaded", onReadyListener, false);
- if (event.target == element.contentDocument) {
- for (let handler in frame.onReady)
- errors.catchAndLog(function () handler.call(frame))();
- }
- }
- element.addEventListener("DOMContentLoaded", onReadyListener, false);
-
- cache.push({
- frame: frame,
- element: element,
- unload: function unload() {
- // Call before removing to let a chance to avoid "dead object" exception
- if (typeof frame.onUnload === "function")
- frame.onUnload();
- hostDocument.documentElement.removeChild(element);
- }
- });
- }
-
- /* Begin element construction or schedule it for later */
- if (isHostFrameReady) {
- createElement();
- } else {
- hostFrame.addEventListener("DOMContentLoaded", createElement, false);
- }
-
- return frame;
-}
-
-exports.remove = function remove(frame) {
- if (!(frame instanceof HiddenFrame))
- throw new Error("The object to be removed must be a HiddenFrame.");
-
- let entry = cache.filter(function (v) v.frame === frame)[0];
- if (!entry)
- return;
-
- // Remove from cache before calling in order to avoid loop
- cache.splice(cache.indexOf(entry), 1);
- entry.unload();
-}
-
-require("../system/unload").when(function () {
- for each (let entry in cache.slice())
- exports.remove(entry.frame);
-
- if (hostFrame && hostFrame !== hiddenWindow)
- hiddenWindow.document.body.removeChild(hostFrame);
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/frame/utils.js b/tools/addon-sdk-1.12/lib/sdk/frame/utils.js
deleted file mode 100644
index ad4ca7c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/frame/utils.js
+++ /dev/null
@@ -1,63 +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": "experimental"
-};
-
-const XUL = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
-
-/**
- * Creates a XUL `browser` element in a privileged document.
- * @params {nsIDOMDocument} document
- * @params {String} options.type
- * By default is 'content' for possible values see:
- * https://developer.mozilla.org/en/XUL/iframe#a-browser.type
- * @params {String} options.uri
- * URI of the document to be loaded into created frame.
- * @params {Boolean} options.remote
- * If `true` separate process will be used for this frame, also in such
- * case all the following options are ignored.
- * @params {Boolean} options.allowAuth
- * Whether to allow auth dialogs. Defaults to `false`.
- * @params {Boolean} options.allowJavascript
- * Whether to allow Javascript execution. Defaults to `false`.
- * @params {Boolean} options.allowPlugins
- * Whether to allow plugin execution. Defaults to `false`.
- */
-function create(document, options) {
- options = options || {};
- let remote = 'remote' in options && options.remote === true;
-
- let frame = document.createElementNS(XUL, 'browser');
- // Type="content" is mandatory to enable stuff here:
- // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsFrameLoader.cpp#1776
- frame.setAttribute('type', options.type || 'content');
- frame.setAttribute('src', options.uri || 'about:blank');
-
- // Load in separate process if `options.remote` is `true`.
- // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsFrameLoader.cpp#1347
- if (remote) {
- // We remove XBL binding to avoid execution of code that is not going to
- // work because browser has no docShell attribute in remote mode
- // (for example)
- frame.setAttribute('style', '-moz-binding: none;');
- frame.setAttribute('remote', 'true');
- }
-
- document.documentElement.appendChild(frame);
-
- // If browser is remote it won't have a `docShell`.
- if (!remote) {
- let docShell = frame.docShell;
- docShell.allowAuth = options.allowAuth || false;
- docShell.allowJavascript = options.allowJavascript || false;
- docShell.allowPlugins = options.allowPlugins || false;
- }
-
- return frame;
-}
-exports.create = create;
diff --git a/tools/addon-sdk-1.12/lib/sdk/hotkeys.js b/tools/addon-sdk-1.12/lib/sdk/hotkeys.js
deleted file mode 100644
index 3491d2c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/hotkeys.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "stable"
-};
-
-const INVALID_HOTKEY = "Hotkey must have at least one modifier.";
-
-const { toJSON: jsonify, toString: stringify,
- isFunctionKey } = require("./keyboard/utils");
-const { register, unregister } = require("./keyboard/hotkeys");
-
-const Hotkey = exports.Hotkey = function Hotkey(options) {
- if (!(this instanceof Hotkey))
- return new Hotkey(options);
-
- // Parsing key combination string.
- let hotkey = jsonify(options.combo);
- if (!isFunctionKey(hotkey.key) && !hotkey.modifiers.length) {
- throw new TypeError(INVALID_HOTKEY);
- }
-
- this.onPress = options.onPress;
- this.toString = stringify.bind(null, hotkey);
- // Registering listener on keyboard combination enclosed by this hotkey.
- // Please note that `this.toString()` is a normalized version of
- // `options.combination` where order of modifiers is sorted and `accel` is
- // replaced with platform specific key.
- register(this.toString(), this.onPress);
- // We freeze instance before returning it in order to make it's properties
- // read-only.
- return Object.freeze(this);
-};
-Hotkey.prototype.destroy = function destroy() {
- unregister(this.toString(), this.onPress);
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/io/byte-streams.js b/tools/addon-sdk-1.12/lib/sdk/io/byte-streams.js
deleted file mode 100644
index 27b1802..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/io/byte-streams.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et filetype=javascript
- * 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": "experimental"
-};
-
-exports.ByteReader = ByteReader;
-exports.ByteWriter = ByteWriter;
-
-const {Cc, Ci} = require("chrome");
-
-// This just controls the maximum number of bytes we read in at one time.
-const BUFFER_BYTE_LEN = 0x8000;
-
-function ByteReader(inputStream) {
- const self = this;
-
- let stream = Cc["@mozilla.org/binaryinputstream;1"].
- createInstance(Ci.nsIBinaryInputStream);
- stream.setInputStream(inputStream);
-
- let manager = new StreamManager(this, stream);
-
- this.read = function ByteReader_read(numBytes) {
- manager.ensureOpened();
- if (typeof(numBytes) !== "number")
- numBytes = Infinity;
-
- let data = "";
- let read = 0;
- try {
- while (true) {
- let avail = stream.available();
- let toRead = Math.min(numBytes - read, avail, BUFFER_BYTE_LEN);
- if (toRead <= 0)
- break;
- data += stream.readBytes(toRead);
- read += toRead;
- }
- }
- catch (err) {
- throw new Error("Error reading from stream: " + err);
- }
-
- return data;
- };
-}
-
-function ByteWriter(outputStream) {
- const self = this;
-
- let stream = Cc["@mozilla.org/binaryoutputstream;1"].
- createInstance(Ci.nsIBinaryOutputStream);
- stream.setOutputStream(outputStream);
-
- let manager = new StreamManager(this, stream);
-
- this.write = function ByteWriter_write(str) {
- manager.ensureOpened();
- try {
- stream.writeBytes(str, str.length);
- }
- catch (err) {
- throw new Error("Error writing to stream: " + err);
- }
- };
-}
-
-
-// This manages the lifetime of stream, a ByteReader or ByteWriter. It defines
-// closed and close() on stream and registers an unload listener that closes
-// rawStream if it's still opened. It also provides ensureOpened(), which
-// throws an exception if the stream is closed.
-function StreamManager(stream, rawStream) {
- const self = this;
- this.rawStream = rawStream;
- this.opened = true;
-
- stream.__defineGetter__("closed", function stream_closed() {
- return !self.opened;
- });
-
- stream.close = function stream_close() {
- self.ensureOpened();
- self.unload();
- };
-
- require("../system/unload").ensure(this);
-}
-
-StreamManager.prototype = {
- ensureOpened: function StreamManager_ensureOpened() {
- if (!this.opened)
- throw new Error("The stream is closed and cannot be used.");
- },
- unload: function StreamManager_unload() {
- this.rawStream.close();
- this.opened = false;
- }
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/io/data.js b/tools/addon-sdk-1.12/lib/sdk/io/data.js
deleted file mode 100644
index 9dd7246..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/io/data.js
+++ /dev/null
@@ -1,84 +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 { Cc, Ci, Cu } = require("chrome");
-const base64 = require("../base64");
-
-const IOService = Cc["@mozilla.org/network/io-service;1"].
- getService(Ci.nsIIOService);
-
-const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm");
-const FaviconService = Cc["@mozilla.org/browser/favicon-service;1"].
- getService(Ci.nsIFaviconService);
-const { deprecateFunction, deprecatedUsage } = require("../util/deprecate");
-
-const PNG_B64 = "data:image/png;base64,";
-const DEF_FAVICON_URI = "chrome://mozapps/skin/places/defaultFavicon.png";
-let DEF_FAVICON = null;
-
-/**
- * Takes URI of the page and returns associated favicon URI.
- * If page under passed uri has no favicon then base64 encoded data URI of
- * default faveicon is returned.
- * @param {String} uri
- * @returns {String}
- */
-exports.getFaviconURIForLocation = function getFaviconURIForLocation(uri) {
- let pageURI = NetUtil.newURI(uri);
- try {
- return FaviconService.getFaviconDataAsDataURL(
- FaviconService.getFaviconForPage(pageURI));
- }
- catch(e) {
- if (!DEF_FAVICON) {
- DEF_FAVICON = PNG_B64 +
- base64.encode(getChromeURIContent(DEF_FAVICON_URI));
- }
- return DEF_FAVICON;
- }
-}
-
-/**
- * Takes chrome URI and returns content under that URI.
- * @param {String} chromeURI
- * @returns {String}
- */
-function getChromeURIContent(chromeURI) {
- let channel = IOService.newChannel(chromeURI, null, null);
- let input = channel.open();
- let stream = Cc["@mozilla.org/binaryinputstream;1"].
- createInstance(Ci.nsIBinaryInputStream);
- stream.setInputStream(input);
- let content = stream.readBytes(input.available());
- stream.close();
- input.close();
- return content;
-}
-exports.getChromeURIContent = function deprecated_getChromeURIContent() {
- deprecatedUsage(
- 'getChromeURIContent is deprecated, ' +
- 'please use require("sdk/net/url").readURI instead.'
- );
-};
-
-/**
- * Creates a base-64 encoded ASCII string from a string of binary data.
- */
-exports.base64Encode = deprecateFunction(base64.encode,
- 'base64Encode is deprecated, ' +
- 'please use require("sdk/base64").encode instead.'
-);
-/**
- * Decodes a string of data which has been encoded using base-64 encoding.
- */
-exports.base64Decode = deprecateFunction(base64.decode,
- 'base64Dencode is deprecated, ' +
- 'please use require("sdk/base64").decode instead.'
-);
diff --git a/tools/addon-sdk-1.12/lib/sdk/io/file.js b/tools/addon-sdk-1.12/lib/sdk/io/file.js
deleted file mode 100644
index 735edea..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/io/file.js
+++ /dev/null
@@ -1,196 +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": "experimental"
-};
-
-const {Cc,Ci,Cr} = require("chrome");
-const byteStreams = require("./byte-streams");
-const textStreams = require("./text-streams");
-
-// Flags passed when opening a file. See nsprpub/pr/include/prio.h.
-const OPEN_FLAGS = {
- RDONLY: parseInt("0x01"),
- WRONLY: parseInt("0x02"),
- CREATE_FILE: parseInt("0x08"),
- APPEND: parseInt("0x10"),
- TRUNCATE: parseInt("0x20"),
- EXCL: parseInt("0x80")
-};
-
-var dirsvc = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties);
-
-function MozFile(path) {
- var file = Cc['@mozilla.org/file/local;1']
- .createInstance(Ci.nsILocalFile);
- file.initWithPath(path);
- return file;
-}
-
-function ensureReadable(file) {
- if (!file.isReadable())
- throw new Error("path is not readable: " + file.path);
-}
-
-function ensureDir(file) {
- ensureExists(file);
- if (!file.isDirectory())
- throw new Error("path is not a directory: " + file.path);
-}
-
-function ensureFile(file) {
- ensureExists(file);
- if (!file.isFile())
- throw new Error("path is not a file: " + file.path);
-}
-
-function ensureExists(file) {
- if (!file.exists())
- throw friendlyError(Cr.NS_ERROR_FILE_NOT_FOUND, file.path);
-}
-
-function friendlyError(errOrResult, filename) {
- var isResult = typeof(errOrResult) === "number";
- var result = isResult ? errOrResult : errOrResult.result;
- switch (result) {
- case Cr.NS_ERROR_FILE_NOT_FOUND:
- return new Error("path does not exist: " + filename);
- }
- return isResult ? new Error("XPCOM error code: " + errOrResult) : errOrResult;
-}
-
-exports.exists = function exists(filename) {
- return MozFile(filename).exists();
-};
-
-exports.isFile = function isFile(filename) {
- return MozFile(filename).isFile();
-};
-
-exports.read = function read(filename, mode) {
- if (typeof(mode) !== "string")
- mode = "";
-
- // Ensure mode is read-only.
- mode = /b/.test(mode) ? "b" : "";
-
- var stream = exports.open(filename, mode);
- try {
- var str = stream.read();
- }
- finally {
- stream.close();
- }
-
- return str;
-};
-
-exports.join = function join(base) {
- if (arguments.length < 2)
- throw new Error("need at least 2 args");
- base = MozFile(base);
- for (var i = 1; i < arguments.length; i++)
- base.append(arguments[i]);
- return base.path;
-};
-
-exports.dirname = function dirname(path) {
- var parent = MozFile(path).parent;
- return parent ? parent.path : "";
-};
-
-exports.basename = function basename(path) {
- var leafName = MozFile(path).leafName;
-
- // On Windows, leafName when the path is a volume letter and colon ("c:") is
- // the path itself. But such a path has no basename, so we want the empty
- // string.
- return leafName == path ? "" : leafName;
-};
-
-exports.list = function list(path) {
- var file = MozFile(path);
- ensureDir(file);
- ensureReadable(file);
-
- var entries = file.directoryEntries;
- var entryNames = [];
- while(entries.hasMoreElements()) {
- var entry = entries.getNext();
- entry.QueryInterface(Ci.nsIFile);
- entryNames.push(entry.leafName);
- }
- return entryNames;
-};
-
-exports.open = function open(filename, mode) {
- var file = MozFile(filename);
- if (typeof(mode) !== "string")
- mode = "";
-
- // File opened for write only.
- if (/w/.test(mode)) {
- if (file.exists())
- ensureFile(file);
- var stream = Cc['@mozilla.org/network/file-output-stream;1'].
- createInstance(Ci.nsIFileOutputStream);
- var openFlags = OPEN_FLAGS.WRONLY |
- OPEN_FLAGS.CREATE_FILE |
- OPEN_FLAGS.TRUNCATE;
- var permFlags = parseInt("0644"); // u+rw go+r
- try {
- stream.init(file, openFlags, permFlags, 0);
- }
- catch (err) {
- throw friendlyError(err, filename);
- }
- return /b/.test(mode) ?
- new byteStreams.ByteWriter(stream) :
- new textStreams.TextWriter(stream);
- }
-
- // File opened for read only, the default.
- ensureFile(file);
- stream = Cc['@mozilla.org/network/file-input-stream;1'].
- createInstance(Ci.nsIFileInputStream);
- try {
- stream.init(file, OPEN_FLAGS.RDONLY, 0, 0);
- }
- catch (err) {
- throw friendlyError(err, filename);
- }
- return /b/.test(mode) ?
- new byteStreams.ByteReader(stream) :
- new textStreams.TextReader(stream);
-};
-
-exports.remove = function remove(path) {
- var file = MozFile(path);
- ensureFile(file);
- file.remove(false);
-};
-
-exports.mkpath = function mkpath(path) {
- var file = MozFile(path);
- if (!file.exists())
- file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755")); // u+rwx go+rx
- else if (!file.isDirectory())
- throw new Error("The path already exists and is not a directory: " + path);
-};
-
-exports.rmdir = function rmdir(path) {
- var file = MozFile(path);
- ensureDir(file);
- try {
- file.remove(false);
- }
- catch (err) {
- // Bug 566950 explains why we're not catching a specific exception here.
- throw new Error("The directory is not empty: " + path);
- }
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/io/text-streams.js b/tools/addon-sdk-1.12/lib/sdk/io/text-streams.js
deleted file mode 100644
index 0aa469d..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/io/text-streams.js
+++ /dev/null
@@ -1,244 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et filetype=javascript
- * 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": "experimental"
-};
-
-const {Cc,Ci,Cu,components} = require("chrome");
-var NetUtil = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", NetUtil);
-NetUtil = NetUtil.NetUtil;
-
-// NetUtil.asyncCopy() uses this buffer length, and since we call it, for best
-// performance we use it, too.
-const BUFFER_BYTE_LEN = 0x8000;
-const PR_UINT32_MAX = 0xffffffff;
-const DEFAULT_CHARSET = "UTF-8";
-
-exports.TextReader = TextReader;
-exports.TextWriter = TextWriter;
-
-/**
- * An input stream that reads text from a backing stream using a given text
- * encoding.
- *
- * @param inputStream
- * The stream is backed by this nsIInputStream. It must already be
- * opened.
- * @param charset
- * Text in inputStream is expected to be in this character encoding. If
- * not given, "UTF-8" is assumed. See nsICharsetConverterManager.idl for
- * documentation on how to determine other valid values for this.
- */
-function TextReader(inputStream, charset) {
- const self = this;
- charset = checkCharset(charset);
-
- let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].
- createInstance(Ci.nsIConverterInputStream);
- stream.init(inputStream, charset, BUFFER_BYTE_LEN,
- Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
- let manager = new StreamManager(this, stream);
-
- /**
- * Reads a string from the stream. If the stream is closed, an exception is
- * thrown.
- *
- * @param numChars
- * The number of characters to read. If not given, the remainder of
- * the stream is read.
- * @return The string read. If the stream is already at EOS, returns the
- * empty string.
- */
- this.read = function TextReader_read(numChars) {
- manager.ensureOpened();
-
- let readAll = false;
- if (typeof(numChars) === "number")
- numChars = Math.max(numChars, 0);
- else
- readAll = true;
-
- let str = "";
- let totalRead = 0;
- let chunkRead = 1;
-
- // Read in numChars or until EOS, whichever comes first. Note that the
- // units here are characters, not bytes.
- while (true) {
- let chunk = {};
- let toRead = readAll ?
- PR_UINT32_MAX :
- Math.min(numChars - totalRead, PR_UINT32_MAX);
- if (toRead <= 0 || chunkRead <= 0)
- break;
-
- // The converter stream reads in at most BUFFER_BYTE_LEN bytes in a call
- // to readString, enough to fill its byte buffer. chunkRead will be the
- // number of characters encoded by the bytes in that buffer.
- chunkRead = stream.readString(toRead, chunk);
- str += chunk.value;
- totalRead += chunkRead;
- }
-
- return str;
- };
-}
-
-/**
- * A buffered output stream that writes text to a backing stream using a given
- * text encoding.
- *
- * @param outputStream
- * The stream is backed by this nsIOutputStream. It must already be
- * opened.
- * @param charset
- * Text will be written to outputStream using this character encoding.
- * If not given, "UTF-8" is assumed. See nsICharsetConverterManager.idl
- * for documentation on how to determine other valid values for this.
- */
-function TextWriter(outputStream, charset) {
- const self = this;
- charset = checkCharset(charset);
-
- let stream = outputStream;
-
- // Buffer outputStream if it's not already.
- let ioUtils = Cc["@mozilla.org/io-util;1"].getService(Ci.nsIIOUtil);
- if (!ioUtils.outputStreamIsBuffered(outputStream)) {
- stream = Cc["@mozilla.org/network/buffered-output-stream;1"].
- createInstance(Ci.nsIBufferedOutputStream);
- stream.init(outputStream, BUFFER_BYTE_LEN);
- }
-
- // I'd like to use nsIConverterOutputStream. But NetUtil.asyncCopy(), which
- // we use below in writeAsync(), naturally expects its sink to be an instance
- // of nsIOutputStream, which nsIConverterOutputStream's only implementation is
- // not. So we use uconv and manually convert all strings before writing to
- // outputStream.
- let uconv = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
- createInstance(Ci.nsIScriptableUnicodeConverter);
- uconv.charset = charset;
-
- let manager = new StreamManager(this, stream);
-
- /**
- * Flushes the backing stream's buffer.
- */
- this.flush = function TextWriter_flush() {
- manager.ensureOpened();
- stream.flush();
- };
-
- /**
- * Writes a string to the stream. If the stream is closed, an exception is
- * thrown.
- *
- * @param str
- * The string to write.
- */
- this.write = function TextWriter_write(str) {
- manager.ensureOpened();
- let istream = uconv.convertToInputStream(str);
- let len = istream.available();
- while (len > 0) {
- stream.writeFrom(istream, len);
- len = istream.available();
- }
- istream.close();
- };
-
- /**
- * Writes a string on a background thread. After the write completes, the
- * backing stream's buffer is flushed, and both the stream and the backing
- * stream are closed, also on the background thread. If the stream is already
- * closed, an exception is thrown immediately.
- *
- * @param str
- * The string to write.
- * @param callback
- * An optional function. If given, it's called as callback(error) when
- * the write completes. error is an Error object or undefined if there
- * was no error. Inside callback, |this| is the stream object.
- */
- this.writeAsync = function TextWriter_writeAsync(str, callback) {
- manager.ensureOpened();
- let istream = uconv.convertToInputStream(str);
- NetUtil.asyncCopy(istream, stream, function (result) {
- let err = components.isSuccessCode(result) ? undefined :
- new Error("An error occured while writing to the stream: " + result);
- if (err)
- console.error(err);
-
- // asyncCopy() closes its output (and input) stream.
- manager.opened = false;
-
- if (typeof(callback) === "function") {
- try {
- callback.call(self, err);
- }
- catch (exc) {
- console.exception(exc);
- }
- }
- });
- };
-}
-
-// This manages the lifetime of stream, a TextReader or TextWriter. It defines
-// closed and close() on stream and registers an unload listener that closes
-// rawStream if it's still opened. It also provides ensureOpened(), which
-// throws an exception if the stream is closed.
-function StreamManager(stream, rawStream) {
- const self = this;
- this.rawStream = rawStream;
- this.opened = true;
-
- /**
- * True iff the stream is closed.
- */
- stream.__defineGetter__("closed", function stream_closed() {
- return !self.opened;
- });
-
- /**
- * Closes both the stream and its backing stream. If the stream is already
- * closed, an exception is thrown. For TextWriters, this first flushes the
- * backing stream's buffer.
- */
- stream.close = function stream_close() {
- self.ensureOpened();
- self.unload();
- };
-
- require("../system/unload").ensure(this);
-}
-
-StreamManager.prototype = {
- ensureOpened: function StreamManager_ensureOpened() {
- if (!this.opened)
- throw new Error("The stream is closed and cannot be used.");
- },
- unload: function StreamManager_unload() {
- // TextWriter.writeAsync() causes rawStream to close and therefore sets
- // opened to false, so check that we're still opened.
- if (this.opened) {
- // Calling close() on both an nsIUnicharInputStream and
- // nsIBufferedOutputStream closes their backing streams. It also forces
- // nsIOutputStreams to flush first.
- this.rawStream.close();
- this.opened = false;
- }
- }
-};
-
-function checkCharset(charset) {
- return typeof(charset) === "string" ? charset : DEFAULT_CHARSET;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/keyboard/hotkeys.js b/tools/addon-sdk-1.12/lib/sdk/keyboard/hotkeys.js
deleted file mode 100644
index 2d963ab..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/keyboard/hotkeys.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { observer: keyboardObserver } = require("./observer");
-const { getKeyForCode, normalize, isFunctionKey,
- MODIFIERS } = require("./utils");
-
-/**
- * Register a global `hotkey` that executes `listener` when the key combination
- * in `hotkey` is pressed. If more then one `listener` is registered on the same
- * key combination only last one will be executed.
- *
- * @param {string} hotkey
- * Key combination in the format of 'modifier key'.
- *
- * Examples:
- *
- * "accel s"
- * "meta shift i"
- * "control alt d"
- *
- * Modifier keynames:
- *
- * - **shift**: The Shift key.
- * - **alt**: The Alt key. On the Macintosh, this is the Option key. On
- * Macintosh this can only be used in conjunction with another modifier,
- * since `Alt+Letter` combinations are reserved for entering special
- * characters in text.
- * - **meta**: The Meta key. On the Macintosh, this is the Command key.
- * - **control**: The Control key.
- * - **accel**: The key used for keyboard shortcuts on the user's platform,
- * which is Control on Windows and Linux, and Command on Mac. Usually, this
- * would be the value you would use.
- *
- * @param {function} listener
- * Function to execute when the `hotkey` is executed.
- */
-exports.register = function register(hotkey, listener) {
- hotkey = normalize(hotkey);
- hotkeys[hotkey] = listener;
-};
-
-/**
- * Unregister a global `hotkey`. If passed `listener` is not the one registered
- * for the given `hotkey`, the call to this function will be ignored.
- *
- * @param {string} hotkey
- * Key combination in the format of 'modifier key'.
- * @param {function} listener
- * Function that will be invoked when the `hotkey` is pressed.
- */
-exports.unregister = function unregister(hotkey, listener) {
- hotkey = normalize(hotkey);
- if (hotkeys[hotkey] === listener)
- delete hotkeys[hotkey];
-};
-
-/**
- * Map of hotkeys and associated functions.
- */
-const hotkeys = exports.hotkeys = {};
-
-keyboardObserver.on("keydown", function onKeypress(event, window) {
- let key, modifiers = [];
- let isChar = "isChar" in event && event.isChar;
- let which = "which" in event ? event.which : null;
- let keyCode = "keyCode" in event ? event.keyCode : null;
-
- if ("shiftKey" in event && event.shiftKey)
- modifiers.push("shift");
- if ("altKey" in event && event.altKey)
- modifiers.push("alt");
- if ("ctrlKey" in event && event.ctrlKey)
- modifiers.push("control");
- if ("metaKey" in event && event.metaKey)
- modifiers.push("meta");
-
- // If it's not a printable character then we fall back to a human readable
- // equivalent of one of the following constants.
- // http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/events/nsIDOMKeyEvent.idl
- key = getKeyForCode(keyCode);
-
- // If only non-function (f1 - f24) key or only modifiers are pressed we don't
- // have a valid combination so we return immediately (Also, sometimes
- // `keyCode` may be one for the modifier which means we do not have a
- // modifier).
- if (!key || (!isFunctionKey(key) && !modifiers.length) || key in MODIFIERS)
- return;
-
- let combination = normalize({ key: key, modifiers: modifiers });
- let hotkey = hotkeys[combination];
-
- if (hotkey) {
- try {
- hotkey();
- } catch (exception) {
- console.exception(exception);
- } finally {
- // Work around bug 582052 by preventing the (nonexistent) default action.
- event.preventDefault();
- }
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/keyboard/observer.js b/tools/addon-sdk-1.12/lib/sdk/keyboard/observer.js
deleted file mode 100644
index 26c0a83..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/keyboard/observer.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { Trait } = require("../deprecated/light-traits");
-const { EventEmitterTrait: EventEmitter } = require("../deprecated/events");
-const { DOMEventAssembler } = require("../deprecated/events/assembler");
-const { browserWindowIterator } = require('../deprecated/window-utils');
-const { isBrowser } = require('../window/utils');
-const { observer: windowObserver } = require("../windows/observer");
-
-// Event emitter objects used to register listeners and emit events on them
-// when they occur.
-const observer = Trait.compose(DOMEventAssembler, EventEmitter).create({
- /**
- * Method is implemented by `EventEmitter` and is used just for emitting
- * events on registered listeners.
- */
- _emit: Trait.required,
- /**
- * Events that are supported and emitted by the module.
- */
- supportedEventsTypes: [ "keydown", "keyup", "keypress" ],
- /**
- * 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) {
- this._emit(event.type, event, event.target.ownerDocument.defaultView);
- }
-});
-
-// Adding each opened window to a list of observed windows.
-windowObserver.on("open", function onOpen(window) {
- if (isBrowser(window))
- observer.observe(window);
-});
-// Removing each closed window form the list of observed windows.
-windowObserver.on("close", function onClose(window) {
- if (isBrowser(window))
- observer.ignore(window);
-});
-
-// Making observer aware of already opened windows.
-for each (let window in browserWindowIterator())
- observer.observe(window);
-
-exports.observer = observer;
diff --git a/tools/addon-sdk-1.12/lib/sdk/keyboard/utils.js b/tools/addon-sdk-1.12/lib/sdk/keyboard/utils.js
deleted file mode 100644
index a4a8f76..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/keyboard/utils.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { Cc, Ci } = require("chrome");
-const runtime = require("../system/runtime");
-const { isString } = require("../lang/type");
-const array = require("../util/array");
-
-
-const SWP = "{{SEPARATOR}}";
-const SEPARATOR = "-"
-const INVALID_COMBINATION = "Hotkey key combination must contain one or more " +
- "modifiers and only one key";
-
-// Map of modifier key mappings.
-const MODIFIERS = exports.MODIFIERS = {
- 'accel': runtime.OS === "Darwin" ? 'meta' : 'control',
- 'meta': 'meta',
- 'control': 'control',
- 'ctrl': 'control',
- 'option': 'alt',
- 'command': 'meta',
- 'alt': 'alt',
- 'shift': 'shift'
-};
-
-// Hash of key:code pairs for all the chars supported by `nsIDOMKeyEvent`.
-// This is just a copy of the `nsIDOMKeyEvent` hash with normalized names.
-// @See: http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/events/nsIDOMKeyEvent.idl
-const CODES = exports.CODES = new function Codes() {
- let nsIDOMKeyEvent = Ci.nsIDOMKeyEvent;
- // Names that will be substituted with a shorter analogs.
- let aliases = {
- 'subtract': '-',
- 'add': '+',
- 'equals': '=',
- 'slash': '/',
- 'backslash': '\\',
- 'openbracket': '[',
- 'closebracket': ']',
- 'quote': '\'',
- 'backquote': '`',
- 'period': '.',
- 'semicolon': ';',
- 'comma': ','
- };
-
- // Normalizing keys and copying values to `this` object.
- Object.keys(nsIDOMKeyEvent).filter(function(key) {
- // Filter out only key codes.
- return key.indexOf('DOM_VK') === 0;
- }).map(function(key) {
- // Map to key:values
- return [ key, nsIDOMKeyEvent[key] ];
- }).map(function([key, value]) {
- return [ key.replace('DOM_VK_', '').replace('_', '').toLowerCase(), value ];
- }).forEach(function ([ key, value ]) {
- this[aliases[key] || key] = value;
- }, this);
-};
-
-// Inverted `CODES` hash of `code:key`.
-const KEYS = exports.KEYS = new function Keys() {
- Object.keys(CODES).forEach(function(key) {
- this[CODES[key]] = key;
- }, this)
-}
-
-exports.getKeyForCode = function getKeyForCode(code) {
- return (code in KEYS) && KEYS[code];
-};
-exports.getCodeForKey = function getCodeForKey(key) {
- return (key in CODES) && CODES[key];
-};
-
-/**
- * Utility function that takes string or JSON that defines a `hotkey` and
- * returns normalized string version of it.
- * @param {JSON|String} hotkey
- * @param {String} [separator=" "]
- * Optional string that represents separator used to concatenate keys in the
- * given `hotkey`.
- * @returns {String}
- * @examples
- *
- * require("keyboard/hotkeys").normalize("b Shift accel");
- * // 'control shift b' -> on windows & linux
- * // 'meta shift b' -> on mac
- * require("keyboard/hotkeys").normalize("alt-d-shift", "-");
- * // 'alt shift d'
- */
-var normalize = exports.normalize = function normalize(hotkey, separator) {
- if (!isString(hotkey))
- hotkey = toString(hotkey, separator);
- return toString(toJSON(hotkey, separator), separator);
-};
-
-/*
- * Utility function that splits a string of characters that defines a `hotkey`
- * into modifier keys and the defining key.
- * @param {String} hotkey
- * @param {String} [separator=" "]
- * Optional string that represents separator used to concatenate keys in the
- * given `hotkey`.
- * @returns {JSON}
- * @examples
- *
- * require("keyboard/hotkeys").toJSON("accel shift b");
- * // { key: 'b', modifiers: [ 'control', 'shift' ] } -> on windows & linux
- * // { key: 'b', modifiers: [ 'meta', 'shift' ] } -> on mac
- *
- * require("keyboard/hotkeys").normalize("alt-d-shift", "-");
- * // { key: 'd', modifiers: [ 'alt', 'shift' ] }
- */
-var toJSON = exports.toJSON = function toJSON(hotkey, separator) {
- separator = separator || SEPARATOR;
- // Since default separator is `-`, combination may take form of `alt--`. To
- // avoid misbehavior we replace `--` with `-{{SEPARATOR}}` where
- // `{{SEPARATOR}}` can be swapped later.
- hotkey = hotkey.toLowerCase().replace(separator + separator, separator + SWP);
-
- let value = {};
- let modifiers = [];
- let keys = hotkey.split(separator);
- keys.forEach(function(name) {
- // If name is `SEPARATOR` than we swap it back.
- if (name === SWP)
- name = separator;
- if (name in MODIFIERS) {
- array.add(modifiers, MODIFIERS[name]);
- } else {
- if (!value.key)
- value.key = name;
- else
- throw new TypeError(INVALID_COMBINATION);
- }
- });
-
- if (!value.key)
- throw new TypeError(INVALID_COMBINATION);
-
- value.modifiers = modifiers.sort();
- return value;
-};
-
-/**
- * Utility function that takes object that defines a `hotkey` and returns
- * string representation of it.
- *
- * _Please note that this function does not validates data neither it normalizes
- * it, if you are unsure that data is well formed use `normalize` function
- * instead.
- *
- * @param {JSON} hotkey
- * @param {String} [separator=" "]
- * Optional string that represents separator used to concatenate keys in the
- * given `hotkey`.
- * @returns {String}
- * @examples
- *
- * require("keyboard/hotkeys").toString({
- * key: 'b',
- * modifiers: [ 'control', 'shift' ]
- * }, '+');
- * // 'control+shift+b
- *
- */
-var toString = exports.toString = function toString(hotkey, separator) {
- let keys = hotkey.modifiers.slice();
- keys.push(hotkey.key);
- return keys.join(separator || SEPARATOR);
-};
-
-/**
- * Utility function takes `key` name and returns `true` if it's function key
- * (F1, ..., F24) and `false` if it's not.
- */
-var isFunctionKey = exports.isFunctionKey = function isFunctionKey(key) {
- var $
- return key[0].toLowerCase() === 'f' &&
- ($ = parseInt(key.substr(1)), 0 < $ && $ < 25);
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/l10n.js b/tools/addon-sdk-1.12/lib/sdk/l10n.js
deleted file mode 100644
index 40f219c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/l10n.js
+++ /dev/null
@@ -1,83 +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": "stable"
-};
-
-const core = require("./l10n/core");
-const { getRulesForLocale } = require("./l10n/plural-rules");
-
-// Retrieve the plural mapping function
-let pluralMappingFunction = getRulesForLocale(core.language()) ||
- getRulesForLocale("en");
-
-exports.get = function get(k) {
- // For now, we only accept a "string" as first argument
- // TODO: handle plural forms in gettext pattern
- if (typeof k !== "string")
- throw new Error("First argument of localization method should be a string");
-
- // Get translation from big hashmap or default to hard coded string:
- let localized = core.get(k) || k;
-
- // # Simplest usecase:
- // // String hard coded in source code:
- // _("Hello world")
- // // Identifier of a key stored in properties file
- // _("helloString")
- if (arguments.length <= 1)
- return localized;
-
- let args = arguments;
-
- if (typeof localized == "object" && "other" in localized) {
- // # Plural form:
- // // Strings hard coded in source code:
- // _(["One download", "%d downloads"], 10);
- // // Identifier of a key stored in properties file
- // _("downloadNumber", 0);
- let n = arguments[1];
-
- // First handle simple universal forms that may not be mandatory
- // for each language, (i.e. not different than 'other' form,
- // but still usefull for better phrasing)
- // For example 0 in english is the same form than 'other'
- // but we accept 'zero' form if specified in localization file
- if (n === 0 && "zero" in localized)
- localized = localized["zero"];
- else if (n === 1 && "one" in localized)
- localized = localized["one"];
- else if (n === 2 && "two" in localized)
- localized = localized["two"];
- else {
- let pluralForm = pluralMappingFunction(n);
- if (pluralForm in localized)
- localized = localized[pluralForm];
- else // Fallback in case of error: missing plural form
- localized = localized["other"];
- }
-
- // Simulate a string with one placeholder:
- args = [null, n];
- }
-
- // # String with placeholders:
- // // Strings hard coded in source code:
- // _("Hello %s", username)
- // // Identifier of a key stored in properties file
- // _("helloString", username)
- // * We supports `%1s`, `%2s`, ... pattern in order to change arguments order
- // in translation.
- // * In case of plural form, we has `%d` instead of `%s`.
- let offset = 1;
- localized = localized.replace(/%(\d*)(s|d)/g, function (v, n) {
- let rv = args[n != "" ? n : offset];
- offset++;
- return rv;
- });
-
- return localized;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/l10n/core.js b/tools/addon-sdk-1.12/lib/sdk/l10n/core.js
deleted file mode 100644
index 50472e9..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/l10n/core.js
+++ /dev/null
@@ -1,35 +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/. */
-
-// Following pseudo module is set by `api-utils/addon/runner` and its load
-// method needs to be called before loading `core` module. But it may have
-// failed, so that this pseudo won't be available
-
-module.metadata = {
- "stability": "unstable"
-};
-
-
-let hash = {}, bestMatchingLocale = null;
-try {
- let data = require("@l10n/data");
- hash = data.hash;
- bestMatchingLocale = data.bestMatchingLocale;
-}
-catch(e) {}
-
-// Returns the translation for a given key, if available.
-exports.get = function get(k) {
- return k in hash ? hash[k] : null;
-}
-
-// Returns the full length locale code: ja-JP-mac, en-US or fr
-exports.locale = function locale() {
- return bestMatchingLocale;
-}
-// Returns the short locale code: ja, en, fr
-exports.language = function language() {
- return bestMatchingLocale ? bestMatchingLocale.split("-")[0].toLowerCase()
- : null;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/l10n/html.js b/tools/addon-sdk-1.12/lib/sdk/l10n/html.js
deleted file mode 100644
index 1a36415..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/l10n/html.js
+++ /dev/null
@@ -1,93 +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/. */
-
-module.metadata = {
- "stability": "unstable"
-};
-
-const { Ci } = require("chrome");
-const events = require("../system/events");
-const core = require("./core");
-
-const assetsURI = require('../self').data.url();
-
-// Taken from Gaia:
-// https://github.com/andreasgal/gaia/blob/04fde2640a7f40314643016a5a6c98bf3755f5fd/webapi.js#L1470
-function translateElement(element) {
- element = element || document;
-
- // check all translatable children (= w/ a `data-l10n-id' attribute)
- var children = element.querySelectorAll('*[data-l10n-id]');
- var elementCount = children.length;
- for (var i = 0; i < elementCount; i++) {
- var child = children[i];
-
- // translate the child
- var key = child.dataset.l10nId;
- var data = core.get(key);
- if (data)
- child.textContent = data;
- }
-}
-exports.translateElement = translateElement;
-
-function onDocumentReady2Translate(event) {
- let document = event.target;
- document.removeEventListener("DOMContentLoaded", onDocumentReady2Translate,
- false);
-
- translateElement(document);
-
- // Finally display document when we finished replacing all text content
- document.documentElement.style.visibility = "visible";
-}
-
-function onContentWindow(event) {
- let document = event.subject;
-
- // Accept only HTML documents
- if (!(document instanceof Ci.nsIDOMHTMLDocument))
- return;
-
- // Bug 769483: data:URI documents instanciated with nsIDOMParser
- // have a null `location` attribute at this time
- if (!document.location)
- return;
-
- // Accept only document from this addon
- if (document.location.href.indexOf(assetsURI) !== 0)
- return;
-
- // First hide content of the document in order to have content blinking
- // between untranslated and translated states
- // TODO: use result of bug 737003 discussion in order to avoid any conflict
- // with document CSS
- document.documentElement.style.visibility = "hidden";
-
- // Wait for DOM tree to be built before applying localization
- document.addEventListener("DOMContentLoaded", onDocumentReady2Translate,
- false);
-}
-
-// Listen to creation of content documents in order to translate them as soon
-// as possible in their loading process
-const ON_CONTENT = "document-element-inserted";
-let enabled = false;
-function enable() {
- if (!enabled) {
- events.on(ON_CONTENT, onContentWindow);
- enabled = true;
- }
-}
-exports.enable = enable;
-
-function disable() {
- if (enabled) {
- events.off(ON_CONTENT, onContentWindow);
- enabled = false;
- }
-}
-exports.disable = disable;
-
-require("api-utils/unload").when(disable);
diff --git a/tools/addon-sdk-1.12/lib/sdk/l10n/loader.js b/tools/addon-sdk-1.12/lib/sdk/l10n/loader.js
deleted file mode 100644
index 9af6c5c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/l10n/loader.js
+++ /dev/null
@@ -1,71 +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 { Cc, Ci } = require("chrome");
-const { getPreferedLocales, findClosestLocale } = require("./locale");
-const { readURI } = require("../net/url");
-const { resolve } = require("../core/promise");
-
-function parseJsonURI(uri) {
- return readURI(uri).
- then(JSON.parse).
- then(null, function (error) {
- throw Error("Failed to parse locale file:\n" + uri + "\n" + error);
- });
-}
-
-// Returns the array stored in `locales.json` manifest that list available
-// locales files
-function getAvailableLocales(rootURI) {
- let uri = rootURI + "locales.json";
- return parseJsonURI(uri).then(function (manifest) {
- return "locales" in manifest &&
- Array.isArray(manifest.locales) ?
- manifest.locales : [];
- });
-}
-
-// Returns URI of the best locales file to use from the XPI
-function getBestLocale(rootURI) {
- // Read localization manifest file that contains list of available languages
- return getAvailableLocales(rootURI).then(function (availableLocales) {
- // Retrieve list of prefered locales to use
- let preferedLocales = getPreferedLocales();
-
- // Compute the most preferable locale to use by using these two lists
- return findClosestLocale(availableLocales, preferedLocales);
- });
-}
-
-/**
- * Read localization files and returns a promise of data to put in `@l10n/data`
- * pseudo module, in order to allow l10n/core to fetch it.
- */
-exports.load = function load(rootURI) {
- // First, search for a locale file:
- return getBestLocale(rootURI).then(function (bestMatchingLocale) {
- // It may be null if the addon doesn't have any locale file
- if (!bestMatchingLocale)
- return resolve(null);
-
- let localeURI = rootURI + "locale/" + bestMatchingLocale + ".json";
-
- // Locale files only contains one big JSON object that is used as
- // an hashtable of: "key to translate" => "translated key"
- // TODO: We are likely to change this in order to be able to overload
- // a specific key translation. For a specific package, module or line?
- return parseJsonURI(localeURI).then(function (json) {
- return {
- hash: json,
- bestMatchingLocale: bestMatchingLocale
- };
- });
- });
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/l10n/locale.js b/tools/addon-sdk-1.12/lib/sdk/l10n/locale.js
deleted file mode 100644
index 0e59a64..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/l10n/locale.js
+++ /dev/null
@@ -1,126 +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 prefs = require("../preferences/service");
-const { Cu, Cc, Ci } = require("chrome");
-const { Services } = Cu.import("resource://gre/modules/Services.jsm");
-
-
-/**
- * Gets the currently selected locale for display.
- * Gets all usable locale that we can use sorted by priority of relevance
- * @return Array of locales, begins with highest priority
- */
-const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
-const PREF_SELECTED_LOCALE = "general.useragent.locale";
-const PREF_ACCEPT_LANGUAGES = "intl.accept_languages";
-exports.getPreferedLocales = function getPreferedLocales() {
- let locales = [];
-
- function addLocale(locale) {
- locale = locale.toLowerCase();
- if (locales.indexOf(locale) === -1)
- locales.push(locale);
- }
-
- // Most important locale is OS one. But we use it, only if
- // "intl.locale.matchOS" pref is set to `true`.
- // Currently only used for multi-locales mobile builds.
- // http://mxr.mozilla.org/mozilla-central/source/mobile/android/installer/Makefile.in#46
- if (prefs.get(PREF_MATCH_OS_LOCALE, false)) {
- let localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].
- getService(Ci.nsILocaleService);
- let osLocale = localeService.getLocaleComponentForUserAgent();
- addLocale(osLocale);
- }
-
- // In some cases, mainly on Fennec and on Linux version,
- // `general.useragent.locale` is a special 'localized' value, like:
- // "chrome://global/locale/intl.properties"
- let browserUiLocale = prefs.getLocalized(PREF_SELECTED_LOCALE, "") ||
- prefs.get(PREF_SELECTED_LOCALE, "");
- if (browserUiLocale)
- addLocale(browserUiLocale);
-
-
- // Third priority is the list of locales used for web content
- let contentLocales = prefs.get(PREF_ACCEPT_LANGUAGES, "");
- if (contentLocales) {
- // This list is a string of locales seperated by commas.
- // There is spaces after commas, so strip each item
- for each(let locale in contentLocales.split(","))
- addLocale(locale.replace(/(^\s+)|(\s+$)/g, ""));
- }
-
- // Finally, we ensure that en-US is the final fallback if it wasn't added
- addLocale("en-US");
-
- return locales;
-}
-
-/**
- * Selects the closest matching locale from a list of locales.
- *
- * @param aLocales
- * An array of available locales
- * @param aMatchLocales
- * An array of prefered locales, ordered by priority. Most wanted first.
- * Locales have to be in lowercase.
- * If null, uses getPreferedLocales() results
- * @return the best match for the currently selected locale
- *
- * Stolen from http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/extensions/XPIProvider.jsm
- */
-exports.findClosestLocale = function findClosestLocale(aLocales, aMatchLocales) {
-
- aMatchLocales = aMatchLocales || exports.getPreferedLocales();
-
- // Holds the best matching localized resource
- let bestmatch = null;
- // The number of locale parts it matched with
- let bestmatchcount = 0;
- // The number of locale parts in the match
- let bestpartcount = 0;
-
- for each (let locale in aMatchLocales) {
- let lparts = locale.split("-");
- for each (let localized in aLocales) {
- let found = localized.toLowerCase();
- // Exact match is returned immediately
- if (locale == found)
- return localized;
-
- let fparts = found.split("-");
- /* If we have found a possible match and this one isn't any longer
- then we dont need to check further. */
- if (bestmatch && fparts.length < bestmatchcount)
- continue;
-
- // Count the number of parts that match
- let maxmatchcount = Math.min(fparts.length, lparts.length);
- let matchcount = 0;
- while (matchcount < maxmatchcount &&
- fparts[matchcount] == lparts[matchcount])
- matchcount++;
-
- /* If we matched more than the last best match or matched the same and
- this locale is less specific than the last best match. */
- if (matchcount > bestmatchcount ||
- (matchcount == bestmatchcount && fparts.length < bestpartcount)) {
- bestmatch = localized;
- bestmatchcount = matchcount;
- bestpartcount = fparts.length;
- }
- }
- // If we found a valid match for this locale return it
- if (bestmatch)
- return bestmatch;
- }
- return null;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/l10n/plural-rules.js b/tools/addon-sdk-1.12/lib/sdk/l10n/plural-rules.js
deleted file mode 100644
index 22e5b8b..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/l10n/plural-rules.js
+++ /dev/null
@@ -1,403 +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/. */
-
-// This file is automatically generated with /python-lib/plural-rules-generator.py
-// Fetching data from: http://unicode.org/repos/cldr/trunk/common/supplemental/plurals.xml
-
-// Mapping of short locale name == to == > rule index in following list
-
-module.metadata = {
- "stability": "unstable"
-};
-
-const LOCALES_TO_RULES = {
- "af": 3,
- "ak": 4,
- "am": 4,
- "ar": 1,
- "asa": 3,
- "az": 0,
- "be": 11,
- "bem": 3,
- "bez": 3,
- "bg": 3,
- "bh": 4,
- "bm": 0,
- "bn": 3,
- "bo": 0,
- "br": 20,
- "brx": 3,
- "bs": 11,
- "ca": 3,
- "cgg": 3,
- "chr": 3,
- "cs": 12,
- "cy": 17,
- "da": 3,
- "de": 3,
- "dv": 3,
- "dz": 0,
- "ee": 3,
- "el": 3,
- "en": 3,
- "eo": 3,
- "es": 3,
- "et": 3,
- "eu": 3,
- "fa": 0,
- "ff": 5,
- "fi": 3,
- "fil": 4,
- "fo": 3,
- "fr": 5,
- "fur": 3,
- "fy": 3,
- "ga": 8,
- "gd": 24,
- "gl": 3,
- "gsw": 3,
- "gu": 3,
- "guw": 4,
- "gv": 23,
- "ha": 3,
- "haw": 3,
- "he": 2,
- "hi": 4,
- "hr": 11,
- "hu": 0,
- "id": 0,
- "ig": 0,
- "ii": 0,
- "is": 3,
- "it": 3,
- "iu": 7,
- "ja": 0,
- "jmc": 3,
- "jv": 0,
- "ka": 0,
- "kab": 5,
- "kaj": 3,
- "kcg": 3,
- "kde": 0,
- "kea": 0,
- "kk": 3,
- "kl": 3,
- "km": 0,
- "kn": 0,
- "ko": 0,
- "ksb": 3,
- "ksh": 21,
- "ku": 3,
- "kw": 7,
- "lag": 18,
- "lb": 3,
- "lg": 3,
- "ln": 4,
- "lo": 0,
- "lt": 10,
- "lv": 6,
- "mas": 3,
- "mg": 4,
- "mk": 16,
- "ml": 3,
- "mn": 3,
- "mo": 9,
- "mr": 3,
- "ms": 0,
- "mt": 15,
- "my": 0,
- "nah": 3,
- "naq": 7,
- "nb": 3,
- "nd": 3,
- "ne": 3,
- "nl": 3,
- "nn": 3,
- "no": 3,
- "nr": 3,
- "nso": 4,
- "ny": 3,
- "nyn": 3,
- "om": 3,
- "or": 3,
- "pa": 3,
- "pap": 3,
- "pl": 13,
- "ps": 3,
- "pt": 3,
- "rm": 3,
- "ro": 9,
- "rof": 3,
- "ru": 11,
- "rwk": 3,
- "sah": 0,
- "saq": 3,
- "se": 7,
- "seh": 3,
- "ses": 0,
- "sg": 0,
- "sh": 11,
- "shi": 19,
- "sk": 12,
- "sl": 14,
- "sma": 7,
- "smi": 7,
- "smj": 7,
- "smn": 7,
- "sms": 7,
- "sn": 3,
- "so": 3,
- "sq": 3,
- "sr": 11,
- "ss": 3,
- "ssy": 3,
- "st": 3,
- "sv": 3,
- "sw": 3,
- "syr": 3,
- "ta": 3,
- "te": 3,
- "teo": 3,
- "th": 0,
- "ti": 4,
- "tig": 3,
- "tk": 3,
- "tl": 4,
- "tn": 3,
- "to": 0,
- "tr": 0,
- "ts": 3,
- "tzm": 22,
- "uk": 11,
- "ur": 3,
- "ve": 3,
- "vi": 0,
- "vun": 3,
- "wa": 4,
- "wae": 3,
- "wo": 0,
- "xh": 3,
- "xog": 3,
- "yo": 0,
- "zh": 0,
- "zu": 3
-};
-
-// Utility functions for plural rules methods
-function isIn(n, list) list.indexOf(n) !== -1;
-function isBetween(n, start, end) start <= n && n <= end;
-
-// List of all plural rules methods, that maps an integer to the plural form name to use
-const RULES = {
- "0": function (n) {
-
- return "other"
- },
- "1": function (n) {
- if ((isBetween((n % 100), 3, 10)))
- return "few";
- if (n == 0)
- return "zero";
- if ((isBetween((n % 100), 11, 99)))
- return "many";
- if (n == 2)
- return "two";
- if (n == 1)
- return "one";
- return "other"
- },
- "2": function (n) {
- if (n != 0 && (n % 10) == 0)
- return "many";
- if (n == 2)
- return "two";
- if (n == 1)
- return "one";
- return "other"
- },
- "3": function (n) {
- if (n == 1)
- return "one";
- return "other"
- },
- "4": function (n) {
- if ((isBetween(n, 0, 1)))
- return "one";
- return "other"
- },
- "5": function (n) {
- if ((isBetween(n, 0, 2)) && n != 2)
- return "one";
- return "other"
- },
- "6": function (n) {
- if (n == 0)
- return "zero";
- if ((n % 10) == 1 && (n % 100) != 11)
- return "one";
- return "other"
- },
- "7": function (n) {
- if (n == 2)
- return "two";
- if (n == 1)
- return "one";
- return "other"
- },
- "8": function (n) {
- if ((isBetween(n, 3, 6)))
- return "few";
- if ((isBetween(n, 7, 10)))
- return "many";
- if (n == 2)
- return "two";
- if (n == 1)
- return "one";
- return "other"
- },
- "9": function (n) {
- if (n == 0 || n != 1 && (isBetween((n % 100), 1, 19)))
- return "few";
- if (n == 1)
- return "one";
- return "other"
- },
- "10": function (n) {
- if ((isBetween((n % 10), 2, 9)) && !(isBetween((n % 100), 11, 19)))
- return "few";
- if ((n % 10) == 1 && !(isBetween((n % 100), 11, 19)))
- return "one";
- return "other"
- },
- "11": function (n) {
- if ((isBetween((n % 10), 2, 4)) && !(isBetween((n % 100), 12, 14)))
- return "few";
- if ((n % 10) == 0 || (isBetween((n % 10), 5, 9)) || (isBetween((n % 100), 11, 14)))
- return "many";
- if ((n % 10) == 1 && (n % 100) != 11)
- return "one";
- return "other"
- },
- "12": function (n) {
- if ((isBetween(n, 2, 4)))
- return "few";
- if (n == 1)
- return "one";
- return "other"
- },
- "13": function (n) {
- if ((isBetween((n % 10), 2, 4)) && !(isBetween((n % 100), 12, 14)))
- return "few";
- if (n != 1 && (isBetween((n % 10), 0, 1)) || (isBetween((n % 10), 5, 9)) || (isBetween((n % 100), 12, 14)))
- return "many";
- if (n == 1)
- return "one";
- return "other"
- },
- "14": function (n) {
- if ((isBetween((n % 100), 3, 4)))
- return "few";
- if ((n % 100) == 2)
- return "two";
- if ((n % 100) == 1)
- return "one";
- return "other"
- },
- "15": function (n) {
- if (n == 0 || (isBetween((n % 100), 2, 10)))
- return "few";
- if ((isBetween((n % 100), 11, 19)))
- return "many";
- if (n == 1)
- return "one";
- return "other"
- },
- "16": function (n) {
- if ((n % 10) == 1 && n != 11)
- return "one";
- return "other"
- },
- "17": function (n) {
- if (n == 3)
- return "few";
- if (n == 0)
- return "zero";
- if (n == 6)
- return "many";
- if (n == 2)
- return "two";
- if (n == 1)
- return "one";
- return "other"
- },
- "18": function (n) {
- if (n == 0)
- return "zero";
- if ((isBetween(n, 0, 2)) && n != 0 && n != 2)
- return "one";
- return "other"
- },
- "19": function (n) {
- if ((isBetween(n, 2, 10)))
- return "few";
- if ((isBetween(n, 0, 1)))
- return "one";
- return "other"
- },
- "20": function (n) {
- if ((isBetween((n % 10), 3, 4) || ((n % 10) == 9)) && !(isBetween((n % 100), 10, 19) || isBetween((n % 100), 70, 79) || isBetween((n % 100), 90, 99)))
- return "few";
- if ((n % 1000000) == 0 && n != 0)
- return "many";
- if ((n % 10) == 2 && !isIn((n % 100), [12, 72, 92]))
- return "two";
- if ((n % 10) == 1 && !isIn((n % 100), [11, 71, 91]))
- return "one";
- return "other"
- },
- "21": function (n) {
- if (n == 0)
- return "zero";
- if (n == 1)
- return "one";
- return "other"
- },
- "22": function (n) {
- if ((isBetween(n, 0, 1)) || (isBetween(n, 11, 99)))
- return "one";
- return "other"
- },
- "23": function (n) {
- if ((isBetween((n % 10), 1, 2)) || (n % 20) == 0)
- return "one";
- return "other"
- },
- "24": function (n) {
- if ((isBetween(n, 3, 10) || isBetween(n, 13, 19)))
- return "few";
- if (isIn(n, [2, 12]))
- return "two";
- if (isIn(n, [1, 11]))
- return "one";
- return "other"
- },
-};
-
-/**
- * Return a function that gives the plural form name for a given integer
- * for the specified `locale`
- * let fun = getRulesForLocale('en');
- * fun(1) -> 'one'
- * fun(0) -> 'other'
- * fun(1000) -> 'other'
- */
-exports.getRulesForLocale = function getRulesForLocale(locale) {
- let index = LOCALES_TO_RULES[locale];
- if (!(index in RULES)) {
- console.warn('Plural form unknown for locale "' + locale + '"');
- return function () { return "other"; };
- }
- return RULES[index];
-}
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/l10n/prefs.js b/tools/addon-sdk-1.12/lib/sdk/l10n/prefs.js
deleted file mode 100644
index 016077c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/l10n/prefs.js
+++ /dev/null
@@ -1,44 +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 observers = require("../deprecated/observer-service");
-const core = require("./core");
-const { id: jetpackId} = require('../self');
-
-const OPTIONS_DISPLAYED = "addon-options-displayed";
-
-function onOptionsDisplayed(document, addonId) {
- if (addonId !== jetpackId)
- return;
- let query = 'setting[data-jetpack-id="' + jetpackId + '"][pref-name], ' +
- 'button[data-jetpack-id="' + jetpackId + '"][pref-name]';
- let nodes = document.querySelectorAll(query);
- for (let node of nodes) {
- let name = node.getAttribute("pref-name");
- if (node.tagName == "setting") {
- let desc = core.get(name + "_description");
- if (desc)
- node.setAttribute("desc", desc);
- let title = core.get(name + "_title");
- if (title)
- node.setAttribute("title", title);
-
- for (let item of node.querySelectorAll("menuitem, radio")) {
- let key = name + "_options." + item.getAttribute("label");
- let label = core.get(key);
- if (label)
- item.setAttribute("label", label);
- }
- }
- else if (node.tagName == "button") {
- let label = core.get(name + "_label");
- if (label)
- node.setAttribute("label", label);
- }
- }
-}
-
-observers.add(OPTIONS_DISPLAYED, onOptionsDisplayed);
diff --git a/tools/addon-sdk-1.12/lib/sdk/lang/functional.js b/tools/addon-sdk-1.12/lib/sdk/lang/functional.js
deleted file mode 100644
index 3595a27..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/lang/functional.js
+++ /dev/null
@@ -1,163 +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/. */
-
-// Disclaimer: Most of the functions in this module implement APIs from
-// Jeremy Ashkenas's http://underscorejs.org/ library and all credits for
-// those goes to him.
-
-"use strict";
-
-module.metadata = {
- "stability": "unstable"
-};
-
-const { setTimeout } = require("../timers");
-
-/**
- * Takes `lambda` function and returns a method. When returned method is
- * invoked it calls wrapped `lambda` and passes `this` as a first argument
- * and given argument as rest.
- */
-function method(lambda) {
- return function method() {
- return lambda.apply(null, [this].concat(Array.slice(arguments)));
- }
-}
-exports.method = method;
-
-/**
- * Takes a function and returns a wrapped one instead, calling which will call
- * original function in the next turn of event loop. This is basically utility
- * to do `setTimeout(function() { ... }, 0)`, with a difference that returned
- * function is reused, instead of creating a new one each time. This also allows
- * to use this functions as event listeners.
- */
-function defer(f) {
- return function deferred()
- setTimeout(invoke, 0, f, arguments, this);
-}
-exports.defer = defer;
-// Exporting `remit` alias as `defer` may conflict with promises.
-exports.remit = defer;
-
-/**
- * Invokes `callee` by passing `params` as an arguments and `self` as `this`
- * pseudo-variable. Returns value that is returned by a callee.
- * @param {Function} callee
- * Function to invoke.
- * @param {Array} params
- * Arguments to invoke function with.
- * @param {Object} self
- * Object to be passed as a `this` pseudo variable.
- */
-function invoke(callee, params, self) callee.apply(self, params);
-exports.invoke = invoke;
-
-/**
- * Curries a function with the arguments given.
- *
- * @param {Function} fn
- * The function to curry
- *
- * @returns The function curried
- */
-function curry(fn) {
- if (typeof fn !== "function")
- throw new TypeError(String(fn) + " is not a function");
-
- let args = Array.slice(arguments, 1);
-
- return function() fn.apply(this, args.concat(Array.slice(arguments)));
-}
-exports.curry = curry;
-
-/**
- * Returns the composition of a list of functions, where each function consumes
- * the return value of the function that follows. In math terms, composing the
- * functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
- * @example
- *
- * var greet = function(name) { return "hi: " + name; };
- * var exclaim = function(statement) { return statement + "!"; };
- * var welcome = compose(exclaim, greet);
- *
- * welcome('moe'); // => 'hi: moe!'
- */
-function compose() {
- let lambdas = Array.slice(arguments);
- return function composed() {
- let args = Array.slice(arguments), index = lambdas.length;
- while (0 <= --index)
- args = [ lambdas[index].apply(this, args) ];
- return args[0];
- };
-}
-exports.compose = compose;
-
-/*
- * Returns the first function passed as an argument to the second,
- * allowing you to adjust arguments, run code before and after, and
- * conditionally execute the original function.
- * @example
- *
- * var hello = function(name) { return "hello: " + name; };
- * hello = wrap(hello, function(f) {
- * return "before, " + f("moe") + ", after";
- * });
- *
- * hello(); // => 'before, hello: moe, after'
- */
-function wrap(f, wrapper) {
- return function wrapped()
- wrapper.apply(this, [ f ].concat(Array.slice(arguments)))
-};
-exports.wrap = wrap;
-
-/**
- * Returns the same value that is used as the argument. In math: f(x) = x
- */
-function identity(value) value
-exports.identity = identity;
-
-/**
- * Memoizes a given function by caching the computed result. Useful for
- * speeding up slow-running computations. If passed an optional hashFunction,
- * it will be used to compute the hash key for storing the result, based on
- * the arguments to the original function. The default hashFunction just uses
- * the first argument to the memoized function as the key.
- */
-function memoize(f, hasher) {
- let memo = Object.create(null);
- hasher = hasher || identity;
- return function memoizer() {
- let key = hasher.apply(this, arguments);
- return key in memo ? memo[key] : (memo[key] = f.apply(this, arguments));
- };
-}
-exports.memoize = memoize;
-
-/**
- * Much like setTimeout, invokes function after wait milliseconds. If you pass
- * the optional arguments, they will be forwarded on to the function when it is
- * invoked.
- */
-function delay(f, ms) {
- let args = Array.slice(arguments, 2);
- setTimeout(function(context) { return f.apply(context, args); }, ms, this);
-};
-exports.delay = delay;
-
-/**
- * Creates a version of the function that can only be called one time. Repeated
- * calls to the modified function will have no effect, returning the value from
- * the original call. Useful for initialization functions, instead of having to
- * set a boolean flag and then check it later.
- */
-function once(f) {
- let ran = false, cache;
- return function() ran ? cache : (ran = true, cache = f.apply(this, arguments))
-};
-exports.once = once;
-// export cache as once will may be conflicting with event once a lot.
-exports.cache = once;
diff --git a/tools/addon-sdk-1.12/lib/sdk/lang/type.js b/tools/addon-sdk-1.12/lib/sdk/lang/type.js
deleted file mode 100644
index a184edf..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/lang/type.js
+++ /dev/null
@@ -1,344 +0,0 @@
-/* vim:ts=2:sts=2:sw=2:
- * 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"
-};
-
-/**
- * Returns `true` if `value` is `undefined`.
- * @examples
- * var foo; isUndefined(foo); // true
- * isUndefined(0); // false
- */
-function isUndefined(value) {
- return value === undefined;
-}
-exports.isUndefined = isUndefined;
-
-/**
- * Returns `true` if value is `null`.
- * @examples
- * isNull(null); // true
- * isNull(undefined); // false
- */
-function isNull(value) {
- return value === null;
-}
-exports.isNull = isNull;
-
-/**
- * Returns `true` if value is a string.
- * @examples
- * isString("moe"); // true
- */
-function isString(value) {
- return typeof value === "string";
-}
-exports.isString = isString;
-
-/**
- * Returns `true` if `value` is a number.
- * @examples
- * isNumber(8.4 * 5); // true
- */
-function isNumber(value) {
- return typeof value === "number";
-}
-exports.isNumber = isNumber;
-
-/**
- * Returns `true` if `value` is a `RegExp`.
- * @examples
- * isRegExp(/moe/); // true
- */
-function isRegExp(value) {
- return isObject(value) && instanceOf(value, RegExp);
-}
-exports.isRegExp = isRegExp;
-
-/**
- * Returns true if `value` is a `Date`.
- * @examples
- * isDate(new Date()); // true
- */
-function isDate(value) {
- return isObject(value) && instanceOf(value, Date);
-}
-exports.isDate = isDate;
-
-/**
- * Returns true if object is a Function.
- * @examples
- * isFunction(function foo(){}) // true
- */
-function isFunction(value) {
- return typeof value === "function";
-}
-exports.isFunction = isFunction;
-
-/**
- * Returns `true` if `value` is an object (please note that `null` is considered
- * to be an atom and not an object).
- * @examples
- * isObject({}) // true
- * isObject(null) // false
- */
-function isObject(value) {
- return typeof value === "object" && value !== null;
-}
-exports.isObject = isObject;
-
-/**
- * Returns true if `value` is an Array.
- * @examples
- * isArray([1, 2, 3]) // true
- * isArray({ 0: 'foo', length: 1 }) // false
- */
-var isArray = Array.isArray || function isArray(value) {
- Object.prototype.toString.call(value) === "[object Array]";
-}
-exports.isArray = isArray;
-
-/**
- * Returns `true` if `value` is an Arguments object.
- * @examples
- * (function(){ return isArguments(arguments); })(1, 2, 3); // true
- * isArguments([1,2,3]); // false
- */
-function isArguments(value) {
- Object.prototype.toString.call(value) === "[object Arguments]";
-}
-exports.isArguments = isArguments;
-
-/**
- * Returns true if it is a primitive `value`. (null, undefined, number,
- * boolean, string)
- * @examples
- * isPrimitive(3) // true
- * isPrimitive('foo') // true
- * isPrimitive({ bar: 3 }) // false
- */
-function isPrimitive(value) {
- return !isFunction(value) && !isObject(value);
-}
-exports.isPrimitive = isPrimitive;
-
-/**
- * Returns `true` if given `object` is flat (it is direct decedent of
- * `Object.prototype` or `null`).
- * @examples
- * isFlat({}) // true
- * isFlat(new Type()) // false
- */
-function isFlat(object) {
- return isObject(object) && (isNull(Object.getPrototypeOf(object)) ||
- isNull(Object.getPrototypeOf(
- Object.getPrototypeOf(object))));
-}
-exports.isFlat = isFlat;
-
-/**
- * Returns `true` if object contains no values.
- */
-function isEmpty(object) {
- if (isObject(object)) {
- for (var key in object)
- return false;
- return true;
- }
- return false;
-}
-exports.isEmpty = isEmpty;
-
-/**
- * Returns `true` if `value` is an array / flat object containing only atomic
- * values and other flat objects.
- */
-function isJSON(value, visited) {
- // Adding value to array of visited values.
- (visited || (visited = [])).push(value);
- // If `value` is an atom return `true` cause it's valid JSON.
- return isPrimitive(value) ||
- // If `value` is an array of JSON values that has not been visited
- // yet.
- (isArray(value) && value.every(function(element) {
- return isJSON(element, visited);
- })) ||
- // If `value` is a plain object containing properties with a JSON
- // values it's a valid JSON.
- (isFlat(value) && Object.keys(value).every(function(key) {
- var $ = Object.getOwnPropertyDescriptor(value, key);
- // Check every proprety of a plain object to verify that
- // it's neither getter nor setter, but a JSON value, that
- // has not been visited yet.
- return ((!isObject($.value) || !~visited.indexOf($.value)) &&
- !('get' in $) && !('set' in $) &&
- isJSON($.value, visited));
- }));
-}
-exports.isJSON = function (value) {
- return isJSON(value);
-};
-
-/**
- * Returns if `value` is an instance of a given `Type`. This is exactly same as
- * `value instanceof Type` with a difference that `Type` can be from a scope
- * that has a different top level object. (Like in case where `Type` is a
- * function from different iframe / jetpack module / sandbox).
- */
-function instanceOf(value, Type) {
- var isConstructorNameSame;
- var isConstructorSourceSame;
-
- // If `instanceof` returned `true` we know result right away.
- var isInstanceOf = value instanceof Type;
-
- // If `instanceof` returned `false` we do ducktype check since `Type` may be
- // from a different sandbox. If a constructor of the `value` or a constructor
- // of the value's prototype has same name and source we assume that it's an
- // instance of the Type.
- if (!isInstanceOf && value) {
- isConstructorNameSame = value.constructor.name === Type.name;
- isConstructorSourceSame = String(value.constructor) == String(Type);
- isInstanceOf = (isConstructorNameSame && isConstructorSourceSame) ||
- instanceOf(Object.getPrototypeOf(value), Type);
- }
- return isInstanceOf;
-}
-exports.instanceOf = instanceOf;
-
-/**
- * Function returns textual representation of a value passed to it. Function
- * takes additional `indent` argument that is used for indentation. Also
- * optional `limit` argument may be passed to limit amount of detail returned.
- * @param {Object} value
- * @param {String} [indent=" "]
- * @param {Number} [limit]
- */
-function source(value, indent, limit, offset, visited) {
- var result;
- var names;
- var nestingIndex;
- var isCompact = !isUndefined(limit);
-
- indent = indent || " ";
- offset = (offset || "");
- result = "";
- visited = visited || [];
-
- if (isUndefined(value)) {
- result += "undefined";
- }
- else if (isNull(value)) {
- result += "null";
- }
- else if (isString(value)) {
- result += '"' + value + '"';
- }
- else if (isFunction(value)) {
- value = String(value).split("\n");
- if (isCompact && value.length > 2) {
- value = value.splice(0, 2);
- value.push("...}");
- }
- result += value.join("\n" + offset);
- }
- else if (isArray(value)) {
- if ((nestingIndex = (visited.indexOf(value) + 1))) {
- result = "#" + nestingIndex + "#";
- }
- else {
- visited.push(value);
-
- if (isCompact)
- value = value.slice(0, limit);
-
- result += "[\n";
- result += value.map(function(value) {
- return offset + indent + source(value, indent, limit, offset + indent,
- visited);
- }).join(",\n");
- result += isCompact && value.length > limit ?
- ",\n" + offset + "...]" : "\n" + offset + "]";
- }
- }
- else if (isObject(value)) {
- if ((nestingIndex = (visited.indexOf(value) + 1))) {
- result = "#" + nestingIndex + "#"
- }
- else {
- visited.push(value)
-
- names = Object.keys(value);
-
- result += "{ // " + value + "\n";
- result += (isCompact ? names.slice(0, limit) : names).map(function(name) {
- var _limit = isCompact ? limit - 1 : limit;
- var descriptor = Object.getOwnPropertyDescriptor(value, name);
- var result = offset + indent + "// ";
- var accessor;
- if (0 <= name.indexOf(" "))
- name = '"' + name + '"';
-
- if (descriptor.writable)
- result += "writable ";
- if (descriptor.configurable)
- result += "configurable ";
- if (descriptor.enumerable)
- result += "enumerable ";
-
- result += "\n";
- if ("value" in descriptor) {
- result += offset + indent + name + ": ";
- result += source(descriptor.value, indent, _limit, indent + offset,
- visited);
- }
- else {
-
- if (descriptor.get) {
- result += offset + indent + "get " + name + " ";
- accessor = source(descriptor.get, indent, _limit, indent + offset,
- visited);
- result += accessor.substr(accessor.indexOf("{"));
- }
-
- if (descriptor.set) {
- result += offset + indent + "set " + name + " ";
- accessor = source(descriptor.set, indent, _limit, indent + offset,
- visited);
- result += accessor.substr(accessor.indexOf("{"));
- }
- }
- return result;
- }).join(",\n");
-
- if (isCompact) {
- if (names.length > limit && limit > 0) {
- result += ",\n" + offset + indent + "//...";
- }
- }
- else {
- if (names.length)
- result += ",";
-
- result += "\n" + offset + indent + '"__proto__": ';
- result += source(Object.getPrototypeOf(value), indent, 0,
- offset + indent);
- }
-
- result += "\n" + offset + "}";
- }
- }
- else {
- result += String(value);
- }
- return result;
-}
-exports.source = function (value, indentation, limit) {
- return source(value, indentation, limit);
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/loader/cuddlefish.js b/tools/addon-sdk-1.12/lib/sdk/loader/cuddlefish.js
deleted file mode 100644
index cac05a9..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/loader/cuddlefish.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 expandtab */
-/* 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"
-};
-
-// This module is manually loaded by bootstrap.js in a sandbox and immediatly
-// put in module cache so that it is never loaded in any other way.
-
-/* Workarounds to include dependencies in the manifest
-require('chrome') // Otherwise CFX will complain about Components
-require('toolkit/loader') // Otherwise CFX will stip out loader.js
-require('sdk/addon/runner') // Otherwise CFX will stip out addon/runner.js
-*/
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
-
-// `loadSandbox` is exposed by bootstrap.js
-const loaderURI = module.uri.replace("sdk/loader/cuddlefish.js",
- "toolkit/loader.js");
-// We need to keep a reference to the sandbox in order to unload it in
-// bootstrap.js
-const loaderSandbox = loadSandbox(loaderURI);
-const loaderModule = loaderSandbox.exports;
-
-const { override } = loaderModule;
-
-function CuddlefishLoader(options) {
- let { manifest } = options;
-
- options = override(options, {
- // Put `api-utils/loader` and `api-utils/cuddlefish` loaded as JSM to module
- // cache to avoid subsequent loads via `require`.
- modules: override({
- 'toolkit/loader': loaderModule,
- 'addon-sdk/sdk/loader/cuddlefish': exports
- }, options.modules),
- resolve: function resolve(id, requirer) {
- let entry = requirer && requirer in manifest && manifest[requirer];
- let uri = null;
-
- // If manifest entry for this requirement is present we follow manifest.
- // Note: Standard library modules like 'panel' will be present in
- // manifest unless they were moved to platform.
- if (entry) {
- let requirement = entry.requirements[id];
- // If requirer entry is in manifest and it's requirement is not, than
- // it has no authority to load since linker was not able to find it.
- if (!requirement)
- throw Error('Module: ' + requirer.id + ' located at ' + requirer.uri
- + ' has no authority to load: ' + id, requirer.uri);
-
- uri = requirement;
- }
- // If requirer is off manifest than it's a system module and we allow it
- // to go off manifest.
- else {
- uri = id;
- }
- return uri;
- }
- });
-
- let loader = loaderModule.Loader(options);
- // Hack to allow loading from `toolkit/loader`.
- loader.modules[loaderURI] = loaderSandbox;
- return loader;
-}
-
-exports = override(loaderModule, {
- Loader: CuddlefishLoader
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/loader/sandbox.js b/tools/addon-sdk-1.12/lib/sdk/loader/sandbox.js
deleted file mode 100644
index 3c085aa..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/loader/sandbox.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "experimental"
-};
-
-const { Cc, Ci, CC, Cu } = require('chrome');
-const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')();
-const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1'].
- getService(Ci.mozIJSSubScriptLoader);
-
-/**
- * Make a new sandbox that inherits given `source`'s principals. Source can be
- * URI string, DOMWindow or `null` for system principals.
- */
-function sandbox(target, options) {
- return Cu.Sandbox(target || systemPrincipal, options || {});
-}
-exports.sandbox = sandbox
-
-/**
- * Evaluates given `source` in a given `sandbox` and returns result.
- */
-function evaluate(sandbox, code, uri, line, version) {
- return Cu.evalInSandbox(code, sandbox, version || '1.8', uri || '', line || 1);
-}
-exports.evaluate = evaluate;
-
-/**
- * Evaluates code under the given `uri` in the given `sandbox`.
- *
- * @param {String} uri
- * The URL pointing to the script to load.
- * It must be a local chrome:, resource:, file: or data: URL.
- */
-function load(sandbox, uri) {
- if (uri.indexOf('data:') === 0) {
- let source = uri.substr(uri.indexOf(',') + 1);
-
- return evaluate(sandbox, decodeURIComponent(source), '1.8', uri, 0);
- } else {
- return scriptLoader.loadSubScript(uri, sandbox, 'UTF-8');
- }
-}
-exports.load = load; \ No newline at end of file
diff --git a/tools/addon-sdk-1.12/lib/sdk/net/url.js b/tools/addon-sdk-1.12/lib/sdk/net/url.js
deleted file mode 100644
index 5992e0d..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/net/url.js
+++ /dev/null
@@ -1,108 +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/. */
-
-const { Cu, components } = require("chrome");
-const { defer } = require("../core/promise");
-const { merge } = require("../util/object");
-
-const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
-
-/**
- * Open a channel synchronously for the URI given, with an optional charset, and
- * returns a resolved promise if succeed; rejected promise otherwise.
- */
-function readSync(uri, charset) {
- let { promise, resolve, reject } = defer();
-
- try {
- resolve(readURISync(uri, charset));
- }
- catch (e) {
- reject("Failed to read: '" + uri + "' (Error Code: " + e.result + ")");
- }
-
- return promise;
-}
-
-/**
- * Open a channel synchronously for the URI given, with an optional charset, and
- * returns a promise.
- */
-function readAsync(uri, charset) {
- let channel = NetUtil.newChannel(uri, charset, null);
-
- let { promise, resolve, reject } = defer();
-
- NetUtil.asyncFetch(channel, function (stream, result) {
- if (components.isSuccessCode(result)) {
- let count = stream.available();
- let data = NetUtil.readInputStreamToString(stream, count, { charset : charset });
-
- resolve(data);
- } else {
- reject("Failed to read: '" + uri + "' (Error Code: " + result + ")");
- }
- });
-
- return promise;
-}
-
-/**
- * Reads a URI and returns a promise. If the `sync` option is set to `true`, the
- * promise will be resolved synchronously.
- *
- * @param uri {string} The URI to read
- * @param [options] {object} This parameter can have any or all of the following
- * fields: `sync`, `charset`. By default the `charset` is set to 'UTF-8'.
- *
- * @returns {promise} The promise that will be resolved with the content of the
- * URL given.
- *
- * @example
- * let promise = readURI('resource://gre/modules/NetUtil.jsm', {
- * sync: true,
- * charset: 'US-ASCII'
- });
- */
-function readURI(uri, options) {
- options = merge({
- charset: "UTF-8",
- sync: false
- }, options);
-
- return options.sync
- ? readSync(uri, options.charset)
- : readAsync(uri, options.charset);
-}
-
-exports.readURI = readURI;
-
-/**
- * Reads a URI synchronously.
- * This function is intentionally undocumented to favorites the `readURI` usage.
- *
- * @param uri {string} The URI to read
- * @param [charset] {string} The character set to use when read the content of
- * the `uri` given. By default is set to 'UTF-8'.
- *
- * @returns {string} The content of the URI given.
- *
- * @example
- * let data = readURISync('resource://gre/modules/NetUtil.jsm');
- */
-function readURISync(uri, charset) {
- charset = typeof charset === "string" ? charset : "UTF-8";
-
- let channel = NetUtil.newChannel(uri, charset, null);
- let stream = channel.open();
-
- let count = stream.available();
- let data = NetUtil.readInputStreamToString(stream, count, { charset : charset });
-
- stream.close();
-
- return data;
-}
-
-exports.readURISync = readURISync;
diff --git a/tools/addon-sdk-1.12/lib/sdk/net/xhr.js b/tools/addon-sdk-1.12/lib/sdk/net/xhr.js
deleted file mode 100644
index b4fc1ef..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/net/xhr.js
+++ /dev/null
@@ -1,154 +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 { Cc, Ci } = require("chrome");
-const memory = require('../deprecated/memory');
-const { when: unload } = require("../system/unload");
-
-// ## Implementation Notes ##
-//
-// Making `XMLHttpRequest` objects available to Jetpack code involves a
-// few key principles universal to all low-level module implementations:
-//
-// * **Unloadability**. A Jetpack-based extension using this module can be
-// asked to unload itself at any time, e.g. because the user decides to
-// uninstall or disable the extension. This means we need to keep track of
-// all in-progress reqests and abort them on unload.
-//
-// * **Developer-Ergonomic Tracebacks**. Whenever an exception is raised
-// by a Jetpack-based extension, we want it to be logged in a
-// place that is specific to that extension--so that a developer
-// can distinguish it from an error on a web page or in another
-// extension, for instance. We also want it to be logged with a
-// full stack traceback, which the Mozilla platform doesn't usually
-// do.
-//
-// Because of this, we don't actually want to give the Mozilla
-// platform's "real" XHR implementation to clients, but instead provide
-// a simple wrapper that trivially delegates to the implementation in
-// all cases except where callbacks are involved: whenever Mozilla
-// platform code calls into the extension, such as during the XHR's
-// `onreadystatechange` callback, we want to wrap the client's callback
-// in a try-catch clause that traps any exceptions raised by the
-// callback and logs them via console.exception() instead of allowing
-// them to propagate back into Mozilla platform code.
-
-// This is a private list of all active requests, so we know what to
-// abort if we're asked to unload.
-var requests = [];
-
-// Events on XHRs that we should listen for, so we know when to remove
-// a request from our private list.
-const TERMINATE_EVENTS = ["load", "error", "abort"];
-
-// Read-only properties of XMLHttpRequest objects that we want to
-// directly delegate to.
-const READ_ONLY_PROPS = ["readyState", "responseText", "responseXML",
- "status", "statusText"];
-
-// Methods of XMLHttpRequest that we want to directly delegate to.
-const DELEGATED_METHODS = ["abort", "getAllResponseHeaders",
- "getResponseHeader", "overrideMimeType",
- "send", "sendAsBinary", "setRequestHeader",
- "open"];
-
-var getRequestCount = exports.getRequestCount = function getRequestCount() {
- return requests.length;
-};
-
-var XMLHttpRequest = exports.XMLHttpRequest = function XMLHttpRequest() {
- var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
- .createInstance(Ci.nsIXMLHttpRequest);
- // For the sake of simplicity, don't tie this request to any UI.
- req.mozBackgroundRequest = true;
-
- memory.track(req, "XMLHttpRequest");
-
- this._req = req;
- this._orsc = null;
-
- requests.push(this);
-
- var self = this;
-
- this._boundCleanup = function _boundCleanup() {
- self._cleanup();
- };
-
- TERMINATE_EVENTS.forEach(
- function(name) {
- self._req.addEventListener(name, self._boundCleanup, false);
- });
-};
-
-XMLHttpRequest.prototype = {
- _cleanup: function _cleanup() {
- this.onreadystatechange = null;
- var index = requests.indexOf(this);
- if (index != -1) {
- var self = this;
- TERMINATE_EVENTS.forEach(
- function(name) {
- self._req.removeEventListener(name, self._boundCleanup, false);
- });
- requests.splice(index, 1);
- }
- },
- _unload: function _unload() {
- this._req.abort();
- this._cleanup();
- },
- addEventListener: function addEventListener() {
- throw new Error("not implemented");
- },
- removeEventListener: function removeEventListener() {
- throw new Error("not implemented");
- },
- set upload(newValue) {
- throw new Error("not implemented");
- },
- get onreadystatechange() {
- return this._orsc;
- },
- set onreadystatechange(cb) {
- this._orsc = cb;
- if (cb) {
- var self = this;
- this._req.onreadystatechange = function() {
- try {
- self._orsc.apply(self, arguments);
- } catch (e) {
- console.exception(e);
- }
- };
- } else
- this._req.onreadystatechange = null;
- }
-};
-
-READ_ONLY_PROPS.forEach(
- function(name) {
- XMLHttpRequest.prototype.__defineGetter__(
- name,
- function() {
- return this._req[name];
- });
- });
-
-DELEGATED_METHODS.forEach(
- function(name) {
- XMLHttpRequest.prototype[name] = function() {
- return this._req[name].apply(this._req, arguments);
- };
- });
-
-unload(function() {
- requests.slice().forEach(function(request) { request._unload(); });
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/notifications.js b/tools/addon-sdk-1.12/lib/sdk/notifications.js
deleted file mode 100644
index 909552f..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/notifications.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et filetype=javascript
- * 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": "stable"
-};
-
-const { Cc, Ci, Cr } = require("chrome");
-const apiUtils = require("./deprecated/api-utils");
-const errors = require("./deprecated/errors");
-
-try {
- let alertServ = Cc["@mozilla.org/alerts-service;1"].
- getService(Ci.nsIAlertsService);
-
- // The unit test sets this to a mock notification function.
- var notify = alertServ.showAlertNotification.bind(alertServ);
-}
-catch (err) {
- // An exception will be thrown if the platform doesn't provide an alert
- // service, e.g., if Growl is not installed on OS X. In that case, use a
- // mock notification function that just logs to the console.
- notify = notifyUsingConsole;
-}
-
-exports.notify = function notifications_notify(options) {
- let valOpts = validateOptions(options);
- let clickObserver = !valOpts.onClick ? null : {
- observe: function notificationClickObserved(subject, topic, data) {
- if (topic === "alertclickcallback")
- errors.catchAndLog(valOpts.onClick).call(exports, valOpts.data);
- }
- };
- function notifyWithOpts(notifyFn) {
- notifyFn(valOpts.iconURL, valOpts.title, valOpts.text, !!clickObserver,
- valOpts.data, clickObserver);
- }
- try {
- notifyWithOpts(notify);
- }
- catch (err if err instanceof Ci.nsIException &&
- err.result == Cr.NS_ERROR_FILE_NOT_FOUND) {
- console.warn("The notification icon named by " + valOpts.iconURL +
- " does not exist. A default icon will be used instead.");
- delete valOpts.iconURL;
- notifyWithOpts(notify);
- }
- catch (err) {
- notifyWithOpts(notifyUsingConsole);
- }
-};
-
-function notifyUsingConsole(iconURL, title, text) {
- title = title ? "[" + title + "]" : "";
- text = text || "";
- let str = [title, text].filter(function (s) s).join(" ");
- console.log(str);
-}
-
-function validateOptions(options) {
- return apiUtils.validateOptions(options, {
- data: {
- is: ["string", "undefined"]
- },
- iconURL: {
- is: ["string", "undefined"]
- },
- onClick: {
- is: ["function", "undefined"]
- },
- text: {
- is: ["string", "undefined"]
- },
- title: {
- is: ["string", "undefined"]
- }
- });
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/page-mod.js b/tools/addon-sdk-1.12/lib/sdk/page-mod.js
deleted file mode 100644
index 8bd4e5f..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/page-mod.js
+++ /dev/null
@@ -1,380 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "stable"
-};
-
-const observers = require('./deprecated/observer-service');
-const { Loader, validationAttributes } = require('./content/loader');
-const { Worker } = require('./content/worker');
-const { EventEmitter } = require('./deprecated/events');
-const { List } = require('./deprecated/list');
-const { Registry } = require('./util/registry');
-const { MatchPattern } = require('./page-mod/match-pattern');
-const { validateOptions : validate } = require('./deprecated/api-utils');
-const { Cc, Ci } = require('chrome');
-const { merge } = require('./util/object');
-const { readURISync } = require('./net/url');
-const { windowIterator } = require('./deprecated/window-utils');
-const { isBrowser, getFrames } = require('./window/utils');
-const { getTabs, getTabContentWindow, getTabForContentWindow,
- getURI: getTabURI } = require('./tabs/utils');
-const { has, hasAny } = require('./util/array');
-
-const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].
- getService(Ci.nsIStyleSheetService);
-
-const USER_SHEET = styleSheetService.USER_SHEET;
-
-const io = Cc['@mozilla.org/network/io-service;1'].
- getService(Ci.nsIIOService);
-
-// Valid values for `attachTo` option
-const VALID_ATTACHTO_OPTIONS = ['existing', 'top', 'frame'];
-
-// contentStyle* / contentScript* are sharing the same validation constraints,
-// so they can be mostly reused, except for the messages.
-const validStyleOptions = {
- contentStyle: merge(Object.create(validationAttributes.contentScript), {
- msg: 'The `contentStyle` option must be a string or an array of strings.'
- }),
- contentStyleFile: merge(Object.create(validationAttributes.contentScriptFile), {
- msg: 'The `contentStyleFile` option must be a local URL or an array of URLs'
- })
-};
-
-// rules registry
-const RULES = {};
-
-const Rules = EventEmitter.resolve({ toString: null }).compose(List, {
- add: function() Array.slice(arguments).forEach(function onAdd(rule) {
- if (this._has(rule))
- return;
- // registering rule to the rules registry
- if (!(rule in RULES))
- RULES[rule] = new MatchPattern(rule);
- this._add(rule);
- this._emit('add', rule);
- }.bind(this)),
- remove: function() Array.slice(arguments).forEach(function onRemove(rule) {
- if (!this._has(rule))
- return;
- this._remove(rule);
- this._emit('remove', rule);
- }.bind(this)),
-});
-
-/**
- * PageMod constructor (exported below).
- * @constructor
- */
-const PageMod = Loader.compose(EventEmitter, {
- on: EventEmitter.required,
- _listeners: EventEmitter.required,
- attachTo: [],
- contentScript: Loader.required,
- contentScriptFile: Loader.required,
- contentScriptWhen: Loader.required,
- contentScriptOptions: Loader.required,
- include: null,
- constructor: function PageMod(options) {
- this._onContent = this._onContent.bind(this);
- options = options || {};
-
- let { contentStyle, contentStyleFile } = validate(options, validStyleOptions);
-
- if ('contentScript' in options)
- this.contentScript = options.contentScript;
- if ('contentScriptFile' in options)
- this.contentScriptFile = options.contentScriptFile;
- if ('contentScriptOptions' in options)
- this.contentScriptOptions = options.contentScriptOptions;
- if ('contentScriptWhen' in options)
- this.contentScriptWhen = options.contentScriptWhen;
- if ('onAttach' in options)
- this.on('attach', options.onAttach);
- if ('onError' in options)
- this.on('error', options.onError);
- if ('attachTo' in options) {
- if (typeof options.attachTo == 'string')
- this.attachTo = [options.attachTo];
- else if (Array.isArray(options.attachTo))
- this.attachTo = options.attachTo;
- else
- throw new Error('The `attachTo` option must be a string or an array ' +
- 'of strings.');
-
- let isValidAttachToItem = function isValidAttachToItem(item) {
- return typeof item === 'string' &&
- VALID_ATTACHTO_OPTIONS.indexOf(item) !== -1;
- }
- if (!this.attachTo.every(isValidAttachToItem))
- throw new Error('The `attachTo` option valid accept only following ' +
- 'values: '+ VALID_ATTACHTO_OPTIONS.join(', '));
- if (!hasAny(this.attachTo, ["top", "frame"]))
- throw new Error('The `attachTo` option must always contain at least' +
- ' `top` or `frame` value');
- }
- else {
- this.attachTo = ["top", "frame"];
- }
-
- let include = options.include;
- let rules = this.include = Rules();
- rules.on('add', this._onRuleAdd = this._onRuleAdd.bind(this));
- rules.on('remove', this._onRuleRemove = this._onRuleRemove.bind(this));
-
- if (Array.isArray(include))
- rules.add.apply(null, include);
- else
- rules.add(include);
-
- let styleRules = "";
-
- if (contentStyleFile)
- styleRules = [].concat(contentStyleFile).map(readURISync).join("");
-
- if (contentStyle)
- styleRules += [].concat(contentStyle).join("");
-
- if (styleRules) {
- this._onRuleUpdate = this._onRuleUpdate.bind(this);
-
- this._styleRules = styleRules;
-
- this._registerStyleSheet();
- rules.on('add', this._onRuleUpdate);
- rules.on('remove', this._onRuleUpdate);
- }
-
- this.on('error', this._onUncaughtError = this._onUncaughtError.bind(this));
- pageModManager.add(this._public);
-
- this._loadingWindows = [];
-
- // `_applyOnExistingDocuments` has to be called after `pageModManager.add()`
- // otherwise its calls to `_onContent` method won't do anything.
- if ('attachTo' in options && has(options.attachTo, 'existing'))
- this._applyOnExistingDocuments();
- },
-
- destroy: function destroy() {
-
- this._unregisterStyleSheet();
-
- this.include.removeListener('add', this._onRuleUpdate);
- this.include.removeListener('remove', this._onRuleUpdate);
-
- for each (let rule in this.include)
- this.include.remove(rule);
- pageModManager.remove(this._public);
- this._loadingWindows = [];
-
- },
-
- _loadingWindows: [],
-
- _applyOnExistingDocuments: function _applyOnExistingDocuments() {
- let mod = this;
- // Returns true if the tab match one rule
- function isMatchingURI(uri) {
- // Use Array.some as `include` isn't a native array
- return Array.some(mod.include, function (rule) {
- return RULES[rule].test(uri);
- });
- }
- let tabs = getAllTabs().filter(function (tab) {
- return isMatchingURI(getTabURI(tab));
- });
-
- tabs.forEach(function (tab) {
- // Fake a newly created document
- let window = getTabContentWindow(tab);
- if (has(mod.attachTo, "top"))
- mod._onContent(window);
- if (has(mod.attachTo, "frame"))
- getFrames(window).forEach(mod._onContent);
- });
- },
-
- _onContent: function _onContent(window) {
- // not registered yet
- if (!pageModManager.has(this))
- return;
-
- let isTopDocument = window.top === window;
- // Is a top level document and `top` is not set, ignore
- if (isTopDocument && !has(this.attachTo, "top"))
- return;
- // Is a frame document and `frame` is not set, ignore
- if (!isTopDocument && !has(this.attachTo, "frame"))
- return;
-
- // Immediatly evaluate content script if the document state is already
- // matching contentScriptWhen expectations
- let state = window.document.readyState;
- if ('start' === this.contentScriptWhen ||
- // Is `load` event already dispatched?
- 'complete' === state ||
- // Is DOMContentLoaded already dispatched and waiting for it?
- ('ready' === this.contentScriptWhen && state === 'interactive') ) {
- this._createWorker(window);
- return;
- }
-
- let eventName = 'end' == this.contentScriptWhen ? 'load' : 'DOMContentLoaded';
- let self = this;
- window.addEventListener(eventName, function onReady(event) {
- if (event.target.defaultView != window)
- return;
- window.removeEventListener(eventName, onReady, true);
-
- self._createWorker(window);
- }, true);
- },
- _createWorker: function _createWorker(window) {
- let worker = Worker({
- window: window,
- contentScript: this.contentScript,
- contentScriptFile: this.contentScriptFile,
- contentScriptOptions: this.contentScriptOptions,
- onError: this._onUncaughtError
- });
- this._emit('attach', worker);
- let self = this;
- worker.once('detach', function detach() {
- worker.destroy();
- });
- },
- _onRuleAdd: function _onRuleAdd(url) {
- pageModManager.on(url, this._onContent);
- },
- _onRuleRemove: function _onRuleRemove(url) {
- pageModManager.off(url, this._onContent);
- },
- _onUncaughtError: function _onUncaughtError(e) {
- if (this._listeners('error').length == 1)
- console.exception(e);
- },
- _onRuleUpdate: function _onRuleUpdate(){
- this._registerStyleSheet();
- },
-
- _registerStyleSheet : function _registerStyleSheet() {
- let rules = this.include;
- let styleRules = this._styleRules;
-
- let documentRules = [];
-
- this._unregisterStyleSheet();
-
- for each (let rule in rules) {
- let pattern = RULES[rule];
-
- if (!pattern)
- continue;
-
- if (pattern.regexp)
- documentRules.push("regexp(\"" + pattern.regexp.source + "\")");
- else if (pattern.exactURL)
- documentRules.push("url(" + pattern.exactURL + ")");
- else if (pattern.domain)
- documentRules.push("domain(" + pattern.domain + ")");
- else if (pattern.urlPrefix)
- documentRules.push("url-prefix(" + pattern.urlPrefix + ")");
- else if (pattern.anyWebPage) {
- documentRules.push("regexp(\"^(https?|ftp)://.*?\")");
- break;
- }
- }
-
- let uri = "data:text/css;charset=utf-8,";
- if (documentRules.length > 0)
- uri += encodeURIComponent("@-moz-document " +
- documentRules.join(",") + " {" + styleRules + "}");
- else
- uri += encodeURIComponent(styleRules);
-
- this._registeredStyleURI = io.newURI(uri, null, null);
-
- styleSheetService.loadAndRegisterSheet(
- this._registeredStyleURI,
- USER_SHEET
- );
- },
-
- _unregisterStyleSheet : function () {
- let uri = this._registeredStyleURI;
-
- if (uri && styleSheetService.sheetRegistered(uri, USER_SHEET))
- styleSheetService.unregisterSheet(uri, USER_SHEET);
-
- this._registeredStyleURI = null;
- }
-});
-exports.PageMod = function(options) PageMod(options)
-exports.PageMod.prototype = PageMod.prototype;
-
-const PageModManager = Registry.resolve({
- constructor: '_init',
- _destructor: '_registryDestructor'
-}).compose({
- constructor: function PageModRegistry(constructor) {
- this._init(PageMod);
- observers.add(
- 'document-element-inserted',
- this._onContentWindow = this._onContentWindow.bind(this)
- );
- },
- _destructor: function _destructor() {
- observers.remove('document-element-inserted', this._onContentWindow);
- this._removeAllListeners();
- for (let rule in RULES) {
- delete RULES[rule];
- }
-
- // We need to do some cleaning er PageMods, like unregistering any
- // `contentStyle*`
- this._registry.forEach(function(pageMod) {
- pageMod.destroy();
- });
-
- this._registryDestructor();
- },
- _onContentWindow: function _onContentWindow(document) {
- let window = document.defaultView;
- // XML documents don't have windows, and we don't yet support them.
- if (!window)
- return;
- // We apply only on documents in tabs of Firefox
- if (!getTabForContentWindow(window))
- return;
-
- for (let rule in RULES)
- if (RULES[rule].test(document.URL))
- this._emit(rule, window);
- },
- off: function off(topic, listener) {
- this.removeListener(topic, listener);
- if (!this._listeners(topic).length)
- delete RULES[topic];
- }
-});
-const pageModManager = PageModManager();
-
-// Returns all tabs on all currently opened windows
-function getAllTabs() {
- let tabs = [];
- // Iterate over all chrome windows
- for (let window in windowIterator()) {
- if (!isBrowser(window))
- continue;
- tabs = tabs.concat(getTabs(window));
- }
- return tabs;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/page-mod/match-pattern.js b/tools/addon-sdk-1.12/lib/sdk/page-mod/match-pattern.js
deleted file mode 100644
index 5c42e66..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/page-mod/match-pattern.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { URL } = require("../url");
-
-exports.MatchPattern = MatchPattern;
-
-function MatchPattern(pattern) {
- if (typeof pattern.test == "function") {
-
- // For compatibility with -moz-document rules, we require the RegExp's
- // global, ignoreCase, and multiline flags to be set to false.
- if (pattern.global) {
- throw new Error("A RegExp match pattern cannot be set to `global` " +
- "(i.e. //g).");
- }
- if (pattern.ignoreCase) {
- throw new Error("A RegExp match pattern cannot be set to `ignoreCase` " +
- "(i.e. //i).");
- }
- if (pattern.multiline) {
- throw new Error("A RegExp match pattern cannot be set to `multiline` " +
- "(i.e. //m).");
- }
-
- this.regexp = pattern;
- }
- else {
- let firstWildcardPosition = pattern.indexOf("*");
- let lastWildcardPosition = pattern.lastIndexOf("*");
- if (firstWildcardPosition != lastWildcardPosition)
- throw new Error("There can be at most one '*' character in a wildcard.");
-
- if (firstWildcardPosition == 0) {
- if (pattern.length == 1)
- this.anyWebPage = true;
- else if (pattern[1] != ".")
- throw new Error("Expected a *.<domain name> string, got: " + pattern);
- else
- this.domain = pattern.substr(2);
- }
- else {
- if (pattern.indexOf(":") == -1) {
- throw new Error("When not using *.example.org wildcard, the string " +
- "supplied is expected to be either an exact URL to " +
- "match or a URL prefix. The provided string ('" +
- pattern + "') is unlikely to match any pages.");
- }
-
- if (firstWildcardPosition == -1)
- this.exactURL = pattern;
- else if (firstWildcardPosition == pattern.length - 1)
- this.urlPrefix = pattern.substr(0, pattern.length - 1);
- else {
- throw new Error("The provided wildcard ('" + pattern + "') has a '*' " +
- "in an unexpected position. It is expected to be the " +
- "first or the last character in the wildcard.");
- }
- }
- }
-}
-
-MatchPattern.prototype = {
-
- test: function MatchPattern_test(urlStr) {
- try {
- var url = URL(urlStr);
- }
- catch (err) {
- return false;
- }
-
- // Test the URL against a RegExp pattern. For compatibility with
- // -moz-document rules, we require the RegExp to match the entire URL,
- // so we not only test for a match, we also make sure the matched string
- // is the entire URL string.
- //
- // Assuming most URLs don't match most match patterns, we call `test` for
- // speed when determining whether or not the URL matches, then call `exec`
- // for the small subset that match to make sure the entire URL matches.
- //
- if (this.regexp && this.regexp.test(urlStr) &&
- this.regexp.exec(urlStr)[0] == urlStr)
- return true;
-
- if (this.anyWebPage && /^(https?|ftp)$/.test(url.scheme))
- return true;
- if (this.exactURL && this.exactURL == urlStr)
- return true;
- if (this.domain && url.host &&
- url.host.slice(-this.domain.length) == this.domain)
- return true;
- if (this.urlPrefix && 0 == urlStr.indexOf(this.urlPrefix))
- return true;
-
- return false;
- }
-
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/page-worker.js b/tools/addon-sdk-1.12/lib/sdk/page-worker.js
deleted file mode 100644
index f667e4d..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/page-worker.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "stable"
-};
-
-const { Symbiont } = require("./content/symbiont");
-const { Trait } = require("./deprecated/traits");
-
-if (!require("./system/xul-app").isOneOf(["Firefox", "Thunderbird"])) {
- throw new Error([
- "The page-worker module currently supports only Firefox and Thunderbird. ",
- "In the future, we would like it to support other applications, however. ",
- "Please see https://bugzilla.mozilla.org/show_bug.cgi?id=546740 for more ",
- "information."
- ].join(""));
-}
-
-const Page = Trait.compose(
- Symbiont.resolve({
- constructor: '_initSymbiont'
- }),
- {
- _frame: Trait.required,
- _initFrame: Trait.required,
- postMessage: Symbiont.required,
- on: Symbiont.required,
- destroy: Symbiont.required,
-
- constructor: function Page(options) {
- options = options || {};
-
- this.contentURL = 'contentURL' in options ? options.contentURL
- : 'about:blank';
- if ('contentScriptWhen' in options)
- this.contentScriptWhen = options.contentScriptWhen;
- if ('contentScriptFile' in options)
- this.contentScriptFile = options.contentScriptFile;
- if ('contentScriptOptions' in options)
- this.contentScriptOptions = options.contentScriptOptions;
- if ('contentScript' in options)
- this.contentScript = options.contentScript;
- if ('allow' in options)
- this.allow = options.allow;
- if ('onError' in options)
- this.on('error', options.onError);
- if ('onMessage' in options)
- this.on('message', options.onMessage);
-
- this.on('propertyChange', this._onChange.bind(this));
-
- this._initSymbiont();
- },
-
- _onChange: function _onChange(e) {
- if ('contentURL' in e && this._frame) {
- // Cleanup the worker before injecting the content script in the new
- // document
- this._workerCleanup();
- this._initFrame(this._frame);
- }
- }
- }
-);
-exports.Page = function(options) Page(options);
-exports.Page.prototype = Page.prototype;
diff --git a/tools/addon-sdk-1.12/lib/sdk/panel.js b/tools/addon-sdk-1.12/lib/sdk/panel.js
deleted file mode 100644
index 3ce6284..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/panel.js
+++ /dev/null
@@ -1,403 +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": "stable"
-};
-
-if (!require("./system/xul-app").is("Firefox")) {
- throw new Error([
- "The panel module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=jetpack-panel-apps ",
- "for more information."
- ].join(""));
-}
-
-const { Cc, Ci } = require("chrome");
-
-const { validateOptions: valid } = require('./deprecated/api-utils');
-const { Symbiont } = require('./content/content');
-const { EventEmitter } = require('./deprecated/events');
-const timer = require('./timers');
-const runtime = require('./system/runtime');
-const { getMostRecentBrowserWindow } = require('./window/utils');
-
-const windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
- getService(Ci.nsIWindowMediator);
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
- ON_SHOW = 'popupshown',
- ON_HIDE = 'popuphidden',
- validNumber = { is: ['number', 'undefined', 'null'] };
-
-/**
- * Emits show and hide events.
- */
-const Panel = Symbiont.resolve({
- constructor: '_init',
- _onInit: '_onSymbiontInit',
- destroy: '_symbiontDestructor',
- _documentUnload: '_workerDocumentUnload'
-}).compose({
- _frame: Symbiont.required,
- _init: Symbiont.required,
- _onSymbiontInit: Symbiont.required,
- _symbiontDestructor: Symbiont.required,
- _emit: Symbiont.required,
- on: Symbiont.required,
- removeListener: Symbiont.required,
-
- _inited: false,
-
- /**
- * If set to `true` frame loaders between xul panel frame and
- * hidden frame are swapped. If set to `false` frame loaders are
- * set back to normal. Setting the value that was already set will
- * have no effect.
- */
- set _frameLoadersSwapped(value) {
- if (this.__frameLoadersSwapped == value) return;
- this._frame.QueryInterface(Ci.nsIFrameLoaderOwner)
- .swapFrameLoaders(this._viewFrame);
- this.__frameLoadersSwapped = value;
- },
- __frameLoadersSwapped: false,
-
- constructor: function Panel(options) {
- this._onShow = this._onShow.bind(this);
- this._onHide = this._onHide.bind(this);
- this.on('inited', this._onSymbiontInit.bind(this));
- this.on('propertyChange', this._onChange.bind(this));
-
- options = options || {};
- if ('onShow' in options)
- this.on('show', options.onShow);
- if ('onHide' in options)
- this.on('hide', options.onHide);
- if ('width' in options)
- this.width = options.width;
- if ('height' in options)
- this.height = options.height;
- if ('contentURL' in options)
- this.contentURL = options.contentURL;
-
- this._init(options);
- },
- _destructor: function _destructor() {
- this.hide();
- this._removeAllListeners('show');
- this._removeAllListeners('hide');
- this._removeAllListeners('propertyChange');
- this._removeAllListeners('inited');
- // defer cleanup to be performed after panel gets hidden
- this._xulPanel = null;
- this._symbiontDestructor(this);
- this._removeAllListeners();
- },
- destroy: function destroy() {
- this._destructor();
- },
- /* Public API: Panel.width */
- get width() this._width,
- set width(value)
- this._width = valid({ $: value }, { $: validNumber }).$ || this._width,
- _width: 320,
- /* Public API: Panel.height */
- get height() this._height,
- set height(value)
- this._height = valid({ $: value }, { $: validNumber }).$ || this._height,
- _height: 240,
-
- /* Public API: Panel.isShowing */
- get isShowing() !!this._xulPanel && this._xulPanel.state == "open",
-
- /* Public API: Panel.show */
- show: function show(anchor) {
- anchor = anchor || null;
- let document = getWindow(anchor).document;
- let xulPanel = this._xulPanel;
- if (!xulPanel) {
- xulPanel = this._xulPanel = document.createElementNS(XUL_NS, 'panel');
- xulPanel.setAttribute("type", "arrow");
-
- // One anonymous node has a big padding that doesn't work well with
- // Jetpack, as we would like to display an iframe that completely fills
- // the panel.
- // -> Use a XBL wrapper with inner stylesheet to remove this padding.
- let css = ".panel-inner-arrowcontent, .panel-arrowcontent {padding: 0;}";
- let originalXBL = "chrome://global/content/bindings/popup.xml#arrowpanel";
- let binding =
- '<bindings xmlns="http://www.mozilla.org/xbl">' +
- '<binding id="id" extends="' + originalXBL + '">' +
- '<resources>' +
- '<stylesheet src="data:text/css;charset=utf-8,' +
- document.defaultView.encodeURIComponent(css) + '"/>' +
- '</resources>' +
- '</binding>' +
- '</bindings>';
- xulPanel.style.MozBinding = 'url("data:text/xml;charset=utf-8,' +
- document.defaultView.encodeURIComponent(binding) + '")';
-
- let frame = document.createElementNS(XUL_NS, 'iframe');
- frame.setAttribute('type', 'content');
- frame.setAttribute('flex', '1');
- frame.setAttribute('transparent', 'transparent');
- if (runtime.OS === "Darwin") {
- frame.style.borderRadius = "6px";
- frame.style.padding = "1px";
- }
-
- // Load an empty document in order to have an immediatly loaded iframe,
- // so swapFrameLoaders is going to work without having to wait for load.
- frame.setAttribute("src","data:;charset=utf-8,");
-
- xulPanel.appendChild(frame);
- document.getElementById("mainPopupSet").appendChild(xulPanel);
- }
- let { width, height } = this, x, y, position;
-
- if (!anchor) {
- // Open the popup in the middle of the window.
- x = document.documentElement.clientWidth / 2 - width / 2;
- y = document.documentElement.clientHeight / 2 - height / 2;
- position = null;
- }
- else {
- // Open the popup by the anchor.
- let rect = anchor.getBoundingClientRect();
-
- let window = anchor.ownerDocument.defaultView;
-
- let zoom = window.mozScreenPixelsPerCSSPixel;
- let screenX = rect.left + window.mozInnerScreenX * zoom;
- let screenY = rect.top + window.mozInnerScreenY * zoom;
-
- // Set up the vertical position of the popup relative to the anchor
- // (always display the arrow on anchor center)
- let horizontal, vertical;
- if (screenY > window.screen.availHeight / 2 + height)
- vertical = "top";
- else
- vertical = "bottom";
-
- if (screenY > window.screen.availWidth / 2 + width)
- horizontal = "left";
- else
- horizontal = "right";
-
- let verticalInverse = vertical == "top" ? "bottom" : "top";
- position = vertical + "center " + verticalInverse + horizontal;
-
- // Allow panel to flip itself if the panel can't be displayed at the
- // specified position (useful if we compute a bad position or if the
- // user moves the window and panel remains visible)
- xulPanel.setAttribute("flip","both");
- }
-
- // Resize the iframe instead of using panel.sizeTo
- // because sizeTo doesn't work with arrow panels
- xulPanel.firstChild.style.width = width + "px";
- xulPanel.firstChild.style.height = height + "px";
-
- // Wait for the XBL binding to be constructed
- function waitForBinding() {
- if (!xulPanel.openPopup) {
- timer.setTimeout(waitForBinding, 50);
- return;
- }
- xulPanel.openPopup(anchor, position, x, y);
- }
- waitForBinding();
-
- return this._public;
- },
- /* Public API: Panel.hide */
- hide: function hide() {
- // The popuphiding handler takes care of swapping back the frame loaders
- // and removing the XUL panel from the application window, we just have to
- // trigger it by hiding the popup.
- // XXX Sometimes I get "TypeError: xulPanel.hidePopup is not a function"
- // when quitting the host application while a panel is visible. To suppress
- // them, this now checks for "hidePopup" in xulPanel before calling it.
- // It's not clear if there's an actual issue or the error is just normal.
- let xulPanel = this._xulPanel;
- if (xulPanel && "hidePopup" in xulPanel)
- xulPanel.hidePopup();
- return this._public;
- },
-
- /* Public API: Panel.resize */
- resize: function resize(width, height) {
- this.width = width;
- this.height = height;
- // Resize the iframe instead of using panel.sizeTo
- // because sizeTo doesn't work with arrow panels
- let xulPanel = this._xulPanel;
- if (xulPanel) {
- xulPanel.firstChild.style.width = width + "px";
- xulPanel.firstChild.style.height = height + "px";
- }
- },
-
- // While the panel is visible, this is the XUL <panel> we use to display it.
- // Otherwise, it's null.
- get _xulPanel() this.__xulPanel,
- set _xulPanel(value) {
- let xulPanel = this.__xulPanel;
- if (value === xulPanel) return;
- if (xulPanel) {
- xulPanel.removeEventListener(ON_HIDE, this._onHide, false);
- xulPanel.removeEventListener(ON_SHOW, this._onShow, false);
- xulPanel.parentNode.removeChild(xulPanel);
- }
- if (value) {
- value.addEventListener(ON_HIDE, this._onHide, false);
- value.addEventListener(ON_SHOW, this._onShow, false);
- }
- this.__xulPanel = value;
- },
- __xulPanel: null,
- get _viewFrame() this.__xulPanel.children[0],
- /**
- * When the XUL panel becomes hidden, we swap frame loaders back to move
- * the content of the panel to the hidden frame & remove panel element.
- */
- _onHide: function _onHide() {
- try {
- this._frameLoadersSwapped = false;
- this._xulPanel = null;
- this._emit('hide');
- } catch(e) {
- this._emit('error', e);
- }
- },
-
- /**
- * Retrieve computed text color style in order to apply to the iframe
- * document. As MacOS background is dark gray, we need to use skin's
- * text color.
- */
- _applyStyleToDocument: function _applyStyleToDocument() {
- try {
- let win = this._xulPanel.ownerDocument.defaultView;
- let node = win.document.getAnonymousElementByAttribute(
- this._xulPanel, "class", "panel-arrowcontent");
- if (!node) {
- // Before bug 764755, anonymous content was different:
- // TODO: Remove this when targeting FF16+
- node = win.document.getAnonymousElementByAttribute(
- this._xulPanel, "class", "panel-inner-arrowcontent");
- }
- let textColor = win.getComputedStyle(node).getPropertyValue("color");
- let doc = this._xulPanel.firstChild.contentDocument;
- let style = doc.createElement("style");
- style.textContent = "body { color: " + textColor + "; }";
- let container = doc.head ? doc.head : doc.documentElement;
-
- if (container.firstChild)
- container.insertBefore(style, container.firstChild);
- else
- container.appendChild(style);
- }
- catch(e) {
- console.error("Unable to apply panel style");
- console.exception(e);
- }
- },
-
- /**
- * When the XUL panel becomes shown, we swap frame loaders between panel
- * frame and hidden frame to preserve state of the content dom.
- */
- _onShow: function _onShow() {
- try {
- if (!this._inited) { // defer if not initialized yet
- this.on('inited', this._onShow.bind(this));
- } else {
- this._frameLoadersSwapped = true;
- this._applyStyleToDocument();
- this._emit('show');
- }
- } catch(e) {
- this._emit('error', e);
- }
- },
- /**
- * Notification that panel was fully initialized.
- */
- _onInit: function _onInit() {
- this._inited = true;
-
- // Avoid panel document from resizing the browser window
- // New platform capability added through bug 635673
- if ("allowWindowControl" in this._frame.docShell)
- this._frame.docShell.allowWindowControl = false;
-
- // perform all deferred tasks like initSymbiont, show, hide ...
- // TODO: We're publicly exposing a private event here; this
- // 'inited' event should really be made private, somehow.
- this._emit('inited');
- },
-
- // Catch document unload event in order to rebind load event listener with
- // Symbiont._initFrame if Worker._documentUnload destroyed the worker
- _documentUnload: function(subject, topic, data) {
- if (this._workerDocumentUnload(subject, topic, data)) {
- this._initFrame(this._frame);
- return true;
- }
- return false;
- },
-
- _onChange: function _onChange(e) {
- if ('contentURL' in e && this._frame) {
- // Cleanup the worker before injecting the content script in the new
- // document
- this._workerCleanup();
- this._initFrame(this._frame);
- }
- }
-});
-exports.Panel = function(options) Panel(options)
-exports.Panel.prototype = Panel.prototype;
-
-function getWindow(anchor) {
- let window;
-
- if (anchor) {
- let anchorWindow = anchor.ownerDocument.defaultView.top;
- let anchorDocument = anchorWindow.document;
-
- let enumerator = windowMediator.getEnumerator("navigator:browser");
- while (enumerator.hasMoreElements()) {
- let enumWindow = enumerator.getNext();
-
- // Check if the anchor is in this browser window.
- if (enumWindow == anchorWindow) {
- window = anchorWindow;
- break;
- }
-
- // Check if the anchor is in a browser tab in this browser window.
- let browser = enumWindow.gBrowser.getBrowserForDocument(anchorDocument);
- if (browser) {
- window = enumWindow;
- break;
- }
-
- // Look in other subdocuments (sidebar, etc.)?
- }
- }
-
- // If we didn't find the anchor's window (or we have no anchor),
- // return the most recent browser window.
- if (!window)
- window = getMostRecentBrowserWindow();
-
- return window;
-}
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/passwords.js b/tools/addon-sdk-1.12/lib/sdk/passwords.js
deleted file mode 100644
index 7aeb22a..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/passwords.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "stable"
-};
-
-const { search, remove, store } = require("./passwords/utils");
-const { defer, delay } = require("./lang/functional");
-
-/**
- * Utility function that returns `onComplete` and `onError` callbacks form the
- * given `options` objects. Also properties are removed from the passed
- * `options` objects.
- * @param {Object} options
- * Object that is passed to the exported functions of this module.
- * @returns {Function[]}
- * Array with two elements `onComplete` and `onError` functions.
- */
-function getCallbacks(options) {
- let value = [
- 'onComplete' in options ? options.onComplete : null,
- 'onError' in options ? defer(options.onError) : console.exception
- ];
-
- delete options.onComplete;
- delete options.onError;
-
- return value;
-};
-
-/**
- * Creates a wrapper function that tries to call `onComplete` with a return
- * value of the wrapped function or falls back to `onError` if wrapped function
- * throws an exception.
- */
-function createWrapperMethod(wrapped) {
- return function (options) {
- let [ onComplete, onError ] = getCallbacks(options);
- try {
- let value = wrapped(options);
- if (onComplete) {
- delay(function() {
- try {
- onComplete(value);
- } catch (exception) {
- onError(exception);
- }
- });
- }
- } catch (exception) {
- onError(exception);
- }
- };
-}
-
-exports.search = createWrapperMethod(search);
-exports.store = createWrapperMethod(store);
-exports.remove = createWrapperMethod(remove);
diff --git a/tools/addon-sdk-1.12/lib/sdk/passwords/utils.js b/tools/addon-sdk-1.12/lib/sdk/passwords/utils.js
deleted file mode 100644
index 8cc2230..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/passwords/utils.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { Cc, Ci, CC } = require("chrome");
-const { uri: ADDON_URI } = require("../self");
-const loginManager = Cc["@mozilla.org/login-manager;1"].
- getService(Ci.nsILoginManager);
-const { URL: parseURL } = require("../url");
-const LoginInfo = CC("@mozilla.org/login-manager/loginInfo;1",
- "nsILoginInfo", "init");
-
-function filterMatchingLogins(loginInfo)
- Object.keys(this).every(function(key) loginInfo[key] === this[key], this);
-
-/**
- * Removes `user`, `password` and `path` fields from the given `url` if it's
- * 'http', 'https' or 'ftp'. All other URLs are returned unchanged.
- * @example
- * http://user:pass@www.site.com/foo/?bar=baz#bang -> http://www.site.com
- */
-function normalizeURL(url) {
- let { scheme, host, port } = parseURL(url);
- // We normalize URL only if it's `http`, `https` or `ftp`. All other types of
- // URLs (`resource`, `chrome`, etc..) should not be normalized as they are
- // used with add-on associated credentials path.
- return scheme === "http" || scheme === "https" || scheme === "ftp" ?
- scheme + "://" + (host || "") + (port ? ":" + port : "") :
- url
-}
-
-function Login(options) {
- let login = Object.create(Login.prototype);
- Object.keys(options || {}).forEach(function(key) {
- if (key === 'url')
- login.hostname = normalizeURL(options.url);
- else if (key === 'formSubmitURL')
- login.formSubmitURL = options.formSubmitURL ?
- normalizeURL(options.formSubmitURL) : null;
- else if (key === 'realm')
- login.httpRealm = options.realm;
- else
- login[key] = options[key];
- });
-
- return login;
-}
-Login.prototype.toJSON = function toJSON() {
- return {
- url: this.hostname || ADDON_URI,
- realm: this.httpRealm || null,
- formSubmitURL: this.formSubmitURL || null,
- username: this.username || null,
- password: this.password || null,
- usernameField: this.usernameField || '',
- passwordField: this.passwordField || '',
- }
-};
-Login.prototype.toLoginInfo = function toLoginInfo() {
- let { url, realm, formSubmitURL, username, password, usernameField,
- passwordField } = this.toJSON();
-
- return new LoginInfo(url, formSubmitURL, realm, username, password,
- usernameField, passwordField);
-};
-
-function loginToJSON(value) Login(value).toJSON()
-
-/**
- * Returns array of `nsILoginInfo` objects that are stored in the login manager
- * and have all the properties with matching values as a given `options` object.
- * @param {Object} options
- * @returns {nsILoginInfo[]}
- */
-exports.search = function search(options) {
- return loginManager.getAllLogins()
- .filter(filterMatchingLogins, Login(options))
- .map(loginToJSON);
-};
-
-/**
- * Stores login info created from the given `options` to the applications
- * built-in login management system.
- * @param {Object} options.
- */
-exports.store = function store(options) {
- loginManager.addLogin(Login(options).toLoginInfo());
-};
-
-/**
- * Removes login info from the applications built-in login management system.
- * _Please note: When removing a login info the specified properties must
- * exactly match to the one that is already stored or exception will be thrown._
- * @param {Object} options.
- */
-exports.remove = function remove(options) {
- loginManager.removeLogin(Login(options).toLoginInfo());
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/platform/xpcom.js b/tools/addon-sdk-1.12/lib/sdk/platform/xpcom.js
deleted file mode 100644
index 279d234..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/platform/xpcom.js
+++ /dev/null
@@ -1,229 +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 { Cc, Ci, Cr, Cm, components: { classesByID } } = require('chrome');
-const { registerFactory, unregisterFactory, isCIDRegistered } =
- Cm.QueryInterface(Ci.nsIComponentRegistrar);
-
-const { merge } = require('../util/object');
-const { Class, extend, mix } = require('../core/heritage');
-const { uuid } = require('../util/uuid');
-
-// This is a base prototype, that provides bare bones of XPCOM. JS based
-// components can be easily implement by extending it.
-const Unknown = new function() {
- function hasInterface(component, iid) {
- return component && component.interfaces &&
- ( component.interfaces.some(function(id) iid.equals(Ci[id])) ||
- component.implements.some(function($) hasInterface($, iid)) ||
- hasInterface(Object.getPrototypeOf(component), iid));
- }
-
- return Class({
- /**
- * The `QueryInterface` method provides runtime type discovery used by XPCOM.
- * This method return queried instance of `this` if given `iid` is listed in
- * the `interfaces` property or in equivalent properties of objects in it's
- * prototype chain. In addition it will look up in the prototypes under
- * `implements` array property, this ways compositions made via `Class`
- * utility will carry interfaces implemented by composition components.
- */
- QueryInterface: function QueryInterface(iid) {
- // For some reason there are cases when `iid` is `null`. In such cases we
- // just return `this`. Otherwise we verify that component implements given
- // `iid` interface. This will be no longer necessary once Bug 748003 is
- // fixed.
- if (iid && !hasInterface(this, iid))
- throw Cr.NS_ERROR_NO_INTERFACE;
-
- return this;
- },
- /**
- * Array of `XPCOM` interfaces (as strings) implemented by this component.
- * All components implement `nsISupports` by default which is default value
- * here. Provide array of interfaces implemented by an object when
- * extending, to append them to this list (Please note that there is no
- * need to repeat interfaces implemented by super as they will be added
- * automatically).
- */
- interfaces: Object.freeze([ 'nsISupports' ])
- });
-}
-exports.Unknown = Unknown;
-
-// Base exemplar for creating instances implementing `nsIFactory` interface,
-// that maybe registered into runtime via `register` function. Instances of
-// this factory create instances of enclosed component on `createInstance`.
-const Factory = Class({
- extends: Unknown,
- interfaces: [ 'nsIFactory' ],
- /**
- * All the descendants will get auto generated `id` (also known as `classID`
- * in XPCOM world) unless one is manually provided.
- */
- get id() { throw Error('Factory must implement `id` property') },
- /**
- * XPCOM `contractID` may optionally be provided to associate this factory
- * with it. `contract` is a unique string that has a following format:
- * '@vendor.com/unique/id;1'.
- */
- contract: null,
- /**
- * Class description that is being registered. This value is intended as a
- * human-readable description for the given class and does not needs to be
- * globally unique.
- */
- description: 'Jetpack generated factory',
- /**
- * This method is required by `nsIFactory` interfaces, but as in most
- * implementations it does nothing interesting.
- */
- lockFactory: function lockFactory(lock) undefined,
- /**
- * If property is `true` XPCOM service / factory will be registered
- * automatically on creation.
- */
- register: true,
- /**
- * If property is `true` XPCOM factory will be unregistered prior to add-on
- * unload.
- */
- unregister: true,
- /**
- * Method is called on `Service.new(options)` passing given `options` to
- * it. Options is expected to have `component` property holding XPCOM
- * component implementation typically decedent of `Unknown` or any custom
- * implementation with a `new` method and optional `register`, `unregister`
- * flags. Unless `register` is `false` Service / Factory will be
- * automatically registered. Unless `unregister` is `false` component will
- * be automatically unregistered on add-on unload.
- */
- initialize: function initialize(options) {
- merge(this, {
- id: 'id' in options ? options.id : uuid(),
- register: 'register' in options ? options.register : this.register,
- unregister: 'unregister' in options ? options.unregister : this.unregister,
- contract: 'contract' in options ? options.contract : null,
- Component: options.Component
- });
-
- // If service / factory has auto registration enabled then register.
- if (this.register)
- register(this);
- },
- /**
- * Creates an instance of the class associated with this factory.
- */
- createInstance: function createInstance(outer, iid) {
- try {
- if (outer)
- throw Cr.NS_ERROR_NO_AGGREGATION;
- return this.create().QueryInterface(iid);
- }
- catch (error) {
- throw error instanceof Ci.nsIException ? error : Cr.NS_ERROR_FAILURE;
- }
- },
- create: function create() this.Component()
-});
-exports.Factory = Factory;
-
-// Exemplar for creating services that implement `nsIFactory` interface, that
-// can be registered into runtime via call to `register`. This services return
-// enclosed `component` on `getService`.
-const Service = Class({
- extends: Factory,
- initialize: function initialize(options) {
- this.component = options.Component();
- Factory.prototype.initialize.call(this, options);
- },
- description: 'Jetpack generated service',
- /**
- * Creates an instance of the class associated with this factory.
- */
- create: function create() this.component
-});
-exports.Service = Service;
-
-function isRegistered({ id }) isCIDRegistered(id)
-exports.isRegistered = isRegistered;
-
-/**
- * Registers given `component` object to be used to instantiate a particular
- * class identified by `component.id`, and creates an association of class
- * name and `component.contract` with the class.
- */
-function register(factory) {
- if (!(factory instanceof Factory)) {
- throw new Error("xpcom.register() expect a Factory instance.\n" +
- "Please refactor your code to new xpcom module if you" +
- " are repacking an addon from SDK <= 1.5:\n" +
- "https://addons.mozilla.org/en-US/developers/docs/sdk/latest/packages/api-utils/xpcom.html");
- }
-
- registerFactory(factory.id, factory.description, factory.contract, factory);
-
- if (factory.unregister)
- require('../system/unload').when(unregister.bind(null, factory));
-}
-exports.register = register;
-
-/**
- * Unregister a factory associated with a particular class identified by
- * `factory.classID`.
- */
-function unregister(factory) {
- if (isRegistered(factory))
- unregisterFactory(factory.id, factory);
-}
-exports.unregister = unregister;
-
-function autoRegister(path) {
- // TODO: This assumes that the url points to a directory
- // that contains subdirectories corresponding to OS/ABI and then
- // further subdirectories corresponding to Gecko platform version.
- // we should probably either behave intelligently here or allow
- // the caller to pass-in more options if e.g. there aren't
- // Gecko-specific binaries for a component (which will be the case
- // if only frozen interfaces are used).
-
- var runtime = require("../system/runtime");
- var osDirName = runtime.OS + "_" + runtime.XPCOMABI;
- var platformVersion = require("../system/xul-app").platformVersion.substring(0, 5);
-
- var file = Cc['@mozilla.org/file/local;1']
- .createInstance(Ci.nsILocalFile);
- file.initWithPath(path);
- file.append(osDirName);
- file.append(platformVersion);
-
- if (!(file.exists() && file.isDirectory()))
- throw new Error("component not available for OS/ABI " +
- osDirName + " and platform " + platformVersion);
-
- Cm.QueryInterface(Ci.nsIComponentRegistrar);
- Cm.autoRegister(file);
-}
-exports.autoRegister = autoRegister;
-
-/**
- * Returns registered factory that has a given `id` or `null` if not found.
- */
-function factoryByID(id) classesByID[id] || null
-exports.factoryByID = factoryByID;
-
-/**
- * Returns factory registered with a given `contract` or `null` if not found.
- * In contrast to `Cc[contract]` that does ignores new factory registration
- * with a given `contract` this will return a factory currently associated
- * with a `contract`.
- */
-function factoryByContract(contract) factoryByID(Cm.contractIDToCID(contract))
-exports.factoryByContract = factoryByContract;
diff --git a/tools/addon-sdk-1.12/lib/sdk/preferences/event-target.js b/tools/addon-sdk-1.12/lib/sdk/preferences/event-target.js
deleted file mode 100644
index fe9e07a..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/preferences/event-target.js
+++ /dev/null
@@ -1,60 +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 { Cc, Ci } = require('chrome');
-const { Class } = require('../core/heritage');
-const { EventTarget } = require('../event/target');
-const { Branch } = require('./service');
-const { emit, off } = require('../event/core');
-const { when: unload } = require('../system/unload');
-
-const prefTargetNS = require('../core/namespace').ns();
-
-const PrefsTarget = Class({
- extends: EventTarget,
- initialize: function(options) {
- options = options || {};
- EventTarget.prototype.initialize.call(this, options);
-
- let branchName = options.branchName || '';
- let branch = Cc["@mozilla.org/preferences-service;1"].
- getService(Ci.nsIPrefService).
- getBranch(branchName).
- QueryInterface(Ci.nsIPrefBranch2);
- prefTargetNS(this).branch = branch;
-
- // provides easy access to preference values
- this.prefs = Branch(branchName);
-
- // start listening to preference changes
- let observer = prefTargetNS(this).observer = onChange.bind(this);
- branch.addObserver('', observer, false);
-
- // Make sure to destroy this on unload
- unload(destroy.bind(this));
- }
-});
-exports.PrefsTarget = PrefsTarget;
-
-/* HELPERS */
-
-function onChange(subject, topic, name) {
- if (topic === 'nsPref:changed')
- emit(this, name, name);
- emit(this, '', name);
-}
-
-function destroy() {
- off(this);
-
- // stop listening to preference changes
- let branch = prefTargetNS(this).branch;
- branch.removeObserver('', prefTargetNS(this).observer, false);
- prefTargetNS(this).observer = null;
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/preferences/service.js b/tools/addon-sdk-1.12/lib/sdk/preferences/service.js
deleted file mode 100644
index 4303fc1..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/preferences/service.js
+++ /dev/null
@@ -1,174 +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"
-};
-
-// The minimum and maximum integers that can be set as preferences.
-// The range of valid values is narrower than the range of valid JS values
-// because the native preferences code treats integers as NSPR PRInt32s,
-// which are 32-bit signed integers on all platforms.
-const MAX_INT = 0x7FFFFFFF;
-const MIN_INT = -0x80000000;
-
-const {Cc,Ci,Cr} = require("chrome");
-
-const prefService = Cc["@mozilla.org/preferences-service;1"].
- getService(Ci.nsIPrefService);
-const prefSvc = prefService.getBranch(null);
-const defaultBranch = prefService.getDefaultBranch(null);
-
-function Branch(branchName) {
- function getPrefKeys() {
- return keys(branchName).map(function(key) {
- return key.replace(branchName, "");
- });
- }
-
- return Proxy.create({
- get: function(receiver, pref) {
- return get(branchName + pref);
- },
- set: function(receiver, pref, val) {
- set(branchName + pref, val);
- },
- delete: function(pref) {
- reset(branchName + pref);
- return true;
- },
- has: function hasPrefKey(pref) {
- return has(branchName + pref)
- },
- getPropertyDescriptor: function(name) {
- return {
- value: get(branchName + name)
- };
- },
- enumerate: getPrefKeys,
- keys: getPrefKeys
- }, Branch.prototype);
-}
-
-function get(name, defaultValue) {
- switch (prefSvc.getPrefType(name)) {
- case Ci.nsIPrefBranch.PREF_STRING:
- return prefSvc.getComplexValue(name, Ci.nsISupportsString).data;
-
- case Ci.nsIPrefBranch.PREF_INT:
- return prefSvc.getIntPref(name);
-
- case Ci.nsIPrefBranch.PREF_BOOL:
- return prefSvc.getBoolPref(name);
-
- case Ci.nsIPrefBranch.PREF_INVALID:
- return defaultValue;
-
- default:
- // This should never happen.
- throw new Error("Error getting pref " + name +
- "; its value's type is " +
- prefSvc.getPrefType(name) +
- ", which I don't know " +
- "how to handle.");
- }
-}
-exports.get = get;
-
-function set(name, value) {
- var prefType;
- if (typeof value != "undefined" && value != null)
- prefType = value.constructor.name;
-
- switch (prefType) {
- case "String":
- {
- var string = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- string.data = value;
- prefSvc.setComplexValue(name, Ci.nsISupportsString, string);
- }
- break;
-
- case "Number":
- // We throw if the number is outside the range or not an integer, since
- // the result will not be what the consumer wanted to store.
- if (value > MAX_INT || value < MIN_INT)
- throw new Error("you cannot set the " + name +
- " pref to the number " + value +
- ", as number pref values must be in the signed " +
- "32-bit integer range -(2^31) to 2^31-1. " +
- "To store numbers outside that range, store " +
- "them as strings.");
- if (value % 1 != 0)
- throw new Error("cannot store non-integer number: " + value);
- prefSvc.setIntPref(name, value);
- break;
-
- case "Boolean":
- prefSvc.setBoolPref(name, value);
- break;
-
- default:
- throw new Error("can't set pref " + name + " to value '" + value +
- "'; it isn't a string, integer, or boolean");
- }
-}
-exports.set = set;
-
-function has(name) {
- return (prefSvc.getPrefType(name) != Ci.nsIPrefBranch.PREF_INVALID);
-}
-exports.has = has;
-
-function keys(root) {
- return prefSvc.getChildList(root);
-}
-exports.keys = keys;
-
-function isSet(name) {
- return (has(name) && prefSvc.prefHasUserValue(name));
-}
-exports.isSet = isSet;
-
-function reset(name) {
- try {
- prefSvc.clearUserPref(name);
- } catch (e if e.result == Cr.NS_ERROR_UNEXPECTED) {
- // The pref service throws NS_ERROR_UNEXPECTED when the caller tries
- // to reset a pref that doesn't exist or is already set to its default
- // value. This interface fails silently in those cases, so callers
- // can unconditionally reset a pref without having to check if it needs
- // resetting first or trap exceptions after the fact. It passes through
- // other exceptions, however, so callers know about them, since we don't
- // know what other exceptions might be thrown and what they might mean.
- }
-}
-exports.reset = reset;
-
-function getLocalized(name, defaultValue) {
- let value = null;
- try {
- value = prefSvc.getComplexValue(name, Ci.nsIPrefLocalizedString).data;
- }
- finally {
- return value || defaultValue;
- }
-}
-exports.getLocalized = getLocalized;
-
-function setLocalized(name, value) {
- // We can't use `prefs.set` here as we have to use `getDefaultBranch`
- // (instead of `getBranch`) in order to have `mIsDefault` set to true, here:
- // http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/nsPrefBranch.cpp#233
- // Otherwise, we do not enter into this expected condition:
- // http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/nsPrefBranch.cpp#244
- defaultBranch.setCharPref(name, value);
-}
-exports.setLocalized = setLocalized;
-
-exports.Branch = Branch;
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/private-browsing.js b/tools/addon-sdk-1.12/lib/sdk/private-browsing.js
deleted file mode 100644
index 6d2a709..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/private-browsing.js
+++ /dev/null
@@ -1,36 +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": "stable"
-};
-
-const { setMode, getMode, on: onStateChange } = require('./private-browsing/utils');
-const { emit, on, once, off } = require('./event/core');
-const { when: unload } = require('./system/unload');
-const observers = require('./deprecated/observer-service');
-
-onStateChange('start', function onStart() {
- emit(exports, 'start');
-});
-
-onStateChange('stop', function onStop() {
- emit(exports, 'stop');
-});
-
-// Make sure listeners are cleaned up.
-unload(function() off(exports));
-
-Object.defineProperty(exports, "isActive", { get: function() getMode() });
-exports.activate = function activate() setMode(true);
-exports.deactivate = function deactivate() setMode(false);
-exports.on = on.bind(null, exports);
-exports.once = once.bind(null, exports);
-exports.removeListener = function removeListener(type, listener) {
- // Note: We can't just bind `off` as we do it for other methods cause skipping
- // a listener argument will remove all listeners for the given event type
- // causing misbehavior. This way we make sure all arguments are passed.
- off(exports, type, listener);
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/private-browsing/utils.js b/tools/addon-sdk-1.12/lib/sdk/private-browsing/utils.js
deleted file mode 100644
index 1f57ca0..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/private-browsing/utils.js
+++ /dev/null
@@ -1,74 +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 { Cc, Ci } = require('chrome');
-const { defer } = require('../lang/functional');
-const observers = require('../deprecated/observer-service');
-const { emit, on, once, off } = require('../event/core');
-const { when: unload } = require('../system/unload');
-const { getWindowLoadingContext } = require('../window/utils');
-const { deprecateFunction } = require('../util/deprecate');
-
-let deferredEmit = defer(emit);
-
-let pbService;
-
-// Currently, only Firefox implements the private browsing service.
-if (require("../system/xul-app").is("Firefox")) {
- pbService = Cc["@mozilla.org/privatebrowsing;1"].
- getService(Ci.nsIPrivateBrowsingService);
-
- // set up an observer for private browsing switches.
- observers.add('private-browsing-transition-complete', function onChange() {
- // Emit event with in next turn of event loop.
- deferredEmit(exports, pbService.privateBrowsingEnabled ? 'start' : 'stop');
- });
-}
-
-// checks that per-window private browsing implemented
-let isWindowPBEnabled = function isWindowPBEnabled(chromeWin) {
- return !!(chromeWin &&
- 'gPrivateBrowsingUI' in chromeWin &&
- 'privateWindow' in chromeWin.gPrivateBrowsingUI);
-}
-exports.isWindowPBEnabled = isWindowPBEnabled;
-
-// We toggle private browsing mode asynchronously in order to work around
-// bug 659629. Since private browsing transitions are asynchronous
-// anyway, this doesn't significantly change the behavior of the API.
-// Note: this method should not be used with `chromeWin` argument until
-// the UI has been implemented. Bug 729865
-let setMode = defer(function setMode(value, chromeWin) {
- value = !!value; // Cast to boolean.
-
- if (isWindowPBEnabled(chromeWin))
- return getWindowLoadingContext(chromeWin).usePrivateBrowsing = value;
-
- // default
- return pbService && (pbService.privateBrowsingEnabled = value);
-});
-exports.setMode = deprecateFunction(
- setMode,
- 'require("private-browsing").activate and require("private-browsing").deactivate ' +
- 'is deprecated.'
-);
-
-let getMode = function getMode(chromeWin) {
- if (isWindowPBEnabled(chromeWin))
- return getWindowLoadingContext(chromeWin).usePrivateBrowsing;
-
- // default
- return pbService ? pbService.privateBrowsingEnabled : false;
-};
-exports.getMode = getMode;
-
-exports.on = on.bind(null, exports);
-
-// Make sure listeners are cleaned up.
-unload(function() off(exports));
diff --git a/tools/addon-sdk-1.12/lib/sdk/querystring.js b/tools/addon-sdk-1.12/lib/sdk/querystring.js
deleted file mode 100644
index e0e2273..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/querystring.js
+++ /dev/null
@@ -1,121 +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"
-};
-
-let unescape = decodeURIComponent;
-exports.unescape = unescape;
-
-// encodes a string safely for application/x-www-form-urlencoded
-// adheres to RFC 3986
-// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent
-function escape(query) {
- return encodeURIComponent(query).
- replace(/%20/g, '+').
- replace(/!/g, '%21').
- replace(/'/g, '%27').
- replace(/\(/g, '%28').
- replace(/\)/g, '%29').
- replace(/\*/g, '%2A');
-}
-exports.escape = escape;
-
-// Converts an object of unordered key-vals to a string that can be passed
-// as part of a request
-function stringify(options, separator, assigner) {
- separator = separator || '&';
- assigner = assigner || '=';
- // Explicitly return null if we have null, and empty string, or empty object.
- if (!options)
- return '';
-
- // If content is already a string, just return it as is.
- if (typeof(options) == 'string')
- return options;
-
- // At this point we have a k:v object. Iterate over it and encode each value.
- // Arrays and nested objects will get encoded as needed. For example...
- //
- // { foo: [1, 2, { omg: 'bbq', 'all your base!': 'are belong to us' }], bar: 'baz' }
- //
- // will be encoded as
- //
- // foo[0]=1&foo[1]=2&foo[2][omg]=bbq&foo[2][all+your+base!]=are+belong+to+us&bar=baz
- //
- // Keys (including '[' and ']') and values will be encoded with
- // `escape` before returning.
- //
- // Execution was inspired by jQuery, but some details have changed and numeric
- // array keys are included (whereas they are not in jQuery).
-
- let encodedContent = [];
- function add(key, val) {
- encodedContent.push(escape(key) + assigner + escape(val));
- }
-
- function make(key, value) {
- if (value && typeof(value) === 'object')
- Object.keys(value).forEach(function(name) {
- make(key + '[' + name + ']', value[name]);
- });
- else
- add(key, value);
- }
-
- Object.keys(options).forEach(function(name) { make(name, options[name]); });
- return encodedContent.join(separator);
-
- //XXXzpao In theory, we can just use a FormData object on 1.9.3, but I had
- // trouble getting that working. It would also be nice to stay
- // backwards-compat as long as possible. Keeping this in for now...
- // let formData = Cc['@mozilla.org/files/formdata;1'].
- // createInstance(Ci.nsIDOMFormData);
- // for ([k, v] in Iterator(content)) {
- // formData.append(k, v);
- // }
- // return formData;
-}
-exports.stringify = stringify;
-
-// Exporting aliases that nodejs implements just for the sake of
-// interoperability.
-exports.encode = stringify;
-exports.serialize = stringify;
-
-// Note: That `stringify` and `parse` aren't bijective as we use `stringify`
-// as it was implement in request module, but implement `parse` to match nodejs
-// behavior.
-// TODO: Make `stringify` implement API as in nodejs and figure out backwards
-// compatibility.
-function parse(query, separator, assigner) {
- separator = separator || '&';
- assigner = assigner || '=';
- let result = {};
-
- if (typeof query !== 'string' || query.length === 0)
- return result;
-
- query.split(separator).forEach(function(chunk) {
- let pair = chunk.split(assigner);
- let key = unescape(pair[0]);
- let value = unescape(pair.slice(1).join(assigner));
-
- if (!(key in result))
- result[key] = value;
- else if (Array.isArray(result[key]))
- result[key].push(value);
- else
- result[key] = [result[key], value];
- });
-
- return result;
-};
-exports.parse = parse;
-// Exporting aliases that nodejs implements just for the sake of
-// interoperability.
-exports.decode = parse;
diff --git a/tools/addon-sdk-1.12/lib/sdk/request.js b/tools/addon-sdk-1.12/lib/sdk/request.js
deleted file mode 100644
index da5be7f..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/request.js
+++ /dev/null
@@ -1,213 +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": "stable"
-};
-
-const { ns } = require("./core/namespace");
-const { emit } = require("./event/core");
-const { merge } = require("./util/object");
-const { stringify } = require("./querystring");
-const { EventTarget } = require("./event/target");
-const { Class } = require("./core/heritage");
-const { XMLHttpRequest } = require("./net/xhr");
-const apiUtils = require("./deprecated/api-utils");
-
-const response = ns();
-const request = ns();
-
-// Instead of creating a new validator for each request, just make one and
-// reuse it.
-const { validateOptions, validateSingleOption } = new OptionsValidator({
- url: {
- //XXXzpao should probably verify that url is a valid url as well
- is: ["string"]
- },
- headers: {
- map: function (v) v || {},
- is: ["object"],
- },
- content: {
- map: function (v) v || null,
- is: ["string", "object", "null"],
- },
- contentType: {
- map: function (v) v || "application/x-www-form-urlencoded",
- is: ["string"],
- },
- overrideMimeType: {
- map: function(v) v || null,
- is: ["string", "null"],
- }
-});
-
-const REUSE_ERROR = "This request object has been used already. You must " +
- "create a new one to make a new request."
-
-// Utility function to prep the request since it's the same between GET and
-// POST
-function runRequest(mode, target) {
- let source = request(target)
- let { xhr, url, content, contentType, headers, overrideMimeType } = source;
-
- // If this request has already been used, then we can't reuse it.
- // Throw an error.
- if (xhr)
- throw new Error(REUSE_ERROR);
-
- xhr = source.xhr = new XMLHttpRequest();
-
- // Build the data to be set. For GET requests, we want to append that to
- // the URL before opening the request.
- let data = stringify(content);
- // If the URL already has ? in it, then we want to just use &
- if (mode == "GET" && data)
- url = url + (/\?/.test(url) ? "&" : "?") + data;
-
- // open the request
- xhr.open(mode, url);
-
- // request header must be set after open, but before send
- xhr.setRequestHeader("Content-Type", contentType);
-
- // set other headers
- Object.keys(headers).forEach(function(name) {
- xhr.setRequestHeader(name, headers[name]);
- });
-
- // set overrideMimeType
- if (overrideMimeType)
- xhr.overrideMimeType(overrideMimeType);
-
- // handle the readystate, create the response, and call the callback
- xhr.onreadystatechange = function onreadystatechange() {
- if (xhr.readyState === 4) {
- let response = Response(xhr);
- source.response = response;
- emit(target, 'complete', response);
- }
- };
-
- // actually send the request.
- // We don't want to send data on GET requests.
- xhr.send(mode !== "GET" ? data : null);
-}
-
-const Request = Class({
- extends: EventTarget,
- initialize: function initialize(options) {
- // `EventTarget.initialize` will set event listeners that are named
- // like `onEvent` in this case `onComplete` listener will be set to
- // `complete` event.
- EventTarget.prototype.initialize.call(this, options);
-
- // Copy normalized options.
- merge(request(this), validateOptions(options));
- },
- get url() { return request(this).url; },
- set url(value) { request(this).url = validateSingleOption('url', value); },
- get headers() { return request(this).headers; },
- set headers(value) {
- return request(this).headers = validateSingleOption('headers', value);
- },
- get content() { return request(this).content; },
- set content(value) {
- request(this).content = validateSingleOption('content', value);
- },
- get contentType() { return request(this).contentType; },
- set contentType(value) {
- request(this).contentType = validateSingleOption('contentType', value);
- },
- get response() { return request(this).response; },
- get: function() {
- runRequest('GET', this);
- return this;
- },
- post: function() {
- runRequest('POST', this);
- return this;
- },
- put: function() {
- runRequest('PUT', this);
- return this;
- }
-});
-exports.Request = Request;
-
-const Response = Class({
- initialize: function initialize(request) {
- response(this).request = request;
- },
- get text() response(this).request.responseText,
- get xml() {
- throw new Error("Sorry, the 'xml' property is no longer available. " +
- "see bug 611042 for more information.");
- },
- get status() response(this).request.status,
- get statusText() response(this).request.statusText,
- get json() {
- try {
- return JSON.parse(this.text);
- } catch(error) {
- return null;
- }
- },
- get headers() {
- let headers = {}, lastKey;
- // Since getAllResponseHeaders() will return null if there are no headers,
- // defend against it by defaulting to ""
- let rawHeaders = response(this).request.getAllResponseHeaders() || "";
- rawHeaders.split("\n").forEach(function (h) {
- // According to the HTTP spec, the header string is terminated by an empty
- // line, so we can just skip it.
- if (!h.length) {
- return;
- }
-
- let index = h.indexOf(":");
- // The spec allows for leading spaces, so instead of assuming a single
- // leading space, just trim the values.
- let key = h.substring(0, index).trim(),
- val = h.substring(index + 1).trim();
-
- // For empty keys, that means that the header value spanned multiple lines.
- // In that case we should append the value to the value of lastKey with a
- // new line. We'll assume lastKey will be set because there should never
- // be an empty key on the first pass.
- if (key) {
- headers[key] = val;
- lastKey = key;
- }
- else {
- headers[lastKey] += "\n" + val;
- }
- });
- return headers;
- }
-});
-
-// apiUtils.validateOptions doesn't give the ability to easily validate single
-// options, so this is a wrapper that provides that ability.
-function OptionsValidator(rules) {
- return {
- validateOptions: function (options) {
- return apiUtils.validateOptions(options, rules);
- },
- validateSingleOption: function (field, value) {
- // We need to create a single rule object from our listed rules. To avoid
- // JavaScript String warnings, check for the field & default to an empty object.
- let singleRule = {};
- if (field in rules) {
- singleRule[field] = rules[field];
- }
- let singleOption = {};
- singleOption[field] = value;
- // This should throw if it's invalid, which will bubble up & out.
- return apiUtils.validateOptions(singleOption, singleRule)[field];
- }
- };
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/selection.js b/tools/addon-sdk-1.12/lib/sdk/selection.js
deleted file mode 100644
index da94efe..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/selection.js
+++ /dev/null
@@ -1,481 +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": "stable"
-};
-
-if (!require("./system/xul-app").is("Firefox")) {
- throw new Error([
- "The selection module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=560716 for more information."
- ].join(""));
-}
-
-let { Ci, Cc } = require("chrome"),
- { setTimeout } = require("./timers"),
- { emit, off } = require("./event/core"),
- { Unknown } = require("./platform/xpcom"),
- { Class, obscure } = require("./core/heritage"),
- { EventTarget } = require("./event/target"),
- observers = require("./deprecated/observer-service"),
- { ns } = require("./core/namespace");
-
-// When a document is not visible anymore the selection object is detached, and
-// a new selection object is created when it becomes visible again.
-// That makes the previous selection's listeners added previously totally
-// useless – the listeners are not notified anymore.
-// To fix that we're listening for `document-shown` event in order to add
-// the listeners to the new selection object created.
-//
-// See bug 665386 for further details.
-
-let selections = ns();
-
-observers.add("document-shown", function (document) {
- var window = document.defaultView;
-
- // We are not interested in documents without valid defaultView
- if (!window)
- return;
-
- let selection = selections(window).selection;
-
- // We want to handle only the windows where we added selection's listeners
- if (selection) {
- let currentSelection = window.getSelection();
-
- // If the current selection for the window given is different from the one
- // stored in the namespace, we need to add the listeners again, and replace
- // the previous selection in our list with the new one.
- //
- // Notice that we don't have to remove the listeners from the old selection,
- // because is detached. An attempt to remove the listener, will raise an
- // error (see http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsSelection.cpp#5343 )
- //
- // We ensure that the current selection is an instance of
- // `nsISelectionPrivate` before working on it, in case is `null`.
- if (currentSelection instanceof Ci.nsISelectionPrivate &&
- currentSelection !== selection) {
-
- currentSelection.addSelectionListener(SelectionListenerManager);
- selections(window).selection = currentSelection;
- }
- }
-});
-
-const windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator);
-
-// The selection type HTML
-const HTML = 0x01;
-
-// The selection type TEXT
-const TEXT = 0x02;
-
-// The selection type DOM (internal use only)
-const DOM = 0x03;
-
-// A more developer-friendly message than the caught exception when is not
-// possible change a selection.
-const ERR_CANNOT_CHANGE_SELECTION =
- "It isn't possible to change the selection, as there isn't currently a selection";
-
-const Selection = Class({
- /**
- * Creates an object from which a selection can be set, get, etc. Each
- * object has an associated with a range number. Range numbers are the
- * 0-indexed counter of selection ranges as explained at
- * https://developer.mozilla.org/en/DOM/Selection.
- *
- * @param rangeNumber
- * The zero-based range index into the selection
- */
- initialize: function initialize(rangeNumber) {
- // In order to hide the private `rangeNumber` argument from API consumers
- // while still enabling Selection getters/setters to access it, we define
- // it as non enumerable, non configurable property. While consumers still
- // may discover it they won't be able to do any harm which is good enough
- // in this case.
- Object.defineProperties(this, {
- rangeNumber: {
- enumerable: false,
- configurable: false,
- value: rangeNumber
- }
- });
- },
- get text() { return getSelection(TEXT, this.rangeNumber); },
- set text(value) { setSelection(value, this.rangeNumber); },
- get html() { return getSelection(HTML, this.rangeNumber); },
- set html(value) { setSelection(value, this.rangeNumber); },
- get isContiguous() {
- let selection = getSelection(DOM);
-
- // If there are multiple ranges, the selection is definitely discontiguous.
- // It returns `false` also if there are no selection; and `true` if there is
- // a single non empty range, or a selection in a text field - contiguous or
- // not (text field selection APIs doesn't support multiple selections).
-
- if (selection.rangeCount > 1)
- return false;
-
- return !!(safeGetRange(selection, 0) || getElementWithSelection());
- }
-});
-
-/**
- * Returns the most recent content window
- */
-function context() {
- // Overlay names should probably go into the xul-app module instead of here
- return windowMediator.getMostRecentWindow("navigator:browser").document.
- commandDispatcher.focusedWindow;
-}
-
-/**
- * Returns the current selection from most recent content window. Depending on
- * the specified |type|, the value returned can be a string of text, stringified
- * HTML, or a DOM selection object as described at
- * https://developer.mozilla.org/en/DOM/Selection.
- *
- * @param type
- * Specifies the return type of the selection. Valid values are the one
- * of the constants HTML, TEXT, or DOM.
- *
- * @param rangeNumber
- * Specifies the zero-based range index of the returned selection.
- */
-function getSelection(type, rangeNumber) {
- let window, selection;
- try {
- window = context();
- selection = window.getSelection();
- }
- catch (e) {
- return null;
- }
-
- // Get the selected content as the specified type
- if (type == DOM)
- return selection;
- else if (type == TEXT) {
- let range = safeGetRange(selection, rangeNumber);
-
- if (range)
- return range.toString();
-
- let node = getElementWithSelection(window);
-
- if (!node)
- return null;
-
- return node.value.substring(node.selectionStart, node.selectionEnd);
- }
- else if (type == HTML) {
- let range = safeGetRange(selection, rangeNumber);
- // Another way, but this includes the xmlns attribute for all elements in
- // Gecko 1.9.2+ :
- // return Cc["@mozilla.org/xmlextras/xmlserializer;1"].
- // createInstance(Ci.nsIDOMSerializer).serializeToSTring(range.
- // cloneContents());
- if (!range)
- return null;
- let node = window.document.createElement("span");
- node.appendChild(range.cloneContents());
- return node.innerHTML;
- }
- throw new Error("Type " + type + " is unrecognized.");
-}
-
-/**
- * Returns the specified range in a selection without throwing an exception.
- *
- * @param selection
- * A selection object as described at
- * https://developer.mozilla.org/en/DOM/Selection
- *
- * @param rangeNumber
- * Specifies the zero-based range index of the returned selection.
- */
-function safeGetRange(selection, rangeNumber) {
- try {
- let range = selection.getRangeAt(rangeNumber);
- if (!range || range.toString() == "")
- return null;
- return range;
- }
- catch (e) {
- return null;
- }
-}
-
-/**
- * Returns a reference of the DOM's active element for the window given, if it
- * supports the text field selection API and has a text selected.
- *
- * Note:
- * we need this method because window.getSelection doesn't return a selection
- * for text selected in a form field (see bug 85686)
- *
- * @param {nsIWindow} [window]
- * A reference to a window
- */
-function getElementWithSelection(window) {
- let element;
-
- try {
- element = (window || context()).document.activeElement;
- }
- catch (e) {
- element = null;
- }
-
- if (!element)
- return null;
-
- let { value, selectionStart, selectionEnd } = element;
-
- let hasSelection = typeof value === "string" &&
- !isNaN(selectionStart) &&
- !isNaN(selectionEnd) &&
- selectionStart !== selectionEnd;
-
- return hasSelection ? element : null;
-}
-/**
- * Sets the current selection of the most recent content document by changing
- * the existing selected text/HTML range to the specified value.
- *
- * @param val
- * The value for the new selection
- *
- * @param rangeNumber
- * The zero-based range index of the selection to be set
- *
- */
-function setSelection(val, rangeNumber) {
- // Make sure we have a window context & that there is a current selection.
- // Selection cannot be set unless there is an existing selection.
- let window, selection;
-
- try {
- window = context();
- selection = window.getSelection();
- }
- catch (e) {
- throw new Error(ERR_CANNOT_CHANGE_SELECTION);
- }
-
- let range = safeGetRange(selection, rangeNumber);
-
- if (range) {
- // Get rid of the current selection and insert our own
- range.deleteContents();
- let node = window.document.createElement("span");
- range.surroundContents(node);
-
- // Some relevant JEP-111 requirements:
-
- // Setting the text property replaces the selection with the value to
- // which the property is set and sets the html property to the same value
- // to which the text property is being set.
-
- // Setting the html property replaces the selection with the value to
- // which the property is set and sets the text property to the text version
- // of the HTML value.
-
- // This sets both the HTML and text properties.
- node.innerHTML = val;
- } else {
- let node = getElementWithSelection(window);
-
- if (!node)
- throw new Error(ERR_CANNOT_CHANGE_SELECTION);
-
- let { value, selectionStart, selectionEnd } = node;
-
- let newSelectionEnd = selectionStart + val.length;
-
- node.value = value.substring(0, selectionStart) +
- val +
- value.substring(selectionEnd, value.length);
-
- node.setSelectionRange(selectionStart, newSelectionEnd);
- }
-}
-
-function onLoad(event) {
- SelectionListenerManager.onLoad(event);
-}
-
-function onUnload(event) {
- SelectionListenerManager.onUnload(event);
-}
-
-function onSelect() {
- SelectionListenerManager.onSelect();
-}
-
-let SelectionListenerManager = Class({
- extends: Unknown,
- interfaces: [ 'nsISelectionListener' ],
- /**
- * This is the nsISelectionListener implementation. This function is called
- * by Gecko when a selection is changed interactively.
- *
- * We only pay attention to the SELECTALL, KEYPRESS, and MOUSEUP selection
- * reasons. All reasons are listed here:
- *
- * http://mxr.mozilla.org/mozilla1.9.2/source/content/base/public/
- * nsISelectionListener.idl
- *
- * The other reasons (NO_REASON, DRAG_REASON, MOUSEDOWN_REASON) aren't
- * applicable to us.
- */
- notifySelectionChanged: function notifySelectionChanged(document, selection,
- reason) {
- if (!["SELECTALL", "KEYPRESS", "MOUSEUP"].some(function(type) reason &
- Ci.nsISelectionListener[type + "_REASON"]) || selection.toString() == "")
- return;
-
- this.onSelect();
- },
-
- onSelect : function onSelect() {
- setTimeout(emit, 0, module.exports, "select");
- },
-
- /**
- * Part of the Tracker implementation. This function is called by the
- * tabs module when a browser is being tracked. Often, that means a new tab
- * has been opened, but it can also mean an addon has been installed while
- * tabs are already opened. In that case, this function is called for those
- * already-opened tabs.
- *
- * @param browser
- * The browser being tracked
- */
- onTrack: function onTrack(browser) {
- browser.addEventListener("load", onLoad, true);
- browser.addEventListener("unload", onUnload, true);
- },
-
- onLoad: function onLoad(event) {
- // Nothing to do without a useful window
- let window = event.target.defaultView;
- if (!window)
- return;
-
- // Wrap the add selection call with some number of setTimeout 0 because some
- // reason it's possible to add a selection listener "too early". 2 sometimes
- // works for gmail, and more consistently with 3, so make it 5 to be safe.
- let count = 0;
- let self = this;
- function wrap(count, func) {
- if (count-- > 0)
- setTimeout(wrap, 0);
- else
- self.addSelectionListener(window);
- }
- wrap();
- },
-
- addSelectionListener: function addSelectionListener(window) {
- // Don't add the selection's listener more than once to the same window.
- if ("selection" in selections(window))
- return;
-
- let selection = window.getSelection();
-
- // We ensure that the current selection is an instance of
- // `nsISelectionPrivate` before working on it, in case is `null`.
- if (selection instanceof Ci.nsISelectionPrivate) {
- selection.addSelectionListener(this);
-
- // nsISelectionListener implementation seems not fire a notification if
- // a selection is in a text field, therefore we need to add a listener to
- // window.onselect, that is fired only for text fields.
- // For consistency, we add it only when the nsISelectionListener is added.
- //
- // https://developer.mozilla.org/en/DOM/window.onselect
- window.addEventListener("select", onSelect, true);
-
- selections(window).selection = selection;
- }
- },
-
- onUnload: function onUnload(event) {
- // Nothing to do without a useful window
- let window = event.target.defaultView;
- if (!window)
- return;
- this.removeSelectionListener(window);
- off(exports);
- },
-
- removeSelectionListener: function removeSelectionListener(window) {
- // Don't remove the selection's listener to a window that wasn't handled.
- if (!("selection" in selections(window)))
- return;
-
- let selection = window.getSelection();
-
- // We ensure that the current selection is an instance of
- // `nsISelectionPrivate` before working on it, in case is `null`.
- if (selection instanceof Ci.nsISelectionPrivate) {
- selection.removeSelectionListener(this);
-
- window.removeEventListener("select", onSelect);
-
- delete selections(window).selection;
- }
- },
-
- /**
- * Part of the TabTracker implementation. This function is called by the
- * tabs module when a browser is being untracked. Usually, that means a tab
- * has been closed.
- *
- * @param browser
- * The browser being untracked
- */
- onUntrack: function onUntrack(browser) {
- browser.removeEventListener("load", onLoad, true);
- browser.removeEventListener("unload", onUnload, true);
- }
-})();
-
-/**
- * Install |SelectionListenerManager| as tab tracker in order to watch
- * tab opening/closing
- */
-require("./deprecated/tab-browser").Tracker(SelectionListenerManager);
-
-var SelectionIterator = Class(obscure({
- /**
- * Exports an iterator so that discontiguous selections can be iterated.
- *
- * If discontiguous selections are in a text field, only the first one
- * is returned because the text field selection APIs doesn't support
- * multiple selections.
- */
- __iterator__: function() {
- let selection = getSelection(DOM);
- let count = selection.rangeCount || (getElementWithSelection() ? 1 : 0);
-
- for (let i = 0; i < count; i++)
- yield Selection(i);
- }
-}));
-
-var selection = Class({
- extends: EventTarget,
- implements: [ Selection, SelectionIterator ]
-})(0);
-
-module.exports = selection;
diff --git a/tools/addon-sdk-1.12/lib/sdk/self.js b/tools/addon-sdk-1.12/lib/sdk/self.js
deleted file mode 100644
index f9fca1e..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/self.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* vim:st=2:sts=2:sw=2:
- * 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 } = require('chrome');
-const { id, name, prefixURI, rootURI,
- version, loadReason } = require('@loader/options');
-
-const { readURISync } = require('./net/url');
-
-const addonDataURI = prefixURI + name + '/data/';
-
-function uri(path) {
- return addonDataURI + (path || '');
-}
-
-
-// Some XPCOM APIs require valid URIs as an argument for certain operations
-// (see `nsILoginManager` for example). This property represents add-on
-// associated unique URI string that can be used for that.
-exports.uri = 'addon:' + id;
-exports.id = id;
-exports.name = name;
-exports.loadReason = loadReason;
-exports.version = version;
-// If `rootURI` is jar:file://...!/ than add-on is packed.
-exports.packed = rootURI.indexOf('jar:') === 0
-exports.data = Object.freeze({
- url: uri,
- load: function read(path) {
- return readURISync(uri(path));
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/simple-prefs.js b/tools/addon-sdk-1.12/lib/sdk/simple-prefs.js
deleted file mode 100644
index 5cbde49..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/simple-prefs.js
+++ /dev/null
@@ -1,32 +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": "experimental"
-};
-
-const { emit, off } = require("./event/core");
-const { when: unload } = require("./system/unload");
-const { PrefsTarget } = require("./preferences/event-target");
-const { id } = require("./self");
-const observers = require("./deprecated/observer-service");
-
-const ADDON_BRANCH = "extensions." + id + ".";
-const BUTTON_PRESSED = id + "-cmdPressed";
-
-const target = PrefsTarget({ branchName: ADDON_BRANCH });
-
-// Listen to clicks on buttons
-function buttonClick(subject, data) {
- emit(target, data);
-}
-observers.add(BUTTON_PRESSED, buttonClick);
-
-// Make sure we cleanup listeners on unload.
-unload(function() {
- observers.remove(BUTTON_PRESSED, buttonClick);
-});
-
-module.exports = target;
diff --git a/tools/addon-sdk-1.12/lib/sdk/simple-storage.js b/tools/addon-sdk-1.12/lib/sdk/simple-storage.js
deleted file mode 100644
index 2b88cc1..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/simple-storage.js
+++ /dev/null
@@ -1,237 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et filetype=javascript
- * 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": "stable"
-};
-
-const { Cc, Ci } = require("chrome");
-const file = require("./io/file");
-const prefs = require("./preferences/service");
-const jpSelf = require("./self");
-const timer = require("./timers");
-const unload = require("./system/unload");
-const { emit, on, off } = require("./event/core");
-
-const WRITE_PERIOD_PREF = "extensions.addon-sdk.simple-storage.writePeriod";
-const WRITE_PERIOD_DEFAULT = 300000; // 5 minutes
-
-const QUOTA_PREF = "extensions.addon-sdk.simple-storage.quota";
-const QUOTA_DEFAULT = 5242880; // 5 MiB
-
-const JETPACK_DIR_BASENAME = "jetpack";
-
-Object.defineProperties(exports, {
- storage: {
- enumerable: true,
- get: function() { return manager.root; },
- set: function(value) { manager.root = value; }
- },
- quotaUsage: {
- get: function() { return manager.quotaUsage; }
- }
-});
-
-// A generic JSON store backed by a file on disk. This should be isolated
-// enough to move to its own module if need be...
-function JsonStore(options) {
- this.filename = options.filename;
- this.quota = options.quota;
- this.writePeriod = options.writePeriod;
- this.onOverQuota = options.onOverQuota;
- this.onWrite = options.onWrite;
-
- unload.ensure(this);
-
- this.writeTimer = timer.setInterval(this.write.bind(this),
- this.writePeriod);
-}
-
-JsonStore.prototype = {
- // The store's root.
- get root() {
- return this.isRootInited ? this._root : {};
- },
-
- // Performs some type checking.
- set root(val) {
- let types = ["array", "boolean", "null", "number", "object", "string"];
- if (types.indexOf(typeof(val)) < 0) {
- throw new Error("storage must be one of the following types: " +
- types.join(", "));
- }
- this._root = val;
- return val;
- },
-
- // True if the root has ever been set (either via the root setter or by the
- // backing file's having been read).
- get isRootInited() {
- return this._root !== undefined;
- },
-
- // Percentage of quota used, as a number [0, Inf). > 1 implies over quota.
- // Undefined if there is no quota.
- get quotaUsage() {
- return this.quota > 0 ?
- JSON.stringify(this.root).length / this.quota :
- undefined;
- },
-
- // Removes the backing file and all empty subdirectories.
- purge: function JsonStore_purge() {
- try {
- // This'll throw if the file doesn't exist.
- file.remove(this.filename);
- let parentPath = this.filename;
- do {
- parentPath = file.dirname(parentPath);
- // This'll throw if the dir isn't empty.
- file.rmdir(parentPath);
- } while (file.basename(parentPath) !== JETPACK_DIR_BASENAME);
- }
- catch (err) {}
- },
-
- // Initializes the root by reading the backing file.
- read: function JsonStore_read() {
- try {
- let str = file.read(this.filename);
-
- // Ideally we'd log the parse error with console.error(), but logged
- // errors cause tests to fail. Supporting "known" errors in the test
- // harness appears to be non-trivial. Maybe later.
- this.root = JSON.parse(str);
- }
- catch (err) {
- this.root = {};
- }
- },
-
- // If the store is under quota, writes the root to the backing file.
- // Otherwise quota observers are notified and nothing is written.
- write: function JsonStore_write() {
- if (this.quotaUsage > 1)
- this.onOverQuota(this);
- else
- this._write();
- },
-
- // Cleans up on unload. If unloading because of uninstall, the store is
- // purged; otherwise it's written.
- unload: function JsonStore_unload(reason) {
- timer.clearInterval(this.writeTimer);
- this.writeTimer = null;
-
- if (reason === "uninstall")
- this.purge();
- else
- this._write();
- },
-
- // True if the root is an empty object.
- get _isEmpty() {
- if (this.root && typeof(this.root) === "object") {
- let empty = true;
- for (let key in this.root) {
- empty = false;
- break;
- }
- return empty;
- }
- return false;
- },
-
- // Writes the root to the backing file, notifying write observers when
- // complete. If the store is over quota or if it's empty and the store has
- // never been written, nothing is written and write observers aren't notified.
- _write: function JsonStore__write() {
- // Don't write if the root is uninitialized or if the store is empty and the
- // backing file doesn't yet exist.
- if (!this.isRootInited || (this._isEmpty && !file.exists(this.filename)))
- return;
-
- // If the store is over quota, don't write. The current under-quota state
- // should persist.
- if (this.quotaUsage > 1)
- return;
-
- // Finally, write.
- let stream = file.open(this.filename, "w");
- try {
- stream.writeAsync(JSON.stringify(this.root), function writeAsync(err) {
- if (err)
- console.error("Error writing simple storage file: " + this.filename);
- else if (this.onWrite)
- this.onWrite(this);
- }.bind(this));
- }
- catch (err) {
- // writeAsync closes the stream after it's done, so only close on error.
- stream.close();
- }
- }
-};
-
-
-// This manages a JsonStore singleton and tailors its use to simple storage.
-// The root of the JsonStore is lazy-loaded: The backing file is only read the
-// first time the root's gotten.
-let manager = ({
- jsonStore: null,
-
- // The filename of the store, based on the profile dir and extension ID.
- get filename() {
- let storeFile = Cc["@mozilla.org/file/directory_service;1"].
- getService(Ci.nsIProperties).
- get("ProfD", Ci.nsIFile);
- storeFile.append(JETPACK_DIR_BASENAME);
- storeFile.append(jpSelf.id);
- storeFile.append("simple-storage");
- file.mkpath(storeFile.path);
- storeFile.append("store.json");
- return storeFile.path;
- },
-
- get quotaUsage() {
- return this.jsonStore.quotaUsage;
- },
-
- get root() {
- if (!this.jsonStore.isRootInited)
- this.jsonStore.read();
- return this.jsonStore.root;
- },
-
- set root(val) {
- return this.jsonStore.root = val;
- },
-
- unload: function manager_unload() {
- off(this);
- },
-
- new: function manager_constructor() {
- let manager = Object.create(this);
- unload.ensure(manager);
-
- manager.jsonStore = new JsonStore({
- filename: manager.filename,
- writePeriod: prefs.get(WRITE_PERIOD_PREF, WRITE_PERIOD_DEFAULT),
- quota: prefs.get(QUOTA_PREF, QUOTA_DEFAULT),
- onOverQuota: emit.bind(null, exports, "OverQuota")
- });
-
- return manager;
- }
-}).new();
-
-exports.on = on.bind(null, exports);
-exports.removeListener = function(type, listener) {
- off(exports, type, listener);
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/system.js b/tools/addon-sdk-1.12/lib/sdk/system.js
deleted file mode 100644
index 1e374d3..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/system.js
+++ /dev/null
@@ -1,155 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 expandtab */
-/* 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 { Cc, Ci, CC } = require('chrome');
-const options = require('@loader/options');
-const file = require('./io/file');
-const runtime = require("./system/runtime");
-
-const appStartup = Cc['@mozilla.org/toolkit/app-startup;1'].
- getService(Ci.nsIAppStartup);
-const appInfo = Cc["@mozilla.org/xre/app-info;1"].
- getService(Ci.nsIXULAppInfo);
-const directoryService = Cc['@mozilla.org/file/directory_service;1'].
- getService(Ci.nsIProperties);
-
-const PR_WRONLY = parseInt("0x02");
-const PR_CREATE_FILE = parseInt("0x08");
-const PR_APPEND = parseInt("0x10");
-const PR_TRUNCATE = parseInt("0x20");
-
-function openFile(path, mode) {
- let file = Cc["@mozilla.org/file/local;1"].
- createInstance(Ci.nsILocalFile);
- file.initWithPath(path);
- let stream = Cc["@mozilla.org/network/file-output-stream;1"].
- createInstance(Ci.nsIFileOutputStream);
- stream.init(file, mode, -1, 0);
- return stream
-}
-
-const { eAttemptQuit: E_ATTEMPT, eForceQuit: E_FORCE } = appStartup;
-
-/**
- * Parsed JSON object that was passed via `cfx --static-args "{ foo: 'bar' }"`
- */
-exports.staticArgs = options.staticArgs;
-
-/**
- * Environment variables. Environment variables are non-enumerable properties
- * of this object (key is name and value is value).
- */
-exports.env = require('./system/environment').env;
-
-/**
- * Ends the process with the specified `code`. If omitted, exit uses the
- * 'success' code 0. To exit with failure use `1`.
- * TODO: Improve platform to actually quit with an exit code.
- */
-exports.exit = function exit(code) {
- // This is used by 'cfx' to find out exit code.
- if ('resultFile' in options && options.resultFile) {
- let mode = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
- let stream = openFile(options.resultFile, mode);
- let status = code ? 'FAIL' : 'OK';
- stream.write(status, status.length);
- stream.flush();
- stream.close();
- }
-
- appStartup.quit(code ? E_ATTEMPT : E_FORCE);
-};
-
-exports.stdout = new function() {
- let write = dump
- if ('logFile' in options && options.logFile) {
- let mode = PR_WRONLY | PR_CREATE_FILE | PR_APPEND;
- let stream = openFile(options.logFile, mode);
- write = function write(data) {
- let text = String(data);
- stream.write(text, text.length);
- stream.flush();
- }
- }
- return Object.freeze({ write: write });
-};
-
-/**
- * Returns a path of the system's or application's special directory / file
- * associated with a given `id`. For list of possible `id`s please see:
- * https://developer.mozilla.org/en/Code_snippets/File_I%2F%2FO#Getting_special_files
- * http://mxr.mozilla.org/mozilla-central/source/xpcom/io/nsAppDirectoryServiceDefs.h
- * @example
- *
- * // get firefox profile path
- * let profilePath = require('system').pathFor('ProfD');
- * // get OS temp files directory (/tmp)
- * let temps = require('system').pathFor('TmpD');
- * // get OS desktop path for an active user (~/Desktop on linux
- * // or C:\Documents and Settings\username\Desktop on windows).
- * let desktopPath = require('system').pathFor('Desk');
- */
-exports.pathFor = function pathFor(id) {
- return directoryService.get(id, Ci.nsIFile).path;
-};
-
-/**
- * What platform you're running on (all lower case string).
- * For possible values see:
- * https://developer.mozilla.org/en/OS_TARGET
- */
-exports.platform = runtime.OS.toLowerCase();
-
-/**
- * What processor architecture you're running on:
- * `'arm', 'ia32', or 'x64'`.
- */
-exports.architecture = runtime.XPCOMABI.split('_')[0];
-
-/**
- * What compiler used for build:
- * `'msvc', 'n32', 'gcc2', 'gcc3', 'sunc', 'ibmc'...`
- */
-exports.compiler = runtime.XPCOMABI.split('_')[1];
-
-/**
- * The application's build ID/date, for example "2004051604".
- */
-exports.build = appInfo.appBuildID;
-
-/**
- * The XUL application's UUID.
- * This has traditionally been in the form
- * `{AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE}` but for some applications it may
- * be: "appname@vendor.tld".
- */
-exports.id = appInfo.ID;
-
-/**
- * The name of the application.
- */
-exports.name = appInfo.name;
-
-/**
- * The XUL application's version, for example "0.8.0+" or "3.7a1pre".
- */
-exports.version = appInfo.version;
-
-/**
- * XULRunner version.
- */
-exports.platformVersion = appInfo.platformVersion;
-
-
-/**
- * The name of the application vendor, for example "Mozilla".
- */
-exports.vendor = appInfo.vendor;
diff --git a/tools/addon-sdk-1.12/lib/sdk/system/environment.js b/tools/addon-sdk-1.12/lib/sdk/system/environment.js
deleted file mode 100644
index 045bab1..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/system/environment.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 expandtab */
-/* 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": "stable"
-};
-
-const { Cc, Ci } = require('chrome');
-const { get, set, exists } = Cc['@mozilla.org/process/environment;1'].
- getService(Ci.nsIEnvironment);
-
-exports.env = Proxy.create({
- // XPCOM does not provides a way to enumerate environment variables, so we
- // just don't support enumeration.
- getPropertyNames: function() [],
- getOwnPropertyNames: function() [],
- enumerate: function() [],
- keys: function() [],
- // We do not support freezing, cause it would make it impossible to set new
- // environment variables.
- fix: function() undefined,
- // We present all environment variables as own properties of this object,
- // so we just delegate this call to `getOwnPropertyDescriptor`.
- getPropertyDescriptor: function(name) this.getOwnPropertyDescriptor(name),
- // If environment variable with this name is defined, we generate proprety
- // descriptor for it, otherwise fall back to `undefined` so that for consumer
- // this property does not exists.
- getOwnPropertyDescriptor: function(name) {
- return !exists(name) ? undefined : {
- value: get(name),
- enumerable: false, // Non-enumerable as we don't support enumeration.
- configurable: true, // Configurable as it may be deleted.
- writable: true // Writable as we do support set.
- }
- },
-
- // New environment variables can be defined just by defining properties
- // on this object.
- defineProperty: function(name, { value }) set(name, value),
- delete: function(name) set(name, null),
-
- // We present all properties as own, there for we just delegate to `hasOwn`.
- has: function(name) this.hasOwn(name),
- // We do support checks for existence of an environment variable, via `in`
- // operator on this object.
- hasOwn: function(name) exists(name),
-
- // On property get / set we do read / write appropriate environment variables,
- // please note though, that variables with names of standard object properties
- // intentionally (so that this behaves as normal object) can not be
- // read / set.
- get: function(proxy, name) Object.prototype[name] || get(name) || undefined,
- set: function(proxy, name, value) Object.prototype[name] || set(name, value)
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/system/events.js b/tools/addon-sdk-1.12/lib/sdk/system/events.js
deleted file mode 100644
index a75dddc..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/system/events.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 { Cc, Ci } = require('chrome');
-const { Unknown } = require('../platform/xpcom');
-const { Class } = require('../core/heritage');
-const { ns } = require('../core/namespace');
-const { addObserver, removeObserver, notifyObservers } =
- Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
-
-const Subject = Class({
- extends: Unknown,
- initialize: function initialize(object) {
- // Double-wrap the object and set a property identifying the
- // wrappedJSObject as one of our wrappers to distinguish between
- // subjects that are one of our wrappers (which we should unwrap
- // when notifying our observers) and those that are real JS XPCOM
- // components (which we should pass through unaltered).
- this.wrappedJSObject = {
- observersModuleSubjectWrapper: true,
- object: object
- };
- },
- getHelperForLanguage: function() {},
- getInterfaces: function() {}
-});
-
-function emit(type, event) {
- let subject = 'subject' in event ? Subject(event.subject) : null;
- let data = 'data' in event ? event.data : null;
- notifyObservers(subject, type, data);
-}
-exports.emit = emit;
-
-const Observer = Class({
- extends: Unknown,
- initialize: function initialize(listener) {
- this.listener = listener;
- },
- interfaces: [ 'nsIObserver', 'nsISupportsWeakReference' ],
- observe: function(subject, topic, data) {
- // Extract the wrapped object for subjects that are one of our
- // wrappers around a JS object. This way we support both wrapped
- // subjects created using this module and those that are real
- // XPCOM components.
- if (subject && typeof(subject) == 'object' &&
- ('wrappedJSObject' in subject) &&
- ('observersModuleSubjectWrapper' in subject.wrappedJSObject))
- subject = subject.wrappedJSObject.object;
-
- try {
- this.listener({
- type: topic,
- subject: subject,
- data: data
- });
- }
- catch (error) {
- console.exception(error);
- }
- }
-});
-
-const subscribers = ns();
-
-function on(type, listener, strong) {
- // Unless last optional argument is `true` we use a weak reference to a
- // listener.
- let weak = !strong;
- // Take list of observers associated with given `listener` function.
- let observers = subscribers(listener);
- // If `observer` for the given `type` is not registered yet, then
- // associate an `observer` and register it.
- if (!(type in observers)) {
- let observer = Observer(listener);
- observers[type] = observer;
- addObserver(observer, type, weak);
- }
-}
-exports.on = on;
-
-function once(type, listener) {
- // Note: this code assumes order in which listeners are called, which is fine
- // as long as dispatch happens in same order as listener registration which
- // is the case now. That being said we should be aware that this may break
- // in a future if order will change.
- on(type, listener);
- on(type, function cleanup() {
- off(type, listener);
- off(type, cleanup);
- }, true);
-}
-exports.once = once;
-
-function off(type, listener) {
- // Take list of observers as with the given `listener`.
- let observers = subscribers(listener);
- // If `observer` for the given `type` is registered, then
- // remove it & unregister.
- if (type in observers) {
- let observer = observers[type];
- delete observers[type];
- removeObserver(observer, type);
- }
-}
-exports.off = off;
diff --git a/tools/addon-sdk-1.12/lib/sdk/system/globals.js b/tools/addon-sdk-1.12/lib/sdk/system/globals.js
deleted file mode 100644
index df77295..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/system/globals.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 expandtab */
-/* 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"
-};
-
-let { Cc, Ci, CC } = require('chrome');
-let { PlainTextConsole } = require('../console/plain-text');
-let { stdout } = require('../system');
-let ScriptError = CC('@mozilla.org/scripterror;1', 'nsIScriptError');
-let consoleService = Cc['@mozilla.org/consoleservice;1'].getService().
- QueryInterface(Ci.nsIConsoleService);
-
-// On windows dump does not writes into stdout so cfx can't read thous dumps.
-// To workaround this issue we write to a special file from which cfx will
-// read and print to the console.
-// For more details see: bug-673383
-exports.dump = stdout.write;
-
-// Bug 718230: We need to send console messages to stdout and JS Console
-function forsakenConsoleDump(msg, level) {
- stdout.write(msg);
-
- if (level === 'error') {
- let error = ScriptError();
- msg = msg.replace(/^error: /, '');
- error.init(msg, null, null, 0, 0, 0, 'Add-on SDK');
- consoleService.logMessage(error);
- }
- else
- consoleService.logStringMessage(msg);
-};
-exports.console = new PlainTextConsole(forsakenConsoleDump);
-
-// Provide CommonJS `define` to allow authoring modules in a format that can be
-// loaded both into jetpack and into browser via AMD loaders.
-Object.defineProperty(exports, 'define', {
- // `define` is provided as a lazy getter that binds below defined `define`
- // function to the module scope, so that require, exports and module
- // variables remain accessible.
- configurable: true,
- get: function() {
- let sandbox = this;
- return function define(factory) {
- factory = Array.slice(arguments).pop();
- factory.call(sandbox, sandbox.require, sandbox.exports, sandbox.module);
- }
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/system/runtime.js b/tools/addon-sdk-1.12/lib/sdk/system/runtime.js
deleted file mode 100644
index e64b663..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/system/runtime.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { Cc, Ci } = require("chrome");
-const runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
-
-exports.inSafeMode = runtime.inSafeMode;
-exports.OS = runtime.OS;
-exports.processType = runtime.processType;
-exports.widgetToolkit = runtime.widgetToolkit;
-exports.XPCOMABI = runtime.XPCOMABI;
diff --git a/tools/addon-sdk-1.12/lib/sdk/system/unload.js b/tools/addon-sdk-1.12/lib/sdk/system/unload.js
deleted file mode 100644
index 4d2575b..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/system/unload.js
+++ /dev/null
@@ -1,82 +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/. */
-
-// Parts of this module were taken from narwhal:
-//
-// http://narwhaljs.org
-
-module.metadata = {
- "stability": "experimental"
-};
-
-const { on, off } = require('./events');
-const unloadSubject = require('@loader/unload');
-
-const observers = [];
-const unloaders = [];
-
-var when = exports.when = function when(observer) {
- if (observers.indexOf(observer) != -1)
- return;
- observers.unshift(observer);
-};
-
-var ensure = exports.ensure = function ensure(obj, destructorName) {
- if (!destructorName)
- destructorName = "unload";
- if (!(destructorName in obj))
- throw new Error("object has no '" + destructorName + "' property");
-
- let called = false;
- let originalDestructor = obj[destructorName];
-
- function unloadWrapper(reason) {
- if (!called) {
- called = true;
- let index = unloaders.indexOf(unloadWrapper);
- if (index == -1)
- throw new Error("internal error: unloader not found");
- unloaders.splice(index, 1);
- originalDestructor.call(obj, reason);
- originalDestructor = null;
- destructorName = null;
- obj = null;
- }
- };
-
- // TODO: Find out why the order is inverted here. It seems that
- // it may be causing issues!
- unloaders.push(unloadWrapper);
-
- obj[destructorName] = unloadWrapper;
-};
-
-function unload(reason) {
- observers.forEach(function(observer) {
- try {
- observer(reason);
- }
- catch (error) {
- console.exception(error);
- }
- });
-}
-
-when(function(reason) {
- unloaders.slice().forEach(function(unloadWrapper) {
- unloadWrapper(reason);
- });
-});
-
-on('sdk:loader:destroy', function onunload({ subject, data: reason }) {
- // If this loader is unload then `subject.wrappedJSObject` will be
- // `destructor`.
- if (subject.wrappedJSObject === unloadSubject) {
- off('sdk:loader:destroy', onunload);
- unload(reason);
- }
-// Note that we use strong reference to listener here to make sure it's not
-// GC-ed, which may happen otherwise since nothing keeps reference to `onunolad`
-// function.
-}, true);
diff --git a/tools/addon-sdk-1.12/lib/sdk/system/xul-app.js b/tools/addon-sdk-1.12/lib/sdk/system/xul-app.js
deleted file mode 100644
index 6e8b4e8..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/system/xul-app.js
+++ /dev/null
@@ -1,67 +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": "experimental"
-};
-
-const {Cc, Ci} = require("chrome");
-
-var appInfo = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsIXULAppInfo);
-
-var ID = exports.ID = appInfo.ID;
-var name = exports.name = appInfo.name;
-var version = exports.version = appInfo.version;
-var platformVersion = exports.platformVersion = appInfo.platformVersion;
-
-// The following mapping of application names to GUIDs was taken from:
-//
-// https://addons.mozilla.org/en-US/firefox/pages/appversions
-//
-// Using the GUID instead of the app's name is preferable because sometimes
-// re-branded versions of a product have different names: for instance,
-// Firefox, Minefield, Iceweasel, and Shiretoko all have the same
-// GUID.
-// This mapping is duplicated in `app-extensions/bootstrap.js`. They should keep
-// in sync, so if you change one, change the other too!
-
-var ids = exports.ids = {
- Firefox: "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
- Mozilla: "{86c18b42-e466-45a9-ae7a-9b95ba6f5640}",
- Sunbird: "{718e30fb-e89b-41dd-9da7-e25a45638b28}",
- SeaMonkey: "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}",
- Fennec: "{aa3c5121-dab2-40e2-81ca-7ea25febc110}",
- Thunderbird: "{3550f703-e582-4d05-9a08-453d09bdfdc6}"
-};
-
-var is = exports.is = function is(name) {
- if (!(name in ids))
- throw new Error("Unkown Mozilla Application: " + name);
- return ID == ids[name];
-};
-
-var isOneOf = exports.isOneOf = function isOneOf(names) {
- for (var i = 0; i < names.length; i++)
- if (is(names[i]))
- return true;
- return false;
-};
-
-/**
- * Use this to check whether the given version (e.g. xulApp.platformVersion)
- * is in the given range. Versions must be in version comparator-compatible
- * format. See MDC for details:
- * https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIVersionComparator
- */
-var versionInRange = exports.versionInRange =
-function versionInRange(version, lowInclusive, highExclusive) {
- var vc = Cc["@mozilla.org/xpcom/version-comparator;1"]
- .getService(Ci.nsIVersionComparator);
- return (vc.compare(version, lowInclusive) >= 0) &&
- (vc.compare(version, highExclusive) < 0);
-}
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs.js b/tools/addon-sdk-1.12/lib/sdk/tabs.js
deleted file mode 100644
index f006073..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs.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';
-
-module.metadata = {
- 'stability': 'stable'
-};
-
-module.exports = require('./tabs/tabs');
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/common.js b/tools/addon-sdk-1.12/lib/sdk/tabs/common.js
deleted file mode 100644
index dd5bb22..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/common.js
+++ /dev/null
@@ -1,23 +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');
-
-function Options(options) {
- if ('string' === typeof options)
- options = { url: options };
-
- return validateOptions(options, {
- url: { is: ["string"] },
- inBackground: { is: ["undefined", "boolean"] },
- isPinned: { is: ["undefined", "boolean"] },
- onOpen: { is: ["undefined", "function"] },
- onClose: { is: ["undefined", "function"] },
- onReady: { is: ["undefined", "function"] },
- onActivate: { is: ["undefined", "function"] },
- onDeactivate: { is: ["undefined", "function"] }
- });
-}
-exports.Options = Options;
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/events.js b/tools/addon-sdk-1.12/lib/sdk/tabs/events.js
deleted file mode 100644
index eb99f40..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/events.js
+++ /dev/null
@@ -1,30 +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",
- 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: ON_PREFIX + name.charAt(0).toUpperCase() + name.substr(1),
- dom: EVENTS[name]
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/helpers.js b/tools/addon-sdk-1.12/lib/sdk/tabs/helpers.js
deleted file mode 100644
index aaff5cb..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/helpers.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 { getTabForContentWindow } = require('./utils');
-const { Tab } = require('./tab');
-
-function getTabForWindow(win) {
- let tab = getTabForContentWindow(win);
- // We were unable to find the related tab!
- if (!tab)
- return null;
-
- return Tab({ tab: tab });
-}
-exports.getTabForWindow = getTabForWindow;
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/namespace.js b/tools/addon-sdk-1.12/lib/sdk/tabs/namespace.js
deleted file mode 100644
index d359cee..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/namespace.js
+++ /dev/null
@@ -1,9 +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';
-
-let { ns } = require('../core/namespace');
-
-exports.tabsNS = ns();
-exports.tabNS = ns();
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/observer.js b/tools/addon-sdk-1.12/lib/sdk/tabs/observer.js
deleted file mode 100644
index 19a048c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/observer.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { EventEmitterTrait: EventEmitter } = require("../deprecated/events");
-const { DOMEventAssembler } = require("../deprecated/events/assembler");
-const { Trait } = require("../deprecated/light-traits");
-const { getActiveTab, getTabs, getTabContainer } = require("./utils");
-const { browserWindowIterator } = require("../deprecated/window-utils");
-const { isBrowser } = require('../window/utils');
-const { observer: windowObserver } = require("../windows/observer");
-
-const EVENTS = {
- "TabOpen": "open",
- "TabClose": "close",
- "TabSelect": "select",
- "TabMove": "move",
- "TabPinned": "pinned",
- "TabUnpinned": "unpinned"
-};
-
-
-// Event emitter objects used to register listeners and emit events on them
-// when they occur.
-const observer = Trait.compose(DOMEventAssembler, EventEmitter).create({
- /**
- * Method is implemented by `EventEmitter` and is used just for emitting
- * events on registered listeners.
- */
- _emit: Trait.required,
- /**
- * 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) {
- this._emit(EVENTS[event.type], event.target, event);
- }
-});
-
-// 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.
-var selectedTab = null;
-function onTabSelect(tab) {
- if (selectedTab !== tab) {
- if (selectedTab) observer._emit('deactivate', selectedTab);
- if (tab) observer._emit('activate', selectedTab = tab);
- }
-};
-observer.on('select', onTabSelect);
-
-// We also observe opening / closing windows in order to add / remove it's
-// containers to the observed list.
-function onWindowOpen(chromeWindow) {
- if (!isBrowser(chromeWindow)) return; // Ignore if it's not a browser window.
- observer.observe(getTabContainer(chromeWindow));
-}
-windowObserver.on("open", onWindowOpen);
-
-function onWindowClose(chromeWindow) {
- if (!isBrowser(chromeWindow)) return; // Ignore if it's not a browser window.
- // Bug 751546: Emit `deactivate` event on window close immediatly
- // Otherwise we are going to face "dead object" exception on `select` event
- if (getActiveTab(chromeWindow) == selectedTab) {
- observer._emit("deactivate", selectedTab);
- selectedTab = null;
- }
- observer.ignore(getTabContainer(chromeWindow));
-}
-windowObserver.on("close", onWindowClose);
-
-
-// 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", function onWindowActivate(chromeWindow) {
- if (!isBrowser(chromeWindow)) return; // Ignore if it's not a browser window.
- observer._emit("select", getActiveTab(chromeWindow));
-});
-
-// We should synchronize state, since probably we already have at least one
-// window open.
-for each (let window in browserWindowIterator()) onWindowOpen(window);
-
-exports.observer = observer;
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/tab-fennec.js b/tools/addon-sdk-1.12/lib/sdk/tabs/tab-fennec.js
deleted file mode 100644
index 42bf91b..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/tab-fennec.js
+++ /dev/null
@@ -1,141 +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 } = require('./namespace');
-const { EventTarget } = require('../event/target');
-const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL,
- setTabURL, getOwnerWindow, getTabContentType } = require('./utils');
-const { emit } = require('../event/core');
-const { when: unload } = require('../system/unload');
-
-const { EVENTS } = require('./events');
-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 };
-
- EventTarget.prototype.initialize.call(this, options);
- let tabInternals = tabNS(this);
-
- tabInternals.window = options.window || getOwnerWindow(options.tab);
- tabInternals.tab = options.tab;
- },
-
- /**
- * The title of the page currently loaded in the tab.
- * Changing this property changes an actual title.
- * @type {String}
- */
- get title() 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() getTabURL(tabNS(this).tab),
- set url(url) setTabURL(tabNS(this).tab, url),
-
- /**
- * URI of the favicon for the page currently loaded in this tab.
- * @type {String}
- */
- get favicon() {
- // TODO: provide the real favicon when it is available
- console.error(ERR_FENNEC_MSG);
-
- // return 16x16 blank default
- return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAEklEQVQ4jWNgGAWjYBSMAggAAAQQAAF/TXiOAAAAAElFTkSuQmCC';
- },
-
- getThumbnail: function() {
- // TODO: implement!
- console.error(ERR_FENNEC_MSG);
-
- // return 80x45 blank default
- return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAtCAYAAAA5reyyAAAAJElEQVRoge3BAQEAAACCIP+vbkhAAQAAAAAAAAAAAAAAAADXBjhtAAGQ0AF/AAAAAElFTkSuQmCC';
- },
-
- /**
- * 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() {
- 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() 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, tabNS(this).tab.browser.contentWindow);
- },
-
- /**
- * Make this tab active.
- */
- activate: function activate() {
- activateTab(tabNS(this).tab, tabNS(this).window);
- },
-
- /**
- * Close the tab
- */
- close: function close(callback) {
- if (callback)
- this.once(EVENTS.close.name, callback);
-
- closeTab(tabNS(this).tab);
- },
-
- /**
- * Reload the tab
- */
- reload: function reload() {
- tabNS(this).tab.browser.reload();
- }
-});
-exports.Tab = Tab;
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/tab-firefox.js b/tools/addon-sdk-1.12/lib/sdk/tabs/tab-firefox.js
deleted file mode 100644
index 5a36302..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/tab-firefox.js
+++ /dev/null
@@ -1,201 +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 { Trait } = require("../deprecated/traits");
-const { EventEmitter } = require("../deprecated/events");
-const { defer } = require("../lang/functional");
-const { EVENTS } = require("./events");
-const { getThumbnailURIForWindow } = require("../content/thumbnail");
-const { getFaviconURIForLocation } = require("../io/data");
-const { activateTab, getOwnerWindow, getBrowserForTab, getTabTitle, setTabTitle,
- getTabURL, setTabURL, getTabContentType } = require('./utils');
-
-// Array of the inner instances of all the wrapped tabs.
-const TABS = [];
-
-/**
- * Trait used to create tab wrappers.
- */
-const TabTrait = Trait.compose(EventEmitter, {
- on: Trait.required,
- _emit: Trait.required,
- /**
- * Tab DOM element that is being wrapped.
- */
- _tab: null,
- /**
- * Window wrapper whose tab this object represents.
- */
- window: null,
- constructor: function Tab(options) {
- this._onReady = this._onReady.bind(this);
- this._tab = options.tab;
- let window = this.window = options.window || getOwnerWindow(this._tab);
-
- // Setting event listener if was passed.
- for each (let type in EVENTS) {
- let listener = options[type.listener];
- if (listener)
- this.on(type.name, options[type.listener]);
- if ('ready' != type.name) // window spreads this event.
- window.tabs.on(type.name, this._onEvent.bind(this, type.name));
- }
-
- this.on(EVENTS.close.name, this.destroy.bind(this));
- this._browser.addEventListener(EVENTS.ready.dom, this._onReady, true);
-
- if (options.isPinned)
- this.pin();
-
- // Since we will have to identify tabs by a DOM elements facade function
- // is used as constructor that collects all the instances and makes sure
- // that they more then one wrapper is not created per tab.
- return this;
- },
- destroy: function destroy() {
- this._removeAllListeners();
- this._browser.removeEventListener(EVENTS.ready.dom, this._onReady, true);
- },
-
- /**
- * Internal listener that emits public event 'ready' when the page of this
- * tab is loaded.
- */
- _onReady: function _onReady(event) {
- // IFrames events will bubble so we need to ignore those.
- if (event.target == this._contentDocument)
- this._emit(EVENTS.ready.name, this._public);
- },
- /**
- * Internal tab event router. Window will emit tab related events for all it's
- * tabs, this listener will propagate all the events for this tab to it's
- * listeners.
- */
- _onEvent: function _onEvent(type, tab) {
- if (tab == this._public)
- this._emit(type, tab);
- },
- /**
- * Browser DOM element where page of this tab is currently loaded.
- */
- get _browser() getBrowserForTab(this._tab),
- /**
- * Window DOM element containing this tab.
- */
- get _window() getOwnerWindow(this._tab),
- /**
- * Document object of the page that is currently loaded in this tab.
- */
- get _contentDocument() this._browser.contentDocument,
- /**
- * Window object of the page that is currently loaded in this tab.
- */
- get _contentWindow() this._browser.contentWindow,
-
- /**
- * The title of the page currently loaded in the tab.
- * Changing this property changes an actual title.
- * @type {String}
- */
- get title() getTabTitle(this._tab),
- set title(title) setTabTitle(this._tab, title),
-
- /**
- * Returns the MIME type that the document loaded in the tab is being
- * rendered as.
- * @type {String}
- */
- get contentType() getTabContentType(this._tab),
-
- /**
- * Location of the page currently loaded in this tab.
- * Changing this property will loads page under under the specified location.
- * @type {String}
- */
- get url() getTabURL(this._tab),
- set url(url) setTabURL(this._tab, url),
- /**
- * URI of the favicon for the page currently loaded in this tab.
- * @type {String}
- */
- get favicon() getFaviconURIForLocation(this.url),
- /**
- * The CSS style for the tab
- */
- get style() null, // TODO
- /**
- * 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()
- this._window.gBrowser.getBrowserIndexForDocument(this._contentDocument),
- set index(value) this._window.gBrowser.moveTabTo(this._tab, value),
- /**
- * Thumbnail data URI of the page currently loaded in this tab.
- * @type {String}
- */
- getThumbnail: function getThumbnail()
- getThumbnailURIForWindow(this._contentWindow),
- /**
- * Whether or not tab is pinned (Is an app-tab).
- * @type {Boolean}
- */
- get isPinned() this._tab.pinned,
- pin: function pin() {
- this._window.gBrowser.pinTab(this._tab);
- },
- unpin: function unpin() {
- this._window.gBrowser.unpinTab(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, this._contentWindow);
- },
-
- /**
- * Make this tab active.
- * Please note: That this function is called asynchronous since in E10S that
- * will be the case. Besides this function is called from a constructor where
- * we would like to return instance before firing a 'TabActivated' event.
- */
- activate: defer(function activate() {
- activateTab(this._tab);
- }),
- /**
- * Close the tab
- */
- close: function close(callback) {
- if (callback)
- this.once(EVENTS.close.name, callback);
- this._window.gBrowser.removeTab(this._tab);
- },
- /**
- * Reload the tab
- */
- reload: function reload() {
- this._window.gBrowser.reloadTab(this._tab);
- }
-});
-
-function Tab(options) {
- let chromeTab = options.tab;
- for each (let tab in TABS) {
- if (chromeTab == tab._tab)
- return tab._public;
- }
- let tab = TabTrait(options);
- TABS.push(tab);
- return tab._public;
-}
-Tab.prototype = TabTrait.prototype;
-exports.Tab = Tab;
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/tab.js b/tools/addon-sdk-1.12/lib/sdk/tabs/tab.js
deleted file mode 100644
index 420baee..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/tab.js
+++ /dev/null
@@ -1,21 +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'
-};
-
-if (require('../system/xul-app').is('Firefox')) {
- module.exports = require('./tab-firefox');
-}
-else if (require('../system/xul-app').is('Fennec')) {
- module.exports = require('./tab-fennec');
-}
-else {
- throw new Error([
- 'The tabs module currently supports only Firefox & Fennec. In the future',
- ' we would like it to support other applications, however.'
- ].join(''));
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/tabs-firefox.js b/tools/addon-sdk-1.12/lib/sdk/tabs/tabs-firefox.js
deleted file mode 100644
index 92834c2..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/tabs-firefox.js
+++ /dev/null
@@ -1,26 +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';
-
-// TODO: BUG 792670 - remove dependency below
-const { browserWindows } = require('../windows');
-const { tabs } = require('../windows/tabs-firefox');
-
-Object.defineProperties(tabs, {
- open: { value: function open(options) {
- if (options.inNewWindow)
- // `tabs` option is under review and may be removed.
- return browserWindows.open({ tabs: [ options ] });
- // Open in active window if new window was not required.
- return browserWindows.activeWindow.tabs.open(options);
- }}
-});
-
-// Workaround for bug 674195. Freezing objects from other compartments fail,
-// so we use `Object.freeze` from the same component as objects
-// `hasOwnProperty`. Since `hasOwnProperty` here will be from other component
-// we override it to support our workaround.
-module.exports = Object.create(tabs, {
- isPrototypeOf: { value: Object.prototype.isPrototypeOf }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/tabs.js b/tools/addon-sdk-1.12/lib/sdk/tabs/tabs.js
deleted file mode 100644
index fcb3868..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/tabs.js
+++ /dev/null
@@ -1,21 +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'
-};
-
-if (require('../system/xul-app').is('Firefox')) {
- module.exports = require('./tabs-firefox');
-}
-else if (require('../system/xul-app').is('Fennec')) {
- module.exports = require('../windows/tabs-fennec').tabs;
-}
-else {
- throw new Error([
- 'The tabs module currently supports only Firefox & Fennec. In the future',
- ' we would like it to support other applications, however.'
- ].join(''));
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/utils.js b/tools/addon-sdk-1.12/lib/sdk/tabs/utils.js
deleted file mode 100644
index d923e4b..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/tabs/utils.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { defer } = require("../lang/functional");
-const { windows } = require('../window/utils');
-const { Ci } = require('chrome');
-
-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) {
- return window.gBrowser;
-}
-exports.getTabBrowser = getTabBrowser;
-
-function getTabContainer(window) {
- return getTabBrowser(window).tabContainer;
-}
-exports.getTabContainer = getTabContainer;
-
-function getTabs(window) {
- // fennec
- if (window.BrowserApp)
- return window.BrowserApp.tabs;
-
- // firefox - default
- return Array.slice(getTabContainer(window).children);
-}
-exports.getTabs = getTabs;
-
-function getActiveTab(window) {
- return window.gBrowser.selectedTab;
-}
-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 each (let window in windows()) {
- // this function may be called when not using fennec
- if (!window.BrowserApp)
- continue;
-
- for each (let tab in 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
- });
- }
- return window.gBrowser.addTab(url);
-};
-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)
- return gBrowser.removeTab(tab);
-
- let window = getWindowHoldingTab(tab);
- // fennec?
- if (window && window.BrowserApp)
- 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 getTabTitle(tab) {
- return getBrowserForTab(tab).contentDocument.title || tab.label || "";
-}
-exports.getTabTitle = getTabTitle;
-
-function setTabTitle(tab, title) {
- title = String(title);
- if (tab.browser)
- tab.browser.contentDocument.title = title;
- tab.label = String(title);
-}
-exports.setTabTitle = setTabTitle;
-
-function getTabContentWindow(tab) {
- return getBrowserForTab(tab).contentWindow;
-}
-exports.getTabContentWindow = getTabContentWindow;
-
-function getTabForContentWindow(window) {
- // Retrieve the topmost frame container. It can be either <xul:browser>,
- // <xul:iframe/> or <html:iframe/>. But in our case, it should be xul:browser.
- let browser = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .chromeEventHandler;
- // Is null for toplevel documents
- if (!browser)
- return false;
- // Retrieve the owner window, should be browser.xul one
- let chromeWindow = browser.ownerDocument.defaultView;
-
- // Ensure that it is top-level browser window.
- // We need extra checks because of Mac hidden window that has a broken
- // `gBrowser` global attribute.
- if ('gBrowser' in chromeWindow && chromeWindow.gBrowser &&
- 'browsers' in chromeWindow.gBrowser) {
- // Looks like we are on Firefox Desktop
- // Then search for the position in tabbrowser in order to get the tab object
- let browsers = chromeWindow.gBrowser.browsers;
- let i = browsers.indexOf(browser);
- if (i !== -1)
- return chromeWindow.gBrowser.tabs[i];
- return null;
- }
- else if ('BrowserApp' in chromeWindow) {
- // Looks like we are on Firefox Mobile
- return chromeWindow.BrowserApp.getTabForWindow(window)
- }
-
- return null;
-}
-exports.getTabForContentWindow = getTabForContentWindow;
-
-function getTabURL(tab) {
- if (tab.browser) // fennec
- return String(tab.browser.currentURI.spec);
- return String(getBrowserForTab(tab).currentURI.spec);
-}
-exports.getTabURL = getTabURL;
-
-function setTabURL(tab, url) {
- url = String(url);
- if (tab.browser)
- return tab.browser.loadURI(url);
- return getBrowserForTab(tab).loadURI(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;
diff --git a/tools/addon-sdk-1.12/lib/sdk/tabs/worker.js b/tools/addon-sdk-1.12/lib/sdk/tabs/worker.js
deleted file mode 100644
index d2ba336..0000000
--- a/tools/addon-sdk-1.12/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
diff --git a/tools/addon-sdk-1.12/lib/sdk/test.js b/tools/addon-sdk-1.12/lib/sdk/test.js
deleted file mode 100644
index 0a322d6..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/test.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* vim:ts=2:sts=2:sw=2:
- * 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 BaseAssert = require("./test/assert").Assert;
-const { isFunction, isObject } = require("./lang/type");
-
-function extend(target) {
- let descriptor = {}
- Array.slice(arguments, 1).forEach(function(source) {
- Object.getOwnPropertyNames(source).forEach(function onEach(name) {
- descriptor[name] = Object.getOwnPropertyDescriptor(source, name);
- });
- });
- return Object.create(target, descriptor);
-}
-
-/**
- * Function takes test `suite` object in CommonJS format and defines all of the
- * tests from that suite and nested suites in a jetpack format on a given
- * `target` object. Optionally third argument `prefix` can be passed to prefix
- * all the test names.
- */
-function defineTestSuite(target, suite, prefix) {
- prefix = prefix || "";
- // If suite defines `Assert` that's what `assert` object have to be created
- // from and passed to a test function (This allows custom assertion functions)
- // See for details: http://wiki.commonjs.org/wiki/Unit_Testing/1.1
- let Assert = suite.Assert || BaseAssert;
- // Going through each item in the test suite and wrapping it into a
- // Jetpack test format.
- Object.keys(suite).forEach(function(key) {
- // If name starts with test then it's a test function or suite.
- if (key.indexOf("test") === 0) {
- let test = suite[key];
-
- // For each test function so we create a wrapper test function in a
- // jetpack format and copy that to a `target` exports.
- if (isFunction(test)) {
-
- // Since names of the test may match across suites we use full object
- // path as a name to avoid overriding same function.
- target[prefix + key] = function(options) {
-
- // Creating `assert` functions for this test.
- let assert = Assert(options);
-
- // If CommonJS test function expects more than one argument
- // it means that test is async and second argument is a callback
- // to notify that test is finished.
- if (1 < test.length) {
-
- // Letting test runner know that test is executed async and
- // creating a callback function that CommonJS tests will call
- // once it's done.
- options.waitUntilDone();
- test(assert, function() {
- options.done();
- });
- }
-
- // Otherwise CommonJS test is synchronous so we call it only with
- // one argument.
- else {
- test(assert);
- }
- }
- }
-
- // If it's an object then it's a test suite containing test function
- // and / or nested test suites. In that case we just extend prefix used
- // and call this function to copy and wrap tests from nested suite.
- else if (isObject(test)) {
- // We need to clone `tests` instead of modifying it, since it's very
- // likely that it is frozen (usually test suites imported modules).
- test = extend(Object.prototype, test, {
- Assert: test.Assert || Assert
- });
- defineTestSuite(target, test, prefix + key + ".");
- }
- }
- });
-}
-
-/**
- * This function is a CommonJS test runner function, but since Jetpack test
- * runner and test format is different from CommonJS this function shims given
- * `exports` with all its tests into a Jetpack test format so that the built-in
- * test runner will be able to run CommonJS test without manual changes.
- */
-exports.run = function run(exports) {
-
- // We can't leave old properties on exports since those are test in a CommonJS
- // format that why we move everything to a new `suite` object.
- let suite = {};
- Object.keys(exports).forEach(function(key) {
- suite[key] = exports[key];
- delete exports[key];
- });
-
- // Now we wrap all the CommonJS tests to a Jetpack format and define
- // those to a given `exports` object since that where jetpack test runner
- // will look for them.
- defineTestSuite(exports, suite);
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/test/assert.js b/tools/addon-sdk-1.12/lib/sdk/test/assert.js
deleted file mode 100644
index 5eca7d4..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/test/assert.js
+++ /dev/null
@@ -1,349 +0,0 @@
-/* vim:ts=2:sts=2:sw=2:
- * 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 { isFunction, isNull, isObject, isString,
- isRegExp, isArray, isDate, isPrimitive,
- isUndefined, instanceOf, source } = require("../lang/type");
-
-/**
- * The `AssertionError` is defined in assert.
- * @extends Error
- * @example
- * new assert.AssertionError({
- * message: message,
- * actual: actual,
- * expected: expected
- * })
- */
-function AssertionError(options) {
- let assertionError = Object.create(AssertionError.prototype);
-
- if (isString(options))
- options = { message: options };
- if ("actual" in options)
- assertionError.actual = options.actual;
- if ("expected" in options)
- assertionError.expected = options.expected;
- if ("operator" in options)
- assertionError.operator = options.operator;
-
- assertionError.message = options.message;
- assertionError.stack = new Error().stack;
- return assertionError;
-}
-AssertionError.prototype = Object.create(Error.prototype, {
- constructor: { value: AssertionError },
- name: { value: "AssertionError", enumerable: true },
- toString: { value: function toString() {
- let value;
- if (this.message) {
- value = this.name + " : " + this.message;
- }
- else {
- value = [
- this.name + " : ",
- source(this.expected),
- this.operator,
- source(this.actual)
- ].join(" ");
- }
- return value;
- }}
-});
-exports.AssertionError = AssertionError;
-
-function Assert(logger) {
- return Object.create(Assert.prototype, { _log: { value: logger }});
-}
-Assert.prototype = {
- fail: function fail(e) {
- if (!e || typeof(e) !== 'object') {
- this._log.fail(e);
- return;
- }
- let message = e.message;
- if ('operator' in e) {
- message += [
- " -",
- source(e.expected),
- e.operator,
- source(e.actual)
- ].join(" ");
- }
- this._log.fail(message);
- },
- pass: function pass(message) {
- this._log.pass(message);
- },
- error: function error(e) {
- this._log.exception(e);
- },
- ok: function ok(value, message) {
- if (!!!value) {
- this.fail({
- actual: value,
- expected: true,
- message: message,
- operator: "=="
- });
- }
- else {
- this.pass(message);
- }
- },
-
- /**
- * The equality assertion tests shallow, coercive equality with `==`.
- * @example
- * assert.equal(1, 1, "one is one");
- */
- equal: function equal(actual, expected, message) {
- if (actual == expected) {
- this.pass(message);
- }
- else {
- this.fail({
- actual: actual,
- expected: expected,
- message: message,
- operator: "=="
- });
- }
- },
-
- /**
- * The non-equality assertion tests for whether two objects are not equal
- * with `!=`.
- * @example
- * assert.notEqual(1, 2, "one is not two");
- */
- notEqual: function notEqual(actual, expected, message) {
- if (actual != expected) {
- this.pass(message);
- }
- else {
- this.fail({
- actual: actual,
- expected: expected,
- message: message,
- operator: "!=",
- });
- }
- },
-
- /**
- * The equivalence assertion tests a deep (with `===`) equality relation.
- * @example
- * assert.deepEqual({ a: "foo" }, { a: "foo" }, "equivalent objects")
- */
- deepEqual: function deepEqual(actual, expected, message) {
- if (isDeepEqual(actual, expected)) {
- this.pass(message);
- }
- else {
- this.fail({
- actual: actual,
- expected: expected,
- message: message,
- operator: "deepEqual"
- });
- }
- },
-
- /**
- * The non-equivalence assertion tests for any deep (with `===`) inequality.
- * @example
- * assert.notDeepEqual({ a: "foo" }, Object.create({ a: "foo" }),
- * "object's inherit from different prototypes");
- */
- notDeepEqual: function notDeepEqual(actual, expected, message) {
- if (!isDeepEqual(actual, expected)) {
- this.pass(message);
- }
- else {
- this.fail({
- actual: actual,
- expected: expected,
- message: message,
- operator: "notDeepEqual"
- });
- }
- },
-
- /**
- * The strict equality assertion tests strict equality, as determined by
- * `===`.
- * @example
- * assert.strictEqual(null, null, "`null` is `null`")
- */
- strictEqual: function strictEqual(actual, expected, message) {
- if (actual === expected) {
- this.pass(message);
- }
- else {
- this.fail({
- actual: actual,
- expected: expected,
- message: message,
- operator: "==="
- });
- }
- },
-
- /**
- * The strict non-equality assertion tests for strict inequality, as
- * determined by `!==`.
- * @example
- * assert.notStrictEqual(null, undefined, "`null` is not `undefined`");
- */
- notStrictEqual: function notStrictEqual(actual, expected, message) {
- if (actual !== expected) {
- this.pass(message);
- }
- else {
- this.fail({
- actual: actual,
- expected: expected,
- message: message,
- operator: "!=="
- })
- }
- },
-
- /**
- * The assertion whether or not given `block` throws an exception. If optional
- * `Error` argument is provided and it's type of function thrown error is
- * asserted to be an instance of it, if type of `Error` is string then message
- * of throw exception is asserted to contain it.
- * @param {Function} block
- * Function that is expected to throw.
- * @param {Error|RegExp} [Error]
- * Error constructor that is expected to be thrown or a string that
- * must be contained by a message of the thrown exception, or a RegExp
- * matching a message of the thrown exception.
- * @param {String} message
- * Description message
- *
- * @examples
- *
- * assert.throws(function block() {
- * doSomething(4)
- * }, "Object is expected", "Incorrect argument is passed");
- *
- * assert.throws(function block() {
- * Object.create(5)
- * }, TypeError, "TypeError is thrown");
- */
- throws: function throws(block, Error, message) {
- let threw = false;
- let exception = null;
-
- // If third argument is not provided and second argument is a string it
- // means that optional `Error` argument was not passed, so we shift
- // arguments.
- if (isString(Error) && isUndefined(message)) {
- message = Error;
- Error = undefined;
- }
-
- // Executing given `block`.
- try {
- block();
- }
- catch (e) {
- threw = true;
- exception = e;
- }
-
- // If exception was thrown and `Error` argument was not passed assert is
- // passed.
- if (threw && (isUndefined(Error) ||
- // If passed `Error` is RegExp using it's test method to
- // assert thrown exception message.
- (isRegExp(Error) && Error.test(exception.message)) ||
- // If passed `Error` is a constructor function testing if
- // thrown exception is an instance of it.
- (isFunction(Error) && instanceOf(exception, Error))))
- {
- this.pass(message);
- }
-
- // Otherwise we report assertion failure.
- else {
- let failure = {
- message: message,
- operator: "throws"
- };
-
- if (exception)
- failure.actual = exception;
-
- if (Error)
- failure.expected = Error;
-
- this.fail(failure);
- }
- }
-};
-exports.Assert = Assert;
-
-function isDeepEqual(actual, expected) {
-
- // 7.1. All identical values are equivalent, as determined by ===.
- if (actual === expected) {
- return true;
- }
-
- // 7.2. If the expected value is a Date object, the actual value is
- // equivalent if it is also a Date object that refers to the same time.
- else if (isDate(actual) && isDate(expected)) {
- return actual.getTime() === expected.getTime();
- }
-
- // XXX specification bug: this should be specified
- else if (isPrimitive(actual) || isPrimitive(expected)) {
- return expected === actual;
- }
-
- // 7.3. Other pairs that do not both pass typeof value == "object",
- // equivalence is determined by ==.
- else if (!isObject(actual) && !isObject(expected)) {
- return actual == expected;
- }
-
- // 7.4. For all other Object pairs, including Array objects, equivalence is
- // determined by having the same number of owned properties (as verified
- // with Object.prototype.hasOwnProperty.call), the same set of keys
- // (although not necessarily the same order), equivalent values for every
- // corresponding key, and an identical "prototype" property. Note: this
- // accounts for both named and indexed properties on Arrays.
- else {
- return actual.prototype === expected.prototype &&
- isEquivalent(actual, expected);
- }
-}
-
-function isEquivalent(a, b, stack) {
- let aKeys = Object.keys(a);
- let bKeys = Object.keys(b);
-
- return aKeys.length === bKeys.length &&
- isArrayEquivalent(aKeys.sort(), bKeys.sort()) &&
- aKeys.every(function(key) {
- return isDeepEqual(a[key], b[key], stack)
- });
-}
-
-function isArrayEquivalent(a, b, stack) {
- return isArray(a) && isArray(b) &&
- a.every(function(value, index) {
- return isDeepEqual(value, b[index]);
- });
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/test/harness.js b/tools/addon-sdk-1.12/lib/sdk/test/harness.js
deleted file mode 100644
index 46584ca..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/test/harness.js
+++ /dev/null
@@ -1,327 +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 { Loader } = require('./loader');
-const { setTimeout } = require('../timers');
-const memory = require('../deprecated/memory');
-const { PlainTextConsole } = require("../console/plain-text");
-const { when: unload } = require("../system/unload");
-const { format } = require("../console/traceback");
-const system = require("../system");
-
-// Trick manifest builder to make it think we need these modules ?
-const unit = require("../deprecated/unit-test");
-const test = require("../test");
-const url = require("../url");
-
-var cService = Cc['@mozilla.org/consoleservice;1'].getService()
- .QueryInterface(Ci.nsIConsoleService);
-
-// Cuddlefish loader in which we load and execute tests.
-var loader;
-
-// Function to call when we're done running tests.
-var onDone;
-
-// Function to print text to a console, w/o CR at the end.
-var print;
-
-// How many more times to run all tests.
-var iterationsLeft;
-
-// Whether to report memory profiling information.
-var profileMemory;
-
-// Whether we should stop as soon as a test reports a failure.
-var stopOnError;
-
-// Function to call to retrieve a list of tests to execute
-var findAndRunTests;
-
-// Combined information from all test runs.
-var results = {
- passed: 0,
- failed: 0,
- testRuns: []
-};
-
-// JSON serialization of last memory usage stats; we keep it stringified
-// so we don't actually change the memory usage stats (in terms of objects)
-// of the JSRuntime we're profiling.
-var lastMemoryUsage;
-
-function analyzeRawProfilingData(data) {
- var graph = data.graph;
- var shapes = {};
-
- // Convert keys in the graph from strings to ints.
- // TODO: Can we get rid of this ridiculousness?
- var newGraph = {};
- for (id in graph) {
- newGraph[parseInt(id)] = graph[id];
- }
- graph = newGraph;
-
- var modules = 0;
- var moduleIds = [];
- var moduleObjs = {UNKNOWN: 0};
- for (let name in data.namedObjects) {
- moduleObjs[name] = 0;
- moduleIds[data.namedObjects[name]] = name;
- modules++;
- }
-
- var count = 0;
- for (id in graph) {
- var parent = graph[id].parent;
- while (parent) {
- if (parent in moduleIds) {
- var name = moduleIds[parent];
- moduleObjs[name]++;
- break;
- }
- if (!(parent in graph)) {
- moduleObjs.UNKNOWN++;
- break;
- }
- parent = graph[parent].parent;
- }
- count++;
- }
-
- print("\nobject count is " + count + " in " + modules + " modules" +
- " (" + data.totalObjectCount + " across entire JS runtime)\n");
- if (lastMemoryUsage) {
- var last = JSON.parse(lastMemoryUsage);
- var diff = {
- moduleObjs: dictDiff(last.moduleObjs, moduleObjs),
- totalObjectClasses: dictDiff(last.totalObjectClasses,
- data.totalObjectClasses)
- };
-
- for (let name in diff.moduleObjs)
- print(" " + diff.moduleObjs[name] + " in " + name + "\n");
- for (let name in diff.totalObjectClasses)
- print(" " + diff.totalObjectClasses[name] + " instances of " +
- name + "\n");
- }
- lastMemoryUsage = JSON.stringify(
- {moduleObjs: moduleObjs,
- totalObjectClasses: data.totalObjectClasses}
- );
-}
-
-function dictDiff(last, curr) {
- var diff = {};
-
- for (let name in last) {
- var result = (curr[name] || 0) - last[name];
- if (result)
- diff[name] = (result > 0 ? "+" : "") + result;
- }
- for (let name in curr) {
- var result = curr[name] - (last[name] || 0);
- if (result)
- diff[name] = (result > 0 ? "+" : "") + result;
- }
- return diff;
-}
-
-function reportMemoryUsage() {
- memory.gc();
-
- var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
- .getService(Ci.nsIMemoryReporterManager);
- var reporters = mgr.enumerateReporters();
- if (reporters.hasMoreElements())
- print("\n");
- while (reporters.hasMoreElements()) {
- var reporter = reporters.getNext();
- reporter.QueryInterface(Ci.nsIMemoryReporter);
- print(reporter.description + ": " + reporter.memoryUsed + "\n");
- }
-
- var weakrefs = [info.weakref.get()
- for each (info in memory.getObjects())];
- weakrefs = [weakref for each (weakref in weakrefs) if (weakref)];
- print("Tracked memory objects in testing sandbox: " +
- weakrefs.length + "\n");
-}
-
-var gWeakrefInfo;
-
-function showResults() {
- memory.gc();
-
- if (gWeakrefInfo) {
- gWeakrefInfo.forEach(
- function(info) {
- var ref = info.weakref.get();
- if (ref !== null) {
- var data = ref.__url__ ? ref.__url__ : ref;
- var warning = data == "[object Object]"
- ? "[object " + data.constructor.name + "(" +
- [p for (p in data)].join(", ") + ")]"
- : data;
- console.warn("LEAK", warning, info.bin);
- }
- }
- );
- }
-
- onDone(results);
-}
-
-function cleanup() {
- try {
- for (let name in loader.modules)
- memory.track(loader.modules[name],
- "module global scope: " + name);
- memory.track(loader, "Cuddlefish Loader");
-
- if (profileMemory) {
- gWeakrefInfo = [{ weakref: info.weakref, bin: info.bin }
- for each (info in memory.getObjects())];
- }
-
- loader.unload();
-
- if (loader.globals.console.errorsLogged && !results.failed) {
- results.failed++;
- console.error("warnings and/or errors were logged.");
- }
-
- if (consoleListener.errorsLogged && !results.failed) {
- console.warn(consoleListener.errorsLogged + " " +
- "warnings or errors were logged to the " +
- "platform's nsIConsoleService, which could " +
- "be of no consequence; however, they could also " +
- "be indicative of aberrant behavior.");
- }
-
- consoleListener.errorsLogged = 0;
- loader = null;
-
- memory.gc();
- } catch (e) {
- results.failed++;
- console.error("unload.send() threw an exception.");
- console.exception(e);
- };
-
- setTimeout(showResults, 1);
-}
-
-function nextIteration(tests) {
- if (tests) {
- results.passed += tests.passed;
- results.failed += tests.failed;
-
- if (profileMemory)
- reportMemoryUsage();
-
- let testRun = [];
- for each (let test in tests.testRunSummary) {
- let testCopy = {};
- for (let info in test) {
- testCopy[info] = test[info];
- }
- testRun.push(testCopy);
- }
-
- results.testRuns.push(testRun);
- iterationsLeft--;
- }
-
- if (iterationsLeft && (!stopOnError || results.failed == 0)) {
- // Pass the loader which has a hooked console that doesn't dispatch
- // errors to the JS console and avoid firing false alarm in our
- // console listener
- findAndRunTests(loader, nextIteration);
- }
- else {
- setTimeout(cleanup, 0);
- }
-}
-
-var POINTLESS_ERRORS = [
- 'Invalid chrome URI:',
- 'OpenGL LayerManager Initialized Succesfully.',
- '[JavaScript Error: "TelemetryStopwatch:',
- '[JavaScript Warning: "ReferenceErrorL reference to undefined property',
- '[Javascript Warning: "Error: Failed to preserve wrapper of wrapped ' +
- 'native weak map key',
- '[JavaScript Warning: "Duplicate resource declaration for'
-];
-
-var consoleListener = {
- errorsLogged: 0,
- observe: function(object) {
- if (!(object instanceof Ci.nsIScriptError))
- return;
- this.errorsLogged++;
- var message = object.QueryInterface(Ci.nsIConsoleMessage).message;
- var pointless = [err for each (err in POINTLESS_ERRORS)
- if (message.indexOf(err) == 0)];
- if (pointless.length == 0 && message)
- print("console: " + message + "\n");
- }
-};
-
-function TestRunnerConsole(base, options) {
- this.__proto__ = {
- errorsLogged: 0,
- warn: function warn() {
- this.errorsLogged++;
- base.warn.apply(base, arguments);
- },
- error: function error() {
- this.errorsLogged++;
- base.error.apply(base, arguments);
- },
- info: function info(first) {
- if (options.verbose)
- base.info.apply(base, arguments);
- else
- if (first == "pass:")
- print(".");
- },
- __proto__: base
- };
-}
-
-var runTests = exports.runTests = function runTests(options) {
- iterationsLeft = options.iterations;
- profileMemory = options.profileMemory;
- stopOnError = options.stopOnError;
- onDone = options.onDone;
- print = options.print;
- findAndRunTests = options.findAndRunTests;
-
- try {
- cService.registerListener(consoleListener);
- print("Running tests on " + system.name + " " + system.version +
- "/Gecko " + system.platformVersion + " (" +
- system.id + ") under " +
- system.platform + "/" + system.architecture + ".\n");
-
-
- loader = Loader(module, {
- console: new TestRunnerConsole(new PlainTextConsole(print), options)
- });
-
- nextIteration();
- } catch (e) {
- print(format(e) + "\n" + e + "\n");
- onDone({passed: 0, failed: 1});
- }
-};
-
-unload(function() {
- cService.unregisterListener(consoleListener);
-});
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/test/httpd.js b/tools/addon-sdk-1.12/lib/sdk/test/httpd.js
deleted file mode 100644
index 48d3516..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/test/httpd.js
+++ /dev/null
@@ -1,5174 +0,0 @@
-/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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/. */
-
-/*
-* An implementation of an HTTP server both as a loadable script and as an XPCOM
-* component. See the accompanying README file for user documentation on
-* httpd.js.
-*/
-
-module.metadata = {
- "stability": "experimental"
-};
-
-const { components, CC, Cc, Ci, Cr, Cu } = require("chrome");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-
-const PR_UINT32_MAX = Math.pow(2, 32) - 1;
-
-/** True if debugging output is enabled, false otherwise. */
-var DEBUG = false; // non-const *only* so tweakable in server tests
-
-/** True if debugging output should be timestamped. */
-var DEBUG_TIMESTAMP = false; // non-const so tweakable in server tests
-
-var gGlobalObject = Cc["@mozilla.org/systemprincipal;1"].createInstance();
-
-/**
-* Asserts that the given condition holds. If it doesn't, the given message is
-* dumped, a stack trace is printed, and an exception is thrown to attempt to
-* stop execution (which unfortunately must rely upon the exception not being
-* accidentally swallowed by the code that uses it).
-*/
-function NS_ASSERT(cond, msg)
-{
- if (DEBUG && !cond)
- {
- dumpn("###!!!");
- dumpn("###!!! ASSERTION" + (msg ? ": " + msg : "!"));
- dumpn("###!!! Stack follows:");
-
- var stack = new Error().stack.split(/\n/);
- dumpn(stack.map(function(val) { return "###!!! " + val; }).join("\n"));
-
- throw Cr.NS_ERROR_ABORT;
- }
-}
-
-/** Constructs an HTTP error object. */
-function HttpError(code, description)
-{
- this.code = code;
- this.description = description;
-}
-HttpError.prototype =
-{
- toString: function()
- {
- return this.code + " " + this.description;
- }
-};
-
-/**
-* Errors thrown to trigger specific HTTP server responses.
-*/
-const HTTP_400 = new HttpError(400, "Bad Request");
-const HTTP_401 = new HttpError(401, "Unauthorized");
-const HTTP_402 = new HttpError(402, "Payment Required");
-const HTTP_403 = new HttpError(403, "Forbidden");
-const HTTP_404 = new HttpError(404, "Not Found");
-const HTTP_405 = new HttpError(405, "Method Not Allowed");
-const HTTP_406 = new HttpError(406, "Not Acceptable");
-const HTTP_407 = new HttpError(407, "Proxy Authentication Required");
-const HTTP_408 = new HttpError(408, "Request Timeout");
-const HTTP_409 = new HttpError(409, "Conflict");
-const HTTP_410 = new HttpError(410, "Gone");
-const HTTP_411 = new HttpError(411, "Length Required");
-const HTTP_412 = new HttpError(412, "Precondition Failed");
-const HTTP_413 = new HttpError(413, "Request Entity Too Large");
-const HTTP_414 = new HttpError(414, "Request-URI Too Long");
-const HTTP_415 = new HttpError(415, "Unsupported Media Type");
-const HTTP_417 = new HttpError(417, "Expectation Failed");
-
-const HTTP_500 = new HttpError(500, "Internal Server Error");
-const HTTP_501 = new HttpError(501, "Not Implemented");
-const HTTP_502 = new HttpError(502, "Bad Gateway");
-const HTTP_503 = new HttpError(503, "Service Unavailable");
-const HTTP_504 = new HttpError(504, "Gateway Timeout");
-const HTTP_505 = new HttpError(505, "HTTP Version Not Supported");
-
-/** Creates a hash with fields corresponding to the values in arr. */
-function array2obj(arr)
-{
- var obj = {};
- for (var i = 0; i < arr.length; i++)
- obj[arr[i]] = arr[i];
- return obj;
-}
-
-/** Returns an array of the integers x through y, inclusive. */
-function range(x, y)
-{
- var arr = [];
- for (var i = x; i <= y; i++)
- arr.push(i);
- return arr;
-}
-
-/** An object (hash) whose fields are the numbers of all HTTP error codes. */
-const HTTP_ERROR_CODES = array2obj(range(400, 417).concat(range(500, 505)));
-
-
-/**
-* The character used to distinguish hidden files from non-hidden files, a la
-* the leading dot in Apache. Since that mechanism also hides files from
-* easy display in LXR, ls output, etc. however, we choose instead to use a
-* suffix character. If a requested file ends with it, we append another
-* when getting the file on the server. If it doesn't, we just look up that
-* file. Therefore, any file whose name ends with exactly one of the character
-* is "hidden" and available for use by the server.
-*/
-const HIDDEN_CHAR = "^";
-
-/**
-* The file name suffix indicating the file containing overridden headers for
-* a requested file.
-*/
-const HEADERS_SUFFIX = HIDDEN_CHAR + "headers" + HIDDEN_CHAR;
-
-/** Type used to denote SJS scripts for CGI-like functionality. */
-const SJS_TYPE = "sjs";
-
-/** Base for relative timestamps produced by dumpn(). */
-var firstStamp = 0;
-
-/** dump(str) with a trailing "\n" -- only outputs if DEBUG. */
-function dumpn(str)
-{
- if (DEBUG)
- {
- var prefix = "HTTPD-INFO | ";
- if (DEBUG_TIMESTAMP)
- {
- if (firstStamp === 0)
- firstStamp = Date.now();
-
- var elapsed = Date.now() - firstStamp; // milliseconds
- var min = Math.floor(elapsed / 60000);
- var sec = (elapsed % 60000) / 1000;
-
- if (sec < 10)
- prefix += min + ":0" + sec.toFixed(3) + " | ";
- else
- prefix += min + ":" + sec.toFixed(3) + " | ";
- }
-
- dump(prefix + str + "\n");
- }
-}
-
-/** Dumps the current JS stack if DEBUG. */
-function dumpStack()
-{
- // peel off the frames for dumpStack() and Error()
- var stack = new Error().stack.split(/\n/).slice(2);
- stack.forEach(dumpn);
-}
-
-
-/** The XPCOM thread manager. */
-var gThreadManager = null;
-
-/** The XPCOM prefs service. */
-var gRootPrefBranch = null;
-function getRootPrefBranch()
-{
- if (!gRootPrefBranch)
- {
- gRootPrefBranch = Cc["@mozilla.org/preferences-service;1"]
- .getService(Ci.nsIPrefBranch);
- }
- return gRootPrefBranch;
-}
-
-/**
-* JavaScript constructors for commonly-used classes; precreating these is a
-* speedup over doing the same from base principles. See the docs at
-* http://developer.mozilla.org/en/docs/components.Constructor for details.
-*/
-const ServerSocket = CC("@mozilla.org/network/server-socket;1",
- "nsIServerSocket",
- "init");
-const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
- "nsIScriptableInputStream",
- "init");
-const Pipe = CC("@mozilla.org/pipe;1",
- "nsIPipe",
- "init");
-const FileInputStream = CC("@mozilla.org/network/file-input-stream;1",
- "nsIFileInputStream",
- "init");
-const ConverterInputStream = CC("@mozilla.org/intl/converter-input-stream;1",
- "nsIConverterInputStream",
- "init");
-const WritablePropertyBag = CC("@mozilla.org/hash-property-bag;1",
- "nsIWritablePropertyBag2");
-const SupportsString = CC("@mozilla.org/supports-string;1",
- "nsISupportsString");
-
-/* These two are non-const only so a test can overwrite them. */
-var BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream",
- "setInputStream");
-var BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1",
- "nsIBinaryOutputStream",
- "setOutputStream");
-
-/**
-* Returns the RFC 822/1123 representation of a date.
-*
-* @param date : Number
-* the date, in milliseconds from midnight (00:00:00), January 1, 1970 GMT
-* @returns string
-* the representation of the given date
-*/
-function toDateString(date)
-{
- //
- // rfc1123-date = wkday "," SP date1 SP time SP "GMT"
- // date1 = 2DIGIT SP month SP 4DIGIT
- // ; day month year (e.g., 02 Jun 1982)
- // time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
- // ; 00:00:00 - 23:59:59
- // wkday = "Mon" | "Tue" | "Wed"
- // | "Thu" | "Fri" | "Sat" | "Sun"
- // month = "Jan" | "Feb" | "Mar" | "Apr"
- // | "May" | "Jun" | "Jul" | "Aug"
- // | "Sep" | "Oct" | "Nov" | "Dec"
- //
-
- const wkdayStrings = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
- const monthStrings = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
-
- /**
-* Processes a date and returns the encoded UTC time as a string according to
-* the format specified in RFC 2616.
-*
-* @param date : Date
-* the date to process
-* @returns string
-* a string of the form "HH:MM:SS", ranging from "00:00:00" to "23:59:59"
-*/
- function toTime(date)
- {
- var hrs = date.getUTCHours();
- var rv = (hrs < 10) ? "0" + hrs : hrs;
-
- var mins = date.getUTCMinutes();
- rv += ":";
- rv += (mins < 10) ? "0" + mins : mins;
-
- var secs = date.getUTCSeconds();
- rv += ":";
- rv += (secs < 10) ? "0" + secs : secs;
-
- return rv;
- }
-
- /**
-* Processes a date and returns the encoded UTC date as a string according to
-* the date1 format specified in RFC 2616.
-*
-* @param date : Date
-* the date to process
-* @returns string
-* a string of the form "HH:MM:SS", ranging from "00:00:00" to "23:59:59"
-*/
- function toDate1(date)
- {
- var day = date.getUTCDate();
- var month = date.getUTCMonth();
- var year = date.getUTCFullYear();
-
- var rv = (day < 10) ? "0" + day : day;
- rv += " " + monthStrings[month];
- rv += " " + year;
-
- return rv;
- }
-
- date = new Date(date);
-
- const fmtString = "%wkday%, %date1% %time% GMT";
- var rv = fmtString.replace("%wkday%", wkdayStrings[date.getUTCDay()]);
- rv = rv.replace("%time%", toTime(date));
- return rv.replace("%date1%", toDate1(date));
-}
-
-/**
-* Prints out a human-readable representation of the object o and its fields,
-* omitting those whose names begin with "_" if showMembers != true (to ignore
-* "private" properties exposed via getters/setters).
-*/
-function printObj(o, showMembers)
-{
- var s = "******************************\n";
- s += "o = {\n";
- for (var i in o)
- {
- if (typeof(i) != "string" ||
- (showMembers || (i.length > 0 && i[0] != "_")))
- s+= " " + i + ": " + o[i] + ",\n";
- }
- s += " };\n";
- s += "******************************";
- dumpn(s);
-}
-
-/**
-* Instantiates a new HTTP server.
-*/
-function nsHttpServer()
-{
- if (!gThreadManager)
- gThreadManager = Cc["@mozilla.org/thread-manager;1"].getService();
-
- /** The port on which this server listens. */
- this._port = undefined;
-
- /** The socket associated with this. */
- this._socket = null;
-
- /** The handler used to process requests to this server. */
- this._handler = new ServerHandler(this);
-
- /** Naming information for this server. */
- this._identity = new ServerIdentity();
-
- /**
-* Indicates when the server is to be shut down at the end of the request.
-*/
- this._doQuit = false;
-
- /**
-* True if the socket in this is closed (and closure notifications have been
-* sent and processed if the socket was ever opened), false otherwise.
-*/
- this._socketClosed = true;
-
- /**
-* Used for tracking existing connections and ensuring that all connections
-* are properly cleaned up before server shutdown; increases by 1 for every
-* new incoming connection.
-*/
- this._connectionGen = 0;
-
- /**
-* Hash of all open connections, indexed by connection number at time of
-* creation.
-*/
- this._connections = {};
-}
-nsHttpServer.prototype =
-{
- classID: components.ID("{54ef6f81-30af-4b1d-ac55-8ba811293e41}"),
-
- // NSISERVERSOCKETLISTENER
-
- /**
-* Processes an incoming request coming in on the given socket and contained
-* in the given transport.
-*
-* @param socket : nsIServerSocket
-* the socket through which the request was served
-* @param trans : nsISocketTransport
-* the transport for the request/response
-* @see nsIServerSocketListener.onSocketAccepted
-*/
- onSocketAccepted: function(socket, trans)
- {
- dumpn("*** onSocketAccepted(socket=" + socket + ", trans=" + trans + ")");
-
- dumpn(">>> new connection on " + trans.host + ":" + trans.port);
-
- const SEGMENT_SIZE = 8192;
- const SEGMENT_COUNT = 1024;
- try
- {
- var input = trans.openInputStream(0, SEGMENT_SIZE, SEGMENT_COUNT)
- .QueryInterface(Ci.nsIAsyncInputStream);
- var output = trans.openOutputStream(0, 0, 0);
- }
- catch (e)
- {
- dumpn("*** error opening transport streams: " + e);
- trans.close(Cr.NS_BINDING_ABORTED);
- return;
- }
-
- var connectionNumber = ++this._connectionGen;
-
- try
- {
- var conn = new Connection(input, output, this, socket.port, trans.port,
- connectionNumber);
- var reader = new RequestReader(conn);
-
- // XXX add request timeout functionality here!
-
- // Note: must use main thread here, or we might get a GC that will cause
- // threadsafety assertions. We really need to fix XPConnect so that
- // you can actually do things in multi-threaded JS. :-(
- input.asyncWait(reader, 0, 0, gThreadManager.mainThread);
- }
- catch (e)
- {
- // Assume this connection can't be salvaged and bail on it completely;
- // don't attempt to close it so that we can assert that any connection
- // being closed is in this._connections.
- dumpn("*** error in initial request-processing stages: " + e);
- trans.close(Cr.NS_BINDING_ABORTED);
- return;
- }
-
- this._connections[connectionNumber] = conn;
- dumpn("*** starting connection " + connectionNumber);
- },
-
- /**
-* Called when the socket associated with this is closed.
-*
-* @param socket : nsIServerSocket
-* the socket being closed
-* @param status : nsresult
-* the reason the socket stopped listening (NS_BINDING_ABORTED if the server
-* was stopped using nsIHttpServer.stop)
-* @see nsIServerSocketListener.onStopListening
-*/
- onStopListening: function(socket, status)
- {
- dumpn(">>> shutting down server on port " + socket.port);
- this._socketClosed = true;
- if (!this._hasOpenConnections())
- {
- dumpn("*** no open connections, notifying async from onStopListening");
-
- // Notify asynchronously so that any pending teardown in stop() has a
- // chance to run first.
- var self = this;
- var stopEvent =
- {
- run: function()
- {
- dumpn("*** _notifyStopped async callback");
- self._notifyStopped();
- }
- };
- gThreadManager.currentThread
- .dispatch(stopEvent, Ci.nsIThread.DISPATCH_NORMAL);
- }
- },
-
- // NSIHTTPSERVER
-
- //
- // see nsIHttpServer.start
- //
- start: function(port)
- {
- this._start(port, "localhost")
- },
-
- _start: function(port, host)
- {
- if (this._socket)
- throw Cr.NS_ERROR_ALREADY_INITIALIZED;
-
- this._port = port;
- this._doQuit = this._socketClosed = false;
-
- this._host = host;
-
- // The listen queue needs to be long enough to handle
- // network.http.max-persistent-connections-per-server concurrent connections,
- // plus a safety margin in case some other process is talking to
- // the server as well.
- var prefs = getRootPrefBranch();
- var maxConnections;
- try {
- // Bug 776860: The original pref was removed in favor of this new one:
- maxConnections = prefs.getIntPref("network.http.max-persistent-connections-per-server") + 5;
- }
- catch(e) {
- maxConnections = prefs.getIntPref("network.http.max-connections-per-server") + 5;
- }
-
- try
- {
- var loopback = true;
- if (this._host != "127.0.0.1" && this._host != "localhost") {
- var loopback = false;
- }
-
- var socket = new ServerSocket(this._port,
- loopback, // true = localhost, false = everybody
- maxConnections);
- dumpn(">>> listening on port " + socket.port + ", " + maxConnections +
- " pending connections");
- socket.asyncListen(this);
- this._identity._initialize(port, host, true);
- this._socket = socket;
- }
- catch (e)
- {
- dumpn("!!! could not start server on port " + port + ": " + e);
- throw Cr.NS_ERROR_NOT_AVAILABLE;
- }
- },
-
- //
- // see nsIHttpServer.stop
- //
- stop: function(callback)
- {
- if (!callback)
- throw Cr.NS_ERROR_NULL_POINTER;
- if (!this._socket)
- throw Cr.NS_ERROR_UNEXPECTED;
-
- this._stopCallback = typeof callback === "function"
- ? callback
- : function() { callback.onStopped(); };
-
- dumpn(">>> stopping listening on port " + this._socket.port);
- this._socket.close();
- this._socket = null;
-
- // We can't have this identity any more, and the port on which we're running
- // this server now could be meaningless the next time around.
- this._identity._teardown();
-
- this._doQuit = false;
-
- // socket-close notification and pending request completion happen async
- },
-
- //
- // see nsIHttpServer.registerFile
- //
- registerFile: function(path, file)
- {
- if (file && (!file.exists() || file.isDirectory()))
- throw Cr.NS_ERROR_INVALID_ARG;
-
- this._handler.registerFile(path, file);
- },
-
- //
- // see nsIHttpServer.registerDirectory
- //
- registerDirectory: function(path, directory)
- {
- // XXX true path validation!
- if (path.charAt(0) != "/" ||
- path.charAt(path.length - 1) != "/" ||
- (directory &&
- (!directory.exists() || !directory.isDirectory())))
- throw Cr.NS_ERROR_INVALID_ARG;
-
- // XXX determine behavior of nonexistent /foo/bar when a /foo/bar/ mapping
- // exists!
-
- this._handler.registerDirectory(path, directory);
- },
-
- //
- // see nsIHttpServer.registerPathHandler
- //
- registerPathHandler: function(path, handler)
- {
- this._handler.registerPathHandler(path, handler);
- },
-
- //
- // see nsIHttpServer.registerErrorHandler
- //
- registerErrorHandler: function(code, handler)
- {
- this._handler.registerErrorHandler(code, handler);
- },
-
- //
- // see nsIHttpServer.setIndexHandler
- //
- setIndexHandler: function(handler)
- {
- this._handler.setIndexHandler(handler);
- },
-
- //
- // see nsIHttpServer.registerContentType
- //
- registerContentType: function(ext, type)
- {
- this._handler.registerContentType(ext, type);
- },
-
- //
- // see nsIHttpServer.serverIdentity
- //
- get identity()
- {
- return this._identity;
- },
-
- //
- // see nsIHttpServer.getState
- //
- getState: function(path, k)
- {
- return this._handler._getState(path, k);
- },
-
- //
- // see nsIHttpServer.setState
- //
- setState: function(path, k, v)
- {
- return this._handler._setState(path, k, v);
- },
-
- //
- // see nsIHttpServer.getSharedState
- //
- getSharedState: function(k)
- {
- return this._handler._getSharedState(k);
- },
-
- //
- // see nsIHttpServer.setSharedState
- //
- setSharedState: function(k, v)
- {
- return this._handler._setSharedState(k, v);
- },
-
- //
- // see nsIHttpServer.getObjectState
- //
- getObjectState: function(k)
- {
- return this._handler._getObjectState(k);
- },
-
- //
- // see nsIHttpServer.setObjectState
- //
- setObjectState: function(k, v)
- {
- return this._handler._setObjectState(k, v);
- },
-
-
- // NSISUPPORTS
-
- //
- // see nsISupports.QueryInterface
- //
- QueryInterface: function(iid)
- {
- if (iid.equals(Ci.nsIServerSocketListener) || iid.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
-
- // NON-XPCOM PUBLIC API
-
- /**
-* Returns true iff this server is not running (and is not in the process of
-* serving any requests still to be processed when the server was last
-* stopped after being run).
-*/
- isStopped: function()
- {
- return this._socketClosed && !this._hasOpenConnections();
- },
-
- // PRIVATE IMPLEMENTATION
-
- /** True if this server has any open connections to it, false otherwise. */
- _hasOpenConnections: function()
- {
- //
- // If we have any open connections, they're tracked as numeric properties on
- // |this._connections|. The non-standard __count__ property could be used
- // to check whether there are any properties, but standard-wise, even
- // looking forward to ES5, there's no less ugly yet still O(1) way to do
- // this.
- //
- for (var n in this._connections)
- return true;
- return false;
- },
-
- /** Calls the server-stopped callback provided when stop() was called. */
- _notifyStopped: function()
- {
- NS_ASSERT(this._stopCallback !== null, "double-notifying?");
- NS_ASSERT(!this._hasOpenConnections(), "should be done serving by now");
-
- //
- // NB: We have to grab this now, null out the member, *then* call the
- // callback here, or otherwise the callback could (indirectly) futz with
- // this._stopCallback by starting and immediately stopping this, at
- // which point we'd be nulling out a field we no longer have a right to
- // modify.
- //
- var callback = this._stopCallback;
- this._stopCallback = null;
- try
- {
- callback();
- }
- catch (e)
- {
- // not throwing because this is specified as being usually (but not
- // always) asynchronous
- dump("!!! error running onStopped callback: " + e + "\n");
- }
- },
-
- /**
-* Notifies this server that the given connection has been closed.
-*
-* @param connection : Connection
-* the connection that was closed
-*/
- _connectionClosed: function(connection)
- {
- NS_ASSERT(connection.number in this._connections,
- "closing a connection " + this + " that we never added to the " +
- "set of open connections?");
- NS_ASSERT(this._connections[connection.number] === connection,
- "connection number mismatch? " +
- this._connections[connection.number]);
- delete this._connections[connection.number];
-
- // Fire a pending server-stopped notification if it's our responsibility.
- if (!this._hasOpenConnections() && this._socketClosed)
- this._notifyStopped();
- },
-
- /**
-* Requests that the server be shut down when possible.
-*/
- _requestQuit: function()
- {
- dumpn(">>> requesting a quit");
- dumpStack();
- this._doQuit = true;
- }
-};
-
-
-//
-// RFC 2396 section 3.2.2:
-//
-// host = hostname | IPv4address
-// hostname = *( domainlabel "." ) toplabel [ "." ]
-// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
-// toplabel = alpha | alpha *( alphanum | "-" ) alphanum
-// IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
-//
-
-const HOST_REGEX =
- new RegExp("^(?:" +
- // *( domainlabel "." )
- "(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)*" +
- // toplabel
- "[a-z](?:[a-z0-9-]*[a-z0-9])?" +
- "|" +
- // IPv4 address
- "\\d+\\.\\d+\\.\\d+\\.\\d+" +
- ")$",
- "i");
-
-
-/**
-* Represents the identity of a server. An identity consists of a set of
-* (scheme, host, port) tuples denoted as locations (allowing a single server to
-* serve multiple sites or to be used behind both HTTP and HTTPS proxies for any
-* host/port). Any incoming request must be to one of these locations, or it
-* will be rejected with an HTTP 400 error. One location, denoted as the
-* primary location, is the location assigned in contexts where a location
-* cannot otherwise be endogenously derived, such as for HTTP/1.0 requests.
-*
-* A single identity may contain at most one location per unique host/port pair;
-* other than that, no restrictions are placed upon what locations may
-* constitute an identity.
-*/
-function ServerIdentity()
-{
- /** The scheme of the primary location. */
- this._primaryScheme = "http";
-
- /** The hostname of the primary location. */
- this._primaryHost = "127.0.0.1"
-
- /** The port number of the primary location. */
- this._primaryPort = -1;
-
- /**
-* The current port number for the corresponding server, stored so that a new
-* primary location can always be set if the current one is removed.
-*/
- this._defaultPort = -1;
-
- /**
-* Maps hosts to maps of ports to schemes, e.g. the following would represent
-* https://example.com:789/ and http://example.org/:
-*
-* {
-* "xexample.com": { 789: "https" },
-* "xexample.org": { 80: "http" }
-* }
-*
-* Note the "x" prefix on hostnames, which prevents collisions with special
-* JS names like "prototype".
-*/
- this._locations = { "xlocalhost": {} };
-}
-ServerIdentity.prototype =
-{
- // NSIHTTPSERVERIDENTITY
-
- //
- // see nsIHttpServerIdentity.primaryScheme
- //
- get primaryScheme()
- {
- if (this._primaryPort === -1)
- throw Cr.NS_ERROR_NOT_INITIALIZED;
- return this._primaryScheme;
- },
-
- //
- // see nsIHttpServerIdentity.primaryHost
- //
- get primaryHost()
- {
- if (this._primaryPort === -1)
- throw Cr.NS_ERROR_NOT_INITIALIZED;
- return this._primaryHost;
- },
-
- //
- // see nsIHttpServerIdentity.primaryPort
- //
- get primaryPort()
- {
- if (this._primaryPort === -1)
- throw Cr.NS_ERROR_NOT_INITIALIZED;
- return this._primaryPort;
- },
-
- //
- // see nsIHttpServerIdentity.add
- //
- add: function(scheme, host, port)
- {
- this._validate(scheme, host, port);
-
- var entry = this._locations["x" + host];
- if (!entry)
- this._locations["x" + host] = entry = {};
-
- entry[port] = scheme;
- },
-
- //
- // see nsIHttpServerIdentity.remove
- //
- remove: function(scheme, host, port)
- {
- this._validate(scheme, host, port);
-
- var entry = this._locations["x" + host];
- if (!entry)
- return false;
-
- var present = port in entry;
- delete entry[port];
-
- if (this._primaryScheme == scheme &&
- this._primaryHost == host &&
- this._primaryPort == port &&
- this._defaultPort !== -1)
- {
- // Always keep at least one identity in existence at any time, unless
- // we're in the process of shutting down (the last condition above).
- this._primaryPort = -1;
- this._initialize(this._defaultPort, host, false);
- }
-
- return present;
- },
-
- //
- // see nsIHttpServerIdentity.has
- //
- has: function(scheme, host, port)
- {
- this._validate(scheme, host, port);
-
- return "x" + host in this._locations &&
- scheme === this._locations["x" + host][port];
- },
-
- //
- // see nsIHttpServerIdentity.has
- //
- getScheme: function(host, port)
- {
- this._validate("http", host, port);
-
- var entry = this._locations["x" + host];
- if (!entry)
- return "";
-
- return entry[port] || "";
- },
-
- //
- // see nsIHttpServerIdentity.setPrimary
- //
- setPrimary: function(scheme, host, port)
- {
- this._validate(scheme, host, port);
-
- this.add(scheme, host, port);
-
- this._primaryScheme = scheme;
- this._primaryHost = host;
- this._primaryPort = port;
- },
-
-
- // NSISUPPORTS
-
- //
- // see nsISupports.QueryInterface
- //
- QueryInterface: function(iid)
- {
- if (iid.equals(Ci.nsIHttpServerIdentity) || iid.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
-
- // PRIVATE IMPLEMENTATION
-
- /**
-* Initializes the primary name for the corresponding server, based on the
-* provided port number.
-*/
- _initialize: function(port, host, addSecondaryDefault)
- {
- this._host = host;
- if (this._primaryPort !== -1)
- this.add("http", host, port);
- else
- this.setPrimary("http", "localhost", port);
- this._defaultPort = port;
-
- // Only add this if we're being called at server startup
- if (addSecondaryDefault && host != "127.0.0.1")
- this.add("http", "127.0.0.1", port);
- },
-
- /**
-* Called at server shutdown time, unsets the primary location only if it was
-* the default-assigned location and removes the default location from the
-* set of locations used.
-*/
- _teardown: function()
- {
- if (this._host != "127.0.0.1") {
- // Not the default primary location, nothing special to do here
- this.remove("http", "127.0.0.1", this._defaultPort);
- }
-
- // This is a *very* tricky bit of reasoning here; make absolutely sure the
- // tests for this code pass before you commit changes to it.
- if (this._primaryScheme == "http" &&
- this._primaryHost == this._host &&
- this._primaryPort == this._defaultPort)
- {
- // Make sure we don't trigger the readding logic in .remove(), then remove
- // the default location.
- var port = this._defaultPort;
- this._defaultPort = -1;
- this.remove("http", this._host, port);
-
- // Ensure a server start triggers the setPrimary() path in ._initialize()
- this._primaryPort = -1;
- }
- else
- {
- // No reason not to remove directly as it's not our primary location
- this.remove("http", this._host, this._defaultPort);
- }
- },
-
- /**
-* Ensures scheme, host, and port are all valid with respect to RFC 2396.
-*
-* @throws NS_ERROR_ILLEGAL_VALUE
-* if any argument doesn't match the corresponding production
-*/
- _validate: function(scheme, host, port)
- {
- if (scheme !== "http" && scheme !== "https")
- {
- dumpn("*** server only supports http/https schemes: '" + scheme + "'");
- dumpStack();
- throw Cr.NS_ERROR_ILLEGAL_VALUE;
- }
- if (!HOST_REGEX.test(host))
- {
- dumpn("*** unexpected host: '" + host + "'");
- throw Cr.NS_ERROR_ILLEGAL_VALUE;
- }
- if (port < 0 || port > 65535)
- {
- dumpn("*** unexpected port: '" + port + "'");
- throw Cr.NS_ERROR_ILLEGAL_VALUE;
- }
- }
-};
-
-
-/**
-* Represents a connection to the server (and possibly in the future the thread
-* on which the connection is processed).
-*
-* @param input : nsIInputStream
-* stream from which incoming data on the connection is read
-* @param output : nsIOutputStream
-* stream to write data out the connection
-* @param server : nsHttpServer
-* the server handling the connection
-* @param port : int
-* the port on which the server is running
-* @param outgoingPort : int
-* the outgoing port used by this connection
-* @param number : uint
-* a serial number used to uniquely identify this connection
-*/
-function Connection(input, output, server, port, outgoingPort, number)
-{
- dumpn("*** opening new connection " + number + " on port " + outgoingPort);
-
- /** Stream of incoming data. */
- this.input = input;
-
- /** Stream for outgoing data. */
- this.output = output;
-
- /** The server associated with this request. */
- this.server = server;
-
- /** The port on which the server is running. */
- this.port = port;
-
- /** The outgoing poort used by this connection. */
- this._outgoingPort = outgoingPort;
-
- /** The serial number of this connection. */
- this.number = number;
-
- /**
-* The request for which a response is being generated, null if the
-* incoming request has not been fully received or if it had errors.
-*/
- this.request = null;
-
- /** State variables for debugging. */
- this._closed = this._processed = false;
-}
-Connection.prototype =
-{
- /** Closes this connection's input/output streams. */
- close: function()
- {
- dumpn("*** closing connection " + this.number +
- " on port " + this._outgoingPort);
-
- this.input.close();
- this.output.close();
- this._closed = true;
-
- var server = this.server;
- server._connectionClosed(this);
-
- // If an error triggered a server shutdown, act on it now
- if (server._doQuit)
- server.stop(function() { /* not like we can do anything better */ });
- },
-
- /**
-* Initiates processing of this connection, using the data in the given
-* request.
-*
-* @param request : Request
-* the request which should be processed
-*/
- process: function(request)
- {
- NS_ASSERT(!this._closed && !this._processed);
-
- this._processed = true;
-
- this.request = request;
- this.server._handler.handleResponse(this);
- },
-
- /**
-* Initiates processing of this connection, generating a response with the
-* given HTTP error code.
-*
-* @param code : uint
-* an HTTP code, so in the range [0, 1000)
-* @param request : Request
-* incomplete data about the incoming request (since there were errors
-* during its processing
-*/
- processError: function(code, request)
- {
- NS_ASSERT(!this._closed && !this._processed);
-
- this._processed = true;
- this.request = request;
- this.server._handler.handleError(code, this);
- },
-
- /** Converts this to a string for debugging purposes. */
- toString: function()
- {
- return "<Connection(" + this.number +
- (this.request ? ", " + this.request.path : "") +"): " +
- (this._closed ? "closed" : "open") + ">";
- }
-};
-
-
-
-/** Returns an array of count bytes from the given input stream. */
-function readBytes(inputStream, count)
-{
- return new BinaryInputStream(inputStream).readByteArray(count);
-}
-
-
-
-/** Request reader processing states; see RequestReader for details. */
-const READER_IN_REQUEST_LINE = 0;
-const READER_IN_HEADERS = 1;
-const READER_IN_BODY = 2;
-const READER_FINISHED = 3;
-
-
-/**
-* Reads incoming request data asynchronously, does any necessary preprocessing,
-* and forwards it to the request handler. Processing occurs in three states:
-*
-* READER_IN_REQUEST_LINE Reading the request's status line
-* READER_IN_HEADERS Reading headers in the request
-* READER_IN_BODY Reading the body of the request
-* READER_FINISHED Entire request has been read and processed
-*
-* During the first two stages, initial metadata about the request is gathered
-* into a Request object. Once the status line and headers have been processed,
-* we start processing the body of the request into the Request. Finally, when
-* the entire body has been read, we create a Response and hand it off to the
-* ServerHandler to be given to the appropriate request handler.
-*
-* @param connection : Connection
-* the connection for the request being read
-*/
-function RequestReader(connection)
-{
- /** Connection metadata for this request. */
- this._connection = connection;
-
- /**
-* A container providing line-by-line access to the raw bytes that make up the
-* data which has been read from the connection but has not yet been acted
-* upon (by passing it to the request handler or by extracting request
-* metadata from it).
-*/
- this._data = new LineData();
-
- /**
-* The amount of data remaining to be read from the body of this request.
-* After all headers in the request have been read this is the value in the
-* Content-Length header, but as the body is read its value decreases to zero.
-*/
- this._contentLength = 0;
-
- /** The current state of parsing the incoming request. */
- this._state = READER_IN_REQUEST_LINE;
-
- /** Metadata constructed from the incoming request for the request handler. */
- this._metadata = new Request(connection.port);
-
- /**
-* Used to preserve state if we run out of line data midway through a
-* multi-line header. _lastHeaderName stores the name of the header, while
-* _lastHeaderValue stores the value we've seen so far for the header.
-*
-* These fields are always either both undefined or both strings.
-*/
- this._lastHeaderName = this._lastHeaderValue = undefined;
-}
-RequestReader.prototype =
-{
- // NSIINPUTSTREAMCALLBACK
-
- /**
-* Called when more data from the incoming request is available. This method
-* then reads the available data from input and deals with that data as
-* necessary, depending upon the syntax of already-downloaded data.
-*
-* @param input : nsIAsyncInputStream
-* the stream of incoming data from the connection
-*/
- onInputStreamReady: function(input)
- {
- dumpn("*** onInputStreamReady(input=" + input + ") on thread " +
- gThreadManager.currentThread + " (main is " +
- gThreadManager.mainThread + ")");
- dumpn("*** this._state == " + this._state);
-
- // Handle cases where we get more data after a request error has been
- // discovered but *before* we can close the connection.
- var data = this._data;
- if (!data)
- return;
-
- try
- {
- data.appendBytes(readBytes(input, input.available()));
- }
- catch (e)
- {
- if (streamClosed(e))
- {
- dumpn("*** WARNING: unexpected error when reading from socket; will " +
- "be treated as if the input stream had been closed");
- dumpn("*** WARNING: actual error was: " + e);
- }
-
- // We've lost a race -- input has been closed, but we're still expecting
- // to read more data. available() will throw in this case, and since
- // we're dead in the water now, destroy the connection.
- dumpn("*** onInputStreamReady called on a closed input, destroying " +
- "connection");
- this._connection.close();
- return;
- }
-
- switch (this._state)
- {
- default:
- NS_ASSERT(false, "invalid state: " + this._state);
- break;
-
- case READER_IN_REQUEST_LINE:
- if (!this._processRequestLine())
- break;
- /* fall through */
-
- case READER_IN_HEADERS:
- if (!this._processHeaders())
- break;
- /* fall through */
-
- case READER_IN_BODY:
- this._processBody();
- }
-
- if (this._state != READER_FINISHED)
- input.asyncWait(this, 0, 0, gThreadManager.currentThread);
- },
-
- //
- // see nsISupports.QueryInterface
- //
- QueryInterface: function(aIID)
- {
- if (aIID.equals(Ci.nsIInputStreamCallback) ||
- aIID.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
-
- // PRIVATE API
-
- /**
-* Processes unprocessed, downloaded data as a request line.
-*
-* @returns boolean
-* true iff the request line has been fully processed
-*/
- _processRequestLine: function()
- {
- NS_ASSERT(this._state == READER_IN_REQUEST_LINE);
-
- // Servers SHOULD ignore any empty line(s) received where a Request-Line
- // is expected (section 4.1).
- var data = this._data;
- var line = {};
- var readSuccess;
- while ((readSuccess = data.readLine(line)) && line.value == "")
- dumpn("*** ignoring beginning blank line...");
-
- // if we don't have a full line, wait until we do
- if (!readSuccess)
- return false;
-
- // we have the first non-blank line
- try
- {
- this._parseRequestLine(line.value);
- this._state = READER_IN_HEADERS;
- return true;
- }
- catch (e)
- {
- this._handleError(e);
- return false;
- }
- },
-
- /**
-* Processes stored data, assuming it is either at the beginning or in
-* the middle of processing request headers.
-*
-* @returns boolean
-* true iff header data in the request has been fully processed
-*/
- _processHeaders: function()
- {
- NS_ASSERT(this._state == READER_IN_HEADERS);
-
- // XXX things to fix here:
- //
- // - need to support RFC 2047-encoded non-US-ASCII characters
-
- try
- {
- var done = this._parseHeaders();
- if (done)
- {
- var request = this._metadata;
-
- // XXX this is wrong for requests with transfer-encodings applied to
- // them, particularly chunked (which by its nature can have no
- // meaningful Content-Length header)!
- this._contentLength = request.hasHeader("Content-Length")
- ? parseInt(request.getHeader("Content-Length"), 10)
- : 0;
- dumpn("_processHeaders, Content-length=" + this._contentLength);
-
- this._state = READER_IN_BODY;
- }
- return done;
- }
- catch (e)
- {
- this._handleError(e);
- return false;
- }
- },
-
- /**
-* Processes stored data, assuming it is either at the beginning or in
-* the middle of processing the request body.
-*
-* @returns boolean
-* true iff the request body has been fully processed
-*/
- _processBody: function()
- {
- NS_ASSERT(this._state == READER_IN_BODY);
-
- // XXX handle chunked transfer-coding request bodies!
-
- try
- {
- if (this._contentLength > 0)
- {
- var data = this._data.purge();
- var count = Math.min(data.length, this._contentLength);
- dumpn("*** loading data=" + data + " len=" + data.length +
- " excess=" + (data.length - count));
-
- var bos = new BinaryOutputStream(this._metadata._bodyOutputStream);
- bos.writeByteArray(data, count);
- this._contentLength -= count;
- }
-
- dumpn("*** remaining body data len=" + this._contentLength);
- if (this._contentLength == 0)
- {
- this._validateRequest();
- this._state = READER_FINISHED;
- this._handleResponse();
- return true;
- }
-
- return false;
- }
- catch (e)
- {
- this._handleError(e);
- return false;
- }
- },
-
- /**
-* Does various post-header checks on the data in this request.
-*
-* @throws : HttpError
-* if the request was malformed in some way
-*/
- _validateRequest: function()
- {
- NS_ASSERT(this._state == READER_IN_BODY);
-
- dumpn("*** _validateRequest");
-
- var metadata = this._metadata;
- var headers = metadata._headers;
-
- // 19.6.1.1 -- servers MUST report 400 to HTTP/1.1 requests w/o Host header
- var identity = this._connection.server.identity;
- if (metadata._httpVersion.atLeast(nsHttpVersion.HTTP_1_1))
- {
- if (!headers.hasHeader("Host"))
- {
- dumpn("*** malformed HTTP/1.1 or greater request with no Host header!");
- throw HTTP_400;
- }
-
- // If the Request-URI wasn't absolute, then we need to determine our host.
- // We have to determine what scheme was used to access us based on the
- // server identity data at this point, because the request just doesn't
- // contain enough data on its own to do this, sadly.
- if (!metadata._host)
- {
- var host, port;
- var hostPort = headers.getHeader("Host");
- var colon = hostPort.indexOf(":");
- if (colon < 0)
- {
- host = hostPort;
- port = "";
- }
- else
- {
- host = hostPort.substring(0, colon);
- port = hostPort.substring(colon + 1);
- }
-
- // NB: We allow an empty port here because, oddly, a colon may be
- // present even without a port number, e.g. "example.com:"; in this
- // case the default port applies.
- if (!HOST_REGEX.test(host) || !/^\d*$/.test(port))
- {
- dumpn("*** malformed hostname (" + hostPort + ") in Host " +
- "header, 400 time");
- throw HTTP_400;
- }
-
- // If we're not given a port, we're stuck, because we don't know what
- // scheme to use to look up the correct port here, in general. Since
- // the HTTPS case requires a tunnel/proxy and thus requires that the
- // requested URI be absolute (and thus contain the necessary
- // information), let's assume HTTP will prevail and use that.
- port = +port || 80;
-
- var scheme = identity.getScheme(host, port);
- if (!scheme)
- {
- dumpn("*** unrecognized hostname (" + hostPort + ") in Host " +
- "header, 400 time");
- throw HTTP_400;
- }
-
- metadata._scheme = scheme;
- metadata._host = host;
- metadata._port = port;
- }
- }
- else
- {
- NS_ASSERT(metadata._host === undefined,
- "HTTP/1.0 doesn't allow absolute paths in the request line!");
-
- metadata._scheme = identity.primaryScheme;
- metadata._host = identity.primaryHost;
- metadata._port = identity.primaryPort;
- }
-
- NS_ASSERT(identity.has(metadata._scheme, metadata._host, metadata._port),
- "must have a location we recognize by now!");
- },
-
- /**
-* Handles responses in case of error, either in the server or in the request.
-*
-* @param e
-* the specific error encountered, which is an HttpError in the case where
-* the request is in some way invalid or cannot be fulfilled; if this isn't
-* an HttpError we're going to be paranoid and shut down, because that
-* shouldn't happen, ever
-*/
- _handleError: function(e)
- {
- // Don't fall back into normal processing!
- this._state = READER_FINISHED;
-
- var server = this._connection.server;
- if (e instanceof HttpError)
- {
- var code = e.code;
- }
- else
- {
- dumpn("!!! UNEXPECTED ERROR: " + e +
- (e.lineNumber ? ", line " + e.lineNumber : ""));
-
- // no idea what happened -- be paranoid and shut down
- code = 500;
- server._requestQuit();
- }
-
- // make attempted reuse of data an error
- this._data = null;
-
- this._connection.processError(code, this._metadata);
- },
-
- /**
-* Now that we've read the request line and headers, we can actually hand off
-* the request to be handled.
-*
-* This method is called once per request, after the request line and all
-* headers and the body, if any, have been received.
-*/
- _handleResponse: function()
- {
- NS_ASSERT(this._state == READER_FINISHED);
-
- // We don't need the line-based data any more, so make attempted reuse an
- // error.
- this._data = null;
-
- this._connection.process(this._metadata);
- },
-
-
- // PARSING
-
- /**
-* Parses the request line for the HTTP request associated with this.
-*
-* @param line : string
-* the request line
-*/
- _parseRequestLine: function(line)
- {
- NS_ASSERT(this._state == READER_IN_REQUEST_LINE);
-
- dumpn("*** _parseRequestLine('" + line + "')");
-
- var metadata = this._metadata;
-
- // clients and servers SHOULD accept any amount of SP or HT characters
- // between fields, even though only a single SP is required (section 19.3)
- var request = line.split(/[ \t]+/);
- if (!request || request.length != 3)
- throw HTTP_400;
-
- metadata._method = request[0];
-
- // get the HTTP version
- var ver = request[2];
- var match = ver.match(/^HTTP\/(\d+\.\d+)$/);
- if (!match)
- throw HTTP_400;
-
- // determine HTTP version
- try
- {
- metadata._httpVersion = new nsHttpVersion(match[1]);
- if (!metadata._httpVersion.atLeast(nsHttpVersion.HTTP_1_0))
- throw "unsupported HTTP version";
- }
- catch (e)
- {
- // we support HTTP/1.0 and HTTP/1.1 only
- throw HTTP_501;
- }
-
-
- var fullPath = request[1];
- var serverIdentity = this._connection.server.identity;
-
- var scheme, host, port;
-
- if (fullPath.charAt(0) != "/")
- {
- // No absolute paths in the request line in HTTP prior to 1.1
- if (!metadata._httpVersion.atLeast(nsHttpVersion.HTTP_1_1))
- throw HTTP_400;
-
- try
- {
- var uri = Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService)
- .newURI(fullPath, null, null);
- fullPath = uri.path;
- scheme = uri.scheme;
- host = metadata._host = uri.asciiHost;
- port = uri.port;
- if (port === -1)
- {
- if (scheme === "http")
- port = 80;
- else if (scheme === "https")
- port = 443;
- else
- throw HTTP_400;
- }
- }
- catch (e)
- {
- // If the host is not a valid host on the server, the response MUST be a
- // 400 (Bad Request) error message (section 5.2). Alternately, the URI
- // is malformed.
- throw HTTP_400;
- }
-
- if (!serverIdentity.has(scheme, host, port) || fullPath.charAt(0) != "/")
- throw HTTP_400;
- }
-
- var splitter = fullPath.indexOf("?");
- if (splitter < 0)
- {
- // _queryString already set in ctor
- metadata._path = fullPath;
- }
- else
- {
- metadata._path = fullPath.substring(0, splitter);
- metadata._queryString = fullPath.substring(splitter + 1);
- }
-
- metadata._scheme = scheme;
- metadata._host = host;
- metadata._port = port;
- },
-
- /**
-* Parses all available HTTP headers in this until the header-ending CRLFCRLF,
-* adding them to the store of headers in the request.
-*
-* @throws
-* HTTP_400 if the headers are malformed
-* @returns boolean
-* true if all headers have now been processed, false otherwise
-*/
- _parseHeaders: function()
- {
- NS_ASSERT(this._state == READER_IN_HEADERS);
-
- dumpn("*** _parseHeaders");
-
- var data = this._data;
-
- var headers = this._metadata._headers;
- var lastName = this._lastHeaderName;
- var lastVal = this._lastHeaderValue;
-
- var line = {};
- while (true)
- {
- NS_ASSERT(!((lastVal === undefined) ^ (lastName === undefined)),
- lastName === undefined ?
- "lastVal without lastName? lastVal: '" + lastVal + "'" :
- "lastName without lastVal? lastName: '" + lastName + "'");
-
- if (!data.readLine(line))
- {
- // save any data we have from the header we might still be processing
- this._lastHeaderName = lastName;
- this._lastHeaderValue = lastVal;
- return false;
- }
-
- var lineText = line.value;
- var firstChar = lineText.charAt(0);
-
- // blank line means end of headers
- if (lineText == "")
- {
- // we're finished with the previous header
- if (lastName)
- {
- try
- {
- headers.setHeader(lastName, lastVal, true);
- }
- catch (e)
- {
- dumpn("*** e == " + e);
- throw HTTP_400;
- }
- }
- else
- {
- // no headers in request -- valid for HTTP/1.0 requests
- }
-
- // either way, we're done processing headers
- this._state = READER_IN_BODY;
- return true;
- }
- else if (firstChar == " " || firstChar == "\t")
- {
- // multi-line header if we've already seen a header line
- if (!lastName)
- {
- // we don't have a header to continue!
- throw HTTP_400;
- }
-
- // append this line's text to the value; starts with SP/HT, so no need
- // for separating whitespace
- lastVal += lineText;
- }
- else
- {
- // we have a new header, so set the old one (if one existed)
- if (lastName)
- {
- try
- {
- headers.setHeader(lastName, lastVal, true);
- }
- catch (e)
- {
- dumpn("*** e == " + e);
- throw HTTP_400;
- }
- }
-
- var colon = lineText.indexOf(":"); // first colon must be splitter
- if (colon < 1)
- {
- // no colon or missing header field-name
- throw HTTP_400;
- }
-
- // set header name, value (to be set in the next loop, usually)
- lastName = lineText.substring(0, colon);
- lastVal = lineText.substring(colon + 1);
- } // empty, continuation, start of header
- } // while (true)
- }
-};
-
-
-/** The character codes for CR and LF. */
-const CR = 0x0D, LF = 0x0A;
-
-/**
-* Calculates the number of characters before the first CRLF pair in array, or
-* -1 if the array contains no CRLF pair.
-*
-* @param array : Array
-* an array of numbers in the range [0, 256), each representing a single
-* character; the first CRLF is the lowest index i where
-* |array[i] == "\r".charCodeAt(0)| and |array[i+1] == "\n".charCodeAt(0)|,
-* if such an |i| exists, and -1 otherwise
-* @returns int
-* the index of the first CRLF if any were present, -1 otherwise
-*/
-function findCRLF(array)
-{
- for (var i = array.indexOf(CR); i >= 0; i = array.indexOf(CR, i + 1))
- {
- if (array[i + 1] == LF)
- return i;
- }
- return -1;
-}
-
-
-/**
-* A container which provides line-by-line access to the arrays of bytes with
-* which it is seeded.
-*/
-function LineData()
-{
- /** An array of queued bytes from which to get line-based characters. */
- this._data = [];
-}
-LineData.prototype =
-{
- /**
-* Appends the bytes in the given array to the internal data cache maintained
-* by this.
-*/
- appendBytes: function(bytes)
- {
- Array.prototype.push.apply(this._data, bytes);
- },
-
- /**
-* Removes and returns a line of data, delimited by CRLF, from this.
-*
-* @param out
-* an object whose "value" property will be set to the first line of text
-* present in this, sans CRLF, if this contains a full CRLF-delimited line
-* of text; if this doesn't contain enough data, the value of the property
-* is undefined
-* @returns boolean
-* true if a full line of data could be read from the data in this, false
-* otherwise
-*/
- readLine: function(out)
- {
- var data = this._data;
- var length = findCRLF(data);
- if (length < 0)
- return false;
-
- //
- // We have the index of the CR, so remove all the characters, including
- // CRLF, from the array with splice, and convert the removed array into the
- // corresponding string, from which we then strip the trailing CRLF.
- //
- // Getting the line in this matter acknowledges that substring is an O(1)
- // operation in SpiderMonkey because strings are immutable, whereas two
- // splices, both from the beginning of the data, are less likely to be as
- // cheap as a single splice plus two extra character conversions.
- //
- var line = String.fromCharCode.apply(null, data.splice(0, length + 2));
- out.value = line.substring(0, length);
-
- return true;
- },
-
- /**
-* Removes the bytes currently within this and returns them in an array.
-*
-* @returns Array
-* the bytes within this when this method is called
-*/
- purge: function()
- {
- var data = this._data;
- this._data = [];
- return data;
- }
-};
-
-
-
-/**
-* Creates a request-handling function for an nsIHttpRequestHandler object.
-*/
-function createHandlerFunc(handler)
-{
- return function(metadata, response) { handler.handle(metadata, response); };
-}
-
-
-/**
-* The default handler for directories; writes an HTML response containing a
-* slightly-formatted directory listing.
-*/
-function defaultIndexHandler(metadata, response)
-{
- response.setHeader("Content-Type", "text/html", false);
-
- var path = htmlEscape(decodeURI(metadata.path));
-
- //
- // Just do a very basic bit of directory listings -- no need for too much
- // fanciness, especially since we don't have a style sheet in which we can
- // stick rules (don't want to pollute the default path-space).
- //
-
- var body = '<html>\
-<head>\
-<title>' + path + '</title>\
-</head>\
-<body>\
-<h1>' + path + '</h1>\
-<ol style="list-style-type: none">';
-
- var directory = metadata.getProperty("directory").QueryInterface(Ci.nsILocalFile);
- NS_ASSERT(directory && directory.isDirectory());
-
- var fileList = [];
- var files = directory.directoryEntries;
- while (files.hasMoreElements())
- {
- var f = files.getNext().QueryInterface(Ci.nsIFile);
- var name = f.leafName;
- if (!f.isHidden() &&
- (name.charAt(name.length - 1) != HIDDEN_CHAR ||
- name.charAt(name.length - 2) == HIDDEN_CHAR))
- fileList.push(f);
- }
-
- fileList.sort(fileSort);
-
- for (var i = 0; i < fileList.length; i++)
- {
- var file = fileList[i];
- try
- {
- var name = file.leafName;
- if (name.charAt(name.length - 1) == HIDDEN_CHAR)
- name = name.substring(0, name.length - 1);
- var sep = file.isDirectory() ? "/" : "";
-
- // Note: using " to delimit the attribute here because encodeURIComponent
- // passes through '.
- var item = '<li><a href="' + encodeURIComponent(name) + sep + '">' +
- htmlEscape(name) + sep +
- '</a></li>';
-
- body += item;
- }
- catch (e) { /* some file system error, ignore the file */ }
- }
-
- body += ' </ol>\
-</body>\
-</html>';
-
- response.bodyOutputStream.write(body, body.length);
-}
-
-/**
-* Sorts a and b (nsIFile objects) into an aesthetically pleasing order.
-*/
-function fileSort(a, b)
-{
- var dira = a.isDirectory(), dirb = b.isDirectory();
-
- if (dira && !dirb)
- return -1;
- if (dirb && !dira)
- return 1;
-
- var namea = a.leafName.toLowerCase(), nameb = b.leafName.toLowerCase();
- return nameb > namea ? -1 : 1;
-}
-
-
-/**
-* Converts an externally-provided path into an internal path for use in
-* determining file mappings.
-*
-* @param path
-* the path to convert
-* @param encoded
-* true if the given path should be passed through decodeURI prior to
-* conversion
-* @throws URIError
-* if path is incorrectly encoded
-*/
-function toInternalPath(path, encoded)
-{
- if (encoded)
- path = decodeURI(path);
-
- var comps = path.split("/");
- for (var i = 0, sz = comps.length; i < sz; i++)
- {
- var comp = comps[i];
- if (comp.charAt(comp.length - 1) == HIDDEN_CHAR)
- comps[i] = comp + HIDDEN_CHAR;
- }
- return comps.join("/");
-}
-
-
-/**
-* Adds custom-specified headers for the given file to the given response, if
-* any such headers are specified.
-*
-* @param file
-* the file on the disk which is to be written
-* @param metadata
-* metadata about the incoming request
-* @param response
-* the Response to which any specified headers/data should be written
-* @throws HTTP_500
-* if an error occurred while processing custom-specified headers
-*/
-function maybeAddHeaders(file, metadata, response)
-{
- var name = file.leafName;
- if (name.charAt(name.length - 1) == HIDDEN_CHAR)
- name = name.substring(0, name.length - 1);
-
- var headerFile = file.parent;
- headerFile.append(name + HEADERS_SUFFIX);
-
- if (!headerFile.exists())
- return;
-
- const PR_RDONLY = 0x01;
- var fis = new FileInputStream(headerFile, PR_RDONLY, parseInt("444", 8),
- Ci.nsIFileInputStream.CLOSE_ON_EOF);
-
- try
- {
- var lis = new ConverterInputStream(fis, "UTF-8", 1024, 0x0);
- lis.QueryInterface(Ci.nsIUnicharLineInputStream);
-
- var line = {value: ""};
- var more = lis.readLine(line);
-
- if (!more && line.value == "")
- return;
-
-
- // request line
-
- var status = line.value;
- if (status.indexOf("HTTP ") == 0)
- {
- status = status.substring(5);
- var space = status.indexOf(" ");
- var code, description;
- if (space < 0)
- {
- code = status;
- description = "";
- }
- else
- {
- code = status.substring(0, space);
- description = status.substring(space + 1, status.length);
- }
-
- response.setStatusLine(metadata.httpVersion, parseInt(code, 10), description);
-
- line.value = "";
- more = lis.readLine(line);
- }
-
- // headers
- while (more || line.value != "")
- {
- var header = line.value;
- var colon = header.indexOf(":");
-
- response.setHeader(header.substring(0, colon),
- header.substring(colon + 1, header.length),
- false); // allow overriding server-set headers
-
- line.value = "";
- more = lis.readLine(line);
- }
- }
- catch (e)
- {
- dumpn("WARNING: error in headers for " + metadata.path + ": " + e);
- throw HTTP_500;
- }
- finally
- {
- fis.close();
- }
-}
-
-
-/**
-* An object which handles requests for a server, executing default and
-* overridden behaviors as instructed by the code which uses and manipulates it.
-* Default behavior includes the paths / and /trace (diagnostics), with some
-* support for HTTP error pages for various codes and fallback to HTTP 500 if
-* those codes fail for any reason.
-*
-* @param server : nsHttpServer
-* the server in which this handler is being used
-*/
-function ServerHandler(server)
-{
- // FIELDS
-
- /**
-* The nsHttpServer instance associated with this handler.
-*/
- this._server = server;
-
- /**
-* A FileMap object containing the set of path->nsILocalFile mappings for
-* all directory mappings set in the server (e.g., "/" for /var/www/html/,
-* "/foo/bar/" for /local/path/, and "/foo/bar/baz/" for /local/path2).
-*
-* Note carefully: the leading and trailing "/" in each path (not file) are
-* removed before insertion to simplify the code which uses this. You have
-* been warned!
-*/
- this._pathDirectoryMap = new FileMap();
-
- /**
-* Custom request handlers for the server in which this resides. Path-handler
-* pairs are stored as property-value pairs in this property.
-*
-* @see ServerHandler.prototype._defaultPaths
-*/
- this._overridePaths = {};
-
- /**
-* Custom request handlers for the error handlers in the server in which this
-* resides. Path-handler pairs are stored as property-value pairs in this
-* property.
-*
-* @see ServerHandler.prototype._defaultErrors
-*/
- this._overrideErrors = {};
-
- /**
-* Maps file extensions to their MIME types in the server, overriding any
-* mapping that might or might not exist in the MIME service.
-*/
- this._mimeMappings = {};
-
- /**
-* The default handler for requests for directories, used to serve directories
-* when no index file is present.
-*/
- this._indexHandler = defaultIndexHandler;
-
- /** Per-path state storage for the server. */
- this._state = {};
-
- /** Entire-server state storage. */
- this._sharedState = {};
-
- /** Entire-server state storage for nsISupports values. */
- this._objectState = {};
-}
-ServerHandler.prototype =
-{
- // PUBLIC API
-
- /**
-* Handles a request to this server, responding to the request appropriately
-* and initiating server shutdown if necessary.
-*
-* This method never throws an exception.
-*
-* @param connection : Connection
-* the connection for this request
-*/
- handleResponse: function(connection)
- {
- var request = connection.request;
- var response = new Response(connection);
-
- var path = request.path;
- dumpn("*** path == " + path);
-
- try
- {
- try
- {
- if (path in this._overridePaths)
- {
- // explicit paths first, then files based on existing directory mappings,
- // then (if the file doesn't exist) built-in server default paths
- dumpn("calling override for " + path);
- this._overridePaths[path](request, response);
- }
- else
- {
- this._handleDefault(request, response);
- }
- }
- catch (e)
- {
- if (response.partiallySent())
- {
- response.abort(e);
- return;
- }
-
- if (!(e instanceof HttpError))
- {
- dumpn("*** unexpected error: e == " + e);
- throw HTTP_500;
- }
- if (e.code !== 404)
- throw e;
-
- dumpn("*** default: " + (path in this._defaultPaths));
-
- response = new Response(connection);
- if (path in this._defaultPaths)
- this._defaultPaths[path](request, response);
- else
- throw HTTP_404;
- }
- }
- catch (e)
- {
- if (response.partiallySent())
- {
- response.abort(e);
- return;
- }
-
- var errorCode = "internal";
-
- try
- {
- if (!(e instanceof HttpError))
- throw e;
-
- errorCode = e.code;
- dumpn("*** errorCode == " + errorCode);
-
- response = new Response(connection);
- if (e.customErrorHandling)
- e.customErrorHandling(response);
- this._handleError(errorCode, request, response);
- return;
- }
- catch (e2)
- {
- dumpn("*** error handling " + errorCode + " error: " +
- "e2 == " + e2 + ", shutting down server");
-
- connection.server._requestQuit();
- response.abort(e2);
- return;
- }
- }
-
- response.complete();
- },
-
- //
- // see nsIHttpServer.registerFile
- //
- registerFile: function(path, file)
- {
- if (!file)
- {
- dumpn("*** unregistering '" + path + "' mapping");
- delete this._overridePaths[path];
- return;
- }
-
- dumpn("*** registering '" + path + "' as mapping to " + file.path);
- file = file.clone();
-
- var self = this;
- this._overridePaths[path] =
- function(request, response)
- {
- if (!file.exists())
- throw HTTP_404;
-
- response.setStatusLine(request.httpVersion, 200, "OK");
- self._writeFileResponse(request, file, response, 0, file.fileSize);
- };
- },
-
- //
- // see nsIHttpServer.registerPathHandler
- //
- registerPathHandler: function(path, handler)
- {
- // XXX true path validation!
- if (path.charAt(0) != "/")
- throw Cr.NS_ERROR_INVALID_ARG;
-
- this._handlerToField(handler, this._overridePaths, path);
- },
-
- //
- // see nsIHttpServer.registerDirectory
- //
- registerDirectory: function(path, directory)
- {
- // strip off leading and trailing '/' so that we can use lastIndexOf when
- // determining exactly how a path maps onto a mapped directory --
- // conditional is required here to deal with "/".substring(1, 0) being
- // converted to "/".substring(0, 1) per the JS specification
- var key = path.length == 1 ? "" : path.substring(1, path.length - 1);
-
- // the path-to-directory mapping code requires that the first character not
- // be "/", or it will go into an infinite loop
- if (key.charAt(0) == "/")
- throw Cr.NS_ERROR_INVALID_ARG;
-
- key = toInternalPath(key, false);
-
- if (directory)
- {
- dumpn("*** mapping '" + path + "' to the location " + directory.path);
- this._pathDirectoryMap.put(key, directory);
- }
- else
- {
- dumpn("*** removing mapping for '" + path + "'");
- this._pathDirectoryMap.put(key, null);
- }
- },
-
- //
- // see nsIHttpServer.registerErrorHandler
- //
- registerErrorHandler: function(err, handler)
- {
- if (!(err in HTTP_ERROR_CODES))
- dumpn("*** WARNING: registering non-HTTP/1.1 error code " +
- "(" + err + ") handler -- was this intentional?");
-
- this._handlerToField(handler, this._overrideErrors, err);
- },
-
- //
- // see nsIHttpServer.setIndexHandler
- //
- setIndexHandler: function(handler)
- {
- if (!handler)
- handler = defaultIndexHandler;
- else if (typeof(handler) != "function")
- handler = createHandlerFunc(handler);
-
- this._indexHandler = handler;
- },
-
- //
- // see nsIHttpServer.registerContentType
- //
- registerContentType: function(ext, type)
- {
- if (!type)
- delete this._mimeMappings[ext];
- else
- this._mimeMappings[ext] = headerUtils.normalizeFieldValue(type);
- },
-
- // PRIVATE API
-
- /**
-* Sets or remove (if handler is null) a handler in an object with a key.
-*
-* @param handler
-* a handler, either function or an nsIHttpRequestHandler
-* @param dict
-* The object to attach the handler to.
-* @param key
-* The field name of the handler.
-*/
- _handlerToField: function(handler, dict, key)
- {
- // for convenience, handler can be a function if this is run from xpcshell
- if (typeof(handler) == "function")
- dict[key] = handler;
- else if (handler)
- dict[key] = createHandlerFunc(handler);
- else
- delete dict[key];
- },
-
- /**
-* Handles a request which maps to a file in the local filesystem (if a base
-* path has already been set; otherwise the 404 error is thrown).
-*
-* @param metadata : Request
-* metadata for the incoming request
-* @param response : Response
-* an uninitialized Response to the given request, to be initialized by a
-* request handler
-* @throws HTTP_###
-* if an HTTP error occurred (usually HTTP_404); note that in this case the
-* calling code must handle post-processing of the response
-*/
- _handleDefault: function(metadata, response)
- {
- dumpn("*** _handleDefault()");
-
- response.setStatusLine(metadata.httpVersion, 200, "OK");
-
- var path = metadata.path;
- NS_ASSERT(path.charAt(0) == "/", "invalid path: <" + path + ">");
-
- // determine the actual on-disk file; this requires finding the deepest
- // path-to-directory mapping in the requested URL
- var file = this._getFileForPath(path);
-
- // the "file" might be a directory, in which case we either serve the
- // contained index.html or make the index handler write the response
- if (file.exists() && file.isDirectory())
- {
- file.append("index.html"); // make configurable?
- if (!file.exists() || file.isDirectory())
- {
- metadata._ensurePropertyBag();
- metadata._bag.setPropertyAsInterface("directory", file.parent);
- this._indexHandler(metadata, response);
- return;
- }
- }
-
- // alternately, the file might not exist
- if (!file.exists())
- throw HTTP_404;
-
- var start, end;
- if (metadata._httpVersion.atLeast(nsHttpVersion.HTTP_1_1) &&
- metadata.hasHeader("Range") &&
- this._getTypeFromFile(file) !== SJS_TYPE)
- {
- var rangeMatch = metadata.getHeader("Range").match(/^bytes=(\d+)?-(\d+)?$/);
- if (!rangeMatch)
- throw HTTP_400;
-
- if (rangeMatch[1] !== undefined)
- start = parseInt(rangeMatch[1], 10);
-
- if (rangeMatch[2] !== undefined)
- end = parseInt(rangeMatch[2], 10);
-
- if (start === undefined && end === undefined)
- throw HTTP_400;
-
- // No start given, so the end is really the count of bytes from the
- // end of the file.
- if (start === undefined)
- {
- start = Math.max(0, file.fileSize - end);
- end = file.fileSize - 1;
- }
-
- // start and end are inclusive
- if (end === undefined || end >= file.fileSize)
- end = file.fileSize - 1;
-
- if (start !== undefined && start >= file.fileSize) {
- var HTTP_416 = new HttpError(416, "Requested Range Not Satisfiable");
- HTTP_416.customErrorHandling = function(errorResponse)
- {
- maybeAddHeaders(file, metadata, errorResponse);
- };
- throw HTTP_416;
- }
-
- if (end < start)
- {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- start = 0;
- end = file.fileSize - 1;
- }
- else
- {
- response.setStatusLine(metadata.httpVersion, 206, "Partial Content");
- var contentRange = "bytes " + start + "-" + end + "/" + file.fileSize;
- response.setHeader("Content-Range", contentRange);
- }
- }
- else
- {
- start = 0;
- end = file.fileSize - 1;
- }
-
- // finally...
- dumpn("*** handling '" + path + "' as mapping to " + file.path + " from " +
- start + " to " + end + " inclusive");
- this._writeFileResponse(metadata, file, response, start, end - start + 1);
- },
-
- /**
-* Writes an HTTP response for the given file, including setting headers for
-* file metadata.
-*
-* @param metadata : Request
-* the Request for which a response is being generated
-* @param file : nsILocalFile
-* the file which is to be sent in the response
-* @param response : Response
-* the response to which the file should be written
-* @param offset: uint
-* the byte offset to skip to when writing
-* @param count: uint
-* the number of bytes to write
-*/
- _writeFileResponse: function(metadata, file, response, offset, count)
- {
- const PR_RDONLY = 0x01;
-
- var type = this._getTypeFromFile(file);
- if (type === SJS_TYPE)
- {
- var fis = new FileInputStream(file, PR_RDONLY, parseInt("444", 8),
- Ci.nsIFileInputStream.CLOSE_ON_EOF);
-
- try
- {
- var sis = new ScriptableInputStream(fis);
- var s = Cu.Sandbox(gGlobalObject);
- s.importFunction(dump, "dump");
-
- // Define a basic key-value state-preservation API across requests, with
- // keys initially corresponding to the empty string.
- var self = this;
- var path = metadata.path;
- s.importFunction(function getState(k)
- {
- return self._getState(path, k);
- });
- s.importFunction(function setState(k, v)
- {
- self._setState(path, k, v);
- });
- s.importFunction(function getSharedState(k)
- {
- return self._getSharedState(k);
- });
- s.importFunction(function setSharedState(k, v)
- {
- self._setSharedState(k, v);
- });
- s.importFunction(function getObjectState(k, callback)
- {
- callback(self._getObjectState(k));
- });
- s.importFunction(function setObjectState(k, v)
- {
- self._setObjectState(k, v);
- });
- s.importFunction(function registerPathHandler(p, h)
- {
- self.registerPathHandler(p, h);
- });
-
- // Make it possible for sjs files to access their location
- this._setState(path, "__LOCATION__", file.path);
-
- try
- {
- // Alas, the line number in errors dumped to console when calling the
- // request handler is simply an offset from where we load the SJS file.
- // Work around this in a reasonably non-fragile way by dynamically
- // getting the line number where we evaluate the SJS file. Don't
- // separate these two lines!
- var line = new Error().lineNumber;
- Cu.evalInSandbox(sis.read(file.fileSize), s);
- }
- catch (e)
- {
- dumpn("*** syntax error in SJS at " + file.path + ": " + e);
- throw HTTP_500;
- }
-
- try
- {
- s.handleRequest(metadata, response);
- }
- catch (e)
- {
- dump("*** error running SJS at " + file.path + ": " +
- e + " on line " +
- (e instanceof Error
- ? e.lineNumber + " in httpd.js"
- : (e.lineNumber - line)) + "\n");
- throw HTTP_500;
- }
- }
- finally
- {
- fis.close();
- }
- }
- else
- {
- try
- {
- response.setHeader("Last-Modified",
- toDateString(file.lastModifiedTime),
- false);
- }
- catch (e) { /* lastModifiedTime threw, ignore */ }
-
- response.setHeader("Content-Type", type, false);
- maybeAddHeaders(file, metadata, response);
- response.setHeader("Content-Length", "" + count, false);
-
- var fis = new FileInputStream(file, PR_RDONLY, parseInt("444", 8),
- Ci.nsIFileInputStream.CLOSE_ON_EOF);
-
- offset = offset || 0;
- count = count || file.fileSize;
- NS_ASSERT(offset === 0 || offset < file.fileSize, "bad offset");
- NS_ASSERT(count >= 0, "bad count");
- NS_ASSERT(offset + count <= file.fileSize, "bad total data size");
-
- try
- {
- if (offset !== 0)
- {
- // Seek (or read, if seeking isn't supported) to the correct offset so
- // the data sent to the client matches the requested range.
- if (fis instanceof Ci.nsISeekableStream)
- fis.seek(Ci.nsISeekableStream.NS_SEEK_SET, offset);
- else
- new ScriptableInputStream(fis).read(offset);
- }
- }
- catch (e)
- {
- fis.close();
- throw e;
- }
-
- function writeMore()
- {
- gThreadManager.currentThread
- .dispatch(writeData, Ci.nsIThread.DISPATCH_NORMAL);
- }
-
- var input = new BinaryInputStream(fis);
- var output = new BinaryOutputStream(response.bodyOutputStream);
- var writeData =
- {
- run: function()
- {
- var chunkSize = Math.min(65536, count);
- count -= chunkSize;
- NS_ASSERT(count >= 0, "underflow");
-
- try
- {
- var data = input.readByteArray(chunkSize);
- NS_ASSERT(data.length === chunkSize,
- "incorrect data returned? got " + data.length +
- ", expected " + chunkSize);
- output.writeByteArray(data, data.length);
- if (count === 0)
- {
- fis.close();
- response.finish();
- }
- else
- {
- writeMore();
- }
- }
- catch (e)
- {
- try
- {
- fis.close();
- }
- finally
- {
- response.finish();
- }
- throw e;
- }
- }
- };
-
- writeMore();
-
- // Now that we know copying will start, flag the response as async.
- response.processAsync();
- }
- },
-
- /**
-* Get the value corresponding to a given key for the given path for SJS state
-* preservation across requests.
-*
-* @param path : string
-* the path from which the given state is to be retrieved
-* @param k : string
-* the key whose corresponding value is to be returned
-* @returns string
-* the corresponding value, which is initially the empty string
-*/
- _getState: function(path, k)
- {
- var state = this._state;
- if (path in state && k in state[path])
- return state[path][k];
- return "";
- },
-
- /**
-* Set the value corresponding to a given key for the given path for SJS state
-* preservation across requests.
-*
-* @param path : string
-* the path from which the given state is to be retrieved
-* @param k : string
-* the key whose corresponding value is to be set
-* @param v : string
-* the value to be set
-*/
- _setState: function(path, k, v)
- {
- if (typeof v !== "string")
- throw new Error("non-string value passed");
- var state = this._state;
- if (!(path in state))
- state[path] = {};
- state[path][k] = v;
- },
-
- /**
-* Get the value corresponding to a given key for SJS state preservation
-* across requests.
-*
-* @param k : string
-* the key whose corresponding value is to be returned
-* @returns string
-* the corresponding value, which is initially the empty string
-*/
- _getSharedState: function(k)
- {
- var state = this._sharedState;
- if (k in state)
- return state[k];
- return "";
- },
-
- /**
-* Set the value corresponding to a given key for SJS state preservation
-* across requests.
-*
-* @param k : string
-* the key whose corresponding value is to be set
-* @param v : string
-* the value to be set
-*/
- _setSharedState: function(k, v)
- {
- if (typeof v !== "string")
- throw new Error("non-string value passed");
- this._sharedState[k] = v;
- },
-
- /**
-* Returns the object associated with the given key in the server for SJS
-* state preservation across requests.
-*
-* @param k : string
-* the key whose corresponding object is to be returned
-* @returns nsISupports
-* the corresponding object, or null if none was present
-*/
- _getObjectState: function(k)
- {
- if (typeof k !== "string")
- throw new Error("non-string key passed");
- return this._objectState[k] || null;
- },
-
- /**
-* Sets the object associated with the given key in the server for SJS
-* state preservation across requests.
-*
-* @param k : string
-* the key whose corresponding object is to be set
-* @param v : nsISupports
-* the object to be associated with the given key; may be null
-*/
- _setObjectState: function(k, v)
- {
- if (typeof k !== "string")
- throw new Error("non-string key passed");
- if (typeof v !== "object")
- throw new Error("non-object value passed");
- if (v && !("QueryInterface" in v))
- {
- throw new Error("must pass an nsISupports; use wrappedJSObject to ease " +
- "pain when using the server from JS");
- }
-
- this._objectState[k] = v;
- },
-
- /**
-* Gets a content-type for the given file, first by checking for any custom
-* MIME-types registered with this handler for the file's extension, second by
-* asking the global MIME service for a content-type, and finally by failing
-* over to application/octet-stream.
-*
-* @param file : nsIFile
-* the nsIFile for which to get a file type
-* @returns string
-* the best content-type which can be determined for the file
-*/
- _getTypeFromFile: function(file)
- {
- try
- {
- var name = file.leafName;
- var dot = name.lastIndexOf(".");
- if (dot > 0)
- {
- var ext = name.slice(dot + 1);
- if (ext in this._mimeMappings)
- return this._mimeMappings[ext];
- }
- return Cc["@mozilla.org/uriloader/external-helper-app-service;1"]
- .getService(Ci.nsIMIMEService)
- .getTypeFromFile(file);
- }
- catch (e)
- {
- return "application/octet-stream";
- }
- },
-
- /**
-* Returns the nsILocalFile which corresponds to the path, as determined using
-* all registered path->directory mappings and any paths which are explicitly
-* overridden.
-*
-* @param path : string
-* the server path for which a file should be retrieved, e.g. "/foo/bar"
-* @throws HttpError
-* when the correct action is the corresponding HTTP error (i.e., because no
-* mapping was found for a directory in path, the referenced file doesn't
-* exist, etc.)
-* @returns nsILocalFile
-* the file to be sent as the response to a request for the path
-*/
- _getFileForPath: function(path)
- {
- // decode and add underscores as necessary
- try
- {
- path = toInternalPath(path, true);
- }
- catch (e)
- {
- throw HTTP_400; // malformed path
- }
-
- // next, get the directory which contains this path
- var pathMap = this._pathDirectoryMap;
-
- // An example progression of tmp for a path "/foo/bar/baz/" might be:
- // "foo/bar/baz/", "foo/bar/baz", "foo/bar", "foo", ""
- var tmp = path.substring(1);
- while (true)
- {
- // do we have a match for current head of the path?
- var file = pathMap.get(tmp);
- if (file)
- {
- // XXX hack; basically disable showing mapping for /foo/bar/ when the
- // requested path was /foo/bar, because relative links on the page
- // will all be incorrect -- we really need the ability to easily
- // redirect here instead
- if (tmp == path.substring(1) &&
- tmp.length != 0 &&
- tmp.charAt(tmp.length - 1) != "/")
- file = null;
- else
- break;
- }
-
- // if we've finished trying all prefixes, exit
- if (tmp == "")
- break;
-
- tmp = tmp.substring(0, tmp.lastIndexOf("/"));
- }
-
- // no mapping applies, so 404
- if (!file)
- throw HTTP_404;
-
-
- // last, get the file for the path within the determined directory
- var parentFolder = file.parent;
- var dirIsRoot = (parentFolder == null);
-
- // Strategy here is to append components individually, making sure we
- // never move above the given directory; this allows paths such as
- // "<file>/foo/../bar" but prevents paths such as "<file>/../base-sibling";
- // this component-wise approach also means the code works even on platforms
- // which don't use "/" as the directory separator, such as Windows
- var leafPath = path.substring(tmp.length + 1);
- var comps = leafPath.split("/");
- for (var i = 0, sz = comps.length; i < sz; i++)
- {
- var comp = comps[i];
-
- if (comp == "..")
- file = file.parent;
- else if (comp == "." || comp == "")
- continue;
- else
- file.append(comp);
-
- if (!dirIsRoot && file.equals(parentFolder))
- throw HTTP_403;
- }
-
- return file;
- },
-
- /**
-* Writes the error page for the given HTTP error code over the given
-* connection.
-*
-* @param errorCode : uint
-* the HTTP error code to be used
-* @param connection : Connection
-* the connection on which the error occurred
-*/
- handleError: function(errorCode, connection)
- {
- var response = new Response(connection);
-
- dumpn("*** error in request: " + errorCode);
-
- this._handleError(errorCode, new Request(connection.port), response);
- },
-
- /**
-* Handles a request which generates the given error code, using the
-* user-defined error handler if one has been set, gracefully falling back to
-* the x00 status code if the code has no handler, and failing to status code
-* 500 if all else fails.
-*
-* @param errorCode : uint
-* the HTTP error which is to be returned
-* @param metadata : Request
-* metadata for the request, which will often be incomplete since this is an
-* error
-* @param response : Response
-* an uninitialized Response should be initialized when this method
-* completes with information which represents the desired error code in the
-* ideal case or a fallback code in abnormal circumstances (i.e., 500 is a
-* fallback for 505, per HTTP specs)
-*/
- _handleError: function(errorCode, metadata, response)
- {
- if (!metadata)
- throw Cr.NS_ERROR_NULL_POINTER;
-
- var errorX00 = errorCode - (errorCode % 100);
-
- try
- {
- if (!(errorCode in HTTP_ERROR_CODES))
- dumpn("*** WARNING: requested invalid error: " + errorCode);
-
- // RFC 2616 says that we should try to handle an error by its class if we
- // can't otherwise handle it -- if that fails, we revert to handling it as
- // a 500 internal server error, and if that fails we throw and shut down
- // the server
-
- // actually handle the error
- try
- {
- if (errorCode in this._overrideErrors)
- this._overrideErrors[errorCode](metadata, response);
- else
- this._defaultErrors[errorCode](metadata, response);
- }
- catch (e)
- {
- if (response.partiallySent())
- {
- response.abort(e);
- return;
- }
-
- // don't retry the handler that threw
- if (errorX00 == errorCode)
- throw HTTP_500;
-
- dumpn("*** error in handling for error code " + errorCode + ", " +
- "falling back to " + errorX00 + "...");
- response = new Response(response._connection);
- if (errorX00 in this._overrideErrors)
- this._overrideErrors[errorX00](metadata, response);
- else if (errorX00 in this._defaultErrors)
- this._defaultErrors[errorX00](metadata, response);
- else
- throw HTTP_500;
- }
- }
- catch (e)
- {
- if (response.partiallySent())
- {
- response.abort();
- return;
- }
-
- // we've tried everything possible for a meaningful error -- now try 500
- dumpn("*** error in handling for error code " + errorX00 + ", falling " +
- "back to 500...");
-
- try
- {
- response = new Response(response._connection);
- if (500 in this._overrideErrors)
- this._overrideErrors[500](metadata, response);
- else
- this._defaultErrors[500](metadata, response);
- }
- catch (e2)
- {
- dumpn("*** multiple errors in default error handlers!");
- dumpn("*** e == " + e + ", e2 == " + e2);
- response.abort(e2);
- return;
- }
- }
-
- response.complete();
- },
-
- // FIELDS
-
- /**
-* This object contains the default handlers for the various HTTP error codes.
-*/
- _defaultErrors:
- {
- 400: function(metadata, response)
- {
- // none of the data in metadata is reliable, so hard-code everything here
- response.setStatusLine("1.1", 400, "Bad Request");
- response.setHeader("Content-Type", "text/plain", false);
-
- var body = "Bad request\n";
- response.bodyOutputStream.write(body, body.length);
- },
- 403: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 403, "Forbidden");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
-<head><title>403 Forbidden</title></head>\
-<body>\
-<h1>403 Forbidden</h1>\
-</body>\
-</html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 404: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 404, "Not Found");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
-<head><title>404 Not Found</title></head>\
-<body>\
-<h1>404 Not Found</h1>\
-<p>\
-<span style='font-family: monospace;'>" +
- htmlEscape(metadata.path) +
- "</span> was not found.\
-</p>\
-</body>\
-</html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 416: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion,
- 416,
- "Requested Range Not Satisfiable");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
-<head>\
-<title>416 Requested Range Not Satisfiable</title></head>\
-<body>\
-<h1>416 Requested Range Not Satisfiable</h1>\
-<p>The byte range was not valid for the\
-requested resource.\
-</p>\
-</body>\
-</html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 500: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion,
- 500,
- "Internal Server Error");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
-<head><title>500 Internal Server Error</title></head>\
-<body>\
-<h1>500 Internal Server Error</h1>\
-<p>Something's broken in this server and\
-needs to be fixed.</p>\
-</body>\
-</html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 501: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 501, "Not Implemented");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
-<head><title>501 Not Implemented</title></head>\
-<body>\
-<h1>501 Not Implemented</h1>\
-<p>This server is not (yet) Apache.</p>\
-</body>\
-</html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 505: function(metadata, response)
- {
- response.setStatusLine("1.1", 505, "HTTP Version Not Supported");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
-<head><title>505 HTTP Version Not Supported</title></head>\
-<body>\
-<h1>505 HTTP Version Not Supported</h1>\
-<p>This server only supports HTTP/1.0 and HTTP/1.1\
-connections.</p>\
-</body>\
-</html>";
- response.bodyOutputStream.write(body, body.length);
- }
- },
-
- /**
-* Contains handlers for the default set of URIs contained in this server.
-*/
- _defaultPaths:
- {
- "/": function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
-<head><title>httpd.js</title></head>\
-<body>\
-<h1>httpd.js</h1>\
-<p>If you're seeing this page, httpd.js is up and\
-serving requests! Now set a base path and serve some\
-files!</p>\
-</body>\
-</html>";
-
- response.bodyOutputStream.write(body, body.length);
- },
-
- "/trace": function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "text/plain", false);
-
- var body = "Request-URI: " +
- metadata.scheme + "://" + metadata.host + ":" + metadata.port +
- metadata.path + "\n\n";
- body += "Request (semantically equivalent, slightly reformatted):\n\n";
- body += metadata.method + " " + metadata.path;
-
- if (metadata.queryString)
- body += "?" + metadata.queryString;
-
- body += " HTTP/" + metadata.httpVersion + "\r\n";
-
- var headEnum = metadata.headers;
- while (headEnum.hasMoreElements())
- {
- var fieldName = headEnum.getNext()
- .QueryInterface(Ci.nsISupportsString)
- .data;
- body += fieldName + ": " + metadata.getHeader(fieldName) + "\r\n";
- }
-
- response.bodyOutputStream.write(body, body.length);
- }
- }
-};
-
-
-/**
-* Maps absolute paths to files on the local file system (as nsILocalFiles).
-*/
-function FileMap()
-{
- /** Hash which will map paths to nsILocalFiles. */
- this._map = {};
-}
-FileMap.prototype =
-{
- // PUBLIC API
-
- /**
-* Maps key to a clone of the nsILocalFile value if value is non-null;
-* otherwise, removes any extant mapping for key.
-*
-* @param key : string
-* string to which a clone of value is mapped
-* @param value : nsILocalFile
-* the file to map to key, or null to remove a mapping
-*/
- put: function(key, value)
- {
- if (value)
- this._map[key] = value.clone();
- else
- delete this._map[key];
- },
-
- /**
-* Returns a clone of the nsILocalFile mapped to key, or null if no such
-* mapping exists.
-*
-* @param key : string
-* key to which the returned file maps
-* @returns nsILocalFile
-* a clone of the mapped file, or null if no mapping exists
-*/
- get: function(key)
- {
- var val = this._map[key];
- return val ? val.clone() : null;
- }
-};
-
-
-// Response CONSTANTS
-
-// token = *<any CHAR except CTLs or separators>
-// CHAR = <any US-ASCII character (0-127)>
-// CTL = <any US-ASCII control character (0-31) and DEL (127)>
-// separators = "(" | ")" | "<" | ">" | "@"
-// | "," | ";" | ":" | "\" | <">
-// | "/" | "[" | "]" | "?" | "="
-// | "{" | "}" | SP | HT
-const IS_TOKEN_ARRAY =
- [0, 0, 0, 0, 0, 0, 0, 0, // 0
- 0, 0, 0, 0, 0, 0, 0, 0, // 8
- 0, 0, 0, 0, 0, 0, 0, 0, // 16
- 0, 0, 0, 0, 0, 0, 0, 0, // 24
-
- 0, 1, 0, 1, 1, 1, 1, 1, // 32
- 0, 0, 1, 1, 0, 1, 1, 0, // 40
- 1, 1, 1, 1, 1, 1, 1, 1, // 48
- 1, 1, 0, 0, 0, 0, 0, 0, // 56
-
- 0, 1, 1, 1, 1, 1, 1, 1, // 64
- 1, 1, 1, 1, 1, 1, 1, 1, // 72
- 1, 1, 1, 1, 1, 1, 1, 1, // 80
- 1, 1, 1, 0, 0, 0, 1, 1, // 88
-
- 1, 1, 1, 1, 1, 1, 1, 1, // 96
- 1, 1, 1, 1, 1, 1, 1, 1, // 104
- 1, 1, 1, 1, 1, 1, 1, 1, // 112
- 1, 1, 1, 0, 1, 0, 1]; // 120
-
-
-/**
-* Determines whether the given character code is a CTL.
-*
-* @param code : uint
-* the character code
-* @returns boolean
-* true if code is a CTL, false otherwise
-*/
-function isCTL(code)
-{
- return (code >= 0 && code <= 31) || (code == 127);
-}
-
-/**
-* Represents a response to an HTTP request, encapsulating all details of that
-* response. This includes all headers, the HTTP version, status code and
-* explanation, and the entity itself.
-*
-* @param connection : Connection
-* the connection over which this response is to be written
-*/
-function Response(connection)
-{
- /** The connection over which this response will be written. */
- this._connection = connection;
-
- /**
-* The HTTP version of this response; defaults to 1.1 if not set by the
-* handler.
-*/
- this._httpVersion = nsHttpVersion.HTTP_1_1;
-
- /**
-* The HTTP code of this response; defaults to 200.
-*/
- this._httpCode = 200;
-
- /**
-* The description of the HTTP code in this response; defaults to "OK".
-*/
- this._httpDescription = "OK";
-
- /**
-* An nsIHttpHeaders object in which the headers in this response should be
-* stored. This property is null after the status line and headers have been
-* written to the network, and it may be modified up until it is cleared,
-* except if this._finished is set first (in which case headers are written
-* asynchronously in response to a finish() call not preceded by
-* flushHeaders()).
-*/
- this._headers = new nsHttpHeaders();
-
- /**
-* Set to true when this response is ended (completely constructed if possible
-* and the connection closed); further actions on this will then fail.
-*/
- this._ended = false;
-
- /**
-* A stream used to hold data written to the body of this response.
-*/
- this._bodyOutputStream = null;
-
- /**
-* A stream containing all data that has been written to the body of this
-* response so far. (Async handlers make the data contained in this
-* unreliable as a way of determining content length in general, but auxiliary
-* saved information can sometimes be used to guarantee reliability.)
-*/
- this._bodyInputStream = null;
-
- /**
-* A stream copier which copies data to the network. It is initially null
-* until replaced with a copier for response headers; when headers have been
-* fully sent it is replaced with a copier for the response body, remaining
-* so for the duration of response processing.
-*/
- this._asyncCopier = null;
-
- /**
-* True if this response has been designated as being processed
-* asynchronously rather than for the duration of a single call to
-* nsIHttpRequestHandler.handle.
-*/
- this._processAsync = false;
-
- /**
-* True iff finish() has been called on this, signaling that no more changes
-* to this may be made.
-*/
- this._finished = false;
-
- /**
-* True iff powerSeized() has been called on this, signaling that this
-* response is to be handled manually by the response handler (which may then
-* send arbitrary data in response, even non-HTTP responses).
-*/
- this._powerSeized = false;
-}
-Response.prototype =
-{
- // PUBLIC CONSTRUCTION API
-
- //
- // see nsIHttpResponse.bodyOutputStream
- //
- get bodyOutputStream()
- {
- if (this._finished)
- throw Cr.NS_ERROR_NOT_AVAILABLE;
-
- if (!this._bodyOutputStream)
- {
- var pipe = new Pipe(true, false, Response.SEGMENT_SIZE, PR_UINT32_MAX,
- null);
- this._bodyOutputStream = pipe.outputStream;
- this._bodyInputStream = pipe.inputStream;
- if (this._processAsync || this._powerSeized)
- this._startAsyncProcessor();
- }
-
- return this._bodyOutputStream;
- },
-
- //
- // see nsIHttpResponse.write
- //
- write: function(data)
- {
- if (this._finished)
- throw Cr.NS_ERROR_NOT_AVAILABLE;
-
- var dataAsString = String(data);
- this.bodyOutputStream.write(dataAsString, dataAsString.length);
- },
-
- //
- // see nsIHttpResponse.setStatusLine
- //
- setStatusLine: function(httpVersion, code, description)
- {
- if (!this._headers || this._finished || this._powerSeized)
- throw Cr.NS_ERROR_NOT_AVAILABLE;
- this._ensureAlive();
-
- if (!(code >= 0 && code < 1000))
- throw Cr.NS_ERROR_INVALID_ARG;
-
- try
- {
- var httpVer;
- // avoid version construction for the most common cases
- if (!httpVersion || httpVersion == "1.1")
- httpVer = nsHttpVersion.HTTP_1_1;
- else if (httpVersion == "1.0")
- httpVer = nsHttpVersion.HTTP_1_0;
- else
- httpVer = new nsHttpVersion(httpVersion);
- }
- catch (e)
- {
- throw Cr.NS_ERROR_INVALID_ARG;
- }
-
- // Reason-Phrase = *<TEXT, excluding CR, LF>
- // TEXT = <any OCTET except CTLs, but including LWS>
- //
- // XXX this ends up disallowing octets which aren't Unicode, I think -- not
- // much to do if description is IDL'd as string
- if (!description)
- description = "";
- for (var i = 0; i < description.length; i++)
- if (isCTL(description.charCodeAt(i)) && description.charAt(i) != "\t")
- throw Cr.NS_ERROR_INVALID_ARG;
-
- // set the values only after validation to preserve atomicity
- this._httpDescription = description;
- this._httpCode = code;
- this._httpVersion = httpVer;
- },
-
- //
- // see nsIHttpResponse.setHeader
- //
- setHeader: function(name, value, merge)
- {
- if (!this._headers || this._finished || this._powerSeized)
- throw Cr.NS_ERROR_NOT_AVAILABLE;
- this._ensureAlive();
-
- this._headers.setHeader(name, value, merge);
- },
-
- //
- // see nsIHttpResponse.processAsync
- //
- processAsync: function()
- {
- if (this._finished)
- throw Cr.NS_ERROR_UNEXPECTED;
- if (this._powerSeized)
- throw Cr.NS_ERROR_NOT_AVAILABLE;
- if (this._processAsync)
- return;
- this._ensureAlive();
-
- dumpn("*** processing connection " + this._connection.number + " async");
- this._processAsync = true;
-
- /*
-* Either the bodyOutputStream getter or this method is responsible for
-* starting the asynchronous processor and catching writes of data to the
-* response body of async responses as they happen, for the purpose of
-* forwarding those writes to the actual connection's output stream.
-* If bodyOutputStream is accessed first, calling this method will create
-* the processor (when it first is clear that body data is to be written
-* immediately, not buffered). If this method is called first, accessing
-* bodyOutputStream will create the processor. If only this method is
-* called, we'll write nothing, neither headers nor the nonexistent body,
-* until finish() is called. Since that delay is easily avoided by simply
-* getting bodyOutputStream or calling write(""), we don't worry about it.
-*/
- if (this._bodyOutputStream && !this._asyncCopier)
- this._startAsyncProcessor();
- },
-
- //
- // see nsIHttpResponse.seizePower
- //
- seizePower: function()
- {
- if (this._processAsync)
- throw Cr.NS_ERROR_NOT_AVAILABLE;
- if (this._finished)
- throw Cr.NS_ERROR_UNEXPECTED;
- if (this._powerSeized)
- return;
- this._ensureAlive();
-
- dumpn("*** forcefully seizing power over connection " +
- this._connection.number + "...");
-
- // Purge any already-written data without sending it. We could as easily
- // swap out the streams entirely, but that makes it possible to acquire and
- // unknowingly use a stale reference, so we require there only be one of
- // each stream ever for any response to avoid this complication.
- if (this._asyncCopier)
- this._asyncCopier.cancel(Cr.NS_BINDING_ABORTED);
- this._asyncCopier = null;
- if (this._bodyOutputStream)
- {
- var input = new BinaryInputStream(this._bodyInputStream);
- var avail;
- while ((avail = input.available()) > 0)
- input.readByteArray(avail);
- }
-
- this._powerSeized = true;
- if (this._bodyOutputStream)
- this._startAsyncProcessor();
- },
-
- //
- // see nsIHttpResponse.finish
- //
- finish: function()
- {
- if (!this._processAsync && !this._powerSeized)
- throw Cr.NS_ERROR_UNEXPECTED;
- if (this._finished)
- return;
-
- dumpn("*** finishing connection " + this._connection.number);
- this._startAsyncProcessor(); // in case bodyOutputStream was never accessed
- if (this._bodyOutputStream)
- this._bodyOutputStream.close();
- this._finished = true;
- },
-
-
- // NSISUPPORTS
-
- //
- // see nsISupports.QueryInterface
- //
- QueryInterface: function(iid)
- {
- if (iid.equals(Ci.nsIHttpResponse) || iid.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
-
- // POST-CONSTRUCTION API (not exposed externally)
-
- /**
-* The HTTP version number of this, as a string (e.g. "1.1").
-*/
- get httpVersion()
- {
- this._ensureAlive();
- return this._httpVersion.toString();
- },
-
- /**
-* The HTTP status code of this response, as a string of three characters per
-* RFC 2616.
-*/
- get httpCode()
- {
- this._ensureAlive();
-
- var codeString = (this._httpCode < 10 ? "0" : "") +
- (this._httpCode < 100 ? "0" : "") +
- this._httpCode;
- return codeString;
- },
-
- /**
-* The description of the HTTP status code of this response, or "" if none is
-* set.
-*/
- get httpDescription()
- {
- this._ensureAlive();
-
- return this._httpDescription;
- },
-
- /**
-* The headers in this response, as an nsHttpHeaders object.
-*/
- get headers()
- {
- this._ensureAlive();
-
- return this._headers;
- },
-
- //
- // see nsHttpHeaders.getHeader
- //
- getHeader: function(name)
- {
- this._ensureAlive();
-
- return this._headers.getHeader(name);
- },
-
- /**
-* Determines whether this response may be abandoned in favor of a newly
-* constructed response. A response may be abandoned only if it is not being
-* sent asynchronously and if raw control over it has not been taken from the
-* server.
-*
-* @returns boolean
-* true iff no data has been written to the network
-*/
- partiallySent: function()
- {
- dumpn("*** partiallySent()");
- return this._processAsync || this._powerSeized;
- },
-
- /**
-* If necessary, kicks off the remaining request processing needed to be done
-* after a request handler performs its initial work upon this response.
-*/
- complete: function()
- {
- dumpn("*** complete()");
- if (this._processAsync || this._powerSeized)
- {
- NS_ASSERT(this._processAsync ^ this._powerSeized,
- "can't both send async and relinquish power");
- return;
- }
-
- NS_ASSERT(!this.partiallySent(), "completing a partially-sent response?");
-
- this._startAsyncProcessor();
-
- // Now make sure we finish processing this request!
- if (this._bodyOutputStream)
- this._bodyOutputStream.close();
- },
-
- /**
-* Abruptly ends processing of this response, usually due to an error in an
-* incoming request but potentially due to a bad error handler. Since we
-* cannot handle the error in the usual way (giving an HTTP error page in
-* response) because data may already have been sent (or because the response
-* might be expected to have been generated asynchronously or completely from
-* scratch by the handler), we stop processing this response and abruptly
-* close the connection.
-*
-* @param e : Error
-* the exception which precipitated this abort, or null if no such exception
-* was generated
-*/
- abort: function(e)
- {
- dumpn("*** abort(<" + e + ">)");
-
- // This response will be ended by the processor if one was created.
- var copier = this._asyncCopier;
- if (copier)
- {
- // We dispatch asynchronously here so that any pending writes of data to
- // the connection will be deterministically written. This makes it easier
- // to specify exact behavior, and it makes observable behavior more
- // predictable for clients. Note that the correctness of this depends on
- // callbacks in response to _waitToReadData in WriteThroughCopier
- // happening asynchronously with respect to the actual writing of data to
- // bodyOutputStream, as they currently do; if they happened synchronously,
- // an event which ran before this one could write more data to the
- // response body before we get around to canceling the copier. We have
- // tests for this in test_seizepower.js, however, and I can't think of a
- // way to handle both cases without removing bodyOutputStream access and
- // moving its effective write(data, length) method onto Response, which
- // would be slower and require more code than this anyway.
- gThreadManager.currentThread.dispatch({
- run: function()
- {
- dumpn("*** canceling copy asynchronously...");
- copier.cancel(Cr.NS_ERROR_UNEXPECTED);
- }
- }, Ci.nsIThread.DISPATCH_NORMAL);
- }
- else
- {
- this.end();
- }
- },
-
- /**
-* Closes this response's network connection, marks the response as finished,
-* and notifies the server handler that the request is done being processed.
-*/
- end: function()
- {
- NS_ASSERT(!this._ended, "ending this response twice?!?!");
-
- this._connection.close();
- if (this._bodyOutputStream)
- this._bodyOutputStream.close();
-
- this._finished = true;
- this._ended = true;
- },
-
- // PRIVATE IMPLEMENTATION
-
- /**
-* Sends the status line and headers of this response if they haven't been
-* sent and initiates the process of copying data written to this response's
-* body to the network.
-*/
- _startAsyncProcessor: function()
- {
- dumpn("*** _startAsyncProcessor()");
-
- // Handle cases where we're being called a second time. The former case
- // happens when this is triggered both by complete() and by processAsync(),
- // while the latter happens when processAsync() in conjunction with sent
- // data causes abort() to be called.
- if (this._asyncCopier || this._ended)
- {
- dumpn("*** ignoring second call to _startAsyncProcessor");
- return;
- }
-
- // Send headers if they haven't been sent already and should be sent, then
- // asynchronously continue to send the body.
- if (this._headers && !this._powerSeized)
- {
- this._sendHeaders();
- return;
- }
-
- this._headers = null;
- this._sendBody();
- },
-
- /**
-* Signals that all modifications to the response status line and headers are
-* complete and then sends that data over the network to the client. Once
-* this method completes, a different response to the request that resulted
-* in this response cannot be sent -- the only possible action in case of
-* error is to abort the response and close the connection.
-*/
- _sendHeaders: function()
- {
- dumpn("*** _sendHeaders()");
-
- NS_ASSERT(this._headers);
- NS_ASSERT(!this._powerSeized);
-
- // request-line
- var statusLine = "HTTP/" + this.httpVersion + " " +
- this.httpCode + " " +
- this.httpDescription + "\r\n";
-
- // header post-processing
-
- var headers = this._headers;
- headers.setHeader("Connection", "close", false);
- headers.setHeader("Server", "httpd.js", false);
- if (!headers.hasHeader("Date"))
- headers.setHeader("Date", toDateString(Date.now()), false);
-
- // Any response not being processed asynchronously must have an associated
- // Content-Length header for reasons of backwards compatibility with the
- // initial server, which fully buffered every response before sending it.
- // Beyond that, however, it's good to do this anyway because otherwise it's
- // impossible to test behaviors that depend on the presence or absence of a
- // Content-Length header.
- if (!this._processAsync)
- {
- dumpn("*** non-async response, set Content-Length");
-
- var bodyStream = this._bodyInputStream;
- var avail = bodyStream ? bodyStream.available() : 0;
-
- // XXX assumes stream will always report the full amount of data available
- headers.setHeader("Content-Length", "" + avail, false);
- }
-
-
- // construct and send response
- dumpn("*** header post-processing completed, sending response head...");
-
- // request-line
- var preambleData = [statusLine];
-
- // headers
- var headEnum = headers.enumerator;
- while (headEnum.hasMoreElements())
- {
- var fieldName = headEnum.getNext()
- .QueryInterface(Ci.nsISupportsString)
- .data;
- var values = headers.getHeaderValues(fieldName);
- for (var i = 0, sz = values.length; i < sz; i++)
- preambleData.push(fieldName + ": " + values[i] + "\r\n");
- }
-
- // end request-line/headers
- preambleData.push("\r\n");
-
- var preamble = preambleData.join("");
-
- var responseHeadPipe = new Pipe(true, false, 0, PR_UINT32_MAX, null);
- responseHeadPipe.outputStream.write(preamble, preamble.length);
-
- var response = this;
- var copyObserver =
- {
- onStartRequest: function(request, cx)
- {
- dumpn("*** preamble copying started");
- },
-
- onStopRequest: function(request, cx, statusCode)
- {
- dumpn("*** preamble copying complete " +
- "[status=0x" + statusCode.toString(16) + "]");
-
- if (!components.isSuccessCode(statusCode))
- {
- dumpn("!!! header copying problems: non-success statusCode, " +
- "ending response");
-
- response.end();
- }
- else
- {
- response._sendBody();
- }
- },
-
- QueryInterface: function(aIID)
- {
- if (aIID.equals(Ci.nsIRequestObserver) || aIID.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- };
-
- var headerCopier = this._asyncCopier =
- new WriteThroughCopier(responseHeadPipe.inputStream,
- this._connection.output,
- copyObserver, null);
-
- responseHeadPipe.outputStream.close();
-
- // Forbid setting any more headers or modifying the request line.
- this._headers = null;
- },
-
- /**
-* Asynchronously writes the body of the response (or the entire response, if
-* seizePower() has been called) to the network.
-*/
- _sendBody: function()
- {
- dumpn("*** _sendBody");
-
- NS_ASSERT(!this._headers, "still have headers around but sending body?");
-
- // If no body data was written, we're done
- if (!this._bodyInputStream)
- {
- dumpn("*** empty body, response finished");
- this.end();
- return;
- }
-
- var response = this;
- var copyObserver =
- {
- onStartRequest: function(request, context)
- {
- dumpn("*** onStartRequest");
- },
-
- onStopRequest: function(request, cx, statusCode)
- {
- dumpn("*** onStopRequest [status=0x" + statusCode.toString(16) + "]");
-
- if (statusCode === Cr.NS_BINDING_ABORTED)
- {
- dumpn("*** terminating copy observer without ending the response");
- }
- else
- {
- if (!components.isSuccessCode(statusCode))
- dumpn("*** WARNING: non-success statusCode in onStopRequest");
-
- response.end();
- }
- },
-
- QueryInterface: function(aIID)
- {
- if (aIID.equals(Ci.nsIRequestObserver) || aIID.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- };
-
- dumpn("*** starting async copier of body data...");
- this._asyncCopier =
- new WriteThroughCopier(this._bodyInputStream, this._connection.output,
- copyObserver, null);
- },
-
- /** Ensures that this hasn't been ended. */
- _ensureAlive: function()
- {
- NS_ASSERT(!this._ended, "not handling response lifetime correctly");
- }
-};
-
-/**
-* Size of the segments in the buffer used in storing response data and writing
-* it to the socket.
-*/
-Response.SEGMENT_SIZE = 8192;
-
-/** Serves double duty in WriteThroughCopier implementation. */
-function notImplemented()
-{
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-}
-
-/** Returns true iff the given exception represents stream closure. */
-function streamClosed(e)
-{
- return e === Cr.NS_BASE_STREAM_CLOSED ||
- (typeof e === "object" && e.result === Cr.NS_BASE_STREAM_CLOSED);
-}
-
-/** Returns true iff the given exception represents a blocked stream. */
-function wouldBlock(e)
-{
- return e === Cr.NS_BASE_STREAM_WOULD_BLOCK ||
- (typeof e === "object" && e.result === Cr.NS_BASE_STREAM_WOULD_BLOCK);
-}
-
-/**
-* Copies data from source to sink as it becomes available, when that data can
-* be written to sink without blocking.
-*
-* @param source : nsIAsyncInputStream
-* the stream from which data is to be read
-* @param sink : nsIAsyncOutputStream
-* the stream to which data is to be copied
-* @param observer : nsIRequestObserver
-* an observer which will be notified when the copy starts and finishes
-* @param context : nsISupports
-* context passed to observer when notified of start/stop
-* @throws NS_ERROR_NULL_POINTER
-* if source, sink, or observer are null
-*/
-function WriteThroughCopier(source, sink, observer, context)
-{
- if (!source || !sink || !observer)
- throw Cr.NS_ERROR_NULL_POINTER;
-
- /** Stream from which data is being read. */
- this._source = source;
-
- /** Stream to which data is being written. */
- this._sink = sink;
-
- /** Observer watching this copy. */
- this._observer = observer;
-
- /** Context for the observer watching this. */
- this._context = context;
-
- /**
-* True iff this is currently being canceled (cancel has been called, the
-* callback may not yet have been made).
-*/
- this._canceled = false;
-
- /**
-* False until all data has been read from input and written to output, at
-* which point this copy is completed and cancel() is asynchronously called.
-*/
- this._completed = false;
-
- /** Required by nsIRequest, meaningless. */
- this.loadFlags = 0;
- /** Required by nsIRequest, meaningless. */
- this.loadGroup = null;
- /** Required by nsIRequest, meaningless. */
- this.name = "response-body-copy";
-
- /** Status of this request. */
- this.status = Cr.NS_OK;
-
- /** Arrays of byte strings waiting to be written to output. */
- this._pendingData = [];
-
- // start copying
- try
- {
- observer.onStartRequest(this, context);
- this._waitToReadData();
- this._waitForSinkClosure();
- }
- catch (e)
- {
- dumpn("!!! error starting copy: " + e +
- ("lineNumber" in e ? ", line " + e.lineNumber : ""));
- dumpn(e.stack);
- this.cancel(Cr.NS_ERROR_UNEXPECTED);
- }
-}
-WriteThroughCopier.prototype =
-{
- /* nsISupports implementation */
-
- QueryInterface: function(iid)
- {
- if (iid.equals(Ci.nsIInputStreamCallback) ||
- iid.equals(Ci.nsIOutputStreamCallback) ||
- iid.equals(Ci.nsIRequest) ||
- iid.equals(Ci.nsISupports))
- {
- return this;
- }
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
-
- // NSIINPUTSTREAMCALLBACK
-
- /**
-* Receives a more-data-in-input notification and writes the corresponding
-* data to the output.
-*
-* @param input : nsIAsyncInputStream
-* the input stream on whose data we have been waiting
-*/
- onInputStreamReady: function(input)
- {
- if (this._source === null)
- return;
-
- dumpn("*** onInputStreamReady");
-
- //
- // Ordinarily we'll read a non-zero amount of data from input, queue it up
- // to be written and then wait for further callbacks. The complications in
- // this method are the cases where we deviate from that behavior when errors
- // occur or when copying is drawing to a finish.
- //
- // The edge cases when reading data are:
- //
- // Zero data is read
- // If zero data was read, we're at the end of available data, so we can
- // should stop reading and move on to writing out what we have (or, if
- // we've already done that, onto notifying of completion).
- // A stream-closed exception is thrown
- // This is effectively a less kind version of zero data being read; the
- // only difference is that we notify of completion with that result
- // rather than with NS_OK.
- // Some other exception is thrown
- // This is the least kind result. We don't know what happened, so we
- // act as though the stream closed except that we notify of completion
- // with the result NS_ERROR_UNEXPECTED.
- //
-
- var bytesWanted = 0, bytesConsumed = -1;
- try
- {
- input = new BinaryInputStream(input);
-
- bytesWanted = Math.min(input.available(), Response.SEGMENT_SIZE);
- dumpn("*** input wanted: " + bytesWanted);
-
- if (bytesWanted > 0)
- {
- var data = input.readByteArray(bytesWanted);
- bytesConsumed = data.length;
- this._pendingData.push(String.fromCharCode.apply(String, data));
- }
-
- dumpn("*** " + bytesConsumed + " bytes read");
-
- // Handle the zero-data edge case in the same place as all other edge
- // cases are handled.
- if (bytesWanted === 0)
- throw Cr.NS_BASE_STREAM_CLOSED;
- }
- catch (e)
- {
- if (streamClosed(e))
- {
- dumpn("*** input stream closed");
- e = bytesWanted === 0 ? Cr.NS_OK : Cr.NS_ERROR_UNEXPECTED;
- }
- else
- {
- dumpn("!!! unexpected error reading from input, canceling: " + e);
- e = Cr.NS_ERROR_UNEXPECTED;
- }
-
- this._doneReadingSource(e);
- return;
- }
-
- var pendingData = this._pendingData;
-
- NS_ASSERT(bytesConsumed > 0);
- NS_ASSERT(pendingData.length > 0, "no pending data somehow?");
- NS_ASSERT(pendingData[pendingData.length - 1].length > 0,
- "buffered zero bytes of data?");
-
- NS_ASSERT(this._source !== null);
-
- // Reading has gone great, and we've gotten data to write now. What if we
- // don't have a place to write that data, because output went away just
- // before this read? Drop everything on the floor, including new data, and
- // cancel at this point.
- if (this._sink === null)
- {
- pendingData.length = 0;
- this._doneReadingSource(Cr.NS_ERROR_UNEXPECTED);
- return;
- }
-
- // Okay, we've read the data, and we know we have a place to write it. We
- // need to queue up the data to be written, but *only* if none is queued
- // already -- if data's already queued, the code that actually writes the
- // data will make sure to wait on unconsumed pending data.
- try
- {
- if (pendingData.length === 1)
- this._waitToWriteData();
- }
- catch (e)
- {
- dumpn("!!! error waiting to write data just read, swallowing and " +
- "writing only what we already have: " + e);
- this._doneWritingToSink(Cr.NS_ERROR_UNEXPECTED);
- return;
- }
-
- // Whee! We successfully read some data, and it's successfully queued up to
- // be written. All that remains now is to wait for more data to read.
- try
- {
- this._waitToReadData();
- }
- catch (e)
- {
- dumpn("!!! error waiting to read more data: " + e);
- this._doneReadingSource(Cr.NS_ERROR_UNEXPECTED);
- }
- },
-
-
- // NSIOUTPUTSTREAMCALLBACK
-
- /**
-* Callback when data may be written to the output stream without blocking, or
-* when the output stream has been closed.
-*
-* @param output : nsIAsyncOutputStream
-* the output stream on whose writability we've been waiting, also known as
-* this._sink
-*/
- onOutputStreamReady: function(output)
- {
- if (this._sink === null)
- return;
-
- dumpn("*** onOutputStreamReady");
-
- var pendingData = this._pendingData;
- if (pendingData.length === 0)
- {
- // There's no pending data to write. The only way this can happen is if
- // we're waiting on the output stream's closure, so we can respond to a
- // copying failure as quickly as possible (rather than waiting for data to
- // be available to read and then fail to be copied). Therefore, we must
- // be done now -- don't bother to attempt to write anything and wrap
- // things up.
- dumpn("!!! output stream closed prematurely, ending copy");
-
- this._doneWritingToSink(Cr.NS_ERROR_UNEXPECTED);
- return;
- }
-
-
- NS_ASSERT(pendingData[0].length > 0, "queued up an empty quantum?");
-
- //
- // Write out the first pending quantum of data. The possible errors here
- // are:
- //
- // The write might fail because we can't write that much data
- // Okay, we've written what we can now, so re-queue what's left and
- // finish writing it out later.
- // The write failed because the stream was closed
- // Discard pending data that we can no longer write, stop reading, and
- // signal that copying finished.
- // Some other error occurred.
- // Same as if the stream were closed, but notify with the status
- // NS_ERROR_UNEXPECTED so the observer knows something was wonky.
- //
-
- try
- {
- var quantum = pendingData[0];
-
- // XXX |quantum| isn't guaranteed to be ASCII, so we're relying on
- // undefined behavior! We're only using this because writeByteArray
- // is unusably broken for asynchronous output streams; see bug 532834
- // for details.
- var bytesWritten = output.write(quantum, quantum.length);
- if (bytesWritten === quantum.length)
- pendingData.shift();
- else
- pendingData[0] = quantum.substring(bytesWritten);
-
- dumpn("*** wrote " + bytesWritten + " bytes of data");
- }
- catch (e)
- {
- if (wouldBlock(e))
- {
- NS_ASSERT(pendingData.length > 0,
- "stream-blocking exception with no data to write?");
- NS_ASSERT(pendingData[0].length > 0,
- "stream-blocking exception with empty quantum?");
- this._waitToWriteData();
- return;
- }
-
- if (streamClosed(e))
- dumpn("!!! output stream prematurely closed, signaling error...");
- else
- dumpn("!!! unknown error: " + e + ", quantum=" + quantum);
-
- this._doneWritingToSink(Cr.NS_ERROR_UNEXPECTED);
- return;
- }
-
- // The day is ours! Quantum written, now let's see if we have more data
- // still to write.
- try
- {
- if (pendingData.length > 0)
- {
- this._waitToWriteData();
- return;
- }
- }
- catch (e)
- {
- dumpn("!!! unexpected error waiting to write pending data: " + e);
- this._doneWritingToSink(Cr.NS_ERROR_UNEXPECTED);
- return;
- }
-
- // Okay, we have no more pending data to write -- but might we get more in
- // the future?
- if (this._source !== null)
- {
- /*
-* If we might, then wait for the output stream to be closed. (We wait
-* only for closure because we have no data to write -- and if we waited
-* for a specific amount of data, we would get repeatedly notified for no
-* reason if over time the output stream permitted more and more data to
-* be written to it without blocking.)
-*/
- this._waitForSinkClosure();
- }
- else
- {
- /*
-* On the other hand, if we can't have more data because the input
-* stream's gone away, then it's time to notify of copy completion.
-* Victory!
-*/
- this._sink = null;
- this._cancelOrDispatchCancelCallback(Cr.NS_OK);
- }
- },
-
-
- // NSIREQUEST
-
- /** Returns true if the cancel observer hasn't been notified yet. */
- isPending: function()
- {
- return !this._completed;
- },
-
- /** Not implemented, don't use! */
- suspend: notImplemented,
- /** Not implemented, don't use! */
- resume: notImplemented,
-
- /**
-* Cancels data reading from input, asynchronously writes out any pending
-* data, and causes the observer to be notified with the given error code when
-* all writing has finished.
-*
-* @param status : nsresult
-* the status to pass to the observer when data copying has been canceled
-*/
- cancel: function(status)
- {
- dumpn("*** cancel(" + status.toString(16) + ")");
-
- if (this._canceled)
- {
- dumpn("*** suppressing a late cancel");
- return;
- }
-
- this._canceled = true;
- this.status = status;
-
- // We could be in the middle of absolutely anything at this point. Both
- // input and output might still be around, we might have pending data to
- // write, and in general we know nothing about the state of the world. We
- // therefore must assume everything's in progress and take everything to its
- // final steady state (or so far as it can go before we need to finish
- // writing out remaining data).
-
- this._doneReadingSource(status);
- },
-
-
- // PRIVATE IMPLEMENTATION
-
- /**
-* Stop reading input if we haven't already done so, passing e as the status
-* when closing the stream, and kick off a copy-completion notice if no more
-* data remains to be written.
-*
-* @param e : nsresult
-* the status to be used when closing the input stream
-*/
- _doneReadingSource: function(e)
- {
- dumpn("*** _doneReadingSource(0x" + e.toString(16) + ")");
-
- this._finishSource(e);
- if (this._pendingData.length === 0)
- this._sink = null;
- else
- NS_ASSERT(this._sink !== null, "null output?");
-
- // If we've written out all data read up to this point, then it's time to
- // signal completion.
- if (this._sink === null)
- {
- NS_ASSERT(this._pendingData.length === 0, "pending data still?");
- this._cancelOrDispatchCancelCallback(e);
- }
- },
-
- /**
-* Stop writing output if we haven't already done so, discard any data that
-* remained to be sent, close off input if it wasn't already closed, and kick
-* off a copy-completion notice.
-*
-* @param e : nsresult
-* the status to be used when closing input if it wasn't already closed
-*/
- _doneWritingToSink: function(e)
- {
- dumpn("*** _doneWritingToSink(0x" + e.toString(16) + ")");
-
- this._pendingData.length = 0;
- this._sink = null;
- this._doneReadingSource(e);
- },
-
- /**
-* Completes processing of this copy: either by canceling the copy if it
-* hasn't already been canceled using the provided status, or by dispatching
-* the cancel callback event (with the originally provided status, of course)
-* if it already has been canceled.
-*
-* @param status : nsresult
-* the status code to use to cancel this, if this hasn't already been
-* canceled
-*/
- _cancelOrDispatchCancelCallback: function(status)
- {
- dumpn("*** _cancelOrDispatchCancelCallback(" + status + ")");
-
- NS_ASSERT(this._source === null, "should have finished input");
- NS_ASSERT(this._sink === null, "should have finished output");
- NS_ASSERT(this._pendingData.length === 0, "should have no pending data");
-
- if (!this._canceled)
- {
- this.cancel(status);
- return;
- }
-
- var self = this;
- var event =
- {
- run: function()
- {
- dumpn("*** onStopRequest async callback");
-
- self._completed = true;
- try
- {
- self._observer.onStopRequest(self, self._context, self.status);
- }
- catch (e)
- {
- NS_ASSERT(false,
- "how are we throwing an exception here? we control " +
- "all the callers! " + e);
- }
- }
- };
-
- gThreadManager.currentThread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
- },
-
- /**
-* Kicks off another wait for more data to be available from the input stream.
-*/
- _waitToReadData: function()
- {
- dumpn("*** _waitToReadData");
- this._source.asyncWait(this, 0, Response.SEGMENT_SIZE,
- gThreadManager.mainThread);
- },
-
- /**
-* Kicks off another wait until data can be written to the output stream.
-*/
- _waitToWriteData: function()
- {
- dumpn("*** _waitToWriteData");
-
- var pendingData = this._pendingData;
- NS_ASSERT(pendingData.length > 0, "no pending data to write?");
- NS_ASSERT(pendingData[0].length > 0, "buffered an empty write?");
-
- this._sink.asyncWait(this, 0, pendingData[0].length,
- gThreadManager.mainThread);
- },
-
- /**
-* Kicks off a wait for the sink to which data is being copied to be closed.
-* We wait for stream closure when we don't have any data to be copied, rather
-* than waiting to write a specific amount of data. We can't wait to write
-* data because the sink might be infinitely writable, and if no data appears
-* in the source for a long time we might have to spin quite a bit waiting to
-* write, waiting to write again, &c. Waiting on stream closure instead means
-* we'll get just one notification if the sink dies. Note that when data
-* starts arriving from the sink we'll resume waiting for data to be written,
-* dropping this closure-only callback entirely.
-*/
- _waitForSinkClosure: function()
- {
- dumpn("*** _waitForSinkClosure");
-
- this._sink.asyncWait(this, Ci.nsIAsyncOutputStream.WAIT_CLOSURE_ONLY, 0,
- gThreadManager.mainThread);
- },
-
- /**
-* Closes input with the given status, if it hasn't already been closed;
-* otherwise a no-op.
-*
-* @param status : nsresult
-* status code use to close the source stream if necessary
-*/
- _finishSource: function(status)
- {
- dumpn("*** _finishSource(" + status.toString(16) + ")");
-
- if (this._source !== null)
- {
- this._source.closeWithStatus(status);
- this._source = null;
- }
- }
-};
-
-
-/**
-* A container for utility functions used with HTTP headers.
-*/
-const headerUtils =
-{
- /**
-* Normalizes fieldName (by converting it to lowercase) and ensures it is a
-* valid header field name (although not necessarily one specified in RFC
-* 2616).
-*
-* @throws NS_ERROR_INVALID_ARG
-* if fieldName does not match the field-name production in RFC 2616
-* @returns string
-* fieldName converted to lowercase if it is a valid header, for characters
-* where case conversion is possible
-*/
- normalizeFieldName: function(fieldName)
- {
- if (fieldName == "")
- throw Cr.NS_ERROR_INVALID_ARG;
-
- for (var i = 0, sz = fieldName.length; i < sz; i++)
- {
- if (!IS_TOKEN_ARRAY[fieldName.charCodeAt(i)])
- {
- dumpn(fieldName + " is not a valid header field name!");
- throw Cr.NS_ERROR_INVALID_ARG;
- }
- }
-
- return fieldName.toLowerCase();
- },
-
- /**
-* Ensures that fieldValue is a valid header field value (although not
-* necessarily as specified in RFC 2616 if the corresponding field name is
-* part of the HTTP protocol), normalizes the value if it is, and
-* returns the normalized value.
-*
-* @param fieldValue : string
-* a value to be normalized as an HTTP header field value
-* @throws NS_ERROR_INVALID_ARG
-* if fieldValue does not match the field-value production in RFC 2616
-* @returns string
-* fieldValue as a normalized HTTP header field value
-*/
- normalizeFieldValue: function(fieldValue)
- {
- // field-value = *( field-content | LWS )
- // field-content = <the OCTETs making up the field-value
- // and consisting of either *TEXT or combinations
- // of token, separators, and quoted-string>
- // TEXT = <any OCTET except CTLs,
- // but including LWS>
- // LWS = [CRLF] 1*( SP | HT )
- //
- // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
- // qdtext = <any TEXT except <">>
- // quoted-pair = "\" CHAR
- // CHAR = <any US-ASCII character (octets 0 - 127)>
-
- // Any LWS that occurs between field-content MAY be replaced with a single
- // SP before interpreting the field value or forwarding the message
- // downstream (section 4.2); we replace 1*LWS with a single SP
- var val = fieldValue.replace(/(?:(?:\r\n)?[ \t]+)+/g, " ");
-
- // remove leading/trailing LWS (which has been converted to SP)
- val = val.replace(/^ +/, "").replace(/ +$/, "");
-
- // that should have taken care of all CTLs, so val should contain no CTLs
- for (var i = 0, len = val.length; i < len; i++)
- if (isCTL(val.charCodeAt(i)))
- throw Cr.NS_ERROR_INVALID_ARG;
-
- // XXX disallows quoted-pair where CHAR is a CTL -- will not invalidly
- // normalize, however, so this can be construed as a tightening of the
- // spec and not entirely as a bug
- return val;
- }
-};
-
-
-
-/**
-* Converts the given string into a string which is safe for use in an HTML
-* context.
-*
-* @param str : string
-* the string to make HTML-safe
-* @returns string
-* an HTML-safe version of str
-*/
-function htmlEscape(str)
-{
- // this is naive, but it'll work
- var s = "";
- for (var i = 0; i < str.length; i++)
- s += "&#" + str.charCodeAt(i) + ";";
- return s;
-}
-
-
-/**
-* Constructs an object representing an HTTP version (see section 3.1).
-*
-* @param versionString
-* a string of the form "#.#", where # is an non-negative decimal integer with
-* or without leading zeros
-* @throws
-* if versionString does not specify a valid HTTP version number
-*/
-function nsHttpVersion(versionString)
-{
- var matches = /^(\d+)\.(\d+)$/.exec(versionString);
- if (!matches)
- throw "Not a valid HTTP version!";
-
- /** The major version number of this, as a number. */
- this.major = parseInt(matches[1], 10);
-
- /** The minor version number of this, as a number. */
- this.minor = parseInt(matches[2], 10);
-
- if (isNaN(this.major) || isNaN(this.minor) ||
- this.major < 0 || this.minor < 0)
- throw "Not a valid HTTP version!";
-}
-nsHttpVersion.prototype =
-{
- /**
-* Returns the standard string representation of the HTTP version represented
-* by this (e.g., "1.1").
-*/
- toString: function ()
- {
- return this.major + "." + this.minor;
- },
-
- /**
-* Returns true if this represents the same HTTP version as otherVersion,
-* false otherwise.
-*
-* @param otherVersion : nsHttpVersion
-* the version to compare against this
-*/
- equals: function (otherVersion)
- {
- return this.major == otherVersion.major &&
- this.minor == otherVersion.minor;
- },
-
- /** True if this >= otherVersion, false otherwise. */
- atLeast: function(otherVersion)
- {
- return this.major > otherVersion.major ||
- (this.major == otherVersion.major &&
- this.minor >= otherVersion.minor);
- }
-};
-
-nsHttpVersion.HTTP_1_0 = new nsHttpVersion("1.0");
-nsHttpVersion.HTTP_1_1 = new nsHttpVersion("1.1");
-
-
-/**
-* An object which stores HTTP headers for a request or response.
-*
-* Note that since headers are case-insensitive, this object converts headers to
-* lowercase before storing them. This allows the getHeader and hasHeader
-* methods to work correctly for any case of a header, but it means that the
-* values returned by .enumerator may not be equal case-sensitively to the
-* values passed to setHeader when adding headers to this.
-*/
-function nsHttpHeaders()
-{
- /**
-* A hash of headers, with header field names as the keys and header field
-* values as the values. Header field names are case-insensitive, but upon
-* insertion here they are converted to lowercase. Header field values are
-* normalized upon insertion to contain no leading or trailing whitespace.
-*
-* Note also that per RFC 2616, section 4.2, two headers with the same name in
-* a message may be treated as one header with the same field name and a field
-* value consisting of the separate field values joined together with a "," in
-* their original order. This hash stores multiple headers with the same name
-* in this manner.
-*/
- this._headers = {};
-}
-nsHttpHeaders.prototype =
-{
- /**
-* Sets the header represented by name and value in this.
-*
-* @param name : string
-* the header name
-* @param value : string
-* the header value
-* @throws NS_ERROR_INVALID_ARG
-* if name or value is not a valid header component
-*/
- setHeader: function(fieldName, fieldValue, merge)
- {
- var name = headerUtils.normalizeFieldName(fieldName);
- var value = headerUtils.normalizeFieldValue(fieldValue);
-
- // The following three headers are stored as arrays because their real-world
- // syntax prevents joining individual headers into a single header using
- // ",". See also <http://hg.mozilla.org/mozilla-central/diff/9b2a99adc05e/netwerk/protocol/http/src/nsHttpHeaderArray.cpp#l77>
- if (merge && name in this._headers)
- {
- if (name === "www-authenticate" ||
- name === "proxy-authenticate" ||
- name === "set-cookie")
- {
- this._headers[name].push(value);
- }
- else
- {
- this._headers[name][0] += "," + value;
- NS_ASSERT(this._headers[name].length === 1,
- "how'd a non-special header have multiple values?")
- }
- }
- else
- {
- this._headers[name] = [value];
- }
- },
-
- /**
-* Returns the value for the header specified by this.
-*
-* @throws NS_ERROR_INVALID_ARG
-* if fieldName does not constitute a valid header field name
-* @throws NS_ERROR_NOT_AVAILABLE
-* if the given header does not exist in this
-* @returns string
-* the field value for the given header, possibly with non-semantic changes
-* (i.e., leading/trailing whitespace stripped, whitespace runs replaced
-* with spaces, etc.) at the option of the implementation; multiple
-* instances of the header will be combined with a comma, except for
-* the three headers noted in the description of getHeaderValues
-*/
- getHeader: function(fieldName)
- {
- return this.getHeaderValues(fieldName).join("\n");
- },
-
- /**
-* Returns the value for the header specified by fieldName as an array.
-*
-* @throws NS_ERROR_INVALID_ARG
-* if fieldName does not constitute a valid header field name
-* @throws NS_ERROR_NOT_AVAILABLE
-* if the given header does not exist in this
-* @returns [string]
-* an array of all the header values in this for the given
-* header name. Header values will generally be collapsed
-* into a single header by joining all header values together
-* with commas, but certain headers (Proxy-Authenticate,
-* WWW-Authenticate, and Set-Cookie) violate the HTTP spec
-* and cannot be collapsed in this manner. For these headers
-* only, the returned array may contain multiple elements if
-* that header has been added more than once.
-*/
- getHeaderValues: function(fieldName)
- {
- var name = headerUtils.normalizeFieldName(fieldName);
-
- if (name in this._headers)
- return this._headers[name];
- else
- throw Cr.NS_ERROR_NOT_AVAILABLE;
- },
-
- /**
-* Returns true if a header with the given field name exists in this, false
-* otherwise.
-*
-* @param fieldName : string
-* the field name whose existence is to be determined in this
-* @throws NS_ERROR_INVALID_ARG
-* if fieldName does not constitute a valid header field name
-* @returns boolean
-* true if the header's present, false otherwise
-*/
- hasHeader: function(fieldName)
- {
- var name = headerUtils.normalizeFieldName(fieldName);
- return (name in this._headers);
- },
-
- /**
-* Returns a new enumerator over the field names of the headers in this, as
-* nsISupportsStrings. The names returned will be in lowercase, regardless of
-* how they were input using setHeader (header names are case-insensitive per
-* RFC 2616).
-*/
- get enumerator()
- {
- var headers = [];
- for (var i in this._headers)
- {
- var supports = new SupportsString();
- supports.data = i;
- headers.push(supports);
- }
-
- return new nsSimpleEnumerator(headers);
- }
-};
-
-
-/**
-* Constructs an nsISimpleEnumerator for the given array of items.
-*
-* @param items : Array
-* the items, which must all implement nsISupports
-*/
-function nsSimpleEnumerator(items)
-{
- this._items = items;
- this._nextIndex = 0;
-}
-nsSimpleEnumerator.prototype =
-{
- hasMoreElements: function()
- {
- return this._nextIndex < this._items.length;
- },
- getNext: function()
- {
- if (!this.hasMoreElements())
- throw Cr.NS_ERROR_NOT_AVAILABLE;
-
- return this._items[this._nextIndex++];
- },
- QueryInterface: function(aIID)
- {
- if (Ci.nsISimpleEnumerator.equals(aIID) ||
- Ci.nsISupports.equals(aIID))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
-};
-
-
-/**
-* A representation of the data in an HTTP request.
-*
-* @param port : uint
-* the port on which the server receiving this request runs
-*/
-function Request(port)
-{
- /** Method of this request, e.g. GET or POST. */
- this._method = "";
-
- /** Path of the requested resource; empty paths are converted to '/'. */
- this._path = "";
-
- /** Query string, if any, associated with this request (not including '?'). */
- this._queryString = "";
-
- /** Scheme of requested resource, usually http, always lowercase. */
- this._scheme = "http";
-
- /** Hostname on which the requested resource resides. */
- this._host = undefined;
-
- /** Port number over which the request was received. */
- this._port = port;
-
- var bodyPipe = new Pipe(false, false, 0, PR_UINT32_MAX, null);
-
- /** Stream from which data in this request's body may be read. */
- this._bodyInputStream = bodyPipe.inputStream;
-
- /** Stream to which data in this request's body is written. */
- this._bodyOutputStream = bodyPipe.outputStream;
-
- /**
-* The headers in this request.
-*/
- this._headers = new nsHttpHeaders();
-
- /**
-* For the addition of ad-hoc properties and new functionality without having
-* to change nsIHttpRequest every time; currently lazily created, as its only
-* use is in directory listings.
-*/
- this._bag = null;
-}
-Request.prototype =
-{
- // SERVER METADATA
-
- //
- // see nsIHttpRequest.scheme
- //
- get scheme()
- {
- return this._scheme;
- },
-
- //
- // see nsIHttpRequest.host
- //
- get host()
- {
- return this._host;
- },
-
- //
- // see nsIHttpRequest.port
- //
- get port()
- {
- return this._port;
- },
-
- // REQUEST LINE
-
- //
- // see nsIHttpRequest.method
- //
- get method()
- {
- return this._method;
- },
-
- //
- // see nsIHttpRequest.httpVersion
- //
- get httpVersion()
- {
- return this._httpVersion.toString();
- },
-
- //
- // see nsIHttpRequest.path
- //
- get path()
- {
- return this._path;
- },
-
- //
- // see nsIHttpRequest.queryString
- //
- get queryString()
- {
- return this._queryString;
- },
-
- // HEADERS
-
- //
- // see nsIHttpRequest.getHeader
- //
- getHeader: function(name)
- {
- return this._headers.getHeader(name);
- },
-
- //
- // see nsIHttpRequest.hasHeader
- //
- hasHeader: function(name)
- {
- return this._headers.hasHeader(name);
- },
-
- //
- // see nsIHttpRequest.headers
- //
- get headers()
- {
- return this._headers.enumerator;
- },
-
- //
- // see nsIPropertyBag.enumerator
- //
- get enumerator()
- {
- this._ensurePropertyBag();
- return this._bag.enumerator;
- },
-
- //
- // see nsIHttpRequest.headers
- //
- get bodyInputStream()
- {
- return this._bodyInputStream;
- },
-
- //
- // see nsIPropertyBag.getProperty
- //
- getProperty: function(name)
- {
- this._ensurePropertyBag();
- return this._bag.getProperty(name);
- },
-
-
- // NSISUPPORTS
-
- //
- // see nsISupports.QueryInterface
- //
- QueryInterface: function(iid)
- {
- if (iid.equals(Ci.nsIHttpRequest) || iid.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
-
- // PRIVATE IMPLEMENTATION
-
- /** Ensures a property bag has been created for ad-hoc behaviors. */
- _ensurePropertyBag: function()
- {
- if (!this._bag)
- this._bag = new WritablePropertyBag();
- }
-};
-
-
-// XPCOM trappings
-if ("XPCOMUtils" in this && // Firefox 3.6 doesn't load XPCOMUtils in this scope for some reason...
- "generateNSGetFactory" in XPCOMUtils) {
- var NSGetFactory = XPCOMUtils.generateNSGetFactory([nsHttpServer]);
-}
-
-
-
-/**
-* Creates a new HTTP server listening for loopback traffic on the given port,
-* starts it, and runs the server until the server processes a shutdown request,
-* spinning an event loop so that events posted by the server's socket are
-* processed.
-*
-* This method is primarily intended for use in running this script from within
-* xpcshell and running a functional HTTP server without having to deal with
-* non-essential details.
-*
-* Note that running multiple servers using variants of this method probably
-* doesn't work, simply due to how the internal event loop is spun and stopped.
-*
-* @note
-* This method only works with Mozilla 1.9 (i.e., Firefox 3 or trunk code);
-* you should use this server as a component in Mozilla 1.8.
-* @param port
-* the port on which the server will run, or -1 if there exists no preference
-* for a specific port; note that attempting to use some values for this
-* parameter (particularly those below 1024) may cause this method to throw or
-* may result in the server being prematurely shut down
-* @param basePath
-* a local directory from which requests will be served (i.e., if this is
-* "/home/jwalden/" then a request to /index.html will load
-* /home/jwalden/index.html); if this is omitted, only the default URLs in
-* this server implementation will be functional
-*/
-function server(port, basePath)
-{
- if (basePath)
- {
- var lp = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- lp.initWithPath(basePath);
- }
-
- // if you're running this, you probably want to see debugging info
- DEBUG = true;
-
- var srv = new nsHttpServer();
- if (lp)
- srv.registerDirectory("/", lp);
- srv.registerContentType("sjs", SJS_TYPE);
- srv.identity.setPrimary("http", "localhost", port);
- srv.start(port);
-
- var thread = gThreadManager.currentThread;
- while (!srv.isStopped())
- thread.processNextEvent(true);
-
- // get rid of any pending requests
- while (thread.hasPendingEvents())
- thread.processNextEvent(true);
-
- DEBUG = false;
-}
-
-function startServerAsync(port, basePath)
-{
- if (basePath)
- {
- var lp = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- lp.initWithPath(basePath);
- }
-
- var srv = new nsHttpServer();
- if (lp)
- srv.registerDirectory("/", lp);
- srv.registerContentType("sjs", "sjs");
- srv.identity.setPrimary("http", "localhost", port);
- srv.start(port);
- return srv;
-}
-
-exports.nsHttpServer = nsHttpServer;
-exports.ScriptableInputStream = ScriptableInputStream;
-exports.server = server;
-exports.startServerAsync = startServerAsync;
diff --git a/tools/addon-sdk-1.12/lib/sdk/test/loader.js b/tools/addon-sdk-1.12/lib/sdk/test/loader.js
deleted file mode 100644
index 282cf5e..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/test/loader.js
+++ /dev/null
@@ -1,28 +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 { Loader, resolveURI, Require,
- unload, override, descriptor } = require('../loader/cuddlefish');
-
-exports.Loader = function(module, globals, packaging) {
- let options = packaging || require("@loader/options");
- options = override(options, {
- globals: override(require('../system/globals'), globals || {})
- });
-
- let loader = Loader(options);
- return Object.create(loader, descriptor({
- require: Require(loader, module),
- sandbox: function(id) {
- let requirement = loader.resolve(id, module.id);
- let uri = resolveURI(requirement, loader.mapping);
- return loader.sandboxes[uri];
- },
- unload: function(reason) {
- unload(loader, reason);
- }
- }));
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/test/runner.js b/tools/addon-sdk-1.12/lib/sdk/test/runner.js
deleted file mode 100644
index 4db9aca..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/test/runner.js
+++ /dev/null
@@ -1,150 +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 obsvc = require("../deprecated/observer-service");
-var { exit, stdout } = require("../system");
-var cfxArgs = require("@test/options");
-var { Cc, Ci} = require("chrome");
-
-function runTests(findAndRunTests) {
- var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
- .getService(Ci.nsIWindowWatcher);
-
- let ns = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
- let msg = 'Running tests...';
- let markup = '<?xml version="1.0"?><window xmlns="' + ns +
- '" windowtype="test:runner"><label>' + msg + '</label></window>';
- let url = "data:application/vnd.mozilla.xul+xml;charset=utf-8," + escape(markup);
-
-
- var window = ww.openWindow(null, url, "harness", "centerscreen", null);
-
- var harness = require("./harness");
-
- function onDone(tests) {
- stdout.write("\n");
- var total = tests.passed + tests.failed;
- stdout.write(tests.passed + " of " + total + " tests passed.\n");
-
- window.close();
- if (tests.failed == 0) {
- if (tests.passed === 0)
- stdout.write("No tests were run\n");
- exit(0);
- } else {
- printFailedTests(tests, cfxArgs.verbose, stdout.write);
- exit(1);
- }
- };
-
- // We have to wait for this window to be fully loaded *and* focused
- // in order to avoid it to mess with our various window/focus tests.
- // We are first waiting for our window to be fully loaded before ensuring
- // that it will take the focus, and then we wait for it to be focused.
- window.addEventListener("load", function onload() {
- window.removeEventListener("load", onload, true);
-
- window.addEventListener("focus", function onfocus() {
- window.removeEventListener("focus", onfocus, true);
- // Finally, we have to run test on next cycle, otherwise XPCOM components
- // are not correctly updated.
- // For ex: nsIFocusManager.getFocusedElementForWindow may throw
- // NS_ERROR_ILLEGAL_VALUE exception.
- require("../timers").setTimeout(function () {
- harness.runTests({
- findAndRunTests: findAndRunTests,
- iterations: cfxArgs.iterations || 1,
- filter: cfxArgs.filter,
- profileMemory: cfxArgs.profileMemory,
- stopOnError: cfxArgs.stopOnError,
- verbose: cfxArgs.verbose,
- print: stdout.write,
- onDone: onDone
- });
- }, 0);
- }, true);
- window.focus();
- }, true);
-}
-
-function printFailedTests(tests, verbose, print) {
- if (!verbose)
- return;
-
- let iterationNumber = 0;
- let singleIteration = tests.testRuns.length == 1;
- let padding = singleIteration ? "" : " ";
-
- print("\nThe following tests failed:\n");
-
- for each (let testRun in tests.testRuns) {
- iterationNumber++;
-
- if (!singleIteration)
- print(" Iteration " + iterationNumber + ":\n");
-
- for each (let test in testRun) {
- if (test.failed > 0) {
- print(padding + " " + test.name + ": " + test.errors +"\n");
- }
- }
- print("\n");
- }
-}
-
-function main() {
- var testsStarted = false;
-
- if (!testsStarted) {
- testsStarted = true;
- runTests(function findAndRunTests(loader, nextIteration) {
- loader.require("../deprecated/unit-test").findAndRunTests({
- testOutOfProcess: false,
- testInProcess: true,
- stopOnError: cfxArgs.stopOnError,
- filter: cfxArgs.filter,
- onDone: nextIteration
- });
- });
- }
-};
-
-if (require.main === module)
- main();
-
-exports.runTestsFromModule = function runTestsFromModule(module) {
- let id = module.id;
- // Make a copy of exports as it may already be frozen by module loader
- let exports = {};
- Object.keys(module.exports).forEach(function(key) {
- exports[key] = module.exports[key];
- });
-
- runTests(function findAndRunTests(loader, nextIteration) {
- // Consider that all these tests are CommonJS ones
- loader.require('../test').run(exports);
-
- // Reproduce what is done in unit-test-finder.findTests()
- let tests = [];
- for each (let name in Object.keys(exports).sort()) {
- tests.push({
- setup: exports.setup,
- teardown: exports.teardown,
- testFunction: exports[name],
- name: id + "." + name
- });
- }
-
- // Reproduce what is done by unit-test.findAndRunTests()
- var { TestRunner } = loader.require("../deprecated/unit-test");
- var runner = new TestRunner();
- runner.startMany({
- tests: tests,
- stopOnError: cfxArgs.stopOnError,
- onDone: nextIteration
- });
- });
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/test/tmp-file.js b/tools/addon-sdk-1.12/lib/sdk/test/tmp-file.js
deleted file mode 100644
index 634d2f1..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/test/tmp-file.js
+++ /dev/null
@@ -1,73 +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 system = require("sdk/system");
-const file = require("sdk/io/file");
-const unload = require("sdk/system/unload");
-
-// Retrieve the path to the OS temporary directory:
-const tmpDir = require("sdk/system").pathFor("TmpD");
-
-// List of all tmp file created
-let files = [];
-
-// Remove all tmp files on addon disabling
-unload.when(function () {
- files.forEach(function (path){
- // Catch exception in order to avoid leaking following files
- try {
- if (file.exists(path))
- file.remove(path);
- }
- catch(e) {
- console.exception(e);
- }
- });
-});
-
-// Utility function that synchronously reads local resource from the given
-// `uri` and returns content string. Read in binary mode.
-function readBinaryURI(uri) {
- let ioservice = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
- let channel = ioservice.newChannel(uri, "UTF-8", null);
- let stream = Cc["@mozilla.org/binaryinputstream;1"].
- createInstance(Ci.nsIBinaryInputStream);
- stream.setInputStream(channel.open());
-
- let data = "";
- while (true) {
- let available = stream.available();
- if (available <= 0)
- break;
- data += stream.readBytes(available);
- }
- stream.close();
-
- return data;
-}
-
-// Create a temporary file from a given string and returns its path
-exports.createFromString = function createFromString(data, tmpName) {
- let filename = (tmpName ? tmpName : "tmp-file") + "-" + (new Date().getTime());
- let path = file.join(tmpDir, filename);
-
- let tmpFile = file.open(path, "wb");
- tmpFile.write(data);
- tmpFile.close();
-
- // Register tmp file path
- files.push(path);
-
- return path;
-}
-
-// Create a temporary file from a given URL and returns its path
-exports.createFromURL = function createFromURL(url, tmpName) {
- let data = readBinaryURI(url);
- return exports.createFromString(data, tmpName);
-}
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/timers.js b/tools/addon-sdk-1.12/lib/sdk/timers.js
deleted file mode 100644
index bc72717..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/timers.js
+++ /dev/null
@@ -1,53 +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": "deprecated"
-};
-
-const { CC, Ci } = require('chrome');
-const { when: unload } = require('./system/unload');
-
-const { TYPE_ONE_SHOT, TYPE_REPEATING_SLACK } = Ci.nsITimer;
-const Timer = CC('@mozilla.org/timer;1', 'nsITimer');
-const timers = Object.create(null);
-
-// Last timer id.
-let lastID = 0;
-
-// Sets typer either by timeout or by interval
-// depending on a given type.
-function setTimer(type, callback, delay) {
- let id = ++ lastID;
- let timer = timers[id] = Timer();
- let args = Array.slice(arguments, 3);
- timer.initWithCallback({
- notify: function notify() {
- try {
- if (type === TYPE_ONE_SHOT)
- delete timers[id];
- callback.apply(null, args);
- }
- catch(error) {
- console.exception(error);
- }
- }
- }, delay || 0, type);
- return id;
-}
-
-function unsetTimer(id) {
- let timer = timers[id];
- delete timers[id];
- if (timer)
- timer.cancel();
-}
-
-exports.setTimeout = setTimer.bind(null, TYPE_ONE_SHOT);
-exports.setInterval = setTimer.bind(null, TYPE_REPEATING_SLACK);
-exports.clearTimeout = unsetTimer.bind(null);
-exports.clearInterval = unsetTimer.bind(null);
-
-unload(function() { Object.keys(timers).forEach(unsetTimer) });
diff --git a/tools/addon-sdk-1.12/lib/sdk/url.js b/tools/addon-sdk-1.12/lib/sdk/url.js
deleted file mode 100644
index 3581398..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/url.js
+++ /dev/null
@@ -1,236 +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": "experimental"
-};
-
-const { Cc, Ci, Cr } = require("chrome");
-
-const { Class } = require("./core/heritage");
-const base64 = require("./base64");
-
-var ios = Cc['@mozilla.org/network/io-service;1']
- .getService(Ci.nsIIOService);
-
-var resProt = ios.getProtocolHandler("resource")
- .QueryInterface(Ci.nsIResProtocolHandler);
-
-function newURI(uriStr, base) {
- try {
- let baseURI = base ? ios.newURI(base, null, null) : null;
- return ios.newURI(uriStr, null, baseURI);
- }
- catch (e if e.result == Cr.NS_ERROR_MALFORMED_URI) {
- throw new Error("malformed URI: " + uriStr);
- }
- catch (e if (e.result == Cr.NS_ERROR_FAILURE ||
- e.result == Cr.NS_ERROR_ILLEGAL_VALUE)) {
- throw new Error("invalid URI: " + uriStr);
- }
-}
-
-function resolveResourceURI(uri) {
- var resolved;
- try {
- resolved = resProt.resolveURI(uri);
- } catch (e if e.result == Cr.NS_ERROR_NOT_AVAILABLE) {
- throw new Error("resource does not exist: " + uri.spec);
- };
- return resolved;
-}
-
-let fromFilename = exports.fromFilename = function fromFilename(path) {
- var file = Cc['@mozilla.org/file/local;1']
- .createInstance(Ci.nsILocalFile);
- file.initWithPath(path);
- return ios.newFileURI(file).spec;
-};
-
-let toFilename = exports.toFilename = function toFilename(url) {
- var uri = newURI(url);
- if (uri.scheme == "resource")
- uri = newURI(resolveResourceURI(uri));
- if (uri.scheme == "chrome") {
- var channel = ios.newChannelFromURI(uri);
- try {
- channel = channel.QueryInterface(Ci.nsIFileChannel);
- return channel.file.path;
- } catch (e if e.result == Cr.NS_NOINTERFACE) {
- throw new Error("chrome url isn't on filesystem: " + url);
- }
- }
- if (uri.scheme == "file") {
- var file = uri.QueryInterface(Ci.nsIFileURL).file;
- return file.path;
- }
- throw new Error("cannot map to filename: " + url);
-};
-
-function URL(url, base) {
- if (!(this instanceof URL)) {
- return new URL(url, base);
- }
-
- var uri = newURI(url, base);
-
- var userPass = null;
- try {
- userPass = uri.userPass ? uri.userPass : null;
- } catch (e if e.result == Cr.NS_ERROR_FAILURE) {}
-
- var host = null;
- try {
- host = uri.host;
- } catch (e if e.result == Cr.NS_ERROR_FAILURE) {}
-
- var port = null;
- try {
- port = uri.port == -1 ? null : uri.port;
- } catch (e if e.result == Cr.NS_ERROR_FAILURE) {}
-
- this.__defineGetter__("scheme", function() uri.scheme);
- this.__defineGetter__("userPass", function() userPass);
- this.__defineGetter__("host", function() host);
- this.__defineGetter__("port", function() port);
- this.__defineGetter__("path", function() uri.path);
-
- Object.defineProperties(this, {
- toString: {
- value: function URL_toString() new String(uri.spec).toString(),
- enumerable: false
- },
- valueOf: {
- value: function() new String(uri.spec).valueOf(),
- enumerable: false
- },
- toSource: {
- value: function() new String(uri.spec).toSource(),
- enumerable: false
- }
- });
-
- return this;
-};
-
-URL.prototype = Object.create(String.prototype);
-exports.URL = URL;
-
-/**
- * Parse and serialize a Data URL.
- *
- * See: http://tools.ietf.org/html/rfc2397
- *
- * Note: Could be extended in the future to decode / encode automatically binary
- * data.
- */
-const DataURL = Class({
-
- get base64 () {
- return "base64" in this.parameters;
- },
-
- set base64 (value) {
- if (value)
- this.parameters["base64"] = "";
- else
- delete this.parameters["base64"];
- },
- /**
- * Initialize the Data URL object. If a uri is given, it will be parsed.
- *
- * @param {String} [uri] The uri to parse
- *
- * @throws {URIError} if the Data URL is malformed
- */
- initialize: function(uri) {
- // Due to bug 751834 it is not possible document and define these
- // properties in the prototype.
-
- /**
- * An hashmap that contains the parameters of the Data URL. By default is
- * empty, that accordingly to RFC is equivalent to {"charset" : "US-ASCII"}
- */
- this.parameters = {};
-
- /**
- * The MIME type of the data. By default is empty, that accordingly to RFC
- * is equivalent to "text/plain"
- */
- this.mimeType = "";
-
- /**
- * The string that represent the data in the Data URL
- */
- this.data = "";
-
- if (typeof uri === "undefined")
- return;
-
- uri = String(uri);
-
- let matches = uri.match(/^data:([^,]*),(.*)$/i);
-
- if (!matches)
- throw new URIError("Malformed Data URL: " + uri);
-
- let mediaType = matches[1].trim();
-
- this.data = decodeURIComponent(matches[2].trim());
-
- if (!mediaType)
- return;
-
- let parametersList = mediaType.split(";");
-
- this.mimeType = parametersList.shift().trim();
-
- for (let parameter, i = 0; parameter = parametersList[i++];) {
- let pairs = parameter.split("=");
- let name = pairs[0].trim();
- let value = pairs.length > 1 ? decodeURIComponent(pairs[1].trim()) : "";
-
- this.parameters[name] = value;
- }
-
- if (this.base64)
- this.data = base64.decode(this.data);
-
- },
-
- /**
- * Returns the object as a valid Data URL string
- *
- * @returns {String} The Data URL
- */
- toString : function() {
- let parametersList = [];
-
- for (let name in this.parameters) {
- let encodedParameter = encodeURIComponent(name);
- let value = this.parameters[name];
-
- if (value)
- encodedParameter += "=" + encodeURIComponent(value);
-
- parametersList.push(encodedParameter);
- }
-
- // If there is at least a parameter, add an empty string in order
- // to start with a `;` on join call.
- if (parametersList.length > 0)
- parametersList.unshift("");
-
- let data = this.base64 ? base64.encode(this.data) : this.data;
-
- return "data:" +
- this.mimeType +
- parametersList.join(";") + "," +
- encodeURIComponent(data);
- }
-});
-
-exports.DataURL = DataURL;
diff --git a/tools/addon-sdk-1.12/lib/sdk/util/array.js b/tools/addon-sdk-1.12/lib/sdk/util/array.js
deleted file mode 100644
index 764eeca..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/util/array.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "experimental"
-};
-
-/**
- * Returns `true` if given `array` contain given `element` or `false`
- * otherwise.
- * @param {Array} array
- * Target array.
- * @param {Object|String|Number|Boolean} element
- * Element being looked up.
- * @returns {Boolean}
- */
-var has = exports.has = function has(array, element) {
- // shorter and faster equivalent of `array.indexOf(element) >= 0`
- return !!~array.indexOf(element);
-};
-var hasAny = exports.hasAny = function hasAny(array, elements) {
- if (arguments.length < 2)
- return false;
- if (!Array.isArray(elements))
- elements = [ elements ];
- return array.some(function (element) {
- return has(elements, element);
- });
-};
-
-/**
- * Adds given `element` to the given `array` if it does not contain it yet.
- * `true` is returned if element was added otherwise `false` is returned.
- * @param {Array} array
- * Target array.
- * @param {Object|String|Number|Boolean} element
- * Element to be added.
- * @returns {Boolean}
- */
-var add = exports.add = function add(array, element) {
- var result;
- if ((result = !has(array, element)))
- array.push(element);
-
- return result;
-};
-
-/**
- * Removes first occurrence of the given `element` from the given `array`. If
- * `array` does not contain given `element` `false` is returned otherwise
- * `true` is returned.
- * @param {Array} array
- * Target array.
- * @param {Object|String|Number|Boolean} element
- * Element to be removed.
- * @returns {Boolean}
- */
-exports.remove = function remove(array, element) {
- var result;
- if ((result = has(array, element)))
- array.splice(array.indexOf(element), 1);
-
- return result;
-};
-
-/**
- * Produces a duplicate-free version of the given `array`.
- * @param {Array} array
- * Source array.
- * @returns {Array}
- */
-exports.unique = function unique(array) {
- var value = [];
- return array.forEach(function(element) {
- add(value, element);
- });
- return value;
-};
-
-exports.flatten = function flatten(array){
- var flat = [];
- for (var i = 0, l = array.length; i < l; i++) {
- flat = flat.concat(Array.isArray(array[i]) ? flatten(array[i]) : array[i]);
- }
- return flat;
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/util/collection.js b/tools/addon-sdk-1.12/lib/sdk/util/collection.js
deleted file mode 100644
index 54e7313..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/util/collection.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "experimental"
-};
-
-exports.Collection = Collection;
-
-/**
- * Adds a collection property to the given object. Setting the property to a
- * scalar value empties the collection and adds the value. Setting it to an
- * array empties the collection and adds all the items in the array.
- *
- * @param obj
- * The property will be defined on this object.
- * @param propName
- * The name of the property.
- * @param array
- * If given, this will be used as the collection's backing array.
- */
-exports.addCollectionProperty = function addCollProperty(obj, propName, array) {
- array = array || [];
- let publicIface = new Collection(array);
-
- obj.__defineSetter__(propName, function (itemOrItems) {
- array.splice(0, array.length);
- publicIface.add(itemOrItems);
- });
-
- obj.__defineGetter__(propName, function () {
- return publicIface;
- });
-};
-
-/**
- * A collection is ordered, like an array, but its items are unique, like a set.
- *
- * @param array
- * The collection is backed by an array. If this is given, it will be
- * used as the backing array. This way the caller can fully control the
- * collection. Otherwise a new empty array will be used, and no one but
- * the collection will have access to it.
- */
-function Collection(array) {
- array = array || [];
-
- /**
- * Provides iteration over the collection. Items are yielded in the order
- * they were added.
- */
- this.__iterator__ = function Collection___iterator__() {
- let items = array.slice();
- for (let i = 0; i < items.length; i++)
- yield items[i];
- };
-
- /**
- * The number of items in the collection.
- */
- this.__defineGetter__("length", function Collection_get_length() {
- return array.length;
- });
-
- /**
- * Adds a single item or an array of items to the collection. Any items
- * already contained in the collection are ignored.
- *
- * @param itemOrItems
- * An item or array of items.
- * @return The collection.
- */
- this.add = function Collection_add(itemOrItems) {
- let items = toArray(itemOrItems);
- for (let i = 0; i < items.length; i++) {
- let item = items[i];
- if (array.indexOf(item) < 0)
- array.push(item);
- }
- return this;
- };
-
- /**
- * Removes a single item or an array of items from the collection. Any items
- * not contained in the collection are ignored.
- *
- * @param itemOrItems
- * An item or array of items.
- * @return The collection.
- */
- this.remove = function Collection_remove(itemOrItems) {
- let items = toArray(itemOrItems);
- for (let i = 0; i < items.length; i++) {
- let idx = array.indexOf(items[i]);
- if (idx >= 0)
- array.splice(idx, 1);
- }
- return this;
- };
-};
-
-function toArray(itemOrItems) {
- let isArr = itemOrItems &&
- itemOrItems.constructor &&
- itemOrItems.constructor.name === "Array";
- return isArr ? itemOrItems : [itemOrItems];
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/util/deprecate.js b/tools/addon-sdk-1.12/lib/sdk/util/deprecate.js
deleted file mode 100644
index b38606a..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/util/deprecate.js
+++ /dev/null
@@ -1,27 +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": "experimental"
-};
-
-const traceback = require("../console/traceback");
-
-function deprecateUsage(msg) {
- // Print caller stacktrace in order to help figuring out which code
- // does use deprecated thing
- let stack = traceback.get().slice(0, -2);
- console.error("DEPRECATED: " + msg + "\n" + traceback.format(stack));
-}
-exports.deprecateUsage = deprecateUsage;
-
-function deprecateFunction(fun, msg) {
- return function deprecated() {
- deprecateUsage(msg);
- return fun.apply(this, arguments);
- };
-}
-exports.deprecateFunction = deprecateFunction;
diff --git a/tools/addon-sdk-1.12/lib/sdk/util/list.js b/tools/addon-sdk-1.12/lib/sdk/util/list.js
deleted file mode 100644
index 0a143d9..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/util/list.js
+++ /dev/null
@@ -1,78 +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 listNS = require('../core/namespace').ns();
-
-const List = Class({
- /**
- * List constructor can take any number of element to populate itself.
- * @params {Object|String|Number} element
- * @example
- * List(1,2,3).length == 3 // true
- */
- initialize: function List() {
- listNS(this).keyValueMap = [];
-
- for (let i = 0, ii = arguments.length; i < ii; i++)
- addListItem(this, arguments[i]);
- },
- /**
- * Number of elements in this list.
- * @type {Number}
- */
- get length() listNS(this).keyValueMap.length,
- /**
- * Returns a string representing this list.
- * @returns {String}
- */
- toString: function toString() 'List(' + listNS(this).keyValueMap + ')',
- /**
- * Custom iterator providing `List`s enumeration behavior.
- * We cant reuse `_iterator` that is defined by `Iterable` since it provides
- * iteration in an arbitrary order.
- * @see https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in
- * @param {Boolean} onKeys
- */
- __iterator__: function __iterator__(onKeys, onKeyValue) {
- let array = listNS(this).keyValueMap.slice(0),
- i = -1;
- for each(let element in array)
- yield onKeyValue ? [++i, element] : onKeys ? ++i : element;
- }
-});
-exports.List = List;
-
-function addListItem(that, value) {
- let list = listNS(that).keyValueMap,
- index = list.indexOf(value);
-
- if (-1 === index) {
- try {
- that[that.length] = value;
- }
- catch (e) {}
- list.push(value);
- }
-}
-exports.addListItem = addListItem;
-
-function removeListItem(that, element) {
- let list = listNS(that).keyValueMap,
- index = list.indexOf(element);
-
- if (0 <= index) {
- list.splice(index, 1);
- try {
- for (let length = list.length; index < length; index++)
- that[index] = list[index];
- that[list.length] = undefined;
- }
- catch(e){}
- }
-}
-exports.removeListItem = removeListItem;
-
-exports.listNS = listNS;
diff --git a/tools/addon-sdk-1.12/lib/sdk/util/object.js b/tools/addon-sdk-1.12/lib/sdk/util/object.js
deleted file mode 100644
index 4b1a2d4..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/util/object.js
+++ /dev/null
@@ -1,57 +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"
-};
-
-/**
- * Merges all the properties of all arguments into first argument. If two or
- * more argument objects have own properties with the same name, the property
- * is overridden, with precedence from right to left, implying, that properties
- * of the object on the left are overridden by a same named property of the
- * object on the right.
- *
- * Any argument given with "falsy" value - commonly `null` and `undefined` in
- * case of objects - are skipped.
- *
- * @examples
- * var a = { bar: 0, a: 'a' }
- * var b = merge(a, { foo: 'foo', bar: 1 }, { foo: 'bar', name: 'b' });
- * b === a // true
- * b.a // 'a'
- * b.foo // 'bar'
- * b.bar // 1
- * b.name // 'b'
- */
-function merge(source) {
- let descriptor = {};
- // `Boolean` converts the first parameter to a boolean value. Any object is
- // converted to `true` where `null` and `undefined` becames `false`. Therefore
- // the `filter` method will keep only objects that are defined and not null.
- Array.slice(arguments, 1).filter(Boolean).forEach(function onEach(properties) {
- Object.getOwnPropertyNames(properties).forEach(function(name) {
- descriptor[name] = Object.getOwnPropertyDescriptor(properties, name);
- });
- });
- return Object.defineProperties(source, descriptor);
-}
-exports.merge = merge;
-
-/**
- * Returns an object that inherits from the first argument and contains all the
- * properties from all following arguments.
- * `extend(source1, source2, source3)` is equivalent of
- * `merge(Object.create(source1), source2, source3)`.
- */
-function extend(source) {
- let rest = Array.slice(arguments, 1);
- rest.unshift(Object.create(source));
- return merge.apply(null, rest);
-}
-exports.extend = extend;
-
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/util/registry.js b/tools/addon-sdk-1.12/lib/sdk/util/registry.js
deleted file mode 100644
index 7d385f0..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/util/registry.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { EventEmitter } = require('../deprecated/events');
-const unload = require('../system/unload');
-
-const Registry = EventEmitter.compose({
- _registry: null,
- _constructor: null,
- constructor: function Registry(constructor) {
- this._registry = [];
- this._constructor = constructor;
- this.on('error', this._onError = this._onError.bind(this));
- unload.ensure(this, "_destructor");
- },
- _destructor: function _destructor() {
- let _registry = this._registry.slice(0);
- for each (let instance in _registry)
- this._emit('remove', instance);
- this._registry.splice(0);
- },
- _onError: function _onError(e) {
- if (!this._listeners('error').length)
- console.error(e);
- },
- has: function has(instance) {
- let _registry = this._registry;
- return (
- (0 <= _registry.indexOf(instance)) ||
- (instance && instance._public && 0 <= _registry.indexOf(instance._public))
- );
- },
- add: function add(instance) {
- let { _constructor, _registry } = this;
- if (!(instance instanceof _constructor))
- instance = new _constructor(instance);
- if (0 > _registry.indexOf(instance)) {
- _registry.push(instance);
- this._emit('add', instance);
- }
- return instance;
- },
- remove: function remove(instance) {
- let _registry = this._registry;
- let index = _registry.indexOf(instance)
- if (0 <= index) {
- this._emit('remove', instance);
- _registry.splice(index, 1);
- }
- }
-});
-exports.Registry = Registry;
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/util/uuid.js b/tools/addon-sdk-1.12/lib/sdk/util/uuid.js
deleted file mode 100644
index 0ebf981..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/util/uuid.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";
-
-module.metadata = {
- "stability": "unstable"
-};
-
-const { Cc, Ci, components: { ID: parseUUID } } = require('chrome');
-const { generateUUID } = Cc['@mozilla.org/uuid-generator;1'].
- getService(Ci.nsIUUIDGenerator);
-
-// Returns `uuid`. If `id` is passed then it's parsed to `uuid` and returned
-// if not then new one is generated.
-exports.uuid = function uuid(id) id ? parseUUID(id) : generateUUID()
diff --git a/tools/addon-sdk-1.12/lib/sdk/widget.js b/tools/addon-sdk-1.12/lib/sdk/widget.js
deleted file mode 100644
index f1236aa..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/widget.js
+++ /dev/null
@@ -1,938 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "stable"
-};
-
-// Widget content types
-const CONTENT_TYPE_URI = 1;
-const CONTENT_TYPE_HTML = 2;
-const CONTENT_TYPE_IMAGE = 3;
-
-const ERR_CONTENT = "No content or contentURL property found. Widgets must "
- + "have one or the other.",
- ERR_LABEL = "The widget must have a non-empty label property.",
- ERR_ID = "You have to specify a unique value for the id property of " +
- "your widget in order for the application to remember its " +
- "position.",
- ERR_DESTROYED = "The widget has been destroyed and can no longer be used.";
-
-// Supported events, mapping from DOM event names to our event names
-const EVENTS = {
- "click": "click",
- "mouseover": "mouseover",
- "mouseout": "mouseout",
-};
-
-if (!require("./system/xul-app").is("Firefox")) {
- throw new Error([
- "The widget module currently supports only Firefox. In the future ",
- "it will support other applications. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=560716 for more information."
- ].join(""));
-}
-
-const { validateOptions } = require("./deprecated/api-utils");
-const panels = require("./panel");
-const { EventEmitter, EventEmitterTrait } = require("./deprecated/events");
-const { Trait } = require("./deprecated/traits");
-const LightTrait = require('./deprecated/light-traits').Trait;
-const { Loader, Symbiont } = require("./content/content");
-const { Cortex } = require('./deprecated/cortex');
-const windowsAPI = require("./windows");
-const { WindowTracker } = require("./deprecated/window-utils");
-const { isBrowser } = require("./window/utils");
-const { setTimeout } = require("./timers");
-const unload = require("./system/unload");
-const { uuid } = require("./util/uuid");
-
-// Data types definition
-const valid = {
- number: { is: ["null", "undefined", "number"] },
- string: { is: ["null", "undefined", "string"] },
- id: {
- is: ["string"],
- ok: function (v) v.length > 0,
- msg: ERR_ID,
- readonly: true
- },
- label: {
- is: ["string"],
- ok: function (v) v.length > 0,
- msg: ERR_LABEL
- },
- panel: {
- is: ["null", "undefined", "object"],
- ok: function(v) !v || v instanceof panels.Panel
- },
- width: {
- is: ["null", "undefined", "number"],
- map: function (v) {
- if (null === v || undefined === v) v = 16;
- return v;
- },
- defaultValue: 16
- },
- allow: {
- is: ["null", "undefined", "object"],
- map: function (v) {
- if (!v) v = { script: true };
- return v;
- },
- get defaultValue() ({ script: true })
- },
-};
-
-// Widgets attributes definition
-let widgetAttributes = {
- label: valid.label,
- id: valid.id,
- tooltip: valid.string,
- width: valid.width,
- content: valid.string,
- panel: valid.panel,
- allow: valid.allow
-};
-
-// Import data definitions from loader, but don't compose with it as Model
-// functions allow us to recreate easily all Loader code.
-let loaderAttributes = require("./content/loader").validationAttributes;
-for (let i in loaderAttributes)
- widgetAttributes[i] = loaderAttributes[i];
-
-widgetAttributes.contentURL.optional = true;
-
-// Widgets public events list, that are automatically binded in options object
-const WIDGET_EVENTS = [
- "click",
- "mouseover",
- "mouseout",
- "error",
- "message",
- "attach"
-];
-
-// `Model` utility functions that help creating these various Widgets objects
-let model = {
-
- // Validate one attribute using api-utils.js:validateOptions function
- _validate: function _validate(name, suspect, validation) {
- let $1 = {};
- $1[name] = suspect;
- let $2 = {};
- $2[name] = validation;
- return validateOptions($1, $2)[name];
- },
-
- /**
- * This method has two purposes:
- * 1/ Validate and define, on a given object, a set of attribute
- * 2/ Emit a "change" event on this object when an attribute is changed
- *
- * @params {Object} object
- * Object on which we can bind attributes on and watch for their changes.
- * This object must have an EventEmitter interface, or, at least `_emit`
- * method
- * @params {Object} attrs
- * Dictionary of attributes definition following api-utils:validateOptions
- * scheme
- * @params {Object} values
- * Dictionary of attributes default values
- */
- setAttributes: function setAttributes(object, attrs, values) {
- let properties = {};
- for (let name in attrs) {
- let value = values[name];
- let req = attrs[name];
-
- // Retrieve default value from typedef if the value is not defined
- if ((typeof value == "undefined" || value == null) && req.defaultValue)
- value = req.defaultValue;
-
- // Check for valid value if value is defined or mandatory
- if (!req.optional || typeof value != "undefined")
- value = model._validate(name, value, req);
-
- // In any case, define this property on `object`
- let property = null;
- if (req.readonly) {
- property = {
- value: value,
- writable: false,
- enumerable: true,
- configurable: false
- };
- }
- else {
- property = model._createWritableProperty(name, value);
- }
-
- properties[name] = property;
- }
- Object.defineProperties(object, properties);
- },
-
- // Generate ES5 property definition for a given attribute
- _createWritableProperty: function _createWritableProperty(name, value) {
- return {
- get: function () {
- return value;
- },
- set: function (newValue) {
- value = newValue;
- // The main goal of all this Model stuff is here:
- // We want to forward all changes to some listeners
- this._emit("change", name, value);
- },
- enumerable: true,
- configurable: false
- };
- },
-
- /**
- * Automagically register listeners in options dictionary
- * by detecting listener attributes with name starting with `on`
- *
- * @params {Object} object
- * Target object that need to follow EventEmitter interface, or, at least,
- * having `on` method.
- * @params {Array} events
- * List of events name to automatically bind.
- * @params {Object} listeners
- * Dictionary of event listener functions to register.
- */
- setEvents: function setEvents(object, events, listeners) {
- for (let i = 0, l = events.length; i < l; i++) {
- let name = events[i];
- let onName = "on" + name[0].toUpperCase() + name.substr(1);
- if (!listeners[onName])
- continue;
- object.on(name, listeners[onName].bind(object));
- }
- }
-
-};
-
-
-/**
- * Main Widget class: entry point of the widget API
- *
- * Allow to control all widget across all existing windows with a single object.
- * Widget.getView allow to retrieve a WidgetView instance to control a widget
- * specific to one window.
- */
-const WidgetTrait = LightTrait.compose(EventEmitterTrait, LightTrait({
-
- _initWidget: function _initWidget(options) {
- model.setAttributes(this, widgetAttributes, options);
-
- browserManager.validate(this);
-
- // We must have at least content or contentURL defined
- if (!(this.content || this.contentURL))
- throw new Error(ERR_CONTENT);
-
- this._views = [];
-
- // Set tooltip to label value if we don't have tooltip defined
- if (!this.tooltip)
- this.tooltip = this.label;
-
- model.setEvents(this, WIDGET_EVENTS, options);
-
- this.on('change', this._onChange.bind(this));
-
- let self = this;
- this._port = EventEmitterTrait.create({
- emit: function () {
- let args = arguments;
- self._views.forEach(function(v) v.port.emit.apply(v.port, args));
- }
- });
- // expose wrapped port, that exposes only public properties.
- this._port._public = Cortex(this._port);
-
- // Register this widget to browser manager in order to create new widget on
- // all new windows
- browserManager.addItem(this);
- },
-
- _onChange: function _onChange(name, value) {
- // Set tooltip to label value if we don't have tooltip defined
- if (name == 'tooltip' && !value) {
- // we need to change tooltip again in order to change the value of the
- // attribute itself
- this.tooltip = this.label;
- return;
- }
-
- // Forward attributes changes to WidgetViews
- if (['width', 'tooltip', 'content', 'contentURL'].indexOf(name) != -1) {
- this._views.forEach(function(v) v[name] = value);
- }
- },
-
- _onEvent: function _onEvent(type, eventData) {
- this._emit(type, eventData);
- },
-
- _createView: function _createView() {
- // Create a new WidgetView instance
- let view = WidgetView(this);
-
- // Keep a reference to it
- this._views.push(view);
-
- return view;
- },
-
- // a WidgetView instance is destroyed
- _onViewDestroyed: function _onViewDestroyed(view) {
- let idx = this._views.indexOf(view);
- this._views.splice(idx, 1);
- },
-
- /**
- * Called on browser window closed, to destroy related WidgetViews
- * @params {ChromeWindow} window
- * Window that has been closed
- */
- _onWindowClosed: function _onWindowClosed(window) {
- for each (let view in this._views) {
- if (view._isInChromeWindow(window)) {
- view.destroy();
- break;
- }
- }
- },
-
- /**
- * Get the WidgetView instance related to a BrowserWindow instance
- * @params {BrowserWindow} window
- * BrowserWindow reference from "windows" module
- */
- getView: function getView(window) {
- for each (let view in this._views) {
- if (view._isInWindow(window)) {
- return view._public;
- }
- }
- return null;
- },
-
- get port() this._port._public,
- set port(v) {}, // Work around Cortex failure with getter without setter
- // See bug 653464
- _port: null,
-
- postMessage: function postMessage(message) {
- this._views.forEach(function(v) v.postMessage(message));
- },
-
- destroy: function destroy() {
- if (this.panel)
- this.panel.destroy();
-
- // Dispatch destroy calls to views
- // we need to go backward as we remove items from this array in
- // _onViewDestroyed
- for (let i = this._views.length - 1; i >= 0; i--)
- this._views[i].destroy();
-
- // Unregister widget to stop creating it over new windows
- // and allow creation of new widget with same id
- browserManager.removeItem(this);
- }
-
-}));
-
-// Widget constructor
-const Widget = function Widget(options) {
- let w = WidgetTrait.create(Widget.prototype);
- w._initWidget(options);
-
- // Return a Cortex of widget in order to hide private attributes like _onEvent
- let _public = Cortex(w);
- unload.ensure(_public, "destroy");
- return _public;
-}
-exports.Widget = Widget;
-
-
-
-/**
- * WidgetView is an instance of a widget for a specific window.
- *
- * This is an external API that can be retrieved by calling Widget.getView or
- * by watching `attach` event on Widget.
- */
-const WidgetViewTrait = LightTrait.compose(EventEmitterTrait, LightTrait({
-
- // Reference to the matching WidgetChrome
- // set right after constructor call
- _chrome: null,
-
- // Public interface of the WidgetView, passed in `attach` event or in
- // Widget.getView
- _public: null,
-
- _initWidgetView: function WidgetView__initWidgetView(baseWidget) {
- this._baseWidget = baseWidget;
-
- model.setAttributes(this, widgetAttributes, baseWidget);
-
- this.on('change', this._onChange.bind(this));
-
- let self = this;
- this._port = EventEmitterTrait.create({
- emit: function () {
- if (!self._chrome)
- throw new Error(ERR_DESTROYED);
- self._chrome.update(self._baseWidget, "emit", arguments);
- }
- });
- // expose wrapped port, that exposes only public properties.
- this._port._public = Cortex(this._port);
-
- this._public = Cortex(this);
- },
-
- // Called by WidgetChrome, when the related Worker is applied to the document,
- // so that we can start sending events to it
- _onWorkerReady: function () {
- // Emit an `attach` event with a WidgetView instance without private attrs
- this._baseWidget._emit("attach", this._public);
- },
-
- _onChange: function WidgetView__onChange(name, value) {
- if (name == 'tooltip' && !value) {
- this.tooltip = this.label;
- return;
- }
-
- // Forward attributes changes to WidgetChrome instance
- if (['width', 'tooltip', 'content', 'contentURL'].indexOf(name) != -1) {
- this._chrome.update(this._baseWidget, name, value);
- }
- },
-
- _onEvent: function WidgetView__onEvent(type, eventData, domNode) {
- // Dispatch event in view
- this._emit(type, eventData);
-
- // And forward it to the main Widget object
- if ("click" == type || type.indexOf("mouse") == 0)
- this._baseWidget._onEvent(type, this._public);
- else
- this._baseWidget._onEvent(type, eventData);
-
- // Special case for click events: if the widget doesn't have a click
- // handler, but it does have a panel, display the panel.
- if ("click" == type && !this._listeners("click").length && this.panel)
- this.panel.show(domNode);
- },
-
- _isInWindow: function WidgetView__isInWindow(window) {
- return windowsAPI.BrowserWindow({
- window: this._chrome.window
- }) == window;
- },
-
- _isInChromeWindow: function WidgetView__isInChromeWindow(window) {
- return this._chrome.window == window;
- },
-
- _onPortEvent: function WidgetView__onPortEvent(args) {
- let port = this._port;
- port._emit.apply(port, args);
- let basePort = this._baseWidget._port;
- basePort._emit.apply(basePort, args);
- },
-
- get port() this._port._public,
- set port(v) {}, // Work around Cortex failure with getter without setter
- // See bug 653464
- _port: null,
-
- postMessage: function WidgetView_postMessage(message) {
- if (!this._chrome)
- throw new Error(ERR_DESTROYED);
- this._chrome.update(this._baseWidget, "postMessage", message);
- },
-
- destroy: function WidgetView_destroy() {
- this._chrome.destroy();
- delete this._chrome;
- this._baseWidget._onViewDestroyed(this);
- this._emit("detach");
- }
-
-}));
-
-const WidgetView = function WidgetView(baseWidget) {
- let w = WidgetViewTrait.create(WidgetView.prototype);
- w._initWidgetView(baseWidget);
- return w;
-}
-
-
-
-/**
- * Keeps track of all browser windows.
- * Exposes methods for adding/removing widgets
- * across all open windows (and future ones).
- * Create a new instance of BrowserWindow per window.
- */
-let browserManager = {
- items: [],
- windows: [],
-
- // Registers the manager to listen for window openings and closings. Note
- // that calling this method can cause onTrack to be called immediately if
- // there are open windows.
- init: function () {
- let windowTracker = new WindowTracker(this);
- unload.ensure(windowTracker);
- },
-
- // Registers a window with the manager. This is a WindowTracker callback.
- onTrack: function browserManager_onTrack(window) {
- if (isBrowser(window)) {
- let win = new BrowserWindow(window);
- win.addItems(this.items);
- this.windows.push(win);
- }
- },
-
- // Unregisters a window from the manager. It's told to undo all
- // modifications. This is a WindowTracker callback. Note that when
- // WindowTracker is unloaded, it calls onUntrack for every currently opened
- // window. The browserManager therefore doesn't need to specially handle
- // unload itself, since unloading the browserManager means untracking all
- // currently opened windows.
- onUntrack: function browserManager_onUntrack(window) {
- if (isBrowser(window)) {
- this.items.forEach(function(i) i._onWindowClosed(window));
- for (let i = 0; i < this.windows.length; i++) {
- if (this.windows[i].window == window) {
- this.windows.splice(i, 1)[0];
- return;
- }
- }
-
- }
- },
-
- // Used to validate widget by browserManager before adding it,
- // in order to check input very early in widget constructor
- validate : function (item) {
- let idx = this.items.indexOf(item);
- if (idx > -1)
- throw new Error("The widget " + item + " has already been added.");
- if (item.id) {
- let sameId = this.items.filter(function(i) i.id == item.id);
- if (sameId.length > 0)
- throw new Error("This widget ID is already used: " + item.id);
- } else {
- item.id = this.items.length;
- }
- },
-
- // Registers an item with the manager. It's added to all currently registered
- // windows, and when new windows are registered it will be added to them, too.
- addItem: function browserManager_addItem(item) {
- this.items.push(item);
- this.windows.forEach(function (w) w.addItems([item]));
- },
-
- // Unregisters an item from the manager. It's removed from all windows that
- // are currently registered.
- removeItem: function browserManager_removeItem(item) {
- let idx = this.items.indexOf(item);
- if (idx > -1)
- this.items.splice(idx, 1);
- }
-};
-
-
-
-/**
- * Keeps track of a single browser window.
- *
- * This is where the core of how a widget's content is added to a window lives.
- */
-function BrowserWindow(window) {
- this.window = window;
- this.doc = window.document;
-}
-
-BrowserWindow.prototype = {
-
- // Adds an array of items to the window.
- addItems: function BW_addItems(items) {
- items.forEach(this._addItemToWindow, this);
- },
-
- _addItemToWindow: function BW__addItemToWindow(baseWidget) {
- // Create a WidgetView instance
- let widget = baseWidget._createView();
-
- // Create a WidgetChrome instance
- let item = new WidgetChrome({
- widget: widget,
- doc: this.doc,
- window: this.window
- });
-
- widget._chrome = item;
-
- this._insertNodeInToolbar(item.node);
-
- // We need to insert Widget DOM Node before finishing widget view creation
- // (because fill creates an iframe and tries to access its docShell)
- item.fill();
- },
-
- _insertNodeInToolbar: function BW__insertNodeInToolbar(node) {
- // Add to the customization palette
- let toolbox = this.doc.getElementById("navigator-toolbox");
- let palette = toolbox.palette;
- palette.appendChild(node);
-
- // Search for widget toolbar by reading toolbar's currentset attribute
- let container = null;
- let toolbars = this.doc.getElementsByTagName("toolbar");
- let id = node.getAttribute("id");
- for (let i = 0, l = toolbars.length; i < l; i++) {
- let toolbar = toolbars[i];
- if (toolbar.getAttribute("currentset").indexOf(id) == -1)
- continue;
- container = toolbar;
- }
-
- // if widget isn't in any toolbar, add it to the addon-bar
- // TODO: we may want some "first-launch" module to do this only on very
- // first execution
- if (!container) {
- container = this.doc.getElementById("addon-bar");
- // TODO: find a way to make the following code work when we use "cfx run":
- // http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser.js#8586
- // until then, force display of addon bar directly from sdk code
- // https://bugzilla.mozilla.org/show_bug.cgi?id=627484
- if (container.collapsed)
- this.window.toggleAddonBar();
- }
-
- // Now retrieve a reference to the next toolbar item
- // by reading currentset attribute on the toolbar
- let nextNode = null;
- let currentSet = container.getAttribute("currentset");
- let ids = (currentSet == "__empty") ? [] : currentSet.split(",");
- let idx = ids.indexOf(id);
- if (idx != -1) {
- for (let i = idx; i < ids.length; i++) {
- nextNode = this.doc.getElementById(ids[i]);
- if (nextNode)
- break;
- }
- }
-
- // Finally insert our widget in the right toolbar and in the right position
- container.insertItem(id, nextNode, null, false);
-
- // Update DOM in order to save position: which toolbar, and which position
- // in this toolbar. But only do this the first time we add it to the toolbar
- // Otherwise, this code will collide with other instance of Widget module
- // during Firefox startup. See bug 685929.
- if (ids.indexOf(id) == -1) {
- container.setAttribute("currentset", container.currentSet);
- // Save DOM attribute in order to save position on new window opened
- this.window.document.persist(container.id, "currentset");
- }
- }
-}
-
-
-/**
- * Final Widget class that handles chrome DOM Node:
- * - create initial DOM nodes
- * - receive instruction from WidgetView through update method and update DOM
- * - watch for DOM events and forward them to WidgetView
- */
-function WidgetChrome(options) {
- this.window = options.window;
- this._doc = options.doc;
- this._widget = options.widget;
- this._symbiont = null; // set later
- this.node = null; // set later
-
- this._createNode();
-}
-
-// Update a property of a widget.
-WidgetChrome.prototype.update = function WC_update(updatedItem, property, value) {
- switch(property) {
- case "contentURL":
- case "content":
- this.setContent();
- break;
- case "width":
- this.node.style.minWidth = value + "px";
- this.node.querySelector("iframe").style.width = value + "px";
- break;
- case "tooltip":
- this.node.setAttribute("tooltiptext", value);
- break;
- case "postMessage":
- this._symbiont.postMessage(value);
- break;
- case "emit":
- let port = this._symbiont.port;
- port.emit.apply(port, value);
- break;
- }
-}
-
-// Add a widget to this window.
-WidgetChrome.prototype._createNode = function WC__createNode() {
- // XUL element container for widget
- let node = this._doc.createElement("toolbaritem");
- let guid = String(uuid());
-
- // Temporary work around require("self") failing on unit-test execution ...
- let jetpackID = "testID";
- try {
- jetpackID = require("./self").id;
- } catch(e) {}
-
- // Compute an unique and stable widget id with jetpack id and widget.id
- let id = "widget:" + jetpackID + "-" + this._widget.id;
- node.setAttribute("id", id);
- node.setAttribute("label", this._widget.label);
- node.setAttribute("tooltiptext", this._widget.tooltip);
- node.setAttribute("align", "center");
- // Bug 626326: Prevent customize toolbar context menu to appear
- node.setAttribute("context", "");
-
- // TODO move into a stylesheet, configurable by consumers.
- // Either widget.style, exposing the style object, or a URL
- // (eg, can load local stylesheet file).
- node.setAttribute("style", [
- "overflow: hidden; margin: 1px 2px 1px 2px; padding: 0px;",
- "min-height: 16px;",
- ].join(""));
-
- node.style.minWidth = this._widget.width + "px";
-
- this.node = node;
-}
-
-// Initial population of a widget's content.
-WidgetChrome.prototype.fill = function WC_fill() {
- // Create element
- var iframe = this._doc.createElement("iframe");
- iframe.setAttribute("type", "content");
- iframe.setAttribute("transparent", "transparent");
- iframe.style.overflow = "hidden";
- iframe.style.height = "16px";
- iframe.style.maxHeight = "16px";
- iframe.style.width = this._widget.width + "px";
- iframe.setAttribute("flex", "1");
- iframe.style.border = "none";
- iframe.style.padding = "0px";
-
- // Do this early, because things like contentWindow are null
- // until the node is attached to a document.
- this.node.appendChild(iframe);
-
- // add event handlers
- this.addEventHandlers();
-
- // set content
- this.setContent();
-}
-
-// Get widget content type.
-WidgetChrome.prototype.getContentType = function WC_getContentType() {
- if (this._widget.content)
- return CONTENT_TYPE_HTML;
- return (this._widget.contentURL && /\.(jpg|gif|png|ico)$/.test(this._widget.contentURL))
- ? CONTENT_TYPE_IMAGE : CONTENT_TYPE_URI;
-}
-
-// Set widget content.
-WidgetChrome.prototype.setContent = function WC_setContent() {
- let type = this.getContentType();
- let contentURL = null;
-
- switch (type) {
- case CONTENT_TYPE_HTML:
- contentURL = "data:text/html;charset=utf-8," + encodeURIComponent(this._widget.content);
- break;
- case CONTENT_TYPE_URI:
- contentURL = this._widget.contentURL;
- break;
- case CONTENT_TYPE_IMAGE:
- let imageURL = this._widget.contentURL;
- contentURL = "data:text/html;charset=utf-8,<html><body><img src='" +
- encodeURI(imageURL) + "'></body></html>";
- break;
- default:
- throw new Error("The widget's type cannot be determined.");
- }
-
- let iframe = this.node.firstElementChild;
-
- let self = this;
- // Cleanup previously created symbiont (in case we are update content)
- if (this._symbiont)
- this._symbiont.destroy();
-
- this._symbiont = Trait.compose(Symbiont.resolve({
- _onContentScriptEvent: "_onContentScriptEvent-not-used",
- _onInit: "_initSymbiont"
- }), {
- // Overload `Symbiont._onInit` in order to know when the related worker
- // is ready.
- _onInit: function () {
- this._initSymbiont();
- self._widget._onWorkerReady();
- },
- _onContentScriptEvent: function () {
- // Redirect events to WidgetView
- self._widget._onPortEvent(arguments);
- }
- })({
- frame: iframe,
- contentURL: contentURL,
- contentScriptFile: this._widget.contentScriptFile,
- contentScript: this._widget.contentScript,
- contentScriptWhen: this._widget.contentScriptWhen,
- contentScriptOptions: this._widget.contentScriptOptions,
- allow: this._widget.allow,
- onMessage: function(message) {
- setTimeout(function() {
- self._widget._onEvent("message", message);
- }, 0);
- }
- });
-}
-
-// Detect if document consists of a single image.
-WidgetChrome._isImageDoc = function WC__isImageDoc(doc) {
- return doc.body.childNodes.length == 1 &&
- doc.body.firstElementChild &&
- doc.body.firstElementChild.tagName == "IMG";
-}
-
-// Set up all supported events for a widget.
-WidgetChrome.prototype.addEventHandlers = function WC_addEventHandlers() {
- let contentType = this.getContentType();
-
- let self = this;
- let listener = function(e) {
- // Ignore event firings that target the iframe.
- if (e.target == self.node.firstElementChild)
- return;
-
- // The widget only supports left-click for now,
- // so ignore right-clicks.
- if (e.type == "click" && e.button == 2)
- return;
-
- // Proxy event to the widget
- setTimeout(function() {
- self._widget._onEvent(EVENTS[e.type], null, self.node);
- }, 0);
- };
-
- this.eventListeners = {};
- let iframe = this.node.firstElementChild;
- for (let type in EVENTS) {
- iframe.addEventListener(type, listener, true, true);
-
- // Store listeners for later removal
- this.eventListeners[type] = listener;
- }
-
- // On document load, make modifications required for nice default
- // presentation.
- function loadListener(e) {
- let containerStyle = self.window.getComputedStyle(self.node.parentNode);
- // Ignore event firings that target the iframe
- if (e.target == iframe)
- return;
- // Ignore about:blank loads
- if (e.type == "load" && e.target.location == "about:blank")
- return;
-
- // We may have had an unload event before that cleaned up the symbiont
- if (!self._symbiont)
- self.setContent();
-
- let doc = e.target;
- if (contentType == CONTENT_TYPE_IMAGE || WidgetChrome._isImageDoc(doc)) {
- // Force image content to size.
- // Add-on authors must size their images correctly.
- doc.body.firstElementChild.style.width = self._widget.width + "px";
- doc.body.firstElementChild.style.height = "16px";
- }
-
- // Extend the add-on bar's default text styles to the widget.
- doc.body.style.color = containerStyle.color;
- doc.body.style.fontFamily = containerStyle.fontFamily;
- doc.body.style.fontSize = containerStyle.fontSize;
- doc.body.style.fontWeight = containerStyle.fontWeight;
- doc.body.style.textShadow = containerStyle.textShadow;
- // Allow all content to fill the box by default.
- doc.body.style.margin = "0";
- }
- iframe.addEventListener("load", loadListener, true);
- this.eventListeners["load"] = loadListener;
-
- // Register a listener to unload symbiont if the toolbaritem is moved
- // on user toolbars customization
- function unloadListener(e) {
- if (e.target.location == "about:blank")
- return;
- self._symbiont.destroy();
- self._symbiont = null;
- // This may fail but not always, it depends on how the node is
- // moved or removed
- try {
- self.setContent();
- } catch(e) {}
-
- }
-
- iframe.addEventListener("unload", unloadListener, true);
- this.eventListeners["unload"] = unloadListener;
-}
-
-// Remove and unregister the widget from everything
-WidgetChrome.prototype.destroy = function WC_destroy(removedItems) {
- // remove event listeners
- for (let type in this.eventListeners) {
- let listener = this.eventListeners[type];
- this.node.firstElementChild.removeEventListener(type, listener, true);
- }
- // remove dom node
- this.node.parentNode.removeChild(this.node);
- // cleanup symbiont
- this._symbiont.destroy();
- // cleanup itself
- this.eventListeners = null;
- this._widget = null;
- this._symbiont = null;
-}
-
-// Init the browserManager only after setting prototypes and such above, because
-// it will cause browserManager.onTrack to be called immediately if there are
-// open windows.
-browserManager.init();
diff --git a/tools/addon-sdk-1.12/lib/sdk/window/browser.js b/tools/addon-sdk-1.12/lib/sdk/window/browser.js
deleted file mode 100644
index 2b63a83..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/window/browser.js
+++ /dev/null
@@ -1,41 +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 { windowNS } = require('./namespace');
-const { on, off, once } = require('../event/core');
-const { method } = require('../lang/functional');
-const { getWindowTitle } = require('./utils');
-const unload = require('../system/unload');
-const { getMode } = require('../private-browsing/utils');
-const { EventTarget } = require('../event/target');
-
-const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec, consider using require("tabs") instead';
-
-const BrowserWindow = Class({
- initialize: function initialize(options) {
- EventTarget.prototype.initialize.call(this, options);
- windowNS(this).window = options.window;
- },
- activate: function activate() {
- // TODO
- return null;
- },
- close: function() {
- throw new Error(ERR_FENNEC_MSG);
- return null;
- },
- get title() getWindowTitle(windowNS(this).window),
- // NOTE: Fennec only has one window, which is assumed below
- // TODO: remove assumption below
- // NOTE: tabs requires windows
- get tabs() require('../tabs'),
- get activeTab() require('../tabs').activeTab,
- on: method(on),
- removeListener: method(off),
- once: method(once),
- get isPrivateBrowsing() getMode(windowNS(this).window),
-});
-exports.BrowserWindow = BrowserWindow;
diff --git a/tools/addon-sdk-1.12/lib/sdk/window/namespace.js b/tools/addon-sdk-1.12/lib/sdk/window/namespace.js
deleted file mode 100644
index b486f88..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/window/namespace.js
+++ /dev/null
@@ -1,6 +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";
-
-exports.windowNS = require('../core/namespace').ns();
diff --git a/tools/addon-sdk-1.12/lib/sdk/window/utils.js b/tools/addon-sdk-1.12/lib/sdk/window/utils.js
deleted file mode 100644
index 0bca8b1..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/window/utils.js
+++ /dev/null
@@ -1,205 +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 { Cc, Ci } = require('chrome');
-const array = require('../util/array');
-
-const windowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1'].
- getService(Ci.nsIWindowWatcher);
-const appShellService = Cc['@mozilla.org/appshell/appShellService;1'].
- getService(Ci.nsIAppShellService);
-const observers = require('../deprecated/observer-service');
-const WM = Cc['@mozilla.org/appshell/window-mediator;1'].
- getService(Ci.nsIWindowMediator);
-
-const BROWSER = 'navigator:browser',
- URI_BROWSER = 'chrome://browser/content/browser.xul',
- NAME = '_blank',
- FEATURES = 'chrome,all,dialog=no';
-
-function getMostRecentBrowserWindow() {
- return WM.getMostRecentWindow(BROWSER);
-}
-exports.getMostRecentBrowserWindow = getMostRecentBrowserWindow;
-
-/**
- * Returns the ID of the window's current inner window.
- */
-function getInnerId(window) {
- return window.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
-};
-exports.getInnerId = getInnerId;
-
-/**
- * Returns the ID of the window's outer window.
- */
-function getOuterId(window) {
- return window.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
-};
-exports.getOuterId = getOuterId;
-
-/**
- * Returns `nsIXULWindow` for the given `nsIDOMWindow`.
- */
-function getXULWindow(window) {
- return window.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIWebNavigation).
- QueryInterface(Ci.nsIDocShellTreeItem).
- treeOwner.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIXULWindow);
-};
-exports.getXULWindow = getXULWindow;
-
-/**
- * Returns `nsIBaseWindow` for the given `nsIDOMWindow`.
- */
-function getBaseWindow(window) {
- return window.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIWebNavigation).
- QueryInterface(Ci.nsIDocShell).
- QueryInterface(Ci.nsIDocShellTreeItem).
- treeOwner.
- QueryInterface(Ci.nsIBaseWindow);
-}
-exports.getBaseWindow = getBaseWindow;
-
-function getWindowDocShell(window) window.gBrowser.docShell;
-exports.getWindowDocShell = getWindowDocShell;
-
-function getWindowLoadingContext(window) {
- return getWindowDocShell(window).
- QueryInterface(Ci.nsILoadContext);
-}
-exports.getWindowLoadingContext = getWindowLoadingContext;
-
-/**
- * Removes given window from the application's window registry. Unless
- * `options.close` is `false` window is automatically closed on application
- * quit.
- * @params {nsIDOMWindow} window
- * @params {Boolean} options.close
- */
-function backgroundify(window, options) {
- let base = getBaseWindow(window);
- base.visibility = false;
- base.enabled = false;
- appShellService.unregisterTopLevelWindow(getXULWindow(window));
- if (!options || options.close !== false)
- observers.add('quit-application-granted', window.close.bind(window));
-
- return window;
-}
-exports.backgroundify = backgroundify;
-
-/**
- * Takes hash of options and serializes it to a features string that
- * can be used passed to `window.open`. For more details on features string see:
- * https://developer.mozilla.org/en/DOM/window.open#Position_and_size_features
- */
-function serializeFeatures(options) {
- return Object.keys(options).reduce(function(result, name) {
- let value = options[name];
- return result + ',' + name + '=' +
- (value === true ? 'yes' : value === false ? 'no' : value);
- }, '').substr(1);
-}
-
-/**
- * Opens a top level window and returns it's `nsIDOMWindow` representation.
- * @params {String} uri
- * URI of the document to be loaded into window.
- * @params {nsIDOMWindow} options.parent
- * Used as parent for the created window.
- * @params {String} options.name
- * Optional name that is assigned to the window.
- * @params {Object} options.features
- * Map of key, values like: `{ width: 10, height: 15, chrome: true }`.
- */
-function open(uri, options) {
- options = options || {};
- return windowWatcher.
- openWindow(options.parent || null,
- uri,
- options.name || null,
- serializeFeatures(options.features || {}),
- options.args || null);
-}
-exports.open = open;
-
-/**
- * Opens a top level window and returns it's `nsIDOMWindow` representation.
- * Same as `open` but with more features
- * @param {Object} options
- *
- */
-function openDialog(options) {
- options = options || {};
-
- let browser = WM.getMostRecentWindow(BROWSER);
- return browser.openDialog.apply(
- browser,
- array.flatten([
- options.url || URI_BROWSER,
- options.name || '_blank',
- options.features || 'chrome,all,dialog=no',
- options.args || null
- ])
- );
-}
-exports.openDialog = openDialog;
-
-/**
- * Returns an array of all currently opened windows.
- * Note that these windows may still be loading.
- */
-function windows() {
- let list = [];
- let winEnum = windowWatcher.getWindowEnumerator();
- while (winEnum.hasMoreElements()) {
- let window = winEnum.getNext().QueryInterface(Ci.nsIDOMWindow);
- list.push(window);
- }
- return list;
-}
-exports.windows = windows;
-
-/**
- * Check if the given window is completely loaded.
- * i.e. if its "load" event has already been fired and all possible DOM content
- * is done loading (the whole DOM document, images content, ...)
- * @params {nsIDOMWindow} window
- */
-function isDocumentLoaded(window) {
- return window.document.readyState == "complete";
-}
-exports.isDocumentLoaded = isDocumentLoaded;
-
-function isBrowser(window) {
- return window.document.documentElement.getAttribute("windowtype") === BROWSER;
-};
-exports.isBrowser = isBrowser;
-
-function getWindowTitle(window) {
- return window && window.document ? window.document.title : null;
-}
-exports.getWindowTitle = getWindowTitle;
-
-function isXULBrowser(window) {
- return !!(isBrowser(window) && window.XULBrowserWindow);
-}
-exports.isXULBrowser = isXULBrowser;
-
-function getFrames(window) {
- return Array.slice(window.frames).reduce(function(frames, frame) {
- return frames.concat(frame, getFrames(frame))
- }, [])
-}
-exports.getFrames = getFrames;
diff --git a/tools/addon-sdk-1.12/lib/sdk/windows.js b/tools/addon-sdk-1.12/lib/sdk/windows.js
deleted file mode 100644
index 15399c9..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/windows.js
+++ /dev/null
@@ -1,21 +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': 'stable'
-};
-
-if (require('./system/xul-app').is('Firefox')) {
- module.exports = require('./windows/firefox');
-}
-else if (require('./system/xul-app').is('Fennec')) {
- module.exports = require('./windows/fennec');
-}
-else {
- throw new Error([
- 'The windows module currently supports only Firefox & Fennec. In the future',
- ' we would like it to support other applications, however.'
- ].join(''));
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/windows/dom.js b/tools/addon-sdk-1.12/lib/sdk/windows/dom.js
deleted file mode 100644
index ac2b86b..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/windows/dom.js
+++ /dev/null
@@ -1,33 +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 { Trait } = require('../deprecated/traits');
-const { getWindowTitle } = require('../window/utils');
-const { getMode } = require('../private-browsing/utils');
-
-module.metadata = {
- "stability": "unstable"
-};
-
-const WindowDom = Trait.compose({
- _window: Trait.required,
- get title() {
- return getWindowTitle(this._window);
- },
- close: function close() {
- let window = this._window;
- if (window) window.close();
- return this._public;
- },
- activate: function activate() {
- let window = this._window;
- if (window) window.focus();
- return this._public;
- },
- get isPrivateBrowsing() {
- return getMode(this._window);
- }
-});
-exports.WindowDom = WindowDom;
diff --git a/tools/addon-sdk-1.12/lib/sdk/windows/fennec.js b/tools/addon-sdk-1.12/lib/sdk/windows/fennec.js
deleted file mode 100644
index a497ea9..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/windows/fennec.js
+++ /dev/null
@@ -1,84 +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 { BrowserWindow } = require('../window/browser');
-const windowUtils = require('../deprecated/window-utils');
-const { WindowTracker } = windowUtils;
-const { isBrowser } = require('../window/utils');
-const { windowNS } = require('../window/namespace');
-const { on, off, once, emit } = require('../event/core');
-const { method } = require('../lang/functional');
-const { EventTarget } = require('../event/target');
-const { List, addListItem } = require('../util/list');
-
-const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec, consider using require("tabs") instead';
-
-// NOTE: On Fennec there is only one window.
-
-let BrowserWindows = Class({
- implements: [ List ],
- extends: EventTarget,
- initialize: function() {
- List.prototype.initialize.apply(this);
- },
- get activeWindow() {
- let window = windowUtils.activeBrowserWindow;
- return window ? getBrowserWindow({window: window}) : null;
- },
- open: function open(options) {
- throw new Error(ERR_FENNEC_MSG);
- return null;
- }
-});
-const browserWindows = exports.browserWindows = BrowserWindows();
-
-
-/**
- * Gets a `BrowserWindow` for the given `chromeWindow` if previously
- * registered, `null` otherwise.
- */
-function getRegisteredWindow(chromeWindow) {
- for each (let window in browserWindows) {
- if (chromeWindow === windowNS(window).window)
- return window;
- }
-
- return null;
-}
-
-/**
- * Gets a `BrowserWindow` for the provided window options obj
- * @params {Object} options
- * Options that are passed to the the `BrowserWindowTrait`
- * @returns {BrowserWindow}
- */
-function getBrowserWindow(options) {
- let window = null;
-
- // if we have a BrowserWindow already then use it
- if ('window' in options)
- window = getRegisteredWindow(options.window);
- if (window)
- return window;
-
- // we don't have a BrowserWindow yet, so create one
- var window = BrowserWindow(options);
- addListItem(browserWindows, window);
- return window;
-}
-
-WindowTracker({
- onTrack: function onTrack(chromeWindow) {
- if (!isBrowser(chromeWindow)) return;
- let window = getBrowserWindow({ window: chromeWindow });
- emit(browserWindows, 'open', window);
- },
- onUntrack: function onUntrack(chromeWindow) {
- if (!isBrowser(chromeWindow)) return;
- let window = getBrowserWindow({ window: chromeWindow });
- emit(browserWindows, 'close', window);
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/windows/firefox.js b/tools/addon-sdk-1.12/lib/sdk/windows/firefox.js
deleted file mode 100644
index 9a55a08..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/windows/firefox.js
+++ /dev/null
@@ -1,241 +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, Cr } = require('chrome'),
- { Trait } = require('../deprecated/traits'),
- { List } = require('../deprecated/list'),
- { EventEmitter } = require('../deprecated/events'),
- { WindowTabs, WindowTabTracker } = require('./tabs-firefox'),
- { WindowDom } = require('./dom'),
- { WindowLoader } = require('./loader'),
- { isBrowser, getWindowDocShell } = require('../window/utils'),
- { Options } = require('../tabs/common'),
- apiUtils = require('../deprecated/api-utils'),
- unload = require('../system/unload'),
- windowUtils = require('../deprecated/window-utils'),
- { WindowTrackerTrait } = windowUtils,
- { ns } = require('../core/namespace'),
- { observer: windowObserver } = require('./observer'),
- { isWindowPBEnabled } = require('../private-browsing/utils');
-
-/**
- * Window trait composes safe wrappers for browser window that are E10S
- * compatible.
- */
-const BrowserWindowTrait = Trait.compose(
- EventEmitter,
- WindowDom.resolve({ close: '_close' }),
- WindowTabs,
- WindowTabTracker,
- WindowLoader,
- /* WindowSidebars, */
- Trait.compose({
- _emit: Trait.required,
- _close: Trait.required,
- _load: Trait.required,
- /**
- * Constructor returns wrapper of the specified chrome window.
- * @param {nsIWindow} window
- */
- constructor: function BrowserWindow(options) {
- // Register this window ASAP, in order to avoid loop that would try
- // to create this window instance over and over (see bug 648244)
- windows.push(this);
-
- // make sure we don't have unhandled errors
- this.on('error', console.exception.bind(console));
-
- if ('onOpen' in options)
- this.on('open', options.onOpen);
- if ('onClose' in options)
- this.on('close', options.onClose);
- if ('onActivate' in options)
- this.on('activate', options.onActivate);
- if ('onDeactivate' in options)
- this.on('deactivate', options.onDeactivate);
- if ('window' in options)
- this._window = options.window;
-
- if ('tabs' in options) {
- this._tabOptions = Array.isArray(options.tabs) ?
- options.tabs.map(Options) :
- [ Options(options.tabs) ];
- }
- else if ('url' in options) {
- this._tabOptions = [ Options(options.url) ];
- }
-
- this._load();
- return this;
- },
- destroy: function () this._onUnload(),
- _tabOptions: [],
- _onLoad: function() {
- try {
- this._initWindowTabTracker();
- }
- catch(e) {
- this._emit('error', e);
- }
-
- this._emitOnObject(browserWindows, 'open', this._public);
- },
- _onUnload: function() {
- if (!this._window)
- return;
- this._destroyWindowTabTracker();
- this._emitOnObject(browserWindows, 'close', this._public);
- this._window = null;
- // Removing reference from the windows array.
- windows.splice(windows.indexOf(this), 1);
- this._removeAllListeners();
- },
- close: function close(callback) {
- // maybe we should deprecate this with message ?
- if (callback) this.on('close', callback);
- return this._close();
- }
- })
-);
-
-/**
- * Gets a `BrowserWindowTrait` for the given `chromeWindow` if previously
- * registered, `null` otherwise.
- */
-function getRegisteredWindow(chromeWindow) {
- for each (let window in windows) {
- if (chromeWindow === window._window)
- return window;
- }
-
- return null;
-}
-
-/**
- * Wrapper for `BrowserWindowTrait`. Creates new instance if wrapper for
- * window doesn't exists yet. If wrapper already exists then returns it
- * instead.
- * @params {Object} options
- * Options that are passed to the the `BrowserWindowTrait`
- * @returns {BrowserWindow}
- * @see BrowserWindowTrait
- */
-function BrowserWindow(options) {
- let window = null;
-
- if ("window" in options)
- window = getRegisteredWindow(options.window);
-
- return (window || BrowserWindowTrait(options))._public;
-}
-// to have proper `instanceof` behavior will go away when #596248 is fixed.
-BrowserWindow.prototype = BrowserWindowTrait.prototype;
-exports.BrowserWindow = BrowserWindow;
-
-const windows = [];
-
-const browser = ns();
-
-function onWindowActivation (chromeWindow, event) {
- if (!isBrowser(chromeWindow)) return; // Ignore if it's not a browser window.
-
- let window = getRegisteredWindow(chromeWindow);
-
- if (window)
- window._emit(event.type, window._public);
- else
- window = BrowserWindowTrait({ window: chromeWindow });
-
- browser(browserWindows).internals._emit(event.type, window._public);
-}
-
-windowObserver.on("activate", onWindowActivation);
-windowObserver.on("deactivate", onWindowActivation);
-
-/**
- * `BrowserWindows` trait is composed out of `List` trait and it represents
- * "live" list of currently open browser windows. Instance mutates itself
- * whenever new browser window gets opened / closed.
- */
-// Very stupid to resolve all `toStrings` but this will be fixed by #596248
-const browserWindows = Trait.resolve({ toString: null }).compose(
- List.resolve({ constructor: '_initList' }),
- EventEmitter.resolve({ toString: null }),
- WindowTrackerTrait.resolve({ constructor: '_initTracker', toString: null }),
- Trait.compose({
- _emit: Trait.required,
- _add: Trait.required,
- _remove: Trait.required,
-
- // public API
-
- /**
- * Constructor creates instance of `Windows` that represents live list of open
- * windows.
- */
- constructor: function BrowserWindows() {
- browser(this._public).internals = this;
-
- this._trackedWindows = [];
- this._initList();
- this._initTracker();
- unload.ensure(this, "_destructor");
- },
- _destructor: function _destructor() {
- this._removeAllListeners('open');
- this._removeAllListeners('close');
- this._removeAllListeners('activate');
- this._removeAllListeners('deactivate');
- this._clear();
-
- delete browser(this._public).internals;
- },
- /**
- * This property represents currently active window.
- * Property is non-enumerable, in order to preserve array like enumeration.
- * @type {Window|null}
- */
- get activeWindow() {
- let window = windowUtils.activeBrowserWindow;
- return window ? BrowserWindow({window: window}) : null;
- },
- open: function open(options) {
- if (typeof options === "string")
- // `tabs` option is under review and may be removed.
- options = { tabs: [Options(options)] };
- return BrowserWindow(options);
- },
-
- /**
- * Internal listener which is called whenever new window gets open.
- * Creates wrapper and adds to this list.
- * @param {nsIWindow} chromeWindow
- */
- _onTrack: function _onTrack(chromeWindow) {
- if (!isBrowser(chromeWindow)) return;
- let window = BrowserWindow({ window: chromeWindow });
- this._add(window);
- this._emit('open', window);
- },
- /**
- * Internal listener which is called whenever window gets closed.
- * Cleans up references and removes wrapper from this list.
- * @param {nsIWindow} window
- */
- _onUntrack: function _onUntrack(chromeWindow) {
- if (!isBrowser(chromeWindow)) return;
- let window = BrowserWindow({ window: chromeWindow });
- this._remove(window);
- this._emit('close', window);
-
- // Bug 724404: do not leak this module and linked windows:
- // We have to do it on untrack and not only when `_onUnload` is called
- // when windows are closed, otherwise, we will leak on addon disabling.
- window.destroy();
- }
- }).resolve({ toString: null })
-)();
-
-exports.browserWindows = browserWindows;
diff --git a/tools/addon-sdk-1.12/lib/sdk/windows/loader.js b/tools/addon-sdk-1.12/lib/sdk/windows/loader.js
deleted file mode 100644
index be3d84c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/windows/loader.js
+++ /dev/null
@@ -1,120 +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 { Cc, Ci } = require('chrome'),
- { setTimeout } = require('../timers'),
- { Trait } = require('../deprecated/traits'),
- { openDialog } = require('../window/utils'),
-
- ON_LOAD = 'load',
- ON_UNLOAD = 'unload',
- STATE_LOADED = 'complete';
-
-/**
- * Trait provides private `_window` property and requires `_onLoad` property
- * that will be called when `_window` is loaded. If `_window` property value
- * is changed with already loaded window `_onLoad` still will be called.
- */
-const WindowLoader = Trait.compose({
- /**
- * Internal listener that is called when window is loaded.
- * Please keep in mind that this trait will not handle exceptions that may
- * be thrown by this method so method itself should take care of
- * handling them.
- * @param {nsIWindow} window
- */
- _onLoad: Trait.required,
- _tabOptions: Trait.required,
- /**
- * Internal listener that is called when `_window`'s DOM 'unload' event
- * is dispatched. Please note that this trait will not handle exceptions that
- * may be thrown by this method so method itself should take care of
- * handling them.
- */
- _onUnload: Trait.required,
- _load: function _load() {
- if (this.__window) return;
- this._window = openDialog({
- args: this._tabOptions.map(function(options) options.url).join("|")
- });
- },
- /**
- * Private window who's load event is being tracked. Once window is loaded
- * `_onLoad` is called.
- * @type {nsIWindow}
- */
- get _window() this.__window,
- set _window(window) {
- let _window = this.__window;
- if (!window) window = null;
-
- if (window !== _window) {
- if (_window) {
- _window.removeEventListener(ON_UNLOAD, this.__unloadListener, false);
- _window.removeEventListener(ON_LOAD, this.__loadListener, false);
- }
-
- if (window) {
- window.addEventListener(
- ON_UNLOAD,
- this.__unloadListener ||
- (this.__unloadListener = this._unloadListener.bind(this))
- ,
- false
- );
-
- this.__window = window;
-
- // If window is not loaded yet setting up a listener.
- if (STATE_LOADED != window.document.readyState) {
- window.addEventListener(
- ON_LOAD,
- this.__loadListener ||
- (this.__loadListener = this._loadListener.bind(this))
- ,
- false
- );
- }
- else { // If window is loaded calling listener next turn of event loop.
- this._onLoad(window)
- }
- }
- }
- },
- __window: null,
- /**
- * Internal method used for listening 'load' event on the `_window`.
- * Method takes care of removing itself from 'load' event listeners once
- * event is being handled.
- */
- _loadListener: function _loadListener(event) {
- let window = this._window;
- if (!event.target || event.target.defaultView != window) return;
- window.removeEventListener(ON_LOAD, this.__loadListener, false);
- this._onLoad(window);
- },
- __loadListener: null,
- /**
- * Internal method used for listening 'unload' event on the `_window`.
- * Method takes care of removing itself from 'unload' event listeners once
- * event is being handled.
- */
- _unloadListener: function _unloadListener(event) {
- let window = this._window;
- if (!event.target
- || event.target.defaultView != window
- || STATE_LOADED != window.document.readyState
- ) return;
- window.removeEventListener(ON_UNLOAD, this.__unloadListener, false);
- this._onUnload(window);
- },
- __unloadListener: null
-});
-exports.WindowLoader = WindowLoader;
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/windows/observer.js b/tools/addon-sdk-1.12/lib/sdk/windows/observer.js
deleted file mode 100644
index 1097bf3..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/windows/observer.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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 { EventEmitterTrait: EventEmitter } = require("../deprecated/events");
-const { WindowTracker, windowIterator } = require("../deprecated/window-utils");
-const { DOMEventAssembler } = require("../deprecated/events/assembler");
-const { Trait } = require("../deprecated/light-traits");
-
-// Event emitter objects used to register listeners and emit events on them
-// when they occur.
-const observer = Trait.compose(DOMEventAssembler, EventEmitter).create({
- /**
- * Method is implemented by `EventEmitter` and is used just for emitting
- * events on registered listeners.
- */
- _emit: Trait.required,
- /**
- * Events that are supported and emitted by the module.
- */
- supportedEventsTypes: [ "activate", "deactivate" ],
- /**
- * 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) {
- this._emit(event.type, event.target, event);
- }
-});
-
-// Using `WindowTracker` to track window events.
-WindowTracker({
- onTrack: function onTrack(chromeWindow) {
- observer._emit("open", chromeWindow);
- observer.observe(chromeWindow);
- },
- onUntrack: function onUntrack(chromeWindow) {
- observer._emit("close", chromeWindow);
- observer.ignore(chromeWindow);
- }
-});
-
-exports.observer = observer;
diff --git a/tools/addon-sdk-1.12/lib/sdk/windows/tabs-fennec.js b/tools/addon-sdk-1.12/lib/sdk/windows/tabs-fennec.js
deleted file mode 100644
index ddf4aeb..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/windows/tabs-fennec.js
+++ /dev/null
@@ -1,190 +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 } = require('../tabs/tab');
-const { browserWindows } = require('./fennec');
-const { windowNS } = require('../window/namespace');
-const { tabsNS, tabNS } = require('../tabs/namespace');
-const { openTab, getTabs, getSelectedTab } = require('../tabs/utils');
-const { Options } = require('../tabs/common');
-const { on, once, off, emit } = require('../event/core');
-const { method } = require('../lang/functional');
-const { EVENTS } = require('../tabs/events');
-const { EventTarget } = require('../event/target');
-const { when: unload } = require('../system/unload');
-const { windowIterator } = require('../deprecated/window-utils');
-const { List, addListItem, removeListItem } = require('../util/list');
-
-const mainWindow = windowNS(browserWindows.activeWindow).window;
-
-const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec';
-
-const Tabs = Class({
- implements: [ List ],
- extends: EventTarget,
- initialize: function initialize(options) {
- let tabsInternals = tabsNS(this);
- let window = tabsNS(this).window = options.window || mainWindow;
-
- EventTarget.prototype.initialize.call(this, options);
- List.prototype.initialize.apply(this, getTabs(window).map(Tab));
-
- // TabOpen event
- window.BrowserApp.deck.addEventListener(EVENTS.open.dom, onTabOpen, false);
-
- // TabSelect
- window.BrowserApp.deck.addEventListener(EVENTS.activate.dom, onTabSelect, false);
-
- // TabClose
- window.BrowserApp.deck.addEventListener(EVENTS.close.dom, onTabClose, false);
- },
- get activeTab() {
- return getTabForRawTab(getSelectedTab(tabsNS(this).window));
- },
- open: function(options) {
- options = Options(options);
- let activeWin = browserWindows.activeWindow;
-
- if (options.isPinned) {
- console.error(ERR_FENNEC_MSG); // TODO
- }
-
- let rawTab = openTab(windowNS(activeWin).window, options.url, {
- inBackground: options.inBackground
- });
-
- // by now the tab has been created
- let tab = getTabForRawTab(rawTab);
-
- if (options.onClose)
- tab.on('close', options.onClose);
-
- if (options.onOpen) {
- // NOTE: on Fennec this will be true
- if (tabNS(tab).opened)
- options.onOpen(tab);
-
- tab.on('open', options.onOpen);
- }
-
- if (options.onReady)
- tab.on('ready', options.onReady);
-
- if (options.onActivate)
- tab.on('activate', options.onActivate);
-
- return tab;
- }
-});
-let gTabs = exports.tabs = Tabs(mainWindow);
-
-function tabsUnloader(event, window) {
- window = window || (event && event.target);
- if (!(window && window.BrowserApp))
- return;
- window.BrowserApp.deck.removeEventListener(EVENTS.open.dom, onTabOpen, false);
- window.BrowserApp.deck.removeEventListener(EVENTS.activate.dom, onTabSelect, false);
- window.BrowserApp.deck.removeEventListener(EVENTS.close.dom, onTabClose, false);
-}
-
-// unload handler
-unload(function() {
- for (let window in windowIterator()) {
- tabsUnloader(null, window);
- }
-});
-
-function addTab(tab) {
- addListItem(gTabs, tab);
- return tab;
-}
-
-function removeTab(tab) {
- removeListItem(gTabs, tab);
- return tab;
-}
-
-function getTabForBrowser(browser) {
- return getTabForRawTab(getRawTabForBrowser(browser));
-}
-
-function getRawTabForBrowser(browser) {
- let tabs = mainWindow.BrowserApp.tabs;
- for (let i = 0; i < tabs.length; i++) {
- let tab = tabs[i];
- if (tab.browser === browser)
- return tab
- }
- return null;
-}
-
-// TabOpen
-function onTabOpen(event) {
- let browser = event.target;
-
- let tab = getTabForBrowser(browser);
- if (tab === null) {
- let rawTab = getRawTabForBrowser(browser);
-
- // create a Tab instance for this new tab
- tab = addTab(Tab(rawTab));
- }
-
- tabNS(tab).opened = true;
-
- // TabReady
- let onReady = tabNS(tab).onReady = onTabReady.bind(tab);
- browser.addEventListener(EVENTS.ready.dom, onReady, false);
-
- emit(tab, 'open', tab);
- emit(gTabs, 'open', tab);
-};
-
-function onTabReady() {
- emit(this, 'ready', this);
- emit(gTabs, 'ready', this);
-}
-
-// TabSelect
-function onTabSelect(event) {
- // Set value whenever new tab becomes active.
- let tab = getTabForBrowser(event.target);
- emit(tab, 'activate', tab);
- emit(gTabs, 'activate', tab);
-
- for each (let t in gTabs) {
- if (t === tab) continue;
- emit(t, 'deactivate', t);
- emit(gTabs, 'deactivate', t);
- }
-};
-
-// TabClose
-function onTabClose(event) {
- let tab = getTabForBrowser(event.target);
- removeTab(tab);
-
- emit(gTabs, 'close', tab);
- emit(tab, 'close', tab);
-};
-
-function getTabForRawTab(rawTab) {
- for each (let tab in gTabs) {
- if (tabNS(tab).tab === rawTab)
- return tab;
- }
- return null;
-}
-
-unload(function() {
- for each (let tab in gTabs) {
- let tabInternals = tabNS(tab);
- tabInternals.tab.browser.removeEventListener(EVENTS.ready.dom, tabInternals.onReady, false);
- tabInternals.onReady = null;
- tabInternals.tab = null;
- tabInternals.window = null;
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/windows/tabs-firefox.js b/tools/addon-sdk-1.12/lib/sdk/windows/tabs-firefox.js
deleted file mode 100644
index f41e752..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/windows/tabs-firefox.js
+++ /dev/null
@@ -1,188 +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 { Trait } = require("../deprecated/traits");
-const { List } = require("../deprecated/list");
-const { Tab } = require("../tabs/tab");
-const { EventEmitter } = require("../deprecated/events");
-const { EVENTS } = require("../tabs/events");
-const { getOwnerWindow, getActiveTab, getTabs,
- openTab, activateTab } = require("../tabs/utils");
-const { Options } = require("../tabs/common");
-const { observer: tabsObserver } = require("../tabs/observer");
-
-const TAB_BROWSER = "tabbrowser";
-
-/**
- * This is a trait that is used in composition of window wrapper. Trait tracks
- * tab related events of the wrapped window in order to keep track of open
- * tabs and maintain their wrappers. Every new tab gets wrapped and jetpack
- * type event is emitted.
- */
-const WindowTabTracker = Trait.compose({
- /**
- * Chrome window whose tabs are tracked.
- */
- _window: Trait.required,
- /**
- * Function used to emit events.
- */
- _emit: EventEmitter.required,
- _tabOptions: Trait.required,
- /**
- * Function to add event listeners.
- */
- on: EventEmitter.required,
- removeListener: EventEmitter.required,
- /**
- * Initializes tab tracker for a browser window.
- */
- _initWindowTabTracker: function _initWindowTabTracker() {
- // Ugly hack that we have to remove at some point (see Bug 658059). At this
- // point it is necessary to invoke lazy `tabs` getter on the windows object
- // which creates a `TabList` instance.
- this.tabs;
-
- // Binding all methods used as event listeners to the instance.
- this._onTabReady = this._emitEvent.bind(this, "ready");
- this._onTabOpen = this._onTabEvent.bind(this, "open");
- this._onTabClose = this._onTabEvent.bind(this, "close");
- this._onTabActivate = this._onTabEvent.bind(this, "activate");
- this._onTabDeactivate = this._onTabEvent.bind(this, "deactivate");
- this._onTabPinned = this._onTabEvent.bind(this, "pinned");
- this._onTabUnpinned = this._onTabEvent.bind(this, "unpinned");
-
- for each (let tab in getTabs(this._window)) {
- // We emulate "open" events for all open tabs since gecko does not emits
- // them on the tabs that new windows are open with. Also this is
- // necessary to synchronize tabs lists with an actual state.
- this._onTabOpen(tab);
- }
-
- // We also emulate "activate" event so that it's picked up by a tab list.
- this._onTabActivate(getActiveTab(this._window));
-
- // Setting up event listeners
- tabsObserver.on("open", this._onTabOpen);
- tabsObserver.on("close", this._onTabClose);
- tabsObserver.on("activate", this._onTabActivate);
- tabsObserver.on("deactivate", this._onTabDeactivate);
- tabsObserver.on("pinned", this._onTabPinned);
- tabsObserver.on("unpinned", this._onTabUnpinned);
- },
- _destroyWindowTabTracker: function _destroyWindowTabTracker() {
- // We emulate close events on all tabs, since gecko does not emits such
- // events by itself.
- for each (let tab in this.tabs)
- this._emitEvent("close", tab);
-
- this._tabs._clear();
-
- tabsObserver.removeListener("open", this._onTabOpen);
- tabsObserver.removeListener("close", this._onTabClose);
- tabsObserver.removeListener("activate", this._onTabActivate);
- tabsObserver.removeListener("deactivate", this._onTabDeactivate);
- },
- _onTabEvent: function _onTabEvent(type, tab) {
- if (this._window === getOwnerWindow(tab)) {
- let options = this._tabOptions.shift() || {};
- options.tab = tab;
- options.window = this._public;
-
- // creating tab wrapper and adding listener to "ready" events.
- let wrappedTab = Tab(options);
-
- // Setting up an event listener for ready events.
- if (type === "open")
- wrappedTab.on("ready", this._onTabReady);
-
- this._emitEvent(type, wrappedTab);
- }
- },
- _emitEvent: function _emitEvent(type, tab) {
- // Notifies combined tab list that tab was added / removed.
- tabs._emit(type, tab);
- // Notifies contained tab list that window was added / removed.
- this._tabs._emit(type, tab);
- }
-});
-exports.WindowTabTracker = WindowTabTracker;
-
-/**
- * This trait is used to create live representation of open tab lists. Each
- * window wrapper's tab list is represented by an object created from this
- * trait. It is also used to represent list of all the open windows. Trait is
- * composed out of `EventEmitter` in order to emit 'TabOpen', 'TabClose' events.
- * **Please note** that objects created by this trait can't be exposed outside
- * instead you should expose it's `_public` property, see comments in
- * constructor for details.
- */
-const TabList = List.resolve({ constructor: "_init" }).compose(
- // This is ugly, but necessary. Will be removed by #596248
- EventEmitter.resolve({ toString: null }),
- Trait.compose({
- on: Trait.required,
- _emit: Trait.required,
- constructor: function TabList(options) {
- this._window = options.window;
- // Add new items to the list
- this.on(EVENTS.open.name, this._add.bind(this));
-
- // Remove closed items from the list
- this.on(EVENTS.close.name, this._remove.bind(this));
-
- // Set value whenever new tab becomes active.
- this.on("activate", function onTabActivate(tab) {
- this._activeTab = tab;
- }.bind(this));
-
- // Initialize list.
- this._init();
- // This list is not going to emit any events, object holding this list
- // will do it instead, to make that possible we return a private API.
- return this;
- },
- get activeTab() this._activeTab,
- _activeTab: null,
-
- open: function open(options) {
- options = Options(options);
- this._window._tabOptions.push(options);
- let tab = openTab(this._window._window, options.url);
- if (!options.inBackground)
- activateTab(tab);
- }
- // This is ugly, but necessary. Will be removed by #596248
- }).resolve({ toString: null })
-);
-
-/**
- * Combined list of all open tabs on all the windows.
- * type {TabList}
- */
-var tabs = TabList({ window: null });
-exports.tabs = tabs._public;
-
-/**
- * Trait is a part of composition that represents window wrapper. This trait is
- * composed out of `WindowTabTracker` that allows it to keep track of open tabs
- * on the window being wrapped.
- */
-const WindowTabs = Trait.compose(
- WindowTabTracker,
- Trait.compose({
- _window: Trait.required,
- /**
- * List of tabs
- */
- get tabs() (this._tabs || (this._tabs = TabList({ window: this })))._public,
- _tabs: null,
- })
-);
-exports.WindowTabs = WindowTabs;
diff --git a/tools/addon-sdk-1.12/lib/toolkit/loader.js b/tools/addon-sdk-1.12/lib/toolkit/loader.js
deleted file mode 100644
index 09a9889..0000000
--- a/tools/addon-sdk-1.12/lib/toolkit/loader.js
+++ /dev/null
@@ -1,400 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 expandtab */
-/* 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/.
- */
-;(function(id, factory) { // Module boilerplate :(
- if (typeof(define) === 'function') { // RequireJS
- define(factory);
- } else if (typeof(require) === 'function') { // CommonJS
- factory.call(this, require, exports, module);
- } else if (~String(this).indexOf('BackstagePass')) { // JSM
- factory(function require(uri) {
- var imports = {};
- this['Components'].utils.import(uri, imports);
- return imports;
- }, this, { uri: __URI__, id: id });
- this.EXPORTED_SYMBOLS = Object.keys(this);
- } else if (~String(this).indexOf('Sandbox')) { // Sandbox
- factory(function require(uri) {}, this, { uri: __URI__, id: id });
- } else { // Browser or alike
- var globals = this
- factory(function require(id) {
- return globals[id];
- }, (globals[id] = {}), { uri: document.location.href + '#' + id, id: id });
- }
-}).call(this, 'loader', function(require, exports, module) {
-
-'use strict';
-
-module.metadata = {
- "stability": "unstable"
-};
-
-const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu,
- results: Cr, manager: Cm } = Components;
-const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')();
-const { loadSubScript } = Cc['@mozilla.org/moz/jssubscript-loader;1'].
- getService(Ci.mozIJSSubScriptLoader);
-const { notifyObservers } = Cc['@mozilla.org/observer-service;1'].
- getService(Ci.nsIObserverService);
-
-// Define some shortcuts.
-const bind = Function.call.bind(Function.bind);
-const getOwnPropertyNames = Object.getOwnPropertyNames;
-const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
-const define = Object.defineProperties;
-const prototypeOf = Object.getPrototypeOf;
-const create = Object.create;
-const keys = Object.keys;
-
-// Workaround for bug 674195. Freezing objects from other compartments fail,
-// so we use `Object.freeze` from the same component instead.
-function freeze(object) {
- if (prototypeOf(object) === null) {
- Object.freeze(object);
- }
- else {
- prototypeOf(prototypeOf(object.isPrototypeOf)).
- constructor. // `Object` from the owner compartment.
- freeze(object);
- }
- return object;
-}
-
-// Returns map of given `object`-s own property descriptors.
-const descriptor = iced(function descriptor(object) {
- let value = {};
- getOwnPropertyNames(object).forEach(function(name) {
- value[name] = getOwnPropertyDescriptor(object, name)
- });
- return value;
-});
-exports.descriptor = descriptor;
-
-// Freeze important built-ins so they can't be used by untrusted code as a
-// message passing channel.
-freeze(Object);
-freeze(Object.prototype);
-freeze(Function);
-freeze(Function.prototype);
-freeze(Array);
-freeze(Array.prototype);
-freeze(String);
-freeze(String.prototype);
-
-// This function takes `f` function sets it's `prototype` to undefined and
-// freezes it. We need to do this kind of deep freeze with all the exposed
-// functions so that untrusted code won't be able to use them a message
-// passing channel.
-function iced(f) {
- f.prototype = undefined;
- return freeze(f);
-}
-
-// Defines own properties of given `properties` object on the given
-// target object overriding any existing property with a conflicting name.
-// Returns `target` object. Note we only export this function because it's
-// useful during loader bootstrap when other util modules can't be used &
-// thats only case where this export should be used.
-const override = iced(function override(target, source) {
- let properties = descriptor(target)
- let extension = descriptor(source || {})
- getOwnPropertyNames(extension).forEach(function(name) {
- properties[name] = extension[name];
- });
- return define({}, properties);
-});
-exports.override = override;
-
-// Function takes set of options and returns a JS sandbox. Function may be
-// passed set of options:
-// - `name`: A string value which identifies the sandbox in about:memory. Will
-// throw exception if omitted.
-// - `principal`: String URI or `nsIPrincipal` for the sandbox. Defaults to
-// system principal.
-// - `prototype`: Ancestor for the sandbox that will be created. Defaults to
-// `{}`.
-// - `wantXrays`: A Boolean value indicating whether code outside the sandbox
-// wants X-ray vision with respect to objects inside the sandbox. Defaults
-// to `true`.
-// - `sandbox`: A sandbox to share JS compartment with. If omitted new
-// compartment will be created.
-// For more details see:
-// https://developer.mozilla.org/en/Components.utils.Sandbox
-const Sandbox = iced(function Sandbox(options) {
- // Normalize options and rename to match `Cu.Sandbox` expectations.
- options = {
- // Do not expose `Components` if you really need them (bad idea!) you
- // still can expose via prototype.
- wantComponents: false,
- sandboxName: options.name,
- principal: 'principal' in options ? options.principal : systemPrincipal,
- wantXrays: 'wantXrays' in options ? options.wantXrays : true,
- sandboxPrototype: 'prototype' in options ? options.prototype : {},
- sameGroupAs: 'sandbox' in options ? options.sandbox : null
- };
-
- // Make `options.sameGroupAs` only if `sandbox` property is passed,
- // otherwise `Cu.Sandbox` will throw.
- if (!options.sameGroupAs)
- delete options.sameGroupAs;
-
- let sandbox = Cu.Sandbox(options.principal, options);
-
- // Each sandbox at creation gets set of own properties that will be shadowing
- // ones from it's prototype. We override delete such `sandbox` properties
- // to avoid shadowing.
- delete sandbox.Iterator;
- delete sandbox.Components;
- delete sandbox.importFunction;
- delete sandbox.debug;
-
- return sandbox;
-});
-exports.Sandbox = Sandbox;
-
-// Evaluates code from the given `uri` into given `sandbox`. If
-// `options.source` is passed, then that code is evaluated instead.
-// Optionally following options may be given:
-// - `options.encoding`: Source encoding, defaults to 'UTF-8'.
-// - `options.line`: Line number to start count from for stack traces.
-// Defaults to 1.
-// - `options.version`: Version of JS used, defaults to '1.8'.
-const evaluate = iced(function evaluate(sandbox, uri, options) {
- let { source, line, version, encoding } = override({
- encoding: 'UTF-8',
- line: 1,
- version: '1.8',
- source: null
- }, options);
-
-
- return source ? Cu.evalInSandbox(source, sandbox, version, uri, line)
- : loadSubScript(uri, sandbox, encoding);
-});
-exports.evaluate = evaluate;
-
-// Populates `exports` of the given CommonJS `module` object, in the context
-// of the given `loader` by evaluating code associated with it.
-const load = iced(function load(loader, module) {
- let { sandboxes, globals } = loader;
- let require = Require(loader, module);
-
- let sandbox = sandboxes[module.uri] = Sandbox({
- name: module.uri,
- // Get an existing module sandbox, if any, so we can reuse its compartment
- // when creating the new one to reduce memory consumption.
- sandbox: sandboxes[keys(sandboxes).shift()],
- // We expose set of properties defined by `CommonJS` specification via
- // prototype of the sandbox. Also globals are deeper in the prototype
- // chain so that each module has access to them as well.
- prototype: create(globals, descriptor({
- require: require,
- module: module,
- exports: module.exports
- })),
- wantXrays: false
- });
-
- evaluate(sandbox, module.uri);
-
- if (module.exports && typeof(module.exports) === 'object')
- freeze(module.exports);
-
- return module;
-});
-exports.load = load;
-
-// Utility function to check if id is relative.
-function isRelative(id) { return id[0] === '.'; }
-// Utility function to normalize module `uri`s so they have `.js` extension.
-function normalize(uri) { return uri.substr(-3) === '.js' ? uri : uri + '.js'; }
-// Utility function to join paths. In common case `base` is a
-// `requirer.uri` but in some cases it may be `baseURI`. In order to
-// avoid complexity we require `baseURI` with a trailing `/`.
-const resolve = iced(function resolve(id, base) {
- let paths = id.split('/');
- let result = base.split('/');
- result.pop();
- while (paths.length) {
- let path = paths.shift();
- if (path === '..')
- result.pop();
- else if (path !== '.')
- result.push(path);
- }
- return result.join('/');
-});
-exports.resolve = resolve;
-
-const resolveURI = iced(function resolveURI(id, mapping) {
- let count = mapping.length, index = 0;
- while (index < count) {
- let [ path, uri ] = mapping[index ++];
- if (id.indexOf(path) === 0)
- return normalize(id.replace(path, uri));
- }
-});
-exports.resolveURI = resolveURI;
-
-// Creates version of `require` that will be exposed to the given `module`
-// in the context of the given `loader`. Each module gets own limited copy
-// of `require` that is allowed to load only a modules that are associated
-// with it during link time.
-const Require = iced(function Require(loader, requirer) {
- let { modules, mapping, resolve } = loader;
-
- function require(id) {
- if (!id) // Throw if `id` is not passed.
- throw Error('you must provide a module name when calling require() from '
- + requirer.id, requirer.uri);
-
- // Resolve `id` to its requirer if it's relative.
- let requirement = requirer ? resolve(id, requirer.id) : id;
-
-
- // Resolves `uri` of module using loaders resolve function.
- let uri = resolveURI(requirement, mapping);
-
- if (!uri) // Throw if `uri` can not be resolved.
- throw Error('Module: Can not resolve "' + id + '" module required by ' +
- requirer.id + ' located at ' + requirer.uri, requirer.uri);
-
- let module = null;
- // If module is already cached by loader then just use it.
- if (uri in modules) {
- module = modules[uri];
- }
- // Otherwise load and cache it. We also freeze module to prevent it from
- // further changes at runtime.
- else {
- module = modules[uri] = Module(requirement, uri);
- freeze(load(loader, module));
- }
-
- return module.exports;
- }
- // Make `require.main === module` evaluate to true in main module scope.
- require.main = loader.main === requirer ? requirer : undefined;
- return iced(require);
-});
-exports.Require = Require;
-
-const main = iced(function main(loader, id) {
- let uri = resolveURI(id, loader.mapping)
- let module = loader.main = loader.modules[uri] = Module(id, uri);
- return load(loader, module).exports;
-});
-exports.main = main;
-
-// Makes module object that is made available to CommonJS modules when they
-// are evaluated, along with `exports` and `require`.
-const Module = iced(function Module(id, uri) {
- return create(null, {
- id: { enumerable: true, value: id },
- exports: { enumerable: true, writable: true, value: create(null) },
- uri: { value: uri }
- });
-});
-exports.Module = Module;
-
-// Takes `loader`, and unload `reason` string and notifies all observers that
-// they should cleanup after them-self.
-const unload = iced(function unload(loader, reason) {
- // subject is a unique object created per loader instance.
- // This allows any code to cleanup on loader unload regardless of how
- // it was loaded. To handle unload for specific loader subject may be
- // asserted against loader.destructor or require('@loader/unload')
- // Note: We don not destroy loader's module cache or sandboxes map as
- // some modules may do cleanup in subsequent turns of event loop. Destroying
- // cache may cause module identity problems in such cases.
- let subject = { wrappedJSObject: loader.destructor };
- notifyObservers(subject, 'sdk:loader:destroy', reason);
-});
-exports.unload = unload;
-
-// Function makes new loader that can be used to load CommonJS modules
-// described by a given `options.manifest`. Loader takes following options:
-// - `globals`: Optional map of globals, that all module scopes will inherit
-// from. Map is also exposed under `globals` property of the returned loader
-// so it can be extended further later. Defaults to `{}`.
-// - `modules` Optional map of built-in module exports mapped by module id.
-// These modules will incorporated into module cache. Each module will be
-// frozen.
-// - `resolve` Optional module `id` resolution function. If given it will be
-// used to resolve module URIs, by calling it with require term, requirer
-// module object (that has `uri` property) and `baseURI` of the loader.
-// If `resolve` does not returns `uri` string exception will be thrown by
-// an associated `require` call.
-const Loader = iced(function Loader(options) {
- let { modules, globals, resolve, paths } = override({
- paths: {},
- modules: {},
- globals: {},
- resolve: exports.resolve
- }, options);
-
- // We create an identity object that will be dispatched on an unload
- // event as subject. This way unload listeners will be able to assert
- // which loader is unloaded. Please note that we intentionally don't
- // use `loader` as subject to prevent a loader access leakage through
- // observer notifications.
- let destructor = freeze(create(null));
-
- // Make mapping array that is sorted from longest path to shortest path
- // to allow overlays.
- let mapping = keys(paths).
- sort(function(a, b) { return b.length - a.length }).
- map(function(path) { return [ path, paths[path] ] });
-
- // Define pseudo modules.
- modules = override({
- '@loader/unload': destructor,
- '@loader/options': options,
- 'chrome': { Cc: Cc, Ci: Ci, Cu: Cu, Cr: Cr, Cm: Cm,
- CC: bind(CC, Components), components: Components,
- // `ChromeWorker` has to be inject in loader global scope.
- // It is done by bootstrap.js:loadSandbox for the SDK.
- ChromeWorker: ChromeWorker
- }
- }, modules);
-
- modules = keys(modules).reduce(function(result, id) {
- // We resolve `uri` from `id` since modules are cached by `uri`.
- let uri = resolveURI(id, mapping);
- let module = Module(id, uri);
- module.exports = freeze(modules[id]);
- result[uri] = freeze(module);
- return result;
- }, {});
-
- // Loader object is just a representation of a environment
- // state. We freeze it and mark make it's properties non-enumerable
- // as they are pure implementation detail that no one should rely upon.
- return freeze(create(null, {
- destructor: { enumerable: false, value: destructor },
- globals: { enumerable: false, value: globals },
- mapping: { enumerable: false, value: mapping },
- // Map of module objects indexed by module URIs.
- modules: { enumerable: false, value: modules },
- // Map of module sandboxes indexed by module URIs.
- sandboxes: { enumerable: false, value: {} },
- resolve: { enumerable: false, value: resolve },
- // Main (entry point) module, it can be set only once, since loader
- // instance can have only one main module.
- main: new function() {
- let main;
- return {
- enumerable: false,
- get: function() { return main; },
- // Only set main if it has not being set yet!
- set: function(module) { main = main || module; }
- }
- }
- }));
-});
-exports.Loader = Loader;
-
-});
-