diff options
author | Kris Maglione <maglione.k@gmail.com> | 2011-08-23 22:42:38 -0400 |
---|---|---|
committer | Kris Maglione <maglione.k@gmail.com> | 2011-08-23 22:42:38 -0400 |
commit | 435f30f7eb0446d7834e0ededd9fd12237ffcfd8 (patch) | |
tree | 17ed64428efe8972f67f07f3cb25ce7b70fe6ba1 | |
parent | 9ad4be54a98fc2b069095a572744618695c4adb3 (diff) | |
download | pentadactyl-435f30f7eb0446d7834e0ededd9fd12237ffcfd8.tar.gz |
First work towards group-local option values.
-rw-r--r-- | common/content/buffer.js | 32 | ||||
-rw-r--r-- | common/modules/base.jsm | 4 | ||||
-rw-r--r-- | common/modules/contexts.jsm | 8 | ||||
-rw-r--r-- | common/modules/finder.jsm | 3 | ||||
-rw-r--r-- | common/modules/options.jsm | 395 | ||||
-rw-r--r-- | common/modules/overlay.jsm | 10 | ||||
-rw-r--r-- | common/modules/util.jsm | 17 |
7 files changed, 280 insertions, 189 deletions
diff --git a/common/content/buffer.js b/common/content/buffer.js index 39cc8bea..d90ab09d 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -1887,14 +1887,16 @@ var Buffer = Module("buffer", { mappings.add([modes.NORMAL], ["]]", "<next-page>"], "Follow the link labeled 'next' or '>' if it exists", function (args) { - buffer.findLink("next", options["nextpattern"], (args.count || 1) - 1, true); + buffer.findLink("next", options.get("nextpattern").get(buffer.focusedFrame), + (args.count || 1) - 1, true); }, { count: true }); mappings.add([modes.NORMAL], ["[[", "<previous-page>"], "Follow the link labeled 'prev', 'previous' or '<' if it exists", function (args) { - buffer.findLink("previous", options["previouspattern"], (args.count || 1) - 1, true); + buffer.findLink("previous", options.get("previouspattern").get(buffer.focusedFrame), + (args.count || 1) - 1, true); }, { count: true }); @@ -2052,19 +2054,23 @@ var Buffer = Module("buffer", { "The current buffer's character encoding", "string", "UTF-8", { - scope: Option.SCOPE_LOCAL, - getter: function () config.browser.docShell.QueryInterface(Ci.nsIDocCharset).charset, - setter: function (val) { + scope: Option.SCOPE_BUFFER, + getter: function (val, context) util.docShell(context.content).QueryInterface(Ci.nsIDocCharset).charset, + setter: function (val, context) { if (options["encoding"] == val) return val; // Stolen from browser.jar/content/browser/browser.js, more or less. try { - config.browser.docShell.QueryInterface(Ci.nsIDocCharset).charset = val; - PlacesUtils.history.setCharsetForURI(getWebNavigation().currentURI, val); - window.getWebNavigation().reload(Ci.nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE); + let docShell = util.docShell(context.content).QueryInterface(Ci.nsIDocCharset); + + docShell.charset = val; + PlacesUtils.history.setCharsetForURI(docShell.currentURI, val); + docShell.reload(docShell.LOAD_FLAGS_CHARSET_CHANGE); + } + catch (e) { + dactyl.reportError(e); } - catch (e) { dactyl.reportError(e); } return null; }, completer: function (context) completion.charset(context) @@ -2133,8 +2139,12 @@ var Buffer = Module("buffer", { "Show current website without styling defined by the author", "boolean", false, { - setter: function (value) config.browser.markupDocumentViewer.authorStyleDisabled = value, - getter: function () config.browser.markupDocumentViewer.authorStyleDisabled + scope: Option.SCOPE_TAB, + setter: function (value, context) { + if (context.browser) + context.browser.markupDocumentViewer.authorStyleDisabled = value + }, + getter: function (value, context) context.browser && context.browser.markupDocumentViewer.authorStyleDisabled }); } }); diff --git a/common/modules/base.jsm b/common/modules/base.jsm index b0abfece..46ec85c9 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -1500,6 +1500,8 @@ update(iter, { nth: function nth(iter, pred, n, self) { if (typeof pred === "number") [pred, n] = [function () true, pred]; // Hack. + if (n === undefined) + n = 0; for (let elem in iter) if (pred.call(self, elem) && n-- === 0) @@ -1641,6 +1643,8 @@ var array = Class("array", Array, { * given predicate. */ nth: function nth(ary, pred, n, self) { + if (n === undefined) + n = 0; for (let elem in values(ary)) if (pred.call(self, elem) && n-- === 0) return elem; diff --git a/common/modules/contexts.jsm b/common/modules/contexts.jsm index 85525269..9596b8cd 100644 --- a/common/modules/contexts.jsm +++ b/common/modules/contexts.jsm @@ -97,13 +97,15 @@ var Contexts = Module("contexts", { this.builtin.modifiable = false; this.GroupFlag = Class("GroupFlag", CommandOption, { - init: function (name) { + init: function (name, defaultValue) { this.name = name; this.type = ArgType("group", function (group) { return isString(group) ? contexts.getGroup(group, name) : group[name]; }); + + this.defaultValue = defaultValue; }, get toStringParams() [this.name], @@ -112,7 +114,9 @@ var Contexts = Module("contexts", { description: "Group to which to add", - get default() (contexts.context && contexts.context.group || contexts.user)[this.name], + get default() let (group = contexts.context && contexts.context.group) + !group && this.defaultValue !== undefined ? this.defaultValue + : (group || contexts.user)[this.name], completer: function (context) modules.completion.group(context) }); diff --git a/common/modules/finder.jsm b/common/modules/finder.jsm index b3a11e15..3f24b99b 100644 --- a/common/modules/finder.jsm +++ b/common/modules/finder.jsm @@ -673,8 +673,7 @@ var RangeFind = Class("RangeFind", { this.range = range; this.document = range.startContainer.ownerDocument; this.window = this.document.defaultView; - this.docShell = this.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell); + this.docShell = util.docShell(this.window); if (this.selection == null) return false; diff --git a/common/modules/options.jsm b/common/modules/options.jsm index dabd29a5..15545b06 100644 --- a/common/modules/options.jsm +++ b/common/modules/options.jsm @@ -102,9 +102,11 @@ var Option = Class("Option", { options.cleanupPrefs.set(this.name, value); }, - /** @property {value} The option's global value. @see #scope */ - get globalValue() { try { return options.store.get(this.name, {}).value; } catch (e) { util.reportError(e); throw e; } }, - set globalValue(val) { options.store.set(this.name, { value: val, time: Date.now() }); }, + /** @property {Window|OptionHive|null} The default context for this option. */ + context: null, + + /** @property {[OptionHive]|null} The default hives for this option. */ + hives: null, /** * Returns *value* as an array of parsed values if the option type is @@ -124,64 +126,140 @@ var Option = Class("Option", { stringify: function stringify(vals) Commands.quote(vals), /** + * Returns a context object for the given window. + * + * @param {Window} context The context for which to get this option value. + * @optional + * @returns {object} + * window: The global window for which to get the value. + * tab: The tab for which to get the value. + * content: The content window for which to get the value. + * hive: The option hive containing the value. + */ + getContext: function getContext(context) { + if (context instanceof OptionHive) + context = undefined; + + if (context === undefined) + context = this.modules.content; + + if (!context && this.scope & Option.SCOPE_BUFFER) + context = this.modules.buffer.focusedFrame; + + let res = {}; + if (context) { + if (this.scope & Option.SCOPE_WINDOW) + res.window = util.topWindow(context); + if (this.scope & Option.SCOPE_BUFFER) + res.content = context; + if (this.scope & Option.SCOPE_TAB) { + res.tab = array.nth(this.modules.tabs.allTabs, + function (tab) tab.linkedBrowser.contentWindow + == this, + 0, context.top); + res.browser = res.tab && res.tab.linkedBrowser; + } + } + return res; + }, + + /** * Returns the option's value as an array of parsed values if the option * type is "charlist" or "stringlist" or else the simple value. * - * @param {number} scope The scope to return these values from (see - * {@link Option#scope}). - * @returns {value|[string]} + * @param {Window|OptionHive} context The context for which to get this option value. + * @optional + * @param {boolean} skipGetter If true, return the saved value, not + * the return value from the getter. + * @see #getContext */ - get: function get(scope) { - if (scope) { - if ((scope & this.scope) == 0) // option doesn't exist in this scope - return null; - } - else - scope = this.scope; + get: function get(context, skipGetter) { + if (context === undefined) + context = this.context; - let values; + let hive = this._valueHive(context); + let value = hive ? hive.values[this.name] : this.globalValue; + if (this.getter && !skipGetter) + return util.trapErrors(this.getter, this, value, + this.getContext(context)); - /* - if (config.has("tabs") && (scope & Option.SCOPE_LOCAL)) - values = tabs.options[this.name]; - */ - if ((scope & Option.SCOPE_GLOBAL) && (values == undefined)) - values = this.globalValue; + return value; + }, - if (this.getter) - return util.trapErrors(this.getter, this, values); + _valueHive: function _valueHive(context) { + let { contexts, options } = this.modules; + let hives = this.hives || options.hives; - return values; + context = context || this.context; + if (context instanceof Ci.nsIDOMWindow) + hives = array(contexts.matchingGroups(null, context.document).options); + else if (context instanceof OptionHive) + hives = array([context]); + + return hives.nth(function (h) h.has(this), 0, this.name); }, /** * Sets the option's value from an array of values if the option type is * "charlist" or "stringlist" or else the simple value. * - * @param {number} scope The scope to apply these values to (see - * {@link Option#scope}). + * @param {OptionHive} hive The hive for which to set this value. + * @optional + * @see #getContext */ - set: function set(newValues, scope, skipGlobal) { - scope = scope || this.scope; - if ((scope & this.scope) == 0) // option doesn't exist in this scope - return; + set: function set(newValue, hive) { - if (this.setter) - newValues = this.setter(newValues); - if (newValues === undefined) - return; + hive = hive || this.hives && this.hives[0]; + if (hive) { + hive.values[this.name] = newValue; + hive.setFrom[this.name] = null; + } + else { + this.globalValue = newValue; + } - /* - if (config.has("tabs") && (scope & Option.SCOPE_LOCAL)) - tabs.options[this.name] = newValues; - */ - if ((scope & Option.SCOPE_GLOBAL) && !skipGlobal) - this.globalValue = newValues; + + this.runSetters(hive); this.hasChanged = true; - this.setFrom = null; + }, - // dactyl.triggerObserver("options." + this.name, newValues); + _runSetter: function _setter(window) { + let opt = util.topWindow(window).dactyl.modules.options.get(this.name); + if (opt) { + let context = opt.getContext(window); + let value = opt.get(window, true) + if (!opt.getter || value != opt.getter(value, context)) + opt.setter(value, context); + } + }, + + runSetters: function runSetters(hive) { + if (this.setter) { + if (this.scope & Option.SCOPE_GLOBAL) + this.setter(this.get(null, true), this.getContext(null)); + + if (this.scope & Option.SCOPE_WINDOW) + for (let window in values(overlay.windows)) + this._runSetter(window); + + if (this.scope & Option.SCOPE_TAB) + for (let window in values(overlay.windows)) + for (let tab in values(window.dactyl.modules.tabs.allTabs)) + this._runSetter(tab.linkedBrowser.contentWindow); + + if (this.scope & Option.SCOPE_BUFFER) + if (hive) + for (let doc in util.iterDocuments(["content"])) { + let win = doc.defaultView; + if ("dactyl" in util.topWindow(win) && + hive.filter(doc.documentURIObject || util.newURI(doc.documentURI), + doc)) + this._runSetter(win); + } + else + this._runSetter(this.modules.buffer.focusedFrame); + } }, getValues: deprecated("Option#get", "get"), @@ -286,13 +364,9 @@ var Option = Class("Option", { type: null, /** - * @property {number} The scope of the option. This can be local, global, - * or both. - * @see Option#SCOPE_LOCAL - * @see Option#SCOPE_GLOBAL - * @see Option#SCOPE_BOTH + * @property {number} The scope of the option. */ - scope: 1, // Option.SCOPE_GLOBAL // XXX set to BOTH by default someday? - kstep + scope: Class.Memoize(function () Option.SCOPE_WINDOW), /** * @property {function(CompletionContext, Args)} This option's completer. @@ -379,37 +453,37 @@ var Option = Class("Option", { */ hasChanged: false, + _set: function _set(obj) { + update(options.store.get(this.name, {}), obj); + }, + + /** @property {value} The option's global value. */ + get globalValue() { try { return options.store.get(this.name, {}).value; } catch (e) { util.reportError(e); throw e; } }, + set globalValue(val) { this._set({ value: val, time: Date.now() }); }, + /** * Returns the timestamp when the option's value was last changed. */ get lastSet() options.store.get(this.name).time, - set lastSet(val) { options.store.set(this.name, { value: this.globalValue, time: Date.now() }); }, + set lastSet(val) { this._set({ time: Date.now() }); }, /** * @property {nsIFile} The script in which this option was last set. null * implies an interactive command. */ - setFrom: null + get setFrom() let (hive = this._valueHive()) + hive ? hive.setFrom[this.name] + : options.store.get(this.name, {}).setFrom, + + set setFrom(val) let (hive = this._valueHive()) + hive ? (hive.setFrom[this.name] = val) + : this._set({ setFrom: val }) }, { - /** - * @property {number} Global option scope. - * @final - */ SCOPE_GLOBAL: 1, - - /** - * @property {number} Local option scope. Options in this scope only - * apply to the current tab/buffer. - * @final - */ - SCOPE_LOCAL: 2, - - /** - * @property {number} Both local and global option scope. - * @final - */ - SCOPE_BOTH: 3, + SCOPE_WINDOW: 2, + SCOPE_TAB: 3, + SCOPE_BUFFER: 4, has: { toggleAll: function toggleAll() toggleAll.supercall(this, "all") ^ !!toggleAll.superapply(this, arguments), @@ -760,6 +834,7 @@ var OptionHive = Class("OptionHive", Contexts.Hive, { init: function init(group) { init.supercall(this, group); this.values = {}; + this.setFrom = {}; this.has = Set.has(this.values); }, @@ -786,12 +861,6 @@ var Options = Module("options", { this._optionMap = {}; storage.newMap("options", { store: false }); - storage.addObserver("options", function optionObserver(key, event, option) { - // Trigger any setters. - let opt = self.get(option); - if (event == "change" && opt) - opt.set(opt.globalValue, Option.SCOPE_GLOBAL, true); - }, window); services["dactyl:"].pages["options.dtd"] = function () [null, util.makeDTD( @@ -813,13 +882,8 @@ var Options = Module("options", { * *onlyNonDefault* is specified. * * @param {function(Option)} filter Limit the list - * @param {number} scope Only list options in this scope (see - * {@link Option#scope}). */ - list: function list(filter, scope) { - if (!scope) - scope = Option.SCOPE_BOTH; - + list: function list(filter) { function opts(opt) { for (let opt in Iterator(this)) { let option = { @@ -832,8 +896,6 @@ var Options = Module("options", { if (filter && !filter(opt)) continue; - if (!(opt.scope & scope)) - continue; if (opt.type == "boolean") { if (!opt.value) @@ -935,20 +997,26 @@ var Options = Module("options", { }, /** - * Returns the option with *name* in the specified *scope*. + * Returns the option with *name* in the specified *context*. * * @param {string} name The option's name. - * @param {number} scope The option's scope (see {@link Option#scope}). - * @optional + * @param {Window|OptionHive} context The context for which to get + * this option. * @returns {Option} The matching option. */ - get: function get(name, scope) { - if (!scope) - scope = Option.SCOPE_BOTH; - - if (this._optionMap[name] && (this._optionMap[name].scope & scope)) - return this._optionMap[name]; - return null; + get: function get(name, context) { + let opt = null; + if (Set.has(this._optionMap, name)) { + opt = this._optionMap[name]; + + if (context) { + opt = Object.create(opt); + if (context instanceof OptionHive) + opt.hives = array([context]); + opt.context = context; + } + } + return opt; }, /** @@ -961,25 +1029,28 @@ var Options = Module("options", { * @returns {Object} The parsed command object. */ parseOpt: function parseOpt(args, modifiers) { + modifiers = modifiers || {}; + let res = {}; let matches, prefix, postfix; - [matches, prefix, res.name, postfix, res.valueGiven, res.operator, res.value] = + [matches, prefix, res.name, postfix, res.valueGiven, res.operator, res.stringValue] = args.match(/^\s*(no|inv)?([^=]+?)([?&!])?\s*(([-+^]?)=(.*))?\s*$/) || []; res.args = args; res.onlyNonDefault = false; // used for :set to print non-default options + res.context = modifiers.context; if (!args) { res.name = "all"; res.onlyNonDefault = true; } if (matches) { - if (res.option = this.get(res.name, res.scope)) { + if (res.option = this.get(res.name, res.context)) { if (prefix === "no" && res.option.type !== "boolean") res.option = null; } - else if (res.option = this.get(prefix + res.name, res.scope)) { + else if (res.option = this.get(prefix + res.name, res.context)) { res.name = prefix + res.name; prefix = ""; } @@ -994,18 +1065,16 @@ var Options = Module("options", { res.reset = (postfix == "&"); res.unsetBoolean = (prefix == "no"); - res.scope = modifiers && modifiers.scope; - if (!res.option) return res; - if (res.value === undefined) - res.value = ""; + if (res.stringValue === undefined) + res.stringValue = ""; - res.optionValue = res.option.get(res.scope); + res.optionValue = res.option.get(res.context); try { - res.values = res.option.parse(res.value); + res.value = res.option.parse(res.stringValue); } catch (e) { res.error = e; @@ -1068,7 +1137,55 @@ var Options = Module("options", { } }); + commands.add(["se[t]"], + "Set an option", + function (args) { + setAction(args); + }, + { + bang: true, + + completer: setCompleter, + + domains: function domains(args) array.flatten(args.map(function (spec) { + try { + let opt = modules.options.parseOpt(spec); + if (opt.option && opt.option.domains) + return opt.option.domains(opt.value); + } + catch (e) { + util.reportError(e); + } + return []; + })), + + keepQuotes: true, + + options: [ + contexts.GroupFlag("options", null), + ], + + privateData: function privateData(args) args.some(function (spec) { + let opt = modules.options.parseOpt(spec); + return opt.option && opt.option.privateData && + (!callable(opt.option.privateData) || + opt.option.privateData(opt.value)); + }), + + serialize: function () [ + { + command: this.name, + literalArg: [opt.type == "boolean" ? (opt.value ? "" : "no") + opt.name + : opt.name + "=" + opt.stringValue] + } + for (opt in modules.options) + if (!opt.getter) + ] + }); + function setAction(args, modifiers) { + modifiers = modifiers || {}; + let bang = args.bang; if (!args.length) args[0] = ""; @@ -1136,6 +1253,7 @@ var Options = Module("options", { return; } + modifiers.context = args["-group"]; let opt = modules.options.parseOpt(arg, modifiers); util.assert(opt, _("command.set.errorParsing", arg)); util.assert(!opt.error, _("command.set.errorParsing", opt.error)); @@ -1162,13 +1280,13 @@ var Options = Module("options", { flushList(); if (opt.option.type === "boolean") { util.assert(!opt.valueGiven, _("error.invalidArgument", arg)); - opt.values = !opt.unsetBoolean; + opt.value = !opt.unsetBoolean; } else if (/^(string|number)$/.test(opt.option.type) && opt.invert) - opt.values = Option.splitList(opt.value); + opt.value = Option.splitList(opt.stringValue); try { - var res = opt.option.op(opt.operator || "=", opt.values, opt.scope, opt.invert, - opt.value); + var res = opt.option.op(opt.operator || "=", opt.value, opt.scope, opt.invert, + opt.stringValue); } catch (e) { res = e; @@ -1183,6 +1301,7 @@ var Options = Module("options", { function setCompleter(context, args, modifiers) { const { completion } = modules; + modifiers = modifiers || {} let filter = context.filter; @@ -1193,8 +1312,8 @@ var Options = Module("options", { context.pushProcessor(0, function (item, text, next) next(item, text.substr(0, 100))); context.completions = [ - [prefs.get(filter), _("option.currentValue")], - [prefs.defaults.get(filter), _("option.defaultValue")] + [prefs.get(filter), _("option.currentValue")], + [prefs.defaults.get(filter), _("option.defaultValue")] ].filter(function (k) k[0] != null); return null; } @@ -1232,13 +1351,13 @@ var Options = Module("options", { if (opt.get || opt.reset || !option || prefix) return null; - if (!opt.value && !opt.operator && !opt.invert) { + if (!opt.stringValue && !opt.operator && !opt.invert) { context.fork("default", 0, this, function (context) { context.title = ["Extra Completions"]; context.pushProcessor(0, function (item, text, next) next(item, text.substr(0, 100))); context.completions = [ - [option.stringValue, _("option.currentValue")], - [option.stringDefaultValue, _("option.defaultValue")] + [option.stringValue, _("option.currentValue")], + [option.stringDefaultValue, _("option.defaultValue")] ].filter(function (f) f[0] !== ""); context.quote = ["", util.identity, ""]; }); @@ -1248,7 +1367,7 @@ var Options = Module("options", { modules.completion.optionValue(optcontext, opt.name, opt.operator); // Fill in the current values if we're removing - if (opt.operator == "-" && isArray(opt.values)) { + if (opt.operator == "-" && isArray(opt.value)) { let have = Set([i.text for (i in values(context.allItems.items))]); context = context.fork("current-values", 0); context.anchored = optcontext.anchored; @@ -1335,64 +1454,6 @@ var Options = Module("options", { } ); - [ - { - names: ["setl[ocal]"], - description: "Set local option", - modifiers: { scope: Option.SCOPE_LOCAL } - }, - { - names: ["setg[lobal]"], - description: "Set global option", - modifiers: { scope: Option.SCOPE_GLOBAL } - }, - { - names: ["se[t]"], - description: "Set an option", - modifiers: {}, - extra: { - serialize: function () [ - { - command: this.name, - literalArg: [opt.type == "boolean" ? (opt.value ? "" : "no") + opt.name - : opt.name + "=" + opt.stringValue] - } - for (opt in modules.options) - if (!opt.getter && !opt.isDefault && (opt.scope & Option.SCOPE_GLOBAL)) - ] - } - } - ].forEach(function (params) { - commands.add(params.names, params.description, - function (args, modifiers) { - setAction(args, update(modifiers, params.modifiers)); - }, - update({ - bang: true, - completer: setCompleter, - domains: function domains(args) array.flatten(args.map(function (spec) { - try { - let opt = modules.options.parseOpt(spec); - if (opt.option && opt.option.domains) - return opt.option.domains(opt.values); - } - catch (e) { - util.reportError(e); - } - return []; - })), - keepQuotes: true, - privateData: function privateData(args) args.some(function (spec) { - let opt = modules.options.parseOpt(spec); - return opt.option && opt.option.privateData && - (!callable(opt.option.privateData) || - opt.option.privateData(opt.values)); - }) - }, params.extra || {})); - }); - - // TODO: deprecated. This needs to support "g:"-prefixed globals at a - // minimum for now. commands.add(["unl[et]"], "Delete a variable", function (args) { diff --git a/common/modules/overlay.jsm b/common/modules/overlay.jsm index fc841df5..b028b239 100644 --- a/common/modules/overlay.jsm +++ b/common/modules/overlay.jsm @@ -299,10 +299,10 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen overlay.windows = array.uniq(overlay.windows.concat(window), true); } - if (overlay.onWindowVisible) - overlay.onWindowVisible.push(finish); - else + if (window.dactylWindowVisible) finish(); + else + overlay.onWindowVisible.push(finish); modules.events.listen(window, "unload", function onUnload() { window.removeEventListener("unload", onUnload.wrapped, false); @@ -350,7 +350,7 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen "xul-window-visible": function () { if (this.onWindowVisible) { this.onWindowVisible.forEach(function (f) f.call(this), this); - this.onWindowVisible = null; + this.onWindowVisible = []; } } }, @@ -367,7 +367,7 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen for (let doc in util.iterDocuments()) if (~["interactive", "complete"].indexOf(doc.readyState)) { - this.onWindowVisible = null; + doc.defaultView.dactylWindowVisible = true; this._loadOverlays(doc.defaultView); } else diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 7a8197d5..6813d1e9 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -479,6 +479,16 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), pattern.replace(/\\(.)/, function (m0, m1) chars.indexOf(m1) >= 0 ? m1 : m0), /** + * Returns the nsIDocShell for a given window. + * + * @param {Window} win The window. + * @returns {nsIDocShell} + */ + docShell: function docShell(win) + win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell), + + /** * Prints a message to the console. If *msg* is an object it is pretty * printed. * @@ -748,11 +758,14 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * Iterates over all currently open documents, including all * top-level window and sub-frames thereof. */ - iterDocuments: function iterDocuments() { + iterDocuments: function iterDocuments(types) { + types = types || ["chrome", "content"]; + types = types.map(function (t) "type" + util.capitalize(t)); + let windows = services.windowMediator.getXULWindowEnumerator(null); while (windows.hasMoreElements()) { let window = windows.getNext().QueryInterface(Ci.nsIXULWindow); - for each (let type in ["typeChrome", "typeContent"]) { + for each (let type in types) { let docShells = window.docShell.getDocShellEnumerator(Ci.nsIDocShellTreeItem[type], Ci.nsIDocShell.ENUMERATE_FORWARDS); while (docShells.hasMoreElements()) |