diff --git a/common/bootstrap.js b/common/bootstrap.js index 39bf9e73..1138197c 100755 --- a/common/bootstrap.js +++ b/common/bootstrap.js @@ -38,6 +38,7 @@ function writeFile(file, buf) { let initialized = false; let addon = null; let basePath = null; +let components = {}; function startup(data, reason) { dump("dactyl: bootstrap: startup\n"); @@ -68,12 +69,16 @@ function FactoryProxy(url, classID) { } FactoryProxy.prototype = { QueryInterface: XPCOMUtils.generateQI(Ci.nsIFactory), - init: function () { + register: function () { manager.registerFactory(this.classID, String(this.classID), this.contractID, this); }, + unregister: function () { + manager.unregisterFactory(this.classID, + this); + }, get module() { Class.replaceProperty(this, "module", {}); Cu.import(this.url, this.module); @@ -96,7 +101,6 @@ function init() { function url(path) addon.getResourceURI(path).spec; let result = []; - let components = {}; for each (let line in manifest.split("\n")) { let fields = line.split(/\s+/); @@ -121,7 +125,7 @@ function init() { break; case "contract": components[fields[2]].contractID = fields[1]; - components[fields[2]].init(); + components[fields[2]].register(); break; case "resource": @@ -156,6 +160,14 @@ function init() { require(global, "overlay"); } +function shutdown(data, reason) { + dump("dactyl: bootstrap: shutdown\n"); + for (let factory in values(components)) + // TODO: Categories; + factory.unregister(); + services.observer.notifyObservers(null, "dactyl-cleanup", null); +} + function reasonToString(reason) { for each (let name in ["disable", "downgrade", "enable", "install", "shutdown", "startup", @@ -166,6 +178,5 @@ function reasonToString(reason) { } function install(data, reason) { dump("dactyl: bootstrap: install\n") } -function shutdown(data, reason) { dump("dactyl: bootstrap: shutdown\n") } function uninstall(data, reason) { dump("dactyl: bootstrap: uninstall\n") } diff --git a/common/content/commandline.js b/common/content/commandline.js index a1d7f0b2..03ba6ecb 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -242,7 +242,9 @@ const CommandWidgets = Class("CommandWidgets", { multilineOutput: Class.memoize(function () { let elem = document.getElementById("dactyl-multiline-output"); elem.contentWindow.addEventListener("unload", function (event) { event.preventDefault(); }, true); - elem.contentDocument.body.id = "dactyl-multiline-output-content"; + elem.contentWindow.addEventListener("load", function (event) { + elem.contentDocument.body.id = "dactyl-multiline-output-content"; + }, false); ["copy", "copylink", "selectall"].forEach(function (tail) { // some host apps use "hostPrefixContext-copy" ids let xpath = "//xul:menuitem[contains(@id, '" + "ontext-" + tail + "') and not(starts-with(@id, 'dactyl-'))]"; diff --git a/common/modules/util.jsm b/common/modules/util.jsm index d265c677..d06bb0b7 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -946,19 +946,18 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) overlay("append", function (elem, dom) elem.appendChild(dom)); overlay("prepend", function (elem, dom) elem.insertBefore(dom, elem.firstChild)); if (obj.init) - obj.init(window, window.document.dactylDOMLoaded); + obj.init(window); if (obj.load) - if (doc.dactylLoaded) - obj.load(window, doc.dactylLoaded); - else - doc.addEventListener("load", wrapCallback(function load(event) { - if (event.originalTarget === event.target) { - doc.removeEventListener("load", load.wrapper, true); - doc.dactylLoaded = event; - obj.load(window, event); - } - }), true); + if (doc.readyState === "complete") + obj.load(window); + else + doc.addEventListener("load", wrapCallback(function load(event) { + if (event.originalTarget === event.target) { + doc.removeEventListener("load", load.wrapper, true); + obj.load(window, event); + } + }), true); }, observe: { @@ -981,10 +980,8 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) }, "toplevel-window-ready": function (window, data) { window.addEventListener("DOMContentLoaded", wrapCallback(function listener(event) { - window.dactylDOMLoaded = false; if (event.originalTarget === window.document) { window.removeEventListener("DOMContentLoaded", listener.wrapper, true); - window.document.dactylDOMLoaded = event; util._loadOverlays(window); } }), true) @@ -1001,13 +998,11 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) this.overlays[url].push(fn); }, this); - for (let win in iter(services.windowMediator.getEnumerator(null))) { - util.dump("checkOverlay", win.document.dactylDOMLoaded, win.document.location.href); - if (win.document.dactylDOMLoaded || win.dactylDOMLoaded !== false) + for (let win in iter(services.windowMediator.getEnumerator(null))) + if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) this._loadOverlays(win); else this.observe(win, "toplevel-window-ready"); - } } },