1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-04-24 11:51:24 +02:00

Replace expression closures (function expressions - named and dynamic this).

Expression closures are to be axed. See https://bugzil.la/1083458.

Leaving deprecated() and literal() calls and method shorthand syntax
conversions until after the ESR overlap.
This commit is contained in:
Doug Kearns
2015-06-06 23:12:40 +10:00
parent 07b64b3197
commit b236add69d
43 changed files with 876 additions and 520 deletions
+5 -4
View File
@@ -292,7 +292,7 @@ function init() {
if (!(BOOTSTRAP_CONTRACT in Cc)) { if (!(BOOTSTRAP_CONTRACT in Cc)) {
// Use Sandbox to prevent closures over this scope // Use Sandbox to prevent closures over this scope
let sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance()); let sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance());
let factory = Cu.evalInSandbox("({ createInstance: function () this })", sandbox); let factory = Cu.evalInSandbox("({ createInstance: function () { return this; }})", sandbox);
factory.classID = Components.ID("{f541c8b0-fe26-4621-a30b-e77d21721fb5}"); factory.classID = Components.ID("{f541c8b0-fe26-4621-a30b-e77d21721fb5}");
factory.contractID = BOOTSTRAP_CONTRACT; factory.contractID = BOOTSTRAP_CONTRACT;
@@ -372,9 +372,10 @@ function startup(data, reason) {
return Services.io.newFileURI(uri.QueryInterface(Ci.nsIFileURL).file); return Services.io.newFileURI(uri.QueryInterface(Ci.nsIFileURL).file);
}; };
else else
getURI = function getURI(path) getURI = function getURI(path) {
Services.io.newURI("jar:" + Services.io.newFileURI(basePath).spec.replace(/!/g, "%21") + "!" + let base = Services.io.newFileURI(basePath).spec.replace(/!/g, "%21");
"/" + path, null, null); return Services.io.newURI("jar:" + base + "!" + "/" + path, null, null);
};
try { try {
init(); init();
+4 -2
View File
@@ -266,8 +266,10 @@ var Abbreviations = Module("abbreviations", {
list: function (modes, lhs, hives) { list: function (modes, lhs, hives) {
hives = (hives || this.userHives).filter(h => !h.empty); hives = (hives || this.userHives).filter(h => !h.empty);
function abbrevs(hive) function abbrevs(hive) {
hive.merged.filter(ab => (ab.inModes(modes) && ab.lhs.startsWith(lhs))); return hive.merged.filter(a => a.inModes(modes) &&
a.lhs.startsWith(lhs));
}
let list = ["table", {}, let list = ["table", {},
["tr", { highlight: "Title" }, ["tr", { highlight: "Title" },
+5 -2
View File
@@ -10,10 +10,13 @@
var AutoCommand = Struct("event", "filter", "command"); var AutoCommand = Struct("event", "filter", "command");
update(AutoCommand.prototype, { update(AutoCommand.prototype, {
eventName: Class.Memoize(function () this.event.toLowerCase()), eventName: Class.Memoize(function () {
return this.event.toLowerCase();
}),
match: function (event, pattern) { match: function (event, pattern) {
return (!event || this.eventName == event.toLowerCase()) && (!pattern || String(this.filter) === String(pattern)); return (!event || this.eventName == event.toLowerCase()) &&
(!pattern || String(this.filter) === String(pattern));
} }
}); });
+4 -1
View File
@@ -659,7 +659,10 @@ var Bookmarks = Module("bookmarks", {
context.format = bookmarks.format; context.format = bookmarks.format;
iter(extra).forEach(function ([k, v]) { iter(extra).forEach(function ([k, v]) {
if (v != null) if (v != null)
context.filters.push(function (item) item.item[k] != null && this.matchString(v, item.item[k])); context.filters.push(function (item) {
return item.item[k] != null &&
this.matchString(v, item.item[k]);
});
}); });
context.generate = () => values(bookmarkcache.bookmarks); context.generate = () => values(bookmarkcache.bookmarks);
completion.urls(context, tags); completion.urls(context, tags);
+7 -4
View File
@@ -289,7 +289,9 @@ var CommandWidgets = Class("CommandWidgets", {
yield elem; yield elem;
}, },
completionContainer: Class.Memoize(function () this.completionList.parentNode), completionContainer: Class.Memoize(function () {
return this.completionList.parentNode;
}),
contextMenu: Class.Memoize(function () { contextMenu: Class.Memoize(function () {
["copy", "copylink", "selectall"].forEach(function (tail) { ["copy", "copylink", "selectall"].forEach(function (tail) {
@@ -304,10 +306,11 @@ var CommandWidgets = Class("CommandWidgets", {
return document.getElementById("dactyl-contextmenu"); return document.getElementById("dactyl-contextmenu");
}), }),
multilineOutput: Class.Memoize(function () this._whenReady("dactyl-multiline-output", multilineOutput: Class.Memoize(function () {
elem => { return this._whenReady("dactyl-multiline-output", elem => {
highlight.highlightNode(elem.contentDocument.body, "MOW"); highlight.highlightNode(elem.contentDocument.body, "MOW");
}), true), });
}, true),
multilineInput: Class.Memoize(() => document.getElementById("dactyl-multiline-input")), multilineInput: Class.Memoize(() => document.getElementById("dactyl-multiline-input")),
+7 -3
View File
@@ -16,8 +16,10 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
init: function () { init: function () {
window.dactyl = this; window.dactyl = this;
// cheap attempt at compatibility // cheap attempt at compatibility
let prop = { get: deprecated("dactyl", function liberator() dactyl), let prop = {
configurable: true }; get: deprecated("dactyl", function liberator() { return dactyl; }),
configurable: true
};
Object.defineProperty(window, "liberator", prop); Object.defineProperty(window, "liberator", prop);
Object.defineProperty(modules, "liberator", prop); Object.defineProperty(modules, "liberator", prop);
this.commands = {}; this.commands = {};
@@ -255,7 +257,9 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
argCount: "*", argCount: "*",
completer: function (context, args) { completer: function (context, args) {
context.keys.text = util.identity; context.keys.text = util.identity;
context.keys.description = function () seen[this.text] + /*L*/" matching items"; context.keys.description = function () {
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 = Ary(keys(item).join(" ").toLowerCase().split(/[()\s]+/)
+6 -3
View File
@@ -779,7 +779,9 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
context = context.fork("registers"); context = context.fork("registers");
context.keys = { text: util.identity, description: editor.bound.getRegister }; context.keys = { text: util.identity, description: editor.bound.getRegister };
context.match = function (r) !this.filter || this.filter.contains(r); context.match = function (r) {
return !this.filter || this.filter.contains(r);
};
context.fork("clipboard", 0, this, ctxt => { context.fork("clipboard", 0, this, ctxt => {
ctxt.match = context.match; ctxt.match = context.match;
@@ -1327,11 +1329,12 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
mappings.add([modes.TEXT_EDIT, modes.VISUAL], mappings.add([modes.TEXT_EDIT, modes.VISUAL],
["~"], "Switch case of the character under the cursor and move the cursor to the right", ["~"], "Switch case of the character under the cursor and move the cursor to the right",
function ({ count }) { function ({ count }) {
function munger(range) function munger(range) {
String(range).replace(/./g, c => { return String(range).replace(/./g, c => {
let lc = c.toLocaleLowerCase(); let lc = c.toLocaleLowerCase();
return c == lc ? c.toLocaleUpperCase() : lc; return c == lc ? c.toLocaleUpperCase() : lc;
}); });
}
var range = editor.selectedRange; var range = editor.selectedRange;
if (range.collapsed) { if (range.collapsed) {
+12 -4
View File
@@ -1154,10 +1154,18 @@ var Events = Module("events", {
"Pass certain keys through directly for the given URLs", "Pass certain keys through directly for the given URLs",
"sitemap", "", { "sitemap", "", {
flush: function flush() { flush: function flush() {
memoize(this, "filters", function () this.value.filter(f => f(buffer.documentURI))); memoize(this, "filters", function () {
memoize(this, "pass", function () new RealSet(Ary.flatten(this.filters.map(f => f.keys)))); return this.value.filter(f => f(buffer.documentURI));
memoize(this, "commandHive", function hive() Hive(this.filters, "command")); });
memoize(this, "inputHive", function hive() Hive(this.filters, "input")); memoize(this, "pass", function () {
return new RealSet(Ary.flatten(this.filters.map(f => f.keys)));
});
memoize(this, "commandHive", function hive() {
return Hive(this.filters, "command");
});
memoize(this, "inputHive", function hive() {
return Hive(this.filters, "input");
});
}, },
has: function (key) this.pass.has(key) || hasOwnProperty(this.commandHive.stack.mappings, key), has: function (key) this.pass.has(key) || hasOwnProperty(this.commandHive.stack.mappings, key),
+4 -2
View File
@@ -759,8 +759,10 @@ var Hints = Module("hints", {
events.listen(appContent, "scroll", this.resizeTimer.bound.tell, false); events.listen(appContent, "scroll", this.resizeTimer.bound.tell, false);
const Mode = Hints.Mode; const Mode = Hints.Mode;
Mode.prototype.__defineGetter__("matcher", function () Mode.prototype.__defineGetter__("matcher", function () {
options.get("extendedhinttags").getKey(this.name, options.get("hinttags").matcher)); return options.get("extendedhinttags")
.getKey(this.name, options.get("hinttags").matcher);
});
function cleanLoc(loc) { function cleanLoc(loc) {
try { try {
+9 -3
View File
@@ -65,12 +65,16 @@ var History = Module("history", {
let obj = []; let obj = [];
obj.__defineGetter__("index", () => sh.index); obj.__defineGetter__("index", () => sh.index);
obj.__defineSetter__("index", val => { webNav.gotoIndex(val); }); obj.__defineSetter__("index", val => { webNav.gotoIndex(val); });
obj[Symbol.iterator] = function () this.entries(); obj[Symbol.iterator] = function () { return this.entries(); };
for (let item of iter(sh.SHistoryEnumerator, Ci.nsISHEntry)) for (let item of iter(sh.SHistoryEnumerator, Ci.nsISHEntry))
obj.push(update(Object.create(item), { obj.push(update(Object.create(item), {
index: obj.length, index: obj.length,
icon: Class.Memoize(function () services.favicon.getFaviconImageForPage(this.URI).spec) icon: Class.Memoize(function () {
return services.favicon
.getFaviconImageForPage(this.URI)
.spec;
})
})); }));
return obj; return obj;
}, },
@@ -348,7 +352,9 @@ var History = Module("history", {
if (maxItems && context.maxItems == null) if (maxItems && context.maxItems == null)
context.maxItems = 100; context.maxItems = 100;
context.regenerate = true; context.regenerate = true;
context.generate = function () history.get(context.filter, this.maxItems, sort); context.generate = function () {
return history.get(context.filter, this.maxItems, sort);
};
}; };
completion.addUrlCompleter("history", "History", completion.history); completion.addUrlCompleter("history", "History", completion.history);
+6 -2
View File
@@ -46,7 +46,9 @@ var ProcessorStack = Class("ProcessorStack", {
this.processors.unshift(KeyProcessor(modes.BASE, hive)); this.processors.unshift(KeyProcessor(modes.BASE, hive));
}, },
passUnknown: Class.Memoize(function () options.get("passunknown").getKey(this.modes)), passUnknown: Class.Memoize(function () {
return options.get("passunknown").getKey(this.modes);
}),
notify: function () { notify: function () {
events.dbg("NOTIFY()"); events.dbg("NOTIFY()");
@@ -107,7 +109,9 @@ var ProcessorStack = Class("ProcessorStack", {
} }
else if (result !== Events.KILL && !this.actions.length && else if (result !== Events.KILL && !this.actions.length &&
!(this.events[0].isReplay || this.passUnknown || !(this.events[0].isReplay || this.passUnknown ||
this.modes.some(function (m) m.passEvent(this), this.events[0]))) { this.modes.some(function (m) {
return m.passEvent(this);
}, this.events[0]))) {
// No patching processors, this isn't a fake, pass-through // No patching processors, this isn't a fake, pass-through
// event, we're not in pass-through mode, and we're not // event, we're not in pass-through mode, and we're not
// choosing to pass unknown keys. Kill the event and beep. // choosing to pass unknown keys. Kill the event and beep.
+4 -2
View File
@@ -45,10 +45,12 @@ var Map = Class("Map", {
} }
}, },
name: Class.Memoize(function () this.names[0]), name: Class.Memoize(function () { return this.names[0]; }),
/** @property {[string]} All of this mapping's names (key sequences). */ /** @property {[string]} All of this mapping's names (key sequences). */
names: Class.Memoize(function () this._keys.map(k => DOM.Event.canonicalKeys(k))), names: Class.Memoize(function () {
return this._keys.map(k => DOM.Event.canonicalKeys(k));
}),
get toStringParams() { get toStringParams() {
return [this.modes.map(m => m.name), return [this.modes.map(m => m.name),
+6 -4
View File
@@ -47,10 +47,12 @@ var Marks = Module("marks", {
params.offset = buffer.scrollPosition; params.offset = buffer.scrollPosition;
params.path = DOM(buffer.findScrollable(0, false)).xpath; params.path = DOM(buffer.findScrollable(0, false)).xpath;
params.timestamp = Date.now() * 1000; params.timestamp = Date.now() * 1000;
params.equals = function (m) this.location == m.location params.equals = function (m) {
&& this.offset.x == m.offset.x return this.location == m.location &&
&& this.offset.y == m.offset.y this.offset.x == m.offset.x &&
&& this.path == m.path; this.offset.y == m.offset.y &&
this.path == m.path;
};
return params; return params;
}, },
+26 -8
View File
@@ -447,7 +447,9 @@ var Modes = Module("modes", {
description: Messages.Localized(""), description: Messages.Localized(""),
displayName: Class.Memoize(function () this.name.split("_").map(util.capitalize).join(" ")), displayName: Class.Memoize(function () {
return this.name.split("_").map(util.capitalize).join(" ");
}),
isinstance: function isinstance(obj) isinstance: function isinstance(obj)
this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj, this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj,
@@ -468,7 +470,9 @@ var Modes = Module("modes", {
get count() { return !this.insert; }, get count() { return !this.insert; },
_display: Class.Memoize(function _display() this.name.replace(/_/g, " ")), _display: Class.Memoize(function _display() {
return this.name.replace(/_/g, " ");
}),
display: function display() this._display, display: function display() this._display,
@@ -476,15 +480,27 @@ var Modes = Module("modes", {
hidden: false, hidden: false,
input: Class.Memoize(function input() this.insert || this.bases.length && this.bases.some(b => b.input)), input: Class.Memoize(function input() {
return this.insert || this.bases.length &&
this.bases.some(b => b.input);
}),
insert: Class.Memoize(function insert() this.bases.length && this.bases.some(b => b.insert)), insert: Class.Memoize(function insert() {
return this.bases.length && this.bases.some(b => b.insert);
}),
ownsFocus: Class.Memoize(function ownsFocus() this.bases.length && this.bases.some(b => b.ownsFocus)), ownsFocus: Class.Memoize(function ownsFocus() {
return this.bases.length && this.bases.some(b => b.ownsFocus);
}),
passEvent: function passEvent(event) this.input && event.charCode && !(event.ctrlKey || event.altKey || event.metaKey), passEvent: function passEvent(event) {
return this.input && event.charCode &&
!(event.ctrlKey || event.altKey || event.metaKey);
},
passUnknown: Class.Memoize(function () options.get("passunknown").getKey(this.name)), passUnknown: Class.Memoize(function () {
return options.get("passunknown").getKey(this.name);
}),
get mask() { return this; }, get mask() { return this; },
@@ -505,7 +521,9 @@ var Modes = Module("modes", {
StackElement: (function () { StackElement: (function () {
const StackElement = Struct("main", "extended", "params", "saved"); const StackElement = Struct("main", "extended", "params", "saved");
StackElement.className = "Modes.StackElement"; StackElement.className = "Modes.StackElement";
StackElement.defaultValue("params", function () this.main.params); StackElement.defaultValue("params", function () {
return this.main.params;
});
update(StackElement.prototype, { update(StackElement.prototype, {
get toStringParams() { get toStringParams() {
+6 -2
View File
@@ -70,9 +70,13 @@ var MOW = Module("mow", {
get widget() { return this.widgets.multilineOutput; }, get widget() { return this.widgets.multilineOutput; },
widgets: Class.Memoize(function widgets() commandline.widgets), widgets: Class.Memoize(function widgets() {
return commandline.widgets;
}),
body: Class.Memoize(function body() this.widget.contentDocument.documentElement), body: Class.Memoize(function body() {
return this.widget.contentDocument.documentElement;
}),
get document() { return this.widget.contentDocument; }, get document() { return this.widget.contentDocument; },
get window() { return this.widget.contentWindow; }, get window() { return this.widget.contentWindow; },
+6 -2
View File
@@ -62,7 +62,9 @@ var Tabs = Module("tabs", {
cleanup: function cleanup() { cleanup: function cleanup() {
for (let tab of this.allTabs) { for (let tab of this.allTabs) {
let node = function node(class_) document.getAnonymousElementByAttribute(tab, "class", class_); let node = function node(class_) {
return document.getAnonymousElementByAttribute(tab, "class", class_);
};
for (let elem of ["dactyl-tab-icon-number", "dactyl-tab-number"].map(node)) for (let elem of ["dactyl-tab-icon-number", "dactyl-tab-number"].map(node))
if (elem) if (elem)
elem.parentNode.parentNode.removeChild(elem.parentNode); elem.parentNode.parentNode.removeChild(elem.parentNode);
@@ -74,7 +76,9 @@ var Tabs = Module("tabs", {
updateTabCount: function updateTabCount() { updateTabCount: function updateTabCount() {
for (let [i, tab] of iter(this.visibleTabs)) { for (let [i, tab] of iter(this.visibleTabs)) {
let node = function node(class_) document.getAnonymousElementByAttribute(tab, "class", class_); let node = function node(class_) {
return document.getAnonymousElementByAttribute(tab, "class", class_);
};
if (!node("dactyl-tab-number")) { if (!node("dactyl-tab-number")) {
let img = node("tab-icon-image"); let img = node("tab-icon-image");
if (img) { if (img) {
+3 -1
View File
@@ -238,7 +238,9 @@ var Addon = Class("Addon", {
["cancelUninstall", "findUpdates", "getResourceURI", "hasResource", "isCompatibleWith", ["cancelUninstall", "findUpdates", "getResourceURI", "hasResource", "isCompatibleWith",
"uninstall"].forEach(function (prop) { "uninstall"].forEach(function (prop) {
Addon.prototype[prop] = function proxy() apply(this.addon, prop, arguments); Addon.prototype[prop] = function proxy() {
return apply(this.addon, prop, arguments);
};
}); });
["aboutURL", "appDisabled", "applyBackgroundUpdates", "blocklistState", "contributors", "creator", ["aboutURL", "appDisabled", "applyBackgroundUpdates", "blocklistState", "contributors", "creator",
+35 -15
View File
@@ -273,10 +273,12 @@ function apply(obj, meth, args) {
* @default false * @default false
* @returns {Generator} * @returns {Generator}
*/ */
function prototype(obj) function prototype(obj) {
obj.__proto__ || Object.getPrototypeOf(obj) || return obj.__proto__ ||
Object.getPrototypeOf(obj) ||
XPCNativeWrapper.unwrap(obj).__proto__ || XPCNativeWrapper.unwrap(obj).__proto__ ||
Object.getPrototypeOf(XPCNativeWrapper.unwrap(obj)); Object.getPrototypeOf(XPCNativeWrapper.unwrap(obj));
}
function* properties(obj, prototypes) { function* properties(obj, prototypes) {
let orig = obj; let orig = obj;
@@ -796,7 +798,9 @@ function update(target) {
if (typeof desc.value === "function" && target.__proto__ && !(desc.value instanceof Ci.nsIDOMElement /* wtf? */)) { if (typeof desc.value === "function" && target.__proto__ && !(desc.value instanceof Ci.nsIDOMElement /* wtf? */)) {
let func = desc.value.wrapped || desc.value; let func = desc.value.wrapped || desc.value;
if (!func.superapply) { if (!func.superapply) {
func.__defineGetter__("super", function get_super() Object.getPrototypeOf(target)[k]); func.__defineGetter__("super", function get_super() {
return Object.getPrototypeOf(target)[k];
});
func.superapply = function superapply(self, args) { func.superapply = function superapply(self, args) {
let meth = Object.getPrototypeOf(target)[k]; let meth = Object.getPrototypeOf(target)[k];
@@ -918,8 +922,10 @@ Class.objectGlobal = object => {
* *
* @param {Object} desc The property descriptor. * @param {Object} desc The property descriptor.
*/ */
Class.Property = function Property(desc) update( Class.Property = function Property(desc) {
Object.create(Property.prototype), desc || { configurable: true, writable: true }); return update(Object.create(Property.prototype),
desc || { configurable: true, writable: true });
};
Class.Property.prototype.init = () => {}; Class.Property.prototype.init = () => {};
/** /**
* Extends a subclass with a superclass. The subclass's * Extends a subclass with a superclass. The subclass's
@@ -998,7 +1004,9 @@ Class.Memoize = function Memoize(getter, wait)
} }
}; };
this.set = function s_Memoize(val) Class.replaceProperty(this.instance || this, key, val); this.set = function s_Memoize(val) {
return Class.replaceProperty(this.instance || this, key, val);
};
} }
}); });
@@ -1006,8 +1014,8 @@ Class.Memoize = function Memoize(getter, wait)
* Updates the given object with the object in the target class's * Updates the given object with the object in the target class's
* prototype. * prototype.
*/ */
Class.Update = function Update(obj) Class.Update = function Update(obj) {
Class.Property({ return Class.Property({
configurable: true, configurable: true,
enumerable: true, enumerable: true,
writable: true, writable: true,
@@ -1015,12 +1023,15 @@ Class.Update = function Update(obj)
this.value = update({}, target[key], obj); this.value = update({}, target[key], obj);
} }
}); });
};
Class.replaceProperty = function replaceProperty(obj, prop, value) { Class.replaceProperty = function replaceProperty(obj, prop, value) {
Object.defineProperty(obj, prop, { configurable: true, enumerable: true, value: value, writable: true }); Object.defineProperty(obj, prop, { configurable: true, enumerable: true, value: value, writable: true });
return value; return value;
}; };
Class.toString = function toString() "[class " + this.className + "]"; Class.toString = function toString() {
return "[class " + this.className + "]";
};
Class.prototype = { Class.prototype = {
/** /**
* Initializes new instances of this class. Called automatically * Initializes new instances of this class. Called automatically
@@ -1353,8 +1364,12 @@ function Struct(...args) {
members: Ary(args).map((v, k) => [v, k]).toObject() members: Ary(args).map((v, k) => [v, k]).toObject()
}); });
args.forEach(function (name, i) { args.forEach(function (name, i) {
Struct.prototype.__defineGetter__(name, function () this[i]); Struct.prototype.__defineGetter__(name, function () {
Struct.prototype.__defineSetter__(name, function (val) { this[i] = val; }); return this[i];
});
Struct.prototype.__defineSetter__(name, function (val) {
this[i] = val;
});
}); });
return Struct; return Struct;
} }
@@ -1401,9 +1416,12 @@ var StructBase = Class("StructBase", Array, {
*/ */
defaultValue: function defaultValue(key, val) { defaultValue: function defaultValue(key, val) {
let i = this.prototype.members[key]; let i = this.prototype.members[key];
this.prototype.__defineGetter__(i, function () (this[i] = val.call(this))); this.prototype.__defineGetter__(i, function () {
this.prototype.__defineSetter__(i, function (value) return this[i] = val.call(this);
Class.replaceProperty(this, i, value)); });
this.prototype.__defineSetter__(i, function (value) {
return Class.replaceProperty(this, i, value);
});
return this; return this;
}, },
@@ -1728,7 +1746,9 @@ const Iter = Class("Iter", {
this.iter = iter.__iterator__(); this.iter = iter.__iterator__();
if (this.iter.finalize) if (this.iter.finalize)
this.finalize = function finalize() apply(this.iter, "finalize", arguments); this.finalize = function finalize() {
return apply(this.iter, "finalize", arguments);
};
}, },
next: function next() this.iter.next(), next: function next() this.iter.next(),
+9 -5
View File
@@ -22,7 +22,9 @@ function newURI(url, charset, base) {
var Bookmark = Struct("url", "title", "icon", "post", "keyword", "tags", "charset", "id"); var Bookmark = Struct("url", "title", "icon", "post", "keyword", "tags", "charset", "id");
var Keyword = Struct("keyword", "title", "icon", "url"); var Keyword = Struct("keyword", "title", "icon", "url");
Bookmark.defaultValue("icon", function () BookmarkCache.getFavicon(this.url)); Bookmark.defaultValue("icon", function () {
return BookmarkCache.getFavicon(this.url);
});
update(Bookmark.prototype, { update(Bookmark.prototype, {
get extra() { get extra() {
return [ return [
@@ -48,7 +50,7 @@ update(Bookmark.prototype, {
get folder() { get folder() {
let res = []; let res = [];
res.toString = function () this.join("/"); res.toString = function () { return this.join("/"); };
let id = this.id, title; let id = this.id, title;
while ((id = services.bookmarks.getFolderIdForItem(id)) && while ((id = services.bookmarks.getFolderIdForItem(id)) &&
@@ -87,11 +89,13 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), {
"@@iterator": function () values(bookmarkcache.bookmarks), "@@iterator": function () values(bookmarkcache.bookmarks),
bookmarks: Class.Memoize(function () this.load()), bookmarks: Class.Memoize(function () { return this.load(); }),
keywords: Class.Memoize(function () Ary.toObject([[b.keyword, b] keywords: Class.Memoize(function () {
return Ary.toObject([[b.keyword, b]
for (b of this) for (b of this)
if (b.keyword)])), if (b.keyword)]);
}),
rootFolders: ["toolbarFolder", "bookmarksMenuFolder", "unfiledBookmarksFolder"] rootFolders: ["toolbarFolder", "bookmarksMenuFolder", "unfiledBookmarksFolder"]
.map(s => services.bookmarks[s]), .map(s => services.bookmarks[s]),
+6 -2
View File
@@ -260,7 +260,9 @@ var Buffer = Module("Buffer", {
get modules() { return this.topWindow.dactyl.modules; }, get modules() { return this.topWindow.dactyl.modules; },
set modules(val) {}, set modules(val) {},
topWindow: Class.Memoize(function () util.topWindow(this.win)), topWindow: Class.Memoize(function () {
return util.topWindow(this.win);
}),
/** /**
* @property {nsIURI} The current top-level document's URI. * @property {nsIURI} The current top-level document's URI.
@@ -1042,7 +1044,9 @@ var Buffer = Module("Buffer", {
.sort((a, b) => a[1] - b[1]); .sort((a, b) => a[1] - b[1]);
if (offScreen && !reverse) if (offScreen && !reverse)
elems = elems.filter(function (e) e[1] > this, this.topWindow.innerHeight); elems = elems.filter(function (e) {
return e[1] > this, this.topWindow.innerHeight;
});
let idx = Math.min((count || 1) - 1, elems.length); let idx = Math.min((count || 1) - 1, elems.length);
util.assert(idx in elems); util.assert(idx in elems);
+49 -22
View File
@@ -69,7 +69,9 @@ update(CommandOption, {
* @property {object} The option accepts a boolean argument. * @property {object} The option accepts a boolean argument.
* @final * @final
*/ */
BOOL: ArgType("boolean", function parseBoolArg(val) Commands.parseBool(val)), BOOL: ArgType("boolean", function parseBoolArg(val) {
return Commands.parseBool(val);
}),
/** /**
* @property {object} The option accepts a string argument. * @property {object} The option accepts a string argument.
* @final * @final
@@ -84,12 +86,16 @@ update(CommandOption, {
* @property {object} The option accepts an integer argument. * @property {object} The option accepts an integer argument.
* @final * @final
*/ */
INT: ArgType("int", function parseIntArg(val) parseInt(val)), INT: ArgType("int", function parseIntArg(val) {
return parseInt(val);
}),
/** /**
* @property {object} The option accepts a float argument. * @property {object} The option accepts a float argument.
* @final * @final
*/ */
FLOAT: ArgType("float", function parseFloatArg(val) parseFloat(val)), FLOAT: ArgType("float", function parseFloatArg(val) {
return parseFloat(val);
}),
/** /**
* @property {object} The option accepts a string list argument. * @property {object} The option accepts a string list argument.
* E.g. "foo,bar" * E.g. "foo,bar"
@@ -219,21 +225,29 @@ var Command = Class("Command", {
* @property {[string]} All of this command's name specs. e.g., "com[mand]" * @property {[string]} All of this command's name specs. e.g., "com[mand]"
*/ */
specs: null, specs: null,
parsedSpecs: Class.Memoize(function () Command.parseSpecs(this.specs)), parsedSpecs: Class.Memoize(function () {
return Command.parseSpecs(this.specs);
}),
/** @property {[string]} All of this command's short names, e.g., "com" */ /** @property {[string]} All of this command's short names, e.g., "com" */
shortNames: Class.Memoize(function () Ary.compact(this.parsedSpecs.map(n => n[1]))), shortNames: Class.Memoize(function () {
return Ary.compact(this.parsedSpecs.map(n => n[1]));
}),
/** /**
* @property {[string]} All of this command's long names, e.g., "command" * @property {[string]} All of this command's long names, e.g., "command"
*/ */
longNames: Class.Memoize(function () this.parsedSpecs.map(n => n[0])), longNames: Class.Memoize(function () {
return this.parsedSpecs.map(n => n[0]);
}),
/** @property {string} The command's canonical name. */ /** @property {string} The command's canonical name. */
name: Class.Memoize(function () this.longNames[0]), name: Class.Memoize(function () { return this.longNames[0]; }),
/** @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 () this.names = Ary.flatten(this.parsedSpecs)), names: Class.Memoize(function () {
return this.names = Ary.flatten(this.parsedSpecs);
}),
/** @property {string} This command's description, as shown in :listcommands */ /** @property {string} This command's description, as shown in :listcommands */
description: Messages.Localized(""), description: Messages.Localized(""),
@@ -301,17 +315,20 @@ var Command = Class("Command", {
* @property {Array} The options this command takes. * @property {Array} The options this command takes.
* @see Commands@parseArguments * @see Commands@parseArguments
*/ */
options: Class.Memoize(function () options: Class.Memoize(function () {
this._options.map(function (opt) { return this._options.map(function (opt) {
let option = CommandOption.fromArray(opt); let option = CommandOption.fromArray(opt);
option.localeName = ["command", this.name, option.names[0]]; option.localeName = ["command", this.name, option.names[0]];
return option; return option;
}, this)), }, this);
}),
_options: [], _options: [],
optionMap: Class.Memoize(function () Ary(this.options) optionMap: Class.Memoize(function () {
return Ary(this.options)
.map(opt => opt.names.map(name => [name, opt])) .map(opt => opt.names.map(name => [name, opt]))
.flatten().toObject()), .flatten().toObject();
}),
newArgs: function newArgs(base) { newArgs: function newArgs(base) {
let res = Object.create(this.argsPrototype); let res = Object.create(this.argsPrototype);
@@ -582,7 +599,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
} }
for (let name of names) { for (let name of names) {
ex.__defineGetter__(name, function () this._run(name)); ex.__defineGetter__(name, function () { return this._run(name); });
if (name in this._map && !this._map[name].isPlaceholder) if (name in this._map && !this._map[name].isPlaceholder)
this.remove(name); this.remove(name);
} }
@@ -1290,9 +1307,12 @@ var Commands = Module("commands", {
*/$), /U/g, "\\u"), "x") */$), /U/g, "\\u"), "x")
}), }),
validName: Class.Memoize(function validName() util.regexp("^" + this.nameRegexp.source + "$")), validName: Class.Memoize(function validName() {
return util.regexp("^" + this.nameRegexp.source + "$");
}),
commandRegexp: Class.Memoize(function commandRegexp() util.regexp(literal(function () /* commandRegexp: Class.Memoize(function commandRegexp() {
return util.regexp(literal(function () /*
^ ^
(?P<spec> (?P<spec>
(?P<prespace> [:\s]*) (?P<prespace> [:\s]*)
@@ -1309,7 +1329,8 @@ var Commands = Module("commands", {
$ $
*/$), "x", { */$), "x", {
name: this.nameRegexp name: this.nameRegexp
})), });
}),
/** /**
* Parses a complete Ex command. * Parses a complete Ex command.
@@ -1783,12 +1804,18 @@ var Commands = Module("commands", {
}); });
}, },
javascript: function initJavascript(dactyl, modules, window) { javascript: function initJavascript(dactyl, modules, window) {
const { JavaScript } = modules; const { setCompleter } = modules.JavaScript;
JavaScript.setCompleter([CommandHive.prototype.get, CommandHive.prototype.remove], setCompleter([CommandHive.prototype.get,
[function () [[c.names, c.description] for (c of this)]]); CommandHive.prototype.remove],
JavaScript.setCompleter([Commands.prototype.get], [function () {
[function () [[c.names, c.description] for (c of this.iterator())]]); return [[c.names, c.description] for (c of this)];
}]);
setCompleter([Commands.prototype.get],
[function () {
return [[c.names, c.description]
for (c of this.iterator())];
}]);
}, },
mappings: function initMappings(dactyl, modules, window) { mappings: function initMappings(dactyl, modules, window) {
const { commands, mappings, modes } = modules; const { commands, mappings, modes } = modules;
+138 -50
View File
@@ -62,7 +62,9 @@ var CompletionContext = Class("CompletionContext", {
["anchored", "compare", "editor", "_filter", "filterFunc", "forceAnchored", "top"] ["anchored", "compare", "editor", "_filter", "filterFunc", "forceAnchored", "top"]
.forEach(key => self[key] = parent[key]); .forEach(key => self[key] = parent[key]);
self.__defineGetter__("value", function get_value() this.top.value); self.__defineGetter__("value", function get_value() {
return this.top.value;
});
self.offset = parent.offset; self.offset = parent.offset;
self.advance(offset); self.advance(offset);
@@ -88,8 +90,12 @@ var CompletionContext = Class("CompletionContext", {
if (self != this) if (self != this)
return self; return self;
["_caret", "contextList", "maxItems", "onUpdate", "selectionTypes", "tabPressed", "updateAsync", "value"].forEach(function fe(key) { ["_caret", "contextList", "maxItems", "onUpdate", "selectionTypes", "tabPressed", "updateAsync", "value"].forEach(function fe(key) {
self.__defineGetter__(key, function () this.top[key]); self.__defineGetter__(key, function () {
self.__defineSetter__(key, function (val) this.top[key] = val); return this.top[key];
});
self.__defineSetter__(key, function (val) {
this.top[key] = val;
});
}); });
} }
else { else {
@@ -159,7 +165,7 @@ var CompletionContext = Class("CompletionContext", {
* changes its completion list. Only called when * changes its completion list. Only called when
* {@link #updateAsync} is true. * {@link #updateAsync} is true.
*/ */
this.onUpdate = function onUpdate() true; this.onUpdate = function onUpdate() { return true; };
this.runCount = 0; this.runCount = 0;
@@ -167,12 +173,20 @@ var CompletionContext = Class("CompletionContext", {
* @property {CompletionContext} The top-level completion context. * @property {CompletionContext} The top-level completion context.
*/ */
this.top = this; this.top = this;
this.__defineGetter__("incomplete", function get_incomplete() this._incomplete this.__defineGetter__("incomplete", function get_incomplete() {
|| this.contextList.some(c => c.parent && c.incomplete)); return this._incomplete ||
this.__defineGetter__("waitingForTab", function get_waitingForTab() this._waitingForTab this.contextList.some(c => c.parent && c.incomplete);
|| this.contextList.some(c => c.parent && c.waitingForTab)); });
this.__defineSetter__("incomplete", function get_incomplete(val) { this._incomplete = val; }); this.__defineGetter__("waitingForTab", function get_waitingForTab() {
this.__defineSetter__("waitingForTab", function get_waitingForTab(val) { this._waitingForTab = val; }); return this._waitingForTab ||
this.contextList.some(c => c.parent && c.waitingForTab);
});
this.__defineSetter__("incomplete", function get_incomplete(val) {
this._incomplete = val;
});
this.__defineSetter__("waitingForTab", function get_waitingForTab(val) {
this._waitingForTab = val;
});
this.reset(); this.reset();
} }
/** /**
@@ -211,9 +225,11 @@ var CompletionContext = Class("CompletionContext", {
return this; return this;
}, },
__title: Class.Memoize(function __title() this._title.map(s => __title: Class.Memoize(function __title() {
return this._title.map(s =>
typeof s == "string" ? messages.get("completion.title." + s, s) typeof s == "string" ? messages.get("completion.title." + s, s)
: s)), : s);
}),
set title(val) { set title(val) {
delete this.__title; delete this.__title;
@@ -222,7 +238,9 @@ var CompletionContext = Class("CompletionContext", {
get title() { return this.__title; }, get title() { return this.__title; },
get activeContexts() { get activeContexts() {
return this.contextList.filter(function f(c) c.items.length); return this.contextList.filter(function f(c) {
return c.items.length;
});
}, },
// Temporary // Temporary
@@ -238,12 +256,17 @@ var CompletionContext = Class("CompletionContext", {
let self = this; let self = this;
try { try {
let allItems = this.contextList.map(function m(context) context.hasItems && context.items.length); let allItems = this.contextList.map(function m(context) {
return context.hasItems && context.items.length;
});
if (this.cache.allItems && Ary.equals(this.cache.allItems, allItems)) if (this.cache.allItems && Ary.equals(this.cache.allItems, allItems))
return this.cache.allItemsResult; return this.cache.allItemsResult;
this.cache.allItems = allItems; this.cache.allItems = allItems;
let minStart = apply(Math, "min", this.activeContexts.map(function m(c) c.offset)); let minStart = apply(Math, "min",
this.activeContexts.map(function m(c) {
return c.offset;
}));
if (minStart == Infinity) if (minStart == Infinity)
minStart = 0; minStart = 0;
@@ -256,11 +279,13 @@ var CompletionContext = Class("CompletionContext", {
return Ary.flatten(self.activeContexts.map(function m(context) { return Ary.flatten(self.activeContexts.map(function m(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(function m(item) {
return {
text: prefix + item.text, text: prefix + item.text,
result: prefix + item.result, result: prefix + item.result,
__proto__: item __proto__: item
})); };
});
})); }));
} }
}); });
@@ -275,18 +300,30 @@ var CompletionContext = Class("CompletionContext", {
// Temporary // Temporary
get allSubstrings() { get allSubstrings() {
let contexts = this.activeContexts; let contexts = this.activeContexts;
let minStart = apply(Math, "min", contexts.map(function m(c) c.offset)); let minStart = apply(Math, "min",
contexts.map(function m(c) {
return c.offset;
}));
let lists = contexts.map(function m(context) { let lists = contexts.map(function m(context) {
let prefix = context.value.substring(minStart, context.offset); let prefix = context.value.substring(minStart, context.offset);
return context.substrings.map(function m(s) prefix + s); return context.substrings.map(function m(s) {
return prefix + s;
});
}); });
/* TODO: Deal with sub-substrings for multiple contexts again. /* TODO: Deal with sub-substrings for multiple contexts again.
* Possibly. * Possibly.
*/ */
let substrings = lists.reduce( let substrings = lists.reduce(
function r(res, list) res.filter(function f(str) list.some(function s_(s) s.substr(0, str.length) == str)), function r(res, list) {
return res.filter(function f(str) {
return list.some(function s_(s) {
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));
@@ -299,7 +336,9 @@ var CompletionContext = Class("CompletionContext", {
get caret() { return this._caret - this.offset; }, get caret() { return this._caret - this.offset; },
set caret(val) { this._caret = val + this.offset; }, set caret(val) { this._caret = val + this.offset; },
get compare() { return this._compare || function compare() 0; }, get compare() {
return this._compare || function compare() { return 0; };
},
set compare(val) { this._compare = val; }, set compare(val) { this._compare = val; },
get completions() { return this._completions || []; }, get completions() { return this._completions || []; },
@@ -370,10 +409,10 @@ var CompletionContext = Class("CompletionContext", {
let res = { highlight: "" }; let res = { highlight: "" };
function* result(quote) { function* result(quote) {
yield ["context", function p_context() self]; yield ["context", function p_context() { return self; }];
yield ["result", quote ? function p_result() quote[0] + util.trapErrors(1, quote, this.text) + quote[2] yield ["result", quote ? function p_result() { return quote[0] + util.trapErrors(1, quote, this.text) + quote[2]; }
: function p_result() this.text]; : function p_result() { return this.text; }];
yield ["texts", function p_texts() Array.concat(this.text)]; yield ["texts", function p_texts() { return Array.concat(this.text); }];
}; };
for (let i of iter(this.keys, result(this.quote))) { for (let i of iter(this.keys, result(this.quote))) {
@@ -383,10 +422,16 @@ var CompletionContext = Class("CompletionContext", {
// reference any variables. Don't bother with eval context. // reference any variables. Don't bother with eval context.
v = Function("i", "return i" + v); v = Function("i", "return i" + v);
if (typeof v == "function") if (typeof v == "function")
res.__defineGetter__(k, function p_gf() Class.replaceProperty(this, k, v.call(this, this.item, self))); res.__defineGetter__(k, function p_gf() {
return Class.replaceProperty(this, k, v.call(this, this.item, self));
});
else else
res.__defineGetter__(k, function p_gp() Class.replaceProperty(this, k, this.item[v])); res.__defineGetter__(k, function p_gp() {
res.__defineSetter__(k, function p_s(val) Class.replaceProperty(this, k, val)); return Class.replaceProperty(this, k, this.item[v]);
});
res.__defineSetter__(k, function p_s(val) {
Class.replaceProperty(this, k, val);
});
} }
return res; return res;
}, },
@@ -511,7 +556,9 @@ var CompletionContext = Class("CompletionContext", {
// Item prototypes // Item prototypes
if (!this._cache.constructed) { if (!this._cache.constructed) {
let proto = this.itemPrototype; let proto = this.itemPrototype;
this._cache.constructed = items.map(function m(item) ({ __proto__: proto, item: item })); this._cache.constructed = items.map(function m(item) {
return { __proto__: proto, item: item };
});
} }
// Filters // Filters
@@ -598,7 +645,9 @@ var CompletionContext = Class("CompletionContext", {
let quote = this.quote; let quote = this.quote;
if (quote) if (quote)
substrings = substrings.map(function m(str) quote[0] + quote[1](str)); substrings = substrings.map(function m(str) {
return quote[0] + quote[1](str);
});
return this._substrings = substrings; return this._substrings = substrings;
}, },
@@ -658,7 +707,8 @@ var CompletionContext = Class("CompletionContext", {
let step = start > end ? -1 : 1; let step = start > end ? -1 : 1;
start = Math.max(0, start || 0); start = Math.max(0, start || 0);
end = Math.min(items.length, end ? end : items.length); end = Math.min(items.length, end ? end : items.length);
return iter.map(util.range(start, end, step), function m(i) items[i]); return iter.map(util.range(start, end, step),
function m(i) { return items[i]; });
}, },
getRow: function getRow(idx, doc) { getRow: function getRow(idx, doc) {
@@ -876,7 +926,8 @@ var CompletionContext = Class("CompletionContext", {
*/ */
wait: function wait(timeout, interruptable) { wait: function wait(timeout, interruptable) {
this.allItems; this.allItems;
return util.waitFor(function wf() !this.incomplete, this, timeout, interruptable); return util.waitFor(function wf() { return !this.incomplete; },
this, timeout, interruptable);
} }
}, { }, {
Sort: { Sort: {
@@ -924,7 +975,11 @@ var Completion = Module("completion", {
let res = apply(context, "fork", ["run", 0, this, name].concat(args)); let res = apply(context, "fork", ["run", 0, this, name].concat(args));
if (res) { if (res) {
if (Components.stack.caller.name === "runCompleter") // FIXME if (Components.stack.caller.name === "runCompleter") // FIXME
return { items: res.map(function m(i) ({ item: i })) }; return {
items: res.map(function m(i) {
return { item: i };
})
};
context.contexts["/run"].completions = res; context.contexts["/run"].completions = res;
} }
context.wait(null, true); context.wait(null, true);
@@ -933,7 +988,7 @@ var Completion = Module("completion", {
runCompleter: function runCompleter(name, filter, maxItems) { runCompleter: function runCompleter(name, filter, maxItems) {
return apply(this, "_runCompleter", arguments) return apply(this, "_runCompleter", arguments)
.items.map(function m(i) i.item); .items.map(function m(i) { return i.item; });
}, },
listCompleter: function listCompleter(name, filter, maxItems, ...args) { listCompleter: function listCompleter(name, filter, maxItems, ...args) {
@@ -945,15 +1000,25 @@ var Completion = Module("completion", {
let contexts = context.activeContexts; let contexts = context.activeContexts;
if (!contexts.length) if (!contexts.length)
contexts = context.contextList.filter(function f(c) c.hasItems).slice(0, 1); contexts = context.contextList
.filter(function f(c) {
return c.hasItems;
})
.slice(0, 1);
if (!contexts.length) if (!contexts.length)
contexts = context.contextList.slice(-1); contexts = context.contextList.slice(-1);
modules.commandline.commandOutput( modules.commandline.commandOutput(
["div", { highlight: "Completions" }, ["div", { highlight: "Completions" },
template.map(contexts, function m(context) template.map(contexts, function m(context) {
[template.completionRow(context.title, "CompTitle"), return [template.completionRow(context.title, "CompTitle"),
template.map(context.items, function m(item) context.createRow(item), null, 100)])]); template.map(context.items,
function m(item) {
return context.createRow(item);
},
null,
100)];
})]);
} }
}), }),
@@ -972,7 +1037,9 @@ var Completion = Module("completion", {
context.quote = context.quote || ["", util.identity, ""]; context.quote = context.quote || ["", util.identity, ""];
let quote = context.quote[1]; let quote = context.quote[1];
context.quote[1] = function quote_1(str) quote(str.replace(/!/g, escape)); context.quote[1] = function quote_1(str) {
return quote(str.replace(/!/g, escape));
};
} }
if (this.options["urlseparator"]) if (this.options["urlseparator"])
@@ -1029,8 +1096,14 @@ var Completion = Module("completion", {
let words = context.filter.toLowerCase().split(/\s+/g); let words = context.filter.toLowerCase().split(/\s+/g);
context.hasItems = true; context.hasItems = true;
context.completions = context.completions.filter(function f({ url, title }) context.completions =
words.every(function e(w) (url + " " + title).toLowerCase().indexOf(w) >= 0)); context.completions
.filter(function f({ url, title }) {
return words.every(function e(w) {
return (url + " " + title)
.toLowerCase().indexOf(w) >= 0;
})
});
context.format = this.modules.bookmarks.format; context.format = this.modules.bookmarks.format;
context.keys.extra = function k_extra(item) { context.keys.extra = function k_extra(item) {
@@ -1078,9 +1151,13 @@ var Completion = Module("completion", {
} }
if (tags) if (tags)
context.filters.push(function filter_(item) tags. context.filters.push(function filter_(item) {
every(function e(tag) (item.tags || []). return tags.every(function e(tag) {
some(function s(t) !compare(tag, t)))); return (item.tags || []).some(function s(t) {
return !compare(tag, t);
});
});
});
context.anchored = false; context.anchored = false;
if (!context.title) if (!context.title)
@@ -1095,13 +1172,18 @@ var Completion = Module("completion", {
// accept them if all tokens match either the URL or the title. // accept them if all tokens match either the URL or the title.
// Filter out all directly matching strings. // Filter out all directly matching strings.
let match = context.filters[0]; let match = context.filters[0];
context.filters[0] = function filters_0(item) !match.call(this, item); context.filters[0] = function filters_0(item) {
!match.call(this, item);
};
// and all that don't match the tokens. // and all that don't match the tokens.
let tokens = context.filter.split(/\s+/); let tokens = context.filter.split(/\s+/);
context.filters.push(function filter_(item) tokens.every( context.filters.push(function filter_(item) {
function e(tok) contains(item.url, tok) || return tokens.every(function e(tok) {
contains(item.title, tok))); return contains(item.url, tok) ||
contains(item.title, tok);
});
});
let re = RegExp(tokens.filter(util.identity).map(util.regexp.escape).join("|"), "g"); let re = RegExp(tokens.filter(util.identity).map(util.regexp.escape).join("|"), "g");
function highlight(item, text, i) { function highlight(item, text, i) {
@@ -1139,7 +1221,9 @@ var Completion = Module("completion", {
["div", { highlight: "Completions" }, ["div", { highlight: "Completions" },
template.completionRow(["Context", "Title"], "CompTitle"), template.completionRow(["Context", "Title"], "CompTitle"),
template.map(completion.contextList || [], template.map(completion.contextList || [],
function m(item) template.completionRow(item, "CompItem"))]); function m(item) {
return template.completionRow(item, "CompItem");
})]);
}, },
{ {
argCount: "*", argCount: "*",
@@ -1169,7 +1253,11 @@ var Completion = Module("completion", {
return first == val || second == val; return first == val || second == val;
}, },
has: function () { has: function () {
let test = function test(val) this.value.some(function s(value) this.checkHas(value, val), this); let test = function test(val) {
return this.value.some(function s(value) {
return this.checkHas(value, val)
}, this);
};
return Array.some(arguments, test, this); return Array.some(arguments, test, this);
} }
}; };
+20 -8
View File
@@ -88,7 +88,9 @@ var ConfigBase = Class("ConfigBase", {
"resource://dactyl-local/config.json" "resource://dactyl-local/config.json"
], ],
configs: Class.Memoize(function () this.configFiles.map(url => JSON.parse(File.readURL(url)))), configs: Class.Memoize(function () {
return this.configFiles.map(url => JSON.parse(File.readURL(url)));
}),
loadConfig: function loadConfig(documentURL) { loadConfig: function loadConfig(documentURL) {
@@ -211,7 +213,9 @@ var ConfigBase = Class("ConfigBase", {
/** /**
* The current dactyl locale. * The current dactyl locale.
*/ */
locale: Class.Memoize(function () this.bestLocale(this.locales)), locale: Class.Memoize(function () {
return this.bestLocale(this.locales);
}),
/** /**
* The current application locale. * The current application locale.
@@ -237,7 +241,9 @@ var ConfigBase = Class("ConfigBase", {
if (f.isDirectory())).array; if (f.isDirectory())).array;
} }
let exists = function exists(pkg) services["resource:"].hasSubstitution("dactyl-locale-" + pkg); let exists = function exists(pkg) {
return services["resource:"].hasSubstitution("dactyl-locale-" + pkg);
};
return Ary.uniq([this.appLocale, this.appLocale.replace(/-.*/, "")] return Ary.uniq([this.appLocale, this.appLocale.replace(/-.*/, "")]
.filter(exists) .filter(exists)
@@ -415,11 +421,12 @@ var ConfigBase = Class("ConfigBase", {
get fileExt() { return this.name.slice(0, -6); }, get fileExt() { return this.name.slice(0, -6); },
dtd: Class.Memoize(function () dtd: Class.Memoize(function () {
iter(this.dtdExtra, return iter(this.dtdExtra,
(["dactyl." + k, v] for ([k, v] of iter(config.dtdDactyl))), (["dactyl." + k, v] for ([k, v] of iter(config.dtdDactyl))),
(["dactyl." + s, config[s]] for (s of config.dtdStrings))) (["dactyl." + s, config[s]] for (s of config.dtdStrings)))
.toObject()), .toObject();
}),
dtdDactyl: memoize({ dtdDactyl: memoize({
get name() { return config.name; }, get name() { return config.name; },
@@ -435,7 +442,9 @@ var ConfigBase = Class("ConfigBase", {
"list.mailto": Class.Memoize(() => config.name + "@googlegroups.com"), "list.mailto": Class.Memoize(() => config.name + "@googlegroups.com"),
"list.href": Class.Memoize(() => "http://groups.google.com/group/" + config.name), "list.href": Class.Memoize(() => "http://groups.google.com/group/" + config.name),
"hg.latest": Class.Memoize(function () this.code + "source/browse/"), // XXX "hg.latest": Class.Memoize(function () {
return this.code + "source/browse/"; // XXX
}),
"irc": "irc://irc.oftc.net/#pentadactyl" "irc": "irc://irc.oftc.net/#pentadactyl"
}), }),
@@ -517,7 +526,10 @@ var ConfigBase = Class("ConfigBase", {
return this.browser.mPanelContainer.boxObject.height; return this.browser.mPanelContainer.boxObject.height;
}, },
tabStrip: Class.Memoize(function () document.getElementById("TabsToolbar") || this.tabbrowser.mTabContainer) tabStrip: Class.Memoize(function () {
return document.getElementById("TabsToolbar") ||
this.tabbrowser.mTabContainer;
})
}), }),
/** /**
+29 -13
View File
@@ -15,7 +15,9 @@ lazyRequire("overlay", ["overlay"]);
lazyRequire("storage", ["File"]); lazyRequire("storage", ["File"]);
lazyRequire("template", ["template"]); lazyRequire("template", ["template"]);
var Const = function Const(val) Class.Property({ enumerable: true, value: val }); var Const = function Const(val) {
return Class.Property({ enumerable: true, value: val });
};
var Group = Class("Group", { var Group = Class("Group", {
init: function init(name, description, filter, persist) { init: function init(name, description, filter, persist) {
@@ -93,7 +95,9 @@ var Group = Class("Group", {
}); });
}, },
defaultFilter: Class.Memoize(function () this.compileFilter(["*"])) defaultFilter: Class.Memoize(function () {
return this.compileFilter(["*"]);
})
}); });
var Contexts = Module("contexts", { var Contexts = Module("contexts", {
@@ -204,13 +208,15 @@ var Contexts = Module("contexts", {
}); });
memoize(contexts.hives, name, memoize(contexts.hives, name,
() => Object.create(Object.create(contexts.hiveProto, () => Object.create(
Object.create(contexts.hiveProto,
{ _hive: { value: name } }))); { _hive: { value: name } })));
memoize(contexts.groupsProto, name, memoize(contexts.groupsProto, name, function () {
function () [group[name] return [group[name]
for (group of values(this.groups)) for (group of values(this.groups))
if (hasOwnProperty(group, name))]); if (hasOwnProperty(group, name))];
});
}, },
get toStringParams() { return [this.name, this.Hive]; } get toStringParams() { return [this.name, this.Hive]; }
@@ -397,11 +403,13 @@ var Contexts = Module("contexts", {
return frame; return frame;
}, },
groups: Class.Memoize(function () this.matchingGroups()), groups: Class.Memoize(function () { return this.matchingGroups(); }),
allGroups: Class.Memoize(function () Object.create(this.groupsProto, { allGroups: Class.Memoize(function () {
return Object.create(this.groupsProto, {
groups: { value: this.initializedGroups() } groups: { value: this.initializedGroups() }
})), });
}),
matchingGroups: function (uri) Object.create(this.groupsProto, { matchingGroups: function (uri) Object.create(this.groupsProto, {
groups: { value: this.activeGroups(uri) } groups: { value: this.activeGroups(uri) }
@@ -443,7 +451,9 @@ var Contexts = Module("contexts", {
group = this.Group(name, description, filter, persist); group = this.Group(name, description, filter, persist);
this.groupList.unshift(group); this.groupList.unshift(group);
this.groupMap[name] = group; this.groupMap[name] = group;
this.hiveProto.__defineGetter__(name, function () group[this._hive]); this.hiveProto.__defineGetter__(name, function () {
return group[this._hive];
});
} }
if (replace) { if (replace) {
@@ -553,9 +563,11 @@ var Contexts = Module("contexts", {
break; break;
case "-ex": case "-ex":
action = function action() modules.commands action = function action() {
return modules.commands
.execute(action.macro, makeParams(this, arguments), .execute(action.macro, makeParams(this, arguments),
false, null, action.context); false, null, action.context);
};
action.macro = util.compileMacro(rhs, true); action.macro = util.compileMacro(rhs, true);
action.context = this.context && update({}, this.context); action.context = this.context && update({}, this.context);
break; break;
@@ -571,7 +583,9 @@ var Contexts = Module("contexts", {
break; break;
} }
action.toString = function toString() (type === default_ ? "" : type + " ") + rhs; action.toString = function toString() {
return (type === default_ ? "" : type + " ") + rhs;
};
args = null; args = null;
return action; return action;
}, },
@@ -608,7 +622,9 @@ var Contexts = Module("contexts", {
get persist() { return this.group.persist; }, get persist() { return this.group.persist; },
set persist(val) { this.group.persist = val; }, set persist(val) { this.group.persist = val; },
prefix: Class.Memoize(function () this.name === "builtin" ? "" : this.name + ":"), prefix: Class.Memoize(function () {
return this.name === "builtin" ? "" : this.name + ":";
}),
get toStringParams() { return [this.name]; } get toStringParams() { return [this.name]; }
}) })
+24 -10
View File
@@ -150,7 +150,7 @@ var DOM = Class("DOM", {
} }
if (DOM.isJSONXML(val)) if (DOM.isJSONXML(val))
val = (function () this).bind(val); val = (function () { return this; }).bind(val);
if (callable(val)) if (callable(val))
return this.each(function (elem, i) { return this.each(function (elem, i) {
@@ -539,8 +539,10 @@ var DOM = Class("DOM", {
let encodeComponent = encodeURIComponent; let encodeComponent = encodeURIComponent;
if (charset !== "UTF-8") if (charset !== "UTF-8")
encodeComponent = function encodeComponent(str) encodeComponent = function encodeComponent(str) {
escape(converter.ConvertFromUnicode(str) + converter.Finish()); return escape(converter.ConvertFromUnicode(str) +
converter.Finish());
};
let elems = []; let elems = [];
if (field instanceof Ci.nsIDOMHTMLInputElement && field.type == "submit") if (field instanceof Ci.nsIDOMHTMLInputElement && field.type == "submit")
@@ -1122,11 +1124,21 @@ var DOM = Class("DOM", {
return this; return this;
}, },
code_key: Class.Memoize(function (prop) this.init()[prop]), code_key: Class.Memoize(function (prop) {
code_nativeKey: Class.Memoize(function (prop) this.init()[prop]), return this.init()[prop];
keyTable: Class.Memoize(function (prop) this.init()[prop]), }),
key_code: Class.Memoize(function (prop) this.init()[prop]), code_nativeKey: Class.Memoize(function (prop) {
key_key: Class.Memoize(function (prop) this.init()[prop]), return this.init()[prop];
}),
keyTable: Class.Memoize(function (prop) {
return this.init()[prop];
}),
key_code: Class.Memoize(function (prop) {
return this.init()[prop];
}),
key_key: Class.Memoize(function (prop) {
return this.init()[prop];
}),
pseudoKeys: new RealSet(["count", "leader", "nop", "pass"]), pseudoKeys: new RealSet(["count", "leader", "nop", "pass"]),
/** /**
@@ -1927,8 +1939,10 @@ var DOM = Class("DOM", {
dactyl: NS dactyl: NS
}, },
namespaceNames: Class.Memoize(function () namespaceNames: Class.Memoize(function () {
iter(this.namespaces).map(([k, v]) => ([v, k])).toObject()) return iter(this.namespaces).map(([k, v]) => ([v, k]))
.toObject();
})
}); });
Object.keys(DOM.Event.types).forEach(function (event) { Object.keys(DOM.Event.types).forEach(function (event) {
+3 -1
View File
@@ -750,7 +750,9 @@ var RangeFind = Class("RangeFind", {
this.save(); this.save();
}, },
docShell: Class.Memoize(function () util.docShell(this.window)), docShell: Class.Memoize(function () {
return util.docShell(this.window);
}),
intersects: function (range) RangeFind.intersects(this.range, range), intersects: function (range) RangeFind.intersects(this.range, range),
+3 -2
View File
@@ -80,13 +80,14 @@ var Help = Module("Help", {
init: function init() { init: function init() {
this.initialized = false; this.initialized = false;
function Loop(fn) function Loop(fn) {
function (uri, path) { return function (uri, path) {
if (!help.initialized) if (!help.initialized)
return RedirectChannel(uri.spec, uri, 2, return RedirectChannel(uri.spec, uri, 2,
"Initializing. Please wait..."); "Initializing. Please wait...");
return fn.apply(this, arguments); return fn.apply(this, arguments);
};
} }
update(services["dactyl:"].providers, { update(services["dactyl:"].providers, {
+19 -11
View File
@@ -17,7 +17,9 @@ var Highlight = Struct("class", "selector", "sites",
"value", "extends", "agent", "value", "extends", "agent",
"base", "baseClass", "style"); "base", "baseClass", "style");
Highlight.liveProperty = function (name, prop) { Highlight.liveProperty = function (name, prop) {
this.prototype.__defineGetter__(name, function () this.get(name)); this.prototype.__defineGetter__(name, function () {
return this.get(name);
});
this.prototype.__defineSetter__(name, function (val) { this.prototype.__defineSetter__(name, function (val) {
if (isObject(val) && name !== "style") { if (isObject(val) && name !== "style") {
if (isArray(val)) if (isArray(val))
@@ -45,22 +47,28 @@ Highlight.liveProperty("selector", "css");
Highlight.liveProperty("sites"); Highlight.liveProperty("sites");
Highlight.liveProperty("style", "css"); Highlight.liveProperty("style", "css");
Highlight.defaultValue("baseClass", function () /^(\w*)/.exec(this.class)[0]); Highlight.defaultValue("baseClass", function () {
return /^(\w*)/.exec(this.class)[0];
});
Highlight.defaultValue("selector", function () highlight.selector(this.class)); Highlight.defaultValue("selector", function () {
return highlight.selector(this.class);
});
Highlight.defaultValue("sites", function () Highlight.defaultValue("sites", function () {
this.base ? this.base.sites return this.base ? this.base.sites
: ["resource://dactyl*", "dactyl:*", "file://*"].concat( : ["resource://dactyl*", "dactyl:*", "file://*"]
highlight.styleableChrome)); .concat(highlight.styleableChrome);
});
Highlight.defaultValue("style", function () Highlight.defaultValue("style", function () {
styles.system.add("highlight:" + this.class, this.sites, this.css, this.agent, true)); return styles.system.add("highlight:" + this.class, this.sites, this.css, this.agent, true);
});
Highlight.defaultValue("defaultExtends", () => []); Highlight.defaultValue("defaultExtends", () => []);
Highlight.defaultValue("defaultValue", () => ""); Highlight.defaultValue("defaultValue", () => "");
Highlight.defaultValue("extends", function () this.defaultExtends); Highlight.defaultValue("extends", function () { return this.defaultExtends; });
Highlight.defaultValue("value", function () this.defaultValue); Highlight.defaultValue("value", function () { return this.defaultValue; });
update(Highlight.prototype, { update(Highlight.prototype, {
get base() { get base() {
+6 -2
View File
@@ -837,7 +837,9 @@ unlet s:cpo_save
sep = sep || " "; sep = sep || " ";
let width = 0; let width = 0;
let lines = []; let lines = [];
lines.__defineGetter__("last", function () this[this.length - 1]); lines.__defineGetter__("last", function () {
return this[this.length - 1];
});
for (let item of values(items.array || items)) { for (let item of values(items.array || items)) {
if (item.length > width && (!lines.length || lines.last.length > 1)) { if (item.length > width && (!lines.length || lines.last.length > 1)) {
@@ -1056,7 +1058,9 @@ unlet s:cpo_save
dir = dir.replace("/+$", "") + "/"; dir = dir.replace("/+$", "") + "/";
completion.file(context, true, dir + context.filter); completion.file(context, true, dir + context.filter);
context.title[0] = dir; context.title[0] = dir;
context.keys.text = function (f) this.path.substr(dir.length); context.keys.text = function (f) {
return this.path.substr(dir.length);
};
}); });
}; };
+15 -6
View File
@@ -43,13 +43,17 @@ var JavaScript = Module("javascript", {
} }
}), }),
globals: Class.Memoize(function () [ globals: Class.Memoize(function () {
return [
[this.modules.userContext, /*L*/"Global Variables"], [this.modules.userContext, /*L*/"Global Variables"],
[this.modules, "modules"], [this.modules, "modules"],
[this.window, "window"] [this.window, "window"]
]), ];
}),
toplevel: Class.Memoize(function () this.modules.jsmodules), toplevel: Class.Memoize(function () {
return this.modules.jsmodules;
}),
lazyInit: true, lazyInit: true,
@@ -358,7 +362,9 @@ var JavaScript = Module("javascript", {
// Constants are unsorted, and appear before other non-null strings. // Constants are unsorted, and appear before other non-null strings.
// Other strings are sorted in the default manner. // Other strings are sorted in the default manner.
let isnan = function isnan(item) item != '' && isNaN(item); let isnan = function isnan(item) {
return item != '' && isNaN(item);
};
let compare = base.compare; let compare = base.compare;
base.compare = function (a, b) { base.compare = function (a, b) {
@@ -617,7 +623,10 @@ var JavaScript = Module("javascript", {
return null; return null;
}, },
magicalNames: Class.Memoize(function () Object.getOwnPropertyNames(Cu.Sandbox(this.window), true).sort()), magicalNames: Class.Memoize(function () {
return Object.getOwnPropertyNames(Cu.Sandbox(this.window), true)
.sort();
}),
/** /**
* A list of properties of the global object which are not * A list of properties of the global object which are not
@@ -706,7 +715,7 @@ var JavaScript = Module("javascript", {
modes.addMode("REPL", { modes.addMode("REPL", {
description: "JavaScript Read Eval Print Loop", description: "JavaScript Read Eval Print Loop",
bases: [modes.COMMAND_LINE], bases: [modes.COMMAND_LINE],
displayName: Class.Memoize(function () this.name) displayName: Class.Memoize(function () { return this.name; })
}); });
}, },
commandline: function initCommandLine(dactyl, modules, window) { commandline: function initCommandLine(dactyl, modules, window) {
+4 -2
View File
@@ -195,7 +195,8 @@ var Modules = function Modules(window) {
config.loadStyles(); config.loadStyles();
overlay.overlayWindow(Object.keys(config.overlays), overlay.overlayWindow(Object.keys(config.overlays),
function _overlay(window) ({ function _overlay(window) {
return {
ready: function onInit(document) { ready: function onInit(document) {
const modules = Modules(window); const modules = Modules(window);
modules.moduleManager = this; modules.moduleManager = this;
@@ -388,7 +389,8 @@ overlay.overlayWindow(Object.keys(config.overlays),
if (!parents || ~parents.indexOf(k)) if (!parents || ~parents.indexOf(k))
util.trapErrors(v); util.trapErrors(v);
} }
})); };
});
endModule(); endModule();
+16 -9
View File
@@ -39,14 +39,17 @@ var Messages = Module("messages", {
services.stringBundle.flushBundles(); services.stringBundle.flushBundles();
}, },
bundles: Class.Memoize(function () bundles: Class.Memoize(function () {
Ary.uniq([JSMLoader.getTarget("dactyl://locale/" + this.name + ".properties"), let urls = [
JSMLoader.getTarget("dactyl://locale-local/" + this.name + ".properties"), JSMLoader.getTarget("dactyl://locale/"),
"resource://dactyl-locale/en-US/" + this.name + ".properties", JSMLoader.getTarget("dactyl://locale-local/"),
"resource://dactyl-locale-local/en-US/" + this.name + ".properties"], "resource://dactyl-locale/en-US/",
true) "resource://dactyl-locale-local/en-US/"
].map(url => url + this.name + ".properties");
return Ary.uniq(urls, true)
.map(services.stringBundle.createBundle) .map(services.stringBundle.createBundle)
.filter(function (bundle) { .filter(bundle => {
try { try {
bundle.getSimpleEnumeration(); bundle.getSimpleEnumeration();
return true; return true;
@@ -54,7 +57,8 @@ var Messages = Module("messages", {
catch (e) { catch (e) {
return false; return false;
} }
})), });
}),
iterate: function* () { iterate: function* () {
let seen = new RealSet; let seen = new RealSet;
@@ -166,7 +170,10 @@ var Messages = Module("messages", {
let value = this[_prop]; let value = this[_prop];
function getter(key, default_) { function getter(key, default_) {
return function getter() messages.get([name, key].join("."), default_); return function getter() {
return messages.get([name, key].join("."),
default_);
};
} }
if (value != null) { if (value != null) {
+22 -9
View File
@@ -272,7 +272,7 @@ var Option = Class("Option", {
name: null, name: null,
/** @property {[string]} All names by which this option is identified. */ /** @property {[string]} All names by which this option is identified. */
names: Class.Memoize(function () this.realNames), names: Class.Memoize(function () { return this.realNames; }),
/** /**
* @property {string} The option's data type. One of: * @property {string} The option's data type. One of:
@@ -461,7 +461,9 @@ var Option = Class("Option", {
re.bang = bang; re.bang = bang;
re.result = result !== undefined ? result : !bang; re.result = result !== undefined ? result : !bang;
re.key = re.bang + Option.quote(util.regexp.getSource(re), /^!|:/); re.key = re.bang + Option.quote(util.regexp.getSource(re), /^!|:/);
re.toString = function () Option.unparseRegexp(this, keepQuotes); re.toString = function () {
return Option.unparseRegexp(this, keepQuotes);
};
return re; return re;
}, },
@@ -705,15 +707,21 @@ var Option = Class("Option", {
// NOTE: Vim doesn't prepend if there's a match in the current value // NOTE: Vim doesn't prepend if there's a match in the current value
return uniq(Array.concat(values, this.value), true); return uniq(Array.concat(values, this.value), true);
case "-": case "-":
return this.value.filter(function (item) !this.has(item), new RealSet(values)); return this.value.filter(function (item) {
return !this.has(item), new RealSet(values);
});
case "=": case "=":
if (invert) { if (invert) {
let old = this.value.map(String); let old = this.value.map(String);
let new_ = values.map(String); let new_ = values.map(String);
let map = Ary(this.value).concat(values).map(val => [String(val), val]).toObject(); let map = Ary(this.value).concat(values).map(val => [String(val), val]).toObject();
let keepValues = old.filter(function (item) !this.has(item), new RealSet(new_)); let keepValues = old.filter(function (item) {
let addValues = new_.filter(function (item) !this.has(item), new RealSet(old)); return !this.has(item);
}, new RealSet(new_));
let addValues = new_.filter(function (item) {
return !this.has(item);
}, new RealSet(old));
return addValues.concat(keepValues).map(s => map[s]); return addValues.concat(keepValues).map(s => map[s]);
} }
return values; return values;
@@ -816,8 +824,9 @@ var Option = Class("Option", {
}, this); }, this);
update(BooleanOption.prototype, { update(BooleanOption.prototype, {
names: Class.Memoize(function () names: Class.Memoize(function () {
Ary.flatten([[name, "no" + name] for (name of this.realNames)])) return Ary.flatten([[name, "no" + name] for (name of this.realNames)]);
})
}); });
var OptionHive = Class("OptionHive", Contexts.Hive, { var OptionHive = Class("OptionHive", Contexts.Hive, {
@@ -982,8 +991,12 @@ var Options = Module("options", {
memoize(this._options, this._options.length, closure); memoize(this._options, this._options.length, closure);
// quickly access options with options["wildmode"]: // quickly access options with options["wildmode"]:
this.__defineGetter__(name, function () this._optionMap[name].value); this.__defineGetter__(name, function () {
this.__defineSetter__(name, function (value) { this._optionMap[name].value = value; }); return this._optionMap[name].value;
});
this.__defineSetter__(name, function (value) {
this._optionMap[name].value = value;
});
} }
}; };
}, },
+20 -9
View File
@@ -211,23 +211,28 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
filter = filter.trim(); filter = filter.trim();
if (filter === "*") if (filter === "*")
var test = function test(uri) true; var test = function test(uri) { return true; };
else if (!/^(?:[a-z-]+:|[a-z-.]+$)/.test(filter)) { else if (!/^(?:[a-z-]+:|[a-z-.]+$)/.test(filter)) {
let re = util.regexp(filter); let re = util.regexp(filter);
test = function test(uri) re.test(uri.spec); test = function test(uri) { return re.test(uri.spec); };
} }
else if (/[*]$/.test(filter)) { else if (/[*]$/.test(filter)) {
let re = RegExp("^" + util.regexp.escape(filter.substr(0, filter.length - 1))); let re = RegExp("^" + util.regexp.escape(filter.substr(0, filter.length - 1)));
test = function test(uri) re.test(uri.spec); test = function test(uri) { return re.test(uri.spec); };
test.re = re; test.re = re;
} }
else if (/[\/:]/.test(filter)) { else if (/[\/:]/.test(filter)) {
test = function test(uri) uri.spec === filter; test = function test(uri) { return uri.spec === filter; };
test.exact = true; test.exact = true;
} }
else else
test = function test(uri) { try { return util.isSubdomain(uri.host, filter); } catch (e) { return false; } }; test = function test(uri) {
test.toString = function toString() filter; try {
return util.isSubdomain(uri.host, filter);
}
catch (e) { return false; }
};
test.toString = function toString() { return filter; };
test.key = filter; test.key = filter;
} }
if (arguments.length < 2) if (arguments.length < 2)
@@ -417,7 +422,7 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
delete desc.value; delete desc.value;
delete desc.writable; delete desc.writable;
desc.get = function get() value; desc.get = function get() { return value; }
desc.set = function set(val) { desc.set = function set(val) {
if (!callable(val) || !Function.prototype.toString(val).contains(sentinel)) if (!callable(val) || !Function.prototype.toString(val).contains(sentinel))
Class.replaceProperty(this, k, val); Class.replaceProperty(this, k, val);
@@ -434,8 +439,14 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
if (callable(value)) { if (callable(value)) {
var sentinel = "(function DactylOverlay() {}())"; var sentinel = "(function DactylOverlay() {}())";
value.toString = function toString() toString.toString.call(this).replace(/\}?$/, sentinel + "; $&"); value.toString = function toString() {
value.toSource = function toSource() toSource.toSource.call(this).replace(/\}?$/, sentinel + "; $&"); return toString.toString.call(this)
.replace(/\}?$/, sentinel + "; $&");
};
value.toSource = function toSource() {
return toSource.toSource.call(this)
.replace(/\}?$/, sentinel + "; $&");
};
} }
} }
catch (e) { catch (e) {
+11 -4
View File
@@ -219,11 +219,12 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
if (this._prefContexts.length) if (this._prefContexts.length)
this._prefContexts[this._prefContexts.length - 1][name] = this.get(name, null); this._prefContexts[this._prefContexts.length - 1][name] = this.get(name, null);
function assertType(needType) function assertType(needType) {
util.assert(type === Ci.nsIPrefBranch.PREF_INVALID || type === needType, return util.assert(type === Ci.nsIPrefBranch.PREF_INVALID || type === needType,
type === Ci.nsIPrefBranch.PREF_INT type === Ci.nsIPrefBranch.PREF_INT
? /*L*/"E521: Number required after =: " + name + "=" + value ? /*L*/"E521: Number required after =: " + name + "=" + value
: /*L*/"E474: Invalid argument: " + name + "=" + value); : /*L*/"E474: Invalid argument: " + name + "=" + value);
}
let type = this.branch.getPrefType(name); let type = this.branch.getPrefType(name);
try { try {
@@ -434,8 +435,14 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
}; };
}, },
javascript: function init_javascript(dactyl, modules) { javascript: function init_javascript(dactyl, modules) {
modules.JavaScript.setCompleter([this.get, this.safeSet, this.set, this.reset, this.toggle], const { setCompleter } = modules.JavaScript;
[function (context) (context.anchored=false, this.getNames().map(pref => [pref, ""]))]);
setCompleter([this.get, this.safeSet, this.set,
this.reset, this.toggle],
[function (context) {
context.anchored=false;
return this.getNames().map(pref => [pref, ""]);
}]);
} }
}); });
+7 -3
View File
@@ -233,7 +233,8 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
let branch = Item.PREFIX + Item.BRANCH; let branch = Item.PREFIX + Item.BRANCH;
overlay.overlayWindow("chrome://browser/content/sanitize.xul", overlay.overlayWindow("chrome://browser/content/sanitize.xul",
function (win) prefOverlay(branch, false, { function (win) {
return prefOverlay(branch, false, {
append: { append: {
itemList: [ itemList: [
["listitem", { xmlns: "xul", label: /*L*/"See :help privacy for the following:", ["listitem", { xmlns: "xul", label: /*L*/"See :help privacy for the following:",
@@ -259,7 +260,8 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
} }
}); });
} }
})); });
});
} }
}); });
}, },
@@ -394,7 +396,9 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
session: 8 session: 8
}, },
UNPERMS: Class.Memoize(function () iter(this.PERMS).map(Array.reverse).toObject()), UNPERMS: Class.Memoize(function () {
return iter(this.PERMS).map(Array.reverse).toObject();
}),
COMMANDS: { COMMANDS: {
"unset": /*L*/"Unset", "unset": /*L*/"Unset",
+6 -3
View File
@@ -178,10 +178,13 @@ var Services = Module("Services", {
addClass: function addClass(name, class_, ifaces, init, quiet) { addClass: function addClass(name, class_, ifaces, init, quiet) {
this.services[name] = { class: class_, interfaces: Array.concat(ifaces || []), method: "createInstance", init: init, quiet: quiet }; this.services[name] = { class: class_, interfaces: Array.concat(ifaces || []), method: "createInstance", init: init, quiet: quiet };
if (init) if (init)
memoize(this.services[name], "callable", memoize(this.services[name], "callable", function () {
function () callable(XPCOMShim(this.interfaces)[this.init])); return callable(XPCOMShim(this.interfaces)[this.init]);
});
this[name] = (function Create() this._create(name, arguments)).bind(this); this[name] = (function Create() {
return this._create(name, arguments);
}).bind(this);
update.apply(null, [this[name]].concat([Ci[i] for (i of Array.concat(ifaces))])); update.apply(null, [this[name]].concat([Ci[i] for (i of Array.concat(ifaces))]));
return this[name]; return this[name];
}, },
+13 -4
View File
@@ -289,7 +289,9 @@ var Storage = Module("Storage", {
this.keys[key] = new constructor(key, params.store, load, params); this.keys[key] = new constructor(key, params.store, load, params);
this.keys[key].timer = new Timer(1000, 10000, () => this.save(key)); this.keys[key].timer = new Timer(1000, 10000, () => this.save(key));
this.__defineGetter__(key, function () this.keys[key]); this.__defineGetter__(key, function () {
return this.keys[key];
});
} }
return this.keys[key]; return this.keys[key];
}, },
@@ -698,13 +700,18 @@ var File = Class("File", {
*/ */
PATH_SEP: Class.Memoize(() => /foo(.)bar/.exec(OS.Path.join("foo", "bar"))[1]), PATH_SEP: Class.Memoize(() => /foo(.)bar/.exec(OS.Path.join("foo", "bar"))[1]),
pathSplit: Class.Memoize(function () util.regexp("[/" + util.regexp.escape(this.PATH_SEP) + "]", "g")), pathSplit: Class.Memoize(function () {
return util.regexp("[/" + util.regexp.escape(this.PATH_SEP) + "]",
"g");
}),
DoesNotExist: function DoesNotExist(path, error) ({ DoesNotExist: function DoesNotExist(path, error) ({
__proto__: DoesNotExist.prototype, __proto__: DoesNotExist.prototype,
path: path, path: path,
exists: function () false, exists: function () false,
__noSuchMethod__: function () { throw error || Error("Does not exist"); } __noSuchMethod__: function () {
throw error || Error("Does not exist");
}
}), }),
defaultEncoding: "UTF-8", defaultEncoding: "UTF-8",
@@ -827,7 +834,9 @@ var File = Class("File", {
catch (e) {} catch (e) {}
if (isFunction) if (isFunction)
File.prototype[prop] = util.wrapCallback(function wrapper() apply(this.file, prop, arguments)); File.prototype[prop] = util.wrapCallback(function wrapper() {
return apply(this.file, prop, arguments);
});
else else
Object.defineProperty(File.prototype, prop, { Object.defineProperty(File.prototype, prop, {
configurable: true, configurable: true,
+19 -10
View File
@@ -19,7 +19,7 @@ var namespace = "@namespace html " + JSON.stringify(XHTML) + ";\n" +
var Sheet = Struct("name", "id", "sites", "css", "hive", "agent"); var Sheet = Struct("name", "id", "sites", "css", "hive", "agent");
Sheet.liveProperty = function (name) { Sheet.liveProperty = function (name) {
let i = this.prototype.members[name]; let i = this.prototype.members[name];
this.prototype.__defineGetter__(name, function () this[i]); this.prototype.__defineGetter__(name, function () { return this[i]; });
this.prototype.__defineSetter__(name, function (val) { this.prototype.__defineSetter__(name, function (val) {
if (isArray(val)) if (isArray(val))
val = Array.slice(val); val = Array.slice(val);
@@ -322,12 +322,13 @@ var Styles = Module("Styles", {
hives = hives || styles.hives.filter(h => (h.modifiable && h.sheets.length)); hives = hives || styles.hives.filter(h => (h.modifiable && h.sheets.length));
function sheets(group) function sheets(group) {
group.sheets.slice() return group.sheets.slice()
.filter(sheet => ((!name || sheet.name === name) && .filter(sheet => ((!name || sheet.name === name) &&
(!sites || sites.every(s => sheet.sites.indexOf(s) >= 0)))) (!sites || sites.every(s => sheet.sites.indexOf(s) >= 0))))
.sort((a, b) => (a.name && b.name ? String.localeCompare(a.name, b.name) .sort((a, b) => (a.name && b.name ? String.localeCompare(a.name, b.name)
: !!b.name - !!a.name || a.id - b.id)); : !!b.name - !!a.name || a.id - b.id));
}
let uris = util.visibleURIs(content); let uris = util.visibleURIs(content);
@@ -414,8 +415,11 @@ var Styles = Module("Styles", {
context.generate = () => values(group.sites); context.generate = () => values(group.sites);
context.keys.text = util.identity; context.keys.text = util.identity;
context.keys.description = function (site) this.sheets.length + /*L*/" sheet" + (this.sheets.length == 1 ? "" : "s") + ": " + context.keys.description = function (site) {
return this.sheets.length + /*L*/" sheet" +
(this.sheets.length == 1 ? "" : "s") + ": " +
Ary.compact(this.sheets.map(s => s.name)).join(", "); Ary.compact(this.sheets.map(s => s.name)).join(", ");
};
context.keys.sheets = site => group.sheets.filter(s => s.sites.indexOf(site) >= 0); context.keys.sheets = site => group.sheets.filter(s => s.sites.indexOf(site) >= 0);
context.keys.active = site => uris.some(Styles.matchFilter(site)); context.keys.active = site => uris.some(Styles.matchFilter(site));
@@ -438,20 +442,25 @@ var Styles = Module("Styles", {
filter = filter.trim(); filter = filter.trim();
if (filter === "*") if (filter === "*")
var test = function test(uri) true; var test = function test(uri) { return true; };
else if (!/^(?:[a-z-]+:|[a-z-.]+$)/.test(filter)) { else if (!/^(?:[a-z-]+:|[a-z-.]+$)/.test(filter)) {
let re = util.regexp(filter); let re = util.regexp(filter);
test = function test(uri) re.test(uri.spec); test = function test(uri) { return re.test(uri.spec); };
} }
else if (/[*]$/.test(filter)) { else if (/[*]$/.test(filter)) {
let re = RegExp("^" + util.regexp.escape(filter.substr(0, filter.length - 1))); let re = RegExp("^" + util.regexp.escape(filter.substr(0, filter.length - 1)));
test = function test(uri) re.test(uri.spec); test = function test(uri) { return re.test(uri.spec); };
} }
else if (/[\/:]/.test(filter)) else if (/[\/:]/.test(filter))
test = function test(uri) uri.spec === filter; test = function test(uri) { return uri.spec === filter; };
else else
test = function test(uri) { try { return util.isSubdomain(uri.host, filter); } catch (e) { return false; } }; test = function test(uri) {
test.toString = function toString() filter; try {
return util.isSubdomain(uri.host, filter);
}
catch (e) { return false; }
};
test.toString = function toString() { return filter; }
test.key = filter; test.key = filter;
if (arguments.length < 2) if (arguments.length < 2)
return test; return test;
+1 -1
View File
@@ -448,7 +448,7 @@ var Template = Module("Template", {
// TODO: This might be mind-bogglingly slow. We'll see. // TODO: This might be mind-bogglingly slow. We'll see.
return ["table", {}, return ["table", {},
["tr", { highlight: "Title", align: "left" }, ["tr", { highlight: "Title", align: "left" },
this.map(headings, function (h) this.map(headings, h =>
["th", {}, h])], ["th", {}, h])],
this.map(iter, row => this.map(iter, row =>
["tr", {}, ["tr", {},
+25 -18
View File
@@ -257,18 +257,19 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
compileFormat: function compileFormat(format) { compileFormat: function compileFormat(format) {
let stack = [frame()]; let stack = [frame()];
stack.__defineGetter__("top", function () this[this.length - 1]); stack.__defineGetter__("top", function () {
return this[this.length - 1];
});
function frame() { function frame() {
return update( return update(function _frame(obj) {
function _frame(obj) return _frame === stack.top || _frame.valid(obj)
_frame === stack.top || _frame.valid(obj)
? _frame.elements.map(e => callable(e) ? e(obj) : e) ? _frame.elements.map(e => callable(e) ? e(obj) : e)
.join("") .join("")
: "", : "";
{ }, {
elements: [], elements: [],
seen: {}, seen: new RealSet,
valid: function valid(obj) this.elements.every(e => !e.test || e.test(obj)) valid: function valid(obj) this.elements.every(e => !e.test || e.test(obj))
}); });
} }
@@ -341,23 +342,25 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
*/ */
compileMacro: function compileMacro(macro, keepUnknown) { compileMacro: function compileMacro(macro, keepUnknown) {
let stack = [frame()]; let stack = [frame()];
stack.__defineGetter__("top", function () this[this.length - 1]); stack.__defineGetter__("top", function () {
return this[this.length - 1];
});
let unknown = util.identity; let unknown = util.identity;
if (!keepUnknown) if (!keepUnknown)
unknown = () => ""; unknown = () => "";
// FIXME: duplicated in compileFormat
function frame() { function frame() {
return update( return update(function _frame(obj) {
function _frame(obj) return _frame === stack.top || _frame.valid(obj)
_frame === stack.top || _frame.valid(obj)
? _frame.elements.map(e => callable(e) ? e(obj) : e) ? _frame.elements.map(e => callable(e) ? e(obj) : e)
.join("") .join("")
: "", : "";
{ }, {
elements: [], elements: [],
seen: new RealSet, seen: new RealSet,
valid: function valid(obj) this.elements.every(e => (!e.test || e.test(obj))) valid: function valid(obj) this.elements.every(e => !e.test || e.test(obj))
}); });
} }
@@ -394,9 +397,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
let quote = util.identity; let quote = util.identity;
if (flags.has("q")) if (flags.has("q"))
quote = function quote(obj) typeof obj === "number" ? obj : JSON.stringify(obj); quote = function quote(obj) {
return typeof obj === "number" ? obj : JSON.stringify(obj);
};
if (flags.has("e")) if (flags.has("e"))
quote = function quote(obj) ""; quote = function quote(obj) { return ""; };
if (hasOwnProperty(defaults, name)) if (hasOwnProperty(defaults, name))
stack.top.elements.push(quote(defaults[name])); stack.top.elements.push(quote(defaults[name]));
@@ -879,7 +884,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
isDactyl: Class.Memoize(function () { isDactyl: Class.Memoize(function () {
let base = util.regexp.escape(Components.stack.filename.replace(/[^\/]+$/, "")); let base = util.regexp.escape(Components.stack.filename.replace(/[^\/]+$/, ""));
let re = RegExp("^(?:.* -> )?(?:resource://dactyl(?!-content/eval.js)|" + base + ")\\S+$"); let re = RegExp("^(?:.* -> )?(?:resource://dactyl(?!-content/eval.js)|" + base + ")\\S+$");
return function isDactyl(frame) re.test(frame.filename); return function isDactyl(frame) { return re.test(frame.filename); };
}), }),
/** /**
@@ -1407,7 +1412,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
this.errors.push([new Date, obj + "\n" + obj.stack]); this.errors.push([new Date, obj + "\n" + obj.stack]);
this.errors = this.errors.slice(-this.maxErrors); this.errors = this.errors.slice(-this.maxErrors);
this.errors.toString = function () [k + "\n" + v for ([k, v] of this)].join("\n\n"); this.errors.toString = function () {
return [k + "\n" + v for ([k, v] of this)].join("\n\n");
};
this.dump(String(error)); this.dump(String(error));
this.dump(obj); this.dump(obj);
+4 -2
View File
@@ -177,13 +177,15 @@ const Config = Module("config", ConfigBase, {
Leave: "Triggered before exiting Songbird" Leave: "Triggered before exiting Songbird"
}, },
completers: Class.memoize(function () update({ completers: Class.memoize(function () {
return update({
displaypane: "displayPane", displaypane: "displayPane",
playlist: "playlist", playlist: "playlist",
mediaview: "mediaView", mediaview: "mediaView",
mediasort: "mediaListSort", mediasort: "mediaListSort",
song: "song" song: "song"
}, this.__proto__.completers)), }, this.__proto__.completers);
}),
removeTab: function (tab) { removeTab: function (tab) {
if (config.tabbrowser.mTabs.length > 1) if (config.tabbrowser.mTabs.length > 1)
+3 -1
View File
@@ -76,7 +76,9 @@ var Config = Module("config", ConfigBase, {
dactyl.beep(); dactyl.beep();
}, },
completers: Class.Memoize(function () update({ mailfolder: "mailFolder" }, this.__proto__.completers)), completers: Class.Memoize(function () {
return update({ mailfolder: "mailFolder" }, this.__proto__.completers);
}),
dialogs: { dialogs: {
about: ["About Thunderbird", about: ["About Thunderbird",