/* 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) { 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); return l10n.lookupFormat("cmdStatus3", [ args.directory ]); } } ];