Bug 913591: Uplift Add-on SDK to Firefox. r=me

7db663a...e833700
This commit is contained in:
Dave Townsend 2013-09-06 11:09:20 -07:00
parent 668a8f74a1
commit 1bb71e5b82
16 changed files with 188 additions and 55 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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,<html><head><title>#title#</title></head></html>';
@ -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');

View File

@ -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');

View File

@ -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);

View File

@ -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");

View File

@ -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,<iframe src='data:text/html,iframe'>");
@ -117,6 +121,7 @@ exports["test nested frames"] = function(assert, done) {
assert.fail(Error(reason))
}).then(function() {
loader.unload();
off(events, "data", handler);
done();
});
};

View File

@ -16,6 +16,8 @@ const { setTimeout } = require("sdk/timers");
const { LoaderWithHookedConsole } = require("sdk/test/loader");
const { Worker } = require("sdk/content/worker");
const { close } = require("sdk/window/helpers");
const { set: setPref } = require("sdk/preferences/service");
const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
const DEFAULT_CONTENT_URL = "data:text/html;charset=utf-8,foo";
@ -658,6 +660,7 @@ exports["test:global postMessage"] = WorkerTest(
DEFAULT_CONTENT_URL,
function(assert, browser, done) {
let { loader } = LoaderWithHookedConsole(module, onMessage);
setPref(DEPRECATE_PREF, true);
// Intercept all console method calls
let seenMessages = 0;

View File

@ -2,10 +2,15 @@
* 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 deprecate = require("sdk/util/deprecate");
const { LoaderWithHookedConsole } = require("sdk/test/loader");
const { get, set } = require("sdk/preferences/service");
const PREFERENCE = "devtools.errorconsole.deprecation_warnings";
exports["test Deprecate Usage"] = function testDeprecateUsage(assert) {
set(PREFERENCE, true);
let { loader, messages } = LoaderWithHookedConsole(module);
let deprecate = loader.require("sdk/util/deprecate");
@ -31,6 +36,7 @@ exports["test Deprecate Usage"] = function testDeprecateUsage(assert) {
}
exports["test Deprecate Function"] = function testDeprecateFunction(assert) {
set(PREFERENCE, true);
let { loader, messages } = LoaderWithHookedConsole(module);
let deprecate = loader.require("sdk/util/deprecate");
@ -63,6 +69,7 @@ exports["test Deprecate Function"] = function testDeprecateFunction(assert) {
}
exports.testDeprecateEvent = function(assert, done) {
set(PREFERENCE, true);
let { loader, messages } = LoaderWithHookedConsole(module);
let deprecate = loader.require("sdk/util/deprecate");
@ -91,4 +98,63 @@ exports.testDeprecateEvent = function(assert, done) {
emit(testObj, 'fire');
}
exports.testDeprecateSettingToggle = function (assert, done) {
let { loader, messages } = LoaderWithHookedConsole(module);
let deprecate = loader.require("sdk/util/deprecate");
function fn () { deprecate.deprecateUsage("foo"); }
set(PREFERENCE, false);
fn();
assert.equal(messages.length, 0, 'no deprecation warnings');
set(PREFERENCE, true);
fn();
assert.equal(messages.length, 1, 'deprecation warnings when toggled');
set(PREFERENCE, false);
fn();
assert.equal(messages.length, 1, 'no new deprecation warnings');
done();
};
exports.testDeprecateSetting = function (assert, done) {
// Set devtools.errorconsole.deprecation_warnings to false
set(PREFERENCE, false);
let { loader, messages } = LoaderWithHookedConsole(module);
let deprecate = loader.require("sdk/util/deprecate");
// deprecateUsage test
function functionIsDeprecated() {
deprecate.deprecateUsage("foo");
}
functionIsDeprecated();
assert.equal(messages.length, 0,
"no errors dispatched on deprecateUsage");
// deprecateFunction test
function originalFunction() {};
let deprecateFunction = deprecate.deprecateFunction(originalFunction,
"bar");
deprecateFunction();
assert.equal(messages.length, 0,
"no errors dispatched on deprecateFunction");
// deprecateEvent
let { on, emit } = loader.require('sdk/event/core');
let testObj = {};
testObj.on = deprecate.deprecateEvent(on.bind(null, testObj), 'BAD', ['fire']);
testObj.on('fire', () => {
assert.equal(messages.length, 0,
"no errors dispatched on deprecateEvent");
done();
});
emit(testObj, 'fire');
}
require("test").run(exports);

View File

@ -16,6 +16,8 @@ exports["test hotkey: function key"] = function(assert, done) {
combo: "f1",
onPress: function() {
assert.pass("first callback is called");
assert.equal(this, showHotKey,
'Context `this` in `onPress` should be the hotkey object');
keyDown(element, "f2");
showHotKey.destroy();
}

View File

@ -24,6 +24,7 @@ const { pb } = require('./private-browsing/helper');
const { URL } = require('sdk/url');
const SVG_URL = self.data.url('mofo_logo.SVG');
const Isolate = fn => '(' + fn + ')()';
function ignorePassingDOMNodeWarning(type, message) {
if (type !== 'warn' || !message.startsWith('Passing a DOM node'))
@ -166,54 +167,53 @@ exports["test Document Reload"] = function(assert, done) {
exports["test Parent Resize Hack"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator).
getMostRecentWindow("navigator:browser");
let docShell = browserWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
if (!("allowWindowControl" in docShell)) {
// bug 635673 is not fixed in this firefox build
assert.pass("allowWindowControl attribute that allow to fix browser window " +
"resize is not available on this build.");
return;
}
let browserWindow = getMostRecentBrowserWindow();
let previousWidth = browserWindow.outerWidth, previousHeight = browserWindow.outerHeight;
let previousWidth = browserWindow.outerWidth;
let previousHeight = browserWindow.outerHeight;
let content = "<script>" +
"function contentResize() {" +
" resizeTo(200,200);" +
" resizeBy(200,200);" +
" window.postMessage('resize-attempt', '*');" +
"}" +
"</script>" +
"Try to resize browser window";
let panel = Panel({
contentURL: "data:text/html;charset=utf-8," + encodeURIComponent(content),
contentScript: "self.on('message', function(message){" +
" if (message=='resize') " +
" unsafeWindow.contentResize();" +
"});",
contentScriptWhen: "ready",
onMessage: function (message) {
contentScript: Isolate(() => {
self.on('message', message => {
if (message === 'resize') unsafeWindow.contentResize();
});
window.addEventListener('message', ({ data }) => self.postMessage(data));
}),
onMessage: function (message) {
if (message !== "resize-attempt") return;
assert.equal(browserWindow, getMostRecentBrowserWindow(),
"The browser window is still the same");
assert.equal(previousWidth, browserWindow.outerWidth,
"Size doesn't change by calling resizeTo/By/...");
assert.equal(previousHeight, browserWindow.outerHeight,
"Size doesn't change by calling resizeTo/By/...");
try {
panel.destroy();
}
catch (e) {
assert.fail(e);
throw e;
}
done();
},
onShow: function () {
panel.postMessage('resize');
timer.setTimeout(function () {
assert.equal(previousWidth,browserWindow.outerWidth,"Size doesn't change by calling resizeTo/By/...");
assert.equal(previousHeight,browserWindow.outerHeight,"Size doesn't change by calling resizeTo/By/...");
try {
panel.destroy();
}
catch (e) {
console.exception(e);
throw e;
}
done();
},0);
}
onShow: () => panel.postMessage('resize')
});
panel.show();
}

View File

@ -18,6 +18,8 @@ const { getMode, isGlobalPBSupported,
isWindowPBSupported, isTabPBSupported } = require('sdk/private-browsing/utils');
const { pb } = require('./private-browsing/helper');
const prefs = require('sdk/preferences/service');
const { set: setPref } = require("sdk/preferences/service");
const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
const kAutoStartPref = "browser.privatebrowsing.autostart";
@ -55,6 +57,7 @@ exports.testIsPrivateDefaults = function(test) {
};
exports.testWindowDefaults = function(test) {
setPref(DEPRECATE_PREF, true);
// Ensure that browserWindow still works while being deprecated
let { loader, messages } = LoaderWithHookedConsole(module);
let windows = loader.require("sdk/windows").browserWindows;

View File

@ -6,11 +6,13 @@
const { XMLHttpRequest } = require('sdk/net/xhr');
const { LoaderWithHookedConsole } = require('sdk/test/loader');
const { data } = require('sdk/self');
const { set: setPref } = require("sdk/preferences/service");
const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
exports.testAPIExtension = function(assert) {
let { loader, messages } = LoaderWithHookedConsole(module);
let { XMLHttpRequest } = loader.require("sdk/net/xhr");
setPref(DEPRECATE_PREF, true);
let xhr = new XMLHttpRequest();
assert.equal(typeof(xhr.forceAllowThirdPartyCookie), "function",