diff --git a/addon-sdk/source/lib/sdk/addon/installer.js b/addon-sdk/source/lib/sdk/addon/installer.js index f72b21e0a28..451ad224c0a 100644 --- a/addon-sdk/source/lib/sdk/addon/installer.js +++ b/addon-sdk/source/lib/sdk/addon/installer.js @@ -87,20 +87,24 @@ exports.uninstall = function uninstall(addonId) { AddonManager.addAddonListener(listener); // Order Addonmanager to uninstall the addon - AddonManager.getAddonByID(addonId, function (addon) { - addon.uninstall(); - }); + getAddon(addonId).then(addon => addon.uninstall(), reject); return promise; }; exports.disable = function disable(addonId) { - let { promise, resolve, reject } = defer(); - - AddonManager.getAddonByID(addonId, function (addon) { + return getAddon(addonId).then(addon => { addon.userDisabled = true; - resolve(); + return addonId; }); - - return promise; }; + +exports.isActive = function isActive(addonId) { + return getAddon(addonId).then(addon => addon.isActive && !addon.appDisabled); +}; + +function getAddon (id) { + let { promise, resolve, reject } = defer(); + AddonManager.getAddonByID(id, addon => addon ? resolve(addon) : reject()); + return promise; +} diff --git a/addon-sdk/source/lib/sdk/content/worker.js b/addon-sdk/source/lib/sdk/content/worker.js index 4d8bceca9fc..d781f39c239 100644 --- a/addon-sdk/source/lib/sdk/content/worker.js +++ b/addon-sdk/source/lib/sdk/content/worker.js @@ -130,13 +130,13 @@ const WorkerSandbox = EventEmitter.compose({ // Even if this principal is for a domain that is specified in the multiple // domain principal. let principals = window; - let wantXHRConstructor = false; + let wantDOMConstructors = [] if (EXPANDED_PRINCIPALS.length > 0 && !worker._injectInDocument) { principals = EXPANDED_PRINCIPALS.concat(window); // We have to replace XHR constructor of the content document // with a custom cross origin one, automagically added by platform code: delete proto.XMLHttpRequest; - wantXHRConstructor = true; + wantDOMConstructors.push("XMLHttpRequest"); } // Instantiate trusted code in another Sandbox in order to prevent content @@ -149,7 +149,7 @@ const WorkerSandbox = EventEmitter.compose({ let content = this._sandbox = sandbox(principals, { sandboxPrototype: proto, wantXrays: true, - wantXHRConstructor: wantXHRConstructor, + wantDOMConstructors: wantDOMConstructors, sameZoneAs: window }); // We have to ensure that window.top and window.parent are the exact same diff --git a/addon-sdk/source/lib/sdk/hotkeys.js b/addon-sdk/source/lib/sdk/hotkeys.js index ce47191b225..00081455e6a 100644 --- a/addon-sdk/source/lib/sdk/hotkeys.js +++ b/addon-sdk/source/lib/sdk/hotkeys.js @@ -24,7 +24,7 @@ const Hotkey = exports.Hotkey = function Hotkey(options) { throw new TypeError(INVALID_HOTKEY); } - this.onPress = options.onPress; + this.onPress = options.onPress && options.onPress.bind(this); 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 diff --git a/addon-sdk/source/lib/sdk/util/deprecate.js b/addon-sdk/source/lib/sdk/util/deprecate.js index be3ca64508a..40f236de524 100644 --- a/addon-sdk/source/lib/sdk/util/deprecate.js +++ b/addon-sdk/source/lib/sdk/util/deprecate.js @@ -9,12 +9,16 @@ module.metadata = { }; const { get, format } = require("../console/traceback"); +const { get: getPref } = require("../preferences/service"); +const PREFERENCE = "devtools.errorconsole.deprecation_warnings"; function deprecateUsage(msg) { // Print caller stacktrace in order to help figuring out which code // does use deprecated thing let stack = get().slice(2); - console.error("DEPRECATED: " + msg + "\n" + format(stack)); + + if (getPref(PREFERENCE)) + console.error("DEPRECATED: " + msg + "\n" + format(stack)); } exports.deprecateUsage = deprecateUsage; diff --git a/addon-sdk/source/test/private-browsing/global.js b/addon-sdk/source/test/private-browsing/global.js index 22ac59e67e9..199a853a2f3 100644 --- a/addon-sdk/source/test/private-browsing/global.js +++ b/addon-sdk/source/test/private-browsing/global.js @@ -7,6 +7,8 @@ const timer = require("sdk/timers"); const { LoaderWithHookedConsole, deactivate, pb, pbUtils } = require("./helper"); const tabs = require("sdk/tabs"); const { getMostRecentBrowserWindow, isWindowPrivate } = require('sdk/window/utils'); +const { set: setPref } = require("sdk/preferences/service"); +const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; exports["test activate private mode via handler"] = function(test) { test.waitUntilDone(); @@ -174,6 +176,7 @@ exports.testBothListeners = function(test) { exports.testAutomaticUnload = function(test) { test.waitUntilDone(); + setPref(DEPRECATE_PREF, true); // Create another private browsing instance and unload it let { loader, errors } = LoaderWithHookedConsole(module); diff --git a/addon-sdk/source/test/tabs/test-fennec-tabs.js b/addon-sdk/source/test/tabs/test-fennec-tabs.js index b841589e89a..e579ebba93d 100644 --- a/addon-sdk/source/test/tabs/test-fennec-tabs.js +++ b/addon-sdk/source/test/tabs/test-fennec-tabs.js @@ -8,6 +8,8 @@ const { Loader, LoaderWithHookedConsole } = require('sdk/test/loader'); const timer = require('sdk/timers'); const tabs = require('sdk/tabs'); const windows = require('sdk/windows'); +const { set: setPref } = require("sdk/preferences/service"); +const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; const tabsLen = tabs.length; const URL = 'data:text/html;charset=utf-8,#title#'; @@ -96,6 +98,7 @@ exports.testAutomaticDestroy = function(assert, done) { // TEST: tab properties exports.testTabProperties = function(assert, done) { + setPref(DEPRECATE_PREF, true); let { loader, messages } = LoaderWithHookedConsole(); let tabs = loader.require('sdk/tabs'); diff --git a/addon-sdk/source/test/tabs/test-firefox-tabs.js b/addon-sdk/source/test/tabs/test-firefox-tabs.js index 8777fd9e071..d3c5294ed2c 100644 --- a/addon-sdk/source/test/tabs/test-firefox-tabs.js +++ b/addon-sdk/source/test/tabs/test-firefox-tabs.js @@ -12,6 +12,8 @@ const { open, focus, close } = require('sdk/window/helpers'); const { StringBundle } = require('sdk/deprecated/app-strings'); const tabs = require('sdk/tabs'); const { browserWindows } = require('sdk/windows'); +const { set: setPref } = require("sdk/preferences/service"); +const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; const base64png = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAA"; @@ -904,6 +906,7 @@ exports.testOnLoadEventWithImage = function(assert, done) { }; exports.testFaviconGetterDeprecation = function (assert, done) { + setPref(DEPRECATE_PREF, true); const { LoaderWithHookedConsole } = require("sdk/test/loader"); let { loader, messages } = LoaderWithHookedConsole(module); let tabs = loader.require('sdk/tabs'); diff --git a/addon-sdk/source/test/test-addon-installer.js b/addon-sdk/source/test/test-addon-installer.js index a816799ac51..0938c23bba0 100644 --- a/addon-sdk/source/test/test-addon-installer.js +++ b/addon-sdk/source/test/test-addon-installer.js @@ -48,7 +48,7 @@ exports["test Install"] = function (assert, done) { done(); } ); -} +}; exports["test Failing Install With Invalid Path"] = function (assert, done) { AddonInstaller.install("invalid-path").then( @@ -62,7 +62,7 @@ exports["test Failing Install With Invalid Path"] = function (assert, done) { done(); } ); -} +}; exports["test Failing Install With Invalid File"] = function (assert, done) { let directory = system.pathFor("ProfD"); @@ -131,6 +131,38 @@ exports["test Update"] = function (assert, done) { } next(); -} +}; + +exports['test Uninstall failure'] = function (assert, done) { + AddonInstaller.uninstall('invalid-addon-path').then( + () => assert.fail('Addon uninstall should not resolve successfully'), + () => assert.pass('Addon correctly rejected invalid uninstall') + ).then(done, assert.fail); +}; + +exports['test Addon Disable'] = function (assert, done) { + let ensureActive = (addonId) => AddonInstaller.isActive(addonId).then(state => { + assert.equal(state, true, 'Addon should be enabled by default'); + return addonId; + }); + let ensureInactive = (addonId) => AddonInstaller.isActive(addonId).then(state => { + assert.equal(state, false, 'Addon should be disabled after disabling'); + return addonId; + }); + + AddonInstaller.install(ADDON_PATH) + .then(ensureActive) + .then(AddonInstaller.disable) + .then(ensureInactive) + .then(AddonInstaller.uninstall) + .then(done, assert.fail); +}; + +exports['test Disable failure'] = function (assert, done) { + AddonInstaller.disable('not-an-id').then( + () => assert.fail('Addon disable should not resolve successfully'), + () => assert.pass('Addon correctly rejected invalid disable') + ).then(done, assert.fail); +}; require("test").run(exports); diff --git a/addon-sdk/source/test/test-addon-page.js b/addon-sdk/source/test/test-addon-page.js index 7cc6a4edaf0..fc885e377a0 100644 --- a/addon-sdk/source/test/test-addon-page.js +++ b/addon-sdk/source/test/test-addon-page.js @@ -18,6 +18,8 @@ const { setTimeout } = require('sdk/timers'); const { is } = require('sdk/system/xul-app'); const tabs = require('sdk/tabs'); const isAustralis = "gCustomizeMode" in windows.activeBrowserWindow; +const { set: setPref } = require("sdk/preferences/service"); +const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; let uri = require('sdk/self').data.url('index.html'); @@ -29,6 +31,7 @@ function isChromeVisible(window) { exports['test add-on page deprecation message'] = function(assert) { let { loader, messages } = LoaderWithHookedConsole(module); loader.require('sdk/addon-page'); + setPref(DEPRECATE_PREF, true); assert.equal(messages.length, 1, "only one error is dispatched"); assert.equal(messages[0].type, "error", "the console message is an error"); diff --git a/addon-sdk/source/test/test-content-events.js b/addon-sdk/source/test/test-content-events.js index f4a7b164479..9ec694f2530 100644 --- a/addon-sdk/source/test/test-content-events.js +++ b/addon-sdk/source/test/test-content-events.js @@ -41,7 +41,9 @@ exports["test multiple tabs"] = function(assert, done) { let { events } = loader.require("sdk/content/events"); let { on, off } = loader.require("sdk/event/core"); let actual = []; - on(events, "data", function({type, target, timeStamp}) { + + on(events, "data", handler); + function handler ({type, target, timeStamp}) { // ignore about:blank pages and *-document-global-created // events that are not very consistent. // ignore http:// requests, as Fennec's `about:home` page @@ -52,7 +54,7 @@ exports["test multiple tabs"] = function(assert, done) { type !== "chrome-document-global-created" && type !== "content-document-global-created") actual.push(type + " -> " + target.URL) - }); + } let window = getMostRecentBrowserWindow(); let firstTab = open("data:text/html,first-tab", window); @@ -78,6 +80,7 @@ exports["test multiple tabs"] = function(assert, done) { assert.fail(Error(reason)); }).then(function() { loader.unload(); + off(events, "data", handler); done(); }); }; @@ -87,14 +90,15 @@ exports["test nested frames"] = function(assert, done) { let { events } = loader.require("sdk/content/events"); let { on, off } = loader.require("sdk/event/core"); let actual = []; - on(events, "data", function({type, target, timeStamp}) { + on(events, "data", handler); + function handler ({type, target, timeStamp}) { // ignore about:blank pages and *-global-created // events that are not very consistent. if (target.URL !== "about:blank" && type !== "chrome-document-global-created" && type !== "content-document-global-created") actual.push(type + " -> " + target.URL) - }); + } let window = getMostRecentBrowserWindow(); let uri = encodeURI("data:text/html,