1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 22:47:59 +01:00

ES6-ify some things. Still a long way to go...

This commit is contained in:
Kris Maglione
2015-12-20 02:02:54 -08:00
parent 65725c9516
commit 27cdeb1885
28 changed files with 411 additions and 303 deletions

View File

@@ -366,23 +366,21 @@ var Abbreviations = Module("abbreviations", {
} }
], ],
serialize: function () { serialize: function () {
return Ary(abbreviations.userHives) return abbreviations.userHives
.filter(h => h.persist) .filter(h => h.persist)
.map(hive => [ .flatMap(hive =>
{ hive.merged
command: this.name, .filter(abbr => abbr.modesEqual(modes))
arguments: [abbr.lhs], .map(abbr => ({
literalArg: abbr.rhs, command: this.name,
options: { arguments: [abbr.lhs],
"-group": hive.name == "user" ? undefined : hive.name, literalArg: abbr.rhs,
"-javascript": callable(abbr.rhs) ? null : undefined options: {
} "-group": hive.name == "user" ? undefined : hive.name,
} "-javascript": callable(abbr.rhs) ? null : undefined
for (abbr of hive.merged) }
if (abbr.modesEqual(modes)) })));
]). },
flatten().array;
}
}); });
commands.add([ch + "una[bbreviate]"], commands.add([ch + "una[bbreviate]"],

View File

@@ -436,10 +436,9 @@ var Bookmarks = Module("bookmarks", {
names: ["-tags", "-T"], names: ["-tags", "-T"],
description: "A comma-separated list of tags", description: "A comma-separated list of tags",
completer: function tags(context) { completer: function tags(context) {
context.generate = () => Ary(b.tags context.generate = () => new RealSet(Array.from(bookmarkcache)
for (b of bookmarkcache) .flatMap(b.tags));
if (b.tags))
.flatten().uniq().array;
context.keys = { text: identity, description: identity }; context.keys = { text: identity, description: identity };
}, },
type: CommandOption.LIST type: CommandOption.LIST

View File

@@ -243,12 +243,12 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
{ argCount: "0" }); { argCount: "0" });
}, },
mappings: function initMappings(dactyl, modules, window) { mappings: function initMappings(dactyl, modules, window) {
let openModes = Ary.toObject([ let openModes = {
[dactyl.CURRENT_TAB, ""], [dactyl.CURRENT_TAB]: "",
[dactyl.NEW_TAB, "tab"], [dactyl.NEW_TAB]: "tab",
[dactyl.NEW_BACKGROUND_TAB, "background tab"], [dactyl.NEW_BACKGROUND_TAB]: "background tab",
[dactyl.NEW_WINDOW, "win"] [dactyl.NEW_WINDOW]: "win",
]); };
function open(mode, args) { function open(mode, args) {
if (dactyl.forceTarget in openModes) if (dactyl.forceTarget in openModes)

View File

@@ -240,8 +240,8 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
let name = commands.add(params.name, params.description, let name = commands.add(params.name, params.description,
function (args) { function (args) {
let results = Ary(params.iterate(args)) let results = Array.from(params.iterate(args))
.sort((a, b) => String.localeCompare(a.name, b.name)); .sort((a, b) => String.localeCompare(a.name, b.name));
let filters = args.map(arg => { let filters = args.map(arg => {
let re = util.regexp.escape(arg); let re = util.regexp.escape(arg);
@@ -261,22 +261,24 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
return seen[this.text] + /*L*/" matching items"; return seen[this.text] + /*L*/" matching items";
}; };
context.ignoreCase = true; context.ignoreCase = true;
let seen = {}; let seen = {};
context.completions = Ary(keys(item).join(" ").toLowerCase().split(/[()\s]+/) context.completions = new RealSet(
for (item of params.iterate(args))) Array.from(params.iterate(args))
.flatten() .flatMap(item => Object.keys(item).join(" ")
.map(function (k) { .toLowerCase().split(/[()\s]+/))
seen[k] = (seen[k] || 0) + 1; .map(k => {
return k; seen[k] = (seen[k] || 0) + 1;
}).uniq(); return k;
}));
}, },
options: params.options || [] options: params.options || []
}); });
if (params.index) if (params.index)
this.indices[params.index] = function* () { this.indices[params.index] = function* () {
let results = Ary((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs())) let results = Array.from((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs()))
.array.sort((a, b) => String.localeCompare(a.name, b.name)); .sort((a, b) => String.localeCompare(a.name, b.name));
for (let obj of results) { for (let obj of results) {
let res = dactyl.generateHelp(obj, null, null, true); let res = dactyl.generateHelp(obj, null, null, true);
@@ -646,7 +648,6 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* Initialize the help system. * Initialize the help system.
*/ */
initHelp: function initHelp() { initHelp: function initHelp() {
util.dumpStack('INIT HELP');
if ("noscriptOverlay" in window) if ("noscriptOverlay" in window)
window.noscriptOverlay.safeAllow("dactyl:", true, false); window.noscriptOverlay.safeAllow("dactyl:", true, false);
@@ -1415,11 +1416,13 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
// FIXME: cleanup // FIXME: cleanup
cleanupValue: config.cleanups.guioptions || cleanupValue: config.cleanups.guioptions ||
"rb" + [k for ([k, v] of iter(groups[1].opts)) "rb" + Object.entries(groups[1].opts)
if (!Dactyl.isToolbarHidden(document.getElementById(v[1][0])))].join(""), .filter(([k, v]) => !Dactyl.isToolbarHidden(document.getElementById(v[1][0])))
.map(([k]) => k)
.join(""),
values: Ary(groups).map(g => [[k, v[0]] for ([k, v] of iter(g.opts))]) values: groups.flatMap(g => Object.entries(g.opts)
.flatten(), .map(([k, v]) => [k, v[0]])),
setter: function (value) { setter: function (value) {
for (let group of groups) for (let group of groups)

View File

@@ -23,10 +23,10 @@ var EventHive = Class("EventHive", Contexts.Hive, {
}, },
_events: function _events(event, callback) { _events: function _events(event, callback) {
if (!isObject(event)) if (isObject(event))
var [self, events] = [null, Ary.toObject([[event, callback]])]; var [self, events] = [event, event[callback || "events"]];
else else
[self, events] = [event, event[callback || "events"]]; [self, events] = [null, { [event]: callback }];
if (hasOwnProp(events, "input") && !hasOwnProp(events, "dactyl-input")) if (hasOwnProp(events, "input") && !hasOwnProp(events, "dactyl-input"))
events["dactyl-input"] = events.input; events["dactyl-input"] = events.input;
@@ -1141,7 +1141,7 @@ var Events = Module("events", {
return this.value.filter(f => f(buffer.documentURI)); return this.value.filter(f => f(buffer.documentURI));
}); });
memoize(this, "pass", function () { memoize(this, "pass", function () {
return new RealSet(Ary.flatten(this.filters.map(f => f.keys))); return new RealSet(this.filters.flatMap(f => f.keys));
}); });
memoize(this, "commandHive", function hive() { memoize(this, "commandHive", function hive() {
return Hive(this.filters, "command"); return Hive(this.filters, "command");

View File

@@ -1379,7 +1379,8 @@ var Hints = Module("hints", {
}, },
validator: function (value) { validator: function (value) {
let values = DOM.Event.parse(value).map(DOM.Event.bound.stringify); let values = DOM.Event.parse(value).map(DOM.Event.bound.stringify);
return Option.validIf(Ary.uniq(values).length === values.length && values.length > 1,
return Option.validIf(new RealSet(values).size === values.length && values.length > 1,
_("option.hintkeys.duplicate")); _("option.hintkeys.duplicate"));
} }
}); });

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-2014 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2008-2015 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.
@@ -290,7 +290,7 @@ var History = Module("history", {
description: "The sort order of the results", description: "The sort order of the results",
completer: function (context) { completer: function (context) {
context.compare = CompletionContext.Sort.unsorted; context.compare = CompletionContext.Sort.unsorted;
return Ary.flatten([ return [
"annotation", "annotation",
"date", "date",
"date added", "date added",
@@ -300,10 +300,10 @@ var History = Module("history", {
"title", "title",
"uri", "uri",
"visitcount" "visitcount"
].map(order => [ ].flatMap(order => [
["+" + order.replace(" ", ""), /*L*/"Sort by " + order + " ascending"], ["+" + order.replace(" ", ""), /*L*/"Sort by " + order + " ascending"],
["-" + order.replace(" ", ""), /*L*/"Sort by " + order + " descending"] ["-" + order.replace(" ", ""), /*L*/"Sort by " + order + " descending"]
])); ]);
} }
} }
], ],

View File

@@ -17,7 +17,9 @@ var ProcessorStack = Class("ProcessorStack", {
events.dbg("STACK " + mode); events.dbg("STACK " + mode);
let main = { __proto__: mode.main, params: mode.params }; let main = { __proto__: mode.main, params: mode.params };
this.modes = Ary([mode.params.keyModes, main, mode.main.allBases.slice(1)]).flatten().compact(); this.modes = Ary([mode.params.keyModes,
main,
mode.main.allBases.slice(1)]).flatten().compact();
if (builtin) if (builtin)
hives = hives.filter(h => h.name === "builtin"); hives = hives.filter(h => h.name === "builtin");

View File

@@ -116,7 +116,7 @@ var Map = Class("Map", {
return this.keys.indexOf(name) >= 0; return this.keys.indexOf(name) >= 0;
}, },
get keys() { return Ary.flatten(this.names.map(mappings.bound.expand)); }, get keys() { return this.names.flatMap(mappings.bound.expand); },
/** /**
* Execute the action for this mapping. * Execute the action for this mapping.
@@ -404,7 +404,7 @@ var Mappings = Module("mappings", {
iterate: function* (mode) { iterate: function* (mode) {
let seen = new RealSet; let seen = new RealSet;
for (let hive of this.hives.iterValues()) for (let hive of this.hives.iterValues())
for (let map of Ary.iterValues(hive.getStack(mode))) for (let map of hive.getStack(mode))
if (!seen.add(map.name)) if (!seen.add(map.name))
yield map; yield map;
}, },
@@ -646,26 +646,24 @@ var Mappings = Module("mappings", {
if (this.name != "map") if (this.name != "map")
return []; return [];
else else
return Ary(mappings.userHives) return mappings.userHives
.filter(h => h.persist) .filter(h => h.persist)
.map(hive => [ .flatMap(hive =>
{ Array.from(userMappings(hive))
command: "map", .filter(map => map.persist)
options: { .map(map => ({
"-count": map.count ? null : undefined, command: "map",
"-description": map.description, options: {
"-group": hive.name == "user" ? undefined : hive.name, "-count": map.count ? null : undefined,
"-modes": uniqueModes(map.modes), "-description": map.description,
"-silent": map.silent ? null : undefined "-group": hive.name == "user" ? undefined : hive.name,
}, "-modes": uniqueModes(map.modes),
arguments: [map.names[0]], "-silent": map.silent ? null : undefined
literalArg: map.rhs, },
ignoreDefaults: true arguments: [map.names[0]],
} literalArg: map.rhs,
for (map of userMappings(hive)) ignoreDefaults: true
if (map.persist) })));
])
.flatten().array;
} }
}; };
function* userMappings(hive) { function* userMappings(hive) {
@@ -731,9 +729,11 @@ var Mappings = Module("mappings", {
return Array.concat(value).every(findMode); return Array.concat(value).every(findMode);
}, },
completer: function () { completer: function () {
return [[Ary.compact([mode.name.toLowerCase().replace(/_/g, "-"), mode.char]), mode.description] return modes.all.filter(mode => !mode.hidden)
for (mode of modes.all) .map(
if (!mode.hidden)]; mode => [Ary.compact([mode.name.toLowerCase().replace(/_/g, "-"),
mode.char]),
mode.description]);
} }
}; };

View File

@@ -685,8 +685,10 @@ var Modes = Module("modes", {
}, },
get values() { get values() {
return Ary.toObject([[m.name.toLowerCase(), m.description] return Ary.toObject(
for (m of modes._modes) if (!m.hidden)]); modes._modes.filter(mode => !mode.hidden)
.map(mode => [mode.name.toLowerCase(),
mode.description]));
} }
}; };

View File

@@ -186,7 +186,6 @@ defineModule("base", {
"Set", "Set",
"Struct", "Struct",
"StructBase", "StructBase",
"Symbol",
"TextEncoder", "TextEncoder",
"TextDecoder", "TextDecoder",
"Timer", "Timer",
@@ -217,6 +216,7 @@ defineModule("base", {
"iterOwnProperties", "iterOwnProperties",
"keys", "keys",
"literal", "literal",
"loadPolyfill",
"memoize", "memoize",
"module", "module",
"octal", "octal",
@@ -228,6 +228,12 @@ defineModule("base", {
] ]
}); });
function loadPolyfill(obj) {
JSMLoader.loadSubScript("resource://dactyl/polyfill.jsm",
obj);
}
loadPolyfill(this);
this.lazyRequire("cache", ["cache"]); this.lazyRequire("cache", ["cache"]);
this.lazyRequire("config", ["config"]); this.lazyRequire("config", ["config"]);
this.lazyRequire("messages", ["_", "Messages"]); this.lazyRequire("messages", ["_", "Messages"]);
@@ -236,11 +242,6 @@ this.lazyRequire("services", ["services"]);
this.lazyRequire("storage", ["File"]); this.lazyRequire("storage", ["File"]);
this.lazyRequire("util", ["FailedAssertion", "util"]); this.lazyRequire("util", ["FailedAssertion", "util"]);
if (typeof Symbol == "undefined")
this.Symbol = {
iterator: "@@iterator"
};
let literal_ = function literal(comment) { let literal_ = function literal(comment) {
if (comment) if (comment)
return /^function.*?\/\*([^]*)\*\/(?:\/\* use strict \*\/)\s*\S$/.exec(comment)[1]; return /^function.*?\/\*([^]*)\*\/(?:\/\* use strict \*\/)\s*\S$/.exec(comment)[1];
@@ -1203,34 +1204,19 @@ for (let name of properties(Class.prototype)) {
} }
var closureHooks = { var closureHooks = {
get: function closure_get(target, prop) { get(target, prop) {
if (hasOwnProp(target._closureCache, prop)) if (prop in target._closureCache)
return target._closureCache[prop]; return target._closureCache[prop];
let p = target[prop]; let p = target[prop];
if (callable(p)) if (callable(p))
return target._closureCache[prop] = p.bind(target); return target._closureCache[prop] = p.bind(target);
return p; return p;
}
/*
getOwnPropertyNames: function getOwnPropertyNames(target) {
return [k for (k in properties(target, true))];
}, },
getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, prop) {
let self = this;
return {
configurable: false,
writable: false,
get value() { return self.get(target, prop); }
}
}
*/
}; };
Class.makeClosure = function makeClosure() { Class.makeClosure = function makeClosure() {
this._closureCache = {}; this._closureCache = Object.create(null);
return new Proxy(this, closureHooks); return new Proxy(this, closureHooks);
}; };
@@ -1402,7 +1388,7 @@ function Struct(...args) {
const Struct = Class(className || "Struct", StructBase, { const Struct = Class(className || "Struct", StructBase, {
length: args.length, length: args.length,
members: Ary(args).map((v, k) => [v, k]).toObject() members: Ary.toObject(args.map((v, k) => [v, k])),
}); });
args.forEach(function (name, i) { args.forEach(function (name, i) {
Struct.prototype.__defineGetter__(name, function () { Struct.prototype.__defineGetter__(name, function () {
@@ -1617,12 +1603,12 @@ function iter(obj, iface) {
else if (Symbol.iterator in obj) else if (Symbol.iterator in obj)
res = obj[Symbol.iterator](); res = obj[Symbol.iterator]();
else if (isinstance(obj, [Ci.nsIDOMHTMLCollection, Ci.nsIDOMNodeList])) else if (isinstance(obj, [Ci.nsIDOMHTMLCollection, Ci.nsIDOMNodeList]))
res = Ary.iterItems(obj); res = Array.from(obj).entries();
else if (ctypes && ctypes.CData && obj instanceof ctypes.CData) { else if (ctypes && ctypes.CData && obj instanceof ctypes.CData) {
while (obj.constructor instanceof ctypes.PointerType) while (obj.constructor instanceof ctypes.PointerType)
obj = obj.contents; obj = obj.contents;
if (obj.constructor instanceof ctypes.ArrayType) if (obj.constructor instanceof ctypes.ArrayType)
res = Ary.iterItems(obj); res = Array.from(obj).entries();
else if (obj.constructor instanceof ctypes.StructType) else if (obj.constructor instanceof ctypes.StructType)
res = (function* () { res = (function* () {
for (let prop of obj.constructor.fields) { for (let prop of obj.constructor.fields) {
@@ -1664,14 +1650,14 @@ function iter(obj, iface) {
} }
if (res === undefined) if (res === undefined)
res = Iterator(obj)[Symbol.iterator](); res = Object.entries(obj).values();
return Iter(res); return Iter(res);
} }
update(iter, { update(iter, {
toArray: function toArray(iter) { toArray: deprecated("Array.from", function toArray(iter) {
return Ary(iter).array; return Array.from(iter);
}, }),
// See Ary.prototype for API docs. // See Ary.prototype for API docs.
toObject: function toObject(iter) { toObject: function toObject(iter) {
@@ -1939,10 +1925,10 @@ var Ary = Class("Ary", Array, {
* @param {Array} ary * @param {Array} ary
* @returns {Iterator(Object)} * @returns {Iterator(Object)}
*/ */
iterValues: function* iterValues(ary) { iterValues: deprecated("Array#values", function* iterValues(ary) {
for (let i = 0; i < ary.length; i++) for (let i = 0; i < ary.length; i++)
yield ary[i]; yield ary[i];
}, }),
/** /**
* Returns an Iterator for an array's indices and values. * Returns an Iterator for an array's indices and values.
@@ -1950,11 +1936,11 @@ var Ary = Class("Ary", Array, {
* @param {Array} ary * @param {Array} ary
* @returns {Iterator([{number}, {Object}])} * @returns {Iterator([{number}, {Object}])}
*/ */
iterItems: function* iterItems(ary) { iterItems: deprecated("Array#entries", function* iterItems(ary) {
let length = ary.length; let length = ary.length;
for (let i = 0; i < length; i++) for (let i = 0; i < length; i++)
yield [i, ary[i]]; yield [i, ary[i]];
}, }),
/** /**
* Returns the nth member of the given array that matches the * Returns the nth member of the given array that matches the

View File

@@ -94,9 +94,12 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), {
bookmarks: Class.Memoize(function () { return this.load(); }), bookmarks: Class.Memoize(function () { return this.load(); }),
keywords: Class.Memoize(function () { keywords: Class.Memoize(function () {
return Ary.toObject([[b.keyword, b] let res = {};
for (b of this) for (let bookmark of this)
if (b.keyword)]); if (bookmark.keyword)
res[bookmark.keyword] = res;
return res;
}), }),
rootFolders: ["toolbarFolder", "bookmarksMenuFolder", "unfiledBookmarksFolder"] rootFolders: ["toolbarFolder", "bookmarksMenuFolder", "unfiledBookmarksFolder"]

View File

@@ -58,8 +58,8 @@ var Buffer = Module("Buffer", {
* buffer. Only returns style sheets for the 'screen' media type. * buffer. Only returns style sheets for the 'screen' media type.
*/ */
get alternateStyleSheets() { get alternateStyleSheets() {
let stylesheets = Ary.flatten( let stylesheets = this.allFrames()
this.allFrames().map(w => Array.slice(w.document.styleSheets))); .flatMap(w => w.document.styleSheets);
return stylesheets.filter( return stylesheets.filter(
s => /^(screen|all|)$/i.test(s.media.mediaText) && !/^\s*$/.test(s.title) s => /^(screen|all|)$/i.test(s.media.mediaText) && !/^\s*$/.test(s.title)
@@ -415,11 +415,12 @@ var Buffer = Module("Buffer", {
* Returns a list of all frames in the given window or current buffer. * Returns a list of all frames in the given window or current buffer.
*/ */
allFrames: function allFrames(win=this.win, focusedFirst) { allFrames: function allFrames(win=this.win, focusedFirst) {
let frames = iter(util.iterFrames(win)).toArray(); let frames = Array.from(util.iterFrames(win));
if (focusedFirst) if (focusedFirst) {
return frames.filter(f => f === this.focusedFrame).concat( let focused = this.focusedFrame;
frames.filter(f => f !== this.focusedFrame)); return frames.sort((a, b) => (b === focused) - (a === focused));
}
return frames; return frames;
}, },
@@ -2415,8 +2416,10 @@ var Buffer = Module("Buffer", {
let frames = buffer.allFrames(undefined, true); let frames = buffer.allFrames(undefined, true);
let elements = Ary.flatten(frames.map(win => [m for (m of DOM.XPath(xpath, win.document))])) let elements = Array.from(frames)
.filter(function (elem) { .flatMap(win => DOM.XPath(xpath, win.document))
.filter(elem => {
if (isinstance(elem, [Ci.nsIDOMHTMLFrameElement, if (isinstance(elem, [Ci.nsIDOMHTMLFrameElement,
Ci.nsIDOMHTMLIFrameElement])) Ci.nsIDOMHTMLIFrameElement]))
return Editor.getEditor(elem.contentWindow); return Editor.getEditor(elem.contentWindow);
@@ -2428,9 +2431,11 @@ var Buffer = Module("Buffer", {
let style = elem.style; let style = elem.style;
let rect = elem.rect; let rect = elem.rect;
return elem.isVisible && return elem.isVisible &&
(elem[0] instanceof Ci.nsIDOMXULTextBoxElement || style.MozUserFocus != "ignore") && (elem[0] instanceof Ci.nsIDOMXULTextBoxElement ||
rect.width && rect.height; style.MozUserFocus != "ignore") &&
rect.width && rect.height;
}); });
dactyl.assert(elements.length > 0); dactyl.assert(elements.length > 0);

View File

@@ -251,7 +251,7 @@ var Command = Class("Command", {
/** @property {[string]} All of this command's long and short names. */ /** @property {[string]} All of this command's long and short names. */
names: Class.Memoize(function () { names: Class.Memoize(function () {
return this.names = Ary.flatten(this.parsedSpecs); return this.parsedSpecs.flatMap();
}), }),
/** @property {string} This command's description, as shown in :listcommands */ /** @property {string} This command's description, as shown in :listcommands */
@@ -330,9 +330,9 @@ var Command = Class("Command", {
_options: [], _options: [],
optionMap: Class.Memoize(function () { optionMap: Class.Memoize(function () {
return Ary(this.options) return Ary.toObject(
.map(opt => opt.names.map(name => [name, opt])) Array.from(this.options)
.flatten().toObject(); .flatMap(opt => opt.names.map(name => [name, opt])));
}), }),
newArgs: function newArgs(base) { newArgs: function newArgs(base) {
@@ -456,7 +456,7 @@ var Command = Class("Command", {
* @returns {Array} * @returns {Array}
*/ */
parseSpecs: function parseSpecs(specs) { parseSpecs: function parseSpecs(specs) {
return specs.map(function (spec) { return specs.map(spec => {
let [, head, tail] = /([^[]+)(?:\[(.*)])?/.exec(spec); let [, head, tail] = /([^[]+)(?:\[(.*)])?/.exec(spec);
return tail ? [head + tail, head] : [head]; return tail ? [head + tail, head] : [head];
}); });
@@ -498,8 +498,9 @@ var Ex = Module("Ex", {
args = Array.slice(args); args = Array.slice(args);
let res = cmd.newArgs({ context: this.context }); let res = cmd.newArgs({ context: this.context });
if (isObject(args[0])) if (isObject(args[0]))
for (let [k, v] of iter(args.shift())) for (let [k, v] of Object.entries(args.shift()))
if (k == "!") if (k == "!")
res.bang = v; res.bang = v;
else if (k == "#") else if (k == "#")
@@ -515,8 +516,9 @@ var Ex = Module("Ex", {
res.explicitOpts[opt.names[0]] = val; res.explicitOpts[opt.names[0]] = val;
} }
for (let [i, val] of Ary.iterItems(args)) for (let [i, val] of args.entries())
res[i] = String(val); res[i] = String(val);
return res; return res;
}, },
@@ -593,7 +595,9 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
if (this.cached) if (this.cached)
this.modules.initDependencies("commands"); this.modules.initDependencies("commands");
this.cached = false; this.cached = false;
return Ary.iterValues(this._list.sort((a, b) => a.name > b.name));
return this._list.sort((a, b) => String.localeCompare(a.name, b.name))
.values();
}, },
/** @property {string} The last executed Ex command line. */ /** @property {string} The last executed Ex command line. */
@@ -623,7 +627,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
extra.hive = this; extra.hive = this;
extra.parsedSpecs = Command.parseSpecs(specs); extra.parsedSpecs = Command.parseSpecs(specs);
let names = Ary.flatten(extra.parsedSpecs); let names = extra.parsedSpecs.flatMap();
let name = names[0]; let name = names[0];
if (this.name != "builtin") { if (this.name != "builtin") {
@@ -934,10 +938,10 @@ var Commands = Module("commands", {
let defaults = {}; let defaults = {};
if (args.ignoreDefaults) if (args.ignoreDefaults)
defaults = Ary(this.options).map(opt => [opt.names[0], opt.default]) defaults = Ary.toObject(Array.from(this.options,
.toObject(); opt => [opt.names[0], opt.default]));
for (let [opt, val] of iter(args.options || {})) { for (let [opt, val] of Object.entries(args.options || {})) {
if (val === undefined) if (val === undefined)
continue; continue;
if (val != null && defaults[opt] === val) if (val != null && defaults[opt] === val)
@@ -1788,28 +1792,32 @@ var Commands = Module("commands", {
literal: 1, literal: 1,
serialize: function () { serialize: function () {
return Ary(commands.userHives) return commands.userHives
.filter(h => h.persist) .filter(h => h.persist)
.map(hive => [ .flatMap(hive =>
{ Array.from(hive)
.filter(cmd => cmd.persist)
.map(cmd =>
({
command: this.name, command: this.name,
bang: true, bang: true,
options: iter([v, typeof cmd[k] == "boolean" ? null : cmd[k]] options: Ary.toObject(
// FIXME: this map is expressed multiple times Object.entries({
for ([k, v] of iter({ argCount: "-nargs",
argCount: "-nargs", bang: "-bang",
bang: "-bang", count: "-count",
count: "-count", description: "-description",
description: "-description" })
})) .filter(([k, v]) => cmd[k])
if (cmd[k])).toObject(), .map(([k, v]) => [
v,
typeof cmd[k] == "boolean" ? null : cmd[k]
])),
arguments: [cmd.name], arguments: [cmd.name],
literalArg: cmd.action, literalArg: cmd.action,
ignoreDefaults: true ignoreDefaults: true
} }))
for (cmd of hive) if (cmd.persist) );
])
.flatten().array;
} }
}); });

View File

@@ -284,17 +284,17 @@ var CompletionContext = Class("CompletionContext", {
get longestSubstring() { return self.longestAllSubstring; }, get longestSubstring() { return self.longestAllSubstring; },
get items() { get items() {
return Ary.flatten(self.activeContexts.map(function m(context) { return self.activeContexts.flatMap(context => {
let prefix = self.value.substring(minStart, context.offset); let prefix = self.value.substring(minStart, context.offset);
return context.items.map(function m(item) { return context.items.map(item => {
return { return {
text: prefix + item.text, text: prefix + item.text,
result: prefix + item.result, result: prefix + item.result,
__proto__: item __proto__: item
}; };
}); });
})); });
} }
}); });
@@ -323,24 +323,23 @@ var CompletionContext = Class("CompletionContext", {
* Possibly. * Possibly.
*/ */
let substrings = lists.reduce( let substrings = lists.reduce(
function r(res, list) { (res, list) => {
return res.filter(function f(str) { return res.filter(str => {
return list.some(function s_(s) { return list.some(s => s.substr(0, str.length) == str);
return s.substr(0, str.length) == str;
});
}); });
}, },
lists.pop()); lists.pop());
if (!substrings) // FIXME: How is this undefined? if (!substrings) // FIXME: How is this undefined?
return []; return [];
return Ary.uniq(Array.slice(substrings)); return Ary.uniq(Array.slice(substrings));
}, },
// Temporary // Temporary
get longestAllSubstring() { get longestAllSubstring() {
return this.allSubstrings.reduce(function r(a, b) { return this.allSubstrings.reduce(function r(a, b) {
return a.length > b.length ? a : b, ""; return a.length > b.length ? a : b;
}); }, "");
}, },
get caret() { return this._caret - this.offset; }, get caret() { return this._caret - this.offset; },

View File

@@ -235,20 +235,19 @@ var ConfigBase = Class("ConfigBase", {
let uri = "resource://dactyl-locale/"; let uri = "resource://dactyl-locale/";
let jar = io.isJarURL(uri); let jar = io.isJarURL(uri);
let res;
if (jar) { if (jar) {
let prefix = getDir(jar.JAREntry); let prefix = getDir(jar.JAREntry);
var res = iter(s.slice(prefix.length).replace(/\/.*/, "") res = Array.from(io.listJar(jar.JARFile, prefix),
for (s of io.listJar(jar.JARFile, prefix))) s => slice(prefix.length).replace(/\/.*/, ""));
.toArray();
} }
else { else {
res = Ary(f.leafName res = Array.from(util.getFile(uri).readDirectory())
// Fails on FF3: for (f of util.getFile(uri).iterDirectory()) .filter(f => f.isDirectory())
for (f of util.getFile(uri).readDirectory()) .map(f => f.leafName);
if (f.isDirectory())).array;
} }
let exists = function exists(pkg) { let exists = pkg => {
return services["resource:"].hasSubstitution("dactyl-locale-" + pkg); return services["resource:"].hasSubstitution("dactyl-locale-" + pkg);
}; };
@@ -265,9 +264,14 @@ var ConfigBase = Class("ConfigBase", {
* @returns {string} * @returns {string}
*/ */
bestLocale: function (list) { bestLocale: function (list) {
return values([this.appLocale, this.appLocale.replace(/-.*/, ""), let candidates = [this.appLocale,
"en", "en-US", list[0]]) this.appLocale.replace(/-.*/, ""),
.find(bind("has", new RealSet(list))); "en",
"en-US",
list[0]];
list = new RealSet(list);
return candidates.find(locale => list.has(locale));
}, },
/** /**

View File

@@ -723,17 +723,17 @@ var DOM = Class("DOM", {
return this[0].getAttributeNS(ns, key); return this[0].getAttributeNS(ns, key);
}, },
css: update(function css(key, val) { css: update(function css(props, val = undefined) {
if (val !== undefined) if (val !== undefined)
key = Ary.toObject([[key, val]]); props = { [props]: val };
if (isObject(key)) if (isObject(props))
return this.each(function (elem) { return this.each(elem => {
for (let [k, v] of iter(key)) for (let [k, v] of Object.entries(props))
elem.style[css.property(k)] = v; elem.style[css.property(k)] = v;
}); });
return this[0].style[css.property(key)]; return this[0].style[css.property(props)];
}, { }, {
name: function (property) { name: function (property) {
return property.replace(/[A-Z]/g, m0 => "-" + m0.toLowerCase()); return property.replace(/[A-Z]/g, m0 => "-" + m0.toLowerCase());
@@ -895,13 +895,13 @@ var DOM = Class("DOM", {
if (isObject(event)) if (isObject(event))
capture = listener; capture = listener;
else else
event = Ary.toObject([[event, listener]]); event = { [event]: listener };
for (let [evt, callback] of iter(event)) for (let [evt, callback] of Object.entries(event))
event[evt] = util.wrapCallback(callback, true); event[evt] = util.wrapCallback(callback, true);
return this.each(function (elem) { return this.each(elem => {
for (let [evt, callback] of iter(event)) for (let [evt, callback] of Object.entries(event))
elem.addEventListener(evt, callback, capture); elem.addEventListener(evt, callback, capture);
}); });
}, },
@@ -909,30 +909,31 @@ var DOM = Class("DOM", {
if (isObject(event)) if (isObject(event))
capture = listener; capture = listener;
else else
event = Ary.toObject([[event, listener]]); event = { [event]: listener };
return this.each(function (elem) { return this.each(elem => {
for (let [k, v] of iter(event)) for (let [event, callback] of Object.entries(event))
elem.removeEventListener(k, v.wrapper || v, capture); elem.removeEventListener(event, callback.wrapper || v, capture);
}); });
}, },
once: function once(event, listener, capture) { once: function once(event, listener, capture) {
if (isObject(event)) if (isObject(event))
capture = listener; capture = listener;
else else
event = Ary.toObject([[event, listener]]); event = { [event]: listener };
for (let pair of iter(event)) { for (let pair of iter(event)) {
let [evt, callback] = pair; let [evt, callback] = pair;
event[evt] = util.wrapCallback(function wrapper(event) { event[evt] = util.wrapCallback(function wrapper(event) {
this.removeEventListener(evt, wrapper.wrapper, capture); this.removeEventListener(evt, wrapper.wrapper, capture);
return callback.apply(this, arguments); return callback.apply(this, arguments);
}, true); }, true);
} }
return this.each(function (elem) { return this.each(elem => {
for (let [k, v] of iter(event)) for (let [event, callback] of Object.entries(event))
elem.addEventListener(k, v, capture); elem.addEventListener(event, callback, capture);
}); });
}, },
@@ -940,6 +941,7 @@ var DOM = Class("DOM", {
this.canceled = false; this.canceled = false;
return this.each(function (elem) { return this.each(function (elem) {
let evt = DOM.Event(this.document, event, params, elem); let evt = DOM.Event(this.document, event, params, elem);
if (!DOM.Event.dispatch(elem, evt, extraProps)) if (!DOM.Event.dispatch(elem, evt, extraProps))
this.canceled = true; this.canceled = true;
}, this); }, this);
@@ -1231,7 +1233,7 @@ var DOM = Class("DOM", {
*/ */
parse: function parse(input, unknownOk=true) { parse: function parse(input, unknownOk=true) {
if (isArray(input)) if (isArray(input))
return Ary.flatten(input.map(k => this.parse(k, unknownOk))); return input.flatMap(k => this.parse(k, unknownOk));
let out = []; let out = [];
for (let match of util.regexp.iterate(/<.*?>?>|[^<]|<(?!.*>)/g, input)) { for (let match of util.regexp.iterate(/<.*?>?>|[^<]|<(?!.*>)/g, input)) {
@@ -1971,11 +1973,11 @@ var DOM = Class("DOM", {
* @returns {string} * @returns {string}
*/ */
makeXPath: function makeXPath(nodes) { makeXPath: function makeXPath(nodes) {
return Ary(nodes).map(util.debrace).flatten() return nodes.flatMap(util.debrace)
.map(node => /^[a-z]+:/.test(node) ? node .flatMap(node => /^[a-z]+:/.test(node) ? node
: [node, "xhtml:" + node]) : [node, "xhtml:" + node])
.flatten() .map(node => "//" + node)
.map(node => "//" + node).join(" | "); .join(" | ");
}, },
namespaces: { namespaces: {

View File

@@ -27,16 +27,16 @@ var HelpBuilder = Class("HelpBuilder", {
// Scrape the list of help files from all.xml // Scrape the list of help files from all.xml
this.tags["all"] = this.tags["all.xml"] = "all"; this.tags["all"] = this.tags["all.xml"] = "all";
let files = this.findHelpFile("all").map(doc => let files = this.findHelpFile("all").flatMap(
[f.value for (f of DOM.XPath("//dactyl:include/@href", doc))]); doc => Array.from(DOM.XPath("//dactyl:include/@href", doc),
f => f.value));
// Scrape the tags from the rest of the help files. // Scrape the tags from the rest of the help files.
Ary.flatten(files).forEach(function (file) { for (let file of files) {
this.tags[file + ".xml"] = file; this.tags[file + ".xml"] = file;
this.findHelpFile(file).forEach(function (doc) { for (let doc of this.findHelpFile(file))
this.addTags(file, doc); this.addTags(file, doc);
}, this); }
}, this);
} }
finally { finally {
delete help._data; delete help._data;
@@ -129,10 +129,12 @@ var Help = Module("Help", {
| (?: ^ [^\S\n]* \n) + | (?: ^ [^\S\n]* \n) +
`), "gmxy"); `), "gmxy");
let betas = util.regexp(/\[((?:b|rc)\d)\]/, "gx"); let matchBetas = util.regexp(/\[((?:b|rc)\d)\]/, "gx");
let beta = Ary(betas.iterate(NEWS)) let betas = Array.from(betas.iterate(NEWS),
.map(m => m[1]).uniq().slice(-1)[0]; match => match[1]);
let beta = betas.sort().pop();
function rec(text, level, li) { function rec(text, level, li) {
let res = []; let res = [];
@@ -154,7 +156,9 @@ var Help = Module("Help", {
else if (match.par) { else if (match.par) {
let [, par, tags] = /([^]*?)\s*((?:\[[^\]]+\])*)\n*$/.exec(match.par); let [, par, tags] = /([^]*?)\s*((?:\[[^\]]+\])*)\n*$/.exec(match.par);
let t = tags; let t = tags;
tags = Ary(betas.iterate(tags)).map(m => m[1]);
tags = Array.from(matchBetas.iterate(tags),
match => match[1]);
let group = !tags.length ? "" : let group = !tags.length ? "" :
!tags.some(t => t == beta) ? "HelpNewsOld" : "HelpNewsNew"; !tags.some(t => t == beta) ? "HelpNewsOld" : "HelpNewsNew";

View File

@@ -456,13 +456,13 @@ var Highlights = Module("Highlight", {
context.keys = { text: f => f.leafName.replace(extRe, ""), context.keys = { text: f => f.leafName.replace(extRe, ""),
description: ".parent.path" }; description: ".parent.path" };
context.completions = context.completions =
Ary.flatten( io.getRuntimeDirectories("colors")
io.getRuntimeDirectories("colors").map( .flatMap(dir => dir.readDirectory()
dir => dir.readDirectory() .filter(file => extRe.test(file.leafName)))
.filter(file => extRe.test(file.leafName)))) .concat([
.concat([ { leafName: "default",
{ leafName: "default", parent: { path: /*L*/"Revert to builtin colorscheme" } } parent: { path: /*L*/"Revert to builtin colorscheme" } }
]); ]);
}; };

View File

@@ -589,11 +589,13 @@ var IO = Module("io", {
* otherwise, the return value of *func*. * otherwise, the return value of *func*.
*/ */
withTempFiles: function withTempFiles(func, self, checked, ext, label) { withTempFiles: function withTempFiles(func, self, checked, ext, label) {
let args = Ary(util.range(0, func.length)) let args = Array.from(util.range(0, func.length),
.map(bind("createTempFile", this, ext, label)).array; () => this.createTempFile(ext, label));
try { try {
if (!args.every(identity)) if (!args.every(identity))
return false; return false;
var res = func.apply(self || this, args); var res = func.apply(self || this, args);
} }
finally { finally {
@@ -679,11 +681,10 @@ var IO = Module("io", {
dactyl.assert(!file.exists() || args.bang, _("io.exists", JSON.stringify(file.path))); dactyl.assert(!file.exists() || args.bang, _("io.exists", JSON.stringify(file.path)));
// TODO: Use a set/specifiable list here: // TODO: Use a set/specifiable list here:
let lines = [cmd.serialize().map(commands.commandToString, cmd) let lines = Array.from(commands.iterator())
for (cmd of commands.iterator()) .filter(cmd => cmd.serialize)
if (cmd.serialize)]; .flatMap(cmd => cmd.serialize()
.map(commands.commandToString, cmd));
lines = Ary.flatten(lines);
lines.unshift('"' + config.version + "\n"); lines.unshift('"' + config.version + "\n");
lines.push("\n\" vim: set ft=" + config.name + ":"); lines.push("\n\" vim: set ft=" + config.name + ":");
@@ -840,7 +841,7 @@ let &cpo = s:cpo_save
unlet s:cpo_save unlet s:cpo_save
" vim: tw=130 et ts=8 sts=4 sw=4: " vim: tw=130 et ts=8 sts=4 sw=4:
`;//}}} `;//}}} "
const { options } = modules; const { options } = modules;
@@ -876,15 +877,21 @@ unlet s:cpo_save
appname: config.appName, appname: config.appName,
fileext: config.fileExtension, fileext: config.fileExtension,
maintainer: "Doug Kearns <dougkearns@gmail.com>", maintainer: "Doug Kearns <dougkearns@gmail.com>",
autocommands: wrap("syn keyword " + config.name + "AutoEvent ", autocommands: wrap("syn keyword " + config.name + "AutoEvent ",
keys(config.autocommands)), Object.keys(config.autocommands)),
commands: wrap("syn keyword " + config.name + "Command ", commands: wrap("syn keyword " + config.name + "Command ",
Ary(c.specs for (c of commands.iterator())).flatten()), Array.from(commands.iterator()).flatMap(cmd => cmd.specs)),
options: wrap("syn keyword " + config.name + "Option ", options: wrap("syn keyword " + config.name + "Option ",
Ary(o.names for (o of options) if (o.type != "boolean")).flatten()), Array.from(options).filter(opt => opt.type != "boolean")
.flatMap(opt => opt.names)),
toggleoptions: wrap("let s:toggleOptions = [", toggleoptions: wrap("let s:toggleOptions = [",
Ary(o.realNames for (o of options) if (o.type == "boolean")) Array.from(options).filter(opt => opt.type == "boolean")
.flatten().map(JSON.stringify), .flatMap(opt => opt.realNames)
.map(JSON.stringify),
", ") + "]" ", ") + "]"
}; //}}} }; //}}}
@@ -1103,16 +1110,14 @@ unlet s:cpo_save
context.title = ["Shell Command", "Path"]; context.title = ["Shell Command", "Path"];
context.generate = () => { context.generate = () => {
let dirNames = services.environment.get("PATH").split(config.OS.pathListSep); let dirNames = services.environment.get("PATH").split(config.OS.pathListSep);
let commands = [];
for (let dirName of dirNames) { return dirNames.flatMap(dirName => {
let dir = io.File(dirName); let dir = io.File(dirName);
if (dir.exists() && dir.isDirectory()) if (dir.exists() && dir.isDirectory())
commands.push([[file.leafName, dir.path] for (file of iter(dir.directoryEntries)) return Array.from(dir.directoryEntries)
if (file.isFile() && file.isExecutable())]); .filter(file => file.isFile() && file.isExecutable())
} .map(file => [file.leafName, dir.path])
});
return Ary.flatten(commands);
}; };
}; };

View File

@@ -110,9 +110,10 @@ var JavaScript = Module("javascript", {
if (isPrototypeOf.call(this.toplevel, obj) && !toplevel) if (isPrototypeOf.call(this.toplevel, obj) && !toplevel)
return []; return [];
let completions = [k for (k of this.iter(obj, toplevel))]; let completions = Array.from(this.iter(obj, toplevel));
if (obj === this.modules) // Hack. if (obj === this.modules) // Hack.
completions = Ary.uniq(completions.concat([k for (k of this.iter(this.modules.jsmodules, toplevel))])); completions = [...new RealSet([...completions,
...this.iter(this.modules.jsmodules, toplevel)])];
return completions; return completions;
}, },
@@ -640,7 +641,9 @@ var JavaScript = Module("javascript", {
* enumerable by any standard method. * enumerable by any standard method.
*/ */
globalNames: Class.Memoize(function () { globalNames: Class.Memoize(function () {
return Ary.uniq([ let interfaces = Object.keys(Ci);
let names = new RealSet([
"Array", "ArrayBuffer", "AttributeName", "Audio", "Boolean", "Components", "Array", "ArrayBuffer", "AttributeName", "Audio", "Boolean", "Components",
"CSSFontFaceStyleDecl", "CSSGroupRuleRuleList", "CSSNameSpaceRule", "CSSFontFaceStyleDecl", "CSSGroupRuleRuleList", "CSSNameSpaceRule",
"CSSRGBColor", "CSSRect", "ComputedCSSStyleDeclaration", "Date", "Error", "CSSRGBColor", "CSSRect", "ComputedCSSStyleDeclaration", "Date", "Error",
@@ -655,11 +658,14 @@ var JavaScript = Module("javascript", {
"XMLList", "XMLSerializer", "XPCNativeWrapper", "XMLList", "XMLSerializer", "XPCNativeWrapper",
"XULControllers", "constructor", "decodeURI", "decodeURIComponent", "XULControllers", "constructor", "decodeURI", "decodeURIComponent",
"encodeURI", "encodeURIComponent", "escape", "eval", "isFinite", "isNaN", "encodeURI", "encodeURIComponent", "escape", "eval", "isFinite", "isNaN",
"isXMLName", "parseFloat", "parseInt", "undefined", "unescape", "uneval" "isXMLName", "parseFloat", "parseInt", "undefined", "unescape", "uneval",
].concat([k.substr(6) for (k of keys(Ci)) if (/^nsIDOM/.test(k))])
.concat([k.substr(3) for (k of keys(Ci)) if (/^nsI/.test(k))]) ...interfaces.filter(key => /^nsIDOM/.test(key)).map(key => k.substr(6)),
.concat(this.magicalNames) ...interfaces.filter(key => /^nsI/.test(key)).map(key => k.substr(3)),
.filter(k => k in this.window)); ...this.magicalNames,
]);
return [...names].filter(key => key in this.window);
}) })
}, { }, {
EVAL_TMP: "__dactyl_eval_tmp", EVAL_TMP: "__dactyl_eval_tmp",

View File

@@ -104,6 +104,8 @@ var Modules = function Modules(window) {
wantXrays: true, wantXrays: true,
metadata: { addonID: config.addon.id } }); metadata: { addonID: config.addon.id } });
loadPolyfill(sandbox);
// Hack: // Hack:
// sandbox.Object = jsmodules.Object; // sandbox.Object = jsmodules.Object;
sandbox.File = global.File; sandbox.File = global.File;

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2011-2014 Kris Maglione <maglione.k@gmail.com> // Copyright (c) 2011-2015 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.
@@ -40,25 +40,24 @@ var Messages = Module("messages", {
}, },
bundles: Class.Memoize(function () { bundles: Class.Memoize(function () {
let urls = [ let urls = new RealSet([
JSMLoader.getTarget("dactyl://locale/"), JSMLoader.getTarget("dactyl://locale/"),
JSMLoader.getTarget("dactyl://locale-local/"), JSMLoader.getTarget("dactyl://locale-local/"),
"resource://dactyl-locale/en-US/", "resource://dactyl-locale/en-US/",
"resource://dactyl-locale-local/en-US/" "resource://dactyl-locale-local/en-US/"
].map(url => url + this.name + ".properties"); ].map(url => url + this.name + ".properties"));
return Ary.uniq(urls, true) return Array.from(urls, services.stringBundle.createBundle)
.map(services.stringBundle.createBundle) .filter(bundle => {
.filter(bundle => { try {
try { bundle.getSimpleEnumeration();
bundle.getSimpleEnumeration(); return true;
return true; }
} catch (e) {
catch (e) { return false;
return false; }
} });
}); }),
}),
iterate: function* () { iterate: function* () {
let seen = new RealSet; let seen = new RealSet;
@@ -111,12 +110,16 @@ var Messages = Module("messages", {
file = io.File(file); file = io.File(file);
function properties(base, iter_, prop="description") { function properties(base, iter_, prop="description") {
return iter(function* _properties() { return Array.from(function* _properties() {
function key(...args) { function key(...args) {
return [base, obj.identifier || obj.name].concat(args).join(".").replace(/[\\:=]/g, "\\$&"); return [base,
obj.identifier || obj.name,
...args]
.join(".")
.replace(/[\\:=]/g, "\\$&");
} }
for (var obj of iter_) { for (let obj of iter_) {
if (!obj.hive || obj.hive.name !== "user") { if (!obj.hive || obj.hive.name !== "user") {
yield key(prop) + " = " + obj[prop]; yield key(prop) + " = " + obj[prop];
@@ -135,20 +138,22 @@ var Messages = Module("messages", {
yield key("deprecated") + " = " + obj.deprecated; yield key("deprecated") + " = " + obj.deprecated;
} }
} }
}()).toArray(); }());
} }
file.write( let allMessages = [
Ary(commands.allHives.map(h => properties("command", h))) ...commands.allHives.map(h => properties("command", h)),
.concat(modes.all.map(m => ...modes.all.flatMap(m =>
properties("map", values(mappings.builtin.getStack(m) properties("map", values(mappings.builtin.getStack(m)
.filter(map => map.modes[0] == m))))) .filter(map => map.modes[0] == m)))),
.concat(properties("mode", values(modes.all.filter(m => !m.hidden)))) ...properties("mode", values(modes.all.filter(m => !m.hidden))),
.concat(properties("option", options)) ...properties("option", options),
.concat(properties("hintmode", values(hints.modes), "prompt")) ...properties("hintmode", values(hints.modes), "prompt"),
.concat(properties("pageinfo", values(Buffer.pageInfo), "title")) ...properties("pageinfo", values(Buffer.pageInfo), "title"),
.concat(properties("sanitizeitem", values(sanitizer.itemMap))) ...properties("sanitizeitem", values(sanitizer.itemMap)),
.flatten().uniq().join("\n")); ];
file.write(allMessages.join("\n"));
} }
}, { }, {
Localized: Class("Localized", Class.Property, { Localized: Class("Localized", Class.Property, {

View File

@@ -611,7 +611,7 @@ var Option = Class("Option", {
list: function list(value, parse) { list: function list(value, parse) {
let prev = null; let prev = null;
return Ary.compact(Option.splitList(value, true) return Ary.compact(Option.splitList(value, true)
.map(function (v) { .map(v => {
let [count, filter, quote] = Commands.parseArg(v, /:/, true); let [count, filter, quote] = Commands.parseArg(v, /:/, true);
let val = v.substr(count + 1); let val = v.substr(count + 1);
@@ -624,7 +624,7 @@ var Option = Class("Option", {
util.assert(prev, _("error.syntaxError"), false); util.assert(prev, _("error.syntaxError"), false);
prev.result += "," + v; prev.result += "," + v;
} }
}, this)); }));
}, },
}, },
@@ -886,7 +886,7 @@ var Option = Class("Option", {
update(BooleanOption.prototype, { update(BooleanOption.prototype, {
names: Class.Memoize(function () { names: Class.Memoize(function () {
return Ary.flatten([[name, "no" + name] for (name of this.realNames)]); return this.realNames.flatMap(name => [name, "no" + name]);
}) })
}); });
@@ -1504,7 +1504,7 @@ var Options = Module("options", {
bang: true, bang: true,
completer: setCompleter, completer: setCompleter,
domains: function domains(args) { domains: function domains(args) {
return Ary.flatten(args.map(function (spec) { return args.flatMap(spec => {
try { try {
let opt = modules.options.parseOpt(spec); let opt = modules.options.parseOpt(spec);
if (opt.option && opt.option.domains) if (opt.option && opt.option.domains)
@@ -1514,17 +1514,17 @@ var Options = Module("options", {
util.reportError(e); util.reportError(e);
} }
return []; return [];
})); });
}, },
keepQuotes: true, keepQuotes: true,
privateData: function privateData(args) { privateData: args => args.some(spec => {
return args.some(function (spec) { let opt = modules.options.parseOpt(spec);
let opt = modules.options.parseOpt(spec);
return opt.option && opt.option.privateData && return (opt.option &&
(!callable(opt.option.privateData) || opt.option.privateData &&
opt.option.privateData(opt.values)); (!callable(opt.option.privateData) ||
}); opt.option.privateData(opt.values)));
} }),
}, params.extra || {})); }, params.extra || {}));
}); });

View File

@@ -71,10 +71,10 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
let doc = target.ownerDocument || target.document || target; let doc = target.ownerDocument || target.document || target;
let listeners = this.getData(doc, "listeners"); let listeners = this.getData(doc, "listeners");
if (!isObject(event)) if (isObject(event))
var [self, events] = [null, Ary.toObject([[event, callback]])]; var [self, events] = [event, event[callback || "events"]];
else else
[self, events] = [event, event[callback || "events"]]; [self, events] = [null, { [event]: callback }];
for (let [event, callback] of iter(events)) { for (let [event, callback] of iter(events)) {
let args = [Cu.getWeakReference(target), let args = [Cu.getWeakReference(target),

View File

@@ -0,0 +1,70 @@
// Copyright (c) 2015 Kris Maglione <maglione.k@gmail.com>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
"use strict";
// Implementations for some ES6 and ES7 features that aren't in Firefox
// mainline yet.
{
// This is similar to the same-named function in self-hosted JS, but
// somewhat less efficient.
//
// It helps dodge some of the pitfalls of using the `call` method of the
// function you're intending to call, which might have been replaced,
// and can fail for other reasons (on CPOWs, most notably).
let callFunction = Function.call.bind(Function.call);
let identity = x => x;
if (!Object.entries)
Object.entries = function (obj) {
let result = [];
for (let key of Object.keys(obj)) {
// The check is necessary, since keys may be removed during
// iteration.
if (key in obj)
result.push([key, obj[val]]);
}
return result;
};
if (!Object.values)
Object.values = function (obj) {
let result = [];
for (let key of Object.keys(obj)) {
// The check is necessary, since keys may be removed during
// iteration.
if (key in obj)
result.push(obj[val]);
}
return result;
};
if (!Array.prototype.flatMap)
Array.prototype.flatMap = function (fn = identity, self = null) {
let result = [];
for (let [i, value] of Array.prototype.entries.call(this)) {
let res = callFunction(fn, self, value, i);
if (isObject(res) && Symbol.iterator in res)
result.push(...res);
else if (res !== undefined)
result.push(res);
}
return result;
};
if (!Array.prototype.values)
Array.prototype.values = function* () {
for (let [i, value] of this.entries())
yield value;
};
}

View File

@@ -125,9 +125,9 @@ var Hive = Class("Hive", {
}, },
get sites() { get sites() {
return Ary(this.sheets).map(s => s.sites) let sites = this.sheets.flatMap(s => s.sites);
.flatten()
.uniq().array; return [...new RealSet(sites)];
}, },
/** /**
@@ -557,6 +557,7 @@ var Styles = Module("Styles", {
' (?:[^\\']|\\.)* (?:'|$) ' (?:[^\\']|\\.)* (?:'|$)
) )
`, "gx", this); `, "gx", this);
// " Vim.
}, },
get token() { get token() {
@@ -617,7 +618,11 @@ var Styles = Module("Styles", {
let [filter, css] = args; let [filter, css] = args;
if (!css) if (!css)
styles.list(window.content, filter ? filter.split(",") : null, args["-name"], args.explicitOpts["-group"] ? [args["-group"]] : null); styles.list(window.content,
filter ? filter.split(",") : null,
args["-name"],
args.explicitOpts["-group"] ? [args["-group"]]
: null);
else { else {
util.assert(args["-group"].modifiable && args["-group"].hive.modifiable, util.assert(args["-group"].modifiable && args["-group"].hive.modifiable,
_("group.cantChangeBuiltin", _("style.styles"))); _("group.cantChangeBuiltin", _("style.styles")));
@@ -660,9 +665,9 @@ var Styles = Module("Styles", {
{ names: ["-nopersist", "-N"], description: "Do not save this style to an auto-generated RC file" } { names: ["-nopersist", "-N"], description: "Do not save this style to an auto-generated RC file" }
], ],
serialize: function () { serialize: function () {
return Ary(styles.hives) return styles.hives
.filter(hive => hive.persist) .filter(hive => hive.persist)
.map(hive => .flatMap(hive =>
hive.sheets.filter(style => style.persist) hive.sheets.filter(style => style.persist)
.sort((a, b) => String.localeCompare(a.name || "", .sort((a, b) => String.localeCompare(a.name || "",
b.name || "")) b.name || ""))
@@ -674,8 +679,7 @@ var Styles = Module("Styles", {
"-group": hive.name == "user" ? undefined : hive.name, "-group": hive.name == "user" ? undefined : hive.name,
"-name": style.name || undefined "-name": style.name || undefined
} }
}))) })));
.flatten().array;
} }
}); });

View File

@@ -1778,9 +1778,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @returns {Generator(nsIDOMWindow)} * @returns {Generator(nsIDOMWindow)}
*/ */
iterFrames: function* iterFrames(win) { iterFrames: function* iterFrames(win) {
yield win; yield win;
for (let i = 0; i < win.frames.length; i++) for (let i = 0; i < win.frames.length; i++)
yield* iterFrames(win.frames[i]); yield* iterFrames(win.frames[i]);
}, },
/** /**