diff options
Diffstat (limited to 'devtools/client/aboutdebugging/src/modules/extensions-helper.js')
-rw-r--r-- | devtools/client/aboutdebugging/src/modules/extensions-helper.js | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/devtools/client/aboutdebugging/src/modules/extensions-helper.js b/devtools/client/aboutdebugging/src/modules/extensions-helper.js new file mode 100644 index 0000000000..ec0d7c2661 --- /dev/null +++ b/devtools/client/aboutdebugging/src/modules/extensions-helper.js @@ -0,0 +1,92 @@ +/* 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 lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + FileUtils: "resource://gre/modules/FileUtils.sys.mjs", +}); + +const { + PREFERENCES, +} = require("resource://devtools/client/aboutdebugging/src/constants.js"); + +exports.parseFileUri = function (url) { + // Strip a leading slash from Windows drive letter URIs. + // file:///home/foo ~> /home/foo + // file:///C:/foo ~> C:/foo + const windowsRegex = /^file:\/\/\/([a-zA-Z]:\/.*)/; + if (windowsRegex.test(url)) { + return windowsRegex.exec(url)[1]; + } + return url.slice("file://".length); +}; + +exports.getExtensionUuid = function (extension) { + const { manifestURL } = extension; + // Strip off the protocol and rest, leaving us with just the UUID. + return manifestURL ? /moz-extension:\/\/([^/]*)/.exec(manifestURL)[1] : null; +}; + +/** + * Open a file picker to allow the user to locate a temporary extension. A temporary + * extension can either be: + * - a folder + * - a .xpi file + * - a .zip file + * + * @param {Window} win + * The window object where the filepicker should be opened. + * Note: We cannot use the global window object here because it is undefined if + * this module is loaded from a file outside of devtools/client/aboutdebugging/. + * See browser-loader.js `uri.startsWith(baseURI)` for more details. + * @param {String} message + * The help message that should be displayed to the user in the filepicker. + * @return {Promise} returns a promise that resolves a File object corresponding to the + * file selected by the user. + */ +exports.openTemporaryExtension = function (win, message) { + return new Promise(resolve => { + const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); + fp.init(win, message, Ci.nsIFilePicker.modeOpen); + + // Try to set the last directory used as "displayDirectory". + try { + const lastDirPath = Services.prefs.getCharPref( + PREFERENCES.TEMPORARY_EXTENSION_PATH, + "" + ); + const lastDir = new lazy.FileUtils.File(lastDirPath); + fp.displayDirectory = lastDir; + } catch (e) { + // Empty or invalid value, nothing to handle. + } + + fp.open(res => { + if (res == Ci.nsIFilePicker.returnCancel || !fp.file) { + return; + } + let file = fp.file; + // AddonManager.installTemporaryAddon accepts either + // addon directory or final xpi file. + if ( + !file.isDirectory() && + !file.leafName.endsWith(".xpi") && + !file.leafName.endsWith(".zip") + ) { + file = file.parent; + } + + // We are about to resolve, store the path to the file for the next call. + Services.prefs.setCharPref( + PREFERENCES.TEMPORARY_EXTENSION_PATH, + file.path + ); + + resolve(file); + }); + }); +}; |