michael@0: /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // see http://mxr.mozilla.org/mozilla-central/source/services/sync/Weave.js#76 michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: const rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); michael@0: michael@0: function endsWith(str, end) { michael@0: return str.slice(-end.length) == end; michael@0: } michael@0: michael@0: function jar_entries(jarReader, pattern) { michael@0: var entries = []; michael@0: var enumerator = jarReader.findEntries(pattern); michael@0: while (enumerator.hasMore()) { michael@0: entries.push(enumerator.getNext()); michael@0: } michael@0: return entries; michael@0: } michael@0: michael@0: function dir_entries(baseDir, subpath, ext) { michael@0: var dir = baseDir.clone(); michael@0: dir.append(subpath); michael@0: var enumerator = dir.directoryEntries; michael@0: var entries = []; michael@0: while (enumerator.hasMoreElements()) { michael@0: var file = enumerator.getNext().QueryInterface(Ci.nsIFile); michael@0: if (file.isDirectory()) { michael@0: entries = entries.concat(dir_entries(dir, file.leafName, ext).map(function(p) subpath + "/" + p)); michael@0: } else if (endsWith(file.leafName, ext)) { michael@0: entries.push(subpath + "/" + file.leafName); michael@0: } michael@0: } michael@0: return entries; michael@0: } michael@0: michael@0: function get_modules_under(uri) { michael@0: if (uri instanceof Ci.nsIJARURI) { michael@0: var jar = uri.QueryInterface(Ci.nsIJARURI); michael@0: var jarReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader); michael@0: var file = jar.JARFile.QueryInterface(Ci.nsIFileURL); michael@0: jarReader.open(file.file); michael@0: var entries = jar_entries(jarReader, "components/*.js") michael@0: .concat(jar_entries(jarReader, "modules/*.js")) michael@0: .concat(jar_entries(jarReader, "modules/*.jsm")); michael@0: jarReader.close(); michael@0: return entries; michael@0: } else if (uri instanceof Ci.nsIFileURL){ michael@0: var file = uri.QueryInterface(Ci.nsIFileURL); michael@0: return dir_entries(file.file, "components", ".js") michael@0: .concat(dir_entries(file.file, "modules", ".js")) michael@0: .concat(dir_entries(file.file, "modules", ".jsm")); michael@0: } else { michael@0: throw "Expected a nsIJARURI or nsIFileURL"; michael@0: } michael@0: } michael@0: michael@0: function load_modules_under(spec, uri) { michael@0: var entries = get_modules_under(uri).sort(); michael@0: // The precompilation of JS here sometimes reports errors, which we don't michael@0: // really care about. But if the errors are ever reported to xpcshell's michael@0: // error reporter, it will cause it to return an error code, which will break michael@0: // automation. Currently they won't be, because the component loader spins up michael@0: // its JSContext before xpcshell has time to set its context callback (which michael@0: // overrides the error reporter on all newly-created JSContexts). But as we michael@0: // move towards a singled-cxed browser, we'll run into this. So let's be michael@0: // forward-thinking and deal with it now. michael@0: ignoreReportedErrors(true); michael@0: for each (let entry in entries) { michael@0: try { michael@0: dump(spec + entry + "\n"); michael@0: Cu.import(spec + entry, null); michael@0: } catch(e) {} michael@0: } michael@0: ignoreReportedErrors(false); michael@0: } michael@0: michael@0: function resolveResource(spec) { michael@0: var uri = Services.io.newURI(spec, null, null); michael@0: return Services.io.newURI(rph.resolveURI(uri), null, null); michael@0: } michael@0: michael@0: function precompile_startupcache(uri) { michael@0: load_modules_under(uri, resolveResource(uri)); michael@0: }