1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 18:17:58 +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 () {
return Ary(abbreviations.userHives)
return abbreviations.userHives
.filter(h => h.persist)
.map(hive => [
{
command: this.name,
arguments: [abbr.lhs],
literalArg: abbr.rhs,
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;
}
.flatMap(hive =>
hive.merged
.filter(abbr => abbr.modesEqual(modes))
.map(abbr => ({
command: this.name,
arguments: [abbr.lhs],
literalArg: abbr.rhs,
options: {
"-group": hive.name == "user" ? undefined : hive.name,
"-javascript": callable(abbr.rhs) ? null : undefined
}
})));
},
});
commands.add([ch + "una[bbreviate]"],

View File

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

View File

@@ -243,12 +243,12 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
{ argCount: "0" });
},
mappings: function initMappings(dactyl, modules, window) {
let openModes = Ary.toObject([
[dactyl.CURRENT_TAB, ""],
[dactyl.NEW_TAB, "tab"],
[dactyl.NEW_BACKGROUND_TAB, "background tab"],
[dactyl.NEW_WINDOW, "win"]
]);
let openModes = {
[dactyl.CURRENT_TAB]: "",
[dactyl.NEW_TAB]: "tab",
[dactyl.NEW_BACKGROUND_TAB]: "background tab",
[dactyl.NEW_WINDOW]: "win",
};
function open(mode, args) {
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,
function (args) {
let results = Ary(params.iterate(args))
.sort((a, b) => String.localeCompare(a.name, b.name));
let results = Array.from(params.iterate(args))
.sort((a, b) => String.localeCompare(a.name, b.name));
let filters = args.map(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";
};
context.ignoreCase = true;
let seen = {};
context.completions = Ary(keys(item).join(" ").toLowerCase().split(/[()\s]+/)
for (item of params.iterate(args)))
.flatten()
.map(function (k) {
seen[k] = (seen[k] || 0) + 1;
return k;
}).uniq();
context.completions = new RealSet(
Array.from(params.iterate(args))
.flatMap(item => Object.keys(item).join(" ")
.toLowerCase().split(/[()\s]+/))
.map(k => {
seen[k] = (seen[k] || 0) + 1;
return k;
}));
},
options: params.options || []
});
if (params.index)
this.indices[params.index] = function* () {
let results = Ary((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs()))
.array.sort((a, b) => String.localeCompare(a.name, b.name));
let results = Array.from((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs()))
.sort((a, b) => String.localeCompare(a.name, b.name));
for (let obj of results) {
let res = dactyl.generateHelp(obj, null, null, true);
@@ -646,7 +648,6 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* Initialize the help system.
*/
initHelp: function initHelp() {
util.dumpStack('INIT HELP');
if ("noscriptOverlay" in window)
window.noscriptOverlay.safeAllow("dactyl:", true, false);
@@ -1415,11 +1416,13 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
// FIXME: cleanup
cleanupValue: config.cleanups.guioptions ||
"rb" + [k for ([k, v] of iter(groups[1].opts))
if (!Dactyl.isToolbarHidden(document.getElementById(v[1][0])))].join(""),
"rb" + Object.entries(groups[1].opts)
.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))])
.flatten(),
values: groups.flatMap(g => Object.entries(g.opts)
.map(([k, v]) => [k, v[0]])),
setter: function (value) {
for (let group of groups)

View File

@@ -23,10 +23,10 @@ var EventHive = Class("EventHive", Contexts.Hive, {
},
_events: function _events(event, callback) {
if (!isObject(event))
var [self, events] = [null, Ary.toObject([[event, callback]])];
if (isObject(event))
var [self, events] = [event, event[callback || "events"]];
else
[self, events] = [event, event[callback || "events"]];
[self, events] = [null, { [event]: callback }];
if (hasOwnProp(events, "input") && !hasOwnProp(events, "dactyl-input"))
events["dactyl-input"] = events.input;
@@ -1141,7 +1141,7 @@ var Events = Module("events", {
return this.value.filter(f => f(buffer.documentURI));
});
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() {
return Hive(this.filters, "command");

View File

@@ -1379,7 +1379,8 @@ var Hints = Module("hints", {
},
validator: function (value) {
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"));
}
});

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// 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
// 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",
completer: function (context) {
context.compare = CompletionContext.Sort.unsorted;
return Ary.flatten([
return [
"annotation",
"date",
"date added",
@@ -300,10 +300,10 @@ var History = Module("history", {
"title",
"uri",
"visitcount"
].map(order => [
["+" + order.replace(" ", ""), /*L*/"Sort by " + order + " ascending"],
["-" + order.replace(" ", ""), /*L*/"Sort by " + order + " descending"]
]));
].flatMap(order => [
["+" + order.replace(" ", ""), /*L*/"Sort by " + order + " ascending"],
["-" + order.replace(" ", ""), /*L*/"Sort by " + order + " descending"]
]);
}
}
],

View File

@@ -17,7 +17,9 @@ var ProcessorStack = Class("ProcessorStack", {
events.dbg("STACK " + mode);
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)
hives = hives.filter(h => h.name === "builtin");

View File

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

View File

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

View File

@@ -186,7 +186,6 @@ defineModule("base", {
"Set",
"Struct",
"StructBase",
"Symbol",
"TextEncoder",
"TextDecoder",
"Timer",
@@ -217,6 +216,7 @@ defineModule("base", {
"iterOwnProperties",
"keys",
"literal",
"loadPolyfill",
"memoize",
"module",
"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("config", ["config"]);
this.lazyRequire("messages", ["_", "Messages"]);
@@ -236,11 +242,6 @@ this.lazyRequire("services", ["services"]);
this.lazyRequire("storage", ["File"]);
this.lazyRequire("util", ["FailedAssertion", "util"]);
if (typeof Symbol == "undefined")
this.Symbol = {
iterator: "@@iterator"
};
let literal_ = function literal(comment) {
if (comment)
return /^function.*?\/\*([^]*)\*\/(?:\/\* use strict \*\/)\s*\S$/.exec(comment)[1];
@@ -1203,34 +1204,19 @@ for (let name of properties(Class.prototype)) {
}
var closureHooks = {
get: function closure_get(target, prop) {
if (hasOwnProp(target._closureCache, prop))
get(target, prop) {
if (prop in target._closureCache)
return target._closureCache[prop];
let p = target[prop];
if (callable(p))
return target._closureCache[prop] = p.bind(target);
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() {
this._closureCache = {};
this._closureCache = Object.create(null);
return new Proxy(this, closureHooks);
};
@@ -1402,7 +1388,7 @@ function Struct(...args) {
const Struct = Class(className || "Struct", StructBase, {
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) {
Struct.prototype.__defineGetter__(name, function () {
@@ -1617,12 +1603,12 @@ function iter(obj, iface) {
else if (Symbol.iterator in obj)
res = obj[Symbol.iterator]();
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) {
while (obj.constructor instanceof ctypes.PointerType)
obj = obj.contents;
if (obj.constructor instanceof ctypes.ArrayType)
res = Ary.iterItems(obj);
res = Array.from(obj).entries();
else if (obj.constructor instanceof ctypes.StructType)
res = (function* () {
for (let prop of obj.constructor.fields) {
@@ -1664,14 +1650,14 @@ function iter(obj, iface) {
}
if (res === undefined)
res = Iterator(obj)[Symbol.iterator]();
res = Object.entries(obj).values();
return Iter(res);
}
update(iter, {
toArray: function toArray(iter) {
return Ary(iter).array;
},
toArray: deprecated("Array.from", function toArray(iter) {
return Array.from(iter);
}),
// See Ary.prototype for API docs.
toObject: function toObject(iter) {
@@ -1939,10 +1925,10 @@ var Ary = Class("Ary", Array, {
* @param {Array} ary
* @returns {Iterator(Object)}
*/
iterValues: function* iterValues(ary) {
iterValues: deprecated("Array#values", function* iterValues(ary) {
for (let i = 0; i < ary.length; i++)
yield ary[i];
},
}),
/**
* Returns an Iterator for an array's indices and values.
@@ -1950,11 +1936,11 @@ var Ary = Class("Ary", Array, {
* @param {Array} ary
* @returns {Iterator([{number}, {Object}])}
*/
iterItems: function* iterItems(ary) {
iterItems: deprecated("Array#entries", function* iterItems(ary) {
let length = ary.length;
for (let i = 0; i < length; i++)
yield [i, ary[i]];
},
}),
/**
* 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(); }),
keywords: Class.Memoize(function () {
return Ary.toObject([[b.keyword, b]
for (b of this)
if (b.keyword)]);
let res = {};
for (let bookmark of this)
if (bookmark.keyword)
res[bookmark.keyword] = res;
return res;
}),
rootFolders: ["toolbarFolder", "bookmarksMenuFolder", "unfiledBookmarksFolder"]

View File

@@ -58,8 +58,8 @@ var Buffer = Module("Buffer", {
* buffer. Only returns style sheets for the 'screen' media type.
*/
get alternateStyleSheets() {
let stylesheets = Ary.flatten(
this.allFrames().map(w => Array.slice(w.document.styleSheets)));
let stylesheets = this.allFrames()
.flatMap(w => w.document.styleSheets);
return stylesheets.filter(
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.
*/
allFrames: function allFrames(win=this.win, focusedFirst) {
let frames = iter(util.iterFrames(win)).toArray();
let frames = Array.from(util.iterFrames(win));
if (focusedFirst)
return frames.filter(f => f === this.focusedFrame).concat(
frames.filter(f => f !== this.focusedFrame));
if (focusedFirst) {
let focused = this.focusedFrame;
return frames.sort((a, b) => (b === focused) - (a === focused));
}
return frames;
},
@@ -2415,8 +2416,10 @@ var Buffer = Module("Buffer", {
let frames = buffer.allFrames(undefined, true);
let elements = Ary.flatten(frames.map(win => [m for (m of DOM.XPath(xpath, win.document))]))
.filter(function (elem) {
let elements = Array.from(frames)
.flatMap(win => DOM.XPath(xpath, win.document))
.filter(elem => {
if (isinstance(elem, [Ci.nsIDOMHTMLFrameElement,
Ci.nsIDOMHTMLIFrameElement]))
return Editor.getEditor(elem.contentWindow);
@@ -2428,9 +2431,11 @@ var Buffer = Module("Buffer", {
let style = elem.style;
let rect = elem.rect;
return elem.isVisible &&
(elem[0] instanceof Ci.nsIDOMXULTextBoxElement || style.MozUserFocus != "ignore") &&
rect.width && rect.height;
(elem[0] instanceof Ci.nsIDOMXULTextBoxElement ||
style.MozUserFocus != "ignore") &&
rect.width && rect.height;
});
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. */
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 */
@@ -330,9 +330,9 @@ var Command = Class("Command", {
_options: [],
optionMap: Class.Memoize(function () {
return Ary(this.options)
.map(opt => opt.names.map(name => [name, opt]))
.flatten().toObject();
return Ary.toObject(
Array.from(this.options)
.flatMap(opt => opt.names.map(name => [name, opt])));
}),
newArgs: function newArgs(base) {
@@ -456,7 +456,7 @@ var Command = Class("Command", {
* @returns {Array}
*/
parseSpecs: function parseSpecs(specs) {
return specs.map(function (spec) {
return specs.map(spec => {
let [, head, tail] = /([^[]+)(?:\[(.*)])?/.exec(spec);
return tail ? [head + tail, head] : [head];
});
@@ -498,8 +498,9 @@ var Ex = Module("Ex", {
args = Array.slice(args);
let res = cmd.newArgs({ context: this.context });
if (isObject(args[0]))
for (let [k, v] of iter(args.shift()))
for (let [k, v] of Object.entries(args.shift()))
if (k == "!")
res.bang = v;
else if (k == "#")
@@ -515,8 +516,9 @@ var Ex = Module("Ex", {
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);
return res;
},
@@ -593,7 +595,9 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
if (this.cached)
this.modules.initDependencies("commands");
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. */
@@ -623,7 +627,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
extra.hive = this;
extra.parsedSpecs = Command.parseSpecs(specs);
let names = Ary.flatten(extra.parsedSpecs);
let names = extra.parsedSpecs.flatMap();
let name = names[0];
if (this.name != "builtin") {
@@ -934,10 +938,10 @@ var Commands = Module("commands", {
let defaults = {};
if (args.ignoreDefaults)
defaults = Ary(this.options).map(opt => [opt.names[0], opt.default])
.toObject();
defaults = Ary.toObject(Array.from(this.options,
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)
continue;
if (val != null && defaults[opt] === val)
@@ -1788,28 +1792,32 @@ var Commands = Module("commands", {
literal: 1,
serialize: function () {
return Ary(commands.userHives)
return commands.userHives
.filter(h => h.persist)
.map(hive => [
{
.flatMap(hive =>
Array.from(hive)
.filter(cmd => cmd.persist)
.map(cmd =>
({
command: this.name,
bang: true,
options: iter([v, typeof cmd[k] == "boolean" ? null : cmd[k]]
// FIXME: this map is expressed multiple times
for ([k, v] of iter({
argCount: "-nargs",
bang: "-bang",
count: "-count",
description: "-description"
}))
if (cmd[k])).toObject(),
options: Ary.toObject(
Object.entries({
argCount: "-nargs",
bang: "-bang",
count: "-count",
description: "-description",
})
.filter(([k, v]) => cmd[k])
.map(([k, v]) => [
v,
typeof cmd[k] == "boolean" ? null : cmd[k]
])),
arguments: [cmd.name],
literalArg: cmd.action,
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 items() {
return Ary.flatten(self.activeContexts.map(function m(context) {
return self.activeContexts.flatMap(context => {
let prefix = self.value.substring(minStart, context.offset);
return context.items.map(function m(item) {
return context.items.map(item => {
return {
text: prefix + item.text,
result: prefix + item.result,
__proto__: item
};
});
}));
});
}
});
@@ -323,24 +323,23 @@ var CompletionContext = Class("CompletionContext", {
* Possibly.
*/
let substrings = lists.reduce(
function r(res, list) {
return res.filter(function f(str) {
return list.some(function s_(s) {
return s.substr(0, str.length) == str;
});
(res, list) => {
return res.filter(str => {
return list.some(s => s.substr(0, str.length) == str);
});
},
lists.pop());
if (!substrings) // FIXME: How is this undefined?
return [];
return Ary.uniq(Array.slice(substrings));
},
// Temporary
get longestAllSubstring() {
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; },

View File

@@ -235,20 +235,19 @@ var ConfigBase = Class("ConfigBase", {
let uri = "resource://dactyl-locale/";
let jar = io.isJarURL(uri);
let res;
if (jar) {
let prefix = getDir(jar.JAREntry);
var res = iter(s.slice(prefix.length).replace(/\/.*/, "")
for (s of io.listJar(jar.JARFile, prefix)))
.toArray();
res = Array.from(io.listJar(jar.JARFile, prefix),
s => slice(prefix.length).replace(/\/.*/, ""));
}
else {
res = Ary(f.leafName
// Fails on FF3: for (f of util.getFile(uri).iterDirectory())
for (f of util.getFile(uri).readDirectory())
if (f.isDirectory())).array;
res = Array.from(util.getFile(uri).readDirectory())
.filter(f => f.isDirectory())
.map(f => f.leafName);
}
let exists = function exists(pkg) {
let exists = pkg => {
return services["resource:"].hasSubstitution("dactyl-locale-" + pkg);
};
@@ -265,9 +264,14 @@ var ConfigBase = Class("ConfigBase", {
* @returns {string}
*/
bestLocale: function (list) {
return values([this.appLocale, this.appLocale.replace(/-.*/, ""),
"en", "en-US", list[0]])
.find(bind("has", new RealSet(list)));
let candidates = [this.appLocale,
this.appLocale.replace(/-.*/, ""),
"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);
},
css: update(function css(key, val) {
css: update(function css(props, val = undefined) {
if (val !== undefined)
key = Ary.toObject([[key, val]]);
props = { [props]: val };
if (isObject(key))
return this.each(function (elem) {
for (let [k, v] of iter(key))
if (isObject(props))
return this.each(elem => {
for (let [k, v] of Object.entries(props))
elem.style[css.property(k)] = v;
});
return this[0].style[css.property(key)];
return this[0].style[css.property(props)];
}, {
name: function (property) {
return property.replace(/[A-Z]/g, m0 => "-" + m0.toLowerCase());
@@ -895,13 +895,13 @@ var DOM = Class("DOM", {
if (isObject(event))
capture = listener;
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);
return this.each(function (elem) {
for (let [evt, callback] of iter(event))
return this.each(elem => {
for (let [evt, callback] of Object.entries(event))
elem.addEventListener(evt, callback, capture);
});
},
@@ -909,30 +909,31 @@ var DOM = Class("DOM", {
if (isObject(event))
capture = listener;
else
event = Ary.toObject([[event, listener]]);
event = { [event]: listener };
return this.each(function (elem) {
for (let [k, v] of iter(event))
elem.removeEventListener(k, v.wrapper || v, capture);
return this.each(elem => {
for (let [event, callback] of Object.entries(event))
elem.removeEventListener(event, callback.wrapper || v, capture);
});
},
once: function once(event, listener, capture) {
if (isObject(event))
capture = listener;
else
event = Ary.toObject([[event, listener]]);
event = { [event]: listener };
for (let pair of iter(event)) {
let [evt, callback] = pair;
event[evt] = util.wrapCallback(function wrapper(event) {
this.removeEventListener(evt, wrapper.wrapper, capture);
return callback.apply(this, arguments);
}, true);
}
return this.each(function (elem) {
for (let [k, v] of iter(event))
elem.addEventListener(k, v, capture);
return this.each(elem => {
for (let [event, callback] of Object.entries(event))
elem.addEventListener(event, callback, capture);
});
},
@@ -940,6 +941,7 @@ var DOM = Class("DOM", {
this.canceled = false;
return this.each(function (elem) {
let evt = DOM.Event(this.document, event, params, elem);
if (!DOM.Event.dispatch(elem, evt, extraProps))
this.canceled = true;
}, this);
@@ -1231,7 +1233,7 @@ var DOM = Class("DOM", {
*/
parse: function parse(input, unknownOk=true) {
if (isArray(input))
return Ary.flatten(input.map(k => this.parse(k, unknownOk)));
return input.flatMap(k => this.parse(k, unknownOk));
let out = [];
for (let match of util.regexp.iterate(/<.*?>?>|[^<]|<(?!.*>)/g, input)) {
@@ -1971,11 +1973,11 @@ var DOM = Class("DOM", {
* @returns {string}
*/
makeXPath: function makeXPath(nodes) {
return Ary(nodes).map(util.debrace).flatten()
.map(node => /^[a-z]+:/.test(node) ? node
: [node, "xhtml:" + node])
.flatten()
.map(node => "//" + node).join(" | ");
return nodes.flatMap(util.debrace)
.flatMap(node => /^[a-z]+:/.test(node) ? node
: [node, "xhtml:" + node])
.map(node => "//" + node)
.join(" | ");
},
namespaces: {

View File

@@ -27,16 +27,16 @@ var HelpBuilder = Class("HelpBuilder", {
// Scrape the list of help files from all.xml
this.tags["all"] = this.tags["all.xml"] = "all";
let files = this.findHelpFile("all").map(doc =>
[f.value for (f of DOM.XPath("//dactyl:include/@href", doc))]);
let files = this.findHelpFile("all").flatMap(
doc => Array.from(DOM.XPath("//dactyl:include/@href", doc),
f => f.value));
// 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.findHelpFile(file).forEach(function (doc) {
for (let doc of this.findHelpFile(file))
this.addTags(file, doc);
}, this);
}, this);
}
}
finally {
delete help._data;
@@ -129,10 +129,12 @@ var Help = Module("Help", {
| (?: ^ [^\S\n]* \n) +
`), "gmxy");
let betas = util.regexp(/\[((?:b|rc)\d)\]/, "gx");
let matchBetas = util.regexp(/\[((?:b|rc)\d)\]/, "gx");
let beta = Ary(betas.iterate(NEWS))
.map(m => m[1]).uniq().slice(-1)[0];
let betas = Array.from(betas.iterate(NEWS),
match => match[1]);
let beta = betas.sort().pop();
function rec(text, level, li) {
let res = [];
@@ -154,7 +156,9 @@ var Help = Module("Help", {
else if (match.par) {
let [, par, tags] = /([^]*?)\s*((?:\[[^\]]+\])*)\n*$/.exec(match.par);
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 ? "" :
!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, ""),
description: ".parent.path" };
context.completions =
Ary.flatten(
io.getRuntimeDirectories("colors").map(
dir => dir.readDirectory()
.filter(file => extRe.test(file.leafName))))
.concat([
{ leafName: "default", parent: { path: /*L*/"Revert to builtin colorscheme" } }
]);
io.getRuntimeDirectories("colors")
.flatMap(dir => dir.readDirectory()
.filter(file => extRe.test(file.leafName)))
.concat([
{ leafName: "default",
parent: { path: /*L*/"Revert to builtin colorscheme" } }
]);
};

View File

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

View File

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

View File

@@ -104,6 +104,8 @@ var Modules = function Modules(window) {
wantXrays: true,
metadata: { addonID: config.addon.id } });
loadPolyfill(sandbox);
// Hack:
// sandbox.Object = jsmodules.Object;
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
// given in the LICENSE.txt file included with this file.
@@ -40,25 +40,24 @@ var Messages = Module("messages", {
},
bundles: Class.Memoize(function () {
let urls = [
let urls = new RealSet([
JSMLoader.getTarget("dactyl://locale/"),
JSMLoader.getTarget("dactyl://locale-local/"),
"resource://dactyl-locale/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)
.map(services.stringBundle.createBundle)
.filter(bundle => {
try {
bundle.getSimpleEnumeration();
return true;
}
catch (e) {
return false;
}
});
}),
return Array.from(urls, services.stringBundle.createBundle)
.filter(bundle => {
try {
bundle.getSimpleEnumeration();
return true;
}
catch (e) {
return false;
}
});
}),
iterate: function* () {
let seen = new RealSet;
@@ -111,12 +110,16 @@ var Messages = Module("messages", {
file = io.File(file);
function properties(base, iter_, prop="description") {
return iter(function* _properties() {
return Array.from(function* _properties() {
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") {
yield key(prop) + " = " + obj[prop];
@@ -135,20 +138,22 @@ var Messages = Module("messages", {
yield key("deprecated") + " = " + obj.deprecated;
}
}
}()).toArray();
}());
}
file.write(
Ary(commands.allHives.map(h => properties("command", h)))
.concat(modes.all.map(m =>
properties("map", values(mappings.builtin.getStack(m)
.filter(map => map.modes[0] == m)))))
.concat(properties("mode", values(modes.all.filter(m => !m.hidden))))
.concat(properties("option", options))
.concat(properties("hintmode", values(hints.modes), "prompt"))
.concat(properties("pageinfo", values(Buffer.pageInfo), "title"))
.concat(properties("sanitizeitem", values(sanitizer.itemMap)))
.flatten().uniq().join("\n"));
let allMessages = [
...commands.allHives.map(h => properties("command", h)),
...modes.all.flatMap(m =>
properties("map", values(mappings.builtin.getStack(m)
.filter(map => map.modes[0] == m)))),
...properties("mode", values(modes.all.filter(m => !m.hidden))),
...properties("option", options),
...properties("hintmode", values(hints.modes), "prompt"),
...properties("pageinfo", values(Buffer.pageInfo), "title"),
...properties("sanitizeitem", values(sanitizer.itemMap)),
];
file.write(allMessages.join("\n"));
}
}, {
Localized: Class("Localized", Class.Property, {

View File

@@ -611,7 +611,7 @@ var Option = Class("Option", {
list: function list(value, parse) {
let prev = null;
return Ary.compact(Option.splitList(value, true)
.map(function (v) {
.map(v => {
let [count, filter, quote] = Commands.parseArg(v, /:/, true);
let val = v.substr(count + 1);
@@ -624,7 +624,7 @@ var Option = Class("Option", {
util.assert(prev, _("error.syntaxError"), false);
prev.result += "," + v;
}
}, this));
}));
},
},
@@ -886,7 +886,7 @@ var Option = Class("Option", {
update(BooleanOption.prototype, {
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,
completer: setCompleter,
domains: function domains(args) {
return Ary.flatten(args.map(function (spec) {
return args.flatMap(spec => {
try {
let opt = modules.options.parseOpt(spec);
if (opt.option && opt.option.domains)
@@ -1514,17 +1514,17 @@ var Options = Module("options", {
util.reportError(e);
}
return [];
}));
});
},
keepQuotes: true,
privateData: function privateData(args) {
return args.some(function (spec) {
let opt = modules.options.parseOpt(spec);
return opt.option && opt.option.privateData &&
(!callable(opt.option.privateData) ||
opt.option.privateData(opt.values));
});
}
privateData: args => args.some(spec => {
let opt = modules.options.parseOpt(spec);
return (opt.option &&
opt.option.privateData &&
(!callable(opt.option.privateData) ||
opt.option.privateData(opt.values)));
}),
}, 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 listeners = this.getData(doc, "listeners");
if (!isObject(event))
var [self, events] = [null, Ary.toObject([[event, callback]])];
if (isObject(event))
var [self, events] = [event, event[callback || "events"]];
else
[self, events] = [event, event[callback || "events"]];
[self, events] = [null, { [event]: callback }];
for (let [event, callback] of iter(events)) {
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() {
return Ary(this.sheets).map(s => s.sites)
.flatten()
.uniq().array;
let sites = this.sheets.flatMap(s => s.sites);
return [...new RealSet(sites)];
},
/**
@@ -557,6 +557,7 @@ var Styles = Module("Styles", {
' (?:[^\\']|\\.)* (?:'|$)
)
`, "gx", this);
// " Vim.
},
get token() {
@@ -617,7 +618,11 @@ var Styles = Module("Styles", {
let [filter, css] = args;
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 {
util.assert(args["-group"].modifiable && args["-group"].hive.modifiable,
_("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" }
],
serialize: function () {
return Ary(styles.hives)
return styles.hives
.filter(hive => hive.persist)
.map(hive =>
.flatMap(hive =>
hive.sheets.filter(style => style.persist)
.sort((a, b) => String.localeCompare(a.name || "",
b.name || ""))
@@ -674,8 +679,7 @@ var Styles = Module("Styles", {
"-group": hive.name == "user" ? undefined : hive.name,
"-name": style.name || undefined
}
})))
.flatten().array;
})));
}
});

View File

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