diff --git a/common/content/commandline.js b/common/content/commandline.js index 564f9939..ea0a3013 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -255,24 +255,16 @@ var CommandWidgets = Class("CommandWidgets", { commandbar: Class.memoize(function () ({ group: "Cmd" })), statusbar: Class.memoize(function () ({ group: "Status" })), - _whenReady: function _whenReady(name, id, processor) { - Object.defineProperty(this, name, { - configurable: true, enumerable: true, - get: function get_whenReady() { - let elem = document.getElementById(id); + _whenReady: function _whenReady(name, id) { + let elem = document.getElementById(id); - util.waitFor(function () elem.contentDocument.documentURI === elem.getAttribute("src") && - ["viewable", "complete"].indexOf(elem.contentDocument.readyState) >= 0); + util.waitFor(function () elem.contentDocument.documentURI === elem.getAttribute("src") && + ["viewable", "complete"].indexOf(elem.contentDocument.readyState) >= 0); - res = res || (processor || util.identity).call(self, elem); - return res; - } - }); - let res, self = this; - return Class.replaceProperty(this, name, this[name]); + return elem; }, - get completionList() this._whenReady("completionList", "dactyl-completions"), + completionList: Class.memoize(function () this._whenReady("completionList", "dactyl-completions"), true), completionContainer: Class.memoize(function () this.completionList.parentNode), @@ -286,13 +278,13 @@ var CommandWidgets = Class("CommandWidgets", { return document.getElementById("dactyl-contextmenu"); }), - get multilineOutput() this._whenReady("multilineOutput", "dactyl-multiline-output", - function (elem) { + multilineOutput: Class.memoize(function () { + let elem = this._whenReady("multilineOutput", "dactyl-multiline-output"); elem.contentWindow.addEventListener("unload", function (event) { event.preventDefault(); }, true); elem.contentDocument.documentElement.id = "dactyl-multiline-output-top"; elem.contentDocument.body.id = "dactyl-multiline-output-content"; return elem; - }), + }, true), multilineInput: Class.memoize(function () document.getElementById("dactyl-multiline-input")), @@ -576,9 +568,10 @@ var CommandLine = Module("commandline", { get completionList() { let node = this.widgets.active.commandline; - if (!node.completionList) - this.widgets._whenReady.call(node, "completionList", "dactyl-completions-" + node.id, - function (node) ItemList(node.id)); + if (!node.completionList) { + let elem = this.widgets._whenReady("completionList", "dactyl-completions-" + node.id); + node.completionList = ItemList(elem.id); + } return node.completionList; }, diff --git a/common/modules/base.jsm b/common/modules/base.jsm index b8407a1c..87f9ecc4 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -523,9 +523,11 @@ function memoize(obj, key, getter) { } return obj; } + obj.__defineGetter__(key, function g_replaceProperty() ( Class.replaceProperty(this.instance || this, key, null), Class.replaceProperty(this.instance || this, key, getter.call(this, key)))); + obj.__defineSetter__(key, function s_replaceProperty(val) Class.replaceProperty(this.instance || this, key, val)); } @@ -765,14 +767,33 @@ Class.extend = function extend(subclass, superclass, overrides) { * property's value. * @return {Class.Property} */ -Class.memoize = function memoize(getter) +Class.memoize = function memoize(getter, wait) Class.Property({ configurable: true, enumerable: true, init: function (key) { - this.get = function replace() let (obj = this.instance || this) ( - Class.replaceProperty(obj, key, null), - Class.replaceProperty(obj, key, getter.call(this, key))) + let done = false; + let prop = { configurable: true, enumerable: true, value: null, writable: true }; + if (wait) + prop = { + configurable: true, enumerable: false, + get: function get() { + util.waitFor(function () done); + return this[key]; + } + } + + this.get = function replace() { + let obj = this.instance || this; + Object.defineProperty(obj, key, prop); + try { + return Class.replaceProperty(obj, key, getter.call(this, key)); + } + finally { + done = true; + } + } + this.set = function replace(val) Class.replaceProperty(this.instance || this, val); } }); diff --git a/common/modules/config.jsm b/common/modules/config.jsm index 91a2e686..f80cfcdc 100644 --- a/common/modules/config.jsm +++ b/common/modules/config.jsm @@ -61,13 +61,13 @@ var ConfigBase = Class("ConfigBase", { if (addon && !addon.getResourceURI) util.reportError(Error("Don't have add-on yet")); - return !addon || addon.getResourceURI(); + return !addon || addon.getResourceURI; }); if (!addon) addon = require("addons").AddonManager.getAddonByID(this.addonID); return addon; - }), + }, true), /** * The current application locale.