diff --git a/common/content/io.js b/common/content/io.js index 3148c30d..a40a2bd9 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -759,15 +759,30 @@ lookup: }; completion.addUrlCompleter("f", "Local files", function (context, full) { - let match = /^(chrome:\/\/[^\/]+\/)([^/]*)$/.exec(context.filter); + let match = util.regexp().exec(context.filter); if (match) { - context.key = match[1]; - context.advance(match[1].length); - context.generate = function () iter({ - content: "Chrome content", - locale: "Locale-specific content", - skin: "Theme-specific content" - }); + if (!match[4]) { + context.key = match[2]; + context.advance(match[2].length); + context.generate = function () util.chromePackages.map(function (p) [p, match[1] + p + "/"]); + } + else if (match[3] === "chrome") { + context.key = match[1]; + context.advance(match[1].length + 1); + context.generate = function () iter({ + content: "Chrome content", + locale: "Locale-specific content", + skin: "Theme-specific content" + }); + } } else if (/^(\.{0,2}|~)\/|^file:/.test(context.filter) || util.getFile(context.filter) || io.isJarURL(context.filter)) completion.file(context, full); diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm index 8f5cca84..c7a764b3 100644 --- a/common/modules/storage.jsm +++ b/common/modules/storage.jsm @@ -288,6 +288,8 @@ const File = Class("File", { * Iterates over the objects in this directory. */ iterDirectory: function () { + if (!this.exists()) + throw Error("File does not exist"); if (!this.isDirectory()) throw Error("Not a directory"); for (let file in iter(this.directoryEntries)) @@ -313,32 +315,9 @@ const File = Class("File", { */ read: function (encoding) { let ifstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); - ifstream.init(this, -1, 0, 0); - try { - if (encoding instanceof Ci.nsIOutputStream) { - let l, len = 0; - while ((l = encoding.writeFrom(ifstream, 4096)) != 0) - len += l; - return len; - } - else { - var icstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream); - icstream.init(ifstream, encoding || File.defaultEncoding, 4096, // 4096 bytes buffering - Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); - let buffer = []; - let str = {}; - while (icstream.readString(4096, str) != 0) - buffer.push(str.value); - return buffer.join(""); - } - } - finally { - if (icstream) - icstream.close(); - ifstream.close(); - } + return File.readStream(ifstream, encoding); }, /** @@ -534,6 +513,23 @@ const File = Class("File", { expandPathList: function (list) list.map(this.expandPath), + readStream: function (ifstream, encoding) { + try { + var icstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream); + icstream.init(ifstream, encoding || File.defaultEncoding, 4096, // 4096 bytes buffering + Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); + let buffer = []; + let str = {}; + while (icstream.readString(4096, str) != 0) + buffer.push(str.value); + return buffer.join(""); + } + finally { + icstream.close(); + ifstream.close(); + } + }, + isAbsolutePath: function (path) { try { services.File().initWithPath(path); diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 681a97e5..d7b11554 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -104,6 +104,55 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) throw new FailedAssertion(message); }, + get chromePackages() { + // Horrible hack. + let res = {}; + function process(manifest) { + for each (let line in manifest.split(/\n+/)) { + let match = /^\s*(content|skin|locale|resource)\s+([^\s#]+)\s/.exec(line); + if (match) + res[match[2]] = true; + } + } + function processJar(file) { + let jar = services.ZipReader(file); + if (jar) { + if (jar.hasEntry("chrome.manifest")) + process(File.readStream(jar.getInputStream("chrome.manifest"))); + jar.close(); + } + } + + for each (let dir in ["UChrm", "AChrom"]) { + dir = File(services.directory.get(dir, Ci.nsIFile)); + if (dir.exists() && dir.isDirectory()) + for (let file in dir.iterDirectory()) + if (/\.manifest$/.test(file.leafName)) + process(file.read()); + + dir = File(dir.parent); + if (dir.exists() && dir.isDirectory()) + for (let file in dir.iterDirectory()) + if (/\.jar$/.test(file.leafName)) + processJar(file); + + dir = dir.child("extensions"); + if (dir.exists() && dir.isDirectory()) + for (let ext in dir.iterDirectory()) { + if (/\.xpi$/.test(ext.leafName)) + processJar(ext); + else { + if (ext.isFile()) + ext = File(ext.read().replace(/\n*$/, "")); + let mf = ext.child("chrome.manifest"); + if (mf.exists()) + process(mf.read()); + } + } + } + return Object.keys(res).sort(); + }, + /** * Returns a shallow copy of *obj*. *