summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKris Maglione <maglione.k@gmail.com>2011-08-23 22:42:38 -0400
committerKris Maglione <maglione.k@gmail.com>2011-08-23 22:42:38 -0400
commit435f30f7eb0446d7834e0ededd9fd12237ffcfd8 (patch)
tree17ed64428efe8972f67f07f3cb25ce7b70fe6ba1
parent9ad4be54a98fc2b069095a572744618695c4adb3 (diff)
downloadpentadactyl-435f30f7eb0446d7834e0ededd9fd12237ffcfd8.tar.gz
First work towards group-local option values.
-rw-r--r--common/content/buffer.js32
-rw-r--r--common/modules/base.jsm4
-rw-r--r--common/modules/contexts.jsm8
-rw-r--r--common/modules/finder.jsm3
-rw-r--r--common/modules/options.jsm395
-rw-r--r--common/modules/overlay.jsm10
-rw-r--r--common/modules/util.jsm17
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())