1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-22 18:57:58 +01:00

Use real Sets rather than objects in most places.

This commit is contained in:
Kris Maglione
2014-02-15 18:10:45 -08:00
parent e3fb435f99
commit fd20535999
29 changed files with 353 additions and 262 deletions

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2010 by anekos <anekos@snca.net> // Copyright (c) 2010 by anekos <anekos@snca.net>
// Copyright (c) 2010-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2010-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -132,7 +132,8 @@ var AbbrevHive = Class("AbbrevHive", Contexts.Hive, {
*/ */
get: function (mode, lhs) { get: function (mode, lhs) {
let abbrevs = this._store[mode]; let abbrevs = this._store[mode];
return abbrevs && Set.has(abbrevs, lhs) ? abbrevs[lhs] : null; return abbrevs && hasOwnProperty(abbrevs, lhs) ? abbrevs[lhs]
: null;
}, },
/** /**

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -73,7 +73,7 @@ var Bookmarks = Module("bookmarks", {
if (id != null) if (id != null)
var bmark = bookmarkcache.bookmarks[id]; var bmark = bookmarkcache.bookmarks[id];
else if (!force) { else if (!force) {
if (keyword && Set.has(bookmarkcache.keywords, keyword)) if (keyword && hasOwnProperty(bookmarkcache.keywords, keyword))
bmark = bookmarkcache.keywords[keyword]; bmark = bookmarkcache.keywords[keyword];
else if (bookmarkcache.isBookmarked(uri)) else if (bookmarkcache.isBookmarked(uri))
for (bmark in bookmarkcache) for (bmark in bookmarkcache)
@@ -223,7 +223,7 @@ var Bookmarks = Module("bookmarks", {
if (!alias) if (!alias)
alias = "search"; // for search engines which we can't find a suitable alias alias = "search"; // for search engines which we can't find a suitable alias
if (Set.has(aliases, alias)) if (hasOwnProperty(aliases, alias))
alias += ++aliases[alias]; alias += ++aliases[alias];
else else
aliases[alias] = 0; aliases[alias] = 0;
@@ -251,10 +251,10 @@ var Bookmarks = Module("bookmarks", {
getSuggestions: function getSuggestions(engineName, query, callback) { getSuggestions: function getSuggestions(engineName, query, callback) {
const responseType = "application/x-suggestions+json"; const responseType = "application/x-suggestions+json";
if (Set.has(this.suggestionProviders, engineName)) if (hasOwnProperty(this.suggestionProviders, engineName))
return this.suggestionProviders[engineName](query, callback); return this.suggestionProviders[engineName](query, callback);
let engine = Set.has(this.searchEngines, engineName) && this.searchEngines[engineName]; let engine = hasOwnProperty(this.searchEngines, engineName) && this.searchEngines[engineName];
if (engine && engine.supportsResponseType(responseType)) if (engine && engine.supportsResponseType(responseType))
var queryURI = engine.getSubmission(query, responseType).uri.spec; var queryURI = engine.getSubmission(query, responseType).uri.spec;
if (!queryURI) if (!queryURI)
@@ -320,7 +320,7 @@ var Bookmarks = Module("bookmarks", {
param = query.substr(offset + 1); param = query.substr(offset + 1);
} }
var engine = Set.has(bookmarks.searchEngines, keyword) && bookmarks.searchEngines[keyword]; var engine = hasOwnProperty(bookmarks.searchEngines, keyword) && bookmarks.searchEngines[keyword];
if (engine) { if (engine) {
if (engine.searchForm && !param) if (engine.searchForm && !param)
return engine.searchForm; return engine.searchForm;
@@ -700,7 +700,7 @@ var Bookmarks = Module("bookmarks", {
let engine = bookmarks.searchEngines[name]; let engine = bookmarks.searchEngines[name];
if (engine) if (engine)
var desc = engine.description; var desc = engine.description;
else if (!Set.has(bookmarks.suggestionProviders, name)) else if (!hasOwnProperty(bookmarks.suggestionProviders, name))
return; return;
let [, word] = /^\s*(\S+)/.exec(context.filter) || []; let [, word] = /^\s*(\S+)/.exec(context.filter) || [];

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -278,7 +278,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
let results = array((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs())) let results = array((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs()))
.array.sort((a, b) => String.localeCompare(a.name, b.name)); .array.sort((a, b) => String.localeCompare(a.name, b.name));
let haveTag = Set.has(help.tags); let haveTag = hasOwnProperty(help.tags);
for (let obj in values(results)) { for (let obj in values(results)) {
let res = dactyl.generateHelp(obj, null, null, true); let res = dactyl.generateHelp(obj, null, null, true);
if (!haveTag(obj.helpTag)) if (!haveTag(obj.helpTag))
@@ -620,7 +620,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* @param {string} feature The feature name. * @param {string} feature The feature name.
* @returns {boolean} * @returns {boolean}
*/ */
has: function has(feature) Set.has(config.features, feature), has: function has(feature) config.has(feature),
/** /**
* @private * @private

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
@@ -68,7 +68,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
name = 0; name = 0;
if (name == "_") if (name == "_")
var res = null; var res = null;
else if (Set.has(this.selectionRegisters, name)) else if (hasOwnProperty(this.selectionRegisters, name))
res = { text: dactyl.clipboardRead(this.selectionRegisters[name]) || "" }; res = { text: dactyl.clipboardRead(this.selectionRegisters[name]) || "" };
else if (!/^[0-9]$/.test(name)) else if (!/^[0-9]$/.test(name))
res = this.registers.get(name); res = this.registers.get(name);
@@ -105,7 +105,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
name = 0; name = 0;
if (name == "_") if (name == "_")
; ;
else if (Set.has(this.selectionRegisters, name)) else if (hasOwnProperty(this.selectionRegisters, name))
dactyl.clipboardWrite(value.text, verbose, this.selectionRegisters[name]); dactyl.clipboardWrite(value.text, verbose, this.selectionRegisters[name]);
else if (!/^[0-9]$/.test(name)) else if (!/^[0-9]$/.test(name))
this.registers.set(name, value); this.registers.set(name, value);
@@ -1363,11 +1363,12 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
args.push(obj["file"]); args.push(obj["file"]);
return args; return args;
}, },
has: function (key) Set.has(util.compileMacro(this.value).seen, key), has: function (key) util.compileMacro(this.value).seen.has(key),
validator: function (value) { validator: function (value) {
this.format({}, value); this.format({}, value);
return Object.keys(util.compileMacro(value).seen) let allowed = RealSet(["column", "file", "line"]);
.every(k => ["column", "file", "line"].indexOf(k) >= 0); return [k for (k of util.compileMacro(value).seen)]
.every(k => allowed.has(k));
} }
}); });

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -28,7 +28,7 @@ var EventHive = Class("EventHive", Contexts.Hive, {
else else
[self, events] = [event, event[callback || "events"]]; [self, events] = [event, event[callback || "events"]];
if (Set.has(events, "input") && !Set.has(events, "dactyl-input")) if (hasOwnProperty(events, "input") && !hasOwnProperty(events, "dactyl-input"))
events["dactyl-input"] = events.input; events["dactyl-input"] = events.input;
return [self, events]; return [self, events];
@@ -79,7 +79,7 @@ var EventHive = Class("EventHive", Contexts.Hive, {
let elem = args[0].get(); let elem = args[0].get();
if (target == null || elem == target if (target == null || elem == target
&& self == args[1].get() && self == args[1].get()
&& Set.has(events, args[2]) && hasOwnProperty(events, args[2])
&& args[3].wrapped == events[args[2]] && args[3].wrapped == events[args[2]]
&& args[4] == capture) { && args[4] == capture) {
@@ -1124,12 +1124,12 @@ var Events = Module("events", {
"sitemap", "", { "sitemap", "", {
flush: function flush() { flush: function flush() {
memoize(this, "filters", function () this.value.filter(function (f) f(buffer.documentURI))); memoize(this, "filters", function () this.value.filter(function (f) f(buffer.documentURI)));
memoize(this, "pass", function () Set(array.flatten(this.filters.map(function (f) f.keys)))); memoize(this, "pass", function () RealSet(array.flatten(this.filters.map(function (f) f.keys))));
memoize(this, "commandHive", function hive() Hive(this.filters, "command")); memoize(this, "commandHive", function hive() Hive(this.filters, "command"));
memoize(this, "inputHive", function hive() Hive(this.filters, "input")); memoize(this, "inputHive", function hive() Hive(this.filters, "input"));
}, },
has: function (key) Set.has(this.pass, key) || Set.has(this.commandHive.stack.mappings, key), has: function (key) this.pass.has(key) || hasOwnProperty(this.commandHive.stack.mappings, key),
get pass() (this.flush(), this.pass), get pass() (this.flush(), this.pass),

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -39,7 +39,7 @@ var Map = Class("Map", {
Object.freeze(this.modes); Object.freeze(this.modes);
if (info) { if (info) {
if (Set.has(Map.types, info.type)) if (hasOwnProperty(Map.types, info.type))
this.update(Map.types[info.type]); this.update(Map.types[info.type]);
this.update(info); this.update(info);
} }
@@ -380,11 +380,13 @@ var Mappings = Module("mappings", {
}, },
iterate: function (mode) { iterate: function (mode) {
let seen = {}; let seen = RealSet();
for (let hive in this.hives.iterValues()) for (let hive in this.hives.iterValues())
for (let map in array(hive.getStack(mode)).iterValues()) for (let map in array(hive.getStack(mode)).iterValues())
if (!Set.add(seen, map.name)) if (!seen.has(map.name)) {
seen.add(map.name);
yield map; yield map;
}
}, },
// NOTE: just normal mode for now // NOTE: just normal mode for now
@@ -638,11 +640,13 @@ var Mappings = Module("mappings", {
} }
}; };
function userMappings(hive) { function userMappings(hive) {
let seen = {}; let seen = RealSet();
for (let stack in values(hive.stacks)) for (let stack in values(hive.stacks))
for (let map in array.iterValues(stack)) for (let map in array.iterValues(stack))
if (!Set.add(seen, map.id)) if (!seen.has(map.id)) {
seen.add(map.id);
yield map; yield map;
}
} }
modeDescription = modeDescription ? " in " + modeDescription + " mode" : ""; modeDescription = modeDescription ? " in " + modeDescription + " mode" : "";
@@ -748,13 +752,14 @@ var Mappings = Module("mappings", {
if (!mainOnly) if (!mainOnly)
modes = modes[0].allBases; modes = modes[0].allBases;
let seen = {}; let seen = RealSet();
// Bloody hell. --Kris // Bloody hell. --Kris
for (let [i, mode] in Iterator(modes)) for (let [i, mode] in Iterator(modes))
for (let hive in mappings.hives.iterValues()) for (let hive in mappings.hives.iterValues())
for (let map in array.iterValues(hive.getStack(mode))) for (let map in array.iterValues(hive.getStack(mode)))
for (let name in values(map.names)) for (let name in values(map.names))
if (!Set.add(seen, name)) { if (!seen.has(name)) {
seen.add(name);
yield { yield {
name: name, name: name,
columns: [ columns: [
@@ -800,7 +805,7 @@ var Mappings = Module("mappings", {
name: [mode.char + "listk[eys]", mode.char + "lk"], name: [mode.char + "listk[eys]", mode.char + "lk"],
iterateIndex: function (args) iterateIndex: function (args)
let (self = this, prefix = /^[bCmn]$/.test(mode.char) ? "" : mode.char + "_", let (self = this, prefix = /^[bCmn]$/.test(mode.char) ? "" : mode.char + "_",
haveTag = Set.has(help.tags)) haveTag = k => hasOwnProperty(help.tags, k))
({ helpTag: prefix + map.name, __proto__: map } ({ helpTag: prefix + map.name, __proto__: map }
for (map in self.iterate(args, true)) for (map in self.iterate(args, true))
if (map.hive === mappings.builtin || haveTag(prefix + map.name))), if (map.hive === mappings.builtin || haveTag(prefix + map.name))),

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -446,9 +446,12 @@ var Modes = Module("modes", {
this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj, this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj,
allBases: Class.Memoize(function () { allBases: Class.Memoize(function () {
let seen = {}, res = [], queue = [this].concat(this.bases); let seen = RealSet(),
res = [],
queue = [this].concat(this.bases);
for (let mode in array.iterValues(queue)) for (let mode in array.iterValues(queue))
if (!Set.add(seen, mode)) { if (!seen.has(mode)) {
seen.add(mode);
res.push(mode); res.push(mode);
queue.push.apply(queue, mode.bases); queue.push.apply(queue, mode.bases);
} }
@@ -491,7 +494,7 @@ var Modes = Module("modes", {
StackElement.defaultValue("params", function () this.main.params); StackElement.defaultValue("params", function () this.main.params);
update(StackElement.prototype, { update(StackElement.prototype, {
get toStringParams() !loaded.modes ? this.main.name : [ get toStringParams() !loaded.modes ? [this.main.name] : [
this.main.name, this.main.name,
["(", modes.all.filter(m => this.extended & m) ["(", modes.all.filter(m => this.extended & m)
.map(m => m.name) .map(m => m.name)
@@ -604,7 +607,7 @@ var Modes = Module("modes", {
return (array.nth(this.value, v => val.some(m => m.name === v.mode), 0) return (array.nth(this.value, v => val.some(m => m.name === v.mode), 0)
|| { result: default_ }).result; || { result: default_ }).result;
return Set.has(this.valueMap, val) ? this.valueMap[val] : default_; return hasOwnProperty(this.valueMap, val) ? this.valueMap[val] : default_;
}, },
setter: function (vals) { setter: function (vals) {
@@ -622,7 +625,7 @@ var Modes = Module("modes", {
}, },
validator: function validator(vals) vals.map(v => v.replace(/^!/, "")) validator: function validator(vals) vals.map(v => v.replace(/^!/, ""))
.every(Set.has(this.values)), .every(k => hasOwnProperty(this.values, k)),
get values() array.toObject([[m.name.toLowerCase(), m.description] for (m in values(modes._modes)) if (!m.hidden)]) get values() array.toObject([[m.name.toLowerCase(), m.description] for (m in values(modes._modes)) if (!m.hidden)])
}; };

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -1036,7 +1036,7 @@ var Tabs = Module("tabs", {
tabs.getGroups(); tabs.getGroups();
tabs[visible ? "visibleTabs" : "allTabs"].forEach(function (tab, i) { tabs[visible ? "visibleTabs" : "allTabs"].forEach(function (tab, i) {
let group = (tab.tabItem || tab._tabViewTabItem || defItem).parent || defItem.parent; let group = (tab.tabItem || tab._tabViewTabItem || defItem).parent || defItem.parent;
if (!Set.has(tabGroups, group.id)) if (!hasOwnProperty(tabGroups, group.id))
tabGroups[group.id] = [group.getTitle(), []]; tabGroups[group.id] = [group.getTitle(), []];
group = tabGroups[group.id]; group = tabGroups[group.id];
@@ -1261,11 +1261,11 @@ var Tabs = Module("tabs", {
values: activateGroups, values: activateGroups,
has: Option.has.toggleAll, has: Option.has.toggleAll,
setter: function (newValues) { setter: function (newValues) {
let valueSet = Set(newValues); let valueSet = RealSet(newValues);
for (let group in values(activateGroups)) for (let group in values(activateGroups))
if (group[2]) if (group[2])
prefs.safeSet("browser.tabs." + group[2], prefs.safeSet("browser.tabs." + group[2],
!(valueSet["all"] ^ valueSet[group[0]]), !(valueSet.has("all") ^ valueSet.has(group[0])),
_("option.safeSet", "activate")); _("option.safeSet", "activate"));
return newValues; return newValues;
} }

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2009-2014 Kris Maglione <maglione.k@gmail.com>
// Copyright (c) 2009-2010 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2009-2010 by Doug Kearns <dougkearns@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
@@ -164,7 +164,8 @@ var Addon = Class("Addon", {
}, },
commandAllowed: function commandAllowed(cmd) { commandAllowed: function commandAllowed(cmd) {
util.assert(Set.has(actions, cmd), _("addon.unknownCommand")); util.assert(hasOwnProperty(actions, cmd),
_("addon.unknownCommand"));
let action = actions[cmd]; let action = actions[cmd];
if ("perm" in action && !(this.permissions & AddonManager["PERM_CAN_" + action.perm.toUpperCase()])) if ("perm" in action && !(this.permissions & AddonManager["PERM_CAN_" + action.perm.toUpperCase()]))

View File

@@ -22,6 +22,9 @@ let objproto = Object.prototype;
let { __lookupGetter__, __lookupSetter__, __defineGetter__, __defineSetter__, let { __lookupGetter__, __lookupSetter__, __defineGetter__, __defineSetter__,
hasOwnProperty, propertyIsEnumerable } = objproto; hasOwnProperty, propertyIsEnumerable } = objproto;
hasOwnProperty = Function.call.bind(hasOwnProperty);
propertyIsEnumerable = Function.call.bind(propertyIsEnumerable);
if (typeof XPCSafeJSObjectWrapper === "undefined") if (typeof XPCSafeJSObjectWrapper === "undefined")
this.XPCSafeJSObjectWrapper = XPCNativeWrapper; this.XPCSafeJSObjectWrapper = XPCNativeWrapper;
@@ -147,11 +150,11 @@ defineModule("base", {
"Timer", "UTF8", "XPCOM", "XPCOMShim", "XPCOMUtils", "Timer", "UTF8", "XPCOM", "XPCOMShim", "XPCOMUtils",
"XPCSafeJSObjectWrapper", "array", "bind", "call", "callable", "XPCSafeJSObjectWrapper", "array", "bind", "call", "callable",
"ctypes", "curry", "debuggerProperties", "defineModule", "ctypes", "curry", "debuggerProperties", "defineModule",
"deprecated", "endModule", "forEach", "isArray", "isGenerator", "deprecated", "endModule", "forEach", "hasOwnProperty",
"isinstance", "isObject", "isString", "isSubclass", "isXML", "isArray", "isGenerator", "isinstance", "isObject", "isString",
"iter", "iterAll", "iterOwnProperties", "keys", "literal", "isSubclass", "isXML", "iter", "iterAll", "iterOwnProperties",
"memoize", "modujle", "octal", "properties", "require", "set", "keys", "literal", "memoize", "modujle", "octal", "properties",
"update", "values", "update_" "require", "set", "update", "values", "update_"
] ]
}); });
@@ -171,7 +174,7 @@ function literal(/* comment */) {
let file = caller.filename.replace(/.* -> /, ""); let file = caller.filename.replace(/.* -> /, "");
let key = "literal:" + file + ":" + caller.lineNumber; let key = "literal:" + file + ":" + caller.lineNumber;
if (Set.has(literal.locations, key)) if (hasOwnProperty(literal.locations, key))
return literal.locations[key]; return literal.locations[key];
let source = literal.files[file] || File.readURL(file); let source = literal.files[file] || File.readURL(file);
@@ -224,13 +227,15 @@ function prototype(obj)
function properties(obj, prototypes, debugger_) { function properties(obj, prototypes, debugger_) {
let orig = obj; let orig = obj;
let seen = { dactylPropertyNames: true }; let seen = RealSet(["dactylPropertyNames"]);
try { try {
if ("dactylPropertyNames" in obj && !prototypes) if ("dactylPropertyNames" in obj && !prototypes)
for (let key in values(obj.dactylPropertyNames)) for (let key in values(obj.dactylPropertyNames))
if (key in obj && !Set.add(seen, key)) if (key in obj && !seen.has(key)) {
seen.add(key);
yield key; yield key;
}
} }
catch (e) {} catch (e) {}
@@ -276,8 +281,10 @@ function properties(obj, prototypes, debugger_) {
iter = (prop.name.stringValue for (prop in values(debuggerProperties(obj)))); iter = (prop.name.stringValue for (prop in values(debuggerProperties(obj))));
for (let key in iter) for (let key in iter)
if (!prototypes || !Set.add(seen, key) && obj != orig) if (!prototypes || !seen.has(key) && obj != orig) {
seen.add(key);
yield key; yield key;
}
} }
} }
@@ -291,7 +298,9 @@ function deprecated(alternative, fn) {
return Class.Property(iter(fn).map(([k, v]) => [k, callable(v) ? deprecated(alternative, v) : v]) return Class.Property(iter(fn).map(([k, v]) => [k, callable(v) ? deprecated(alternative, v) : v])
.toObject()); .toObject());
let name, func = callable(fn) ? fn : function () this[fn].apply(this, arguments); let name,
func = callable(fn) ? fn
: function () this[fn].apply(this, arguments);
function deprecatedMethod() { function deprecatedMethod() {
let obj = !this ? "" : let obj = !this ? "" :
@@ -299,7 +308,9 @@ function deprecated(alternative, fn) {
this.constructor.className ? this.constructor.className + "#" : this.constructor.className ? this.constructor.className + "#" :
""; "";
deprecated.warn(func, obj + (fn.name || name), alternative); deprecated.warn(func,
obj + (fn.realName || fn.name || name || "").replace(/__/g, "."),
alternative);
return func.apply(this, arguments); return func.apply(this, arguments);
} }
@@ -310,16 +321,24 @@ function deprecated(alternative, fn) {
} }
deprecated.warn = function warn(func, name, alternative, frame) { deprecated.warn = function warn(func, name, alternative, frame) {
if (!func.seenCaller) if (!func.seenCaller)
func.seenCaller = Set([ func.seenCaller = RealSet([
"resource://dactyl/javascript.jsm", "resource://dactyl/javascript.jsm",
"resource://dactyl/util.jsm" "resource://dactyl/util.jsm"
]); ]);
if (!(loaded.util && util && loaded.config && config.protocolLoaded)) {
dump("DACTYL: deprecated method called too early [" + [name, alternative] + "]:\n" + Error().stack + "\n\n");
return;
}
frame = frame || Components.stack.caller.caller; frame = frame || Components.stack.caller.caller;
let filename = util.fixURI(frame.filename || "unknown"); let filename = util.fixURI(frame.filename || "unknown");
if (!Set.add(func.seenCaller, filename)) if (!func.seenCaller.has(filename)) {
func.seenCaller.add(filename);
util.dactyl(func).warn([util.urlPath(filename), frame.lineNumber, " "].join(":") util.dactyl(func).warn([util.urlPath(filename), frame.lineNumber, " "].join(":")
+ _("warn.deprecated", name, alternative)); + _("warn.deprecated", name, alternative));
}
} }
/** /**
@@ -335,7 +354,7 @@ function keys(obj) iter(function keys() {
yield k; yield k;
else else
for (var k in obj) for (var k in obj)
if (hasOwnProperty.call(obj, k)) if (hasOwnProperty(obj, k))
yield k; yield k;
}()); }());
@@ -355,7 +374,7 @@ function values(obj) iter(function values() {
yield k; yield k;
else else
for (var k in obj) for (var k in obj)
if (hasOwnProperty.call(obj, k)) if (hasOwnProperty(obj, k))
yield obj[k]; yield obj[k];
}()); }());
@@ -371,13 +390,13 @@ var RealSet = Set;
* @param {[string]} ary @optional * @param {[string]} ary @optional
* @returns {object} * @returns {object}
*/ */
this.Set = function Set(ary) { this.Set = deprecated("RealSet", function Set(ary) {
let obj = {}; let obj = {};
if (ary) if (ary)
for (let val in values(ary)) for (let val in values(ary))
obj[val] = true; obj[val] = true;
return obj; return obj;
} });
/** /**
* Adds an element to a set and returns true if the element was * Adds an element to a set and returns true if the element was
* previously contained. * previously contained.
@@ -386,11 +405,18 @@ this.Set = function Set(ary) {
* @param {string} key The key to add. * @param {string} key The key to add.
* @returns boolean * @returns boolean
*/ */
Set.add = curry(function set_add(set, key) { Set.add = deprecated("Set#add",
let res = this.has(set, key); curry(function Set__add(set, key) {
set[key] = true; if (isinstance(set, ["Set"])) {
return res; let res = set.has(key);
}); set.add(key);
return res;
}
let res = this.has(set, key);
set[key] = true;
return res;
}));
/** /**
* Returns true if the given set contains the given key. * Returns true if the given set contains the given key.
* *
@@ -398,8 +424,14 @@ Set.add = curry(function set_add(set, key) {
* @param {string} key The key to check. * @param {string} key The key to check.
* @returns {boolean} * @returns {boolean}
*/ */
Set.has = curry(function set_has(set, key) hasOwnProperty.call(set, key) && Set.has = deprecated("hasOwnProperty or Set#has",
propertyIsEnumerable.call(set, key)); curry(function Set__has(set, key) {
if (isinstance(set, ["Set"]))
return set.has(key);
return hasOwnProperty(set, key) &&
propertyIsEnumerable(set, key);
}));
/** /**
* Returns a new set containing the members of the first argument which * Returns a new set containing the members of the first argument which
* do not exist in any of the other given arguments. * do not exist in any of the other given arguments.
@@ -414,6 +446,7 @@ Set.subtract = function set_subtract(set) {
delete set[k]; delete set[k];
return set; return set;
}; };
/** /**
* Removes an element from a set and returns true if the element was * Removes an element from a set and returns true if the element was
* previously contained. * previously contained.
@@ -422,11 +455,15 @@ Set.subtract = function set_subtract(set) {
* @param {string} key The key to remove. * @param {string} key The key to remove.
* @returns boolean * @returns boolean
*/ */
Set.remove = curry(function set_remove(set, key) { Set.remove = deprecated("Set#delete",
let res = set.has(set, key); curry(function Set__remove(set, key) {
delete set[key]; if (isinstance(set, ["Set"]))
return res; return set.delete(key);
});
let res = set.has(set, key);
delete set[key];
return res;
}));
function set() { function set() {
deprecated.warn(set, "set", "Set"); deprecated.warn(set, "set", "Set");
@@ -472,7 +509,7 @@ function curry(fn, length, self, acc) {
if (acc == null) if (acc == null)
acc = []; acc = [];
return function curried(...args) { function curried(...args) {
// The curried result should preserve 'this' // The curried result should preserve 'this'
if (args.length == 0) if (args.length == 0)
return close(self || this, curried); return close(self || this, curried);
@@ -484,6 +521,8 @@ function curry(fn, length, self, acc) {
return curry(fn, length, self || this, args); return curry(fn, length, self || this, args);
}; };
curried.realName = fn.realName || fn.name;
return curried;
} }
if (curry.bind) if (curry.bind)
@@ -1009,7 +1048,7 @@ Class.prototype = {
} }
try { try {
if ("value" in desc && (k in this.localizedProperties || k in this.magicalProperties)) if ("value" in desc && (this.localizedProperties.has(k) || this.magicalProperties.has(k)))
this[k] = desc.value; this[k] = desc.value;
else else
Object.defineProperty(this, k, desc); Object.defineProperty(this, k, desc);
@@ -1020,8 +1059,8 @@ Class.prototype = {
return this; return this;
}, },
localizedProperties: {}, localizedProperties: RealSet(),
magicalProperties: {} magicalProperties: RealSet()
}; };
for (let name in properties(Class.prototype)) { for (let name in properties(Class.prototype)) {
let desc = Object.getOwnPropertyDescriptor(Class.prototype, name); let desc = Object.getOwnPropertyDescriptor(Class.prototype, name);
@@ -1045,6 +1084,7 @@ Class.makeClosure = function makeClosure() {
return _closure; return _closure;
} }
let x = /commandline/i.test(this);
iter(properties(this), properties(this, true)).forEach(function (k) { iter(properties(this), properties(this, true)).forEach(function (k) {
if (!__lookupGetter__.call(this, k) && callable(this[k])) if (!__lookupGetter__.call(this, k) && callable(this[k]))
closure[k] = closure(this[k]); closure[k] = closure(this[k]);
@@ -1552,10 +1592,12 @@ update(iter, {
array(this.toArray(iter).sort(fn, self)), array(this.toArray(iter).sort(fn, self)),
uniq: function uniq(iter) { uniq: function uniq(iter) {
let seen = {}; let seen = RealSet();
for (let item in iter) for (let item in iter)
if (!Set.add(seen, item)) if (!seen.has(item)) {
seen.add(item);
yield item; yield item;
}
}, },
/** /**

View File

@@ -77,41 +77,42 @@ var Buffer = Module("Buffer", {
/** /**
* Content preference methods. * Content preference methods.
*/ */
prefs: Class.Memoize(() => ({ prefs: Class.Memoize(function ()
/** let (self = this) ({
* Returns a promise for the given preference name. /**
* * Returns a promise for the given preference name.
* @param {string} pref The name of the preference to return. *
* @returns {Promise<string>} * @param {string} pref The name of the preference to return.
*/ * @returns {Promise<string>}
get: promises.withCallback(function get(callback, pref) { */
services.contentPrefs.getByDomainAndName( get: promises.withCallback(function get(callback, pref) {
this.uri.host, pref, this.loadContext, services.contentPrefs.getByDomainAndName(
callback); self.uri.host, pref, self.loadContext,
}), callback);
}),
/** /**
* Sets a content preference for the given buffer. * Sets a content preference for the given buffer.
* *
* @param {string} pref The preference to set. * @param {string} pref The preference to set.
* @param {string} value The value to store. * @param {string} value The value to store.
*/ */
set: promises.withCallback(function set(callback, pref, value) { set: promises.withCallback(function set(callback, pref, value) {
services.contentPrefs.set( services.contentPrefs.set(
this.uri.host, pref, value, this.loadContext, self.uri.host, pref, value, self.loadContext,
callback); callback);
}), }),
/** /**
* Clear a content preference for the given buffer. * Clear a content preference for the given buffer.
* *
* @param {string} pref The preference to clear. * @param {string} pref The preference to clear.
*/ */
clear: promises.withCallback(function clear(callback, pref) { clear: promises.withCallback(function clear(callback, pref) {
services.contentPrefs.removeByDomainAndName( services.contentPrefs.removeByDomainAndName(
this.uri.domain, pref, this.loadContext, callback); self.uri.domain, pref, self.loadContext, callback);
}), }),
})), })),
/** /**
* Gets a content preference for the given buffer. * Gets a content preference for the given buffer.

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2011-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2011-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -18,7 +18,7 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), {
this.cache = {}; this.cache = {};
this.providers = {}; this.providers = {};
this.globalProviders = this.providers; this.globalProviders = this.providers;
this.providing = {}; this.providing = RealSet();
this.localProviders = {}; this.localProviders = {};
if (JSMLoader.cacheFlush) if (JSMLoader.cacheFlush)
@@ -174,22 +174,24 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), {
this.cacheReader.getInputStream(name))); this.cacheReader.getInputStream(name)));
} }
if (Set.has(this.localProviders, name) && !this.isLocal) { if (hasOwnProperty(this.localProviders, name) && !this.isLocal) {
for each (let { cache } in overlay.modules) for each (let { cache } in overlay.modules)
if (cache._has(name)) if (cache._has(name))
return cache.force(name, true); return cache.force(name, true);
} }
if (Set.has(this.providers, name)) { if (hasOwnProperty(this.providers, name)) {
util.assert(!Set.add(this.providing, name), util.assert(!this.providing.has(name),
"Already generating cache for " + name, "Already generating cache for " + name,
false); false);
this.providing.add(name);
try { try {
let [func, self] = this.providers[name]; let [func, self] = this.providers[name];
this.cache[name] = func.call(self || this, name); this.cache[name] = func.call(self || this, name);
} }
finally { finally {
delete this.providing[name]; this.providing.delete(name);
} }
cache.queue.push([Date.now(), name]); cache.queue.push([Date.now(), name]);
@@ -203,9 +205,9 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), {
}, },
get: function get(name, callback, self) { get: function get(name, callback, self) {
if (!Set.has(this.cache, name)) { if (!hasOwnProperty(this.cache, name)) {
if (callback && !(Set.has(this.providers, name) || if (callback && !(hasOwnProperty(this.providers, name) ||
Set.has(this.localProviders, name))) hasOwnProperty(this.localProviders, name)))
this.register(name, callback, self); this.register(name, callback, self);
this.cache[name] = this.force(name); this.cache[name] = this.force(name);
@@ -216,14 +218,15 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), {
return this.cache[name]; return this.cache[name];
}, },
_has: function _has(name) Set.has(this.providers, name) || set.has(this.cache, name), _has: function _has(name) hasOwnProperty(this.providers, name)
|| hasOwnProperty(this.cache, name),
has: function has(name) [this.globalProviders, this.cache, this.localProviders] has: function has(name) [this.globalProviders, this.cache, this.localProviders]
.some(obj => Set.has(obj, name)), .some(obj => hasOwnProperty(obj, name)),
register: function register(name, callback, self) { register: function register(name, callback, self) {
if (this.isLocal) if (this.isLocal)
Set.add(this.localProviders, name); this.localProviders[name] = true;
this.providers[name] = [callback, self]; this.providers[name] = [callback, self];
}, },
@@ -244,7 +247,7 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), {
this.closeWriter(); this.closeWriter();
this.queue.splice(0).forEach(function ([time, entry]) { this.queue.splice(0).forEach(function ([time, entry]) {
if (time && Set.has(this.cache, entry)) { if (time && hasOwnProperty(this.cache, entry)) {
let stream = services.CharsetConv("UTF-8") let stream = services.CharsetConv("UTF-8")
.convertToInputStream(this.stringify(this.cache[entry])); .convertToInputStream(this.stringify(this.cache[entry]));

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -210,7 +210,7 @@ var Command = Class("Command", {
extra: extra extra: extra
}), }),
complained: Class.Memoize(function () ({})), complained: Class.Memoize(function () RealSet()),
/** /**
* @property {[string]} All of this command's name specs. e.g., "com[mand]" * @property {[string]} All of this command's name specs. e.g., "com[mand]"
@@ -325,7 +325,8 @@ var Command = Class("Command", {
explicitOpts: Class.Memoize(function () ({})), explicitOpts: Class.Memoize(function () ({})),
has: function AP_has(opt) Set.has(this.explicitOpts, opt) || typeof opt === "number" && Set.has(this, opt), has: function AP_has(opt) hasOwnProperty(this.explicitOpts, opt)
|| typeof opt === "number" && hasOwnProperty(this, opt),
get literalArg() this.command.literal != null && this[this.command.literal] || "", get literalArg() this.command.literal != null && this[this.command.literal] || "",
@@ -402,8 +403,12 @@ var Command = Class("Command", {
warn: function warn(context, type, message) { warn: function warn(context, type, message) {
let loc = !context ? "" : [context.file, context.line, " "].join(":"); let loc = !context ? "" : [context.file, context.line, " "].join(":");
if (!Set.add(this.complained, type + ":" + (context ? context.file : "[Command Line]"))) let key = type + ":" + (context ? context.file : "[Command Line]");
if (!this.complained.has(key)) {
this.complained.add(key);
this.modules.dactyl.warn(loc + message); this.modules.dactyl.warn(loc + message);
}
} }
}, { }, {
hasName: function hasName(specs, name) hasName: function hasName(specs, name)
@@ -1011,7 +1016,7 @@ var Commands = Module("commands", {
let matchOpts = function matchOpts(arg) { let matchOpts = function matchOpts(arg) {
// Push possible option matches into completions // Push possible option matches into completions
if (complete && !onlyArgumentsRemaining) if (complete && !onlyArgumentsRemaining)
completeOpts = options.filter(opt => (opt.multiple || !Set.has(args, opt.names[0]))); completeOpts = options.filter(opt => (opt.multiple || !hasOwnProperty(args, opt.names[0])));
}; };
let resetCompletions = function resetCompletions() { let resetCompletions = function resetCompletions() {
completeOpts = null; completeOpts = null;
@@ -1721,7 +1726,7 @@ var Commands = Module("commands", {
] ]
})), })),
iterateIndex: function (args) let (tags = help.tags) iterateIndex: function (args) let (tags = help.tags)
this.iterate(args).filter(cmd => (cmd.hive === commands.builtin || Set.has(tags, cmd.helpTag))), this.iterate(args).filter(cmd => (cmd.hive === commands.builtin || hasOwnProperty(tags, cmd.helpTag))),
format: { format: {
headings: ["Command", "Group", "Description"], headings: ["Command", "Group", "Description"],
description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : "")), description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : "")),

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -1183,9 +1183,10 @@ var Completion = Module("completion", {
if (k.indexOf(services.AUTOCOMPLETE) == 0)]), if (k.indexOf(services.AUTOCOMPLETE) == 0)]),
setter: function setter(values) { setter: function setter(values) {
if (values.length == 1 && !Set.has(values[0], this.values) if (values.length == 1 && !hasOwnProperty(values[0], this.values)
&& Array.every(values[0], Set.has(this.valueMap))) && Array.every(values[0], v => hasOwnProperty(this.valueMap, v)))
return Array.map(values[0], function m(v) this[v], this.valueMap); return Array.map(values[0], v => this.valueMap[v]);
return values; return values;
}, },

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -9,16 +9,19 @@
let global = this; let global = this;
defineModule("config", { defineModule("config", {
exports: ["ConfigBase", "Config", "config"], exports: ["ConfigBase", "Config", "config"],
require: ["dom", "io", "protocol", "services", "util", "template"] require: ["io", "protocol", "services"]
}); });
lazyRequire("addons", ["AddonManager"]); lazyRequire("addons", ["AddonManager"]);
lazyRequire("cache", ["cache"]); lazyRequire("cache", ["cache"]);
lazyRequire("dom", ["DOM"]);
lazyRequire("highlight", ["highlight"]); lazyRequire("highlight", ["highlight"]);
lazyRequire("messages", ["_"]); lazyRequire("messages", ["_"]);
lazyRequire("prefs", ["localPrefs", "prefs"]); lazyRequire("prefs", ["localPrefs", "prefs"]);
lazyRequire("storage", ["storage", "File"]); lazyRequire("storage", ["storage", "File"]);
lazyRequire("styles", ["Styles"]); lazyRequire("styles", ["Styles"]);
lazyRequire("template", ["template"]);
lazyRequire("util", ["util"]);
function AboutHandler() {} function AboutHandler() {}
AboutHandler.prototype = { AboutHandler.prototype = {
@@ -50,13 +53,12 @@ var ConfigBase = Class("ConfigBase", {
this.loadConfig(); this.loadConfig();
this.features.push = deprecated("Set.add", function push(feature) Set.add(this, feature));
JSMLoader.registerFactory(JSMLoader.Factory(AboutHandler)); JSMLoader.registerFactory(JSMLoader.Factory(AboutHandler));
JSMLoader.registerFactory(JSMLoader.Factory( JSMLoader.registerFactory(JSMLoader.Factory(
Protocol("dactyl", "{9c8f2530-51c8-4d41-b356-319e0b155c44}", Protocol("dactyl", "{9c8f2530-51c8-4d41-b356-319e0b155c44}",
"resource://dactyl-content/"))); "resource://dactyl-content/")));
this.protocolLoaded = true;
this.timeout(function () { this.timeout(function () {
cache.register("config.dtd", () => util.makeDTD(config.dtd)); cache.register("config.dtd", () => util.makeDTD(config.dtd));
}); });
@@ -71,7 +73,7 @@ var ConfigBase = Class("ConfigBase", {
get prefs() localPrefs, get prefs() localPrefs,
get has() Set.has(this.features), has: function (feature) this.features.has(feature),
configFiles: [ configFiles: [
"resource://dactyl-common/config.json", "resource://dactyl-common/config.json",
@@ -91,6 +93,9 @@ var ConfigBase = Class("ConfigBase", {
if (isArray(this[prop])) if (isArray(this[prop]))
this[prop] = [].concat(this[prop], value); this[prop] = [].concat(this[prop], value);
else if (isinstance(this[prop], ["Set"]))
for (let key of value)
this[prop].add(key);
else if (isObject(this[prop])) { else if (isObject(this[prop])) {
if (isArray(value)) if (isArray(value))
value = Set(value); value = Set(value);
@@ -236,7 +241,7 @@ var ConfigBase = Class("ConfigBase", {
bestLocale: function (list) { bestLocale: function (list) {
return values([this.appLocale, this.appLocale.replace(/-.*/, ""), return values([this.appLocale, this.appLocale.replace(/-.*/, ""),
"en", "en-US", list[0]]) "en", "en-US", list[0]])
.nth(Set.has(Set(list)), 0); .nth((function (l) this.has(l)).bind(RealSet(list)), 0);
}, },
/** /**
@@ -529,7 +534,7 @@ var ConfigBase = Class("ConfigBase", {
* dactyl.has(feature) to check for a feature's presence * dactyl.has(feature) to check for a feature's presence
* in this array. * in this array.
*/ */
features: {}, features: RealSet(),
/** /**
* @property {string} The file extension used for command script files. * @property {string} The file extension used for command script files.

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2010-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2010-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -189,7 +189,9 @@ var Contexts = Module("contexts", {
{ _hive: { value: name } }))); { _hive: { value: name } })));
memoize(contexts.groupsProto, name, memoize(contexts.groupsProto, name,
function () [group[name] for (group in values(this.groups)) if (Set.has(group, name))]); function () [group[name]
for (group in values(this.groups))
if (hasOwnProperty(group, name))]);
}, },
get toStringParams() [this.name, this.Hive] get toStringParams() [this.name, this.Hive]
@@ -211,13 +213,13 @@ var Contexts = Module("contexts", {
let id = util.camelCase(name.replace(/\.[^.]*$/, "")); let id = util.camelCase(name.replace(/\.[^.]*$/, ""));
let contextPath = file.path; let contextPath = file.path;
let self = Set.has(plugins, contextPath) && plugins.contexts[contextPath]; let self = hasOwnProperty(plugins, contextPath) && plugins.contexts[contextPath];
if (!self && isPlugin && false) if (!self && isPlugin && false)
self = Set.has(plugins, id) && plugins[id]; self = hasOwnProperty(plugins, id) && plugins[id];
if (self) { if (self) {
if (Set.has(self, "onUnload")) if (hasOwnProperty(self, "onUnload"))
util.trapErrors("onUnload", self); util.trapErrors("onUnload", self);
} }
else { else {
@@ -310,7 +312,7 @@ var Contexts = Module("contexts", {
.replace(File.PATH_SEP, "-"); .replace(File.PATH_SEP, "-");
let id = util.camelCase(name.replace(/\.[^.]*$/, "")); let id = util.camelCase(name.replace(/\.[^.]*$/, ""));
let self = Set.has(this.pluginModules, canonical) && this.pluginModules[canonical]; let self = hasOwnProperty(this.pluginModules, canonical) && this.pluginModules[canonical];
if (!self) { if (!self) {
self = Object.create(jsmodules); self = Object.create(jsmodules);
@@ -411,7 +413,7 @@ var Contexts = Module("contexts", {
initializedGroups: function (hive) initializedGroups: function (hive)
let (need = hive ? [hive] : Object.keys(this.hives)) let (need = hive ? [hive] : Object.keys(this.hives))
this.groupList.filter(group => need.some(Set.has(group))), this.groupList.filter(group => need.some(hasOwnProperty.bind(null, group))),
addGroup: function addGroup(name, description, filter, persist, replace) { addGroup: function addGroup(name, description, filter, persist, replace) {
let group = this.getGroup(name); let group = this.getGroup(name);
@@ -468,7 +470,7 @@ var Contexts = Module("contexts", {
getGroup: function getGroup(name, hive) { getGroup: function getGroup(name, hive) {
if (name === "default") if (name === "default")
var group = this.context && this.context.context && this.context.context.GROUP; var group = this.context && this.context.context && this.context.context.GROUP;
else if (Set.has(this.groupMap, name)) else if (hasOwnProperty(this.groupMap, name))
group = this.groupMap[name]; group = this.groupMap[name];
if (group && hive) if (group && hive)
@@ -644,7 +646,7 @@ var Contexts = Module("contexts", {
util.assert(!group.builtin || util.assert(!group.builtin ||
!["-description", "-locations", "-nopersist"] !["-description", "-locations", "-nopersist"]
.some(Set.has(args.explicitOpts)), .some(hasOwnProperty.bind(null, args.explicitOpts)),
_("group.cantModifyBuiltin")); _("group.cantModifyBuiltin"));
}, },
{ {

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -627,7 +627,7 @@ var DOM = Class("DOM", {
if (callable(v)) if (callable(v))
v = v.call(this, elem, i); v = v.call(this, elem, i);
if (Set.has(hooks, k) && hooks[k].set) if (hasOwnProperty(hooks, k) && hooks[k].set)
hooks[k].set.call(this, elem, v, k); hooks[k].set.call(this, elem, v, k);
else if (v == null) else if (v == null)
elem.removeAttributeNS(ns, k); elem.removeAttributeNS(ns, k);
@@ -639,7 +639,7 @@ var DOM = Class("DOM", {
if (!this.length) if (!this.length)
return null; return null;
if (Set.has(hooks, key) && hooks[key].get) if (hasOwnProperty(hooks, key) && hooks[key].get)
return hooks[key].get.call(this, this[0], key); return hooks[key].get.call(this, this[0], key);
if (!this[0].hasAttributeNS(ns, key)) if (!this[0].hasAttributeNS(ns, key))
@@ -1071,7 +1071,7 @@ var DOM = Class("DOM", {
keyTable: Class.Memoize(function (prop) this.init()[prop]), keyTable: Class.Memoize(function (prop) this.init()[prop]),
key_code: Class.Memoize(function (prop) this.init()[prop]), key_code: Class.Memoize(function (prop) this.init()[prop]),
key_key: Class.Memoize(function (prop) this.init()[prop]), key_key: Class.Memoize(function (prop) this.init()[prop]),
pseudoKeys: Set(["count", "leader", "nop", "pass"]), pseudoKeys: RealSet(["count", "leader", "nop", "pass"]),
/** /**
* Converts a user-input string of keys into a canonical * Converts a user-input string of keys into a canonical
@@ -1141,19 +1141,19 @@ var DOM = Class("DOM", {
} }
else { else {
let [match, modifier, keyname] = evt_str.match(/^<((?:[*12CASM⌘]-)*)(.+?)>$/i) || [false, '', '']; let [match, modifier, keyname] = evt_str.match(/^<((?:[*12CASM⌘]-)*)(.+?)>$/i) || [false, '', ''];
modifier = Set(modifier.toUpperCase()); modifier = RealSet(modifier.toUpperCase());
keyname = keyname.toLowerCase(); keyname = keyname.toLowerCase();
evt_obj.dactylKeyname = keyname; evt_obj.dactylKeyname = keyname;
if (/^u[0-9a-f]+$/.test(keyname)) if (/^u[0-9a-f]+$/.test(keyname))
keyname = String.fromCharCode(parseInt(keyname.substr(1), 16)); keyname = String.fromCharCode(parseInt(keyname.substr(1), 16));
if (keyname && (unknownOk || keyname.length == 1 || /mouse$/.test(keyname) || if (keyname && (unknownOk || keyname.length == 1 || /mouse$/.test(keyname) ||
this.key_code[keyname] || Set.has(this.pseudoKeys, keyname))) { this.key_code[keyname] || this.pseudoKeys.has(keyname))) {
evt_obj.globKey ="*" in modifier; evt_obj.globKey = modifier.has("*");
evt_obj.ctrlKey ="C" in modifier; evt_obj.ctrlKey = modifier.has("C");
evt_obj.altKey ="A" in modifier; evt_obj.altKey = modifier.has("A");
evt_obj.shiftKey ="S" in modifier; evt_obj.shiftKey = modifier.has("S");
evt_obj.metaKey ="M" in modifier || "" in modifier; evt_obj.metaKey = modifier.has("M") || modifier.has("⌘");
evt_obj.dactylShift = evt_obj.shiftKey; evt_obj.dactylShift = evt_obj.shiftKey;
if (keyname.length == 1) { // normal characters if (keyname.length == 1) { // normal characters
@@ -1164,11 +1164,11 @@ var DOM = Class("DOM", {
evt_obj.charCode = keyname.charCodeAt(0); evt_obj.charCode = keyname.charCodeAt(0);
evt_obj.keyCode = this.key_code[keyname.toLowerCase()]; evt_obj.keyCode = this.key_code[keyname.toLowerCase()];
} }
else if (Set.has(this.pseudoKeys, keyname)) { else if (this.pseudoKeys.has(keyname)) {
evt_obj.dactylString = "<" + this.key_key[keyname] + ">"; evt_obj.dactylString = "<" + this.key_key[keyname] + ">";
} }
else if (/mouse$/.test(keyname)) { // mouse events else if (/mouse$/.test(keyname)) { // mouse events
evt_obj.type = (/2-/.test(modifier) ? "dblclick" : "click"); evt_obj.type = (modifier.has("2") ? "dblclick" : "click");
evt_obj.button = ["leftmouse", "middlemouse", "rightmouse"].indexOf(keyname); evt_obj.button = ["leftmouse", "middlemouse", "rightmouse"].indexOf(keyname);
delete evt_obj.keyCode; delete evt_obj.keyCode;
delete evt_obj.charCode; delete evt_obj.charCode;
@@ -1398,9 +1398,9 @@ var DOM = Class("DOM", {
* The set of input element type attribute values that mark the element as * The set of input element type attribute values that mark the element as
* an editable field. * an editable field.
*/ */
editableInputs: Set(["date", "datetime", "datetime-local", "email", "file", editableInputs: RealSet(["date", "datetime", "datetime-local", "email", "file",
"month", "number", "password", "range", "search", "month", "number", "password", "range", "search",
"tel", "text", "time", "url", "week"]), "tel", "text", "time", "url", "week"]),
/** /**
* Converts a given DOM Node, Range, or Selection to a string. If * Converts a given DOM Node, Range, or Selection to a string. If
@@ -1633,7 +1633,7 @@ var DOM = Class("DOM", {
toPrettyXML: function toPrettyXML(xml, asXML, indent, namespaces) { toPrettyXML: function toPrettyXML(xml, asXML, indent, namespaces) {
const INDENT = indent || " "; const INDENT = indent || " ";
const EMPTY = Set("area base basefont br col frame hr img input isindex link meta param" const EMPTY = RealSet("area base basefont br col frame hr img input isindex link meta param"
.split(" ")); .split(" "));
function namespaced(namespaces, namespace, localName) { function namespaced(namespaces, namespace, localName) {
@@ -1742,7 +1742,7 @@ var DOM = Class("DOM", {
let res = [indent, "<", name]; let res = [indent, "<", name];
for (let [key, val] in Iterator(attr)) { for (let [key, val] in Iterator(attr)) {
if (Set.has(skipAttr, key)) if (hasOwnProperty(skipAttr, key))
continue; continue;
let vals = parseNamespace(key); let vals = parseNamespace(key);
@@ -1758,7 +1758,7 @@ var DOM = Class("DOM", {
'="', DOM.escapeHTML(val), '"'); '="', DOM.escapeHTML(val), '"');
} }
if ((vals[0] || namespaces[""]) == String(XHTML) && Set.has(EMPTY, vals[1]) if ((vals[0] || namespaces[""]) == String(XHTML) && EMPTY.has(vals[1])
|| asXML && !args.length) || asXML && !args.length)
res.push("/>"); res.push("/>");
else { else {
@@ -1881,7 +1881,7 @@ var DOM = Class("DOM", {
Object.keys(DOM.Event.types).forEach(function (event) { Object.keys(DOM.Event.types).forEach(function (event) {
let name = event.replace(/-(.)/g, (m, m1) => m1.toUpperCase()); let name = event.replace(/-(.)/g, (m, m1) => m1.toUpperCase());
if (!Set.has(DOM.prototype, name)) if (!hasOwnProperty(DOM.prototype, name))
DOM.prototype[name] = DOM.prototype[name] =
function _event(arg, extra) { function _event(arg, extra) {
return this[callable(arg) ? "listen" : "dispatch"](event, arg, extra); return this[callable(arg) ? "listen" : "dispatch"](event, arg, extra);

View File

@@ -87,10 +87,10 @@ var Download = Class("Download", {
})), })),
command: function command(name) { command: function command(name) {
util.assert(Set.has(this.allowedCommands, name), _("download.unknownCommand")); util.assert(hasOwnProperty(this.allowedCommands, name), _("download.unknownCommand"));
util.assert(this.allowedCommands[name], _("download.commandNotAllowed")); util.assert(this.allowedCommands[name], _("download.commandNotAllowed"));
if (Set.has(this.commands, name)) if (hasOwnProperty(this.commands, name))
this.commands[name].call(this); this.commands[name].call(this);
}, },
@@ -523,9 +523,9 @@ var Downloads_ = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), {
}, },
completer: function (context, extra) { completer: function (context, extra) {
let seen = Set.has(Set(extra.values.map(val => val.substr(1)))); let seen = RealSet(extra.values.map(val => val.substr(1)));
context.completions = iter(this.values).filter(([k, v]) => !seen(k)) context.completions = iter(this.values).filter(([k, v]) => !seen.has(k))
.map(([k, v]) => [["+" + k, [v, " (", _("sort.ascending"), ")"].join("")], .map(([k, v]) => [["+" + k, [v, " (", _("sort.ascending"), ")"].join("")],
["-" + k, [v, " (", _("sort.descending"), ")"].join("")]]) ["-" + k, [v, " (", _("sort.descending"), ")"].join("")]])
.flatten().array; .flatten().array;
@@ -535,7 +535,7 @@ var Downloads_ = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), {
validator: function (value) { validator: function (value) {
let seen = {}; let seen = {};
return value.every(val => /^[+-]/.test(val) && Set.has(this.values, val.substr(1)) return value.every(val => /^[+-]/.test(val) && hasOwnProperty(this.values, val.substr(1))
&& !Set.add(seen, val.substr(1))) && !Set.add(seen, val.substr(1)))
&& value.length; && value.length;
} }

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -237,7 +237,7 @@ var Help = Module("Help", {
* @returns {string} * @returns {string}
*/ */
findHelp: function (topic, consolidated) { findHelp: function (topic, consolidated) {
if (!consolidated && Set.has(help.files, topic)) if (!consolidated && hasOwnProperty(help.files, topic))
return topic; return topic;
let items = modules.completion._runCompleter("help", topic, null, !!consolidated).items; let items = modules.completion._runCompleter("help", topic, null, !!consolidated).items;
let partialMatch = null; let partialMatch = null;
@@ -268,7 +268,7 @@ var Help = Module("Help", {
if (!topic) { if (!topic) {
let helpFile = consolidated ? "all" : modules.options["helpfile"]; let helpFile = consolidated ? "all" : modules.options["helpfile"];
if (Set.has(help.files, helpFile)) if (hasOwnProperty(help.files, helpFile))
dactyl.open("dactyl://help/" + helpFile, { from: "help" }); dactyl.open("dactyl://help/" + helpFile, { from: "help" });
else else
dactyl.echomsg(_("help.noFile", helpFile.quote())); dactyl.echomsg(_("help.noFile", helpFile.quote()));
@@ -304,7 +304,7 @@ var Help = Module("Help", {
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data)); addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
} }
let empty = Set("area base basefont br col frame hr img input isindex link meta param" let empty = RealSet("area base basefont br col frame hr img input isindex link meta param"
.split(" ")); .split(" "));
function fix(node) { function fix(node) {
switch (node.nodeType) { switch (node.nodeType) {
@@ -319,7 +319,7 @@ var Help = Module("Help", {
for (let { name, value } in array.iterValues(node.attributes)) { for (let { name, value } in array.iterValues(node.attributes)) {
if (name == "dactyl:highlight") { if (name == "dactyl:highlight") {
Set.add(styles, value); styles.add(value);
name = "class"; name = "class";
value = "hl-" + value; value = "hl-" + value;
} }
@@ -345,7 +345,7 @@ var Help = Module("Help", {
data.push(" ", name, '="', DOM.escapeHTML(value), '"'); data.push(" ", name, '="', DOM.escapeHTML(value), '"');
} }
if (node.localName in empty) if (empty.has(node.localName))
data.push(" />"); data.push(" />");
else { else {
data.push(">"); data.push(">");
@@ -362,7 +362,7 @@ var Help = Module("Help", {
let { buffer, content, events } = modules; let { buffer, content, events } = modules;
let chromeFiles = {}; let chromeFiles = {};
let styles = {}; let styles = RealSet();
for (let [file, ] in Iterator(help.files)) { for (let [file, ] in Iterator(help.files)) {
let url = "dactyl://help/" + file; let url = "dactyl://help/" + file;
@@ -380,7 +380,7 @@ var Help = Module("Help", {
addDataEntry(file + ".xhtml", data.join("")); addDataEntry(file + ".xhtml", data.join(""));
} }
let data = [h for (h in highlight) if (Set.has(styles, h.class) || /^Help/.test(h.class))] let data = [h for (h in highlight) if (styles.has(h.class) || /^Help/.test(h.class))]
.map(h => h.selector .map(h => h.selector
.replace(/^\[.*?=(.*?)\]/, ".hl-$1") .replace(/^\[.*?=(.*?)\]/, ".hl-$1")
.replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}") .replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}")

View File

@@ -1,7 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2012 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2012 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// Some code based on Venkman
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -42,7 +41,7 @@ var IO = Module("io", {
this._oldcwd = null; this._oldcwd = null;
this._lastRunCommand = ""; // updated whenever the users runs a command with :! this._lastRunCommand = ""; // updated whenever the users runs a command with :!
this._scriptNames = []; this._scriptNames = RealSet();
}, },
CommandFileMode: Class("CommandFileMode", modules.CommandMode, { CommandFileMode: Class("CommandFileMode", modules.CommandMode, {
@@ -156,7 +155,7 @@ var IO = Module("io", {
else if (/\.js$/.test(filename)) { else if (/\.js$/.test(filename)) {
try { try {
var context = contexts.Script(file, params.group); var context = contexts.Script(file, params.group);
if (Set.has(this._scriptNames, file.path)) if (this._scriptNames.has(file.path))
util.flushCache(); util.flushCache();
dactyl.loadScript(uri.spec, context); dactyl.loadScript(uri.spec, context);
@@ -196,7 +195,7 @@ var IO = Module("io", {
dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime); dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime);
} }
Set.add(this._scriptNames, file.path); this._scriptNames.add(file.path);
dactyl.echomsg(_("io.sourcingEnd", filename.quote()), 2); dactyl.echomsg(_("io.sourcingEnd", filename.quote()), 2);
dactyl.log(_("dactyl.sourced", filename), 3); dactyl.log(_("dactyl.sourced", filename), 3);
@@ -865,7 +864,7 @@ unlet s:cpo_save
commands.add(["scrip[tnames]"], commands.add(["scrip[tnames]"],
"List all sourced script names", "List all sourced script names",
function () { function () {
let names = Object.keys(io._scriptNames); let names = [k for (k of io._scriptNames)];
if (!names.length) if (!names.length)
dactyl.echomsg(_("command.scriptnames.none")); dactyl.echomsg(_("command.scriptnames.none"));
else else

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -72,23 +72,29 @@ var JavaScript = Module("javascript", {
if (obj == null) if (obj == null)
return; return;
let seen = isinstance(obj, ["Sandbox"]) ? Set(JavaScript.magicalNames) : {}; let seen = RealSet(isinstance(obj, ["Sandbox"]) ? JavaScript.magicalNames : []);
let globals = values(toplevel && this.window === obj ? this.globalNames : []); let globals = values(toplevel && this.window === obj ? this.globalNames : []);
if (toplevel && isObject(obj) && "wrappedJSObject" in obj) if (toplevel && isObject(obj) && "wrappedJSObject" in obj)
if (!Set.add(seen, "wrappedJSObject")) if (!seen.has("wrappedJSObject")) {
seen.add("wrappedJSObject");
yield "wrappedJSObject"; yield "wrappedJSObject";
}
for (let key in iter(globals, properties(obj, !toplevel, true))) for (let key in iter(globals, properties(obj, !toplevel, true)))
if (!Set.add(seen, key)) if (!seen.has(key)) {
seen.add(key);
yield key; yield key;
}
// Properties aren't visible in an XPCNativeWrapper until // Properties aren't visible in an XPCNativeWrapper until
// they're accessed. // they're accessed.
for (let key in properties(this.getKey(obj, "wrappedJSObject"), !toplevel, true)) for (let key in properties(this.getKey(obj, "wrappedJSObject"), !toplevel, true))
try { try {
if (key in obj && !Set.has(seen, key)) if (key in obj && !seen.has(key)) {
seen.add(key);
yield key; yield key;
}
} }
catch (e) {} catch (e) {}
}, },

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2009-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -192,8 +192,8 @@ overlay.overlayWindow(Object.keys(config.overlays),
this.startTime = Date.now(); this.startTime = Date.now();
this.deferredInit = { load: {} }; this.deferredInit = { load: {} };
this.seen = {}; this.seen = RealSet();
this.loaded = {}; this.loaded = RealSet();
modules.loaded = this.loaded; modules.loaded = this.loaded;
this.modules = modules; this.modules = modules;
@@ -258,11 +258,12 @@ overlay.overlayWindow(Object.keys(config.overlays),
} }
try { try {
if (Set.has(loaded, module.className)) if (loaded.has(module.className))
return; return;
if (Set.add(seen, module.className)) if (seen.has(module.className))
throw Error("Module dependency loop."); throw Error("Module dependency loop.");
seen.add(module.className);
for (let dep in values(module.requires)) for (let dep in values(module.requires))
this.loadModule(Module.constructors[dep], module.className); this.loadModule(Module.constructors[dep], module.className);
@@ -277,9 +278,9 @@ overlay.overlayWindow(Object.keys(config.overlays),
let obj = defineModule.time(module.className, "init", module); let obj = defineModule.time(module.className, "init", module);
Class.replaceProperty(modules, module.className, obj); Class.replaceProperty(modules, module.className, obj);
Set.add(loaded, module.className); loaded.add(module.className);
if (loaded.dactyl && obj.signals) if (loaded.has("dactyl") && obj.signals)
modules.dactyl.registerObservers(obj); modules.dactyl.registerObservers(obj);
if (!module.lazyDepends) if (!module.lazyDepends)
@@ -300,7 +301,7 @@ overlay.overlayWindow(Object.keys(config.overlays),
let className = mod.className || mod.constructor.className; let className = mod.className || mod.constructor.className;
if (!Set.has(init, className)) { if (!hasOwnProperty(init, className)) {
init[className] = function callee() { init[className] = function callee() {
function finish() { function finish() {
this.currentDependency = className; this.currentDependency = className;
@@ -324,11 +325,12 @@ overlay.overlayWindow(Object.keys(config.overlays),
let { Module, modules } = this.modules; let { Module, modules } = this.modules;
defineModule.modules.forEach((mod) => { defineModule.modules.forEach((mod) => {
let names = Set(Object.keys(mod.INIT)); let names = RealSet(Object.keys(mod.INIT));
if ("init" in mod.INIT) if ("init" in mod.INIT)
Set.add(names, "init"); names.add("init");
keys(names).forEach((name) => { this.deferInit(name, mod.INIT, mod); }); for (let name of names)
this.deferInit(name, mod.INIT, mod);
}); });
Module.list.forEach((mod) => { Module.list.forEach((mod) => {

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2011-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2011-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -45,14 +45,24 @@ var Messages = Module("messages", {
"resource://dactyl-locale-local/en-US/" + this.name + ".properties"], "resource://dactyl-locale-local/en-US/" + this.name + ".properties"],
true) true)
.map(services.stringBundle.createBundle) .map(services.stringBundle.createBundle)
.filter(function (bundle) { try { bundle.getSimpleEnumeration(); return true; } catch (e) { return false; } })), .filter(function (bundle) {
try {
bundle.getSimpleEnumeration();
return true;
}
catch (e) {
return false;
}
})),
iterate: function () { iterate: function () {
let seen = {}; let seen = RealSet();
for (let bundle in values(this.bundles)) for (let bundle in values(this.bundles))
for (let { key, value } in iter(bundle.getSimpleEnumeration(), Ci.nsIPropertyElement)) for (let { key, value } in iter(bundle.getSimpleEnumeration(), Ci.nsIPropertyElement))
if (!Set.add(seen, key)) if (!seen.has(key)) {
seen.add(key);
yield [key, value]; yield [key, value];
}
}, },
get: function get(value, default_) { get: function get(value, default_) {
@@ -139,9 +149,9 @@ var Messages = Module("messages", {
return { configurable: true, enumerable: true, value: this.default, writable: true }; return { configurable: true, enumerable: true, value: this.default, writable: true };
*/ */
if (!Set.has(obj, "localizedProperties")) if (!hasOwnProperty(obj, "localizedProperties"))
obj.localizedProperties = { __proto__: obj.localizedProperties }; obj.localizedProperties = RealSet(obj.localizedProperties);
obj.localizedProperties[prop] = true; obj.localizedProperties.add(prop);
obj[_prop] = this.default; obj[_prop] = this.default;
return { return {

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 by Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 by Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -65,7 +65,7 @@ var Option = Class("Option", {
this.globalValue = this.defaultValue; this.globalValue = this.defaultValue;
}, },
magicalProperties: Set(["cleanupValue"]), magicalProperties: RealSet(["cleanupValue"]),
/** /**
* @property {string} This option's description, as shown in :listoptions. * @property {string} This option's description, as shown in :listoptions.
@@ -329,7 +329,7 @@ var Option = Class("Option", {
let defaultValue = this._defaultValue; let defaultValue = this._defaultValue;
delete this._defaultValue; delete this._defaultValue;
if (Set.has(this.modules.config.optionDefaults, this.name)) if (hasOwnProperty(this.modules.config.optionDefaults, this.name))
defaultValue = this.modules.config.optionDefaults[this.name]; defaultValue = this.modules.config.optionDefaults[this.name];
if (defaultValue == null && this.getter) if (defaultValue == null && this.getter)
@@ -682,11 +682,11 @@ var Option = Class("Option", {
// NOTE: Vim doesn't prepend if there's a match in the current value // NOTE: Vim doesn't prepend if there's a match in the current value
return uniq(Array.concat(values, this.value), true); return uniq(Array.concat(values, this.value), true);
case "-": case "-":
return this.value.filter(function (item) !Set.has(this, item), Set(values)); return this.value.filter(function (item) !this.has(item), RealSet(values));
case "=": case "=":
if (invert) { if (invert) {
let keepValues = this.value.filter(function (item) !Set.has(this, item), Set(values)); let keepValues = this.value.filter(function (item) !this.has(item), RealSet(values));
let addValues = values.filter(function (item) !Set.has(this, item), Set(this.value)); let addValues = values.filter(function (item) !this.has(item), RealSet(this.value));
return addValues.concat(keepValues); return addValues.concat(keepValues);
} }
return values; return values;
@@ -723,7 +723,9 @@ var Option = Class("Option", {
if (isObject(vals) && !isArray(vals)) { if (isObject(vals) && !isArray(vals)) {
let k = values(completions.call(this, { values: {} })).toObject(); let k = values(completions.call(this, { values: {} })).toObject();
let v = values(completions.call(this, { value: "" })).toObject(); let v = values(completions.call(this, { value: "" })).toObject();
return Object.keys(vals).every(Set.has(k)) && values(vals).every(Set.has(v));
return Object.keys(vals).every(hasOwnProperty.bind(null, k)) &&
values(vals).every(hasOwnProperty.bind(null, v));
} }
if (this.values) if (this.values)
@@ -732,12 +734,14 @@ var Option = Class("Option", {
acceptable = completions.call(this); acceptable = completions.call(this);
if (isArray(acceptable)) if (isArray(acceptable))
acceptable = Set(acceptable.map(([k]) => (k))); acceptable = RealSet(acceptable.map(([k]) => (k)));
else
acceptable = RealSet(Object.keys(acceptable));
if (this.type === "regexpmap" || this.type === "sitemap") if (this.type === "regexpmap" || this.type === "sitemap")
return Array.concat(vals).every(re => Set.has(acceptable, re.result)); return Array.concat(vals).every(re => acceptable.has(re.result));
return Array.concat(vals).every(Set.has(acceptable)); return Array.concat(vals).every(v => acceptable.has(v));
}, },
types: {} types: {}
@@ -789,7 +793,7 @@ var OptionHive = Class("OptionHive", Contexts.Hive, {
init: function init(group) { init: function init(group) {
init.supercall(this, group); init.supercall(this, group);
this.values = {}; this.values = {};
this.has = Set.has(this.values); this.has = v => hasOwnProperty(this.values, v);
}, },
add: function add(names, description, type, defaultValue, extraInfo) { add: function add(names, description, type, defaultValue, extraInfo) {
@@ -1098,13 +1102,13 @@ var Options = Module("options", {
let list = []; let list = [];
function flushList() { function flushList() {
let names = Set(list.map(opt => opt.option ? opt.option.name : "")); let names = RealSet(list.map(opt => opt.option ? opt.option.name : ""));
if (list.length) if (list.length)
if (list.some(opt => opt.all)) if (list.some(opt => opt.all))
options.list(opt => !(list[0].onlyNonDefault && opt.isDefault), options.list(opt => !(list[0].onlyNonDefault && opt.isDefault),
list[0].scope); list[0].scope);
else else
options.list(opt => Set.has(names, opt.name), options.list(opt => names.has(opt.name),
list[0].scope); list[0].scope);
list = []; list = [];
} }
@@ -1279,12 +1283,12 @@ var Options = Module("options", {
// Fill in the current values if we're removing // Fill in the current values if we're removing
if (opt.operator == "-" && isArray(opt.values)) { if (opt.operator == "-" && isArray(opt.values)) {
let have = Set([i.text for (i in values(context.allItems.items))]); let have = RealSet((i.text for (i in values(context.allItems.items))));
context = context.fork("current-values", 0); context = context.fork("current-values", 0);
context.anchored = optcontext.anchored; context.anchored = optcontext.anchored;
context.maxItems = optcontext.maxItems; context.maxItems = optcontext.maxItems;
context.filters.push(i => !Set.has(have, i.text)); context.filters.push(i => !have.has(i.text));
modules.completion.optionValue(context, opt.name, opt.operator, null, modules.completion.optionValue(context, opt.name, opt.operator, null,
function (context) { function (context) {
context.generate = () => option.value.map(o => [o, ""]); context.generate = () => option.value.map(o => [o, ""]);
@@ -1313,7 +1317,7 @@ var Options = Module("options", {
util.assert(scope == "g:" || scope == null, util.assert(scope == "g:" || scope == null,
_("command.let.illegalVar", scope + name)); _("command.let.illegalVar", scope + name));
util.assert(Set.has(globalVariables, name) || (expr && !op), util.assert(hasOwnProperty(globalVariables, name) || (expr && !op),
_("command.let.undefinedVar", fullName)); _("command.let.undefinedVar", fullName));
if (!expr) if (!expr)
@@ -1411,7 +1415,7 @@ var Options = Module("options", {
function (args) { function (args) {
for (let [, name] in args) { for (let [, name] in args) {
name = name.replace(/^g:/, ""); // throw away the scope prefix name = name.replace(/^g:/, ""); // throw away the scope prefix
if (!Set.has(dactyl._globalVariables, name)) { if (!hasOwnProperty(dactyl._globalVariables, name)) {
if (!args.bang) if (!args.bang)
dactyl.echoerr(_("command.let.noSuch", name)); dactyl.echoerr(_("command.let.noSuch", name));
return; return;
@@ -1497,7 +1501,7 @@ var Options = Module("options", {
0); 0);
return val && val.result; return val && val.result;
} }
if (Set.has(opt.defaultValue, extra.key)) if (hasOwnProperty(opt.defaultValue, extra.key))
return obj[extra.key]; return obj[extra.key];
} }

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2009 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2009 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2009-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2009-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -247,11 +247,11 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
if (!("value" in prop) || !callable(prop.value) && !(k in item)) if (!("value" in prop) || !callable(prop.value) && !(k in item))
Object.defineProperty(item, k, prop); Object.defineProperty(item, k, prop);
let names = Set([name].concat(params.contains || []).map(e => "clear-" + e)); let names = RealSet([name].concat(params.contains || []).map(e => "clear-" + e));
if (params.action) if (params.action)
storage.addObserver("sanitizer", storage.addObserver("sanitizer",
function (key, event, arg) { function (key, event, arg) {
if (event in names) if (names.has(event))
params.action.apply(params, arg); params.action.apply(params, arg);
}, },
Class.objectGlobal(params.action)); Class.objectGlobal(params.action));
@@ -618,7 +618,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
res && !/^!/.test(res), res && !/^!/.test(res),
validator: function (values) values.length && validator: function (values) values.length &&
values.every(val => (val === "all" || Set.has(sanitizer.itemMap, val.replace(/^!/, "")))) values.every(val => (val === "all" || hasOwnProperty(sanitizer.itemMap, val.replace(/^!/, ""))))
}); });
options.add(["sanitizeshutdown", "ss"], options.add(["sanitizeshutdown", "ss"],
@@ -636,10 +636,10 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
sanitizer.runAtShutdown = false; sanitizer.runAtShutdown = false;
else { else {
sanitizer.runAtShutdown = true; sanitizer.runAtShutdown = true;
let have = Set(value); let have = RealSet(value);
for (let item in values(sanitizer.itemMap)) for (let item in values(sanitizer.itemMap))
prefs.set(item.shutdownPref, prefs.set(item.shutdownPref,
Boolean(Set.has(have, item.name) ^ Set.has(have, "all"))); Boolean(have.has(item.name) ^ have.has("all")));
} }
return value; return value;
} }

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -206,7 +206,7 @@ var Services = Module("Services", {
* *
* @param {string} name The service's cache key. * @param {string} name The service's cache key.
*/ */
has: function has(name) Set.has(this.services, name) && this.services[name].class in Cc && has: function has(name) hasOwnProperty(this.services, name) && this.services[name].class in Cc &&
this.services[name].interfaces.every(iface => iface in Ci) this.services[name].interfaces.every(iface => iface in Ci)
}); });

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -261,7 +261,7 @@ var Styles = Module("Styles", {
update(services["dactyl:"].providers, { update(services["dactyl:"].providers, {
"style": function styleProvider(uri, path) { "style": function styleProvider(uri, path) {
let id = parseInt(path); let id = parseInt(path);
if (Set.has(styles.allSheets, id)) if (hasOwnProperty(styles.allSheets, id))
return ["text/css", styles.allSheets[id].fullCSS]; return ["text/css", styles.allSheets[id].fullCSS];
return null; return null;
} }

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail> // Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -106,7 +106,7 @@ var Template = Module("Template", {
"click": function onClick(event) { "click": function onClick(event) {
event.preventDefault(); event.preventDefault();
if (this.commandAllowed) { if (this.commandAllowed) {
if (Set.has(this.target.commands || {}, this.command)) if (hasOwnProperty(this.target.commands || {}, this.command))
this.target.commands[this.command].call(this.target); this.target.commands[this.command].call(this.target);
else else
this.target.command(this.command); this.target.command(this.command);
@@ -115,7 +115,7 @@ var Template = Module("Template", {
}, },
get commandAllowed() { get commandAllowed() {
if (Set.has(this.target.allowedCommands || {}, this.command)) if (hasOwnProperty(this.target.allowedCommands || {}, this.command))
return this.target.allowedCommands[this.command]; return this.target.allowedCommands[this.command];
if ("commandAllowed" in this.target) if ("commandAllowed" in this.target)
return this.target.commandAllowed(this.command); return this.target.commandAllowed(this.command);
@@ -140,7 +140,7 @@ var Template = Module("Template", {
let obj = params.eventTarget; let obj = params.eventTarget;
let events = obj[this.getAttribute("events") || "events"]; let events = obj[this.getAttribute("events") || "events"];
if (Set.has(events, "input")) if (hasOwnProperty(events, "input"))
events["dactyl-input"] = events["input"]; events["dactyl-input"] = events["input"];
for (let [event, handler] in Iterator(events)) for (let [event, handler] in Iterator(events))
@@ -219,7 +219,7 @@ var Template = Module("Template", {
else if (/^n_/.test(topic)) else if (/^n_/.test(topic))
topic = topic.slice(2); topic = topic.slice(2);
if (help.initialized && !Set.has(help.tags, topic)) if (help.initialized && !hasOwnProperty(help.tags, topic))
return ["span", { highlight: type || ""}, text || token]; return ["span", { highlight: type || ""}, text || token];
type = type || (/^'.*'$/.test(token) ? "HelpOpt" : type = type || (/^'.*'$/.test(token) ? "HelpOpt" :
@@ -241,7 +241,7 @@ var Template = Module("Template", {
else if (/^n_/.test(topic)) else if (/^n_/.test(topic))
topic = topic.slice(2); topic = topic.slice(2);
if (help.initialized && !Set.has(help.tags, topic)) if (help.initialized && !hasOwnProperty(help.tags, topic))
return token; return token;
let tag = (/^'.*'$/.test(token) ? "o" : let tag = (/^'.*'$/.test(token) ? "o" :

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com> // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2013 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -138,7 +138,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
let cleanup = ["dactyl-cleanup-modules", "quit-application"]; let cleanup = ["dactyl-cleanup-modules", "quit-application"];
function register(meth) { function register(meth) {
for (let target in Set(cleanup.concat(Object.keys(obj.observers)))) for (let target of RealSet(cleanup.concat(Object.keys(obj.observers))))
try { try {
services.observer[meth](obj, target, true); services.observer[meth](obj, target, true);
} }
@@ -354,7 +354,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
: "", : "",
{ {
elements: [], elements: [],
seen: {}, seen: RealSet(),
valid: function valid(obj) this.elements.every(e => (!e.test || e.test(obj))) valid: function valid(obj) this.elements.every(e => (!e.test || e.test(obj)))
}); });
@@ -387,15 +387,15 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
else { else {
let [, flags, name] = /^((?:[a-z]-)*)(.*)/.exec(macro); let [, flags, name] = /^((?:[a-z]-)*)(.*)/.exec(macro);
flags = Set(flags); flags = RealSet(flags);
let quote = util.identity; let quote = util.identity;
if (flags.q) if (flags.has("q"))
quote = function quote(obj) typeof obj === "number" ? obj : String.quote(obj); quote = function quote(obj) typeof obj === "number" ? obj : String.quote(obj);
if (flags.e) if (flags.has("e"))
quote = function quote(obj) ""; quote = function quote(obj) "";
if (Set.has(defaults, name)) if (hasOwnProperty(defaults, name))
stack.top.elements.push(quote(defaults[name])); stack.top.elements.push(quote(defaults[name]));
else { else {
let index = idx; let index = idx;
@@ -403,7 +403,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
idx = Number(idx) - 1; idx = Number(idx) - 1;
stack.top.elements.push(update( stack.top.elements.push(update(
obj => obj[name] != null && idx in obj[name] ? quote(obj[name][idx]) obj => obj[name] != null && idx in obj[name] ? quote(obj[name][idx])
: Set.has(obj, name) ? "" : unknown(full), : hasOwnProperty(obj, name) ? "" : unknown(full),
{ {
test: function test(obj) obj[name] != null && idx in obj[name] test: function test(obj) obj[name] != null && idx in obj[name]
&& obj[name][idx] !== false && obj[name][idx] !== false
@@ -413,7 +413,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
else { else {
stack.top.elements.push(update( stack.top.elements.push(update(
obj => obj[name] != null ? quote(obj[name]) obj => obj[name] != null ? quote(obj[name])
: Set.has(obj, name) ? "" : unknown(full), : hasOwnProperty(obj, name) ? "" : unknown(full),
{ {
test: function test(obj) obj[name] != null test: function test(obj) obj[name] != null
&& obj[name] !== false && obj[name] !== false
@@ -422,7 +422,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
for (let elem in array.iterValues(stack)) for (let elem in array.iterValues(stack))
elem.seen[name] = true; elem.seen.add(name);
} }
} }
} }
@@ -757,7 +757,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
try { try {
let xmlhttp = services.Xmlhttp(); let xmlhttp = services.Xmlhttp();
xmlhttp.mozBackgroundRequest = Set.has(params, "background") ? params.background : true; xmlhttp.mozBackgroundRequest = hasOwnProperty(params, "background") ? params.background : true;
let async = params.callback || params.onload || params.onerror; let async = params.callback || params.onload || params.onerror;
if (async) { if (async) {
@@ -1255,10 +1255,10 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
// Replace replacement <tokens>. // Replace replacement <tokens>.
if (tokens) if (tokens)
expr = String.replace(expr, /(\(?P)?<(\w+)>/g, expr = String.replace(expr, /(\(?P)?<(\w+)>/g,
(m, n1, n2) => !n1 && Set.has(tokens, n2) ? tokens[n2].dactylSource (m, n1, n2) => !n1 && hasOwnProperty(tokens, n2) ? tokens[n2].dactylSource
|| tokens[n2].source || tokens[n2].source
|| tokens[n2] || tokens[n2]
: m); : m);
// Strip comments and white space. // Strip comments and white space.
if (/x/.test(flags)) if (/x/.test(flags))