diff options
Diffstat (limited to 'devtools/shared/gcli/commands/cmd.js')
-rw-r--r-- | devtools/shared/gcli/commands/cmd.js | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/devtools/shared/gcli/commands/cmd.js b/devtools/shared/gcli/commands/cmd.js new file mode 100644 index 0000000000..1777ed9604 --- /dev/null +++ b/devtools/shared/gcli/commands/cmd.js @@ -0,0 +1,178 @@ +/* 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 { Cc, Ci, Cu } = require("chrome"); + +const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {}); +const { TextEncoder, TextDecoder } = Cu.import('resource://gre/modules/commonjs/toolkit/loader.js', {}); +const gcli = require("gcli/index"); +const l10n = require("gcli/l10n"); + +loader.lazyGetter(this, "prefBranch", function() { + let prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService); + return prefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch2); +}); + +loader.lazyGetter(this, "supportsString", function() { + return Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString); +}); + +loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm"); + +const PREF_DIR = "devtools.commands.dir"; + +/** + * Load all the .mozcmd files in the directory pointed to by PREF_DIR + * @return A promise of an array of items suitable for gcli.addItems or + * using in gcli.addItemsByModule + */ +function loadItemsFromMozDir() { + let dirName = prefBranch.getComplexValue(PREF_DIR, + Ci.nsISupportsString).data.trim(); + if (dirName == "") { + return Promise.resolve([]); + } + + // replaces ~ with the home directory path in unix and windows + if (dirName.indexOf("~") == 0) { + let dirService = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties); + let homeDirFile = dirService.get("Home", Ci.nsIFile); + let homeDir = homeDirFile.path; + dirName = dirName.substr(1); + dirName = homeDir + dirName; + } + + // statPromise resolves to nothing if dirName is a directory, or it + // rejects with an error message otherwise + let statPromise = OS.File.stat(dirName); + statPromise = statPromise.then( + function onSuccess(stat) { + if (!stat.isDir) { + throw new Error("'" + dirName + "' is not a directory."); + } + }, + function onFailure(reason) { + if (reason instanceof OS.File.Error && reason.becauseNoSuchFile) { + throw new Error("'" + dirName + "' does not exist."); + } else { + throw reason; + } + } + ); + + // We need to return (a promise of) an array of items from the *.mozcmd + // files in dirName (which we can assume to be a valid directory now) + return statPromise.then(() => { + let itemPromises = []; + + let iterator = new OS.File.DirectoryIterator(dirName); + let iterPromise = iterator.forEach(entry => { + if (entry.name.match(/.*\.mozcmd$/) && !entry.isDir) { + itemPromises.push(loadCommandFile(entry)); + } + }); + + return iterPromise.then(() => { + iterator.close(); + return Promise.all(itemPromises).then((itemsArray) => { + return itemsArray.reduce((prev, curr) => { + return prev.concat(curr); + }, []); + }); + }, reason => { iterator.close(); throw reason; }); + }); +} + +exports.mozDirLoader = function(name) { + return loadItemsFromMozDir().then(items => { + return { items: items }; + }); +}; + +/** + * Load the commands from a single file + * @param OS.File.DirectoryIterator.Entry entry The DirectoryIterator + * Entry of the file containing the commands that we should read + */ +function loadCommandFile(entry) { + let readPromise = OS.File.read(entry.path); + return readPromise = readPromise.then(array => { + let decoder = new TextDecoder(); + let source = decoder.decode(array); + var principal = Cc["@mozilla.org/systemprincipal;1"] + .createInstance(Ci.nsIPrincipal); + + let sandbox = new Cu.Sandbox(principal, { + sandboxName: entry.path + }); + let data = Cu.evalInSandbox(source, sandbox, "1.8", entry.name, 1); + + if (!Array.isArray(data)) { + console.error("Command file '" + entry.name + "' does not have top level array."); + return; + } + + return data; + }); +} + +exports.items = [ + { + name: "cmd", + get hidden() { + return !prefBranch.prefHasUserValue(PREF_DIR); + }, + description: l10n.lookup("cmdDesc") + }, + { + item: "command", + runAt: "client", + name: "cmd refresh", + description: l10n.lookup("cmdRefreshDesc"), + get hidden() { + return !prefBranch.prefHasUserValue(PREF_DIR); + }, + exec: function(args, context) { + gcli.load(); + + let dirName = prefBranch.getComplexValue(PREF_DIR, + Ci.nsISupportsString).data.trim(); + return l10n.lookupFormat("cmdStatus3", [ dirName ]); + } + }, + { + item: "command", + runAt: "client", + name: "cmd setdir", + description: l10n.lookup("cmdSetdirDesc"), + manual: l10n.lookup("cmdSetdirManual3"), + params: [ + { + name: "directory", + description: l10n.lookup("cmdSetdirDirectoryDesc"), + type: { + name: "file", + filetype: "directory", + existing: "yes" + }, + defaultValue: null + } + ], + returnType: "string", + get hidden() { + return true; // !prefBranch.prefHasUserValue(PREF_DIR); + }, + exec: function(args, context) { + supportsString.data = args.directory; + prefBranch.setComplexValue(PREF_DIR, Ci.nsISupportsString, supportsString); + + gcli.load(); + + return l10n.lookupFormat("cmdStatus3", [ args.directory ]); + } + } +]; |