]> git.donarmstrong.com Git - dactyl.git/blobdiff - common/modules/bootstrap.jsm
Import 1.0b7.1 supporting Firefox up to 8.*
[dactyl.git] / common / modules / bootstrap.jsm
index 005ba1624c5ef86dc2a3177863f76aef47b27452..d51f8696b1f7192c1c6a47577f01a8c8a7e312dc 100644 (file)
@@ -6,6 +6,8 @@
 
 try {
 
+let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+
 var EXPORTED_SYMBOLS = ["JSMLoader"];
 
 var BOOTSTRAP_CONTRACT = "@dactyl.googlecode.com/base/bootstrap";
@@ -17,21 +19,53 @@ if (!JSMLoader && "@mozilla.org/fuel/application;1" in Components.classes)
                           .getService(Components.interfaces.extIApplication)
                           .storage.get("dactyl.JSMLoader", null);
 
-if (JSMLoader && JSMLoader.bump === 4)
+if (JSMLoader && JSMLoader.bump === 5)
     JSMLoader.global = this;
 else
     JSMLoader = {
-        bump: 4,
-        builtin: Components.utils.Sandbox(this),
+        bump: 5,
+
+        builtin: Cu.Sandbox(this),
+
         canonical: {},
+
         factories: [],
+
         global: this,
+
         globals: JSMLoader ? JSMLoader.globals : {},
-        io: Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService),
-        loader: Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader),
-        manager: Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar),
+
+        io: Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService),
+
+        loader: Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader),
+
+        manager: Components.manager.QueryInterface(Ci.nsIComponentRegistrar),
+
+        modules: JSMLoader && JSMLoader.modules || {},
+
         stale: JSMLoader ? JSMLoader.stale : {},
+
         suffix: "",
+
+        times: {
+            all: 0,
+            add: function add(major, minor, delta) {
+                this.all += delta;
+
+                this[major] = (this[major] || 0) + delta;
+                if (minor) {
+                    minor = ":" + minor;
+                    this[minor] = (this[minor] || 0) + delta;
+                    this[major + minor] = (this[major + minor] || 0) + delta;
+                }
+            },
+            clear: function clear() {
+                for (let key in this)
+                    if (typeof this[key] !== "number")
+                        delete this[key];
+            }
+        },
+
         init: function init(suffix) {
             this.initialized = true;
             this.suffix = suffix || "";
@@ -41,14 +75,16 @@ else
             this.global.JSMLoader = this;
             base.JSMLoader = this;
         },
+
         getTarget: function getTarget(url) {
             if (url.indexOf(":") === -1)
                 url = "resource://dactyl" + this.suffix + "/" + url;
 
             let chan = this.io.newChannel(url, null, null);
-            chan.cancel(Components.results.NS_BINDING_ABORTED);
+            chan.cancel(Cr.NS_BINDING_ABORTED);
             return chan.name;
         },
+
         load: function load(name, target) {
             let url = name;
             if (url.indexOf(":") === -1)
@@ -68,7 +104,13 @@ else
             }
 
             try {
-                let global = Components.utils.import(url, target);
+                let now = Date.now();
+                this.modules[url] = true;
+                let global = Cu.import(url, target);
+
+                if (!(name in this.globals))
+                    this.times.add("require", name, Date.now() - now);
+
                 return this.globals[name] = global;
             }
             catch (e) {
@@ -76,33 +118,52 @@ else
                 throw e;
             }
         },
-        loadSubScript: function loadSubScript() this.loader.loadSubScript.apply(this.loader, arguments),
+
+        loadSubScript: function loadSubScript(script) {
+            let now = Date.now();
+            this.loader.loadSubScript.apply(this.loader, arguments);
+            this.times.add("loadSubScript", script, Date.now() - now);
+        },
+
         cleanup: function unregister() {
             for each (let factory in this.factories.splice(0))
                 this.manager.unregisterFactory(factory.classID, factory);
         },
+
         purge: function purge() {
             dump("dactyl: JSMLoader: purge\n");
 
-            for (let [url, global] in Iterator(this.globals)) {
-                if (url === "bootstrap.jsm" || url === "resource://dactyl/bootstrap.jsm")
-                    continue;
-
-                let target = this.getTarget(url);
-                this.stale[url] = target;
-                this.stale[target] = target;
-
-                for each (let prop in Object.getOwnPropertyNames(global))
+            if (Cu.unload) {
+                Object.keys(this.modules).reverse().forEach(function (url) {
                     try {
-                        if (!(prop in this.builtin) &&
-                            ["JSMLoader", "set", "EXPORTED_SYMBOLS"].indexOf(prop) < 0 &&
-                            !global.__lookupGetter__(prop))
-                            global[prop] = undefined;
+                        Cu.unload(url);
                     }
                     catch (e) {
-                        dump("Deleting property " + prop + " on " + url + ":\n    " + e + "\n");
-                        Components.utils.reportError(e);
+                        Cu.reportError(e);
                     }
+                });
+            }
+            else {
+                for (let [url, global] in Iterator(this.globals)) {
+                    if (url === "bootstrap.jsm" || url === "resource://dactyl/bootstrap.jsm")
+                        continue;
+
+                    let target = this.getTarget(url);
+                    this.stale[url] = target;
+                    this.stale[target] = target;
+
+                    for each (let prop in Object.getOwnPropertyNames(global))
+                        try {
+                            if (!(prop in this.builtin) &&
+                                ["JSMLoader", "Set", "set", "EXPORTED_SYMBOLS"].indexOf(prop) < 0 &&
+                                !global.__lookupGetter__(prop))
+                                global[prop] = undefined;
+                        }
+                        catch (e) {
+                            dump("Deleting property " + prop + " on " + url + ":\n    " + e + "\n");
+                            Cu.reportError(e);
+                        }
+                }
             }
         },