|
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 // see http://mxr.mozilla.org/mozilla-central/source/services/sync/Weave.js#76 |
|
8 |
|
9 const Cc = Components.classes; |
|
10 const Ci = Components.interfaces; |
|
11 const Cu = Components.utils; |
|
12 |
|
13 Cu.import("resource://gre/modules/Services.jsm"); |
|
14 |
|
15 const rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); |
|
16 |
|
17 function endsWith(str, end) { |
|
18 return str.slice(-end.length) == end; |
|
19 } |
|
20 |
|
21 function jar_entries(jarReader, pattern) { |
|
22 var entries = []; |
|
23 var enumerator = jarReader.findEntries(pattern); |
|
24 while (enumerator.hasMore()) { |
|
25 entries.push(enumerator.getNext()); |
|
26 } |
|
27 return entries; |
|
28 } |
|
29 |
|
30 function dir_entries(baseDir, subpath, ext) { |
|
31 var dir = baseDir.clone(); |
|
32 dir.append(subpath); |
|
33 var enumerator = dir.directoryEntries; |
|
34 var entries = []; |
|
35 while (enumerator.hasMoreElements()) { |
|
36 var file = enumerator.getNext().QueryInterface(Ci.nsIFile); |
|
37 if (file.isDirectory()) { |
|
38 entries = entries.concat(dir_entries(dir, file.leafName, ext).map(function(p) subpath + "/" + p)); |
|
39 } else if (endsWith(file.leafName, ext)) { |
|
40 entries.push(subpath + "/" + file.leafName); |
|
41 } |
|
42 } |
|
43 return entries; |
|
44 } |
|
45 |
|
46 function get_modules_under(uri) { |
|
47 if (uri instanceof Ci.nsIJARURI) { |
|
48 var jar = uri.QueryInterface(Ci.nsIJARURI); |
|
49 var jarReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader); |
|
50 var file = jar.JARFile.QueryInterface(Ci.nsIFileURL); |
|
51 jarReader.open(file.file); |
|
52 var entries = jar_entries(jarReader, "components/*.js") |
|
53 .concat(jar_entries(jarReader, "modules/*.js")) |
|
54 .concat(jar_entries(jarReader, "modules/*.jsm")); |
|
55 jarReader.close(); |
|
56 return entries; |
|
57 } else if (uri instanceof Ci.nsIFileURL){ |
|
58 var file = uri.QueryInterface(Ci.nsIFileURL); |
|
59 return dir_entries(file.file, "components", ".js") |
|
60 .concat(dir_entries(file.file, "modules", ".js")) |
|
61 .concat(dir_entries(file.file, "modules", ".jsm")); |
|
62 } else { |
|
63 throw "Expected a nsIJARURI or nsIFileURL"; |
|
64 } |
|
65 } |
|
66 |
|
67 function load_modules_under(spec, uri) { |
|
68 var entries = get_modules_under(uri).sort(); |
|
69 // The precompilation of JS here sometimes reports errors, which we don't |
|
70 // really care about. But if the errors are ever reported to xpcshell's |
|
71 // error reporter, it will cause it to return an error code, which will break |
|
72 // automation. Currently they won't be, because the component loader spins up |
|
73 // its JSContext before xpcshell has time to set its context callback (which |
|
74 // overrides the error reporter on all newly-created JSContexts). But as we |
|
75 // move towards a singled-cxed browser, we'll run into this. So let's be |
|
76 // forward-thinking and deal with it now. |
|
77 ignoreReportedErrors(true); |
|
78 for each (let entry in entries) { |
|
79 try { |
|
80 dump(spec + entry + "\n"); |
|
81 Cu.import(spec + entry, null); |
|
82 } catch(e) {} |
|
83 } |
|
84 ignoreReportedErrors(false); |
|
85 } |
|
86 |
|
87 function resolveResource(spec) { |
|
88 var uri = Services.io.newURI(spec, null, null); |
|
89 return Services.io.newURI(rph.resolveURI(uri), null, null); |
|
90 } |
|
91 |
|
92 function precompile_startupcache(uri) { |
|
93 load_modules_under(uri, resolveResource(uri)); |
|
94 } |