Bug 1456051 - Make addon an ES module. r?maja_zf
This does not really functionally change anything, but it prevents
us from polluting the global space in testing/marionette/driver.js.
MozReview-Commit-ID: Guwt3g0lS8q
--- a/testing/marionette/addon.js
+++ b/testing/marionette/addon.js
@@ -4,20 +4,17 @@
"use strict";
ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
const {UnknownError} = ChromeUtils.import("chrome://marionette/content/error.js", {});
-this.EXPORTED_SYMBOLS = ["addon"];
-
-/** @namespace */
-this.addon = {};
+this.EXPORTED_SYMBOLS = ["Addon"];
// from https://developer.mozilla.org/en-US/Add-ons/Add-on_Manager/AddonManager#AddonInstall_errors
const ERRORS = {
[-1]: "ERROR_NETWORK_FAILURE: A network error occured.",
[-2]: "ERROR_INCORECT_HASH: The downloaded file did not match the expected hash.",
[-3]: "ERROR_CORRUPT_FILE: The file appears to be corrupt.",
[-4]: "ERROR_FILE_ACCESS: There was an error accessing the filesystem.",
[-5]: "ERROR_SIGNEDSTATE_REQUIRED: The addon must be signed and isn't.",
@@ -55,94 +52,98 @@ async function installAddon(file) {
onInstallEnded: success,
};
install.addListener(listener);
install.install();
});
}
-/**
- * Install a Firefox addon.
- *
- * If the addon is restartless, it can be used right away. Otherwise a
- * restart is required.
- *
- * Temporary addons will automatically be uninstalled on shutdown and
- * do not need to be signed, though they must be restartless.
- *
- * @param {string} path
- * Full path to the extension package archive.
- * @param {boolean=} temporary
- * True to install the addon temporarily, false (default) otherwise.
- *
- * @return {Promise.<string>}
- * Addon ID.
- *
- * @throws {UnknownError}
- * If there is a problem installing the addon.
- */
-addon.install = async function(path, temporary = false) {
- let addon;
- let file;
+/** Installs addons by path and uninstalls by ID. */
+class Addon {
+ /**
+ * Install a Firefox addon.
+ *
+ * If the addon is restartless, it can be used right away. Otherwise a
+ * restart is required.
+ *
+ * Temporary addons will automatically be uninstalled on shutdown and
+ * do not need to be signed, though they must be restartless.
+ *
+ * @param {string} path
+ * Full path to the extension package archive.
+ * @param {boolean=} temporary
+ * True to install the addon temporarily, false (default) otherwise.
+ *
+ * @return {Promise.<string>}
+ * Addon ID.
+ *
+ * @throws {UnknownError}
+ * If there is a problem installing the addon.
+ */
+ static async install(path, temporary = false) {
+ let addon;
+ let file;
- try {
- file = new FileUtils.File(path);
- } catch (e) {
- throw new UnknownError(`Expected absolute path: ${e}`, e);
- }
+ try {
+ file = new FileUtils.File(path);
+ } catch (e) {
+ throw new UnknownError(`Expected absolute path: ${e}`, e);
+ }
+
+ if (!file.exists()) {
+ throw new UnknownError(`No such file or directory: ${path}`);
+ }
- if (!file.exists()) {
- throw new UnknownError(`No such file or directory: ${path}`);
+ try {
+ if (temporary) {
+ addon = await AddonManager.installTemporaryAddon(file);
+ } else {
+ addon = await installAddon(file);
+ }
+ } catch (e) {
+ throw new UnknownError(
+ `Could not install add-on: ${path}: ${e.message}`, e);
+ }
+
+ return addon.id;
}
- try {
- if (temporary) {
- addon = await AddonManager.installTemporaryAddon(file);
- } else {
- addon = await installAddon(file);
- }
- } catch (e) {
- throw new UnknownError(
- `Could not install add-on: ${path}: ${e.message}`, e);
- }
-
- return addon.id;
-};
+ /**
+ * Uninstall a Firefox addon.
+ *
+ * If the addon is restartless it will be uninstalled right away.
+ * Otherwise, Firefox must be restarted for the change to take effect.
+ *
+ * @param {string} id
+ * ID of the addon to uninstall.
+ *
+ * @return {Promise}
+ *
+ * @throws {UnknownError}
+ * If there is a problem uninstalling the addon.
+ */
+ static async uninstall(id) {
+ let candidate = await AddonManager.getAddonByID(id);
-/**
- * Uninstall a Firefox addon.
- *
- * If the addon is restartless it will be uninstalled right away.
- * Otherwise, Firefox must be restarted for the change to take effect.
- *
- * @param {string} id
- * ID of the addon to uninstall.
- *
- * @return {Promise}
- *
- * @throws {UnknownError}
- * If there is a problem uninstalling the addon.
- */
-addon.uninstall = async function(id) {
- let candidate = await AddonManager.getAddonByID(id);
+ return new Promise(resolve => {
+ let listener = {
+ onOperationCancelled: addon => {
+ if (addon.id === candidate.id) {
+ AddonManager.removeAddonListener(listener);
+ throw new UnknownError(`Uninstall of ${candidate.id} has been canceled`);
+ }
+ },
- return new Promise(resolve => {
- let listener = {
- onOperationCancelled: addon => {
- if (addon.id === candidate.id) {
- AddonManager.removeAddonListener(listener);
- throw new UnknownError(`Uninstall of ${candidate.id} has been canceled`);
- }
- },
+ onUninstalled: addon => {
+ if (addon.id === candidate.id) {
+ AddonManager.removeAddonListener(listener);
+ resolve();
+ }
+ },
+ };
- onUninstalled: addon => {
- if (addon.id === candidate.id) {
- AddonManager.removeAddonListener(listener);
- resolve();
- }
- },
- };
-
- AddonManager.addAddonListener(listener);
- addon.uninstall();
- });
-};
+ AddonManager.addAddonListener(listener);
+ candidate.uninstall();
+ });
+ }
+}
+this.Addon = Addon;
--- a/testing/marionette/doc/internals/addon.rst
+++ b/testing/marionette/doc/internals/addon.rst
@@ -1,4 +1,7 @@
addon module
============
-.. js:autoclass:: addon
+
+Addon
+-----
+.. js:autoclass:: Addon
:members:
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -6,17 +6,17 @@
/* global XPCNativeWrapper */
ChromeUtils.import("resource://gre/modules/Log.jsm");
ChromeUtils.import("resource://gre/modules/Preferences.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("chrome://marionette/content/accessibility.js");
-ChromeUtils.import("chrome://marionette/content/addon.js");
+const {Addon} = ChromeUtils.import("chrome://marionette/content/addon.js", {});
ChromeUtils.import("chrome://marionette/content/assert.js");
ChromeUtils.import("chrome://marionette/content/atom.js");
const {
browser,
Context,
WindowState,
} = ChromeUtils.import("chrome://marionette/content/browser.js", {});
ChromeUtils.import("chrome://marionette/content/capture.js");
@@ -3291,28 +3291,28 @@ GeckoDriver.prototype.installAddon = fun
let path = cmd.parameters.path;
let temp = cmd.parameters.temporary || false;
if (typeof path == "undefined" || typeof path != "string" ||
typeof temp != "boolean") {
throw new InvalidArgumentError();
}
- return addon.install(path, temp);
+ return Addon.install(path, temp);
};
GeckoDriver.prototype.uninstallAddon = function(cmd) {
assert.firefox();
let id = cmd.parameters.id;
if (typeof id == "undefined" || typeof id != "string") {
throw new InvalidArgumentError();
}
- return addon.uninstall(id);
+ return Addon.uninstall(id);
};
/** Receives all messages from content messageManager. */
/* eslint-disable consistent-return */
GeckoDriver.prototype.receiveMessage = function(message) {
switch (message.name) {
case "Marionette:switchedToFrame":
if (message.json.restorePrevious) {