1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 17:37:57 +01:00

Merge changes from bootstrapped.

This commit is contained in:
Kris Maglione
2010-12-24 20:59:29 -05:00
parent c507f63194
commit 5591ed6797
17 changed files with 259 additions and 125 deletions

View File

@@ -13,6 +13,7 @@ syntax: glob
*/contrib/vim/*.vba
*/bak/*
downloads/*
.git/*
*.py[co]

View File

@@ -48,5 +48,6 @@ if (XPCOMUtils.generateNSGetFactory)
const NSGetFactory = XPCOMUtils.generateNSGetFactory([CommandLineHandler]);
else
const NSGetModule = XPCOMUtils.generateNSGetModule([CommandLineHandler]);
var EXPORTED_SYMBOLS = ["NSGetFactory"];
// vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -202,5 +202,6 @@ if (XPCOMUtils.generateNSGetFactory)
const NSGetFactory = XPCOMUtils.generateNSGetFactory([AboutHandler, ChromeData, Dactyl, Shim]);
else
const NSGetModule = XPCOMUtils.generateNSGetModule([AboutHandler, ChromeData, Dactyl, Shim]);
var EXPORTED_SYMBOLS = ["NSGetFactory"];
// vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -147,6 +147,40 @@ const Buffer = Module("buffer", {
let elem = event.originalTarget;
buffer.viewSource([elem.getAttribute("href"), Number(elem.getAttribute("line"))])
};
this.replaceProgressListener(this.progressListener);
},
cleanup: function () {
for (let prop in properties(this.progressListener))
if (!this.progressListener.__lookupGetter__(prop) &&
!callable(this.progressListener[prop]))
this.origProgressListener[prop] = this.progressListener[prop]
this.replaceProgressListener(this.origProgressListener);
},
replaceProgressListener: function (newListener) {
// I hate this whole hack. --Kris
let obj = window.XULBrowserWindow, getter;
for (let prop in properties(obj))
if ((getter = obj.__lookupGetter__(prop)) && !obj.__lookupSetter__(prop)) {
newListener.__defineGetter__(prop, getter);
delete obj[prop];
}
this.origProgressListener = window.XULBrowserWindow;
try {
config.browser.removeProgressListener(window.XULBrowserWindow);
}
catch (e) {} // Why? --djk
config.browser.addProgressListener(newListener, Ci.nsIWebProgress.NOTIFY_ALL);
window.XULBrowserWindow = newListener;
window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIXULWindow)
.XULBrowserWindow = newListener;
},
destroy: function () {
@@ -1502,26 +1536,6 @@ const Buffer = Module("buffer", {
};
},
events: function () {
try {
config.browser.removeProgressListener(window.XULBrowserWindow);
}
catch (e) {} // Why? --djk
// I hate this whole hack. --Kris
let obj = window.XULBrowserWindow, getter;
for (let p in properties(obj))
if ((getter = obj.__lookupGetter__(p)) && !obj.__lookupSetter__(p)) {
this.progressListener.__defineGetter__(p, getter);
delete obj[p];
}
config.browser.addProgressListener(this.progressListener, Ci.nsIWebProgress.NOTIFY_ALL);
window.XULBrowserWindow = this.progressListener;
window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIXULWindow)
.XULBrowserWindow = this.progressListener;
events.addSessionListener(config.browser, "DOMContentLoaded", this.closure.onDOMContentLoaded, true);
events.addSessionListener(config.browser, "load", this.closure.onPageLoad, true);
events.addSessionListener(config.browser, "scroll", this.closure._updateBufferPosition, false);

View File

@@ -67,6 +67,7 @@ const CommandWidgets = Class("CommandWidgets", {
getGroup: function (value) {
if (this.command && !options.get("guioptions").has("M"))
return this.statusbar;
let statusElem = this.statusbar.message;
if (value && statusElem.editor.rootElement.scrollWidth > statusElem.scrollWidth)
return this.commandbar;
@@ -84,6 +85,14 @@ const CommandWidgets = Class("CommandWidgets", {
return this.commandbar;
}
});
let fontSize = util.computedStyle(document.getElementById(config.mainWindowId)).fontSize;
styles.registerSheet("chrome://dactyl/skin/dactyl.css");
styles.system.add("font-size", "chrome://dactyl/content/buffer.xhtml",
"body { font-size: " + fontSize + "; }");
},
cleanup: function cleanup() {
styles.unregisterSheet("chrome://dactyl/skin/dactyl.css");
},
addElement: function (obj) {
const self = this;
@@ -1742,12 +1751,6 @@ const CommandLine = Module("commandline", {
host && (!item.domains || !item.domains.some(function (d) util.isSubdomain(d, host))));
}
});
},
styles: function () {
let fontSize = util.computedStyle(document.getElementById(config.mainWindowId)).fontSize;
styles.registerSheet("chrome://dactyl/skin/dactyl.css");
styles.system.add("font-size", "chrome://dactyl/content/buffer.xhtml",
"body { font-size: " + fontSize + "; }");
}
});

View File

@@ -530,9 +530,9 @@ const CompletionContext = Class("CompletionContext", {
// of the given string which also matches the current
// item's text.
let len = substring.length;
let i = 0, m, n = len;
let i = 0, n = len;
while (n) {
m = Math.floor(n / 2);
let m = Math.floor(n / 2);
let keep = compare(fixCase(item.text), substring.substring(0, i + m));
if (!keep)
len = i + m - 1;

View File

@@ -37,6 +37,19 @@ const Dactyl = Module("dactyl", {
};
},
cleanup: function () {
delete window.dactyl;
delete window.liberator;
},
destroy: function () {
autocommands.trigger("LeavePre", {});
storage.saveAll();
dactyl.triggerObserver("shutdown", null);
util.dump("All dactyl modules destroyed\n");
autocommands.trigger("Leave", {});
},
/** @property {string} The name of the current user profile. */
profileName: Class.memoize(function () {
// NOTE: services.profile.selectedProfile.name doesn't return
@@ -52,14 +65,6 @@ const Dactyl = Module("dactyl", {
return "unknown";
}),
destroy: function () {
autocommands.trigger("LeavePre", {});
storage.saveAll();
dactyl.triggerObserver("shutdown", null);
util.dump("All dactyl modules destroyed\n");
autocommands.trigger("Leave", {});
},
/**
* @property {number} The current main mode.
* @see modes#mainModes

View File

@@ -13,20 +13,21 @@ plugins.contexts = {};
function Script(file) {
let self = set.has(plugins, file.path) && plugins[file.path];
if (self) {
if (self.onUnload)
if (set.has(self, "onUnload"))
self.onUnload();
}
else {
self = { __proto__: plugins };
plugins[file.path] = self;
self.NAME = file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase());
self.PATH = file.path;
self.CONTEXT = self;
self = update({ __proto__: plugins }, {
NAME: file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase()),
PATH: file.path,
CONTEXT: self
});
Class.replaceProperty(plugins, file.path, self);
// This belongs elsewhere
if (io.getRuntimeDirectories("plugins").some(
function (dir) dir.contains(file, false)))
plugins[self.NAME] = self;
Class.replaceProperty(plugins, self.NAME, self);
}
plugins.contexts[file.path] = self;
return self;
@@ -67,6 +68,13 @@ const IO = Module("io", {
services.downloadManager.addListener(this.downloadListener);
},
destroy: function () {
services.downloadManager.removeListener(this.downloadListener);
for (let [, plugin] in Iterator(plugins.contexts))
if (plugin.onUnload)
plugin.onUnload();
},
// TODO: there seems to be no way, short of a new component, to change
// the process's CWD - see https://bugzilla.mozilla.org/show_bug.cgi?id=280953
/**
@@ -111,13 +119,6 @@ const IO = Module("io", {
return this.cwd;
},
destroy: function () {
services.downloadManager.removeListener(this.downloadListener);
for (let [, plugin] in Iterator(plugins.contexts))
if (plugin.onUnload)
plugin.onUnload();
},
/**
* @property {function} File class.
* @final

View File

@@ -36,6 +36,15 @@ const Tabs = Module("tabs", {
};
},
cleanup: function cleanup() {
for (let [i, tab] in Iterator(this.allTabs)) {
function node(clas) document.getAnonymousElementByAttribute(tab, "class", clas);
for (let elem in values(["dactyl-tab-icon-number", "dactyl-tab-number"].map(node)))
if (elem)
elem.parentNode.parentNode.removeChild(elem.parentNode);
}
},
_updateTabCount: function () {
if (dactyl.has("Gecko2"))
for (let [i, tab] in Iterator(this.visibleTabs)) {
@@ -43,15 +52,15 @@ const Tabs = Module("tabs", {
if (!node("dactyl-tab-number")) {
let nodes = {};
let dom = util.xmlToDom(<xul xmlns:xul={XUL} xmlns:html={XHTML}
><xul:hbox highlight="tab-number"><xul:label key="icon" align="center" highlight="TabIconNumber" class="dactyl-tab-number"/></xul:hbox
><xul:hbox highlight="tab-number"><html:div key="label" highlight="TabNumber"/></xul:hbox
><xul:hbox highlight="tab-number"><xul:label key="icon" align="center" highlight="TabIconNumber" class="dactyl-tab-icon-number"/></xul:hbox
><xul:hbox highlight="tab-number"><html:div key="label" highlight="TabNumber" class="dactyl-tab-number"/></xul:hbox
></xul>.*, document, nodes);
let img = node("tab-icon-image");
img.parentNode.appendChild(dom);
tab.__defineGetter__("ordinal", function () Number(nodes.icon.value));
tab.__defineSetter__("ordinal", function (i) nodes.icon.value = nodes.label.textContent = i);
tab.__defineGetter__("dactylOrdinal", function () Number(nodes.icon.value));
tab.__defineSetter__("dactylOrdinal", function (i) nodes.icon.value = nodes.label.textContent = i);
}
tab.ordinal = i + 1;
tab.dactylOrdinal = i + 1;
}
statusline.updateTabCount(true);
},

View File

@@ -98,6 +98,7 @@ let loaded = {};
let currentModule;
function defineModule(name, params) {
let module = Cu.getGlobalForObject ? Cu.getGlobalForObject(params) : params.__parent__;
defineModule.globals.push(module);
module.NAME = name;
module.EXPORTED_SYMBOLS = params.exports || [];
defineModule.loadLog.push("defineModule " + name);
@@ -114,6 +115,7 @@ function defineModule(name, params) {
currentModule = module;
}
defineModule.globals = [];
defineModule.loadLog = [];
Object.defineProperty(defineModule.loadLog, "push", {
value: function (val) { defineModule.dump(val + "\n"); this[this.length] = val; }
@@ -150,8 +152,10 @@ defineModule.time = function time(major, minor, func, self) {
function endModule() {
defineModule.loadLog.push("endModule " + currentModule.NAME);
for (let [, mod] in Iterator(use[currentModule.NAME] || []))
require(mod, currentModule.NAME, "use");
loaded[currentModule.NAME] = 1;
}
@@ -177,8 +181,8 @@ defineModule("base", {
"call", "callable", "ctypes", "curry", "debuggerProperties", "defineModule",
"deprecated", "endModule", "forEach", "isArray", "isGenerator",
"isinstance", "isObject", "isString", "isSubclass", "iter", "iterAll",
"keys", "memoize", "octal", "properties", "set", "update", "values",
"withCallerGlobal"
"keys", "memoize", "octal", "properties", "require", "set", "update",
"values", "withCallerGlobal"
],
use: ["services", "util"]
});

View File

@@ -42,6 +42,10 @@ const BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver),
services.bookmarks.addObserver(this, false);
},
cleanup: function cleanup() {
services.bookmarks.removeObserver(this);
},
__iterator__: function () (val for ([, val] in Iterator(bookmarkcache.bookmarks))),
get bookmarks() Class.replaceProperty(this, "bookmarks", this.load()),

View File

@@ -28,6 +28,10 @@ const Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference
this.restore();
},
cleanup: function cleanup() {
this._branch.removeObserver("", this);
},
observe: {
"nsPref:changed": function (subject, data) {
let observers = this._observers[data];

View File

@@ -12,6 +12,8 @@
// FIXME:
// - finish 1.9.0 support if we're going to support sanitizing in Melodactyl
try {
Components.utils.import("resource://dactyl/base.jsm");
defineModule("sanitizer", {
exports: ["Range", "Sanitizer", "sanitizer"],
@@ -641,6 +643,6 @@ const Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakR
endModule();
// catch(e){dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack);}
} catch(e){dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack);}
// vim: set fdm=marker sw=4 ts=4 et ft=javascript:

View File

@@ -8,8 +8,7 @@ try {
Components.utils.import("resource://dactyl/base.jsm");
defineModule("services", {
exports: ["Services", "services"],
use: ["util"]
exports: ["AddonManager", "Services", "services"]
});
/**
@@ -72,6 +71,9 @@ const Services = Module("Services", {
this.addClass("Xmlhttp", "@mozilla.org/xmlextras/xmlhttprequest;1", Ci.nsIXMLHttpRequest);
this.addClass("ZipReader", "@mozilla.org/libjar/zip-reader;1", Ci.nsIZipReader, "open");
this.addClass("ZipWriter", "@mozilla.org/zipwriter;1", Ci.nsIZipWriter);
if (!this.extensionManager)
Components.utils.import("resource://gre/modules/AddonManager.jsm");
},
_create: function (classes, ifaces, meth, init, args) {
@@ -85,7 +87,7 @@ const Services = Module("Services", {
return res;
}
catch (e) {
util.dump("Service creation failed for '" + classes + "': " + e + "\n");
dump("dactyl: Service creation failed for '" + classes + "': " + e + "\n");
return null;
}
},
@@ -105,8 +107,12 @@ const Services = Module("Services", {
if (name in this && ifaces && !this.__lookupGetter__(name) && !(this[name] instanceof Ci.nsISupports))
throw TypeError();
this.__defineGetter__(name, function () {
let res = self._create(class_, ifaces, meth);
if (!res)
return null;
delete this[name];
return this[name] = self._create(class_, ifaces, meth);
return this[name] = res;
});
},
@@ -140,10 +146,6 @@ const Services = Module("Services", {
get: function (name) this[name],
}, {
}, {
init: function (dactyl, modules) {
if (!modules.AddonManager && !this.get("extensionManager"))
Components.utils.import("resource://gre/modules/AddonManager.jsm", modules);
},
javascript: function (dactyl, modules) {
modules.JavaScript.setCompleter(this.get, [function () [[k, v] for ([k, v] in Iterator(services)) if (v instanceof Ci.nsISupports)]]);
modules.JavaScript.setCompleter(this.create, [function () [[c, ""] for (c in services.classes)]]);

View File

@@ -142,25 +142,39 @@ const ObjectStore = Class("ObjectStore", StoreBase, {
__iterator__: function () Iterator(this._object),
});
var keys = {};
var observers = {};
const Storage = Module("Storage", {
alwaysReload: {},
init: function () {
this.cleanup();
},
cleanup: function () {
for (let key in keys(this.keys))
delete this[key];
for (let ary in values(this.observers))
for (let obj in values(ary))
if (obj.ref && obj.ref.get())
delete obj.ref.get().dactylStorageRefs;
this.keys = {};
this.observers = {};
},
newObject: function newObject(key, constructor, params) {
if (params == null || !isObject(params))
throw Error("Invalid argument type");
if (!(key in keys) || params.reload || this.alwaysReload[key]) {
if (!(key in this.keys) || params.reload || this.alwaysReload[key]) {
if (key in this && !(params.reload || this.alwaysReload[key]))
throw Error();
let load = function () loadData(key, params.store, params.type || myObject);
keys[key] = new constructor(key, params.store, load, params);
keys[key].timer = new Timer(1000, 10000, function () storage.save(key));
this.__defineGetter__(key, function () keys[key]);
this.keys[key] = new constructor(key, params.store, load, params);
this.keys[key].timer = new Timer(1000, 10000, function () storage.save(key));
this.__defineGetter__(key, function () this.keys[key]);
}
return keys[key];
return this.keys[key];
},
newMap: function newMap(key, options) {
@@ -182,38 +196,36 @@ const Storage = Module("Storage", {
callbackRef = { get: function () callback };
}
this.removeDeadObservers();
if (!(key in observers))
observers[key] = [];
if (!observers[key].some(function (o) o.callback.get() == callback))
observers[key].push({ ref: ref && Cu.getWeakReference(ref), callback: callbackRef });
if (!(key in this.observers))
this.observers[key] = [];
if (!this.observers[key].some(function (o) o.callback.get() == callback))
this.observers[key].push({ ref: ref && Cu.getWeakReference(ref), callback: callbackRef });
},
removeObserver: function (key, callback) {
this.removeDeadObservers();
if (!(key in observers))
if (!(key in this.observers))
return;
observers[key] = observers[key].filter(function (elem) elem.callback.get() != callback);
if (observers[key].length == 0)
this.observers[key] = this.observers[key].filter(function (elem) elem.callback.get() != callback);
if (this.observers[key].length == 0)
delete obsevers[key];
},
removeDeadObservers: function () {
for (let [key, ary] in Iterator(observers)) {
observers[key] = ary = ary.filter(function (o) o.callback.get() && (!o.ref || o.ref.get() && o.ref.get().dactylStorageRefs));
for (let [key, ary] in Iterator(this.observers)) {
this.observers[key] = ary = ary.filter(function (o) o.callback.get() && (!o.ref || o.ref.get() && o.ref.get().dactylStorageRefs));
if (!ary.length)
delete observers[key];
delete this.observers[key];
}
},
get observers() observers,
fireEvent: function fireEvent(key, event, arg) {
this.removeDeadObservers();
if (key in observers)
if (key in this.observers)
// Safe, since we have our own Array object here.
for each (let observer in observers[key])
for each (let observer in this.observers[key])
observer.callback.get()(key, event, arg);
if (key in keys)
if (key in this.keys)
this[key].timer.tell();
},
@@ -223,11 +235,11 @@ const Storage = Module("Storage", {
},
save: function save(key) {
saveData(keys[key]);
saveData(this.keys[key]);
},
saveAll: function storeAll() {
for each (let obj in keys)
for each (let obj in this.keys)
saveData(obj);
},
@@ -237,7 +249,7 @@ const Storage = Module("Storage", {
if (val && !this._privateMode)
this.saveAll();
if (!val && this._privateMode)
for (let key in keys)
for (let key in this.keys)
this.load(key);
return this._privateMode = Boolean(val);
}

View File

@@ -79,6 +79,11 @@ const Hive = Class("Hive", {
this.names = {};
},
cleanup: function cleanup() {
for (let sheet in values(this.sheets))
sheet.enabled = false;
},
__iterator__: function () Iterator(this.sheets),
get sites() array(this.sheets).map(function (s) s.sites).flatten().uniq().array,
@@ -214,6 +219,11 @@ const Styles = Module("Styles", {
this.system = Hive();
},
cleanup: function cleanup() {
for each (let hive in [this.user, this.system])
hive.cleanup();
},
__iterator__: function () Iterator(this.user.sheets.concat(this.system.sheets)),
_proxy: function (name, args)

View File

@@ -54,6 +54,16 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
this.overlays = {};
},
cleanup: function cleanup() {
for (let win in iter(services.windowMediator.getEnumerator(null))) {
for (let elem in values(win.document.dactylOverlayElements || []))
if (elem.parentNode)
elem.parentNode.removeChild(elem);
delete win.document.dactylOverlayElements;
delete win.document.dactylOverlays;
}
},
// FIXME: Only works for Pentadactyl
get activeWindow() services.windowMediator.getMostRecentWindow("navigator:browser"),
dactyl: update(function dactyl(obj) {
@@ -90,12 +100,13 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
let observers = obj.observe;
function register(meth) {
services.observer[meth](obj, "quit-application", true);
services.observer[meth](obj, "dactyl-unload", true);
for (let target in keys(observers))
services.observer[meth](obj, target, true);
}
Class.replaceProperty(obj, "observe",
function (subject, target, data) {
if (target == "quit-application")
if (target == "quit-application" || target == "dactyl-unload")
register("removeObserver");
if (observers[target])
observers[target].call(obj, subject, data);
@@ -838,7 +849,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
let tag = "<" + [namespaced(elem)].concat(
[namespaced(a) + "=" + template.highlight(a.value, true)
for ([i, a] in array.iterItems(elem.attributes))]).join(" ");
return tag + (hasChildren ? "/>" : ">...</" + namespaced(elem) + ">");
return tag + (!hasChildren ? "/>" : ">...</" + namespaced(elem) + ">");
}
catch (e) {
return {}.toString.call(elem);
@@ -899,19 +910,51 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
observe: {
"toplevel-window-ready": function (window, data) {
window.addEventListener("DOMContentLoaded", wrapCallback(function listener(event) {
if (event.originalTarget === window.document) {
window.removeEventListener("DOMContentLoaded", listener.wrapper, true);
util._loadOverlays(window);
}
}), true)
}
},
if (event.originalTarget !== window.document)
return;
_loadOverlays: function _loadOverlays(window) {
if (!window.dactylOverlays)
window.dactylOverlays = [];
let obj = util.overlays[window.document.documentURI];
if (obj) {
obj = obj(window);
util.dump("load overlays", window.document.documentURI);
for each (let obj in util.overlays[window.document.documentURI] || []) {
if (window.dactylOverlays.indexOf(obj) >= 0)
continue;
window.dactylOverlays.push(obj);
this._loadOverlay(window, obj(window));
}
},
_loadOverlay: function _loadOverlay(window, obj) {
let doc = window.document;
if (!doc.dactylOverlayElements)
doc.dactylOverlayElements = [];
util.dump("load overlay", doc.documentURI, String(obj).substr(0, 60));
function overlay(key, fn) {
for (let [elem, xml] in Iterator(obj[key] || {}))
if (elem = window.document.getElementById(elem))
fn(elem, util.xmlToDom(xml, window.document));
if (obj[key]) {
let iterator = Iterator(obj[key]);
if (!isObject(obj[key]))
iterator = ([elem.@id, elem.elements(), elem.@*::*.(function::name() != "id")] for each (elem in obj[key]));
for (let [elem, xml, attr] in iterator) {
if (elem = doc.getElementById(elem)) {
let node = util.xmlToDom(xml, doc, obj.objects);
for (let n in array.iterValues(node.childNodes))
doc.dactylOverlayElements.push(n);
fn(elem, node);
for each (let attr in attr || []) // FIXME: Cleanup...
elem.setAttributeNS(attr.namespace(), attr.localName(), attr);
}
}
}
}
overlay("before", function (elem, dom) elem.parentNode.insertBefore(dom, elem));
@@ -919,22 +962,36 @@ 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, event);
obj.init(window);
if (obj.load)
window.document.addEventListener("load", function (event) {
if (event.originalTarget === event.target)
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);
}
}), true)
}
}), true);
},
overlayWindow: function (url, fn) {
if (url instanceof Ci.nsIDOMWindow)
util._loadOverlay(url, fn);
else {
Array.concat(url).forEach(function (url) {
this.overlays[url] = fn;
if (!this.overlays[url])
this.overlays[url] = [];
this.overlays[url].push(fn);
}, this);
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");
}
},
/**
@@ -1085,7 +1142,11 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
this.dump("");
}
catch (e) {
this.dump(e);
try {
this.dump(String(error));
this.dump(error.stack)
}
catch (e) { dump(e + "\n"); }
}
},