Source code
Revision control
Copy as Markdown
Other Tools
/* 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
"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.
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.sys.mjs `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.browsingContext, 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);
});
});
};