1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-21 06:38:00 +01:00

Replace expression closures (methods).

Expression closures are to be axed. See https://bugzil.la/1083458.
This commit is contained in:
Doug Kearns
2015-07-23 01:55:32 +10:00
parent c035aa936b
commit 77d59cdfd1
45 changed files with 1595 additions and 1045 deletions

View File

@@ -39,7 +39,9 @@ var Abbreviation = Class("Abbreviation", {
* @param {Abbreviation} other The abbreviation to test. * @param {Abbreviation} other The abbreviation to test.
* @returns {boolean} The result of the comparison. * @returns {boolean} The result of the comparison.
*/ */
equals: function (other) this.lhs == other.lhs && this.rhs == other.rhs, equals: function (other) {
return this.lhs == other.lhs && this.rhs == other.rhs;
},
/** /**
* Returns the abbreviation's expansion text. * Returns the abbreviation's expansion text.
@@ -48,7 +50,9 @@ var Abbreviation = Class("Abbreviation", {
* occurring. * occurring.
* @returns {string} * @returns {string}
*/ */
expand: function (editor) String(callable(this.rhs) ? this.rhs(editor) : this.rhs), expand: function (editor) {
return String(callable(this.rhs) ? this.rhs(editor) : this.rhs);
},
/** /**
* Returns true if this abbreviation is defined for all *modes*. * Returns true if this abbreviation is defined for all *modes*.
@@ -56,7 +60,9 @@ var Abbreviation = Class("Abbreviation", {
* @param {[Mode]} modes The modes to test. * @param {[Mode]} modes The modes to test.
* @returns {boolean} The result of the comparison. * @returns {boolean} The result of the comparison.
*/ */
modesEqual: function (modes) Ary.equals(this.modes, modes), modesEqual: function (modes) {
return Ary.equals(this.modes, modes);
},
/** /**
* Returns true if this abbreviation is defined for *mode*. * Returns true if this abbreviation is defined for *mode*.
@@ -64,7 +70,9 @@ var Abbreviation = Class("Abbreviation", {
* @param {Mode} mode The mode to test. * @param {Mode} mode The mode to test.
* @returns {boolean} The result of the comparison. * @returns {boolean} The result of the comparison.
*/ */
inMode: function (mode) this.modes.some(m => m == mode), inMode: function (mode) {
return this.modes.some(m => m == mode);
},
/** /**
* Returns true if this abbreviation is defined in any of *modes*. * Returns true if this abbreviation is defined in any of *modes*.
@@ -72,7 +80,9 @@ var Abbreviation = Class("Abbreviation", {
* @param {[Modes]} modes The modes to test. * @param {[Modes]} modes The modes to test.
* @returns {boolean} The result of the comparison. * @returns {boolean} The result of the comparison.
*/ */
inModes: function (modes) modes.some(mode => this.inMode(mode)), inModes: function (modes) {
return modes.some(mode => this.inMode(mode));
},
/** /**
* Remove *mode* from the list of supported modes for this abbreviation. * Remove *mode* from the list of supported modes for this abbreviation.

View File

@@ -26,7 +26,9 @@ var AutoCmdHive = Class("AutoCmdHive", Contexts.Hive, {
this._store = []; this._store = [];
}, },
"@@iterator": function () this._store[Symbol.iterator](), "@@iterator": function () {
return this._store[Symbol.iterator]();
},
/** /**
* Adds a new autocommand. *cmd* will be executed when one of the specified * Adds a new autocommand. *cmd* will be executed when one of the specified
@@ -171,7 +173,9 @@ var AutoCommands = Module("autocommands", {
hives: contexts.Hives("autocmd", AutoCmdHive), hives: contexts.Hives("autocmd", AutoCmdHive),
user: contexts.hives.autocmd.user, user: contexts.hives.autocmd.user,
allHives: contexts.allGroups.autocmd, allHives: contexts.allGroups.autocmd,
matchingHives: function matchingHives(uri, doc) contexts.matchingGroups(uri, doc).autocmd matchingHives: function matchingHives(uri, doc) {
return contexts.matchingGroups(uri, doc).autocmd;
}
}); });
}, },
commands: function initCommands() { commands: function initCommands() {

View File

@@ -18,8 +18,10 @@ var Bookmarks = Module("bookmarks", {
autocommands.trigger("Bookmark" + util.capitalize(event), autocommands.trigger("Bookmark" + util.capitalize(event),
update({ update({
bookmark: { bookmark: {
toString: function () "bookmarkcache.bookmarks[" + arg.id + "]", toString: function () {
valueOf: function () arg return "bookmarkcache.bookmarks[" + arg.id + "]";
},
valueOf: function () { return arg; }
} }
}, arg.toObject())); }, arg.toObject()));
bookmarks.timer.tell(); bookmarks.timer.tell();
@@ -37,7 +39,7 @@ var Bookmarks = Module("bookmarks", {
return { return {
anchored: false, anchored: false,
title: ["URL", "Info"], title: ["URL", "Info"],
keys: { text: "url", description: "title", icon: "icon", extra: "extra", tags: "tags", isURI: function () true }, keys: { text: "url", description: "title", icon: "icon", extra: "extra", tags: "tags", isURI: function () { return true; }},
process: [template.icon, template.bookmarkDescription] process: [template.icon, template.bookmarkDescription]
}; };
}, },
@@ -752,7 +754,10 @@ var Bookmarks = Module("bookmarks", {
let ctxt = context.fork(name, 0); let ctxt = context.fork(name, 0);
ctxt.title = [/*L*/desc + " Suggestions"]; ctxt.title = [/*L*/desc + " Suggestions"];
ctxt.keys = { text: identity, description: function () "" }; ctxt.keys = {
text: identity,
description: function () { return ""; }
};
ctxt.compare = CompletionContext.Sort.unsorted; ctxt.compare = CompletionContext.Sort.unsorted;
ctxt.filterFunc = null; ctxt.filterFunc = null;

View File

@@ -51,7 +51,10 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
uri = isObject(uri) ? uri : util.newURI(uri || doc.location.href); uri = isObject(uri) ? uri : util.newURI(uri || doc.location.href);
let args = { let args = {
url: { toString: function () uri.spec, valueOf: function () uri }, url: {
toString: function () { return uri.spec; },
valueOf: function () { return uri; }
},
title: doc.title title: doc.title
}; };
@@ -60,12 +63,16 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
else { else {
args.tab = tabs.getContentIndex(doc) + 1; args.tab = tabs.getContentIndex(doc) + 1;
args.doc = { args.doc = {
valueOf: function () doc, valueOf: function () { return doc; },
toString: function () "tabs.getTab(" + (args.tab - 1) + ").linkedBrowser.contentDocument" toString: function () {
return "tabs.getTab(" + (args.tab - 1) + ").linkedBrowser.contentDocument";
}
}; };
args.win = { args.win = {
valueOf: function () doc.defaultView, valueOf: function () { return doc.defaultView; },
toString: function () "tabs.getTab(" + (args.tab - 1) + ").linkedBrowser.contentWindow" toString: function () {
return "tabs.getTab(" + (args.tab - 1) + ").linkedBrowser.contentWindow";
}
}; };
} }

View File

@@ -66,20 +66,29 @@ var CommandWidgets = Class("CommandWidgets", {
this.addElement({ this.addElement({
name: "commandline", name: "commandline",
getGroup: function () options.get("guioptions").has("C") ? this.commandbar : this.statusbar, getGroup: function () {
getValue: function () this.command return options.get("guioptions").has("C") ? this.commandbar
: this.statusbar;
},
getValue: function () {
return this.command;
}
}); });
this.addElement({ this.addElement({
name: "strut", name: "strut",
defaultGroup: "Normal", defaultGroup: "Normal",
getGroup: function () this.commandbar, getGroup: function () { return this.commandbar; },
getValue: function () options.get("guioptions").has("c") getValue: function () {
return options.get("guioptions").has("c");
}
}); });
this.addElement({ this.addElement({
name: "command", name: "command",
test: function test(stack, prev) stack.pop && !isinstance(prev.main, modes.COMMAND_LINE), test: function test(stack, prev) {
return stack.pop && !isinstance(prev.main, modes.COMMAND_LINE);
},
id: "commandline-command", id: "commandline-command",
get: function command_get(elem) { get: function command_get(elem) {
// The long path is because of complications with the // The long path is because of complications with the
@@ -92,7 +101,9 @@ var CommandWidgets = Class("CommandWidgets", {
} }
}, },
getElement: CommandWidgets.getEditor, getElement: CommandWidgets.getEditor,
getGroup: function (value) this.activeGroup.commandline, getGroup: function (value) {
return this.activeGroup.commandline;
},
onChange: function command_onChange(elem, value) { onChange: function command_onChange(elem, value) {
if (elem.inputField != dactyl.focusedElement) if (elem.inputField != dactyl.focusedElement)
try { try {
@@ -114,7 +125,7 @@ var CommandWidgets = Class("CommandWidgets", {
name: "prompt", name: "prompt",
id: "commandline-prompt", id: "commandline-prompt",
defaultGroup: "CmdPrompt", defaultGroup: "CmdPrompt",
getGroup: function () this.activeGroup.commandline getGroup: function () { return this.activeGroup.commandline; }
}); });
this.addElement({ this.addElement({
@@ -136,14 +147,14 @@ var CommandWidgets = Class("CommandWidgets", {
this.addElement({ this.addElement({
name: "message-pre", name: "message-pre",
defaultGroup: "WarningMsg", defaultGroup: "WarningMsg",
getGroup: function () this.activeGroup.message getGroup: function () { return this.activeGroup.message; }
}); });
this.addElement({ this.addElement({
name: "message-box", name: "message-box",
defaultGroup: "Normal", defaultGroup: "Normal",
getGroup: function () this.activeGroup.message, getGroup: function () { return this.activeGroup.message; },
getValue: function () this.message getValue: function () { return this.message; }
}); });
this.addElement({ this.addElement({
@@ -1393,8 +1404,9 @@ var CommandLine = Module("commandline", {
* Returns true if the currently selected 'wildmode' index * Returns true if the currently selected 'wildmode' index
* has the given completion type. * has the given completion type.
*/ */
haveType: function haveType(type) haveType: function haveType(type) {
this.wildmode.checkHas(this.wildtype, type == "first" ? "" : type), return this.wildmode.checkHas(this.wildtype, type == "first" ? "" : type);
},
/** /**
* Returns the completion item for the given selection * Returns the completion item for the given selection
@@ -1405,8 +1417,9 @@ var CommandLine = Module("commandline", {
* @default {@link #selected} * @default {@link #selected}
* @returns {object} * @returns {object}
*/ */
getItem: function getItem(tuple=this.selected) getItem: function getItem(tuple=this.selected) {
tuple && tuple[0] && tuple[0].items[tuple[1]], return tuple && tuple[0] && tuple[0].items[tuple[1]];
},
/** /**
* Returns a tuple representing the next item, at the given * Returns a tuple representing the next item, at the given
@@ -1779,7 +1792,9 @@ var CommandLine = Module("commandline", {
return Events.PASS; return Events.PASS;
}); });
let bind = function bind(...args) apply(mappings, "add", [[modes.COMMAND_LINE]].concat(args)); let bind = function bind(...args) {
apply(mappings, "add", [[modes.COMMAND_LINE]].concat(args));
};
bind(["<Esc>", "<C-[>"], "Stop waiting for completions or exit Command Line mode", bind(["<Esc>", "<C-[>"], "Stop waiting for completions or exit Command Line mode",
function ({ self }) { function ({ self }) {
@@ -2305,12 +2320,17 @@ var ItemList = Class("ItemList", {
* @param {CompletionContext} context * @param {CompletionContext} context
* @returns {ItemList.Group} * @returns {ItemList.Group}
*/ */
getGroup: function getGroup(context) getGroup: function getGroup(context) {
context instanceof ItemList.Group ? context if (context instanceof ItemList.Group)
: context && context.getCache("itemlist-group", return context;
() => ItemList.Group(this, context)), else
return context && context.getCache("itemlist-group",
() => ItemList.Group(this, context));
},
getOffset: function getOffset(tuple) tuple && this.getGroup(tuple[0]).getOffset(tuple[1]) getOffset: function getOffset(tuple) {
return tuple && this.getGroup(tuple[0]).getOffset(tuple[1]);
}
}, { }, {
RESIZE_BRIEF: 1 << 0, RESIZE_BRIEF: 1 << 0,
@@ -2454,9 +2474,13 @@ var ItemList = Class("ItemList", {
} }
}, },
getRow: function getRow(idx) this.context.getRow(idx, this.doc), getRow: function getRow(idx) {
return this.context.getRow(idx, this.doc);
},
getOffset: function getOffset(idx) this.offsets.start + (idx || 0), getOffset: function getOffset(idx) {
return this.offsets.start + (idx || 0);
},
get selectedRow() { return this.getRow(this._selectedIdx); }, get selectedRow() { return this.getRow(this._selectedIdx); },
@@ -2475,10 +2499,13 @@ var ItemList = Class("ItemList", {
Range: Class.Memoize(function () { Range: Class.Memoize(function () {
let Range = Struct("ItemList.Range", "start", "end"); let Range = Struct("ItemList.Range", "start", "end");
update(Range.prototype, { update(Range.prototype, {
contains: function contains(idx) contains: function contains(idx) {
typeof idx == "number" ? idx >= this.start && idx < this.end if (typeof idx == "number")
: this.contains(idx.start) && return idx >= this.start && idx < this.end;
idx.end >= this.start && idx.end <= this.end else
return this.contains(idx.start) &&
idx.end >= this.start && idx.end <= this.end;
}
}); });
return Range; return Range;
}) })

View File

@@ -203,7 +203,8 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
registerObserver: function registerObserver(type, callback, weak) { registerObserver: function registerObserver(type, callback, weak) {
if (!(type in this._observers)) if (!(type in this._observers))
this._observers[type] = []; this._observers[type] = [];
this._observers[type].push(weak ? util.weakReference(callback) : { get: function () callback }); this._observers[type].push(weak ? util.weakReference(callback)
: { get: function () { return callback; } });
}, },
registerObservers: function registerObservers(obj, prop) { registerObservers: function registerObservers(obj, prop) {
@@ -620,7 +621,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* @param {string} feature The feature name. * @param {string} feature The feature name.
* @returns {boolean} * @returns {boolean}
*/ */
has: function has(feature) config.has(feature), has: function has(feature) { return config.has(feature); },
/** /**
* @private * @private
@@ -1083,11 +1084,12 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
node.collapsed = !visible; node.collapsed = !visible;
}, },
confirmQuit: function confirmQuit() confirmQuit: function confirmQuit() {
prefs.withContext(function () { return prefs.withContext(function () {
prefs.set("browser.warnOnQuit", false); prefs.set("browser.warnOnQuit", false);
return window.canQuitApplication(); return window.canQuitApplication();
}), });
},
/** /**
* Quit the host application, no matter how many tabs/windows are open. * Quit the host application, no matter how many tabs/windows are open.

View File

@@ -718,7 +718,9 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
modes.addMode("VISUAL", { modes.addMode("VISUAL", {
char: "v", char: "v",
description: "Active when text is selected", description: "Active when text is selected",
display: function () "VISUAL" + (this._extended & modes.LINE ? " LINE" : ""), display: function () {
return "VISUAL" + (this._extended & modes.LINE ? " LINE" : "");
},
bases: [modes.COMMAND], bases: [modes.COMMAND],
ownsFocus: true ownsFocus: true
}, { }, {
@@ -762,7 +764,9 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
}); });
modes.addMode("AUTOCOMPLETE", { modes.addMode("AUTOCOMPLETE", {
description: "Active when an input autocomplete pop-up is active", description: "Active when an input autocomplete pop-up is active",
display: function () "AUTOCOMPLETE (insert)", display: function () {
return "AUTOCOMPLETE (insert)";
},
bases: [modes.INSERT] bases: [modes.INSERT]
}); });
}, },
@@ -924,26 +928,29 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
editor.selectionController.repaintSelection(editor.selectionController.SELECTION_NORMAL); editor.selectionController.repaintSelection(editor.selectionController.SELECTION_NORMAL);
} }
function clear(forward, re) function clear(forward, re) {
function _clear(editor) { return function _clear(editor) {
updateRange(editor, forward, re, range => {}); updateRange(editor, forward, re, range => {});
dactyl.assert(!editor.selection.isCollapsed); dactyl.assert(!editor.selection.isCollapsed);
editor.selection.deleteFromDocument(); editor.selection.deleteFromDocument();
let parent = DOM(editor.rootElement.parentNode); let parent = DOM(editor.rootElement.parentNode);
if (parent.isInput) if (parent.isInput)
parent.input(); parent.input();
} };
}
function move(forward, re, sameWord) function move(forward, re, sameWord) {
function _move(editor) { return function _move(editor) {
updateRange(editor, forward, re, updateRange(editor, forward, re,
range => { range.collapse(!forward); }, range => { range.collapse(!forward); },
sameWord); sameWord);
} };
function select(forward, re) }
function _select(editor) { function select(forward, re) {
return function _select(editor) {
updateRange(editor, forward, re, range => {}); updateRange(editor, forward, re, range => {});
} };
}
function beginLine(editor_) { function beginLine(editor_) {
editor.executeCommand("cmd_beginLine"); editor.executeCommand("cmd_beginLine");
move(true, /\s/, true)(editor_); move(true, /\s/, true)(editor_);
@@ -1083,9 +1090,10 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
}, },
{ count: true, type: "operator" }); { count: true, type: "operator" });
let bind = function bind(names, description, action, params) let bind = function bind(names, description, action, params) {
mappings.add([modes.INPUT], names, description, mappings.add([modes.INPUT], names, description,
action, update({ type: "editor" }, params)); action, update({ type: "editor" }, params));
};
bind(["<C-w>"], "Delete previous word", bind(["<C-w>"], "Delete previous word",
function () { function () {
@@ -1166,9 +1174,10 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
["<C-]>", "<C-5>"], "Expand Insert mode abbreviation", ["<C-]>", "<C-5>"], "Expand Insert mode abbreviation",
function () { editor.expandAbbreviation(modes.INSERT); }); function () { editor.expandAbbreviation(modes.INSERT); });
bind = function bind(names, description, action, params) bind = function bind(names, description, action, params) {
mappings.add([modes.TEXT_EDIT], names, description, mappings.add([modes.TEXT_EDIT], names, description,
action, update({ type: "editor" }, params)); action, update({ type: "editor" }, params));
};
bind(["<C-a>"], "Increment the next number", bind(["<C-a>"], "Increment the next number",
function ({ count }) { editor.modifyNumber(count || 1); }, function ({ count }) { editor.modifyNumber(count || 1); },
@@ -1279,10 +1288,11 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
}, },
{ arg: true }); { arg: true });
bind = function bind(names, description, action, params) bind = function bind(names, description, action, params) {
mappings.add([modes.TEXT_EDIT, modes.OPERATOR, modes.VISUAL], mappings.add([modes.TEXT_EDIT, modes.OPERATOR, modes.VISUAL],
names, description, names, description,
action, update({ type: "editor" }, params)); action, update({ type: "editor" }, params));
};
// finding characters // finding characters
function offset(backward, before, pos) { function offset(backward, before, pos) {
@@ -1347,7 +1357,9 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
}, },
{ count: true }); { count: true });
bind = function bind(...args) apply(mappings, "add", [[modes.AUTOCOMPLETE]].concat(args)); bind = function bind(...args) {
apply(mappings, "add", [[modes.AUTOCOMPLETE]].concat(args));
};
bind(["<Esc>"], "Return to Insert mode", bind(["<Esc>"], "Return to Insert mode",
() => Events.PASS_THROUGH); () => Events.PASS_THROUGH);

View File

@@ -113,7 +113,7 @@ var Events = Module("events", {
}); });
this._fullscreen = window.fullScreen; this._fullscreen = window.fullScreen;
this._lastFocus = { get: function () null }; this._lastFocus = { get: function () { return null; } };
this._macroKeys = []; this._macroKeys = [];
this._lastMacro = ""; this._lastMacro = "";
@@ -472,8 +472,8 @@ var Events = Module("events", {
let accel = config.OS.isMacOSX ? "metaKey" : "ctrlKey"; let accel = config.OS.isMacOSX ? "metaKey" : "ctrlKey";
let access = iter({ 1: "shiftKey", 2: "ctrlKey", 4: "altKey", 8: "metaKey" }) let access = iter({ 1: "shiftKey", 2: "ctrlKey", 4: "altKey", 8: "metaKey" })
.filter(function ([k, v]) this & k, .filter(function ([k, v]) { return this & k; },
prefs.get("ui.key.chromeAccess")) prefs.get("ui.key.chromeAccess")) // XXX
.map(([k, v]) => [v, true]) .map(([k, v]) => [v, true])
.toObject(); .toObject();
@@ -514,7 +514,9 @@ var Events = Module("events", {
* @param {string} key The key code to test. * @param {string} key The key code to test.
* @returns {boolean} * @returns {boolean}
*/ */
isAcceptKey: function (key) key == "<Return>" || key == "<C-j>" || key == "<C-m>", isAcceptKey: function (key) {
return key == "<Return>" || key == "<C-j>" || key == "<C-m>";
},
/** /**
* Returns true if *key* is a key code defined to reject/cancel input on * Returns true if *key* is a key code defined to reject/cancel input on
@@ -523,7 +525,9 @@ var Events = Module("events", {
* @param {string} key The key code to test. * @param {string} key The key code to test.
* @returns {boolean} * @returns {boolean}
*/ */
isCancelKey: function (key) key == "<Esc>" || key == "<C-[>" || key == "<C-c>", isCancelKey: function (key) {
return key == "<Esc>" || key == "<C-[>" || key == "<C-c>";
},
/** /**
* Returns true if *node* belongs to the current content document or any * Returns true if *node* belongs to the current content document or any
@@ -969,9 +973,10 @@ var Events = Module("events", {
} }
}, },
shouldPass: function shouldPass(event) shouldPass: function shouldPass(event) {
!event.noremap && (!dactyl.focusedElement || events.isContentNode(dactyl.focusedElement)) && return !event.noremap && (!dactyl.focusedElement || events.isContentNode(dactyl.focusedElement)) &&
options.get("passkeys").has(DOM.Event.stringify(event)) options.get("passkeys").has(DOM.Event.stringify(event));
}
}, { }, {
ABORT: {}, ABORT: {},
KILL: true, KILL: true,
@@ -1140,7 +1145,7 @@ var Events = Module("events", {
this.stack = MapHive.Stack(values.map(v => Map(v[map + "Keys"]))); this.stack = MapHive.Stack(values.map(v => Map(v[map + "Keys"])));
function Map(keys) { function Map(keys) {
return { return {
execute: function () Events.PASS_THROUGH, execute: function () { return Events.PASS_THROUGH; },
keys: keys keys: keys
}; };
} }
@@ -1148,9 +1153,13 @@ var Events = Module("events", {
get active() { return this.stack.length; }, get active() { return this.stack.length; },
get: function get(mode, key) this.stack.mappings[key], get: function get(mode, key) {
return this.stack.mappings[key];
},
getCandidates: function getCandidates(mode, key) this.stack.candidates[key] getCandidates: function getCandidates(mode, key) {
return this.stack.candidates[key];
}
}); });
options.add(["passkeys", "pk"], options.add(["passkeys", "pk"],
"Pass certain keys through directly for the given URLs", "Pass certain keys through directly for the given URLs",

View File

@@ -194,7 +194,9 @@ var HintSession = Class("HintSession", CommandMode, {
* @param {string} key The key to test. * @param {string} key The key to test.
* @returns {boolean} Whether the key represents a hint number. * @returns {boolean} Whether the key represents a hint number.
*/ */
isHintKey: function isHintKey(key) this.hintKeys.indexOf(key) >= 0, isHintKey: function isHintKey(key) {
return this.hintKeys.indexOf(key) >= 0;
},
/** /**
* Gets the actual offset of an imagemap area. * Gets the actual offset of an imagemap area.
@@ -1266,9 +1268,10 @@ var Hints = Module("hints", {
}); });
}, },
mappings: function () { mappings: function () {
let bind = function bind(names, description, action, params) let bind = function bind(names, description, action, params) {
mappings.add(config.browserModes, names, description, mappings.add(config.browserModes, names, description,
action, params); action, params);
};
bind(["f"], bind(["f"],
"Start Hints mode", "Start Hints mode",
@@ -1288,9 +1291,10 @@ var Hints = Module("hints", {
function ({ count }) { hints.open("g;", { continue: true, count: count }); }, function ({ count }) { hints.open("g;", { continue: true, count: count }); },
{ count: true }); { count: true });
bind = function bind(names, description, action, params) bind = function bind(names, description, action, params) {
mappings.add([modes.HINTS], names, description, mappings.add([modes.HINTS], names, description,
action, params); action, params);
};
bind(["<Return>"], bind(["<Return>"],
"Follow the selected hint", "Follow the selected hint",
@@ -1306,7 +1310,7 @@ var Hints = Module("hints", {
bind(["<BS>", "<C-h>"], bind(["<BS>", "<C-h>"],
"Delete the previous character", "Delete the previous character",
function ({ self }) self.backspace()); function ({ self }) { self.backspace(); });
bind(["\\"], bind(["\\"],
"Toggle hint filtering", "Toggle hint filtering",
@@ -1343,7 +1347,9 @@ var Hints = Module("hints", {
return vals; return vals;
}, },
testValues: function testValues(vals, validator) vals.every(re => Option.splitList(re).every(validator)), testValues: function testValues(vals, validator) {
return vals.every(re => Option.splitList(re).every(validator));
},
validator: DOM.validateMatcher validator: DOM.validateMatcher
}); });

View File

@@ -341,8 +341,13 @@ var History = Module("history", {
completion.domain = context => { completion.domain = context => {
context.anchored = false; context.anchored = false;
context.compare = (a, b) => String.localeCompare(a.key, b.key); context.compare = (a, b) => String.localeCompare(a.key, b.key);
context.keys = { text: identity, description: identity, context.keys = {
key: function (host) host.split(".").reverse().join(".") }; text: identity,
description: identity,
key: function (host) {
return host.split(".").reverse().join(".");
}
};
// FIXME: Schema-specific // FIXME: Schema-specific
context.generate = () => [ context.generate = () => [

View File

@@ -60,11 +60,13 @@ var ProcessorStack = Class("ProcessorStack", {
} }
}, },
_result: function (result) (result === Events.KILL ? "KILL" : _result: function (result) {
result === Events.PASS ? "PASS" : return (result === Events.KILL ? "KILL" :
result === Events.PASS_THROUGH ? "PASS_THROUGH" : result === Events.PASS ? "PASS" :
result === Events.ABORT ? "ABORT" : result === Events.PASS_THROUGH ? "PASS_THROUGH" :
callable(result) ? result.toSource().substr(0, 50) : result), result === Events.ABORT ? "ABORT" :
callable(result) ? result.toSource().substr(0, 50) : result);
},
execute: function execute(result, force) { execute: function execute(result, force) {
events.dbg("EXECUTE(" + this._result(result) + ", " + force + ") events:" + this.events.length events.dbg("EXECUTE(" + this._result(result) + ", " + force + ") events:" + this.events.length
@@ -255,8 +257,8 @@ var KeyProcessor = Class("KeyProcessor", {
return this.onKeyPress(event); return this.onKeyPress(event);
}, },
execute: function execute(map, args) execute: function execute(map, args) {
() => { return () => {
if (this.preExecute) if (this.preExecute)
apply(this, "preExecute", args); apply(this, "preExecute", args);
@@ -266,7 +268,8 @@ var KeyProcessor = Class("KeyProcessor", {
if (this.postExecute) if (this.postExecute)
apply(this, "postExecute", args); apply(this, "postExecute", args);
return res; return res;
}, };
},
onKeyPress: function onKeyPress(event) { onKeyPress: function onKeyPress(event) {
if (event.skipmap) if (event.skipmap)

View File

@@ -112,7 +112,9 @@ var Map = Class("Map", {
* @param {string} name The name to query. * @param {string} name The name to query.
* @returns {boolean} * @returns {boolean}
*/ */
hasName: function (name) this.keys.indexOf(name) >= 0, hasName: function (name) {
return this.keys.indexOf(name) >= 0;
},
get keys() { return Ary.flatten(this.names.map(mappings.bound.expand)); }, get keys() { return Ary.flatten(this.names.map(mappings.bound.expand)); },
@@ -232,7 +234,9 @@ var MapHive = Class("MapHive", Contexts.Hive, {
* @param {string} cmd The map name to match. * @param {string} cmd The map name to match.
* @returns {Map|null} * @returns {Map|null}
*/ */
get: function (mode, cmd) this.getStack(mode).mappings[cmd], get: function (mode, cmd) {
return this.getStack(mode).mappings[cmd];
},
/** /**
* Returns a count of maps with names starting with but not equal to * Returns a count of maps with names starting with but not equal to
@@ -242,7 +246,9 @@ var MapHive = Class("MapHive", Contexts.Hive, {
* @param {string} prefix The map prefix string to match. * @param {string} prefix The map prefix string to match.
* @returns {number) * @returns {number)
*/ */
getCandidates: function (mode, prefix) this.getStack(mode).candidates[prefix] || 0, getCandidates: function (mode, prefix) {
return this.getStack(mode).candidates[prefix] || 0;
},
/** /**
* Returns whether there is a user-defined mapping *cmd* for the specified * Returns whether there is a user-defined mapping *cmd* for the specified
@@ -252,7 +258,9 @@ var MapHive = Class("MapHive", Contexts.Hive, {
* @param {string} cmd The candidate key mapping. * @param {string} cmd The candidate key mapping.
* @returns {boolean} * @returns {boolean}
*/ */
has: function (mode, cmd) this.getStack(mode).mappings[cmd] != null, has: function (mode, cmd) {
return this.getStack(mode).mappings[cmd] != null;
},
/** /**
* Remove the mapping named *cmd* for *mode*. * Remove the mapping named *cmd* for *mode*.
@@ -291,7 +299,9 @@ var MapHive = Class("MapHive", Contexts.Hive, {
return self; return self;
}, },
"@@iterator": function () Ary.iterValues(this), "@@iterator": function () {
return Ary.iterValues(this);
},
get candidates() { return this.states.candidates; }, get candidates() { return this.states.candidates; },
get mappings() { return this.states.mappings; }, get mappings() { return this.states.mappings; },
@@ -401,7 +411,9 @@ var Mappings = Module("mappings", {
// NOTE: just normal mode for now // NOTE: just normal mode for now
/** @property {Iterator(Map)} */ /** @property {Iterator(Map)} */
"@@iterator": function () this.iterate(modes.NORMAL), "@@iterator": function () {
return this.iterate(modes.NORMAL);
},
getDefault: deprecated("mappings.builtin.get", function getDefault(mode, cmd) this.builtin.get(mode, cmd)), getDefault: deprecated("mappings.builtin.get", function getDefault(mode, cmd) this.builtin.get(mode, cmd)),
getUserIterator: deprecated("mappings.user.iterator", function getUserIterator(modes) this.user.iterator(modes)), getUserIterator: deprecated("mappings.user.iterator", function getUserIterator(modes) this.user.iterator(modes)),
@@ -455,8 +467,9 @@ var Mappings = Module("mappings", {
* @param {string} cmd The map name to match. * @param {string} cmd The map name to match.
* @returns {Map} * @returns {Map}
*/ */
get: function get(mode, cmd) this.hives.map(h => h.get(mode, cmd)) get: function get(mode, cmd) {
.compact()[0] || null, return this.hives.map(h => h.get(mode, cmd)).compact()[0] || null;
},
/** /**
* Returns a count of maps with names starting with but not equal to * Returns a count of maps with names starting with but not equal to
@@ -466,9 +479,10 @@ var Mappings = Module("mappings", {
* @param {string} prefix The map prefix string to match. * @param {string} prefix The map prefix string to match.
* @returns {[Map]} * @returns {[Map]}
*/ */
getCandidates: function (mode, prefix) getCandidates: function (mode, prefix) {
this.hives.map(h => h.getCandidates(mode, prefix)) return this.hives.map(h => h.getCandidates(mode, prefix))
.reduce((a, b) => (a + b), 0), .reduce((a, b) => (a + b), 0);
},
/** /**
* Lists all user-defined mappings matching *filter* for the specified * Lists all user-defined mappings matching *filter* for the specified
@@ -763,7 +777,7 @@ var Mappings = Module("mappings", {
mode.displayName); mode.displayName);
let args = { let args = {
getMode: function (args) findMode(args["-mode"]), getMode: function (args) { return findMode(args["-mode"]); },
iterate: function* (args, mainOnly) { iterate: function* (args, mainOnly) {
let modes = [this.getMode(args)]; let modes = [this.getMode(args)];
if (!mainOnly) if (!mainOnly)
@@ -788,13 +802,15 @@ var Mappings = Module("mappings", {
}; };
}, },
format: { format: {
description: function (map) [ description: function (map) {
return [
options.get("passkeys").has(map.name) options.get("passkeys").has(map.name)
? ["span", { highlight: "URLExtra" }, ? ["span", { highlight: "URLExtra" },
"(", template.linkifyHelp(_("option.passkeys.passedBy")), ")"] "(", template.linkifyHelp(_("option.passkeys.passedBy")), ")"]
: [], : [],
template.linkifyHelp(map.description + (map.rhs ? ": " + map.rhs : "")) template.linkifyHelp(map.description + (map.rhs ? ": " + map.rhs : ""))
], ];
},
help: function (map) { help: function (map) {
let char = Ary.compact(map.modes.map(m => m.char))[0]; let char = Ary.compact(map.modes.map(m => m.char))[0];
return char === "n" ? map.name : char ? char + "_" + map.name : ""; return char === "n" ? map.name : char ? char + "_" + map.name : "";
@@ -831,15 +847,21 @@ var Mappings = Module("mappings", {
}, },
description: "List all " + mode.displayName + " mode mappings along with their short descriptions", description: "List all " + mode.displayName + " mode mappings along with their short descriptions",
index: mode.char + "-map", index: mode.char + "-map",
getMode: function (args) mode, getMode: function (args) { return mode; },
options: [] options: []
}); });
}); });
}, },
completion: function initCompletion(dactyl, modules, window) { completion: function initCompletion(dactyl, modules, window) {
completion.userMapping = function userMapping(context, modes_=[modes.NORMAL], hive=mappings.user) { completion.userMapping = function userMapping(context, modes_=[modes.NORMAL], hive=mappings.user) {
context.keys = { text: function (m) m.names[0], context.keys = {
description: function (m) m.description + ": " + m.action }; text: function (m) {
return m.names[0];
},
description: function (m) {
return m.description + ": " + m.action;
}
};
context.completions = hive.iterate(modes_); context.completions = hive.iterate(modes_);
}; };
}, },
@@ -847,8 +869,10 @@ var Mappings = Module("mappings", {
JavaScript.setCompleter([Mappings.prototype.get, MapHive.prototype.get], JavaScript.setCompleter([Mappings.prototype.get, MapHive.prototype.get],
[ [
null, null,
function (context, obj, args) [[m.names, m.description] function (context, obj, args) {
for (m of this.iterate(args[0]))] return [[m.names, m.description]
for (m of this.iterate(args[0]))];
}
]); ]);
}, },
mappings: function initMappings(dactyl, modules, window) { mappings: function initMappings(dactyl, modules, window) {

View File

@@ -106,10 +106,11 @@ var Modes = Module("modes", {
bases: [this.BASE], bases: [this.BASE],
hidden: true, hidden: true,
passthrough: true, passthrough: true,
display: function () display: function () {
(modes.getStack(1).main == modes.PASS_THROUGH return (modes.getStack(1).main == modes.PASS_THROUGH
? (modes.getStack(2).main.display() || modes.getStack(2).main.name) ? (modes.getStack(2).main.display() || modes.getStack(2).main.name)
: "PASS THROUGH") + " (next)" : "PASS THROUGH") + " (next)";
}
}, { }, {
// Fix me. // Fix me.
preExecute: function (map) { if (modes.main == modes.QUOTE && map.name !== "<C-v>") modes.pop(); }, preExecute: function (map) { if (modes.main == modes.QUOTE && map.name !== "<C-v>") modes.pop(); },
@@ -198,7 +199,9 @@ var Modes = Module("modes", {
NONE: 0, NONE: 0,
"@@iterator": function __iterator__() Ary.iterValues(this.all), "@@iterator": function __iterator__() {
return Ary.iterValues(this.all);
},
get all() { return this._modes.slice(); }, get all() { return this._modes.slice(); },
@@ -251,19 +254,28 @@ var Modes = Module("modes", {
util.dump(" " + i + ": " + mode); util.dump(" " + i + ": " + mode);
}, },
getMode: function getMode(name) this._modeMap[name], getMode: function getMode(name) {
return this._modeMap[name];
},
getStack: function getStack(idx) this._modeStack[this._modeStack.length - idx - 1] || this._modeStack[0], getStack: function getStack(idx) {
return this._modeStack[this._modeStack.length - idx - 1] ||
this._modeStack[0];
},
get stack() { return this._modeStack.slice(); }, get stack() { return this._modeStack.slice(); },
getCharModes: function getCharModes(chr) (this.modeChars[chr] || []).slice(), getCharModes: function getCharModes(chr) {
return (this.modeChars[chr] || []).slice();
},
have: function have(mode) this._modeStack.some(m => isinstance(m.main, mode)), have: function have(mode) {
return this._modeStack.some(m => isinstance(m.main, mode));
},
matchModes: function matchModes(obj) matchModes: function matchModes(obj) {
this._modes.filter(mode => Object.keys(obj) return this._modes.filter(mode => Object.keys(obj).every(k => obj[k] == (mode[k] || false)));
.every(k => obj[k] == (mode[k] || false))), },
// show the current mode string in the command line // show the current mode string in the command line
show: function show() { show: function show() {
@@ -451,8 +463,10 @@ var Modes = Module("modes", {
return this.name.split("_").map(util.capitalize).join(" "); 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, return this.allBases.indexOf(obj) >= 0 ||
callable(obj) && this instanceof obj;
},
allBases: Class.Memoize(function () { allBases: Class.Memoize(function () {
let seen = new RealSet, let seen = new RealSet,
@@ -474,7 +488,7 @@ var Modes = Module("modes", {
return this.name.replace(/_/g, " "); return this.name.replace(/_/g, " ");
}), }),
display: function display() this._display, display: function display() { return this._display; },
extended: false, extended: false,
@@ -506,18 +520,19 @@ var Modes = Module("modes", {
get toStringParams() { return [this.name]; }, get toStringParams() { return [this.name]; },
valueOf: function valueOf() this.id valueOf: function valueOf() { return this.id; }
}, { }, {
_id: 0 _id: 0
}), }),
ModeStack: function ModeStack(array) ModeStack: function ModeStack(array) {
update(array, { return update(array, {
pop: function pop() { pop: function pop() {
if (this.length <= 1) if (this.length <= 1)
throw Error("Trying to pop last element in mode stack"); throw Error("Trying to pop last element in mode stack");
return pop.superapply(this, arguments); return pop.superapply(this, arguments);
} }
}), });
},
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";
@@ -546,19 +561,21 @@ var Modes = Module("modes", {
return Class.Property(update({ return Class.Property(update({
configurable: true, configurable: true,
enumerable: true, enumerable: true,
init: function bound_init(prop) update(this, { init: function bound_init(prop) {
get: function bound_get() { return update(this, {
if (desc.get) get: function bound_get() {
var val = desc.get.call(this, value); if (desc.get)
return val === undefined ? value : val; var val = desc.get.call(this, value);
}, return val === undefined ? value : val;
set: function bound_set(val) { },
modes.save(id, this, prop, desc.test); set: function bound_set(val) {
if (desc.set) modes.save(id, this, prop, desc.test);
value = desc.set.call(this, val); if (desc.set)
value = !desc.set || value === undefined ? val : value; value = desc.set.call(this, val);
} value = !desc.set || value === undefined ? val : value;
}) }
});
}
}, desc)); }, desc));
} }
}, { }, {

View File

@@ -66,7 +66,9 @@ var MOW = Module("mow", {
}); });
}, },
__noSuchMethod__: function (meth, args) apply(Buffer, meth, [this.body].concat(args)), __noSuchMethod__: function (meth, args) {
return apply(Buffer, meth, [this.body].concat(args));
},
get widget() { return this.widgets.multilineOutput; }, get widget() { return this.widgets.multilineOutput; },
@@ -288,7 +290,9 @@ var MOW = Module("mow", {
}, },
visible: Modes.boundProperty({ visible: Modes.boundProperty({
get: function get_mowVisible() !this.widgets.mowContainer.collapsed, get: function get_mowVisible() {
return !this.widgets.mowContainer.collapsed;
},
set: function set_mowVisible(value) { set: function set_mowVisible(value) {
this.widgets.mowContainer.collapsed = !value; this.widgets.mowContainer.collapsed = !value;

View File

@@ -51,7 +51,9 @@ var QuickMarks = Module("quickmarks", {
* @param {string} mark The mark to find. * @param {string} mark The mark to find.
* @returns {string} The mark's URL. * @returns {string} The mark's URL.
*/ */
get: function (mark) this._qmarks.get(mark) || null, get: function (mark) {
return this._qmarks.get(mark) || null;
},
/** /**
* Deletes the specified quickmarks. The *filter* is a list of quickmarks * Deletes the specified quickmarks. The *filter* is a list of quickmarks

View File

@@ -329,7 +329,9 @@ var StatusLine = Module("statusline", {
* Any other number - The progress is cleared. * Any other number - The progress is cleared.
*/ */
progress: Modes.boundProperty({ progress: Modes.boundProperty({
get: function progress() this._progress, get: function progress() {
return this._progress;
},
set: function progress(progress) { set: function progress(progress) {
this._progress = progress || ""; this._progress = progress || "";

View File

@@ -1058,7 +1058,7 @@ var Tabs = Module("tabs", {
let filter = context.filter.toLowerCase(); let filter = context.filter.toLowerCase();
let defItem = { parent: { getTitle: function () "" } }; let defItem = { parent: { getTitle: function () { return ""; } } };
let tabGroups = {}; let tabGroups = {};
tabs.getGroups(); tabs.getGroups();
@@ -1071,22 +1071,28 @@ var Tabs = Module("tabs", {
group[1].push([i, tab.linkedBrowser]); group[1].push([i, tab.linkedBrowser]);
}); });
context.pushProcessor(0, function (item, text, next) [ context.pushProcessor(0, function (item, text, next) {
["span", { highlight: "Indicator", style: "display: inline-block;" }, return [
item.indicator], ["span", { highlight: "Indicator", style: "display: inline-block;" },
next.call(this, item, text) item.indicator],
]); next.call(this, item, text)
context.process[1] = function (item, text) template.bookmarkDescription(item, template.highlightFilter(text, this.filter)); ];
});
context.process[1] = function (item, text) {
return template.bookmarkDescription(item, template.highlightFilter(text, this.filter));
};
context.anchored = false; context.anchored = false;
context.keys = { context.keys = {
text: "text", text: "text",
description: "url", description: "url",
indicator: function (item) item.tab === tabs.getTab() ? "%" : indicator: function (item) {
item.tab === tabs.alternate ? "#" : " ", return item.tab === tabs.getTab() ? "%" :
item.tab === tabs.alternate ? "#" : " ";
},
icon: "icon", icon: "icon",
id: "id", id: "id",
command: function () "tabs.select" command: function () { return "tabs.select"; }
}; };
context.compare = CompletionContext.Sort.number; context.compare = CompletionContext.Sort.number;
context.filters[0] = CompletionContext.Filter.textDescription; context.filters[0] = CompletionContext.Filter.textDescription;
@@ -1121,8 +1127,11 @@ var Tabs = Module("tabs", {
context.title = ["Tab Groups"]; context.title = ["Tab Groups"];
context.keys = { context.keys = {
text: "id", text: "id",
description: function (group) group.getTitle() || description: function (group) {
group.getChildren().map(t => t.tab.label).join(", ") return group.getTitle() ||
group.getChildren().map(t => t.tab.label)
.join(", ");
}
}; };
context.generate = () => { context.generate = () => {
context.incomplete = true; context.incomplete = true;

View File

@@ -19,12 +19,13 @@ var callResult = function callResult(method, ...args) {
return function (result) { result[method].apply(result, args); }; return function (result) { result[method].apply(result, args); };
}; };
var listener = function listener(action, event) var listener = function listener(action, event) {
function addonListener(install) { return function addonListener(install) {
this.dactyl[install.error ? "echoerr" : "echomsg"]( this.dactyl[install.error ? "echoerr" : "echomsg"](
_("addon.error", action, event, (install.name || install.sourceURI.spec) + _("addon.error", action, event, (install.name || install.sourceURI.spec) +
(install.error ? ": " + addons.errors[install.error] : ""))); (install.error ? ": " + addons.errors[install.error] : "")));
}; };
};
var AddonListener = Class("AddonListener", { var AddonListener = Class("AddonListener", {
init: function init(modules) { init: function init(modules) {
@@ -84,14 +85,14 @@ var actions = {
name: "exte[nable]", name: "exte[nable]",
description: "Enable an extension", description: "Enable an extension",
action: function (addon) { addon.userDisabled = false; }, action: function (addon) { addon.userDisabled = false; },
filter: function (addon) addon.userDisabled, filter: function (addon) { return addon.userDisabled; },
perm: "enable" perm: "enable"
}, },
disable: { disable: {
name: "extd[isable]", name: "extd[isable]",
description: "Disable an extension", description: "Disable an extension",
action: function (addon) { addon.userDisabled = true; }, action: function (addon) { addon.userDisabled = true; },
filter: function (addon) !addon.userDisabled, filter: function (addon) { return !addon.userDisabled; },
perm: "disable" perm: "disable"
}, },
options: { options: {
@@ -104,7 +105,9 @@ var actions = {
else else
this.dactyl.open(addon.optionsURL, { from: "extoptions" }); this.dactyl.open(addon.optionsURL, { from: "extoptions" });
}, },
filter: function (addon) addon.isActive && addon.optionsURL filter: function (addon) {
return addon.isActive && addon.optionsURL;
}
}, },
rehash: { rehash: {
name: "extr[ehash]", name: "extr[ehash]",
@@ -185,7 +188,9 @@ var Addon = Class("Addon", {
action.actions([this], this.list.modules); action.actions([this], this.list.modules);
}, },
compare: function compare(other) String.localeCompare(this.name, other.name), compare: function compare(other) {
return String.localeCompare(this.name, other.name);
},
get statusInfo() { get statusInfo() {
let info = this.isActive ? ["span", { highlight: "Enabled" }, "enabled"] let info = this.isActive ? ["span", { highlight: "Enabled" }, "enabled"]
@@ -250,8 +255,8 @@ var Addon = Class("Addon", {
"scope", "screenshots", "size", "sourceURI", "translators", "type", "updateDate", "userDisabled", "scope", "screenshots", "size", "sourceURI", "translators", "type", "updateDate", "userDisabled",
"version"].forEach(function (prop) { "version"].forEach(function (prop) {
Object.defineProperty(Addon.prototype, prop, { Object.defineProperty(Addon.prototype, prop, {
get: function get_proxy() this.addon[prop], get: function get_proxy() { return this.addon[prop]; },
set: function set_proxy(val) this.addon[prop] = val set: function set_proxy(val) { this.addon[prop] = val; }
}); });
}); });

View File

@@ -7,7 +7,9 @@
var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
var Cs = new Proxy(Components.stack, { var Cs = new Proxy(Components.stack, {
get: function Cs_get(target, prop) Components.stack.caller[prop] get: function Cs_get(target, prop) {
return Components.stack.caller[prop];
}
}); });
function module(url) { function module(url) {
@@ -348,7 +350,7 @@ function deprecated(alternative, fn) {
let name, let name,
func = callable(fn) ? fn func = callable(fn) ? fn
: function () apply(this, fn, arguments); : function () { return apply(this, fn, arguments); };
function deprecatedMethod() { function deprecatedMethod() {
let obj = !this ? "" : let obj = !this ? "" :
@@ -365,7 +367,7 @@ function deprecated(alternative, fn) {
deprecatedMethod.realName = func.name; deprecatedMethod.realName = func.name;
return callable(fn) ? deprecatedMethod : Class.Property({ return callable(fn) ? deprecatedMethod : Class.Property({
get: function () deprecatedMethod, get: function () { return deprecatedMethod; },
init: function (prop) { name = prop; } init: function (prop) { name = prop; }
}); });
} }
@@ -773,8 +775,9 @@ function memoize(obj, key, getter) {
} }
}, },
set: function s_replaceProperty(val) set: function s_replaceProperty(val) {
Class.replaceProperty(this.instance || this, key, val) Class.replaceProperty(this.instance || this, key, val);
}
}); });
} }
catch (e) { catch (e) {
@@ -905,7 +908,7 @@ function Class(...args) {
memoize(Constructor, "bound", Class.makeClosure); memoize(Constructor, "bound", Class.makeClosure);
if (Iter && Ary) // Hack. :/ if (Iter && Ary) // Hack. :/
Object.defineProperty(Constructor, "closure", Object.defineProperty(Constructor, "closure",
deprecated("bound", { get: function closure() this.bound })); deprecated("bound", { get: function closure() { return this.bound; } }));
update(Constructor, args[1]); update(Constructor, args[1]);
Constructor.__proto__ = superclass; Constructor.__proto__ = superclass;
@@ -972,8 +975,8 @@ Class.extend = function extend(subclass, superclass, overrides) {
* property's value. * property's value.
* @returns {Class.Property} * @returns {Class.Property}
*/ */
Class.Memoize = function Memoize(getter, wait) Class.Memoize = function Memoize(getter, wait) {
Class.Property({ return Class.Property({
configurable: true, configurable: true,
enumerable: true, enumerable: true,
init: function (key) { init: function (key) {
@@ -1024,6 +1027,7 @@ 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
@@ -1248,7 +1252,7 @@ function XPCOMShim(interfaces) {
throw Cr.NS_ERROR_NO_INTERFACE; throw Cr.NS_ERROR_NO_INTERFACE;
return this; return this;
}, },
getHelperForLanguage: function () null, getHelperForLanguage: function () { return null; },
getInterfaces: function (count) { count.value = 0; } getInterfaces: function (count) { count.value = 0; }
}); });
return (interfaces || []).reduce((shim, iface) => shim.QueryInterface(Ci[iface]), return (interfaces || []).reduce((shim, iface) => shim.QueryInterface(Ci[iface]),
@@ -1257,7 +1261,7 @@ function XPCOMShim(interfaces) {
let stub = Class.Property({ let stub = Class.Property({
configurable: true, configurable: true,
enumerable: false, enumerable: false,
value: function stub() null, value: function stub() { return null; },
writable: true writable: true
}); });
@@ -1280,7 +1284,7 @@ var ErrorBase = Class("ErrorBase", Error, {
this.fileName = frame.filename; this.fileName = frame.filename;
this.lineNumber = frame.lineNumber; this.lineNumber = frame.lineNumber;
}, },
toString: function () String(this.message) toString: function () { return String(this.message); }
}); });
/** /**
@@ -1397,19 +1401,27 @@ var StructBase = Class("StructBase", Array, {
get toStringParams() { return this; }, get toStringParams() { return this; },
clone: function struct_clone() this.constructor.apply(null, this.slice()), clone: function struct_clone() {
return this.constructor.apply(null, this.slice());
},
bound: Class.Property(Object.getOwnPropertyDescriptor(Class.prototype, "bound")), bound: Class.Property(Object.getOwnPropertyDescriptor(Class.prototype, "bound")),
closure: Class.Property(Object.getOwnPropertyDescriptor(Class.prototype, "closure")), closure: Class.Property(Object.getOwnPropertyDescriptor(Class.prototype, "closure")),
get: function struct_get(key, val) this[this.members[key]], get: function struct_get(key, val) {
set: function struct_set(key, val) this[this.members[key]] = val, return this[this.members[key]];
},
set: function struct_set(key, val) {
return this[this.members[key]] = val;
},
toObject: function struct_toObject() { toObject: function struct_toObject() {
return iter.toObject([k, this[k]] for (k of keys(this.members))); return iter.toObject([k, this[k]] for (k of keys(this.members)));
}, },
toString: function struct_toString() Class.prototype.toString.apply(this, arguments), toString: function struct_toString() {
return Class.prototype.toString.apply(this, arguments);
},
// Iterator over our named members // Iterator over our named members
"@@iterator": function* struct__iterator__() { "@@iterator": function* struct__iterator__() {
@@ -1635,7 +1647,9 @@ function iter(obj, iface) {
return Iter(res); return Iter(res);
} }
update(iter, { update(iter, {
toArray: function toArray(iter) Ary(iter).array, toArray: function toArray(iter) {
return Ary(iter).array;
},
// See Ary.prototype for API docs. // See Ary.prototype for API docs.
toObject: function toObject(iter) { toObject: function toObject(iter) {
@@ -1648,7 +1662,9 @@ update(iter, {
return obj; return obj;
}, },
compact: function compact(iter) (item for (item of iter) if (item != null)), compact: function compact(iter) {
return (item for (item of iter) if (item != null));
},
every: function every(iter, pred, self) { every: function every(iter, pred, self) {
pred = pred || identity; pred = pred || identity;
@@ -1733,7 +1749,9 @@ update(iter, {
return undefined; return undefined;
}, },
sort: function sort(iter, fn, self) Ary(iter).sort(fn, self), sort: function sort(iter, fn, self) {
return Ary(iter).sort(fn, self);
},
uniq: function* uniq(iter) { uniq: function* uniq(iter) {
let seen = new RealSet; let seen = new RealSet;

View File

@@ -61,7 +61,7 @@ update(Bookmark.prototype, {
} }
}); });
Bookmark.prototype.members.uri = Bookmark.prototype.members.url; Bookmark.prototype.members.uri = Bookmark.prototype.members.url;
Bookmark.setter = function (key, func) this.prototype.__defineSetter__(key, func); Bookmark.setter = function (key, func) { return this.prototype.__defineSetter__(key, func); };
Bookmark.setter("url", function (val) { this.uri = isString(val) ? newURI(val) : val; }); Bookmark.setter("url", function (val) { this.uri = isString(val) ? newURI(val) : val; });
Bookmark.setter("title", function (val) { services.bookmarks.setItemTitle(this.id, val); }); Bookmark.setter("title", function (val) { services.bookmarks.setItemTitle(this.id, val); });
Bookmark.setter("post", function (val) { bookmarkcache.annotate(this.id, bookmarkcache.POST, val); }); Bookmark.setter("post", function (val) { bookmarkcache.annotate(this.id, bookmarkcache.POST, val); });
@@ -87,7 +87,9 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), {
services.bookmarks.removeObserver(this); services.bookmarks.removeObserver(this);
}, },
"@@iterator": function () values(bookmarkcache.bookmarks), "@@iterator": function () {
return values(bookmarkcache.bookmarks);
},
bookmarks: Class.Memoize(function () { return this.load(); }), bookmarks: Class.Memoize(function () { return this.load(); }),
@@ -137,11 +139,13 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), {
return null; return null;
}, },
readBookmark: function readBookmark(id) ({ readBookmark: function readBookmark(id) {
itemId: id, return {
uri: services.bookmarks.getBookmarkURI(id).spec, itemId: id,
title: services.bookmarks.getItemTitle(id) uri: services.bookmarks.getBookmarkURI(id).spec,
}), title: services.bookmarks.getItemTitle(id)
};
},
findRoot: function findRoot(id) { findRoot: function findRoot(id) {
do { do {
@@ -151,7 +155,9 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), {
return root; return root;
}, },
isBookmark: function (id) this.rootFolders.indexOf(this.findRoot(id)) >= 0, isBookmark: function (id) {
return this.rootFolders.indexOf(this.findRoot(id)) >= 0;
},
/** /**
* Returns true if the given URL is bookmarked and that bookmark is * Returns true if the given URL is bookmarked and that bookmark is
@@ -254,9 +260,10 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), {
}, { }, {
DEFAULT_FAVICON: "chrome://mozapps/skin/places/defaultFavicon.png", DEFAULT_FAVICON: "chrome://mozapps/skin/places/defaultFavicon.png",
getAnnotation: function getAnnotation(item, anno) getAnnotation: function getAnnotation(item, anno) {
services.annotation.itemHasAnnotation(item, anno) ? return services.annotation.itemHasAnnotation(item, anno) ?
services.annotation.getItemAnnotation(item, anno) : null, services.annotation.getItemAnnotation(item, anno) : null;
},
getFavicon: function getFavicon(uri) { getFavicon: function getFavicon(uri) {
try { try {

View File

@@ -29,18 +29,20 @@ lazyRequire("template", ["template"]);
* @instance buffer * @instance buffer
*/ */
var Buffer = Module("Buffer", { var Buffer = Module("Buffer", {
Local: function Local(dactyl, modules, window) ({ Local: function Local(dactyl, modules, window) {
get win() { return {
return window.content; get win() {
let win = services.focus.focusedWindow;
if (!win || win == window || util.topWindow(win) != window)
return window.content; return window.content;
if (win.top == window)
return win; let win = services.focus.focusedWindow;
return win.top; if (!win || win == window || util.topWindow(win) != window)
} return window.content;
}), if (win.top == window)
return win;
return win.top;
}
};
},
init: function init(win) { init: function init(win) {
if (win) if (win)
@@ -870,31 +872,43 @@ var Buffer = Module("Buffer", {
* Scrolls the currently active element horizontally. See * Scrolls the currently active element horizontally. See
* {@link Buffer.scrollHorizontal} for parameters. * {@link Buffer.scrollHorizontal} for parameters.
*/ */
scrollHorizontal: function scrollHorizontal(increment, number) scrollHorizontal: function scrollHorizontal(increment, number) {
Buffer.scrollHorizontal(this.findScrollable(number, true), increment, number), return Buffer.scrollHorizontal(this.findScrollable(number, true),
increment,
number);
},
/** /**
* Scrolls the currently active element vertically. See * Scrolls the currently active element vertically. See
* {@link Buffer.scrollVertical} for parameters. * {@link Buffer.scrollVertical} for parameters.
*/ */
scrollVertical: function scrollVertical(increment, number) scrollVertical: function scrollVertical(increment, number) {
Buffer.scrollVertical(this.findScrollable(number, false), increment, number), return Buffer.scrollVertical(this.findScrollable(number, false),
increment,
number);
},
/** /**
* Scrolls the currently active element to the given horizontal and * Scrolls the currently active element to the given horizontal and
* vertical percentages. See {@link Buffer.scrollToPercent} for * vertical percentages. See {@link Buffer.scrollToPercent} for
* parameters. * parameters.
*/ */
scrollToPercent: function scrollToPercent(horizontal, vertical, dir) scrollToPercent: function scrollToPercent(horizontal, vertical, dir) {
Buffer.scrollToPercent(this.findScrollable(dir || 0, vertical == null), horizontal, vertical), return Buffer.scrollToPercent(this.findScrollable(dir || 0, vertical == null),
horizontal,
vertical);
},
/** /**
* Scrolls the currently active element to the given horizontal and * Scrolls the currently active element to the given horizontal and
* vertical positions. See {@link Buffer.scrollToPosition} for * vertical positions. See {@link Buffer.scrollToPosition} for
* parameters. * parameters.
*/ */
scrollToPosition: function scrollToPosition(horizontal, vertical) scrollToPosition: function scrollToPosition(horizontal, vertical) {
Buffer.scrollToPosition(this.findScrollable(0, vertical == null), horizontal, vertical), return Buffer.scrollToPosition(this.findScrollable(0, vertical == null),
horizontal,
vertical);
},
_scrollByScrollSize: function _scrollByScrollSize(count, direction) { _scrollByScrollSize: function _scrollByScrollSize(count, direction) {
let { options } = this.modules; let { options } = this.modules;
@@ -2109,7 +2123,9 @@ var Buffer = Module("Buffer", {
} }
}, },
notificationCallbacks: Class(XPCOM([Ci.nsIChannelEventSink, Ci.nsIInterfaceRequestor]), { notificationCallbacks: Class(XPCOM([Ci.nsIChannelEventSink, Ci.nsIInterfaceRequestor]), {
getInterface: function getInterface(iid) this.QueryInterface(iid), getInterface: function getInterface(iid) {
return this.QueryInterface(iid);
},
asyncOnChannelRedirect: function (oldChannel, newChannel, flags, callback) { asyncOnChannelRedirect: function (oldChannel, newChannel, flags, callback) {
if (newChannel instanceof Ci.nsIHttpChannel) if (newChannel instanceof Ci.nsIHttpChannel)

View File

@@ -52,14 +52,16 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), {
}); });
}, },
Local: function Local(dactyl, modules, window) ({ Local: function Local(dactyl, modules, window) {
init: function init() { return {
delete this.instance; init: function init() {
this.providers = {}; delete this.instance;
}, this.providers = {};
},
isLocal: true isLocal: true
}), };
},
parse: function parse(str) { parse: function parse(str) {
if ('{['.contains(str[0])) if ('{['.contains(str[0]))
@@ -246,12 +248,16 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), {
return result; return result;
}, },
_has: function _has(name) hasOwnProperty(this.providers, name) _has: function _has(name) {
|| this.storage.has(name), return hasOwnProperty(this.providers, name) ||
this.storage.has(name);
},
has: function has(name) [this.globalProviders, this.localProviders] has: function has(name) {
.some(obj => isinstance(obj, ["Set"]) ? obj.has(name) return [this.globalProviders, this.localProviders]
: hasOwnProperty(obj, name)), .some(obj => isinstance(obj, ["Set"]) ? obj.has(name)
: hasOwnProperty(obj, name));
},
register: function register(name, callback, long) { register: function register(name, callback, long) {
if (this.isLocal) if (this.isLocal)

View File

@@ -101,7 +101,9 @@ update(CommandOption, {
* E.g. "foo,bar" * E.g. "foo,bar"
* @final * @final
*/ */
LIST: ArgType("list", function parseListArg(arg, quoted) Option.splitList(quoted)) LIST: ArgType("list", function parseListArg(arg, quoted) {
return Option.splitList(quoted);
})
}); });
/** /**
@@ -198,7 +200,9 @@ var Command = Class("Command", {
* @param {string} name The candidate name. * @param {string} name The candidate name.
* @returns {boolean} * @returns {boolean}
*/ */
hasName: function hasName(name) Command.hasName(this.parsedSpecs, name), hasName: function hasName(name) {
return Command.hasName(this.parsedSpecs, name);
},
/** /**
* A helper function to parse an argument string. * A helper function to parse an argument string.
@@ -212,12 +216,13 @@ var Command = Class("Command", {
* @returns {Args} * @returns {Args}
* @see Commands#parseArgs * @see Commands#parseArgs
*/ */
parseArgs: function parseArgs(args, complete, extra) parseArgs: function parseArgs(args, complete, extra) {
this.modules.commands.parseArgs(args, { return this.modules.commands.parseArgs(args, {
__proto__: this, __proto__: this,
complete: complete, complete: complete,
extra: extra extra: extra
}), });
},
complained: Class.Memoize(() => new RealSet), complained: Class.Memoize(() => new RealSet),
@@ -300,7 +305,7 @@ var Command = Class("Command", {
* whether to purge the command from history when clearing * whether to purge the command from history when clearing
* private data. * private data.
*/ */
domains: function (args) [], domains: function (args) { return []; },
/** /**
* @property {boolean} At what index this command's literal arguments * @property {boolean} At what index this command's literal arguments
@@ -343,8 +348,10 @@ var Command = Class("Command", {
explicitOpts: Class.Memoize(() => ({})), explicitOpts: Class.Memoize(() => ({})),
has: function AP_has(opt) hasOwnProperty(this.explicitOpts, opt) has: function AP_has(opt) {
|| typeof opt === "number" && hasOwnProperty(this, opt), return hasOwnProperty(this.explicitOpts, opt) ||
typeof opt === "number" && hasOwnProperty(this, opt);
},
get literalArg() { get literalArg() {
let { literal } = this.command; let { literal } = this.command;
@@ -369,7 +376,11 @@ var Command = Class("Command", {
this.options.forEach(function (opt) { this.options.forEach(function (opt) {
if (opt.default !== undefined) { if (opt.default !== undefined) {
let prop = Object.getOwnPropertyDescriptor(opt, "default") || let prop = Object.getOwnPropertyDescriptor(opt, "default") ||
{ configurable: true, enumerable: true, get: function () opt.default }; {
configurable: true,
enumerable: true,
get: function () { return opt.default; }
};
if (prop.get && !prop.set) if (prop.get && !prop.set)
prop.set = function (val) { Class.replaceProperty(this, opt.names[0], val); }; prop.set = function (val) { Class.replaceProperty(this, opt.names[0], val); };
@@ -430,9 +441,10 @@ var Command = Class("Command", {
this.modules.dactyl.warn(loc + message); this.modules.dactyl.warn(loc + message);
} }
}, { }, {
hasName: function hasName(specs, name) hasName: function hasName(specs, name) {
specs.some(([long, short]) => return specs.some(([long, short]) => name.indexOf(short) == 0 &&
name.indexOf(short) == 0 && long.indexOf(name) == 0), long.indexOf(name) == 0);
},
// TODO: do we really need more than longNames as a convenience anyway? // TODO: do we really need more than longNames as a convenience anyway?
/** /**
@@ -453,10 +465,12 @@ var Command = Class("Command", {
// Prototype. // Prototype.
var Ex = Module("Ex", { var Ex = Module("Ex", {
Local: function Local(dactyl, modules, window) ({ Local: function Local(dactyl, modules, window) {
get commands() { return modules.commands; }, return {
get context() { return modules.contexts.context; } get commands() { return modules.commands; },
}), get context() { return modules.contexts.context; }
};
},
_args: function E_args(cmd, args) { _args: function E_args(cmd, args) {
args = Array.slice(args); args = Array.slice(args);
@@ -506,7 +520,9 @@ var Ex = Module("Ex", {
}); });
}, },
__noSuchMethod__: function __noSuchMethod__(meth, args) this._run(meth).apply(this, args) __noSuchMethod__: function __noSuchMethod__(meth, args) {
return this._run(meth).apply(this, args);
}
}); });
var CommandHive = Class("CommandHive", Contexts.Hive, { var CommandHive = Class("CommandHive", Contexts.Hive, {
@@ -849,10 +865,12 @@ var Commands = Module("commands", {
COUNT_ALL: -2, // :%... COUNT_ALL: -2, // :%...
/** @property {Iterator(Command)} @private */ /** @property {Iterator(Command)} @private */
iterator: function iterator() iter.apply(null, this.hives.array) iterator: function iterator() {
.sort((a, b) => (a.serialGroup - b.serialGroup || return iter.apply(null, this.hives.array)
a.name > b.name)) .sort((a, b) => (a.serialGroup - b.serialGroup ||
.iterValues(), a.name > b.name))
.iterValues();
},
/** @property {string} The last executed Ex command line. */ /** @property {string} The last executed Ex command line. */
repeat: null, repeat: null,
@@ -921,8 +939,10 @@ var Commands = Module("commands", {
* any of the command's names. * any of the command's names.
* @returns {Command} * @returns {Command}
*/ */
get: function get(name, full) iter(this.hives).map(([i, hive]) => hive.get(name, full)) get: function get(name, full) {
.find(identity), return iter(this.hives).map(([i, hive]) => hive.get(name, full))
.find(identity);
},
/** /**
* Returns true if a command invocation contains a URL referring to the * Returns true if a command invocation contains a URL referring to the
@@ -1261,7 +1281,14 @@ var Commands = Module("commands", {
complete.advance(args.completeStart); complete.advance(args.completeStart);
complete.keys = { complete.keys = {
text: "names", text: "names",
description: function (opt) messages.get(["command", params.name, "options", opt.names[0], "description"].join("."), opt.description) description: function (opt) {
return messages.get(["command",
params.name,
"options",
opt.names[0],
"description"].join("."),
opt.description);
}
}; };
complete.title = ["Options"]; complete.title = ["Options"];
if (completeOpts) if (completeOpts)
@@ -1478,10 +1505,12 @@ var Commands = Module("commands", {
return [len - str.length, arg, quote]; return [len - str.length, arg, quote];
}, },
quote: function quote(str) Commands.quoteArg[ quote: function quote(str) {
/[\b\f\n\r\t]/.test(str) ? '"' : return Commands.quoteArg[
/[\s"'\\]|^$|^-/.test(str) ? "'" /[\b\f\n\r\t]/.test(str) ? '"' :
: ""](str) /[\s"'\\]|^$|^-/.test(str) ? "'"
: ""](str);
}
}, { }, {
completion: function initCompletion(dactyl, modules, window) { completion: function initCompletion(dactyl, modules, window) {
const { completion, contexts } = modules; const { completion, contexts } = modules;
@@ -1557,7 +1586,10 @@ var Commands = Module("commands", {
args[i] = start + i + end; args[i] = start + i + end;
let params = { let params = {
args: { __proto__: args, toString: function () this.join(" ") }, args: {
__proto__: args,
toString: function () { return this.join(" "); }
},
bang: args.bang ? "!" : "", bang: args.bang ? "!" : "",
count: args.count count: args.count
}; };
@@ -1611,7 +1643,9 @@ var Commands = Module("commands", {
_("group.cantChangeBuiltin", _("command.commands"))); _("group.cantChangeBuiltin", _("command.commands")));
let completer = args["-complete"]; let completer = args["-complete"];
let completerFunc = function (context, args) modules.completion.exMacro(context, args, this); let completerFunc = function (context, args) {
return modules.completion.exMacro(context, args, this);
};
if (completer) { if (completer) {
if (/^custom,/.test(completer)) { if (/^custom,/.test(completer)) {
@@ -1637,14 +1671,18 @@ var Commands = Module("commands", {
let added = args["-group"].add(cmd.split(","), let added = args["-group"].add(cmd.split(","),
args["-description"], args["-description"],
contexts.bindMacro(args, "-ex", contexts.bindMacro(args, "-ex",
function makeParams(args, modifiers) ({ function makeParams(args, modifiers) {
args: { return {
__proto__: args, args: {
toString: function () this.string __proto__: args,
}, toString: function () {
bang: this.bang && args.bang ? "!" : "", return this.string;
count: this.count && args.count }
})), },
bang: this.bang && args.bang ? "!" : "",
count: this.count && args.count
};
}),
{ {
argCount: args["-nargs"], argCount: args["-nargs"],
bang: args["-bang"], bang: args["-bang"],
@@ -1782,13 +1820,15 @@ var Commands = Module("commands", {
name: ["listc[ommands]", "lc"], name: ["listc[ommands]", "lc"],
description: "List all Ex commands along with their short descriptions", description: "List all Ex commands along with their short descriptions",
index: "ex-cmd", index: "ex-cmd",
iterate: function (args) commands.iterator().map(cmd => ({ iterate: function (args) {
__proto__: cmd, return commands.iterator().map(cmd => ({
columns: [ __proto__: cmd,
cmd.hive == commands.builtin ? "" : ["span", { highlight: "Object", style: "padding-right: 1em;" }, columns: [
cmd.hive.name] cmd.hive == commands.builtin ? "" : ["span", { highlight: "Object", style: "padding-right: 1em;" },
] cmd.hive.name]
})), ]
}));
},
iterateIndex: function (args) { iterateIndex: function (args) {
let tags = help.tags; let tags = help.tags;
return this.iterate(args).filter(cmd => (cmd.hive === commands.builtin || return this.iterate(args).filter(cmd => (cmd.hive === commands.builtin ||
@@ -1796,8 +1836,10 @@ var Commands = Module("commands", {
}, },
format: { format: {
headings: ["Command", "Group", "Description"], headings: ["Command", "Group", "Description"],
description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : "")), description: function (cmd) {
help: function (cmd) ":" + cmd.name return template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : ""));
},
help: function (cmd) { return ":" + cmd.name; }
} }
}); });

View File

@@ -111,7 +111,9 @@ var CompletionContext = Class("CompletionContext", {
this.anchored = true; this.anchored = true;
this.forceAnchored = null; this.forceAnchored = null;
this.compare = function compare(a, b) String.localeCompare(a.text, b.text); this.compare = function compare(a, b) {
return String.localeCompare(a.text, b.text);
};
/** /**
* @property {function} This function is called when we close * @property {function} This function is called when we close
* a completion window with Esc or Ctrl-c. Usually this callback * a completion window with Esc or Ctrl-c. Usually this callback
@@ -219,9 +221,11 @@ var CompletionContext = Class("CompletionContext", {
* Returns a key, as detailed in {@link #keys}. * Returns a key, as detailed in {@link #keys}.
* @function * @function
*/ */
this.getKey = function getKey(item, key) (typeof self.keys[key] == "function") ? self.keys[key].call(this, item.item) : this.getKey = function getKey(item, key) {
return (typeof self.keys[key] == "function") ? self.keys[key].call(this, item.item) :
key in self.keys ? item.item[self.keys[key]] key in self.keys ? item.item[self.keys[key]]
: item.item[key]; : item.item[key];
};
return this; return this;
}, },
@@ -330,7 +334,9 @@ var CompletionContext = Class("CompletionContext", {
}, },
// Temporary // Temporary
get longestAllSubstring() { get longestAllSubstring() {
return this.allSubstrings.reduce(function r(a, b) a.length > b.length ? a : b, ""); return this.allSubstrings.reduce(function r(a, b) {
return a.length > b.length ? a : b, "";
});
}, },
get caret() { return this._caret - this.offset; }, get caret() { return this._caret - this.offset; },
@@ -536,12 +542,12 @@ var CompletionContext = Class("CompletionContext", {
// Item matchers // Item matchers
if (this.ignoreCase) if (this.ignoreCase)
this.matchString = this.anchored ? this.matchString = this.anchored ?
function matchString(filter, str) String.toLowerCase(str).indexOf(filter.toLowerCase()) == 0 : function matchString(filter, str) { return String.toLowerCase(str).indexOf(filter.toLowerCase()) == 0; } :
function matchString(filter, str) String.toLowerCase(str).indexOf(filter.toLowerCase()) >= 0; function matchString(filter, str) { return String.toLowerCase(str).indexOf(filter.toLowerCase()) >= 0; };
else else
this.matchString = this.anchored ? this.matchString = this.anchored ?
function matchString(filter, str) String.indexOf(str, filter) == 0 : function matchString(filter, str) { return String.indexOf(str, filter) == 0; } :
function matchString(filter, str) String.indexOf(str, filter) >= 0; function matchString(filter, str) { return String.indexOf(str, filter) >= 0; };
// Item formatters // Item formatters
this.processor = Array.slice(this.process); this.processor = Array.slice(this.process);
@@ -571,7 +577,9 @@ var CompletionContext = Class("CompletionContext", {
filtered.sort(this.compare); filtered.sort(this.compare);
if (!this.anchored) { if (!this.anchored) {
let filter = this.filter; let filter = this.filter;
filtered.sort(function s(a, b) b.text.startsWith(filter) - a.text.startsWith(filter)); filtered.sort(function s(a, b) {
return b.text.startsWith(filter) - a.text.startsWith(filter);
});
} }
} }
@@ -604,11 +612,11 @@ var CompletionContext = Class("CompletionContext", {
text = text.substr(0, 100); text = text.substr(0, 100);
if (this.anchored) { if (this.anchored) {
var compare = function compare(text, s) text.substr(0, s.length) == s; var compare = function compare(text, s) { return text.substr(0, s.length) == s; };
var substrings = [text]; var substrings = [text];
} }
else { else {
var compare = function compare(text, s) text.contains(s); var compare = function compare(text, s) { return text.contains(s); };
var substrings = []; var substrings = [];
let start = 0; let start = 0;
let idx; let idx;
@@ -619,8 +627,8 @@ var CompletionContext = Class("CompletionContext", {
} }
} }
substrings = items.reduce(function r(res, item) substrings = items.reduce(function r(res, item) {
res.map(function m(substring) { return res.map(function m(substring) {
// A simple binary search to find the longest substring // A simple binary search to find the longest substring
// of the given string which also matches the current // of the given string which also matches the current
// item's text. // item's text.
@@ -640,8 +648,8 @@ var CompletionContext = Class("CompletionContext", {
} }
} }
return len == substring.length ? substring : substring.substr(0, Math.max(len, 0)); return len == substring.length ? substring : substring.substr(0, Math.max(len, 0));
}), });
substrings); }, substrings);
let quote = this.quote; let quote = this.quote;
if (quote) if (quote)
@@ -860,7 +868,9 @@ var CompletionContext = Class("CompletionContext", {
* @param {string} str The string to match. * @param {string} str The string to match.
* @returns {boolean} True if the string matches, false otherwise. * @returns {boolean} True if the string matches, false otherwise.
*/ */
match: function match(str) this.matchString(this.filter, str), match: function match(str) {
return this.matchString(this.filter, str);
},
/** /**
* Pushes a new output processor onto the processor chain of * Pushes a new output processor onto the processor chain of
@@ -874,7 +884,9 @@ var CompletionContext = Class("CompletionContext", {
*/ */
pushProcessor: function pushProcess(index, func) { pushProcessor: function pushProcess(index, func) {
let next = this.process[index]; let next = this.process[index];
this.process[index] = function process_(item, text) func(item, text, next); this.process[index] = function process_(item, text) {
return func(item, text, next);
};
}, },
/** /**
@@ -887,7 +899,8 @@ var CompletionContext = Class("CompletionContext", {
throw Error(); throw Error();
this.offset = 0; this.offset = 0;
this.process = [template.icon, function process_1(item, k) k]; this.process = [template.icon,
function process_1(item, k) { return k; }];
this.filters = [CompletionContext.Filter.text]; this.filters = [CompletionContext.Filter.text];
this.tabPressed = false; this.tabPressed = false;
this.title = ["Completions"]; this.title = ["Completions"];
@@ -931,8 +944,10 @@ var CompletionContext = Class("CompletionContext", {
} }
}, { }, {
Sort: { Sort: {
number: function S_number(a, b) parseInt(a.text) - parseInt(b.text) number: function S_number(a, b) {
|| String.localeCompare(a.text, b.text), return parseInt(a.text) - parseInt(b.text) ||
String.localeCompare(a.text, b.text);
},
unsorted: null unsorted: null
}, },
@@ -962,65 +977,67 @@ var Completion = Module("completion", {
get setFunctionCompleter() { return JavaScript.setCompleter; }, // Backward compatibility get setFunctionCompleter() { return JavaScript.setCompleter; }, // Backward compatibility
Local: function Local(dactyl, modules, window) ({ Local: function Local(dactyl, modules, window) {
urlCompleters: {}, return {
urlCompleters: {},
get modules() { return modules; }, get modules() { return modules; },
get options() { return modules.options; }, get options() { return modules.options; },
// FIXME // FIXME
_runCompleter: function _runCompleter(name, filter, maxItems, ...args) { _runCompleter: function _runCompleter(name, filter, maxItems, ...args) {
let context = modules.CompletionContext(filter); let context = modules.CompletionContext(filter);
context.maxItems = maxItems; context.maxItems = maxItems;
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 { return {
items: res.map(function m(i) { items: res.map(function m(i) {
return { item: i }; return { item: i };
}) })
}; };
context.contexts["/run"].completions = res; context.contexts["/run"].completions = res;
}
context.wait(null, true);
return context.allItems;
},
runCompleter: function runCompleter(name, filter, maxItems) {
return apply(this, "_runCompleter", arguments)
.items.map(function m(i) { return i.item; });
},
listCompleter: function listCompleter(name, filter, maxItems, ...args) {
let context = modules.CompletionContext(filter || "");
context.maxItems = maxItems;
apply(context, "fork", ["list", 0, this, name].concat(args));
context = context.contexts["/list"];
context.wait(null, true);
let contexts = context.activeContexts;
if (!contexts.length)
contexts = context.contextList
.filter(function f(c) {
return c.hasItems;
})
.slice(0, 1);
if (!contexts.length)
contexts = context.contextList.slice(-1);
modules.commandline.commandOutput(
["div", { highlight: "Completions" },
template.map(contexts, function m(context) {
return [template.completionRow(context.title, "CompTitle"),
template.map(context.items,
function m(item) {
return context.createRow(item);
},
null,
100)];
})]);
} }
context.wait(null, true); };
return context.allItems; },
},
runCompleter: function runCompleter(name, filter, maxItems) {
return apply(this, "_runCompleter", arguments)
.items.map(function m(i) { return i.item; });
},
listCompleter: function listCompleter(name, filter, maxItems, ...args) {
let context = modules.CompletionContext(filter || "");
context.maxItems = maxItems;
apply(context, "fork", ["list", 0, this, name].concat(args));
context = context.contexts["/list"];
context.wait(null, true);
let contexts = context.activeContexts;
if (!contexts.length)
contexts = context.contextList
.filter(function f(c) {
return c.hasItems;
})
.slice(0, 1);
if (!contexts.length)
contexts = context.contextList.slice(-1);
modules.commandline.commandOutput(
["div", { highlight: "Completions" },
template.map(contexts, function m(context) {
return [template.completionRow(context.title, "CompTitle"),
template.map(context.items,
function m(item) {
return context.createRow(item);
},
null,
100)];
})]);
}
}),
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// COMPLETION TYPES //////////////////////////////////////// ////////////////////// COMPLETION TYPES ////////////////////////////////////////
@@ -1147,7 +1164,9 @@ var Completion = Module("completion", {
let contains = String.indexOf; let contains = String.indexOf;
if (context.ignoreCase) { if (context.ignoreCase) {
compare = util.compareIgnoreCase; compare = util.compareIgnoreCase;
contains = function contains_(a, b) a && a.toLowerCase().contains(b.toLowerCase()); contains = function contains_(a, b) {
return a && a.toLowerCase().contains(b.toLowerCase());
};
} }
if (tags) if (tags)
@@ -1191,8 +1210,12 @@ var Completion = Module("completion", {
} }
let process = context.process; let process = context.process;
context.process = [ context.process = [
function process_0(item, text) highlight.call(this, item, item.text, 0), function process_0(item, text) {
function process_1(item, text) highlight.call(this, item, text, 1) return highlight.call(this, item, item.text, 0);
},
function process_1(item, text) {
return highlight.call(this, item, text, 1);
}
]; ];
}); });
} }

View File

@@ -40,7 +40,7 @@ AboutHandler.prototype = {
return channel; return channel;
}, },
getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT getURIFlags: function (uri) { return Ci.nsIAboutModule.ALLOW_SCRIPT; }
}; };
var ConfigBase = Class("ConfigBase", { var ConfigBase = Class("ConfigBase", {
/** /**
@@ -74,14 +74,20 @@ var ConfigBase = Class("ConfigBase", {
services["dactyl:"].pages["dtd"] = () => [null, cache.get("config.dtd")]; services["dactyl:"].pages["dtd"] = () => [null, cache.get("config.dtd")];
update(services["dactyl:"].providers, { update(services["dactyl:"].providers, {
"locale": function (uri, path) LocaleChannel("dactyl-locale", config.locale, path, uri), "locale": function (uri, path) {
"locale-local": function (uri, path) LocaleChannel("dactyl-local-locale", config.locale, path, uri) return LocaleChannel("dactyl-locale", config.locale, path, uri);
},
"locale-local": function (uri, path) {
return LocaleChannel("dactyl-local-locale", config.locale, path, uri);
}
}); });
}, },
get prefs() { return localPrefs; }, get prefs() { return localPrefs; },
has: function (feature) this.features.has(feature), has: function (feature) {
return this.features.has(feature);
},
configFiles: [ configFiles: [
"resource://dactyl-common/config.json", "resource://dactyl-common/config.json",
@@ -478,59 +484,61 @@ var ConfigBase = Class("ConfigBase", {
this.helpStyled = true; this.helpStyled = true;
}, },
Local: function Local(dactyl, modules, { document, window }) ({ Local: function Local(dactyl, modules, { document, window }) {
init: function init() { return {
this.loadConfig(document.documentURI); init: function init() {
this.loadConfig(document.documentURI);
let append = [ let append = [
["menupopup", { id: "viewSidebarMenu", xmlns: "xul" }], ["menupopup", { id: "viewSidebarMenu", xmlns: "xul" }],
["broadcasterset", { id: "mainBroadcasterSet", xmlns: "xul" }]]; ["broadcasterset", { id: "mainBroadcasterSet", xmlns: "xul" }]];
for (let [id, [name, key, uri]] of iter(this.sidebars)) { for (let [id, [name, key, uri]] of iter(this.sidebars)) {
append[0].push( append[0].push(
["menuitem", { observes: "pentadactyl-" + id + "Sidebar", label: name, ["menuitem", { observes: "pentadactyl-" + id + "Sidebar", label: name,
accesskey: key }]); accesskey: key }]);
append[1].push( append[1].push(
["broadcaster", { id: "pentadactyl-" + id + "Sidebar", autoCheck: "false", ["broadcaster", { id: "pentadactyl-" + id + "Sidebar", autoCheck: "false",
type: "checkbox", group: "sidebar", sidebartitle: name, type: "checkbox", group: "sidebar", sidebartitle: name,
sidebarurl: uri, sidebarurl: uri,
oncommand: "toggleSidebar(this.id || this.observes);" }]); oncommand: "toggleSidebar(this.id || this.observes);" }]);
} }
util.overlayWindow(window, { append: append }); util.overlayWindow(window, { append: append });
}, },
get window() { return window; }, get window() { return window; },
get document() { return document; }, get document() { return document; },
ids: Class.Update({ ids: Class.Update({
get commandContainer() { return document.documentElement.id; } get commandContainer() { return document.documentElement.id; }
}), }),
browser: Class.Memoize(() => window.gBrowser), browser: Class.Memoize(() => window.gBrowser),
tabbrowser: Class.Memoize(() => window.gBrowser), tabbrowser: Class.Memoize(() => window.gBrowser),
get browserModes() { return [modules.modes.NORMAL]; }, get browserModes() { return [modules.modes.NORMAL]; },
/** /**
* @property {string} The ID of the application's main XUL window. * @property {string} The ID of the application's main XUL window.
*/ */
mainWindowId: document.documentElement.id, mainWindowId: document.documentElement.id,
/** /**
* @property {number} The height (px) that is available to the output * @property {number} The height (px) that is available to the output
* window. * window.
*/ */
get outputHeight() { get outputHeight() {
return this.browser.mPanelContainer.boxObject.height; return this.browser.mPanelContainer.boxObject.height;
}, },
tabStrip: Class.Memoize(function () { tabStrip: Class.Memoize(function () {
return document.getElementById("TabsToolbar") || return document.getElementById("TabsToolbar") ||
this.tabbrowser.mTabContainer; this.tabbrowser.mTabContainer;
}) })
}), };
},
/** /**
* @property {Object} A mapping of names and descriptions * @property {Object} A mapping of names and descriptions

View File

@@ -57,7 +57,7 @@ var Group = Class("Group", {
this.children.splice(0).forEach(this.contexts.bound.removeGroup); this.children.splice(0).forEach(this.contexts.bound.removeGroup);
}, },
argsExtra: function argsExtra() ({}), argsExtra: function argsExtra() { return {}; },
makeArgs: function makeArgs(doc, context, args) { makeArgs: function makeArgs(doc, context, args) {
let res = update({ doc: doc, context: context }, args); let res = update({ doc: doc, context: context }, args);
@@ -78,7 +78,9 @@ var Group = Class("Group", {
} }
return update(siteFilter, { return update(siteFilter, {
toString: function () this.filters.join(","), toString: function () {
return this.filters.join(",");
},
toJSONXML: function (modules) { toJSONXML: function (modules) {
let uri = modules && modules.buffer.uri; let uri = modules && modules.buffer.uri;
@@ -112,118 +114,120 @@ var Contexts = Module("contexts", {
this.pluginModules = {}; this.pluginModules = {};
}, },
Local: function Local(dactyl, modules, window) ({ Local: function Local(dactyl, modules, window) {
init: function () { return {
const contexts = this; init: function () {
this.modules = modules; const contexts = this;
this.modules = modules;
Object.defineProperty(modules.plugins, "contexts", Const({})); Object.defineProperty(modules.plugins, "contexts", Const({}));
this.groupList = []; this.groupList = [];
this.groupMap = {}; this.groupMap = {};
this.groupsProto = {}; this.groupsProto = {};
this.hives = {}; this.hives = {};
this.hiveProto = {}; this.hiveProto = {};
this.builtin = this.addGroup("builtin", "Builtin items"); this.builtin = this.addGroup("builtin", "Builtin items");
this.user = this.addGroup("user", "User-defined items", null, true); this.user = this.addGroup("user", "User-defined items", null, true);
this.builtinGroups = [this.builtin, this.user]; this.builtinGroups = [this.builtin, this.user];
this.builtin.modifiable = false; this.builtin.modifiable = false;
this.GroupFlag = Class("GroupFlag", CommandOption, { this.GroupFlag = Class("GroupFlag", CommandOption, {
init: function (name) { init: function (name) {
this.name = name;
this.type = ArgType("group", group => {
return isString(group) ? contexts.getGroup(group, name)
: group[name];
});
},
get toStringParams() { return [this.name]; },
names: ["-group", "-g"],
description: "Group to which to add",
get default() {
return (contexts.context &&
contexts.context.group ||
contexts.user)[this.name];
},
completer: function (context) {
modules.completion.group(context);
}
});
memoize(modules, "userContext", () => contexts.Context(modules.io.getRCFile("~", true), contexts.user, [modules, false]));
memoize(modules, "_userContext", () => modules.userContext);
},
cleanup: function () {
for (let hive of this.groupList.slice())
util.trapErrors("cleanup", hive, "shutdown");
},
destroy: function () {
for (let hive of this.groupList.slice())
util.trapErrors("destroy", hive, "shutdown");
for (let plugin of values(this.modules.plugins.contexts)) {
if (plugin && "onUnload" in plugin && callable(plugin.onUnload))
util.trapErrors("onUnload", plugin);
if (isinstance(plugin, ["Sandbox"]))
util.trapErrors("nukeSandbox", Cu, plugin);
}
},
signals: {
"browser.locationChange": function (webProgress, request, uri) {
this.flush();
}
},
Group: Class("Group", Group,
{ modules: modules,
get hiveMap() { return modules.contexts.hives; }}),
Hives: Class("Hives", Class.Property, {
init: function init(name, constructor) {
const { contexts } = modules;
if (this.Hive)
return {
enumerable: true,
get: () => Ary(contexts.groups[this.name])
};
this.Hive = constructor;
this.name = name; this.name = name;
memoize(contexts.Group.prototype, name, function () {
let group = constructor(this);
this.hives.push(group);
contexts.flush();
return group;
});
this.type = ArgType("group", group => { memoize(contexts.hives, name,
return isString(group) ? contexts.getGroup(group, name) () => Object.create(
: group[name]; Object.create(contexts.hiveProto,
{ _hive: { value: name } })));
memoize(contexts.groupsProto, name, function () {
return [group[name]
for (group of values(this.groups))
if (hasOwnProperty(group, name))];
}); });
}, },
get toStringParams() { return [this.name]; }, get toStringParams() { return [this.name, this.Hive]; }
})
names: ["-group", "-g"], };
},
description: "Group to which to add",
get default() {
return (contexts.context &&
contexts.context.group ||
contexts.user)[this.name];
},
completer: function (context) {
modules.completion.group(context);
}
});
memoize(modules, "userContext", () => contexts.Context(modules.io.getRCFile("~", true), contexts.user, [modules, false]));
memoize(modules, "_userContext", () => modules.userContext);
},
cleanup: function () {
for (let hive of this.groupList.slice())
util.trapErrors("cleanup", hive, "shutdown");
},
destroy: function () {
for (let hive of this.groupList.slice())
util.trapErrors("destroy", hive, "shutdown");
for (let plugin of values(this.modules.plugins.contexts)) {
if (plugin && "onUnload" in plugin && callable(plugin.onUnload))
util.trapErrors("onUnload", plugin);
if (isinstance(plugin, ["Sandbox"]))
util.trapErrors("nukeSandbox", Cu, plugin);
}
},
signals: {
"browser.locationChange": function (webProgress, request, uri) {
this.flush();
}
},
Group: Class("Group", Group,
{ modules: modules,
get hiveMap() { return modules.contexts.hives; }}),
Hives: Class("Hives", Class.Property, {
init: function init(name, constructor) {
const { contexts } = modules;
if (this.Hive)
return {
enumerable: true,
get: () => Ary(contexts.groups[this.name])
};
this.Hive = constructor;
this.name = name;
memoize(contexts.Group.prototype, name, function () {
let group = constructor(this);
this.hives.push(group);
contexts.flush();
return group;
});
memoize(contexts.hives, name,
() => Object.create(
Object.create(contexts.hiveProto,
{ _hive: { value: name } })));
memoize(contexts.groupsProto, name, function () {
return [group[name]
for (group of values(this.groups))
if (hasOwnProperty(group, name))];
});
},
get toStringParams() { return [this.name, this.Hive]; }
})
}),
Context: function Context(file, group, args) { Context: function Context(file, group, args) {
const { contexts, io, newContext, plugins, userContext } = this.modules; const { contexts, io, newContext, plugins, userContext } = this.modules;
@@ -292,7 +296,7 @@ var Contexts = Module("contexts", {
Object.defineProperty(plugins, self.NAME, { Object.defineProperty(plugins, self.NAME, {
configurable: true, configurable: true,
enumerable: true, enumerable: true,
get: function () self, get: function () { return self; },
set: function (val) { set: function (val) {
util.dactyl(val).reportError(FailedAssertion(_("plugin.notReplacingContext", self.NAME), 3, false), true); util.dactyl(val).reportError(FailedAssertion(_("plugin.notReplacingContext", self.NAME), 3, false), true);
} }
@@ -377,7 +381,7 @@ var Contexts = Module("contexts", {
Object.defineProperty(plugins, self.NAME, { Object.defineProperty(plugins, self.NAME, {
configurable: true, configurable: true,
enumerable: true, enumerable: true,
get: function () self, get: function () { return self; },
set: function (val) { set: function (val) {
util.dactyl(val).reportError(FailedAssertion(_("plugin.notReplacingContext", self.NAME), 3, false), true); util.dactyl(val).reportError(FailedAssertion(_("plugin.notReplacingContext", self.NAME), 3, false), true);
} }
@@ -413,9 +417,10 @@ var Contexts = Module("contexts", {
}); });
}), }),
matchingGroups: function (uri) Object.create(this.groupsProto, { matchingGroups: function (uri) {
groups: { value: this.activeGroups(uri) } return Object.create(this.groupsProto,
}), { groups: { value: this.activeGroups(uri) } });
},
activeGroups: function (uri) { activeGroups: function (uri) {
if (uri instanceof Ci.nsIDOMDocument) if (uri instanceof Ci.nsIDOMDocument)
@@ -525,8 +530,8 @@ var Contexts = Module("contexts", {
return Class.Property({ return Class.Property({
configurable: true, configurable: true,
enumerable: true, enumerable: true,
get: function Proxy_get() process(obj[key]), get: function Proxy_get() { return process(obj[key]); },
set: function Proxy_set(val) obj[key] = val set: function Proxy_set(val) { obj[key] = val; }
}); });
} }
@@ -592,11 +597,12 @@ var Contexts = Module("contexts", {
return action; return action;
}, },
withContext: function withContext(defaults, callback, self) withContext: function withContext(defaults, callback, self) {
this.withSavedValues(["context"], function () { return this.withSavedValues(["context"], function () {
this.context = defaults && update({}, defaults); this.context = defaults && update({}, defaults);
return callback.call(self, this.context); return callback.call(self, this.context);
}) });
}
}, { }, {
Hive: Class("Hive", { Hive: Class("Hive", {
init: function init(group) { init: function init(group) {

View File

@@ -22,7 +22,9 @@ var NS = "http://vimperator.org/namespaces/liberator";
function BooleanAttribute(attr) { function BooleanAttribute(attr) {
return { return {
get: function (elem) elem.getAttribute(attr) == "true", get: function (elem) {
return elem.getAttribute(attr) == "true";
},
set: function (elem, val) { set: function (elem, val) {
if (val === "false" || !val) if (val === "false" || !val)
elem.removeAttribute(attr); elem.removeAttribute(attr);
@@ -86,7 +88,9 @@ var DOM = Class("DOM", {
yield this[i]; yield this[i];
}, },
Empty: function Empty() this.constructor(null, this.document), Empty: function Empty() {
return this.constructor(null, this.document);
},
nodes: Class.Memoize(() => ({})), nodes: Class.Memoize(() => ({})),
@@ -117,7 +121,10 @@ var DOM = Class("DOM", {
} }
}, },
matcher: function matcher(sel) elem => (elem.mozMatchesSelector && elem.mozMatchesSelector(sel)), matcher: function matcher(sel) {
return elem => (elem.mozMatchesSelector &&
elem.mozMatchesSelector(sel));
},
each: function each(fn, self) { each: function each(fn, self) {
let obj = self || this.Empty(); let obj = self || this.Empty();
@@ -292,7 +299,9 @@ var DOM = Class("DOM", {
let self = this; let self = this;
return { return {
toString: function () self[0].className, toString: function () {
return self[0].className;
},
get list() { return Array.slice(self[0].classList); }, get list() { return Array.slice(self[0].classList); },
set list(val) { self.attr("class", val.join(" ")); }, set list(val) { self.attr("class", val.join(" ")); },
@@ -303,8 +312,10 @@ var DOM = Class("DOM", {
}); });
}, },
add: function add(cls) this.each("add", cls), add: function add(cls) { return this.each("add", cls); },
remove: function remove(cls) this.each("remove", cls), remove: function remove(cls) {
return this.each("remove", cls);
},
toggle: function toggle(cls, val, thisObj) { toggle: function toggle(cls, val, thisObj) {
if (callable(val)) if (callable(val))
return self.each(function (elem, i) { return self.each(function (elem, i) {
@@ -313,7 +324,9 @@ var DOM = Class("DOM", {
return this.each(val == null ? "toggle" : val ? "add" : "remove", cls); return this.each(val == null ? "toggle" : val ? "add" : "remove", cls);
}, },
has: function has(cls) this[0].classList.has(cls) has: function has(cls) {
return this[0].classList.has(cls);
}
}; };
}, },
@@ -321,7 +334,9 @@ var DOM = Class("DOM", {
let self = this; let self = this;
return { return {
toString: function () self.attrNS(NS, "highlight") || "", toString: function () {
return self.attrNS(NS, "highlight") || "";
},
get list() { get list() {
let s = this.toString().trim(); let s = this.toString().trim();
@@ -334,31 +349,39 @@ var DOM = Class("DOM", {
self.attrNS(NS, "highlight", str || null); self.attrNS(NS, "highlight", str || null);
}, },
has: function has(hl) ~this.list.indexOf(hl), has: function has(hl) {
return ~this.list.indexOf(hl);
},
add: function add(hl) self.each(function () { add: function add(hl) {
highlight.loaded[hl] = true; self.each(function () {
this.highlight.list = this.highlight.list.concat(hl); highlight.loaded[hl] = true;
}), this.highlight.list = this.highlight.list.concat(hl);
});
},
remove: function remove(hl) self.each(function () { remove: function remove(hl) {
this.highlight.list = this.highlight.list.filter(h => h != hl); self.each(function () {
}), this.highlight.list = this.highlight.list.filter(h => h != hl);
});
},
toggle: function toggle(hl, val, thisObj) self.each(function (elem, i) { toggle: function toggle(hl, val, thisObj) {
let { highlight } = this; self.each(function (elem, i) {
let v = callable(val) ? val.call(thisObj || this, elem, i) : val; let { highlight } = this;
let v = callable(val) ? val.call(thisObj || this, elem, i) : val;
highlight[(v == null ? highlight.has(hl) : !v) ? "remove" : "add"](hl); highlight[(v == null ? highlight.has(hl) : !v) ? "remove" : "add"](hl);
}) });
}
}; };
}, },
get rect() { get rect() {
return this[0] instanceof Ci.nsIDOMWindow ? { width: this[0].scrollMaxX + this[0].innerWidth, return this[0] instanceof Ci.nsIDOMWindow ? { width: this[0].scrollMaxX + this[0].innerWidth,
height: this[0].scrollMaxY + this[0].innerHeight, height: this[0].scrollMaxY + this[0].innerHeight,
get right() this.width + this.left, get right() { return this.width + this.left; },
get bottom() this.height + this.top, get bottom() { return this.height + this.top; },
top: -this[0].scrollY, top: -this[0].scrollY,
left: -this[0].scrollX } : left: -this[0].scrollX } :
this[0] ? this[0].getBoundingClientRect() : {}; this[0] ? this[0].getBoundingClientRect() : {};
@@ -712,9 +735,13 @@ var DOM = Class("DOM", {
return this[0].style[css.property(key)]; return this[0].style[css.property(key)];
}, { }, {
name: function (property) property.replace(/[A-Z]/g, m0 => "-" + m0.toLowerCase()), name: function (property) {
return property.replace(/[A-Z]/g, m0 => "-" + m0.toLowerCase());
},
property: function (name) name.replace(/-(.)/g, (m0, m1) => m1.toUpperCase()) property: function (name) {
return name.replace(/-(.)/g, (m0, m1) => m1.toUpperCase());
}
}), }),
append: function append(val) { append: function append(val) {
@@ -789,8 +816,9 @@ var DOM = Class("DOM", {
return this; return this;
}, },
clone: function clone(deep) clone: function clone(deep) {
this.map(elem => elem.cloneNode(deep)), return this.map(elem => elem.cloneNode(deep));
},
toggle: function toggle(val, self) { toggle: function toggle(val, self) {
if (callable(val)) if (callable(val))
@@ -824,11 +852,13 @@ var DOM = Class("DOM", {
}, this); }, this);
}, },
createContents: function createContents() createContents: function createContents() {
this.each(DOM.createContents, this), return this.each(DOM.createContents, this);
},
isScrollable: function isScrollable(direction) isScrollable: function isScrollable(direction) {
this.length && DOM.isScrollable(this[0], direction), return this.length && DOM.isScrollable(this[0], direction);
},
getSet: function getSet(args, get, set) { getSet: function getSet(args, get, set) {
if (!args.length) if (!args.length)
@@ -1455,16 +1485,19 @@ var DOM = Class("DOM", {
? (elem, dir) => services.dactyl.getScrollable(elem) & (dir ? services.dactyl["DIRECTION_" + dir.toUpperCase()] : ~0) ? (elem, dir) => services.dactyl.getScrollable(elem) & (dir ? services.dactyl["DIRECTION_" + dir.toUpperCase()] : ~0)
: (elem, dir) => true), : (elem, dir) => true),
isJSONXML: function isJSONXML(val) isArray(val) && isinstance(val[0], ["String", "Array", "XML", DOM.DOMString]) isJSONXML: function isJSONXML(val) {
|| isObject(val) && "toDOM" in val, return isArray(val) &&
isinstance(val[0], ["String", "Array", "XML", DOM.DOMString]) ||
isObject(val) && "toDOM" in val;
},
DOMString: function DOMString(val) ({ DOMString: function DOMString(val) {
__proto__: DOMString.prototype, return {
__proto__: DOMString.prototype,
toDOM: function toDOM(doc) doc.createTextNode(val), toDOM: function toDOM(doc) { return doc.createTextNode(val); },
toString: function () { return val; }
toString: function () val };
}), },
/** /**
* The set of input element type attribute values that mark the element as * The set of input element type attribute values that mark the element as
@@ -1889,10 +1922,12 @@ var DOM = Class("DOM", {
); );
let res = { let res = {
iterateNext: function () result.iterateNext(), iterateNext: function () { return result.iterateNext(); },
get resultType() { return result.resultType; }, get resultType() { return result.resultType; },
get snapshotLength() { return result.snapshotLength; }, get snapshotLength() { return result.snapshotLength; },
snapshotItem: function (i) result.snapshotItem(i) snapshotItem: function (i) {
return result.snapshotItem(i);
}
}; };
if (asIterator) if (asIterator)
res[Symbol.iterator] = function* () { res[Symbol.iterator] = function* () {
@@ -1912,7 +1947,9 @@ var DOM = Class("DOM", {
} }
}, },
{ {
resolver: function lookupNamespaceURI(prefix) (DOM.namespaces[prefix] || null) resolver: function lookupNamespaceURI(prefix) {
return DOM.namespaces[prefix] || null;
}
}), }),
/** /**

View File

@@ -76,7 +76,9 @@ var Download = Class("Download", {
get status() { return states[this.state]; }, get status() { return states[this.state]; },
inState: function inState(states) states.indexOf(this.status) >= 0, inState: function inState(states) {
return states.indexOf(this.status) >= 0;
},
allowedCommands: Class.Memoize(function () { allowedCommands: Class.Memoize(function () {
let self = this; let self = this;
@@ -161,11 +163,12 @@ var Download = Class("Download", {
url: (a, b) => String.localeCompare(a.source.url, b.source.url) url: (a, b) => String.localeCompare(a.source.url, b.source.url)
}, },
compare: function compare(other) values(this.list.sortOrder).map(function (order) { compare: function compare(other) {
let val = this._compare[order.substr(1)](this, other); return values(this.list.sortOrder).map(function (order) {
let val = this._compare[order.substr(1)](this, other);
return (order[0] == "-") ? -val : val; return (order[0] == "-") ? -val : val;
}, this).find(identity) || 0, }, this).find(identity) || 0;
},
timeRemaining: Infinity, timeRemaining: Infinity,
@@ -344,7 +347,9 @@ var DownloadList = Class("DownloadList",
this.nodes.list.childNodes[i + 1]); this.nodes.list.childNodes[i + 1]);
}, },
shouldSort: function shouldSort() Array.some(arguments, val => this.sortOrder.some(v => v.substr(1) == val)), shouldSort: function shouldSort() {
return Array.some(arguments, val => this.sortOrder.some(v => v.substr(1) == val));
},
update: function update() { update: function update() {
for (let node of values(this.nodes)) for (let node of values(this.nodes))
@@ -427,8 +432,8 @@ var DownloadList = Class("DownloadList",
"tryToKeepPartialData"].forEach(key => { "tryToKeepPartialData"].forEach(key => {
if (!(key in Download.prototype)) if (!(key in Download.prototype))
Object.defineProperty(Download.prototype, key, { Object.defineProperty(Download.prototype, key, {
get: function get() this.download[key], get: function get() { return this.download[key]; },
set: function set(val) this.download[key] = val, set: function set(val) { this.download[key] = val; },
configurable: true configurable: true
}); });
}); });

View File

@@ -23,32 +23,34 @@ function equals(a, b) {
/** @instance rangefinder */ /** @instance rangefinder */
var RangeFinder = Module("rangefinder", { var RangeFinder = Module("rangefinder", {
Local: function (dactyl, modules, window) ({ Local: function (dactyl, modules, window) {
init: function () { return {
this.dactyl = dactyl; init: function () {
this.modules = modules; this.dactyl = dactyl;
this.window = window; this.modules = modules;
this.lastFindPattern = ""; this.window = window;
}, this.lastFindPattern = "";
},
get content() { get content() {
let { window } = this.modes.getStack(0).params; let { window } = this.modes.getStack(0).params;
return window || this.window.content; return window || this.window.content;
}, },
get rangeFind() { get rangeFind() {
let find = overlay.getData(this.content.document, let find = overlay.getData(this.content.document,
"range-find", null); "range-find", null);
if (!isinstance(find, RangeFind) || find.stale) if (!isinstance(find, RangeFind) || find.stale)
return this.rangeFind = null; return this.rangeFind = null;
return find; return find;
}, },
set rangeFind(val) { set rangeFind(val) {
overlay.setData(this.content.document, overlay.setData(this.content.document,
"range-find", val); "range-find", val);
} }
}), };
},
init: function init() { init: function init() {
prefs.safeSet("accessibility.typeaheadfind.autostart", false); prefs.safeSet("accessibility.typeaheadfind.autostart", false);
@@ -754,7 +756,9 @@ var RangeFind = Class("RangeFind", {
return util.docShell(this.window); return util.docShell(this.window);
}), }),
intersects: function (range) RangeFind.intersects(this.range, range), intersects: function (range) {
return RangeFind.intersects(this.range, range);
},
save: function save() { save: function save() {
this.scroll = Point(this.window.pageXOffset, this.window.pageYOffset); this.scroll = Point(this.window.pageXOffset, this.window.pageYOffset);
@@ -802,7 +806,10 @@ var RangeFind = Class("RangeFind", {
return false; return false;
} }
}, },
containsNode: function containsNode(range, n, quiet) n.ownerDocument && this.contains(range, RangeFind.nodeRange(n), quiet), containsNode: function containsNode(range, n, quiet) {
return n.ownerDocument &&
this.contains(range, RangeFind.nodeRange(n), quiet);
},
intersects: function intersects(range, r) { intersects: function intersects(range, r) {
try { try {
return r.compareBoundaryPoints(range.START_TO_END, range) >= 0 && return r.compareBoundaryPoints(range.START_TO_END, range) >= 0 &&

View File

@@ -43,11 +43,13 @@ var HelpBuilder = Class("HelpBuilder", {
} }
}, },
toJSON: function toJSON() ({ toJSON: function toJSON() {
files: this.files, return {
overlays: this.overlays, files: this.files,
tags: this.tags overlays: this.overlays,
}), tags: this.tags
};
},
// Find the tags in the document. // Find the tags in the document.
addTags: function addTags(file, doc) { addTags: function addTags(file, doc) {
@@ -222,189 +224,196 @@ var Help = Module("Help", {
get overlays() { return this.data.overlays; }, get overlays() { return this.data.overlays; },
get tags() { return this.data.tags; }, get tags() { return this.data.tags; },
Local: function Local(dactyl, modules, window) ({ Local: function Local(dactyl, modules, window) {
init: function init() { return {
dactyl.commands["dactyl.help"] = event => { init: function init() {
let elem = event.originalTarget; dactyl.commands["dactyl.help"] = event => {
modules.help.help(elem.getAttribute("tag") || elem.textContent); let elem = event.originalTarget;
}; modules.help.help(elem.getAttribute("tag") || elem.textContent);
}, };
},
/** /**
* Returns the URL of the specified help *topic* if it exists. * Returns the URL of the specified help *topic* if it exists.
* *
* @param {string} topic The help topic to look up. * @param {string} topic The help topic to look up.
* @param {boolean} consolidated Whether to search the consolidated help page. * @param {boolean} consolidated Whether to search the consolidated help page.
* @returns {string} * @returns {string}
*/ */
findHelp: function (topic, consolidated) { findHelp: function (topic, consolidated) {
if (!consolidated && hasOwnProperty(help.files, topic)) if (!consolidated && hasOwnProperty(help.files, topic))
return topic; return topic;
let items = modules.completion._runCompleter("help", topic, null, !!consolidated).items; let items = modules.completion._runCompleter("help", topic, null, !!consolidated).items;
let partialMatch = null; let partialMatch = null;
function format(item) { function format(item) {
return item.description + "#" + encodeURIComponent(item.text); return item.description + "#" + encodeURIComponent(item.text);
}
for (let item of items) {
if (item.text == topic)
return format(item);
else if (!partialMatch && topic)
partialMatch = item;
}
if (partialMatch)
return format(partialMatch);
return null;
},
/**
* Opens the help page containing the specified *topic* if it exists.
*
* @param {string} topic The help topic to open.
* @param {boolean} consolidated Whether to use the consolidated help page.
*/
help: function (topic, consolidated) {
dactyl.initHelp();
if (!topic) {
let helpFile = consolidated ? "all" : modules.options["helpfile"];
if (hasOwnProperty(help.files, helpFile))
dactyl.open("dactyl://help/" + helpFile, { from: "help" });
else
dactyl.echomsg(_("help.noFile", JSON.stringify(helpFile)));
return;
}
let page = this.findHelp(topic, consolidated);
dactyl.assert(page != null, _("help.noTopic", topic));
dactyl.open("dactyl://help/" + page, { from: "help" });
},
exportHelp: function (path) {
const FILE = io.File(path);
const PATH = FILE.leafName.replace(/\..*/, "") + "/";
const TIME = Date.now();
if (!FILE.exists() && (/\/$/.test(path) && !/\./.test(FILE.leafName)))
FILE.create(FILE.DIRECTORY_TYPE, 0o755);
dactyl.initHelp();
if (FILE.isDirectory()) {
var addDataEntry = function addDataEntry(file, data) FILE.child(file).write(data);
var addURIEntry = function addURIEntry(file, uri) addDataEntry(file, util.httpGet(uri).responseText);
}
else {
var zip = services.ZipWriter(FILE.file, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
addURIEntry = function addURIEntry(file, uri)
zip.addEntryChannel(PATH + file, TIME, 9,
services.io.newChannel(uri, null, null), false);
addDataEntry = function addDataEntry(file, data) // Unideal to an extreme.
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
}
let empty = new RealSet("area base basefont br col frame hr img input isindex link meta param"
.split(" "));
function fix(node) {
switch (node.nodeType) {
case Ci.nsIDOMNode.ELEMENT_NODE:
if (isinstance(node, [Ci.nsIDOMHTMLBaseElement]))
return;
data.push("<", node.localName);
if (node instanceof Ci.nsIDOMHTMLHtmlElement)
data.push(" xmlns=" + JSON.stringify(XHTML),
" xmlns:dactyl=" + JSON.stringify(NS));
for (let { name, value } of node.attributes) {
if (name == "dactyl:highlight") {
styles.add(value);
name = "class";
value = "hl-" + value;
}
if (name == "href") {
value = node.href || value;
if (value.startsWith("dactyl://help-tag/")) {
try {
let uri = services.io.newChannel(value, null, null).originalURI;
value = uri.spec == value ? "javascript:;" : uri.path.substr(1);
}
catch (e) {
util.dump("Magical tag thingy failure for: " + value);
dactyl.reportError(e);
}
}
if (!/^#|[\/](#|$)|^[a-z]+:/.test(value))
value = value.replace(/(#|$)/, ".xhtml$1");
}
if (name == "src" && value.indexOf(":") > 0) {
chromeFiles[value] = value.replace(/.*\//, "");
value = value.replace(/.*\//, "");
}
data.push(" ", name, '="', DOM.escapeHTML(value), '"');
}
if (empty.has(node.localName))
data.push(" />");
else {
data.push(">");
if (node instanceof Ci.nsIDOMHTMLHeadElement)
data.push('<link rel="stylesheet" type="text/css" href="help.css"/>');
Array.map(node.childNodes, fix);
data.push("</", node.localName, ">");
}
break;
case Ci.nsIDOMNode.TEXT_NODE:
data.push(DOM.escapeHTML(node.textContent, true));
} }
for (let item of items) {
if (item.text == topic)
return format(item);
else if (!partialMatch && topic)
partialMatch = item;
}
if (partialMatch)
return format(partialMatch);
return null;
},
/**
* Opens the help page containing the specified *topic* if it exists.
*
* @param {string} topic The help topic to open.
* @param {boolean} consolidated Whether to use the consolidated help page.
*/
help: function (topic, consolidated) {
dactyl.initHelp();
if (!topic) {
let helpFile = consolidated ? "all" : modules.options["helpfile"];
if (hasOwnProperty(help.files, helpFile))
dactyl.open("dactyl://help/" + helpFile, { from: "help" });
else
dactyl.echomsg(_("help.noFile", JSON.stringify(helpFile)));
return;
}
let page = this.findHelp(topic, consolidated);
dactyl.assert(page != null, _("help.noTopic", topic));
dactyl.open("dactyl://help/" + page, { from: "help" });
},
exportHelp: function (path) {
const FILE = io.File(path);
const PATH = FILE.leafName.replace(/\..*/, "") + "/";
const TIME = Date.now();
if (!FILE.exists() && (/\/$/.test(path) && !/\./.test(FILE.leafName)))
FILE.create(FILE.DIRECTORY_TYPE, 0o755);
dactyl.initHelp();
if (FILE.isDirectory()) {
var addDataEntry = function addDataEntry(file, data) {
FILE.child(file).write(data);
};
var addURIEntry = function addURIEntry(file, uri) {
addDataEntry(file, util.httpGet(uri).responseText);
};
}
else {
var zip = services.ZipWriter(FILE.file, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
addURIEntry = function addURIEntry(file, uri) {
zip.addEntryChannel(PATH + file, TIME, 9,
services.io.newChannel(uri, null, null), false);
};
addDataEntry = function addDataEntry(file, data) {// Unideal to an extreme.
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
};
}
let empty = new RealSet("area base basefont br col frame hr img input isindex link meta param"
.split(" "));
function fix(node) {
switch (node.nodeType) {
case Ci.nsIDOMNode.ELEMENT_NODE:
if (isinstance(node, [Ci.nsIDOMHTMLBaseElement]))
return;
data.push("<", node.localName);
if (node instanceof Ci.nsIDOMHTMLHtmlElement)
data.push(" xmlns=" + JSON.stringify(XHTML),
" xmlns:dactyl=" + JSON.stringify(NS));
for (let { name, value } of node.attributes) {
if (name == "dactyl:highlight") {
styles.add(value);
name = "class";
value = "hl-" + value;
}
if (name == "href") {
value = node.href || value;
if (value.startsWith("dactyl://help-tag/")) {
try {
let uri = services.io.newChannel(value, null, null).originalURI;
value = uri.spec == value ? "javascript:;" : uri.path.substr(1);
}
catch (e) {
util.dump("Magical tag thingy failure for: " + value);
dactyl.reportError(e);
}
}
if (!/^#|[\/](#|$)|^[a-z]+:/.test(value))
value = value.replace(/(#|$)/, ".xhtml$1");
}
if (name == "src" && value.indexOf(":") > 0) {
chromeFiles[value] = value.replace(/.*\//, "");
value = value.replace(/.*\//, "");
}
data.push(" ", name, '="', DOM.escapeHTML(value), '"');
}
if (empty.has(node.localName))
data.push(" />");
else {
data.push(">");
if (node instanceof Ci.nsIDOMHTMLHeadElement)
data.push('<link rel="stylesheet" type="text/css" href="help.css"/>');
Array.map(node.childNodes, fix);
data.push("</", node.localName, ">");
}
break;
case Ci.nsIDOMNode.TEXT_NODE:
data.push(DOM.escapeHTML(node.textContent, true));
}
}
let { buffer, content, events } = modules;
let chromeFiles = {};
let styles = new RealSet;
for (let [file, ] of iter(help.files)) {
let url = "dactyl://help/" + file;
dactyl.open(url);
util.waitFor(() => (content.location.href == url && buffer.loaded &&
content.document.documentElement instanceof Ci.nsIDOMHTMLHtmlElement),
15000);
events.waitForPageLoad();
var data = [
'<?xml version="1.0" encoding="UTF-8"?>\n',
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n',
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
];
fix(content.document.documentElement);
addDataEntry(file + ".xhtml", data.join(""));
}
data = [h for (h of highlight)
if (styles.has(h.class) || /^Help/.test(h.class))]
.map(h => h.selector
.replace(/^\[.*?=(.*?)\]/, ".hl-$1")
.replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}")
.join("\n");
addDataEntry("help.css", data.replace(/chrome:[^ ")]+\//g, ""));
addDataEntry("tag-map.json", JSON.stringify(help.tags));
let m, re = /(chrome:[^ ");]+\/)([^ ");]+)/g;
while ((m = re.exec(data)))
chromeFiles[m[0]] = m[2];
for (let [uri, leaf] of iter(chromeFiles))
addURIEntry(leaf, uri);
if (zip)
zip.close();
} }
};
let { buffer, content, events } = modules; }
let chromeFiles = {};
let styles = new RealSet;
for (let [file, ] of iter(help.files)) {
let url = "dactyl://help/" + file;
dactyl.open(url);
util.waitFor(() => (content.location.href == url && buffer.loaded &&
content.document.documentElement instanceof Ci.nsIDOMHTMLHtmlElement),
15000);
events.waitForPageLoad();
var data = [
'<?xml version="1.0" encoding="UTF-8"?>\n',
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n',
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
];
fix(content.document.documentElement);
addDataEntry(file + ".xhtml", data.join(""));
}
data = [h for (h of highlight)
if (styles.has(h.class) || /^Help/.test(h.class))]
.map(h => h.selector
.replace(/^\[.*?=(.*?)\]/, ".hl-$1")
.replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}")
.join("\n");
addDataEntry("help.css", data.replace(/chrome:[^ ")]+\//g, ""));
addDataEntry("tag-map.json", JSON.stringify(help.tags));
let m, re = /(chrome:[^ ");]+\/)([^ ");]+)/g;
while ((m = re.exec(data)))
chromeFiles[m[0]] = m[2];
for (let [uri, leaf] of iter(chromeFiles))
addURIEntry(leaf, uri);
if (zip)
zip.close();
}
})
}, { }, {
}, { }, {
commands: function initCommands(dactyl, modules, window) { commands: function initCommands(dactyl, modules, window) {
@@ -445,7 +454,10 @@ var Help = Module("Help", {
context.anchored = false; context.anchored = false;
context.completions = help.tags; context.completions = help.tags;
if (consolidated) if (consolidated)
context.keys = { text: 0, description: function () "all" }; context.keys = {
text: 0,
description: function () { return "all"; }
};
}; };
}, },
javascript: function initJavascript(dactyl, modules, window) { javascript: function initJavascript(dactyl, modules, window) {

View File

@@ -97,9 +97,11 @@ update(Highlight.prototype, {
get cssText() { return this.inheritedCSS + this.value; }, get cssText() { return this.inheritedCSS + this.value; },
toString: function () "Highlight(" + this.class + ")\n\t" + toString: function () {
[k + ": " + JSON.stringify(String(v)) return "Highlight(" + this.class + ")\n\t" +
for ([k, v] of this)].join("\n\t") [k + ": " + JSON.stringify(String(v))
for ([k, v] of this)].join("\n\t");
}
}); });
/** /**
@@ -113,10 +115,15 @@ var Highlights = Module("Highlight", {
this.loaded = {}; this.loaded = {};
}, },
keys: function keys() Object.keys(this.highlight).sort(), keys: function keys() {
return Object.keys(this.highlight).sort();
},
"@@iterator": function () values(this.highlight).sort((a, b) => String.localeCompare(a.class, b.class)) "@@iterator": function () {
.iterValues(), return values(this.highlight)
.sort((a, b) => String.localeCompare(a.class, b.class))
.iterValues();
},
_create: function _create(agent, args) { _create: function _create(agent, args) {
let obj = Highlight.apply(Highlight, args); let obj = Highlight.apply(Highlight, args);
@@ -165,7 +172,9 @@ var Highlights = Module("Highlight", {
return obj; return obj;
}, },
get: function get(k) this.highlight[k], get: function get(k) {
return this.highlight[k];
},
set: function set(key, newStyle, force, append, extend) { set: function set(key, newStyle, force, append, extend) {
let highlight = this.highlight[key] || this._create(false, [key]); let highlight = this.highlight[key] || this._create(false, [key]);
@@ -234,13 +243,13 @@ var Highlights = Module("Highlight", {
* *
* @param {string} class * @param {string} class
*/ */
selector: function selector(class_) selector: function selector(class_) {
class_.replace(/(^|[>\s])([A-Z][\w-]+)\b/g, return class_.replace(/(^|[>\s])([A-Z][\w-]+)\b/g, (m, n1, hl) => {
(m, n1, hl) => { if (this.highlight[hl] && this.highlight[hl].class != class_)
if (this.highlight[hl] && this.highlight[hl].class != class_) return n1 + this.highlight[hl].selector;
return n1 + this.highlight[hl].selector; return n1 + "[dactyl|highlight~=" + hl + "]";
return n1 + "[dactyl|highlight~=" + hl + "]"; });
}), },
groupRegexp: util.regexp(literal(function () /* groupRegexp: util.regexp(literal(function () /*
^ ^

View File

@@ -300,8 +300,9 @@ var IO = Module("io", {
File: Class.Memoize(function () { File: Class.Memoize(function () {
let io = this; let io = this;
return Class("File", File, { return Class("File", File, {
init: function init(path, checkCWD=true) init: function init(path, checkCWD=true) {
init.supercall(this, path, checkCWD && io.cwd) return init.supercall(this, path, checkCWD && io.cwd);
}
}); });
}), }),
@@ -530,11 +531,13 @@ var IO = Module("io", {
function result(status, output) { function result(status, output) {
return { return {
__noSuchMethod__: function (meth, args) apply(this.output, meth, args), __noSuchMethod__: function (meth, args) {
valueOf: function () this.output, return apply(this.output, meth, args);
},
valueOf: function () { return this.output; },
output: output.replace(/^(.*)\n$/, "$1"), output: output.replace(/^(.*)\n$/, "$1"),
returnValue: status, returnValue: status,
toString: function () this.output toString: function () { return this.output; }
}; };
} }

View File

@@ -34,14 +34,16 @@ var JavaScript = Module("javascript", {
this._nullSandbox = Cu.Sandbox("about:blank"); this._nullSandbox = Cu.Sandbox("about:blank");
}, },
Local: function (dactyl, modules, window) ({ Local: function (dactyl, modules, window) {
init: function init() { return {
this.modules = modules; init: function init() {
this.window = window; this.modules = modules;
this.window = window;
init.supercall(this); init.supercall(this);
} }
}), };
},
globals: Class.Memoize(function () { globals: Class.Memoize(function () {
return [ return [
@@ -57,8 +59,10 @@ var JavaScript = Module("javascript", {
lazyInit: true, lazyInit: true,
newContext: function () this.modules.newContext(this.modules.userContext, false, newContext: function () {
"Dactyl JS Temp Context"), return this.modules.newContext(this.modules.userContext, false,
"Dactyl JS Temp Context");
},
completers: Class.Memoize(() => Object.create(JavaScript.completers)), completers: Class.Memoize(() => Object.create(JavaScript.completers)),
@@ -354,8 +358,9 @@ var JavaScript = Module("javascript", {
} }
if (!compl) { if (!compl) {
base.process[1] = function highlight(item, v) base.process[1] = function highlight(item, v) {
template.highlight(typeof v == "xml" ? new String(v.toXMLString()) : v, true, 200); return template.highlight(typeof v == "xml" ? new String(v.toXMLString()) : v, true, 200);
};
// Sort in a logical fashion for object keys: // Sort in a logical fashion for object keys:
// Numbers are sorted as numbers, rather than strings, and appear first. // Numbers are sorted as numbers, rather than strings, and appear first.
@@ -376,7 +381,9 @@ var JavaScript = Module("javascript", {
base.keys = { base.keys = {
text: prefix ? text => text.substr(prefix.length) text: prefix ? text => text.substr(prefix.length)
: text => text, : text => text,
description: function (item) self.getKey(this.obj, item), description: function (item) {
return self.getKey(this.obj, item);
},
key: function (item) { key: function (item) {
if (!isNaN(key)) if (!isNaN(key))
return parseInt(key); return parseInt(key);
@@ -769,7 +776,9 @@ var JavaScript = Module("javascript", {
return this.rootNode; return this.rootNode;
}), }),
__noSuchMethod__: function (meth, args) apply(Buffer, meth, [this.rootNode].concat(args)) __noSuchMethod__: function (meth, args) {
return apply(Buffer, meth, [this.rootNode].concat(args));
}
}); });
modules.CommandREPLMode = Class("CommandREPLMode", modules.CommandMode, { modules.CommandREPLMode = Class("CommandREPLMode", modules.CommandMode, {

View File

@@ -26,7 +26,9 @@ var ModuleBase = Class("ModuleBase", {
*/ */
requires: [], requires: [],
toString: function () "[module " + this.constructor.className + "]" toString: function () {
return "[module " + this.constructor.className + "]";
}
}); });
var _id = 0; var _id = 0;

View File

@@ -29,9 +29,9 @@ var Messages = Module("messages", {
} }
return self.get(message); return self.get(message);
}), }),
valueOf: function valueOf() this.message, valueOf: function valueOf() { return this.message; },
toString: function toString() this.message, toString: function toString() { return this.message; },
toJSON: function toJSON() this.message toJSON: function toJSON() { return this.message; }
}); });
}, },
@@ -200,7 +200,7 @@ var Messages = Module("messages", {
return Class.replaceProperty(this, prop, value); return Class.replaceProperty(this, prop, value);
}, },
set: function set(val) this[_prop] = val set: function set(val) { this[_prop] = val; }
}; };
} }
this.default = prop; this.default = prop;

View File

@@ -107,9 +107,13 @@ var Option = Class("Option", {
* @param {value} value The option value. * @param {value} value The option value.
* @returns {value|[string]} * @returns {value|[string]}
*/ */
parse: function parse(value) Option.dequote(value), parse: function parse(value) {
return Option.dequote(value);
},
parseKey: function parseKey(value) value, parseKey: function parseKey(value) {
return value;
},
/** /**
* Returns *values* packed in the appropriate format for the option type. * Returns *values* packed in the appropriate format for the option type.
@@ -117,7 +121,9 @@ var Option = Class("Option", {
* @param {value|[string]} values The option value. * @param {value|[string]} values The option value.
* @returns {value} * @returns {value}
*/ */
stringify: function stringify(vals) Commands.quote(vals), stringify: function stringify(vals) {
return Commands.quote(vals);
},
/** /**
* Returns the option's value as an array of parsed values if the option * Returns the option's value as an array of parsed values if the option
@@ -203,7 +209,9 @@ var Option = Class("Option", {
get stringDefaultValue() { return this.stringify(this.defaultValue); }, get stringDefaultValue() { return this.stringify(this.defaultValue); },
set stringDefaultValue(val) { this.defaultValue = this.parse(val); }, set stringDefaultValue(val) { this.defaultValue = this.parse(val); },
getKey: function getKey(key) undefined, getKey: function getKey(key) {
return undefined;
},
/** /**
* Returns whether the option value contains one or more of the specified * Returns whether the option value contains one or more of the specified
@@ -211,7 +219,9 @@ var Option = Class("Option", {
* *
* @returns {boolean} * @returns {boolean}
*/ */
has: function has() Array.some(arguments, val => this.value.indexOf(val) >= 0), has: function has() {
return Array.some(arguments, val => this.value.indexOf(val) >= 0);
},
/** /**
* Returns whether this option is identified by *name*. * Returns whether this option is identified by *name*.
@@ -219,16 +229,22 @@ var Option = Class("Option", {
* @param {string} name * @param {string} name
* @returns {boolean} * @returns {boolean}
*/ */
hasName: function hasName(name) this.names.indexOf(name) >= 0, hasName: function hasName(name) {
return this.names.indexOf(name) >= 0;
},
/** /**
* Returns whether the specified *values* are valid for this option. * Returns whether the specified *values* are valid for this option.
* @see Option#validator * @see Option#validator
*/ */
isValidValue: function isValidValue(values) this.validator(values), isValidValue: function isValidValue(values) {
return this.validator(values);
},
invalidArgument: function invalidArgument(arg, op) _("error.invalidArgument", invalidArgument: function invalidArgument(arg, op) {
this.name + (op || "").replace(/=?$/, "=") + arg), return _("error.invalidArgument",
this.name + (op || "").replace(/=?$/, "=") + arg);
},
/** /**
* Resets the option to its default value. * Resets the option to its default value.
@@ -325,8 +341,9 @@ var Option = Class("Option", {
* @property {function(host, values)} A function which should strip * @property {function(host, values)} A function which should strip
* references to a given domain from the given values. * references to a given domain from the given values.
*/ */
filterDomain: function filterDomain(host, values) filterDomain: function filterDomain(host, values) {
Array.filter(values, val => !this.domains([val]).some(val => util.isSubdomain(val, host))), return Array.filter(values, val => !this.domains([val]).some(val => util.isSubdomain(val, host)));
},
/** /**
* @property {value} The option's default value. This value will be used * @property {value} The option's default value. This value will be used
@@ -388,7 +405,9 @@ var Option = Class("Option", {
*/ */
setter: null, setter: null,
testValues: function testValues(values, validator) validator(values), testValues: function testValues(values, validator) {
return validator(values);
},
/** /**
* @property {function} The function called to validate the option's value * @property {function} The function called to validate the option's value
@@ -445,7 +464,9 @@ var Option = Class("Option", {
SCOPE_BOTH: 3, SCOPE_BOTH: 3,
has: { has: {
toggleAll: function toggleAll() toggleAll.supercall(this, "all") ^ !!toggleAll.superapply(this, arguments) toggleAll: function toggleAll() {
return toggleAll.supercall(this, "all") ^ !!toggleAll.superapply(this, arguments);
}
}, },
parseRegexp: function parseRegexp(value, result, flags) { parseRegexp: function parseRegexp(value, result, flags) {
@@ -467,8 +488,10 @@ var Option = Class("Option", {
return re; return re;
}, },
unparseRegexp: function unparseRegexp(re, quoted) re.bang + Option.quote(util.regexp.getSource(re), /^!|:/) + unparseRegexp: function unparseRegexp(re, quoted) {
(typeof re.result === "boolean" ? "" : ":" + (quoted ? re.result : Option.quote(re.result, /:/))), return re.bang + Option.quote(util.regexp.getSource(re), /^!|:/) +
(typeof re.result === "boolean" ? "" : ":" + (quoted ? re.result : Option.quote(re.result, /:/)));
},
parseSite: function parseSite(pattern, result, rest) { parseSite: function parseSite(pattern, result, rest) {
if (isArray(rest)) // Called by Array.map if (isArray(rest)) // Called by Array.map
@@ -484,13 +507,17 @@ var Option = Class("Option", {
bang: bang, bang: bang,
filter: filter, filter: filter,
result: result !== undefined ? result : !bang, result: result !== undefined ? result : !bang,
toString: function toString() this.bang + Option.quote(this.filter, /:/) + toString: function toString() {
(typeof this.result === "boolean" ? "" : ":" + quote(this.result)) return this.bang + Option.quote(this.filter, /:/) +
(typeof this.result === "boolean" ? "" : ":" + quote(this.result));
}
}); });
}, },
getKey: { getKey: {
stringlist: function stringlist(k) this.value.indexOf(k) >= 0, stringlist: function stringlist(k) {
return this.value.indexOf(k) >= 0;
},
get charlist() { return this.stringlist; }, get charlist() { return this.stringlist; },
regexplist: function regexplist(k, default_=null) { regexplist: function regexplist(k, default_=null) {
@@ -505,40 +532,58 @@ var Option = Class("Option", {
}, },
domains: { domains: {
sitelist: function (vals) Ary.compact(vals.map(site => util.getHost(site.filter))), sitelist: function (vals) {
return Ary.compact(vals.map(site => util.getHost(site.filter)));
},
get sitemap() { return this.sitelist; } get sitemap() { return this.sitelist; }
}, },
stringify: { stringify: {
charlist: function (vals) Commands.quote(vals.join("")), charlist: function (vals) {
return Commands.quote(vals.join(""));
},
stringlist: function (vals) vals.map(Option.quote).join(","), stringlist: function (vals) {
return vals.map(Option.quote).join(",");
},
stringmap: function (vals) [Option.quote(k, /:/) + ":" + Option.quote(v, /:/) for ([k, v] of iter(vals))].join(","), stringmap: function (vals) {
return [Option.quote(k, /:/) + ":" + Option.quote(v, /:/) for ([k, v] of iter(vals))].join(",");
},
regexplist: function (vals) vals.join(","), regexplist: function (vals) { return vals.join(","); },
get regexpmap() { return this.regexplist; }, get regexpmap() { return this.regexplist; },
get sitelist() { return this.regexplist; }, get sitelist() { return this.regexplist; },
get sitemap() { return this.regexplist; } get sitemap() { return this.regexplist; }
}, },
parse: { parse: {
number: function (value) { number: function (value) {
let val = Option.dequote(value); let val = Option.dequote(value);
return (Option.validIf(Number(val) % 1 == 0, return (Option.validIf(Number(val) % 1 == 0,
_("option.intRequired")) && _("option.intRequired")) &&
parseInt(val)); parseInt(val));
}, },
boolean: function boolean(value) Option.dequote(value) == "true" || value == true ? true : false, boolean: function boolean(value) {
return Option.dequote(value) == "true" || value == true ? true : false;
},
charlist: function charlist(value) Array.slice(Option.dequote(value)), charlist: function charlist(value) {
return Array.slice(Option.dequote(value));
},
stringlist: function stringlist(value) (value === "") ? [] : Option.splitList(value), stringlist: function stringlist(value) {
return (value === "") ? [] : Option.splitList(value);
},
regexplist: function regexplist(value) (value === "") ? [] : regexplist: function regexplist(value) {
Option.splitList(value, true) if (value === "")
.map(re => Option.parseRegexp(re, undefined, this.regexpFlags)), return [];
else
return Option.splitList(value, true)
.map(re => Option.parseRegexp(re, undefined, this.regexpFlags));
},
sitelist: function sitelist(value) { sitelist: function sitelist(value) {
if (value === "") if (value === "")
@@ -548,15 +593,20 @@ var Option = Class("Option", {
return value.map(Option.parseSite, this); return value.map(Option.parseSite, this);
}, },
stringmap: function stringmap(value) Ary.toObject( stringmap: function stringmap(value) {
Option.splitList(value, true).map(function (v) { return Ary.toObject(Option.splitList(value, true).map(v => {
let [count, key, quote] = Commands.parseArg(v, /:/); let [count, key, quote] = Commands.parseArg(v, /:/);
return [key, Option.dequote(v.substr(count + 1))]; return [key, Option.dequote(v.substr(count + 1))];
})), }));
},
regexpmap: function regexpmap(value) Option.parse.list.call(this, value, Option.parseRegexp), regexpmap: function regexpmap(value) {
return Option.parse.list.call(this, value, Option.parseRegexp);
},
sitemap: function sitemap(value) Option.parse.list.call(this, value, Option.parseSite), sitemap: function sitemap(value) {
return Option.parse.list.call(this, value, Option.parseSite);
},
list: function list(value, parse) { list: function list(value, parse) {
let prev = null; let prev = null;
@@ -580,14 +630,22 @@ var Option = Class("Option", {
parseKey: { parseKey: {
number: Number, number: Number,
boolean: function boolean(value) value == "true" || value == true ? true : false boolean: function boolean(value) {
return value == "true" || value == true ? true : false;
}
}, },
testValues: { testValues: {
regexpmap: function regexpmap(vals, validator) vals.every(re => validator(re.result)), regexpmap: function regexpmap(vals, validator) {
return vals.every(re => validator(re.result));
},
get sitemap() { return this.regexpmap; }, get sitemap() { return this.regexpmap; },
stringlist: function stringlist(vals, validator) vals.every(validator, this), stringlist: function stringlist(vals, validator) {
stringmap: function stringmap(vals, validator) values(vals).every(validator, this) return vals.every(validator, this);
},
stringmap: function stringmap(vals, validator) {
return values(vals).every(validator, this);
}
}, },
dequote: function dequote(value) { dequote: function dequote(value) {
@@ -613,10 +671,13 @@ var Option = Class("Option", {
return res; return res;
}, },
quote: function quote(str, re) isArray(str) ? str.map(s => quote(s, re)).join(",") : // XXX
Commands.quoteArg[/[\s|"'\\,]|^$/.test(str) || re && re.test && re.test(str) quote: function quote(str, re) {
? (/[\b\f\n\r\t]/.test(str) ? '"' : "'") return isArray(str) ? str.map(s => quote(s, re)).join(",") :
: ""](str, re), Commands.quoteArg[/[\s|"'\\,]|^$/.test(str) || re && re.test && re.test(str)
? (/[\b\f\n\r\t]/.test(str) ? '"' : "'")
: ""](str, re);
},
ops: { ops: {
boolean: function boolean(operator, values, scope, invert) { boolean: function boolean(operator, values, scope, invert) {
@@ -1002,8 +1063,9 @@ var Options = Module("options", {
}, },
/** @property {Iterator(Option)} @private */ /** @property {Iterator(Option)} @private */
"@@iterator": function __iterator__() "@@iterator": function __iterator__() {
values(this._options.sort((a, b) => String.localeCompare(a.name, b.name))), return values(this._options.sort((a, b) => String.localeCompare(a.name, b.name)));
},
allPrefs: deprecated("prefs.getNames", function allPrefs() apply(prefs, "getNames", arguments)), allPrefs: deprecated("prefs.getNames", function allPrefs() apply(prefs, "getNames", arguments)),
getPref: deprecated("prefs.get", function getPref() apply(prefs, "get", arguments)), getPref: deprecated("prefs.get", function getPref() apply(prefs, "get", arguments)),
@@ -1130,16 +1192,18 @@ var Options = Module("options", {
name: ["listo[ptions]", "lo"], name: ["listo[ptions]", "lo"],
description: "List all options along with their short descriptions", description: "List all options along with their short descriptions",
index: "option", index: "option",
iterate: function (args) options, iterate: function (args) { return options; },
format: { format: {
description: function (opt) [ description: function (opt) {
return [
opt.scope == Option.SCOPE_LOCAL opt.scope == Option.SCOPE_LOCAL
? ["span", { highlight: "URLExtra" }, ? ["span", { highlight: "URLExtra" },
"(" + _("option.bufferLocal") + ")"] "(" + _("option.bufferLocal") + ")"]
: "", : "",
template.linkifyHelp(opt.description) template.linkifyHelp(opt.description)
], ];
help: function (opt) "'" + opt.name + "'" },
help: function (opt) { return "'" + opt.name + "'"; }
} }
}); });
@@ -1439,24 +1503,28 @@ var Options = Module("options", {
update({ update({
bang: true, bang: true,
completer: setCompleter, completer: setCompleter,
domains: function domains(args) Ary.flatten(args.map(function (spec) { domains: function domains(args) {
try { return Ary.flatten(args.map(function (spec) {
let opt = modules.options.parseOpt(spec); try {
if (opt.option && opt.option.domains) let opt = modules.options.parseOpt(spec);
return opt.option.domains(opt.values); if (opt.option && opt.option.domains)
} return opt.option.domains(opt.values);
catch (e) { }
util.reportError(e); catch (e) {
} util.reportError(e);
return []; }
})), return [];
}));
},
keepQuotes: true, keepQuotes: true,
privateData: function privateData(args) args.some(function (spec) { privateData: function privateData(args) {
let opt = modules.options.parseOpt(spec); return args.some(function (spec) {
return opt.option && opt.option.privateData && let opt = modules.options.parseOpt(spec);
(!callable(opt.option.privateData) || return opt.option && opt.option.privateData &&
opt.option.privateData(opt.values)); (!callable(opt.option.privateData) ||
}) opt.option.privateData(opt.values));
});
}
}, params.extra || {})); }, params.extra || {}));
}); });

View File

@@ -13,8 +13,9 @@ defineModule("overlay", {
lazyRequire("highlight", ["highlight"]); lazyRequire("highlight", ["highlight"]);
var getAttr = function getAttr(elem, ns, name) var getAttr = function getAttr(elem, ns, name) {
elem.hasAttributeNS(ns, name) ? elem.getAttributeNS(ns, name) : null; return elem.hasAttributeNS(ns, name) ? elem.getAttributeNS(ns, name) : null;
};
var setAttr = function setAttr(elem, ns, name, val) { var setAttr = function setAttr(elem, ns, name, val) {
if (val == null) if (val == null)
elem.removeAttributeNS(ns, name); elem.removeAttributeNS(ns, name);
@@ -34,7 +35,7 @@ var Overlay = Class("Overlay", {
get win() { return this.window; }, get win() { return this.window; },
$: function $(sel, node) DOM(sel, node || this.doc), $: function $(sel, node) { return DOM(sel, node || this.doc); },
cleanup: function cleanup(window, reason) { cleanup: function cleanup(window, reason) {
for (let fn of this.cleanups) for (let fn of this.cleanups)

View File

@@ -80,7 +80,7 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
* @param {string} branch The sub-branch to branch to. * @param {string} branch The sub-branch to branch to.
* @returns {Prefs} * @returns {Prefs}
*/ */
Branch: function Branch(branch) Prefs(this.root + branch), Branch: function Branch(branch) { return Prefs(this.root + branch); },
/** /**
* Clears the entire branch. * Clears the entire branch.
@@ -143,21 +143,27 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
* @param {string} branch The sub-branch for which to return preferences. * @param {string} branch The sub-branch for which to return preferences.
* @optional * @optional
*/ */
getNames: function getNames(branch) this.branch.getChildList(branch || "", { value: 0 }), getNames: function getNames(branch) {
return this.branch.getChildList(branch || "", { value: 0 });
},
/** /**
* Returns true if the given preference exists in this branch. * Returns true if the given preference exists in this branch.
* *
* @param {string} name The name of the preference to check. * @param {string} name The name of the preference to check.
*/ */
has: function has(name) this.branch.getPrefType(name) !== 0, has: function has(name) {
return this.branch.getPrefType(name) !== 0;
},
/** /**
* Returns true if the given preference is set to its default value. * Returns true if the given preference is set to its default value.
* *
* @param {string} name The name of the preference to check. * @param {string} name The name of the preference to check.
*/ */
isDefault: function isDefault(name) !this.branch.prefHasUserValue(name), isDefault: function isDefault(name) {
return !this.branch.prefHasUserValue(name);
},
_checkSafe: function _checkSafe(name, message, value) { _checkSafe: function _checkSafe(name, message, value) {
let curval = this.get(name, null); let curval = this.get(name, null);
@@ -382,7 +388,7 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
if (!this._observers[pref]) if (!this._observers[pref])
this._observers[pref] = []; this._observers[pref] = [];
this._observers[pref].push(!strong ? util.weakReference(callback) this._observers[pref].push(!strong ? util.weakReference(callback)
: { get: function () callback }); : { get: function () { return callback; } });
}, },
/** /**
@@ -429,8 +435,10 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
modules.completion.preference = function preference(context) { modules.completion.preference = function preference(context) {
context.anchored = false; context.anchored = false;
context.title = [config.host + " Preference", "Value"]; context.title = [config.host + " Preference", "Value"];
context.keys = { text: function (item) item, context.keys = {
description: function (item) prefs.get(item) }; text: function (item) { return item; },
description: function (item) { return prefs.get(item); }
};
context.completions = prefs.getNames(); context.completions = prefs.getNames();
}; };
}, },

View File

@@ -86,7 +86,9 @@ function ProtocolBase() {
this.pages = {}; this.pages = {};
this.providers = { this.providers = {
"content": function (uri, path) this.pages[path] || this.contentBase + path, "content": function (uri, path) {
return this.pages[path] || this.contentBase + path;
},
"data": function (uri) { "data": function (uri) {
var channel = services.io.newChannel(uri.path.replace(/^\/(.*)(?:#.*)?/, "data:$1"), var channel = services.io.newChannel(uri.path.replace(/^\/(.*)(?:#.*)?/, "data:$1"),
@@ -116,7 +118,7 @@ ProtocolBase.prototype = {
}, },
defaultPort: -1, defaultPort: -1,
allowPort: function (port, scheme) false, allowPort: function (port, scheme) { return false; },
protocolFlags: 0 protocolFlags: 0
| Ci.nsIProtocolHandler.URI_IS_UI_RESOURCE | Ci.nsIProtocolHandler.URI_IS_UI_RESOURCE
| Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE, | Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE,

View File

@@ -52,8 +52,8 @@ var Item = Class("SanitizeItem", {
}, },
// Hack for completion: // Hack for completion:
"0": Class.Property({ get: function () this.name }), "0": Class.Property({ get: function () { return this.name; } }),
"1": Class.Property({ get: function () this.description }), "1": Class.Property({ get: function () { return this.description; } }),
description: Messages.Localized(""), description: Messages.Localized(""),
@@ -66,8 +66,10 @@ var Item = Class("SanitizeItem", {
get cpd() { return prefs.get(this.cpdPref); }, get cpd() { return prefs.get(this.cpdPref); },
get shutdown() { return prefs.get(this.shutdownPref); }, get shutdown() { return prefs.get(this.shutdownPref); },
shouldSanitize: function (shutdown) (!shutdown || this.builtin || this.persistent) && shouldSanitize: function (shutdown) {
prefs.get(shutdown ? this.shutdownPref : this.pref) return (!shutdown || this.builtin || this.persistent) &&
prefs.get(shutdown ? this.shutdownPref : this.pref);
}
}, { }, {
PREFIX: config.prefs.branch.root, PREFIX: config.prefs.branch.root,
BRANCH: "privacy.cpd.", BRANCH: "privacy.cpd.",
@@ -89,7 +91,10 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
this.itemMap = {}; this.itemMap = {};
this.addItem("all", { description: "Sanitize all items", shouldSanitize: function () false }); this.addItem("all", {
description: "Sanitize all items",
shouldSanitize: function () { return false; }
});
// Builtin items // Builtin items
this.addItem("cache", { builtin: true, description: "Cache" }); this.addItem("cache", { builtin: true, description: "Cache" });
this.addItem("downloads", { builtin: true, description: "Download history" }); this.addItem("downloads", { builtin: true, description: "Download history" });
@@ -344,8 +349,8 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
prefs.set("privacy.sanitize.sanitizeOnShutdown", Boolean(val)); prefs.set("privacy.sanitize.sanitizeOnShutdown", Boolean(val));
}, },
sanitize: function sanitize(items, range) sanitize: function sanitize(items, range) {
this.withSavedValues(["sanitizing"], function () { return this.withSavedValues(["sanitizing"], function () {
this.sanitizing = true; this.sanitizing = true;
let errors = this.sanitizeItems(items, range, null); let errors = this.sanitizeItems(items, range, null);
@@ -366,10 +371,11 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
} }
} }
return errors; return errors;
}), });
},
sanitizeItems: function sanitizeItems(items, range, host, key) sanitizeItems: function sanitizeItems(items, range, host, key) {
this.withSavedValues(["sanitizing"], function () { return this.withSavedValues(["sanitizing"], function () {
this.sanitizing = true; this.sanitizing = true;
if (items == null) if (items == null)
items = Object.keys(this.itemMap); items = Object.keys(this.itemMap);
@@ -387,7 +393,8 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
util.reportError(e); util.reportError(e);
} }
return errors; return errors;
}) });
}
}, { }, {
PERMS: { PERMS: {
unset: 0, unset: 0,
@@ -415,8 +422,12 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
offlineapps: "offlineApps", offlineapps: "offlineApps",
sitesettings: "siteSettings" sitesettings: "siteSettings"
}, },
argToPref: function (arg) Sanitizer.argPrefMap[arg] || arg, argToPref: function (arg) {
prefToArg: function (pref) pref.replace(/.*\./, "").toLowerCase(), return Sanitizer.argPrefMap[arg] || arg;
},
prefToArg: function (pref) {
return pref.replace(/.*\./, "").toLowerCase();
},
iterCookies: function* iterCookies(host) { iterCookies: function* iterCookies(host) {
for (let c of iter(services.cookies, Ci.nsICookie2)) for (let c of iter(services.cookies, Ci.nsICookie2))
@@ -664,10 +675,14 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
for (i of values(sanitizer.itemMap)) for (i of values(sanitizer.itemMap))
if (i.persistent || i.builtin)]; if (i.persistent || i.builtin)];
}, },
getter: function () !sanitizer.runAtShutdown ? [] : [ getter: function () {
item.name for (item of values(sanitizer.itemMap)) if (!sanitizer.runAtShutdown)
if (item.shouldSanitize(true)) return [];
], else
return [item.name
for (item of values(sanitizer.itemMap))
if (item.shouldSanitize(true))];
},
setter: function (value) { setter: function (value) {
if (value.length === 0) if (value.length === 0)
sanitizer.runAtShutdown = false; sanitizer.runAtShutdown = false;

View File

@@ -208,8 +208,11 @@ var Services = Module("Services", {
* *
* @param {string} name The service's cache key. * @param {string} name The service's cache key.
*/ */
has: function has(name) hasOwnProperty(this.services, name) && this.services[name].class in Cc && has: function has(name) {
this.services[name].interfaces.every(iface => iface in Ci) return hasOwnProperty(this.services, name) &&
this.services[name].class in Cc &&
this.services[name].interfaces.every(iface => iface in Ci);
}
}); });
endModule(); endModule();

View File

@@ -139,7 +139,10 @@ var ArrayStore = Class("ArrayStore", StoreBase, {
this.fireEvent("change", null); this.fireEvent("change", null);
}, },
get: function get(index) index >= 0 ? this._object[index] : this._object[this._object.length + index] get: function get(index) {
return index >= 0 ? this._object[index] :
this._object[this._object.length + index];
}
}); });
var ObjectStore = Class("ObjectStore", StoreBase, { var ObjectStore = Class("ObjectStore", StoreBase, {
@@ -156,9 +159,13 @@ var ObjectStore = Class("ObjectStore", StoreBase, {
undefined; undefined;
}, },
has: function has(key) hasOwnProperty(this._object, key), has: function has(key) {
return hasOwnProperty(this._object, key);
},
keys: function keys() Object.keys(this._object), keys: function keys() {
return Object.keys(this._object);
},
remove: function remove(key) { remove: function remove(key) {
var res = this._object[key]; var res = this._object[key];
@@ -182,11 +189,13 @@ var ObjectStore = Class("ObjectStore", StoreBase, {
var sessionGlobal = Cu.import("resource://gre/modules/Services.jsm", {}); var sessionGlobal = Cu.import("resource://gre/modules/Services.jsm", {});
var Storage = Module("Storage", { var Storage = Module("Storage", {
Local: function Local(dactyl, modules, window) ({ Local: function Local(dactyl, modules, window) {
init: function init() { return {
this.privateMode = PrivateBrowsingUtils.isWindowPrivate(window); init: function init() {
} this.privateMode = PrivateBrowsingUtils.isWindowPrivate(window);
}), }
};
},
alwaysReload: {}, alwaysReload: {},
@@ -381,7 +390,9 @@ var Storage = Module("Storage", {
} }
}, { }, {
Replacer: { Replacer: {
skipXpcom: function skipXpcom(key, val) val instanceof Ci.nsISupports ? null : val skipXpcom: function skipXpcom(key, val) {
return val instanceof Ci.nsISupports ? null : val;
}
} }
}, { }, {
cleanup: function (dactyl, modules, window) { cleanup: function (dactyl, modules, window) {
@@ -616,31 +627,38 @@ var File = Class("File", {
}, },
// Wrapped native methods: // Wrapped native methods:
copyTo: function copyTo(dir, name) copyTo: function copyTo(dir, name) {
this.file.copyTo(this.constructor(dir).file, return this.file.copyTo(this.constructor(dir).file,
name), name);
},
copyToFollowingLinks: function copyToFollowingLinks(dir, name) copyToFollowingLinks: function copyToFollowingLinks(dir, name) {
this.file.copyToFollowingLinks(this.constructor(dir).file, return this.file.copyToFollowingLinks(this.constructor(dir).file,
name), name);
},
moveTo: function moveTo(dir, name) moveTo: function moveTo(dir, name) {
this.file.moveTo(this.constructor(dir).file, return this.file.moveTo(this.constructor(dir).file,
name), name);
},
equals: function equals(file) equals: function equals(file) {
this.file.equals(this.constructor(file).file), return this.file.equals(this.constructor(file).file);
},
contains: function contains(dir, recur) contains: function contains(dir, recur) {
this.file.contains(this.constructor(dir).file, return this.file.contains(this.constructor(dir).file,
recur), recur);
},
getRelativeDescriptor: function getRelativeDescriptor(file) getRelativeDescriptor: function getRelativeDescriptor(file) {
this.file.getRelativeDescriptor(this.constructor(file).file), return this.file.getRelativeDescriptor(this.constructor(file).file);
},
setRelativeDescriptor: function setRelativeDescriptor(file, path) setRelativeDescriptor: function setRelativeDescriptor(file, path) {
this.file.setRelativeDescriptor(this.constructor(file).file, this.file.setRelativeDescriptor(this.constructor(file).file,
path) path);
}
}, { }, {
/** /**
* @property {number} Open for reading only. * @property {number} Open for reading only.
@@ -705,14 +723,16 @@ var File = Class("File", {
"g"); "g");
}), }),
DoesNotExist: function DoesNotExist(path, error) ({ DoesNotExist: function DoesNotExist(path, error) {
__proto__: DoesNotExist.prototype, return {
path: path, __proto__: DoesNotExist.prototype,
exists: function () false, path: path,
__noSuchMethod__: function () { exists: function () { return false; },
throw error || Error("Does not exist"); __noSuchMethod__: function () {
} throw error || Error("Does not exist");
}), }
};
},
defaultEncoding: "UTF-8", defaultEncoding: "UTF-8",
@@ -757,7 +777,9 @@ var File = Class("File", {
return OS.Path.normalize(path.replace(/\//g, File.PATH_SEP)); return OS.Path.normalize(path.replace(/\//g, File.PATH_SEP));
}, },
expandPathList: function (list) list.map(this.expandPath), expandPathList: function (list) {
return list.map(this.expandPath);
},
readURL: function readURL(url, encoding) { readURL: function readURL(url, encoding) {
let channel = services.io.newChannel(url, null, null); let channel = services.io.newChannel(url, null, null);
@@ -808,7 +830,9 @@ var File = Class("File", {
} }
}, },
replacePathSep: function replacePathSep(path) path.split("/").join(File.PATH_SEP), replacePathSep: function replacePathSep(path) {
return path.split("/").join(File.PATH_SEP);
},
joinPaths: function joinPaths(head, tail, cwd) { joinPaths: function joinPaths(head, tail, cwd) {
let path = this(head, cwd); let path = this(head, cwd);
@@ -840,7 +864,7 @@ var File = Class("File", {
else else
Object.defineProperty(File.prototype, prop, { Object.defineProperty(File.prototype, prop, {
configurable: true, configurable: true,
get: function wrap_get() this.file[prop], get: function wrap_get() { return this.file[prop]; },
set: function wrap_set(val) { this.file[prop] = val; } set: function wrap_set(val) { this.file[prop] = val; }
}); });
} }

View File

@@ -33,10 +33,11 @@ Sheet.liveProperty("agent");
Sheet.liveProperty("css"); Sheet.liveProperty("css");
Sheet.liveProperty("sites"); Sheet.liveProperty("sites");
update(Sheet.prototype, { update(Sheet.prototype, {
formatSites: function (uris) formatSites: function (uris) {
template.map(this.sites, return template.map(this.sites,
filter => ["span", { highlight: uris.some(Styles.matchFilter(filter)) ? "Filter" : "" }, filter], filter => ["span", { highlight: uris.some(Styles.matchFilter(filter)) ? "Filter" : "" }, filter],
","), ",");
},
remove: function () { this.hive.remove(this); }, remove: function () { this.hive.remove(this); },
@@ -119,7 +120,9 @@ var Hive = Class("Hive", {
}); });
}, },
"@@iterator": function () iter(this.sheets), "@@iterator": function () {
return iter(this.sheets);
},
get sites() { get sites() {
return Ary(this.sheets).map(s => s.sites) return Ary(this.sheets).map(s => s.sites)
@@ -259,9 +262,9 @@ var Hive = Class("Hive", {
* @author Kris Maglione <maglione.k@gmail.com> * @author Kris Maglione <maglione.k@gmail.com>
*/ */
var Styles = Module("Styles", { var Styles = Module("Styles", {
Local: function (dactyl, modules, window) ({ Local: function (dactyl, modules, window) {
cleanup: function () {} return { cleanup: function () {} };
}), },
init: function () { init: function () {
this._id = 0; this._id = 0;
@@ -298,7 +301,9 @@ var Styles = Module("Styles", {
return hive; return hive;
}, },
"@@iterator": function () iter(this.user.sheets.concat(this.system.sheets)), "@@iterator": function () {
return iter(this.user.sheets.concat(this.system.sheets));
},
_proxy: function (name, args) { _proxy: function (name, args) {
let obj = this[args[0] ? "system" : "user"]; let obj = this[args[0] ? "system" : "user"];
@@ -677,24 +682,30 @@ var Styles = Module("Styles", {
{ {
name: ["stylee[nable]", "stye[nable]"], name: ["stylee[nable]", "stye[nable]"],
desc: "Enable a user style sheet", desc: "Enable a user style sheet",
action: function (sheet) sheet.enabled = true, action: function (sheet) {
filter: function (sheet) !sheet.enabled sheet.enabled = true;
},
filter: function (sheet) { return !sheet.enabled; }
}, },
{ {
name: ["styled[isable]", "styd[isable]"], name: ["styled[isable]", "styd[isable]"],
desc: "Disable a user style sheet", desc: "Disable a user style sheet",
action: function (sheet) sheet.enabled = false, action: function (sheet) {
filter: function (sheet) sheet.enabled sheet.enabled = false;
},
filter: function (sheet) { return sheet.enabled; }
}, },
{ {
name: ["stylet[oggle]", "styt[oggle]"], name: ["stylet[oggle]", "styt[oggle]"],
desc: "Toggle a user style sheet", desc: "Toggle a user style sheet",
action: function (sheet) sheet.enabled = !sheet.enabled action: function (sheet) {
sheet.enabled = !sheet.enabled;
}
}, },
{ {
name: ["dels[tyle]"], name: ["dels[tyle]"],
desc: "Remove a user style sheet", desc: "Remove a user style sheet",
action: function (sheet) sheet.remove() action: function (sheet) { sheet.remove(); }
} }
].forEach(function (cmd) { ].forEach(function (cmd) {
commands.add(cmd.name, cmd.desc, commands.add(cmd.name, cmd.desc,
@@ -752,8 +763,10 @@ var Styles = Module("Styles", {
const names = Array.slice(DOM(["div"], window.document).style); const names = Array.slice(DOM(["div"], window.document).style);
modules.completion.css = context => { modules.completion.css = context => {
context.title = ["CSS Property"]; context.title = ["CSS Property"];
context.keys = { text: function (p) p + ":", context.keys = {
description: function () "" }; text: function (p) { return p + ":"; },
description: function () { return ""; }
};
for (let match of Styles.propertyIter(context.filter, true)) for (let match of Styles.propertyIter(context.filter, true))
var lastMatch = match; var lastMatch = match;
@@ -767,10 +780,10 @@ var Styles = Module("Styles", {
javascript: function initJavascript(dactyl, modules, window) { javascript: function initJavascript(dactyl, modules, window) {
modules.JavaScript.setCompleter(["get", "add", "remove", "find"].map(m => Hive.prototype[m]), modules.JavaScript.setCompleter(["get", "add", "remove", "find"].map(m => Hive.prototype[m]),
[ // Prototype: (name, filter, css, index) [ // Prototype: (name, filter, css, index)
function (context, obj, args) this.names, function (context, obj, args) { return this.names; },
(context, obj, args) => Styles.completeSite(context, window.content), (context, obj, args) => Styles.completeSite(context, window.content),
null, null,
function (context, obj, args) this.sheets function (context, obj, args) { return this.sheets; }
]); ]);
}, },
template: function initTemplate() { template: function initTemplate() {

View File

@@ -49,14 +49,16 @@ var Binding = Class("Binding", {
}.call(this); }.call(this);
}, },
bind: function bind(func) function bound() { bind: function bind(func) {
try { return function bound() {
return func.apply(this.dactylBinding, arguments); try {
} return func.apply(this.dactylBinding, arguments);
catch (e) { }
util.reportError(e); catch (e) {
throw e; util.reportError(e);
} throw e;
}
};
}, },
events: Class.Memoize(function () { events: Class.Memoize(function () {
@@ -88,7 +90,7 @@ var Binding = Class("Binding", {
Object.defineProperty(Binding.prototype, key, { Object.defineProperty(Binding.prototype, key, {
configurable: true, configurable: true,
enumerable: false, enumerable: false,
value: function () apply(this.node, key, arguments), value: function () { return apply(this.node, key, arguments); },
writable: true writable: true
}); });
}); });
@@ -174,22 +176,26 @@ var Template = Module("Template", {
return res; return res;
}, },
bookmarkDescription: function (item, text) [ bookmarkDescription: function (item, text) {
!(item.extra && item.extra.length) ? [] : return [
["span", { highlight: "URLExtra" }, !(item.extra && item.extra.length) ? [] :
" (", ["span", { highlight: "URLExtra" },
template.map(item.extra, e => " (",
["", e[0], ": ", template.map(item.extra, e =>
["span", { highlight: e[2] }, e[1]]], ["", e[0], ": ",
"\u00a0"), ["span", { highlight: e[2] }, e[1]]],
")\u00a0"], "\u00a0"),
["a", { identifier: item.id == null ? "" : item.id, ")\u00a0"],
"dactyl:command": item.command || "", ["a", { identifier: item.id == null ? "" : item.id,
href: item.item.url, highlight: "URL" }, "dactyl:command": item.command || "",
text || ""] href: item.item.url, highlight: "URL" },
], text || ""]
];
},
filter: function (str) ["span", { highlight: "Filter" }, str], filter: function (str) {
return ["span", { highlight: "Filter" }, str];
},
completionRow: function completionRow(item, highlightGroup) { completionRow: function completionRow(item, highlightGroup) {
if (typeof icon == "function") if (typeof icon == "function")
@@ -378,12 +384,14 @@ var Template = Module("Template", {
return str; return str;
}, },
icon: function (item, text) [ icon: function (item, text) {
["span", { highlight: "CompIcon" }, return [
item.icon ? ["img", { src: item.icon }] : []], ["span", { highlight: "CompIcon" },
["span", { class: "td-strut" }], item.icon ? ["img", { src: item.icon }] : []],
text ["span", { class: "td-strut" }],
], text
];
},
jumps: function jumps(index, elems) { jumps: function jumps(index, elems) {
return ["table", {}, return ["table", {},

View File

@@ -24,7 +24,7 @@ var Magic = Class("Magic", {
get message() { return this.str; }, get message() { return this.str; },
toString: function () this.str toString: function () { return this.str; }
}); });
var FailedAssertion = Class("FailedAssertion", ErrorBase, { var FailedAssertion = Class("FailedAssertion", ErrorBase, {
@@ -119,7 +119,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
}; };
}, { }, {
__noSuchMethod__: function __noSuchMethod__() this().__noSuchMethod__.apply(null, arguments) __noSuchMethod__: function __noSuchMethod__() {
return this().__noSuchMethod__.apply(null, arguments);
}
}), }),
/** /**
@@ -186,15 +188,18 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {string} name The name to mangle. * @param {string} name The name to mangle.
* @returns {string} The mangled name. * @returns {string} The mangled name.
*/ */
camelCase: function camelCase(name) String.replace(name, /-(.)/g, camelCase: function camelCase(name) {
(m, m1) => m1.toUpperCase()), return String.replace(name, /-(.)/g, (m, m1) => m1.toUpperCase());
},
/** /**
* Capitalizes the first character of the given string. * Capitalizes the first character of the given string.
* @param {string} str The string to capitalize * @param {string} str The string to capitalize
* @returns {string} * @returns {string}
*/ */
capitalize: function capitalize(str) str && str[0].toUpperCase() + str.slice(1).toLowerCase(), capitalize: function capitalize(str) {
return str && str[0].toUpperCase() + str.slice(1).toLowerCase();
},
/** /**
* Returns a RegExp object that matches characters specified in the range * Returns a RegExp object that matches characters specified in the range
@@ -255,7 +260,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {string} b * @param {string} b
* @returns {number} * @returns {number}
*/ */
compareIgnoreCase: function compareIgnoreCase(a, b) String.localeCompare(a.toLowerCase(), b.toLowerCase()), compareIgnoreCase: function compareIgnoreCase(a, b) {
return String.localeCompare(a.toLowerCase(), b.toLowerCase());
},
compileFormat: function compileFormat(format) { compileFormat: function compileFormat(format) {
let stack = [frame()]; let stack = [frame()];
@@ -272,7 +279,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
}, { }, {
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) {
return this.elements.every(e => !e.test || e.test(obj));
}
}); });
} }
@@ -296,15 +305,15 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
util.assert(stack.length, /*L*/"Unmatched %] in format"); util.assert(stack.length, /*L*/"Unmatched %] in format");
} }
else { else {
let quote = function quote(obj, char) obj[char]; let quote = function quote(obj, char) { return obj[char]; };
if (char !== char.toLowerCase()) if (char !== char.toLowerCase())
quote = function quote(obj, char) Commands.quote(obj[char]); quote = function quote(obj, char) { return Commands.quote(obj[char]); };
char = char.toLowerCase(); char = char.toLowerCase();
stack.top.elements.push(update( stack.top.elements.push(update(
obj => obj[char] != null ? quote(obj, char) obj => obj[char] != null ? quote(obj, char)
: "", : "",
{ test: function test(obj) obj[char] != null })); { test: function test(obj) { return obj[char] != null; } }));
for (let elem of stack) for (let elem of stack)
elem.seen[char] = true; elem.seen[char] = true;
@@ -362,7 +371,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
}, { }, {
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) {
return this.elements.every(e => !e.test || e.test(obj));
}
}); });
} }
@@ -415,9 +426,12 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
obj => obj[name] != null && idx in obj[name] ? quote(obj[name][idx]) obj => obj[name] != null && idx in obj[name] ? quote(obj[name][idx])
: hasOwnProperty(obj, name) ? "" : unknown(full), : hasOwnProperty(obj, name) ? "" : unknown(full),
{ {
test: function test(obj) obj[name] != null && idx in obj[name] test: function test(obj) {
&& obj[name][idx] !== false return obj[name] != null &&
&& (!flags.e || obj[name][idx] != "") idx in obj[name] &&
obj[name][idx] !== false &&
(!flags.e || obj[name][idx] != "");
}
})); }));
} }
else { else {
@@ -425,9 +439,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
obj => obj[name] != null ? quote(obj[name]) obj => obj[name] != null ? quote(obj[name])
: hasOwnProperty(obj, name) ? "" : unknown(full), : hasOwnProperty(obj, name) ? "" : unknown(full),
{ {
test: function test(obj) obj[name] != null test: function test(obj) {
&& obj[name] !== false return obj[name] != null &&
&& (!flags.e || obj[name] != "") obj[name] !== false &&
(!flags.e || obj[name] != "");
}
})); }));
} }
@@ -554,8 +570,10 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {string} chars The characters to unquote. * @param {string} chars The characters to unquote.
* @returns {string} * @returns {string}
*/ */
dequote: function dequote(pattern, chars) dequote: function dequote(pattern, chars) {
pattern.replace(/\\(.)/, (m0, m1) => chars.contains(m1) ? m1 : m0), return pattern.replace(/\\(.)/,
(m0, m1) => chars.contains(m1) ? m1 : m0);
},
/** /**
* Returns the nsIDocShell for the given window. * Returns the nsIDocShell for the given window.
@@ -564,9 +582,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @returns {nsIDocShell} * @returns {nsIDocShell}
*/ */
docShell: function docShell(win) docShell: function docShell(win) {
win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation) return win.QueryInterface(Ci.nsIInterfaceRequestor)
.QueryInterface(Ci.nsIDocShell), .getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
},
/** /**
* Prints a message to the console. If *msg* is an object it is pretty * Prints a message to the console. If *msg* is an object it is pretty
@@ -799,7 +819,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
if (params.method == "HEAD" && !params.notificationCallbacks) if (params.method == "HEAD" && !params.notificationCallbacks)
params.notificationCallbacks = Class(XPCOM([Ci.nsIChannelEventSink, Ci.nsIInterfaceRequestor]), { params.notificationCallbacks = Class(XPCOM([Ci.nsIChannelEventSink, Ci.nsIInterfaceRequestor]), {
getInterface: function getInterface(iid) this.QueryInterface(iid), getInterface: function getInterface(iid) {
return this.QueryInterface(iid);
},
asyncOnChannelRedirect: function (oldChannel, newChannel, flags, callback) { asyncOnChannelRedirect: function (oldChannel, newChannel, flags, callback) {
if (newChannel instanceof Ci.nsIHttpChannel) if (newChannel instanceof Ci.nsIHttpChannel)
@@ -860,14 +882,16 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {Object} r2 * @param {Object} r2
* @returns {Object} * @returns {Object}
*/ */
intersection: function intersection(r1, r2) ({ intersection: function intersection(r1, r2) {
get width() { return this.right - this.left; }, return {
get height() { return this.bottom - this.top; }, get width() { return this.right - this.left; },
left: Math.max(r1.left, r2.left), get height() { return this.bottom - this.top; },
right: Math.min(r1.right, r2.right), left: Math.max(r1.left, r2.left),
top: Math.max(r1.top, r2.top), right: Math.min(r1.right, r2.right),
bottom: Math.min(r1.bottom, r2.bottom) top: Math.max(r1.top, r2.top),
}), bottom: Math.min(r1.bottom, r2.bottom)
};
},
/** /**
* Returns true if the given stack frame resides in Dactyl code. * Returns true if the given stack frame resides in Dactyl code.
@@ -888,7 +912,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {string} domain * @param {string} domain
* @returns {boolean} * @returns {boolean}
*/ */
isDomainURL: function isDomainURL(url, domain) util.isSubdomain(util.getHost(url), domain), isDomainURL: function isDomainURL(url, domain) {
return util.isSubdomain(util.getHost(url), domain);
},
/** /**
* Returns true if *host* is a subdomain of *domain*. * Returns true if *host* is a subdomain of *domain*.
@@ -1010,7 +1036,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* Removes leading garbage prepended to URIs by the subscript * Removes leading garbage prepended to URIs by the subscript
* loader. * loader.
*/ */
fixURI: function fixURI(url) String.replace(url, /.* -> /, ""), fixURI: function fixURI(url) {
return String.replace(url, /.* -> /, "");
},
/** /**
* Pretty print a JavaScript object. Use HTML markup to color certain items * Pretty print a JavaScript object. Use HTML markup to color certain items
@@ -1302,7 +1330,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
bound: Class.Property(Object.getOwnPropertyDescriptor(Class.prototype, "bound")), bound: Class.Property(Object.getOwnPropertyDescriptor(Class.prototype, "bound")),
closure: Class.Property(Object.getOwnPropertyDescriptor(Class.prototype, "bound")), closure: Class.Property(Object.getOwnPropertyDescriptor(Class.prototype, "bound")),
dactylPropertyNames: ["exec", "match", "test", "toSource", "toString", "global", "ignoreCase", "lastIndex", "multiLine", "source", "sticky"], dactylPropertyNames: ["exec", "match", "test", "toSource", "toString", "global", "ignoreCase", "lastIndex", "multiLine", "source", "sticky"],
iterate: function iterate(str, idx) util.regexp.iterate(this, str, idx) iterate: function iterate(str, idx) {
return util.regexp.iterate(this, str, idx);
}
}); });
// Return a struct with properties for named parameters if we // Return a struct with properties for named parameters if we
@@ -1325,7 +1355,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {string} str * @param {string} str
* @returns {string} * @returns {string}
*/ */
escape: function regexp_escape(str) str.replace(/([\\{}()[\]^$.?*+|])/g, "\\$1"), escape: function regexp_escape(str) {
return str.replace(/([\\{}()[\]^$.?*+|])/g, "\\$1");
},
/** /**
* Given a RegExp, returns its source in the form showable to the user. * Given a RegExp, returns its source in the form showable to the user.
@@ -1333,9 +1365,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {RegExp} re The regexp showable source of which is to be returned. * @param {RegExp} re The regexp showable source of which is to be returned.
* @returns {string} * @returns {string}
*/ */
getSource: function regexp_getSource(re) re.source.replace(/\\(.)/g, getSource: function regexp_getSource(re) {
(m0, m1) => m1 === "/" ? m1 return re.source.replace(/\\(.)/g,
: m0), (m0, m1) => m1 === "/" ? m1
: m0);
},
/** /**
* Iterates over all matches of the given regexp in the given * Iterates over all matches of the given regexp in the given
@@ -1406,7 +1440,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
this.errorCount++; this.errorCount++;
let obj = update({}, error, { let obj = update({}, error, {
toString: function () String(error), toString: function () { return String(error); },
stack: Magic(util.stackLines(String(error.stack || Error().stack)).join("\n").replace(/^/mg, "\t")) stack: Magic(util.stackLines(String(error.stack || Error().stack)).join("\n").replace(/^/mg, "\t"))
}); });
@@ -1463,16 +1497,21 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {Window} window * @param {Window} window
* @returns {nsISelectionController} * @returns {nsISelectionController}
*/ */
selectionController: function selectionController(win) selectionController: function selectionController(win) {
win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation) return win.QueryInterface(Ci.nsIInterfaceRequestor)
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay) .getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsISelectionController), .QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController);
},
/** /**
* Escapes a string against shell meta-characters and argument * Escapes a string against shell meta-characters and argument
* separators. * separators.
*/ */
shellEscape: function shellEscape(str) '"' + String.replace(str, /[\\"$`]/g, "\\$&") + '"', shellEscape: function shellEscape(str) {
return '"' + String.replace(str, /[\\"$`]/g, "\\$&") + '"';
},
/** /**
* Suspend execution for at least *delay* milliseconds. Functions by * Suspend execution for at least *delay* milliseconds. Functions by
@@ -1634,8 +1673,8 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @returns {function} A new function which may not execute * @returns {function} A new function which may not execute
* synchronously. * synchronously.
*/ */
yieldable: deprecated("Task.spawn", function yieldable(func) yieldable: deprecated("Task.spawn", function yieldable(func) {
function magic() { return function magic() {
let gen = func.apply(this, arguments); let gen = func.apply(this, arguments);
(function next() { (function next() {
try { try {
@@ -1643,6 +1682,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
catch (e if e instanceof StopIteration) {}; catch (e if e instanceof StopIteration) {};
})(); })();
};
}), }),
/** /**
@@ -1663,10 +1703,13 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {Window} win The child window. * @param {Window} win The child window.
* @returns {Window} The top-level parent window. * @returns {Window} The top-level parent window.
*/ */
topWindow: function topWindow(win) topWindow: function topWindow(win) {
win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation) return win.QueryInterface(Ci.nsIInterfaceRequestor)
.QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem .getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow), .QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
},
/** /**
* Traps errors in the called function, possibly reporting them. * Traps errors in the called function, possibly reporting them.
@@ -1759,7 +1802,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
*/ */
weakReference: function weakReference(jsval) { weakReference: function weakReference(jsval) {
if (jsval == null) if (jsval == null)
return { get: function get() null }; return { get: function get() { return null; } };
return Cu.getWeakReference(jsval); return Cu.getWeakReference(jsval);
}, },
@@ -1797,7 +1840,9 @@ this.Math = update(Object.create(GlobalMath), {
* @param {number} max The maximum constraint. * @param {number} max The maximum constraint.
* @returns {number} * @returns {number}
*/ */
constrain: function constrain(value, min, max) Math.min(Math.max(min, value), max) constrain: function constrain(value, min, max) {
return Math.min(Math.max(min, value), max);
}
}); });
endModule(); endModule();