webExtension.sys.mjs (5267B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { RootBiDiModule } from "chrome://remote/content/webdriver-bidi/modules/RootBiDiModule.sys.mjs"; 6 7 const lazy = {}; 8 9 ChromeUtils.defineESModuleGetters(lazy, { 10 Addon: "chrome://remote/content/shared/Addon.sys.mjs", 11 assert: "chrome://remote/content/shared/webdriver/Assert.sys.mjs", 12 error: "chrome://remote/content/shared/webdriver/Errors.sys.mjs", 13 pprint: "chrome://remote/content/shared/Format.sys.mjs", 14 }); 15 16 /** 17 * A WebExtension id. 18 * 19 * @typedef {string} Extension 20 */ 21 22 /** 23 * Return value of the install command. 24 * 25 * @typedef InstallResult 26 * 27 * @property {Extension} extension 28 */ 29 30 /** 31 * Enum of types supported by the webExtension.install command. 32 * 33 * @readonly 34 * @enum {ExtensionDataType} 35 */ 36 export const ExtensionDataType = { 37 Path: "path", 38 ArchivePath: "archivePath", 39 Base64: "base64", 40 }; 41 42 /** 43 * Used as an argument for webExtension.install command 44 * to represent a WebExtension archive. 45 * 46 * @typedef ExtensionArchivePath 47 * 48 * @property {ExtensionDataType} [type=ExtensionDataType.ArchivePath] 49 * @property {string} path 50 */ 51 52 /** 53 * Used as an argument for webExtension.install command 54 * to represent an unpacked WebExtension. 55 * 56 * @typedef ExtensionPath 57 * 58 * @property {ExtensionDataType} [type=ExtensionDataType.Path] 59 * @property {string} path 60 */ 61 62 /** 63 * Used as an argument for webExtension.install command 64 * to represent a WebExtension archive encoded as base64 string. 65 * 66 * @typedef ExtensionBase64 67 * 68 * @property {ExtensionDataType} [type=ExtensionDataType.Base64] 69 * @property {string} value 70 */ 71 72 class WebExtensionModule extends RootBiDiModule { 73 constructor(messageHandler) { 74 super(messageHandler); 75 } 76 77 destroy() {} 78 79 /** 80 * Installs a WebExtension. 81 * 82 * @see https://w3c.github.io/webdriver-bidi/#command-webExtension-install 83 * 84 * @param {object=} options 85 * @param {ExtensionArchivePath|ExtensionPath|ExtensionBase64} options.extensionData 86 * The WebExtension to be installed. 87 * @param {boolean=} options.moz_permanent (moz:permanent) 88 * If true, install the web extension permanently. Defaults to `false`. 89 * 90 * @returns {InstallResult} 91 * The id of the installed WebExtension. 92 * 93 * @throws {InvalidArgumentError} 94 * Raised if an argument is of an invalid type or value. 95 * @throws {InvalidWebExtensionError} 96 * Tried to install an invalid WebExtension. 97 */ 98 async install(options = {}) { 99 const { extensionData, "moz:permanent": permanent = false } = options; 100 101 lazy.assert.object( 102 extensionData, 103 `Expected "extensionData" to be an object, ` + 104 lazy.pprint`got ${extensionData}` 105 ); 106 107 const { path, type, value } = extensionData; 108 const extensionDataTypes = Object.values(ExtensionDataType); 109 110 lazy.assert.that( 111 extensionDataType => extensionDataTypes.includes(extensionDataType), 112 `Expected "extensionData.type" to be one of ${extensionDataTypes}, ` + 113 lazy.pprint`got ${type}` 114 )(type); 115 116 lazy.assert.boolean( 117 permanent, 118 lazy.pprint`Expected "moz:permanent" to be a boolean, got ${permanent}` 119 ); 120 121 let extensionId; 122 123 switch (type) { 124 case ExtensionDataType.Base64: 125 lazy.assert.string( 126 value, 127 lazy.pprint`Expected "extensionData.value" to be a string, got ${value}` 128 ); 129 130 extensionId = await lazy.Addon.installWithBase64( 131 value, 132 !permanent, 133 false 134 ); 135 break; 136 case ExtensionDataType.ArchivePath: 137 case ExtensionDataType.Path: 138 lazy.assert.string( 139 path, 140 lazy.pprint`Expected "extensionData.path" to be a string, got ${path}` 141 ); 142 143 if (permanent && type == ExtensionDataType.Path) { 144 throw new lazy.error.InvalidWebExtensionError( 145 "Permanent installation of unpacked extensions is not supported" 146 ); 147 } 148 149 extensionId = await lazy.Addon.installWithPath(path, !permanent, false); 150 } 151 152 return { 153 extension: extensionId, 154 }; 155 } 156 157 /** 158 * Uninstalls a WebExtension. 159 * 160 * @see https://w3c.github.io/webdriver-bidi/#command-webExtension-uninstall 161 * 162 * @param {object=} options 163 * @param {Extension} options.extension 164 * The id of the WebExtension to be uninstalled. 165 * 166 * @throws {InvalidArgumentError} 167 * Raised if an argument is of an invalid type or value. 168 * @throws {NoSuchWebExtensionError} 169 * Raised if the WebExtension with provided id could not be found. 170 * @throws {UnknownError} 171 * Raised if the WebExtension cannot be uninstalled. 172 */ 173 async uninstall(options = {}) { 174 const { extension: addonId } = options; 175 176 lazy.assert.string( 177 addonId, 178 lazy.pprint`Expected "extension" to be a string, got ${addonId}` 179 ); 180 181 if (addonId === "") { 182 throw new lazy.error.NoSuchWebExtensionError( 183 `Expected "extension" to be a non-empty string, got ${addonId}` 184 ); 185 } 186 187 await lazy.Addon.uninstall(addonId); 188 } 189 } 190 191 export const webExtension = WebExtensionModule;