1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-22 21:27:58 +01:00
This commit is contained in:
Kris Maglione
2011-04-07 13:33:29 -04:00
48 changed files with 564 additions and 339 deletions

View File

@@ -203,9 +203,9 @@ var Abbreviations = Module("abbreviations", {
let list = <table> let list = <table>
<tr highlight="Title"> <tr highlight="Title">
<td/> <td/>
<td style="padding-right: 1em;">Mode</td> <td style="padding-right: 1em;"><!--L-->Mode</td>
<td style="padding-right: 1em;">Abbrev</td> <td style="padding-right: 1em;"><!--L-->Abbrev</td>
<td style="padding-right: 1em;">Replacement</td> <td style="padding-right: 1em;"><!--L-->Replacement</td>
</tr> </tr>
<col style="min-width: 6em; padding-right: 1em;"/> <col style="min-width: 6em; padding-right: 1em;"/>
{ {
@@ -224,7 +224,7 @@ var Abbreviations = Module("abbreviations", {
// TODO: Move this to an ItemList to show this automatically // TODO: Move this to an ItemList to show this automatically
if (list.*.length() === list.text().length() + 2) if (list.*.length() === list.text().length() + 2)
dactyl.echomsg(_("abbrev.none")); dactyl.echomsg(_("abbreviation.none"));
else else
commandline.commandOutput(list); commandline.commandOutput(list);
} }
@@ -301,7 +301,7 @@ var Abbreviations = Module("abbreviations", {
if (args.bang) if (args.bang)
args["-group"].clear(modes); args["-group"].clear(modes);
else if (!args["-group"].remove(modes, args[0])) else if (!args["-group"].remove(modes, args[0]))
return dactyl.echoerr(_("abbrev.noSuch")); return dactyl.echoerr(_("abbreviation.noSuch"));
}, { }, {
argCount: "?", argCount: "?",
bang: true, bang: true,

View File

@@ -404,7 +404,7 @@ var Bookmarks = Module("bookmarks", {
let frames = buffer.allFrames(); let frames = buffer.allFrames();
if (!args.bang) if (!args.bang)
return [ return [
[win.document.title, frames.length == 1 ? "Current Location" : "Frame: " + win.location.href] [win.document.title, frames.length == 1 ? /*L*/"Current Location" : /*L*/"Frame: " + win.location.href]
for ([, win] in Iterator(frames))]; for ([, win] in Iterator(frames))];
context.keys.text = "title"; context.keys.text = "title";
context.keys.description = "url"; context.keys.description = "url";
@@ -464,7 +464,7 @@ var Bookmarks = Module("bookmarks", {
context.title = ["Page URL"]; context.title = ["Page URL"];
let frames = buffer.allFrames(); let frames = buffer.allFrames();
context.completions = [ context.completions = [
[win.document.documentURI, frames.length == 1 ? "Current Location" : "Frame: " + win.document.title] [win.document.documentURI, frames.length == 1 ? /*L*/"Current Location" : /*L*/"Frame: " + win.document.title]
for ([, win] in Iterator(frames))]; for ([, win] in Iterator(frames))];
return; return;
} }
@@ -511,7 +511,7 @@ var Bookmarks = Module("bookmarks", {
function (resp) { function (resp) {
if (resp && resp.match(/^y(es)?$/i)) { if (resp && resp.match(/^y(es)?$/i)) {
bookmarks.remove(Object.keys(bookmarkcache.bookmarks)); bookmarks.remove(Object.keys(bookmarkcache.bookmarks));
dactyl.echomsg(_("bookmark.allGone")); dactyl.echomsg(_("bookmark.allDeleted"));
} }
}); });
else { else {
@@ -626,7 +626,7 @@ var Bookmarks = Module("bookmarks", {
if (item && item.url.indexOf("%s") > -1) if (item && item.url.indexOf("%s") > -1)
context.fork("keyword/" + keyword, keyword.length + space.length, null, function (context) { context.fork("keyword/" + keyword, keyword.length + space.length, null, function (context) {
context.format = history.format; context.format = history.format;
context.title = [keyword + " Quick Search"]; context.title = [/*L*/keyword + " Quick Search"];
// context.background = true; // context.background = true;
context.compare = CompletionContext.Sort.unsorted; context.compare = CompletionContext.Sort.unsorted;
context.generate = function () { context.generate = function () {
@@ -671,7 +671,7 @@ var Bookmarks = Module("bookmarks", {
return; return;
let ctxt = context.fork(name, 0); let ctxt = context.fork(name, 0);
ctxt.title = [engine.description + " Suggestions"]; ctxt.title = [/*L*/engine.description + " Suggestions"];
ctxt.keys = { text: util.identity, description: function () "" }; ctxt.keys = { text: util.identity, description: function () "" };
ctxt.compare = CompletionContext.Sort.unsorted; ctxt.compare = CompletionContext.Sort.unsorted;
ctxt.filterFunc = null; ctxt.filterFunc = null;

View File

@@ -75,7 +75,7 @@ var Buffer = Module("buffer", {
} }
if (!verbose && nFeed) if (!verbose && nFeed)
yield nFeed + " feed" + (nFeed > 1 ? "s" : ""); yield nFeed + /*L*/" feed" + (nFeed > 1 ? "s" : "");
}); });
this.addPageInfoSection("g", "General Info", function (verbose) { this.addPageInfoSection("g", "General Info", function (verbose) {
@@ -110,7 +110,7 @@ var Buffer = Module("buffer", {
if (!verbose) { if (!verbose) {
if (pageSize[0]) if (pageSize[0])
yield (pageSize[1] || pageSize[0]) + " bytes"; yield (pageSize[1] || pageSize[0]) + /*L*/" bytes";
yield lastMod; yield lastMod;
return; return;
} }
@@ -141,6 +141,41 @@ var Buffer = Module("buffer", {
.sort(function (a, b) util.compareIgnoreCase(a[0], b[0])); .sort(function (a, b) util.compareIgnoreCase(a[0], b[0]));
}); });
let identity = window.gIdentityHandler;
this.addPageInfoSection("s", "Security", function (verbose) {
if (!verbose || !identity)
return; // For now
// Modified from Firefox
function location(data) array.compact([
data.city, data.state, data.country
]).join(", ");
switch (statusline.security) {
case "secure":
case "extended":
var data = identity.getIdentityData();
yield ["Host", identity.getEffectiveHost()];
if (statusline.security === "extended")
yield ["Owner", data.subjectOrg]
else
yield ["Owner", _("pageinfo.s.ownerUnverified", data.subjectOrg)]
if (location(data).length)
yield ["Location", location(data)];
yield ["Verified by", data.caOrg];
if (identity._overrideService.hasMatchingOverride(identity._lastLocation.hostname,
(identity._lastLocation.port || 443),
data.cert, {}, {}))
yield ["User exception", /*L*/"true"]
break;
}
});
dactyl.commands["buffer.viewSource"] = function (event) { dactyl.commands["buffer.viewSource"] = function (event) {
let elem = event.originalTarget; let elem = event.originalTarget;
buffer.viewSource([elem.getAttribute("href"), Number(elem.getAttribute("line"))]); buffer.viewSource([elem.getAttribute("href"), Number(elem.getAttribute("line"))]);
@@ -544,9 +579,7 @@ var Buffer = Module("buffer", {
* @property {nsISelectionController} The current document's selection * @property {nsISelectionController} The current document's selection
* controller. * controller.
*/ */
get selectionController() config.browser.docShell get selectionController() util.selectionController(this.focusedFrame),
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController),
/** /**
* Opens the appropriate context menu for *elem*. * Opens the appropriate context menu for *elem*.
@@ -572,7 +605,7 @@ var Buffer = Module("buffer", {
try { try {
window.urlSecurityCheck(uri.spec, doc.nodePrincipal); window.urlSecurityCheck(uri.spec, doc.nodePrincipal);
io.CommandFileMode("Save link: ", { io.CommandFileMode(_("buffer.prompt.saveLink") + " ", {
onSubmit: function (path) { onSubmit: function (path) {
let file = io.File(path); let file = io.File(path);
if (file.exists() && file.isDirectory()) if (file.exists() && file.isDirectory())
@@ -796,7 +829,7 @@ var Buffer = Module("buffer", {
* @param {Node} elem The element to query. * @param {Node} elem The element to query.
*/ */
showElementInfo: function showElementInfo(elem) { showElementInfo: function showElementInfo(elem) {
dactyl.echo(<>Element:<br/>{util.objectToString(elem, true)}</>, commandline.FORCE_MULTILINE); dactyl.echo(<><!--L-->Element:<br/>{util.objectToString(elem, true)}</>, commandline.FORCE_MULTILINE);
}, },
/** /**
@@ -1038,7 +1071,7 @@ var Buffer = Module("buffer", {
scrollColumns: deprecated("buffer.scrollHorizontal", function scrollColumns(cols) buffer.scrollHorizontal("columns", cols)), scrollColumns: deprecated("buffer.scrollHorizontal", function scrollColumns(cols) buffer.scrollHorizontal("columns", cols)),
scrollPages: deprecated("buffer.scrollHorizontal", function scrollPages(pages) buffer.scrollVertical("pages", pages)), scrollPages: deprecated("buffer.scrollHorizontal", function scrollPages(pages) buffer.scrollVertical("pages", pages)),
scrollTo: deprecated("Buffer.scrollTo", function scrollTo(x, y) content.scrollTo(x, y)), scrollTo: deprecated("Buffer.scrollTo", function scrollTo(x, y) content.scrollTo(x, y)),
textZoom: deprecated("buffer.zoomValue and buffer.fullZoom", function textZoom() config.browser.markupDocumentViewer.textZoom * 100) textZoom: deprecated("buffer.zoomValue/buffer.fullZoom", function textZoom() config.browser.markupDocumentViewer.textZoom * 100)
}, { }, {
PageInfo: Struct("PageInfo", "name", "title", "action") PageInfo: Struct("PageInfo", "name", "title", "action")
.localize("title"), .localize("title"),
@@ -1090,13 +1123,13 @@ var Buffer = Module("buffer", {
var names = []; var names = [];
if (node.title) if (node.title)
names.push([node.title, "Page Name"]); names.push([node.title, /*L*/"Page Name"]);
if (node.alt) if (node.alt)
names.push([node.alt, "Alternate Text"]); names.push([node.alt, /*L*/"Alternate Text"]);
if (!isinstance(node, Document) && node.textContent) if (!isinstance(node, Document) && node.textContent)
names.push([node.textContent, "Link Text"]); names.push([node.textContent, /*L*/"Link Text"]);
names.push([decodeURIComponent(url.replace(/.*?([^\/]*)\/*$/, "$1")), "File Name"]); names.push([decodeURIComponent(url.replace(/.*?([^\/]*)\/*$/, "$1")), "File Name"]);
@@ -1249,7 +1282,7 @@ var Buffer = Module("buffer", {
// FIXME: arg handling is a bit of a mess, check for filename // FIXME: arg handling is a bit of a mess, check for filename
dactyl.assert(!arg || arg[0] == ">" && !util.OS.isWindows, dactyl.assert(!arg || arg[0] == ">" && !util.OS.isWindows,
_("error.trailing")); _("error.trailingCharacters"));
prefs.withContext(function () { prefs.withContext(function () {
if (arg) { if (arg) {
@@ -1428,7 +1461,7 @@ var Buffer = Module("buffer", {
level = Math.constrain(level, Buffer.ZOOM_MIN, Buffer.ZOOM_MAX); level = Math.constrain(level, Buffer.ZOOM_MIN, Buffer.ZOOM_MAX);
} }
else else
dactyl.assert(false, _("error.trailing")); dactyl.assert(false, _("error.trailingCharacters"));
buffer.setZoom(level, args.bang); buffer.setZoom(level, args.bang);
}, },
@@ -1499,7 +1532,7 @@ var Buffer = Module("buffer", {
i = i + 1; i = i + 1;
return { return {
text: [i + ": " + (tab.label || "(Untitled)"), i + ": " + url], text: [i + ": " + (tab.label || /*L*/"(Untitled)"), i + ": " + url],
tab: tab, tab: tab,
id: i - 1, id: i - 1,
url: url, url: url,
@@ -1850,7 +1883,7 @@ var Buffer = Module("buffer", {
options.add(["pageinfo", "pa"], options.add(["pageinfo", "pa"],
"Define which sections are shown by the :pageinfo command", "Define which sections are shown by the :pageinfo command",
"charlist", "gfm", "charlist", "gsfm",
{ get values() values(buffer.pageInfo).toObject() }); { get values() values(buffer.pageInfo).toObject() });
options.add(["scroll", "scr"], options.add(["scroll", "scr"],

View File

@@ -301,7 +301,7 @@ var CommandWidgets = Class("CommandWidgets", {
}); });
var CommandMode = Class("CommandMode", { var CommandMode = Class("CommandMode", {
init: function init() { init: function CM_init() {
this.keepCommand = userContext.hidden_option_command_afterimage; this.keepCommand = userContext.hidden_option_command_afterimage;
}, },
@@ -311,9 +311,9 @@ var CommandMode = Class("CommandMode", {
get prompt() this.widgets.prompt, get prompt() this.widgets.prompt,
set prompt(val) this.widgets.prompt = val, set prompt(val) this.widgets.prompt = val,
open: function (command) { open: function CM_open(command) {
dactyl.assert(isinstance(this.mode, modes.COMMAND_LINE), dactyl.assert(isinstance(this.mode, modes.COMMAND_LINE),
"Not opening command line in non-command-line mode."); /*L*/"Not opening command line in non-command-line mode.");
this.messageCount = commandline.messageCount; this.messageCount = commandline.messageCount;
modes.push(this.mode, this.extendedMode, this.closure); modes.push(this.mode, this.extendedMode, this.closure);
@@ -341,7 +341,7 @@ var CommandMode = Class("CommandMode", {
get widgets() commandline.widgets, get widgets() commandline.widgets,
enter: function (stack) { enter: function CM_enter(stack) {
commandline.commandSession = this; commandline.commandSession = this;
if (stack.pop && commandline.command) { if (stack.pop && commandline.command) {
this.onChange(commandline.command); this.onChange(commandline.command);
@@ -350,7 +350,7 @@ var CommandMode = Class("CommandMode", {
} }
}, },
leave: function (stack) { leave: function CM_leave(stack) {
if (!stack.push) { if (!stack.push) {
commandline.commandSession = null; commandline.commandSession = null;
this.input.dactylKeyPress = undefined; this.input.dactylKeyPress = undefined;
@@ -375,7 +375,7 @@ var CommandMode = Class("CommandMode", {
}, },
events: { events: {
input: function onInput(event) { input: function CM_onInput(event) {
if (this.completions) { if (this.completions) {
this.resetCompletions(); this.resetCompletions();
@@ -383,7 +383,7 @@ var CommandMode = Class("CommandMode", {
} }
this.onChange(commandline.command); this.onChange(commandline.command);
}, },
keyup: function onKeyUp(event) { keyup: function CM_onKeyUp(event) {
let key = events.toString(event); let key = events.toString(event);
if (/-?Tab>$/.test(key) && this.completions) if (/-?Tab>$/.test(key) && this.completions)
this.completions.tabTimer.flush(); this.completions.tabTimer.flush();
@@ -392,7 +392,7 @@ var CommandMode = Class("CommandMode", {
keepCommand: false, keepCommand: false,
onKeyPress: function onKeyPress(events) { onKeyPress: function CM_onKeyPress(events) {
if (this.completions) if (this.completions)
this.completions.previewClear(); this.completions.previewClear();
@@ -407,7 +407,7 @@ var CommandMode = Class("CommandMode", {
onSubmit: function (value) {}, onSubmit: function (value) {},
resetCompletions: function resetCompletions() { resetCompletions: function CM_resetCompletions() {
if (this.completions) { if (this.completions) {
this.completions.context.cancelAll(); this.completions.context.cancelAll();
this.completions.wildIndex = -1; this.completions.wildIndex = -1;
@@ -426,12 +426,12 @@ var CommandExMode = Class("CommandExMode", CommandMode, {
prompt: ["Normal", ":"], prompt: ["Normal", ":"],
complete: function complete(context) { complete: function CEM_complete(context) {
context.fork("ex", 0, completion, "ex"); context.fork("ex", 0, completion, "ex");
}, },
onSubmit: function onSubmit(command) { onSubmit: function CEM_onSubmit(command) {
contexts.withContext({ file: "[Command Line]", line: 1 }, contexts.withContext({ file: /*L*/"[Command Line]", line: 1 },
function _onSubmit() { function _onSubmit() {
io.withSavedValues(["readHeredoc"], function _onSubmit() { io.withSavedValues(["readHeredoc"], function _onSubmit() {
this.readHeredoc = commandline.readHeredoc; this.readHeredoc = commandline.readHeredoc;
@@ -449,7 +449,7 @@ var CommandPromptMode = Class("CommandPromptMode", CommandMode, {
init.supercall(this); init.supercall(this);
}, },
complete: function (context) { complete: function CPM_complete(context) {
if (this.completer) if (this.completer)
context.forkapply("prompt", 0, this, "completer", Array.slice(arguments, 1)); context.forkapply("prompt", 0, this, "completer", Array.slice(arguments, 1));
}, },
@@ -586,6 +586,9 @@ var CommandLine = Module("commandline", {
get completionList() { get completionList() {
let node = this.widgets.active.commandline; let node = this.widgets.active.commandline;
if (this.commandSession && this.commandSession.completionList)
node = document.getElementById(this.commandSession.completionList);
if (!node.completionList) { if (!node.completionList) {
let elem = document.getElementById("dactyl-completions-" + node.id); let elem = document.getElementById("dactyl-completions-" + node.id);
util.waitFor(bind(this.widgets._ready, null, elem)); util.waitFor(bind(this.widgets._ready, null, elem));
@@ -648,10 +651,9 @@ var CommandLine = Module("commandline", {
* @param {XML} xml The output as an E4X XML object. * @param {XML} xml The output as an E4X XML object.
*/ */
commandOutput: function commandOutput(xml) { commandOutput: function commandOutput(xml) {
XML.ignoreWhitespace = false; XML.ignoreWhitespace = XML.prettyPrinting = false;
XML.prettyPrinting = false;
if (this.command) if (this.command)
this.echo(<>:{this.command}{xml}</>, this.HIGHLIGHT_NORMAL, this.FORCE_MULTILINE); this.echo(<><div xmlns={XHTML}>:{this.command}</div>&#x0d;{xml}</>, this.HIGHLIGHT_NORMAL, this.FORCE_MULTILINE);
else else
this.echo(xml, this.HIGHLIGHT_NORMAL, this.FORCE_MULTILINE); this.echo(xml, this.HIGHLIGHT_NORMAL, this.FORCE_MULTILINE);
this.command = null; this.command = null;
@@ -1627,7 +1629,7 @@ var ItemList = Class("ItemList", {
_init: function _init() { _init: function _init() {
this._div = this._dom( this._div = this._dom(
<div class="ex-command-output" highlight="Normal" style="white-space: nowrap"> <div class="ex-command-output" highlight="Normal" style="white-space: nowrap">
<div highlight="Completions" key="noCompletions"><span highlight="Title">No Completions</span></div> <div highlight="Completions" key="noCompletions"><span highlight="Title"><!--L-->No Completions</span></div>
<div key="completions"/> <div key="completions"/>
<div highlight="Completions"> <div highlight="Completions">
{ {

View File

@@ -197,7 +197,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
argCount: "*", argCount: "*",
completer: function (context, args) { completer: function (context, args) {
context.keys.text = util.identity; context.keys.text = util.identity;
context.keys.description = function () seen[this.text] + " matching items"; context.keys.description = function () seen[this.text] + /*L*/" matching items";
let seen = {}; let seen = {};
context.completions = array(item.description.toLowerCase().split(/[()\s]+/) context.completions = array(item.description.toLowerCase().split(/[()\s]+/)
for (item in params.iterate(args))) for (item in params.iterate(args)))
@@ -605,6 +605,10 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* Initialize the help system. * Initialize the help system.
*/ */
initHelp: function (force) { initHelp: function (force) {
// Waits for the add-on to become available, if necessary.
config.addon;
config.version;
if (force || !this.helpInitialized) { if (force || !this.helpInitialized) {
if ("noscriptOverlay" in window) { if ("noscriptOverlay" in window) {
noscriptOverlay.safeAllow("chrome-data:", true, false); noscriptOverlay.safeAllow("chrome-data:", true, false);
@@ -685,7 +689,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
unescape(encodeURI( // UTF-8 handling hack. unescape(encodeURI( // UTF-8 handling hack.
<document xmlns={NS} <document xmlns={NS}
name="plugins" title={config.appName + " Plugins"}> name="plugins" title={config.appName + " Plugins"}>
<h1 tag="using-plugins">Using Plugins</h1> <h1 tag="using-plugins"><!--L-->Using Plugins</h1>
<toc start="2"/> <toc start="2"/>
{body} {body}
@@ -1010,7 +1014,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
<description>{ <description>{
obj.description ? br + <p>{template.linkifyHelp(obj.description.replace(/\.?$/, "."), true)}</p> : "" }{ obj.description ? br + <p>{template.linkifyHelp(obj.description.replace(/\.?$/, "."), true)}</p> : "" }{
extraHelp ? br + extraHelp : "" }{ extraHelp ? br + extraHelp : "" }{
!(extraHelp || obj.description) ? br + <p>Sorry, no help available.</p> : "" } !(extraHelp || obj.description) ? br + <p><!--L-->Sorry, no help available.</p> : "" }
</description> </description>
</item></>; </item></>;
@@ -1073,7 +1077,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* These are set and accessed with the "g:" prefix. * These are set and accessed with the "g:" prefix.
*/ */
_globalVariables: {}, _globalVariables: {},
globalVariables: deprecated("the options system", { globalVariables: deprecated(/*L*/"the options system", {
get: function globalVariables() this._globalVariables get: function globalVariables() this._globalVariables
}), }),
@@ -1160,7 +1164,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
onExecute: function onExecute(event) { onExecute: function onExecute(event) {
let cmd = event.originalTarget.getAttribute("dactyl-execute"); let cmd = event.originalTarget.getAttribute("dactyl-execute");
commands.execute(cmd, null, false, null, commands.execute(cmd, null, false, null,
{ file: "[Command Line]", line: 1 }); { file: /*L*/"[Command Line]", line: 1 });
}, },
/** /**
@@ -1962,7 +1966,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
commandline.commandOutput( commandline.commandOutput(
<table> <table>
<tr highlight="Title" align="left"> <tr highlight="Title" align="left">
<th colspan="3">Code execution summary</th> <th colspan="3"><!--L-->Code execution summary</th>
</tr> </tr>
<tr><td>&#xa0;&#xa0;Executed:</td><td align="right"><span class="times-executed">{count}</span></td><td>times</td></tr> <tr><td>&#xa0;&#xa0;Executed:</td><td align="right"><span class="times-executed">{count}</span></td><td>times</td></tr>
<tr><td>&#xa0;&#xa0;Average time:</td><td align="right"><span class="time-average">{each.toFixed(2)}</span></td><td>{eachUnits}</td></tr> <tr><td>&#xa0;&#xa0;Average time:</td><td align="right"><span class="time-average">{each.toFixed(2)}</span></td><td>{eachUnits}</td></tr>

View File

@@ -243,7 +243,7 @@ var Editor = Module("editor", {
let args = options.get("editor").format(args); let args = options.get("editor").format(args);
dactyl.assert(args.length >= 1, _("editor.noEditor")); dactyl.assert(args.length >= 1, _("option.notSet", "editor"));
io.run(args.shift(), args, blocking); io.run(args.shift(), args, blocking);
}, },
@@ -272,10 +272,10 @@ var Editor = Module("editor", {
column = 1 + pre.replace(/[^]*\n/, "").length; column = 1 + pre.replace(/[^]*\n/, "").length;
} }
else { else {
var editor = window.GetCurrentEditor ? GetCurrentEditor() var editor_ = window.GetCurrentEditor ? GetCurrentEditor()
: Editor.getEditor(document.commandDispatcher.focusedWindow); : Editor.getEditor(document.commandDispatcher.focusedWindow);
dactyl.assert(editor); dactyl.assert(editor_);
text = Array.map(editor.rootElement.childNodes, function (e) util.domToString(e, true)).join(""); text = Array.map(editor_.rootElement.childNodes, function (e) util.domToString(e, true)).join("");
} }
let origGroup = textBox && textBox.getAttributeNS(NS, "highlight") || ""; let origGroup = textBox && textBox.getAttributeNS(NS, "highlight") || "";
@@ -312,16 +312,16 @@ var Editor = Module("editor", {
if (textBox) if (textBox)
textBox.value = val; textBox.value = val;
else { else {
while (editor.rootElement.firstChild) while (editor_.rootElement.firstChild)
editor.rootElement.removeChild(editor.rootElement.firstChild); editor_.rootElement.removeChild(editor_.rootElement.firstChild);
editor.rootElement.innerHTML = val; editor_.rootElement.innerHTML = val;
} }
} }
try { try {
var tmpfile = io.createTempFile(); var tmpfile = io.createTempFile();
if (!tmpfile) if (!tmpfile)
throw Error("Couldn't create temporary file"); throw Error(/*L*/"Couldn't create temporary file");
if (textBox) { if (textBox) {
highlight.highlightNode(textBox, origGroup + " EditorEditing"); highlight.highlightNode(textBox, origGroup + " EditorEditing");
@@ -329,7 +329,7 @@ var Editor = Module("editor", {
} }
if (!tmpfile.write(text)) if (!tmpfile.write(text))
throw Error("Input contains characters not valid in the current " + throw Error(/*L*/"Input contains characters not valid in the current " +
"file encoding"); "file encoding");
var lastUpdate = Date.now(); var lastUpdate = Date.now();

View File

@@ -322,7 +322,7 @@ var EventHive = Class("EventHive", Contexts.Hive, {
var [self, events] = [null, array.toObject([[event, callback]])]; var [self, events] = [null, array.toObject([[event, callback]])];
else { else {
[self, events] = [event, event[callback || "events"]]; [self, events] = [event, event[callback || "events"]];
[,, capture, allowUntrusted] = arguments; [, , capture, allowUntrusted] = arguments;
} }
if (set.has(events, "input") && !set.has(events, "dactyl-input")) if (set.has(events, "input") && !set.has(events, "dactyl-input"))
@@ -669,12 +669,15 @@ var Events = Module("events", {
let doc = document.commandDispatcher.focusedWindow.document; let doc = document.commandDispatcher.focusedWindow.document;
let event = events.create(doc, type, evt); let event = events.create(doc, type, evt);
let target = dactyl.focusedElement
|| ["complete", "interactive"].indexOf(doc.readyState) >= 0 && doc.documentElement
|| doc.defaultView;
if (target instanceof Element && !Events.isInputElement(target))
target = target.ownerDocument.documentElement;
if (!evt_obj.dactylString && !mode) if (!evt_obj.dactylString && !mode)
events.dispatch(dactyl.focusedElement events.dispatch(target, event, evt);
|| ["complete", "interactive"].indexOf(doc.readyState) >= 0 && doc.documentElement
|| doc.defaultView,
event, evt);
else if (type === "keypress") else if (type === "keypress")
events.events.keypress.call(events, event); events.events.keypress.call(events, event);
} }
@@ -1259,7 +1262,7 @@ var Events = Module("events", {
else else
ignore = true; ignore = true;
if (ignore && !Events.isEscape(key)) if (ignore)
modes.pop(); modes.pop();
} }
else if (!event.isMacro && !event.noremap && events.shouldPass(event)) else if (!event.isMacro && !event.noremap && events.shouldPass(event))
@@ -1487,14 +1490,16 @@ var Events = Module("events", {
key === "<Esc>" || key === "<C-[>", key === "<Esc>" || key === "<C-[>",
isHidden: function isHidden(elem, aggressive) { isHidden: function isHidden(elem, aggressive) {
for (let e = elem; e instanceof Element; e = e.parentNode) { if (util.computedStyle(elem).visibility !== "visible")
if (util.computedStyle(e).visibility !== "visible" || return true;
aggressive && !/set$/.test(e.localName)
&& e.boxObject && e.boxObject.height === 0) if (aggressive)
return true; for (let e = elem; e instanceof Element; e = e.parentNode) {
else if (e.namespaceURI == XUL && e.localName === "panel") if (!/set$/.test(e.localName) && e.boxObject && e.boxObject.height === 0)
break; return true;
} else if (e.namespaceURI == XUL && e.localName === "panel")
break;
}
return false; return false;
}, },
@@ -1530,7 +1535,7 @@ var Events = Module("events", {
literal: 0 literal: 0
}); });
commands.add(["macros"], commands.add(["mac[ros]"],
"List all macros", "List all macros",
function (args) { completion.listCompleter("macro", args[0]); }, { function (args) { completion.listCompleter("macro", args[0]); }, {
argCount: "?", argCount: "?",
@@ -1660,7 +1665,7 @@ var Events = Module("events", {
filter.keys = events.fromString(vals[0]).map(events.closure.toString); filter.keys = events.fromString(vals[0]).map(events.closure.toString);
filter.commandKeys = vals.slice(1).map(events.closure.canonicalKeys); filter.commandKeys = vals.slice(1).map(events.closure.canonicalKeys);
filter.inputKeys = filter.commandKeys.filter(/^<[ACM]-/); filter.inputKeys = filter.commandKeys.filter(bind("test", /^<[ACM]-/));
}); });
this.flush(); this.flush();
return values; return values;

View File

@@ -185,7 +185,7 @@
<xsl:if test="//dactyl:toc[1 and self::*]"> <xsl:if test="//dactyl:toc[1 and self::*]">
<div dactyl:highlight="HelpTOC"> <div dactyl:highlight="HelpTOC">
<h2>Contents</h2> <h2><!--L-->Contents</h2>
<xsl:if test="@start"> <xsl:if test="@start">
<xsl:call-template name="toc"> <xsl:call-template name="toc">
<xsl:with-param name="level" select="number(@start)"/> <xsl:with-param name="level" select="number(@start)"/>
@@ -240,7 +240,7 @@
</xsl:when> </xsl:when>
<xsl:when test="contains($type, 'list') or contains($type, 'map')"> <xsl:when test="contains($type, 'list') or contains($type, 'map')">
<span dactyl:highlight="HelpString" delim=""><xsl:apply-templates mode="help-1"/></span> <span dactyl:highlight="HelpString" delim=""><xsl:apply-templates mode="help-1"/></span>
<xsl:if test=". = ''">(empty)</xsl:if> <xsl:if test=". = ''"><!--L-->(empty)</xsl:if>
</xsl:when> </xsl:when>
<xsl:otherwise> <xsl:otherwise>
<span> <span>
@@ -430,7 +430,7 @@
<xsl:template match="dactyl:deprecated" mode="help-2"> <xsl:template match="dactyl:deprecated" mode="help-2">
<p style="clear: both;"> <p style="clear: both;">
<xsl:apply-templates select="@*" mode="help-1"/> <xsl:apply-templates select="@*" mode="help-1"/>
<span dactyl:highlight="HelpWarning">Deprecated:</span> <span dactyl:highlight="HelpWarning"><!--L-->Deprecated:</span>
<xsl:text> </xsl:text> <xsl:text> </xsl:text>
<xsl:apply-templates select="node()" mode="help-1"/> <xsl:apply-templates select="node()" mode="help-1"/>
</p> </p>
@@ -439,7 +439,7 @@
<p style="clear: both;"> <p style="clear: both;">
<xsl:apply-templates select="@*" mode="help-1"/> <xsl:apply-templates select="@*" mode="help-1"/>
<div style="clear: both;"/> <div style="clear: both;"/>
<span dactyl:highlight="HelpNote">Note:</span> <span dactyl:highlight="HelpNote"><!--L-->Note:</span>
<xsl:text> </xsl:text> <xsl:text> </xsl:text>
<xsl:apply-templates select="node()" mode="help-1"/> <xsl:apply-templates select="node()" mode="help-1"/>
</p> </p>
@@ -448,7 +448,7 @@
<p style="clear: both;"> <p style="clear: both;">
<xsl:apply-templates select="@*" mode="help-1"/> <xsl:apply-templates select="@*" mode="help-1"/>
<div style="clear: both;"/> <div style="clear: both;"/>
<span dactyl:highlight="HelpWarning">Warning:</span> <span dactyl:highlight="HelpWarning"><!--L-->Warning:</span>
<xsl:text> </xsl:text> <xsl:text> </xsl:text>
<xsl:apply-templates select="node()" mode="help-1"/> <xsl:apply-templates select="node()" mode="help-1"/>
</p> </p>

View File

@@ -472,7 +472,7 @@ var HintSession = Class("HintSession", CommandMode, {
else if (n) else if (n)
hints.setClass(elem, n % 2); hints.setClass(elem, n % 2);
else else
hints.setClass(elem, this.validHints[Math.max(0, this.hintNumber-1)].elem === elem); hints.setClass(elem, this.validHints[Math.max(0, this.hintNumber - 1)].elem === elem);
if (n--) if (n--)
this.timeout(next, 50); this.timeout(next, 50);
@@ -1189,7 +1189,7 @@ var Hints = Module("hints", {
"XPath or CSS selector strings of hintable elements for extended hint modes", "XPath or CSS selector strings of hintable elements for extended hint modes",
"regexpmap", { "regexpmap", {
"[iI]": "img", "[iI]": "img",
"[asOTivVWy]": ["a[href]", "area[href]", "img[src]", "iframe[src]"], "[asOTvVWy]": ["a[href]", "area[href]", "img[src]", "iframe[src]"],
"[f]": "body", "[f]": "body",
"[F]": ["body", "code", "div", "html", "p", "pre", "span"], "[F]": ["body", "code", "div", "html", "p", "pre", "span"],
"[S]": ["input:not([type=hidden])", "textarea", "button", "select"] "[S]": ["input:not([type=hidden])", "textarea", "button", "select"]

View File

@@ -219,7 +219,7 @@ var History = Module("history", {
description: "The sort order of the results", description: "The sort order of the results",
completer: function (context, args) { completer: function (context, args) {
context.compare = CompletionContext.Sort.unsorted; context.compare = CompletionContext.Sort.unsorted;
return array.flatten([ return /*L*/array.flatten([
"annotation", "annotation",
"date", "date",
"date added", "date added",

View File

@@ -168,7 +168,7 @@ var MapHive = Class("MapHive", Contexts.Hive, {
modes = Array.concat(modes); modes = Array.concat(modes);
if (!modes.every(util.identity)) if (!modes.every(util.identity))
throw TypeError("Invalid modes: " + modes); throw TypeError(/*L*/"Invalid modes: " + modes);
let map = Map(modes, keys, description, action, extra); let map = Map(modes, keys, description, action, extra);
map.definedAt = contexts.getCaller(Components.stack.caller); map.definedAt = contexts.getCaller(Components.stack.caller);
@@ -431,9 +431,9 @@ var Mappings = Module("mappings", {
let list = <table> let list = <table>
<tr highlight="Title"> <tr highlight="Title">
<td/> <td/>
<td style="padding-right: 1em;">Mode</td> <td style="padding-right: 1em;"><!--L-->Mode</td>
<td style="padding-right: 1em;">Command</td> <td style="padding-right: 1em;"><!--L-->Command</td>
<td style="padding-right: 1em;">Action</td> <td style="padding-right: 1em;"><!--L-->Action</td>
</tr> </tr>
<col style="min-width: 6em; padding-right: 1em;"/> <col style="min-width: 6em; padding-right: 1em;"/>
{ {
@@ -531,7 +531,7 @@ var Mappings = Module("mappings", {
{ {
names: ["-description", "-desc", "-d"], names: ["-description", "-desc", "-d"],
description: "A description of this mapping", description: "A description of this mapping",
default: "User-defined mapping", default: /*L*/"User-defined mapping",
type: CommandOption.STRING type: CommandOption.STRING
}, },
{ {

View File

@@ -146,7 +146,7 @@ var Marks = Module("marks", {
let mark = (this._localMarks.get(this.localURI) || {})[char]; let mark = (this._localMarks.get(this.localURI) || {})[char];
dactyl.assert(mark, _("mark.unset", char)); dactyl.assert(mark, _("mark.unset", char));
dactyl.log(_("marks.jumpingToLocal", Marks.markToString(char, mark)), 5); dactyl.log(_("mark.jumpingToLocal", Marks.markToString(char, mark)), 5);
buffer.scrollToPercent(mark.position.x * 100, mark.position.y * 100); buffer.scrollToPercent(mark.position.x * 100, mark.position.y * 100);
} }
else else
@@ -249,7 +249,7 @@ var Marks = Module("marks", {
"Mark current location within the web page", "Mark current location within the web page",
function (args) { function (args) {
let mark = args[0] || ""; let mark = args[0] || "";
dactyl.assert(mark.length <= 1, _("error.trailing")); dactyl.assert(mark.length <= 1, _("error.trailingCharacters"));
dactyl.assert(/[a-zA-Z]/.test(mark), _("mark.invalid")); dactyl.assert(/[a-zA-Z]/.test(mark), _("mark.invalid"));
marks.add(mark); marks.add(mark);

View File

@@ -207,6 +207,51 @@ var Modes = Module("modes", {
} }
}); });
function makeTree() {
let list = modes.all.filter(function (m) m.name !== m.description);
let tree = {};
for (let mode in values(list))
tree[mode.name] = {};
for (let mode in values(list))
for (let base in values(mode.bases))
tree[base.name][mode.name] = tree[mode.name];
let roots = iter([m.name, tree[m.name]] for (m in values(list)) if (!m.bases.length)).toObject();
default xml namespace = NS;
function rec(obj) {
XML.ignoreWhitespace = XML.prettyPrinting = false;
let res = <ul dactyl:highlight="Dense" xmlns:dactyl={NS}/>;
Object.keys(obj).sort().forEach(function (mode) {
res.* += <li><em>{mode}</em>: {modes.getMode(mode).description}{
rec(obj[mode])
}</li>;
});
if (res.*.length())
return res;
return <></>;
}
return rec(roots).toXMLString();
}
util.timeout(function () {
// Waits for the add-on to become available, if necessary.
config.addon;
config.version;
services["dactyl:"].pages["modes.dtd"] = services["dactyl:"].pages["modes.dtd"]();
});
services["dactyl:"].pages["modes.dtd"] = function () [null,
util.makeDTD(iter({ "modes.tree": makeTree() },
config.dtd))];
}, },
cleanup: function cleanup() { cleanup: function cleanup() {
modes.reset(); modes.reset();
@@ -278,9 +323,13 @@ var Modes = Module("modes", {
// show the current mode string in the command line // show the current mode string in the command line
show: function show() { show: function show() {
if (!loaded.modes)
return;
let msg = null; let msg = null;
if (options.get("showmode").getKey(this.main.name, true)) if (options.get("showmode").getKey([this.main].concat(this.main.allBases), false))
msg = this._getModeMessage(); msg = this._getModeMessage();
if (msg || loaded.commandline) if (msg || loaded.commandline)
commandline.widgets.mode = msg || null; commandline.widgets.mode = msg || null;
}, },
@@ -397,19 +446,22 @@ var Modes = Module("modes", {
while (this._modeStack.length > 1 && this.main != mode) { while (this._modeStack.length > 1 && this.main != mode) {
let a = this._modeStack.pop(); let a = this._modeStack.pop();
this.set(this.topOfStack.main, this.topOfStack.extended, this.topOfStack.params, this.set(this.topOfStack.main, this.topOfStack.extended, this.topOfStack.params,
update({ pop: a }, args || {})); update({ pop: a },
args || {}));
if (mode == null) if (mode == null)
return; return;
} }
}, },
replace: function replace(mode, oldMode) { replace: function replace(mode, oldMode, args) {
while (oldMode && this._modeStack.length > 1 && this.main != oldMode) while (oldMode && this._modeStack.length > 1 && this.main != oldMode)
this.pop(); this.pop();
if (this._modeStack.length > 1) if (this._modeStack.length > 1)
this.set(mode, null, null, { push: this.topOfStack, pop: this._modeStack.pop() }); this.set(mode, null, null,
update({ push: this.topOfStack, pop: this._modeStack.pop() },
args || {}));
this.push(mode); this.push(mode);
}, },
@@ -452,7 +504,7 @@ var Modes = Module("modes", {
this === obj || this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj, this === obj || this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj,
allBases: Class.memoize(function () { allBases: Class.memoize(function () {
let seen = {}, res = [], queue = this.bases; let seen = {}, res = [], queue = this.bases.slice();
for (let mode in array.iterValues(queue)) for (let mode in array.iterValues(queue))
if (!set.add(seen, mode)) { if (!set.add(seen, mode)) {
res.push(mode); res.push(mode);
@@ -552,45 +604,47 @@ var Modes = Module("modes", {
function () { events.feedkeys("<Esc>"); }); function () { events.feedkeys("<Esc>"); });
}, },
options: function initOptions() { options: function initOptions() {
options.add(["passunknown"], let opts = {
completer: function completer(context, extra) {
if (extra.value && context.filter[0] == "!")
context.advance(1);
return completer.superapply(this, arguments);
},
getKey: function getKey(val, default_) {
if (isArray(val))
return (array.nth(this.value, function (v) val.some(function (m) m.name === v.mode), 0)
|| { result: default_ }).result;
return set.has(this.valueMap, val) ? this.valueMap[val] : default_;
},
setter: function (vals) {
modes.all.forEach(function (m) { delete m.passUnknown });
vals = vals.map(function (v) update(new String(v.toLowerCase()), {
mode: v.replace(/^!/, "").toUpperCase(),
result: v[0] !== "!"
}));
this.valueMap = values(vals).map(function (v) [v.mode, v.result]).toObject();
return vals;
},
validator: function validator(vals) vals.map(function (v) v.replace(/^!/, "")).every(set.has(this.values)),
get values() array.toObject([[m.name.toLowerCase(), m.description] for (m in values(modes._modes)) if (!m.hidden)])
};
options.add(["passunknown", "pu"],
"Pass through unknown keys in these modes", "Pass through unknown keys in these modes",
"stringlist", "!text_edit,!input,base", "stringlist", "!text_edit,!input,base",
{ opts);
completer: function completer(context, extra) {
if (extra.value && context.filter[0] == "!")
context.advance(1);
return completer.superapply(this, arguments);
},
getKey: function getKey(val, default_) {
if (isArray(val))
return (array.nth(this.value, function (v) val.some(function (m) m.name === v.mode), 0)
|| { result: default_ }).result;
return set.has(this.valueMap, val) ? this.valueMap[val] : default_;
},
setter: function (vals) {
modes.all.forEach(function (m) { delete m.passUnknown });
vals = vals.map(function (v) update(new String(v.toLowerCase()), {
mode: v.replace(/^!/, "").toUpperCase(),
result: v[0] !== "!"
}));
this.valueMap = values(vals).map(function (v) [v.mode, v.result]).toObject();
return vals;
},
validator: function validator(vals) vals.map(function (v) v.replace(/^!/, "")).every(set.has(this.values)),
get values() array.toObject([[m.name.toLowerCase(), m.description] for (m in values(modes._modes)) if (!m.hidden)])
});
options.add(["showmode", "smd"], options.add(["showmode", "smd"],
"Show the current mode in the command line when it matches this expression", "Show the current mode in the command line when it matches this expression",
"regexplist", "!^normal$", "stringlist", "caret,output_multiline,!normal,base",
{ regexpFlags: "i" }); opts);
}, },
prefs: function initPrefs() { prefs: function initPrefs() {
prefs.watch("accessibility.browsewithcaret", function () modes.onCaretChange.apply(modes, arguments)); prefs.watch("accessibility.browsewithcaret", function () modes.onCaretChange.apply(modes, arguments));

View File

@@ -53,16 +53,16 @@ var MOW = Module("mow", {
<popupset> <popupset>
<menupopup id="dactyl-contextmenu" highlight="Events" events="contextEvents"> <menupopup id="dactyl-contextmenu" highlight="Events" events="contextEvents">
<menuitem id="dactyl-context-copylink" <menuitem id="dactyl-context-copylink"
label="Copy Link Location" dactyl:group="link" label={_("mow.contextMenu.copyLink")} dactyl:group="link"
oncommand="goDoCommand('cmd_copyLink');"/> oncommand="goDoCommand('cmd_copyLink');"/>
<menuitem id="dactyl-context-copypath" <menuitem id="dactyl-context-copypath"
label="Copy File Path" dactyl:group="link path" label={_("mow.contextMenu.copyPath")} dactyl:group="link path"
oncommand="dactyl.clipboardWrite(document.popupNode.getAttribute('path'));"/> oncommand="dactyl.clipboardWrite(document.popupNode.getAttribute('path'));"/>
<menuitem id="dactyl-context-copy" <menuitem id="dactyl-context-copy"
label="Copy" dactyl:group="selection" label={_("mow.contextMenu.copy")} dactyl:group="selection"
command="cmd_copy"/> command="cmd_copy"/>
<menuitem id="dactyl-context-selectall" <menuitem id="dactyl-context-selectall"
label="Select All" label={_("mow.contextMenu.selectAll")}
command="cmd_selectAll"/> command="cmd_selectAll"/>
</menupopup> </menupopup>
</popupset> </popupset>
@@ -278,11 +278,11 @@ var MOW = Module("mow", {
let elem = this.widget.contentDocument.documentElement; let elem = this.widget.contentDocument.documentElement;
if (showHelp) if (showHelp)
this.widgets.message = ["MoreMsg", _("mow.moreHelp")]; this.widgets.message = ["MoreMsg", _("mow.moreHelp")];
else if (force || (options["more"] && Buffer.isScrollable(elem, 1))) else if (force || (options["more"] && Buffer.isScrollable(elem, 1)))
this.widgets.message = ["MoreMsg", _("mow.more")]; this.widgets.message = ["MoreMsg", _("mow.more")];
else else
this.widgets.message = ["Question", _("mow.continue")]; this.widgets.message = ["Question", _("mow.continue")];
}, },
visible: Modes.boundProperty({ visible: Modes.boundProperty({

View File

@@ -157,7 +157,7 @@ var QuickMarks = Module("quickmarks", {
context.fork("current", 0, this, function (context) { context.fork("current", 0, this, function (context) {
context.title = ["Extra Completions"]; context.title = ["Extra Completions"];
context.completions = [ context.completions = [
[quickmarks.get(args[0]), "Current Value"] [quickmarks.get(args[0]), _("option.currentValue")]
].filter(function ([k, v]) k); ].filter(function ([k, v]) k);
}); });
context.fork("url", 0, completion, "url"); context.fork("url", 0, completion, "url");

View File

@@ -308,7 +308,7 @@ var StatusLine = Module("statusline", {
else if (typeof progress == "number") { else if (typeof progress == "number") {
let progressStr = ""; let progressStr = "";
if (this._progress <= 0) if (this._progress <= 0)
progressStr = "[ Loading... ]"; progressStr = /*L*/"[ Loading... ]";
else if (this._progress < 1) { else if (this._progress < 1) {
let progress = Math.round(this._progress * 20); let progress = Math.round(this._progress * 20);
progressStr = "[" progressStr = "["

View File

@@ -266,7 +266,10 @@ var Tabs = Module("tabs", {
let tabs = this.visibleTabs; let tabs = this.visibleTabs;
let position = this.index(null, true); let position = this.index(null, true);
if (spec == null || spec === "") if (spec == null)
return -1;
if (spec === "")
return position; return position;
if (typeof spec === "number") if (typeof spec === "number")
@@ -379,7 +382,7 @@ var Tabs = Module("tabs", {
reloadAll: function (bypassCache) { reloadAll: function (bypassCache) {
this.visibleTabs.forEach(function (tab) { this.visibleTabs.forEach(function (tab) {
try { try {
this.reload(config.tabbrowser.mTabs[i], bypassCache); tabs.reload(tab, bypassCache);
} }
catch (e) { catch (e) {
dactyl.reportError(e, true); dactyl.reportError(e, true);
@@ -678,7 +681,7 @@ var Tabs = Module("tabs", {
if (/^\d+$/.test(arg)) if (/^\d+$/.test(arg))
tabs.select("-" + arg, true); tabs.select("-" + arg, true);
else else
dactyl.echoerr(_("error.trailing")); dactyl.echoerr(_("error.trailingCharacters"));
} }
else if (count > 0) else if (count > 0)
tabs.select("-" + count, true); tabs.select("-" + count, true);
@@ -701,7 +704,7 @@ var Tabs = Module("tabs", {
// count is ignored if an arg is specified, as per Vim // count is ignored if an arg is specified, as per Vim
if (arg) { if (arg) {
dactyl.assert(/^\d+$/.test(arg), _("error.trailing")); dactyl.assert(/^\d+$/.test(arg), _("error.trailingCharacters"));
index = arg - 1; index = arg - 1;
} }
else else
@@ -770,7 +773,7 @@ var Tabs = Module("tabs", {
// FIXME: tabmove! N should probably produce an error // FIXME: tabmove! N should probably produce an error
dactyl.assert(!arg || /^([+-]?\d+)$/.test(arg), dactyl.assert(!arg || /^([+-]?\d+)$/.test(arg),
_("error.trailing")); _("error.trailingCharacters"));
// if not specified, move to after the last tab // if not specified, move to after the last tab
tabs.move(config.tabbrowser.mCurrentTab, arg || "$", args.bang); tabs.move(config.tabbrowser.mCurrentTab, arg || "$", args.bang);
@@ -825,7 +828,7 @@ var Tabs = Module("tabs", {
"Attach the current tab to another window", "Attach the current tab to another window",
function (args) { function (args) {
dactyl.assert(args.length <= 2 && !args.some(function (i) !/^\d+$/.test(i)), dactyl.assert(args.length <= 2 && !args.some(function (i) !/^\d+$/.test(i)),
_("error.trailing")); _("error.trailingCharacters"));
let [winIndex, tabIndex] = args.map(parseInt); let [winIndex, tabIndex] = args.map(parseInt);
let win = dactyl.windows[winIndex - 1]; let win = dactyl.windows[winIndex - 1];

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "dactyl://content/dtd"> <!DOCTYPE document SYSTEM "dactyl://content/modes.dtd">
<document <document
name="map" name="map"
@@ -75,6 +75,15 @@
saved via the <ex>:mk&dactyl.name;rc</ex> command. saved via the <ex>:mk&dactyl.name;rc</ex> command.
</warning> </warning>
<p tag="modes">
The following tree represents all of the modes understood by
dactyl. Mappings for a mode also apply to its children and
descendants. So a mapping in the BASE mode, for instance, is
also active in NORMAL and EX mode.
</p>
&modes.tree;
<h3 tag=":map-commands">Map commands</h3> <h3 tag=":map-commands">Map commands</h3>
<item> <item>

View File

@@ -1,13 +1,12 @@
# TODO: normalize this debacle of Vim legacy messages # TODO: normalize this debacle of Vim legacy messages
# : are we losing the error code prefixes? --djk
abbrev.noSuch = No such abbreviation abbreviation.noSuch = No such abbreviation
abbrev.none = No abbreviations found abbreviation.none = No abbreviations found
addon.check-1 = Checking updates for addons: %S addon.check-1 = Checking updates for addons: %S
addon.cantInstallDir-1 = Cannot install a directory: %S addon.cantInstallDir-1 = Cannot install a directory: %S
addon.unavailable = Don't have add-on yet addon.unavailable = Don't have add-on yet
addon.uknownCommand = Unknown command addon.unknownCommand = Unknown command
addon.commandNotAllowed = Command not allowed addon.commandNotAllowed = Command not allowed
addon.installingUpdates-1 = Installing updates for addons: %S addon.installingUpdates-1 = Installing updates for addons: %S
addon.noUpdates = No addon updates found addon.noUpdates = No addon updates found
@@ -15,9 +14,9 @@ addon.error-3 = Add-on %S %S: %S
addon.action.On = On  addon.action.On = On 
addon.action.Off = Off addon.action.Off = Off
addon.action.Del = Del addon.action.Delete = Del
addon.action.Upd = Upd addon.action.Update = Upd
addon.action.Opt = Opt addon.action.Options = Opt
AddonManager.ERROR_NETWORK_FAILURE = A network error occurred AddonManager.ERROR_NETWORK_FAILURE = A network error occurred
AddonManager.ERROR_INCORRECT_HASH = The downloaded file did not match the expected hash AddonManager.ERROR_INCORRECT_HASH = The downloaded file did not match the expected hash
@@ -35,12 +34,13 @@ bookmark.noMatchingTags-1 = No bookmarks matching tags %S
bookmark.noMatchingString-1 = No bookmarks matching string %S bookmark.noMatchingString-1 = No bookmarks matching string %S
bookmark.none = No bookmarks set bookmark.none = No bookmarks set
bookmark.cantAdd-1 = Could not add bookmark %S bookmark.cantAdd-1 = Could not add bookmark %S
bookmark.allGone = All bookmarks deleted bookmark.allDeleted = All bookmarks deleted
bookmark.removed-1 = Removed bookmark: %S bookmark.removed-1 = Removed bookmark: %S
bookmark.added-1 = Added bookmark: %S bookmark.added-1 = Added bookmark: %S
bookmark.deleted-1 = %S bookmark(s) deleted bookmark.deleted-1 = %S bookmark(s) deleted
bookmark.prompt.deleteAll = This will delete all bookmarks. Would you like to continue? (yes/[no]): bookmark.prompt.deleteAll = This will delete all bookmarks. Would you like to continue? (yes/[no]):
# TODO: add plurals support
buffer.fewerTab-1 = %S fewer tab buffer.fewerTab-1 = %S fewer tab
buffer.fewerTabs-1 = %S fewer tabs buffer.fewerTabs-1 = %S fewer tabs
buffer.cantDetatchLast = Can't detach the last tab buffer.cantDetatchLast = Can't detach the last tab
@@ -50,12 +50,15 @@ buffer.noClosed = No matching closed tab
buffer.noAlternate = No alternate page buffer.noAlternate = No alternate page
buffer.backgroundLoaded = Background tab loaded: %S buffer.backgroundLoaded = Background tab loaded: %S
# TODO: categorise these
buffer.noTitle = [No Title] buffer.noTitle = [No Title]
buffer.noName = [No Name] buffer.noName = [No Name]
buffer.help = [Help] buffer.help = [Help]
buffer.bookmarked = bookmarked buffer.bookmarked = bookmarked
buffer.prompt.uploadFile = Upload file: buffer.prompt.uploadFile = Upload file:
buffer.prompt.saveLink = Save link:
context.scriptGroup-1 = Script group for %S context.scriptGroup-1 = Script group for %S
@@ -84,18 +87,19 @@ command.noBang = E477: No ! allowed
command.colorscheme.notFound-1 = E185: Cannot find color scheme %S command.colorscheme.notFound-1 = E185: Cannot find color scheme %S
command.conditional.illegal = Invalid use of conditional command.conditional.illegal = Invalid use of conditional
command.finish.illegal = E168: :finish used outside of a sourced file command.finish.illegal = E168: :finish used outside of a sourced file
command.let.noSuch-1 = E108: No such variable: %S
command.let.unexpectedChar = E18: Unexpected characters in :let
command.let.illegalVar-1 = E461: Illegal variable name: %S command.let.illegalVar-1 = E461: Illegal variable name: %S
command.let.undefinedVar-1 = E121: Undefined variable: %S
command.let.invalidExpression-1 = E15: Invalid expression: %S command.let.invalidExpression-1 = E15: Invalid expression: %S
command.yank.yankedLine-1 = Yanked %S line command.let.noSuch-1 = E108: No such variable: %S
command.yank.yankedLines-1 = Yanked %S lines command.let.undefinedVar-1 = E121: Undefined variable: %S
command.let.unexpectedChar = E18: Unexpected characters in :let
command.run.noPrevious = E34: No previous command command.run.noPrevious = E34: No previous command
command.sanitize.privateMode = Cannot sanitize items in private mode command.sanitize.privateMode = Cannot sanitize items in private mode
command.set.numberRequired-2 = E521: Number required after =: %S=%S command.scriptnames.none = No sourced scripts found
command.set.errorParsing-1 = Error parsing :set command: %S command.set.errorParsing-1 = Error parsing :set command: %S
command.set.numberRequired-2 = E521: Number required after =: %S=%S
command.set.unknownOption-1 = E518: Unknown option: %S command.set.unknownOption-1 = E518: Unknown option: %S
command.yank.yankedLine-1 = Yanked %S line
command.yank.yankedLines-1 = Yanked %S lines
completion.waitingFor-1 = Waiting for %S completion.waitingFor-1 = Waiting for %S
completion.waitingForKeyPress = Waiting for key press completion.waitingForKeyPress = Waiting for key press
@@ -117,9 +121,9 @@ dactyl.yank-1 = Yank %S
dialog.notAvailable-1 = Dialog %S not available dialog.notAvailable-1 = Dialog %S not available
# TODO: merge with addon.*? # TODO: merge with addon.*?
download.uknownCommand = Unknown command download.unknownCommand = Unknown command
download.commandNotAllowed = Command not allowed download.commandNotAllowed = Command not allowed
download.prompt.launchExternal = This will launch an executable download. Would you like to continue? (yes/[no]/always): download.prompt.launchExecutable = This will launch an executable download. Would you like to continue? (yes/[no]/always):
download.action.Pause = Pause download.action.Pause = Pause
download.action.Remove = Remove download.action.Remove = Remove
@@ -128,7 +132,6 @@ download.action.Retry = Retry
download.action.Cancel = Cancel download.action.Cancel = Cancel
download.action.Delete = Delete download.action.Delete = Delete
editor.noEditor = No editor specified
editor.prompt.editPassword = Editing a password field externally will reveal the password. Would you like to continue? (yes/[no]): editor.prompt.editPassword = Editing a password field externally will reveal the password. Would you like to continue? (yes/[no]):
emenu.notFound-1 = Menu not found: %S emenu.notFound-1 = Menu not found: %S
@@ -173,6 +176,7 @@ io.notInRTP-1 = not found in 'runtimepath': %S
io.searchingFor-1 = Searching for %S io.searchingFor-1 = Searching for %S
io.searchingFor-2 = Searching for %S in %S io.searchingFor-2 = Searching for %S in %S
io.downloadFinished-2 = Download of %S to %S finished io.downloadFinished-2 = Download of %S to %S finished
io.shellReturn-1 = shell returned %S
macro.canceled-1 = Canceled playback of macro '%S' macro.canceled-1 = Canceled playback of macro '%S'
macro.recorded-1 = Recorded macro '%S' macro.recorded-1 = Recorded macro '%S'
@@ -206,26 +210,34 @@ mow.continue = Press ENTER or type command to continue
mow.more = -- More -- mow.more = -- More --
mow.moreHelp = -- More -- SPACE/<C-f>/j: screen/page/line down, <C-b>/<C-u>/k: up, q: quit mow.moreHelp = -- More -- SPACE/<C-f>/j: screen/page/line down, <C-b>/<C-u>/k: up, q: quit
mow.contextMenu.copyLink = Copy Link Location
mow.contextMenu.copyPath = Copy File Path
mow.contextMenu.copy = Copy
mow.contextMenu.selectAll = Select All
option.noSuch = No such option option.noSuch = No such option
option.noSuch-1 = No such option: %S option.noSuch-1 = No such option: %S
option.replaceExisting-1 = Warning: %S already exists: replacing existing option option.replaceExisting-1 = Warning: %S already exists: replacing existing option
option.intRequired = Integer value required option.intRequired = Integer value required
option.operatorNotSupported-2 = Operator %S not supported for option type %S option.operatorNotSupported-2 = Operator %S not supported for option type %S
option.notSet-1 = E764: Option '%S' is not set
option.currentValue = Current Value option.currentValue = Current Value
option.defaultValue = Default Value option.defaultValue = Default Value
option.bufferLocal = buffer local option.bufferLocal = buffer local
option.activate.safeSet = See the 'activate' option.
option.guioptions.safeSet = See 'guioptions' scrollbar flags.
option.hintkeys.duplicate = Duplicate keys not allowed
# The string 'passkeys' must appear exactly, including U0027 apostrophes # The string 'passkeys' must appear exactly, including U0027 apostrophes
option.passkeys.passedBy = passed by 'passkeys' option.passkeys.passedBy = passed by 'passkeys'
option.hintkeys.duplicate = Duplicate keys not allowed
option.showtabline.safeSet = See 'showtabline' option.
option.activate.safeSet = See the 'activate' option.
option.popups.safeSet = See the 'activate' option. option.popups.safeSet = See the 'activate' option.
option.guioptions.safeSet = See 'guioptions' scrollbar flags. option.showtabline.safeSet = See 'showtabline' option.
option.visualbell.safeSet = See 'visualbell' option. option.visualbell.safeSet = See 'visualbell' option.
pageinfo.s.ownerUnverified = %S (unverified)
plugin.searchingFor-1 = Searching for %S plugin.searchingFor-1 = Searching for %S
plugin.searchingForIn-2 = Searching for %S in %S plugin.searchingForIn-2 = Searching for %S in %S
plugin.notReplacingContext-1 = Not replacing plugin context for %S plugin.notReplacingContext-1 = Not replacing plugin context for %S
@@ -269,8 +281,8 @@ error.error-1 = Error: %S
error.interrupted = Interrupted error.interrupted = Interrupted
error.invalidSort-1 = Invalid sort order: %S error.invalidSort-1 = Invalid sort order: %S
error.missingQuote-1 = E114: Missing quote: %S error.missingQuote-1 = E114: Missing quote: %S
error.trailing = Trailing characters error.trailingCharacters = Trailing characters
error.trailing-1 = Trailing characters: %S error.trailingCharacters-1 = Trailing characters: %S
error.invalid-1 = Invalid %S error.invalid-1 = Invalid %S
error.invalidArgument = Invalid argument error.invalidArgument = Invalid argument
error.invalidArgument-1 = Invalid argument: %S error.invalidArgument-1 = Invalid argument: %S
@@ -281,8 +293,8 @@ error.invalidOperation = Invalid operation
error.monkeyPatchOverlay-1 = Not replacing property with eval-generated overlay by %S error.monkeyPatchOverlay-1 = Not replacing property with eval-generated overlay by %S
error.nullComputedStyle-1 = Computed style is null: %S error.nullComputedStyle-1 = Computed style is null: %S
error.syntaxError = Syntax error error.syntaxError = Syntax error
error.charsOutsideRange-1 = Character list outside the range %S error.charactersOutsideRange-1 = Character list outside the range %S
error.invalidCharRange = Invalid character range: %S error.invalidCharacterRange = Invalid character range: %S
error.notWriteable-2 = Could not write to %S: %S error.notWriteable-2 = Could not write to %S: %S
warn.deprecated-2 = %S is deprecated: Please use %S instead. warn.deprecated-2 = %S is deprecated: Please use %S instead.

View File

@@ -635,7 +635,7 @@
<spec>'extendedhinttags' 'eht'</spec> <spec>'extendedhinttags' 'eht'</spec>
<strut/> <strut/>
<type>&option.extendedhinttags.type;</type> <type>&option.extendedhinttags.type;</type>
<default>[asOTivVWy]:a[href],area[href],img[src],iframe[src], <default>[asOTvVWy]:a[href],area[href],img[src],iframe[src],
[f]:body, [f]:body,
[F]:body,code,div,html,p,pre,span, [F]:body,code,div,html,p,pre,span,
[iI]:img, [iI]:img,
@@ -1103,6 +1103,7 @@
<dt>g</dt> <dd>General info</dd> <dt>g</dt> <dd>General info</dd>
<dt>f</dt> <dd>Feeds</dd> <dt>f</dt> <dd>Feeds</dd>
<dt>m</dt> <dd>Meta tags</dd> <dt>m</dt> <dd>Meta tags</dd>
<dt>s</dt> <dd>Security information</dd>
</dl> </dl>
<p> <p>
@@ -1142,6 +1143,21 @@
</description> </description>
</item> </item>
<item>
<tags>'pu' 'passunknown'</tags>
<spec>'passunknown' 'pu'</spec>
<type>&option.showmode.type;</type>
<default>&option.showmode.default;</default>
<description>
<p>
Pass unknown keys through to &dactyl.host; in these
<t>modes</t>. The first element matching a currently
active mode is the one that takes effect. Modes may be
negated by prefixing them with a <tt>!</tt>.
</p>
</description>
</item>
<item> <item>
<tags>'pps' 'popups'</tags> <tags>'pps' 'popups'</tags>
<spec>'popups' 'pps'</spec> <spec>'popups' 'pps'</spec>
@@ -1329,13 +1345,17 @@
</item> </item>
<item> <item>
<tags>'nosmd' 'noshowmode'</tags>
<tags>'smd' 'showmode'</tags> <tags>'smd' 'showmode'</tags>
<spec>'showmode' 'smd'</spec> <spec>'showmode' 'smd'</spec>
<type>&option.showmode.type;</type> <type>&option.showmode.type;</type>
<default>&option.showmode.default;</default> <default>&option.showmode.default;</default>
<description> <description>
<p>Show the current mode in the command line if it matches this expression.</p> <p>
Show the current mode in the command line if it or any
of its parent <t>modes</t> is included in the list.
Modes may be negated by prefixing them with a
<tt>!</tt>.
</p>
</description> </description>
</item> </item>

View File

@@ -92,7 +92,7 @@
<note> <note>
The following items are always cleared entirely, regardless of The following items are always cleared entirely, regardless of
<a>timeframe</a>: <em>cache</em>, <em>host</em>, <em>offlineapps</em>, <a>timespan</a>: <em>cache</em>, <em>host</em>, <em>offlineapps</em>,
<em>passwords</em>, <em>sessions</em>, <em>sitesettings</em>. <em>passwords</em>, <em>sessions</em>, <em>sitesettings</em>.
Conversely, <em>host</em> and <em>options</em> are never cleared Conversely, <em>host</em> and <em>options</em> are never cleared
unless a host is specified. unless a host is specified.

View File

@@ -79,6 +79,7 @@
<dt>Enabled</dt> <dd>Text indicating enabled status, such as of an extension or style group</dd> <dt>Enabled</dt> <dd>Text indicating enabled status, such as of an extension or style group</dd>
<dt>ErrorMsg</dt> <dd>Error messages</dd> <dt>ErrorMsg</dt> <dd>Error messages</dd>
<dt>Filter</dt> <dd>The matching text in a completion list</dd> <dt>Filter</dt> <dd>The matching text in a completion list</dd>
<dt>Find</dt> <dd>Text find highlighting. Only background and foreground colors apply.</dd>
<dt>FrameIndicator</dt> <dd>The indicator shown when a new frame is selected</dd> <dt>FrameIndicator</dt> <dd>The indicator shown when a new frame is selected</dd>
<dt>Function</dt> <dd>A JavaScript Function object</dd> <dt>Function</dt> <dd>A JavaScript Function object</dd>
<dt>Hint</dt> <dd>A hint indicator. See <ex>:help hints</ex></dd> <dt>Hint</dt> <dd>A hint indicator. See <ex>:help hints</ex></dd>

View File

@@ -384,7 +384,7 @@
<h2 tag="app-tabs application-tabs pinned-tabs">Application Tabs</h2> <h2 tag="app-tabs application-tabs pinned-tabs">Application Tabs</h2>
<item> <item>
<tags>pin pintab</tags> <tags>:pin :pintab</tags>
<spec><oa>count</oa>pin<oa>tab</oa><oa>!</oa> <oa>arg</oa></spec> <spec><oa>count</oa>pin<oa>tab</oa><oa>!</oa> <oa>arg</oa></spec>
<description> <description>
<p> <p>
@@ -396,7 +396,7 @@
</item> </item>
<item> <item>
<tags>unpin unpintab</tags> <tags>:unpin :unpintab</tags>
<spec><oa>count</oa>pin<oa>tab</oa> <oa>arg</oa></spec> <spec><oa>count</oa>pin<oa>tab</oa> <oa>arg</oa></spec>
<description> <description>
<p> <p>

View File

@@ -110,7 +110,7 @@ var actions = {
name: "extr[ehash]", name: "extr[ehash]",
description: "Reload an extension", description: "Reload an extension",
action: function (addon) { action: function (addon) {
util.assert(util.haveGecko("2b"), _("error.notUseful", config.host)); util.assert(util.haveGecko("2b"), _("command.notUseful", config.host));
util.timeout(function () { util.timeout(function () {
addon.userDisabled = true; addon.userDisabled = true;
addon.userDisabled = false; addon.userDisabled = false;
@@ -153,9 +153,9 @@ var Addon = Class("Addon", {
<td highlight="AddonButtons Buttons"> <td highlight="AddonButtons Buttons">
<a highlight="Button" key="enable">{_("addon.action.On")}</a> <a highlight="Button" key="enable">{_("addon.action.On")}</a>
<a highlight="Button" key="disable">{_("addon.action.Off")}</a> <a highlight="Button" key="disable">{_("addon.action.Off")}</a>
<a highlight="Button" key="delete">{_("addon.action.Del")}</a> <a highlight="Button" key="delete">{_("addon.action.Delete")}</a>
<a highlight="Button" key="update">{_("addon.action.Upd")}</a> <a highlight="Button" key="update">{_("addon.action.Update")}</a>
<a highlight="Button" key="options">{_("addon.action.Opt")}</a> <a highlight="Button" key="options">{_("addon.action.Options")}</a>
</td> </td>
<td highlight="AddonDescription" key="description"/> <td highlight="AddonDescription" key="description"/>
</tr>, </tr>,
@@ -282,11 +282,11 @@ var AddonList = Class("AddonList", {
XML.ignoreWhitespace = true; XML.ignoreWhitespace = true;
util.xmlToDom(<table highlight="Addons" key="list" xmlns={XHTML}> util.xmlToDom(<table highlight="Addons" key="list" xmlns={XHTML}>
<tr highlight="AddonHead"> <tr highlight="AddonHead">
<td>Name</td> <td><!--L-->Name</td>
<td>Version</td> <td><!--L-->Version</td>
<td>Status</td> <td><!--L-->Status</td>
<td/> <td/>
<td>Description</td> <td><!--L-->Description</td>
</tr> </tr>
</table>, this.document, this.nodes); </table>, this.document, this.nodes);
@@ -418,7 +418,7 @@ var Addons = Module("addons", {
function (args) { function (args) {
let name = args[0]; let name = args[0];
if (args.bang && !command.bang) if (args.bang && !command.bang)
dactyl.assert(!name, _("error.trailing")); dactyl.assert(!name, _("error.trailingCharacters"));
else else
dactyl.assert(name, _("error.argumentRequired")); dactyl.assert(name, _("error.argumentRequired"));

View File

@@ -142,6 +142,7 @@ function defineModule(name, params, module) {
use[mod].push(module); use[mod].push(module);
} }
currentModule = module; currentModule = module;
module.startTime = Date.now();
} }
defineModule.loadLog = []; defineModule.loadLog = [];
@@ -163,7 +164,6 @@ defineModule.dump = function dump_() {
.replace(/^./gm, name + ": $&")); .replace(/^./gm, name + ": $&"));
} }
defineModule.modules = []; defineModule.modules = [];
defineModule.times = { all: 0 };
defineModule.time = function time(major, minor, func, self) { defineModule.time = function time(major, minor, func, self) {
let time = Date.now(); let time = Date.now();
if (typeof func !== "function") if (typeof func !== "function")
@@ -176,13 +176,7 @@ defineModule.time = function time(major, minor, func, self) {
loaded.util && util.reportError(e); loaded.util && util.reportError(e);
} }
let delta = Date.now() - time; JSMLoader.times.add(major, minor, Date.now() - time);
defineModule.times.all += delta;
defineModule.times[major] = (defineModule.times[major] || 0) + delta;
if (minor) {
defineModule.times[":" + minor] = (defineModule.times[":" + minor] || 0) + delta;
defineModule.times[major + ":" + minor] = (defineModule.times[major + ":" + minor] || 0) + delta;
}
return res; return res;
} }
@@ -211,7 +205,7 @@ function require(obj, name, from) {
if (loaded.util) if (loaded.util)
util.reportError(e); util.reportError(e);
else else
defineModule.dump(" " + (e.filename || e.fileName) + ":" + e.lineNumber + ": " + e +"\n"); defineModule.dump(" " + (e.filename || e.fileName) + ":" + e.lineNumber + ": " + e + "\n");
} }
} }
@@ -222,7 +216,7 @@ defineModule("base", {
"Struct", "StructBase", "Timer", "UTF8", "XPCOM", "XPCOMUtils", "XPCSafeJSObjectWrapper", "Struct", "StructBase", "Timer", "UTF8", "XPCOM", "XPCOMUtils", "XPCSafeJSObjectWrapper",
"array", "bind", "call", "callable", "ctypes", "curry", "debuggerProperties", "defineModule", "array", "bind", "call", "callable", "ctypes", "curry", "debuggerProperties", "defineModule",
"deprecated", "endModule", "forEach", "isArray", "isGenerator", "isinstance", "isObject", "deprecated", "endModule", "forEach", "isArray", "isGenerator", "isinstance", "isObject",
"isString", "isSubclass", "iter", "iterAll", "iterOwnProperties","keys", "memoize", "octal", "isString", "isSubclass", "iter", "iterAll", "iterOwnProperties", "keys", "memoize", "octal",
"properties", "require", "set", "update", "values", "withCallerGlobal" "properties", "require", "set", "update", "values", "withCallerGlobal"
], ],
use: ["config", "services", "util"] use: ["config", "services", "util"]
@@ -479,9 +473,13 @@ function curry(fn, length, self, acc) {
} }
if (curry.bind) if (curry.bind)
var bind = function bind(func) func.bind.apply(func, Array.slice(arguments, bind.length)); var bind = function bind(meth, self) let (func = callable(meth) ? meth : self[meth])
func.bind.apply(func, Array.slice(arguments, 1));
else else
var bind = function bind(func, self) { var bind = function bind(func, self) {
if (!callable(func))
func = self[func];
let args = Array.slice(arguments, bind.length); let args = Array.slice(arguments, bind.length);
return function bound() func.apply(self, args.concat(Array.slice(arguments))); return function bound() func.apply(self, args.concat(Array.slice(arguments)));
}; };

View File

@@ -151,7 +151,6 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), {
return this.rootFolders.indexOf(root) >= 0; return this.rootFolders.indexOf(root) >= 0;
}, },
// Should be made thread safe.
load: function load() { load: function load() {
let bookmarks = {}; let bookmarks = {};

View File

@@ -32,6 +32,26 @@ else
manager: Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar), manager: Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar),
stale: JSMLoader ? JSMLoader.stale : {}, stale: JSMLoader ? JSMLoader.stale : {},
suffix: "", suffix: "",
times: {
all: 0,
add: function add(major, minor, delta) {
this.all += delta;
this[major] = (this[major] || 0) + delta;
if (minor) {
minor = ":" + minor;
this[minor] = (this[minor] || 0) + delta;
this[major + minor] = (this[major + minor] || 0) + delta;
}
},
clear: function clear() {
for (let key in this)
if (typeof this[key] !== "number")
delete this[key];
}
},
init: function init(suffix) { init: function init(suffix) {
this.initialized = true; this.initialized = true;
this.suffix = suffix || ""; this.suffix = suffix || "";
@@ -41,6 +61,7 @@ else
this.global.JSMLoader = this; this.global.JSMLoader = this;
base.JSMLoader = this; base.JSMLoader = this;
}, },
getTarget: function getTarget(url) { getTarget: function getTarget(url) {
if (url.indexOf(":") === -1) if (url.indexOf(":") === -1)
url = "resource://dactyl" + this.suffix + "/" + url; url = "resource://dactyl" + this.suffix + "/" + url;
@@ -49,6 +70,7 @@ else
chan.cancel(Components.results.NS_BINDING_ABORTED); chan.cancel(Components.results.NS_BINDING_ABORTED);
return chan.name; return chan.name;
}, },
load: function load(name, target) { load: function load(name, target) {
let url = name; let url = name;
if (url.indexOf(":") === -1) if (url.indexOf(":") === -1)
@@ -68,7 +90,12 @@ else
} }
try { try {
let now = Date.now();
let global = Components.utils.import(url, target); let global = Components.utils.import(url, target);
if (!(name in this.globals))
this.times.add("require", name, Date.now() - now);
return this.globals[name] = global; return this.globals[name] = global;
} }
catch (e) { catch (e) {
@@ -76,11 +103,18 @@ else
throw e; throw e;
} }
}, },
loadSubScript: function loadSubScript() this.loader.loadSubScript.apply(this.loader, arguments),
loadSubScript: function loadSubScript(script) {
let now = Date.now();
this.loader.loadSubScript.apply(this.loader, arguments);
this.times.add("loadSubScript", script, Date.now() - now);
},
cleanup: function unregister() { cleanup: function unregister() {
for each (let factory in this.factories.splice(0)) for each (let factory in this.factories.splice(0))
this.manager.unregisterFactory(factory.classID, factory); this.manager.unregisterFactory(factory.classID, factory);
}, },
purge: function purge() { purge: function purge() {
dump("dactyl: JSMLoader: purge\n"); dump("dactyl: JSMLoader: purge\n");

View File

@@ -310,7 +310,7 @@ var Command = Class("Command", {
util.assert((this.length == 0 || this.command.argCount !== "0") && util.assert((this.length == 0 || this.command.argCount !== "0") &&
(this.length <= 1 || !/^[01?]$/.test(this.command.argCount)), (this.length <= 1 || !/^[01?]$/.test(this.command.argCount)),
_("error.trailing")); _("error.trailingCharacters"));
} }
} }
}); });
@@ -640,47 +640,55 @@ var Commands = Module("commands", {
/** /**
* Displays a list of user-defined commands. * Displays a list of user-defined commands.
*
* @param {string} filter Limits the list to those commands with a name
* matching this anchored substring.
*/ */
list: function list() { list: function list(filter) {
const { commandline, completion } = this.modules; const { commandline, completion } = this.modules;
function completerToString(completer) { function completerToString(completer) {
if (completer) if (completer)
return [k for ([k, v] in Iterator(config.completers)) if (completer == completion.closure[v])][0] || "custom"; return [k for ([k, v] in Iterator(config.completers)) if (completer == completion.closure[v])][0] || "custom";
return ""; return "";
} }
// TODO: allow matching of aliases?
function cmds(hive) hive._list.filter(function (cmd) cmd.name.indexOf(filter || "") == 0)
if (!this.userHives.some(function (h) h._list.length)) let hives = this.userHives.map(function (h) [h, cmds(h)]).filter(function ([h, c]) c.length);
let list = <table>
<tr highlight="Title">
<td/>
<td style="padding-right: 1em;"></td>
<td style="padding-right: 1ex;"><!--L-->Name</td>
<td style="padding-right: 1ex;"><!--L-->Args</td>
<td style="padding-right: 1ex;"><!--L-->Range</td>
<td style="padding-right: 1ex;"><!--L-->Complete</td>
<td style="padding-right: 1ex;"><!--L-->Definition</td>
</tr>
<col style="min-width: 6em; padding-right: 1em;"/>
{
template.map(hives, function ([hive, cmds]) let (i = 0)
<tr style="height: .5ex;"/> +
template.map(cmds, function (cmd)
template.map(cmd.names, function (name)
<tr>
<td highlight="Title">{!i++ ? hive.name : ""}</td>
<td>{cmd.bang ? "!" : " "}</td>
<td>{cmd.name}</td>
<td>{cmd.argCount}</td>
<td>{cmd.count ? "0c" : ""}</td>
<td>{completerToString(cmd.completer)}</td>
<td>{cmd.replacementText || "function () { ... }"}</td>
</tr>)) +
<tr style="height: .5ex;"/>)
}
</table>;
if (list.*.length() === list.text().length() + 2)
dactyl.echomsg(_("command.none")); dactyl.echomsg(_("command.none"));
else else
commandline.commandOutput( commandline.commandOutput(list);
<table>
<tr highlight="Title">
<td/>
<td style="padding-right: 1em;"></td>
<td style="padding-right: 1ex;">Name</td>
<td style="padding-right: 1ex;">Args</td>
<td style="padding-right: 1ex;">Range</td>
<td style="padding-right: 1ex;">Complete</td>
<td style="padding-right: 1ex;">Definition</td>
</tr>
<col style="min-width: 6em; padding-right: 1em;"/>
{
template.map(this.userHives, function (hive) let (i = 0)
<tr style="height: .5ex;"/> +
template.map(hive, function (cmd)
template.map(cmd.names, function (name)
<tr>
<td highlight="Title">{!i++ ? hive.name : ""}</td>
<td>{cmd.bang ? "!" : " "}</td>
<td>{cmd.name}</td>
<td>{cmd.argCount}</td>
<td>{cmd.count ? "0c" : ""}</td>
<td>{completerToString(cmd.completer)}</td>
<td>{cmd.replacementText || "function () { ... }"}</td>
</tr>)) +
<tr style="height: .5ex;"/>)
}
</table>);
} }
}), }),
@@ -863,7 +871,7 @@ var Commands = Module("commands", {
let [count, arg, quote] = Commands.parseArg(str, null, _keepQuotes); let [count, arg, quote] = Commands.parseArg(str, null, _keepQuotes);
if (quote == "\\" && !complete) if (quote == "\\" && !complete)
return [, , , _("error.trailing", "\\")]; return [, , , _("error.trailingCharacters", "\\")];
if (quote && !complete) if (quote && !complete)
return [, , , _("error.missingQuote", quote)]; return [, , , _("error.missingQuote", quote)];
return [count, arg, quote]; return [count, arg, quote];
@@ -1382,8 +1390,6 @@ var Commands = Module("commands", {
commands: function initCommands(dactyl, modules, window) { commands: function initCommands(dactyl, modules, window) {
const { commands, contexts } = modules; const { commands, contexts } = modules;
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
// specified - useful?
commands.add(["com[mand]"], commands.add(["com[mand]"],
"List or define commands", "List or define commands",
function (args) { function (args) {
@@ -1392,8 +1398,8 @@ var Commands = Module("commands", {
util.assert(!cmd || cmd.split(",").every(commands.validName.closure.test), util.assert(!cmd || cmd.split(",").every(commands.validName.closure.test),
_("command.invalidName", cmd)); _("command.invalidName", cmd));
if (!args.literalArg) if (args.length <= 1)
commands.list(); commands.list(cmd);
else { else {
util.assert(args["-group"].modifiable, util.assert(args["-group"].modifiable,
_("group.cantChangeBuiltin", _("command.commands"))); _("group.cantChangeBuiltin", _("command.commands")));
@@ -1488,7 +1494,7 @@ var Commands = Module("commands", {
}, },
{ {
names: ["-literal", "-l"], names: ["-literal", "-l"],
description: "Process the nth ignoring any quoting or meta characters", description: "Process the specified argument ignoring any quoting or meta characters",
type: CommandOption.INT type: CommandOption.INT
}, },
{ {
@@ -1573,7 +1579,7 @@ var Commands = Module("commands", {
] ]
})), })),
iterateIndex: function (args) let (tags = services["dactyl:"].HELP_TAGS) iterateIndex: function (args) let (tags = services["dactyl:"].HELP_TAGS)
this.iterate(args).filter(function (cmd) cmd.hive === commands.builtin || set.has(cmd.helpTag)), this.iterate(args).filter(function (cmd) cmd.hive === commands.builtin || set.has(tags, cmd.helpTag)),
format: { format: {
headings: ["Command", "Group", "Description"], headings: ["Command", "Group", "Description"],
description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : "")), description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : "")),

View File

@@ -960,7 +960,7 @@ var Completion = Module("completion", {
context.title = ["URL", "Title"]; context.title = ["URL", "Title"];
context.fork("additional", 0, this, function (context) { context.fork("additional", 0, this, function (context) {
context.title[0] += " (additional)"; context.title[0] += /*L*/" (additional)";
context.filter = context.parent.filter; // FIXME context.filter = context.parent.filter; // FIXME
context.completions = context.parent.completions; context.completions = context.parent.completions;
// For items whose URL doesn't exactly match the filter, // For items whose URL doesn't exactly match the filter,

View File

@@ -13,7 +13,7 @@ Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("config", { defineModule("config", {
exports: ["ConfigBase", "Config", "config"], exports: ["ConfigBase", "Config", "config"],
require: ["services", "storage", "util", "template"], require: ["services", "storage", "util", "template"],
use: ["io", "messages", "prefs"] use: ["io", "messages", "prefs", "styles"]
}, this); }, this);
var ConfigBase = Class("ConfigBase", { var ConfigBase = Class("ConfigBase", {
@@ -33,9 +33,12 @@ var ConfigBase = Class("ConfigBase", {
loadStyles: function loadStyles() { loadStyles: function loadStyles() {
const { highlight } = require("highlight"); const { highlight } = require("highlight");
highlight.styleableChrome = this.styleableChrome; highlight.styleableChrome = this.styleableChrome;
highlight.loadCSS(this.CSS); highlight.loadCSS(this.CSS);
highlight.loadCSS(this.helpCSS); highlight.loadCSS(this.helpCSS);
if (!util.haveGecko("2b")) if (!util.haveGecko("2b"))
highlight.loadCSS(<![CDATA[ highlight.loadCSS(<![CDATA[
!TabNumber font-weight: bold; margin: 0px; padding-right: .8ex; !TabNumber font-weight: bold; margin: 0px; padding-right: .8ex;
@@ -46,6 +49,25 @@ var ConfigBase = Class("ConfigBase", {
text-shadow: black -1px 0 1px, black 0 1px 1px, black 1px 0 1px, black 0 -1px 1px; text-shadow: black -1px 0 1px, black 0 1px 1px, black 1px 0 1px, black 0 -1px 1px;
} }
]]>); ]]>);
let hl = highlight.set("Find", "");
hl.onChange = function () {
function hex(val) ("#" + util.regexp.iterate(/\d+/g, val)
.map(function (num) ("0" + Number(num).toString(16)).slice(-2))
.join("")
).slice(0, 7);
let elem = services.appShell.hiddenDOMWindow.document.createElement("div");
elem.style.cssText = this.cssText;
let style = util.computedStyle(elem);
let keys = iter(Styles.propertyIter(this.cssText)).map(function (p) p.name).toArray();
let bg = keys.some(function (k) /^background/.test(k));
let fg = keys.indexOf("color") >= 0;
prefs[bg ? "safeSet" : "safeReset"]("ui.textHighlightBackground", hex(style.backgroundColor));
prefs[fg ? "safeSet" : "safeReset"]("ui.textHighlightForeground", hex(style.color));
};
}, },
get addonID() this.name + "@dactyl.googlecode.com", get addonID() this.name + "@dactyl.googlecode.com",
@@ -132,7 +154,7 @@ var ConfigBase = Class("ConfigBase", {
*/ */
VCSPath: Class.memoize(function () { VCSPath: Class.memoize(function () {
if (/pre$/.test(this.addon.version)) { if (/pre$/.test(this.addon.version)) {
let uri = this.addon.getResourceURI("../.hg"); let uri = util.newURI(this.addon.getResourceURI("").spec + "../.hg");
if (uri instanceof Ci.nsIFileURL && if (uri instanceof Ci.nsIFileURL &&
uri.file.exists() && uri.file.exists() &&
io.pathSearch("hg")) io.pathSearch("hg"))
@@ -159,7 +181,7 @@ var ConfigBase = Class("ConfigBase", {
"--template=hg{rev}-" + this.branch + " ({date|isodate})"]).output; "--template=hg{rev}-" + this.branch + " ({date|isodate})"]).output;
let version = this.addon.version; let version = this.addon.version;
if ("@DATE@" !== "@" + "DATE@") if ("@DATE@" !== "@" + "DATE@")
version += " (created: @DATE@)"; version += /*L*/" (created: @DATE@)";
return version; return version;
}), }),
@@ -206,7 +228,7 @@ var ConfigBase = Class("ConfigBase", {
"version" "version"
], ],
helpStyles: /^(Help|StatusLine|REPL)|^(Boolean|Indicator|MoreMsg|Number|Object|Logo|Key(word)?|String)$/, helpStyles: /^(Help|StatusLine|REPL)|^(Boolean|Dense|Indicator|MoreMsg|Number|Object|Logo|Key(word)?|String)$/,
styleHelp: function styleHelp() { styleHelp: function styleHelp() {
if (!this.helpStyled) { if (!this.helpStyled) {
const { highlight } = require("highlight"); const { highlight } = require("highlight");
@@ -428,7 +450,6 @@ var ConfigBase = Class("ConfigBase", {
CmdInput;.dactyl-commandline-command CmdInput;.dactyl-commandline-command
CmdOutput white-space: pre; CmdOutput white-space: pre;
CompGroup CompGroup
CompGroup:not(:first-of-type) margin-top: .5em; CompGroup:not(:first-of-type) margin-top: .5em;
CompGroup:last-of-type padding-bottom: 1.5ex; CompGroup:last-of-type padding-bottom: 1.5ex;
@@ -456,6 +477,7 @@ var ConfigBase = Class("ConfigBase", {
CompMore text-align: center; height: .5ex; line-height: .5ex; margin-bottom: -.5ex; CompMore text-align: center; height: .5ex; line-height: .5ex; margin-bottom: -.5ex;
CompMore::after content: "⌄"; CompMore::after content: "⌄";
Dense margin-top: 0; margin-bottom: 0;
EditorEditing;;* background: #bbb !important; -moz-user-input: none !important; -moz-user-modify: read-only !important; EditorEditing;;* background: #bbb !important; -moz-user-input: none !important; -moz-user-modify: read-only !important;
EditorError;;* background: red !important; EditorError;;* background: red !important;
@@ -624,7 +646,7 @@ var ConfigBase = Class("ConfigBase", {
HelpEx;;;FontCode display: inline-block; color: #527BBD; HelpEx;;;FontCode display: inline-block; color: #527BBD;
HelpExample display: block; margin: 1em 0; HelpExample display: block; margin: 1em 0;
HelpExample::before content: "Example: "; font-weight: bold; HelpExample::before content: /*L*/"Example: "; font-weight: bold;
HelpInfo display: block; width: 20em; margin-left: auto; HelpInfo display: block; width: 20em; margin-left: auto;
HelpInfoLabel display: inline-block; width: 6em; color: magenta; font-weight: bold; vertical-align: text-top; HelpInfoLabel display: inline-block; width: 6em; color: magenta; font-weight: bold; vertical-align: text-top;
@@ -661,7 +683,6 @@ var ConfigBase = Class("ConfigBase", {
HelpList;html|ul;dactyl://help/* display: block; list-style-position: outside; margin: 1em 0; HelpList;html|ul;dactyl://help/* display: block; list-style-position: outside; margin: 1em 0;
HelpListItem;html|li;dactyl://help/* display: list-item; HelpListItem;html|li;dactyl://help/* display: list-item;
HelpNote color: red; font-weight: bold; HelpNote color: red; font-weight: bold;
HelpOpt;;;FontCode color: #106326; HelpOpt;;;FontCode color: #106326;
@@ -708,7 +729,6 @@ var ConfigBase = Class("ConfigBase", {
HelpHead4;html|h4;dactyl://help/* { HelpHead4;html|h4;dactyl://help/* {
} }
HelpTab;html|dl;dactyl://help/* { HelpTab;html|dl;dactyl://help/* {
display: table; display: table;
width: 100%; width: 100%;

View File

@@ -137,7 +137,7 @@ var Download = Class("Download", {
if (this.timeRemaining) if (this.timeRemaining)
this.nodes.time.textContent = util.formatSeconds(this.timeRemaining); this.nodes.time.textContent = util.formatSeconds(this.timeRemaining);
else else
this.nodes.time.textContent = "~1 second"; this.nodes.time.textContent = /*L*/"~1 second";
} }
let total = this.nodes.progressTotal.textContent = this.size ? util.formatBytes(this.size, 1, true) : "Unknown"; let total = this.nodes.progressTotal.textContent = this.size ? util.formatBytes(this.size, 1, true) : "Unknown";
let suffix = RegExp(/( [a-z]+)?$/i.exec(total)[0] + "$"); let suffix = RegExp(/( [a-z]+)?$/i.exec(total)[0] + "$");
@@ -182,20 +182,20 @@ var DownloadList = Class("DownloadList",
util.xmlToDom(<table highlight="Downloads" key="list" xmlns={XHTML}> util.xmlToDom(<table highlight="Downloads" key="list" xmlns={XHTML}>
<tr highlight="DownloadHead"> <tr highlight="DownloadHead">
<span>Title</span> <span><!--L-->Title</span>
<span>Status</span> <span><!--L-->Status</span>
<span/> <span/>
<span>Progress</span> <span><!--L-->Progress</span>
<span/> <span/>
<span>Time remaining</span> <span><!--L-->Time remaining</span>
<span>Source</span> <span><!--L-->Source</span>
</tr> </tr>
<tr highlight="Download"><span><div style="min-height: 1ex; /* FIXME */"/></span></tr> <tr highlight="Download"><span><div style="min-height: 1ex; /* FIXME */"/></span></tr>
<tr highlight="Download" key="totals" active="true"> <tr highlight="Download" key="totals" active="true">
<td><span highlight="Title">Totals:</span>&#xa0;<span key="total"/></td> <td><span highlight="Title"><!--L-->Totals:</span>&#xa0;<span key="total"/></td>
<td/> <td/>
<td highlight="DownloadButtons"> <td highlight="DownloadButtons">
<a highlight="Button" key="clear">Clear</a> <a highlight="Button" key="clear"><!--L-->Clear</a>
</td> </td>
<td highlight="DownloadProgress" key="progress"> <td highlight="DownloadProgress" key="progress">
<span highlight="DownloadProgressHave" key="progressHave" <span highlight="DownloadProgressHave" key="progressHave"
@@ -277,7 +277,7 @@ var DownloadList = Class("DownloadList",
let active = downloads.filter(function (dl) dl.alive).length; let active = downloads.filter(function (dl) dl.alive).length;
if (active) if (active)
this.nodes.total.textContent = active + " active"; this.nodes.total.textContent = /*L*/active + " active";
else for (let key in values(["total", "percent", "time"])) else for (let key in values(["total", "percent", "time"]))
this.nodes[key].textContent = ""; this.nodes[key].textContent = "";
}, },

View File

@@ -33,6 +33,8 @@ Highlight.liveProperty = function (name, prop) {
h.style.css = h.css; h.style.css = h.css;
this.style[prop || name] = this[prop || name]; this.style[prop || name] = this[prop || name];
if (this.onChange)
this.onChange();
}); });
} }
Highlight.liveProperty("agent"); Highlight.liveProperty("agent");
@@ -337,7 +339,7 @@ var Highlights = Module("Highlight", {
if (!modify && /&$/.test(key)) if (!modify && /&$/.test(key))
[clear, modify, key] = [true, true, key.replace(/&$/, "")]; [clear, modify, key] = [true, true, key.replace(/&$/, "")];
dactyl.assert(!(clear && css), _("error.trailing")); dactyl.assert(!(clear && css), _("error.trailingCharacters"));
if (!modify) if (!modify)
modules.commandline.commandOutput( modules.commandline.commandOutput(
@@ -369,7 +371,10 @@ var Highlights = Module("Highlight", {
else if (args.completeArg == 1) { else if (args.completeArg == 1) {
let hl = highlight.get(args[0]); let hl = highlight.get(args[0]);
if (hl) if (hl)
context.completions = [[hl.value, "Current Value"], [hl.defaultValue || "", "Default Value"]]; context.completions = [
[hl.value, _("option.currentValue")],
[hl.defaultValue || "", _("option.defaultValue")]
];
context.fork("css", 0, completion, "css"); context.fork("css", 0, completion, "css");
} }
}, },

View File

@@ -116,7 +116,7 @@ var IO = Module("io", {
outer: outer:
for (let dir in values(dirs)) { for (let dir in values(dirs)) {
for (let [,path] in Iterator(paths)) { for (let [, path] in Iterator(paths)) {
let file = dir.child(path); let file = dir.child(path);
dactyl.echomsg(_("io.searchingFor", file.path.quote()), 3); dactyl.echomsg(_("io.searchingFor", file.path.quote()), 3);
@@ -208,7 +208,7 @@ var IO = Module("io", {
} }
catch (e) { catch (e) {
dactyl.reportError(e); dactyl.reportError(e);
let message = "Sourcing file: " + (e.echoerr || file.path + ": " + e); let message = /*L*/"Sourcing file: " + (e.echoerr || file.path + ": " + e);
if (!params.silent) if (!params.silent)
dactyl.echoerr(message); dactyl.echoerr(message);
} }
@@ -783,9 +783,13 @@ unlet s:cpo_save
commands.add(["scrip[tnames]"], commands.add(["scrip[tnames]"],
"List all sourced script names", "List all sourced script names",
function () { function () {
modules.commandline.commandOutput( if (!io._scriptNames.length)
template.tabular(["<SNR>", "Filename"], ["text-align: right; padding-right: 1em;"], dactyl.echomsg(_("command.scriptnames.none"));
([i + 1, file] for ([i, file] in Iterator(io._scriptNames))))); // TODO: add colon and remove column titles for pedantic Vim compatibility? else
modules.commandline.commandOutput(
template.tabular(["<SNR>", "Filename"], ["text-align: right; padding-right: 1em;"],
([i + 1, file] for ([i, file] in Iterator(io._scriptNames))))); // TODO: add colon and remove column titles for pedantic Vim compatibility?
}, },
{ argCount: "0" }); { argCount: "0" });
@@ -831,7 +835,7 @@ unlet s:cpo_save
let result = io.system(arg); let result = io.system(arg);
if (result.returnValue != 0) if (result.returnValue != 0)
result.output += "\nshell returned " + result.returnValue; result.output += "\n" + _("io.shellReturn", result.returnValue);
modules.commandline.command = "!" + arg; modules.commandline.command = "!" + arg;
modules.commandline.commandOutput(<span highlight="CmdOutput">{result.output}</span>); modules.commandline.commandOutput(<span highlight="CmdOutput">{result.output}</span>);
@@ -981,9 +985,9 @@ unlet s:cpo_save
context.key = match.prefix; context.key = match.prefix;
context.advance(match.prefix.length + 1); context.advance(match.prefix.length + 1);
context.generate = function () iter({ context.generate = function () iter({
content: "Chrome content", content: /*L*/"Chrome content",
locale: "Locale-specific content", locale: /*L*/"Locale-specific content",
skin: "Theme-specific content" skin: /*L*/"Theme-specific content"
}); });
} }
} }

View File

@@ -45,7 +45,7 @@ var JavaScript = Module("javascript", {
}), }),
globals: Class.memoize(function () [ globals: Class.memoize(function () [
[this.modules.userContext, "Global Variables"], [this.modules.userContext, /*L*/"Global Variables"],
[this.modules, "modules"], [this.modules, "modules"],
[this.window, "window"] [this.window, "window"]
]), ]),
@@ -117,12 +117,8 @@ var JavaScript = Module("javascript", {
return cache[key]; return cache[key];
context[JavaScript.EVAL_TMP] = tmp; context[JavaScript.EVAL_TMP] = tmp;
context[JavaScript.EVAL_EXPORT] = function export_(obj) cache[key] = obj;
try { try {
if (tmp != null) // Temporary hack until bug 609949 is fixed. cache[key] = this.modules.dactyl.userEval(arg, context, /*L*/"[Command Line Completion]", 1);
this.modules.dactyl.userEval(JavaScript.EVAL_EXPORT + "(" + arg + ")", context, "[Command Line Completion]", 1);
else
cache[key] = this.modules.dactyl.userEval(arg, context, "[Command Line Completion]", 1);
return cache[key]; return cache[key];
} }
@@ -170,7 +166,7 @@ var JavaScript = Module("javascript", {
if (this._top.char != arg) { if (this._top.char != arg) {
this.context.highlight(this._top.offset, this._i - this._top.offset, "SPELLCHECK"); this.context.highlight(this._top.offset, this._i - this._top.offset, "SPELLCHECK");
throw Error("Invalid JS"); throw Error(/*L*/"Invalid JS");
} }
// The closing character of this stack frame will have pushed a new // The closing character of this stack frame will have pushed a new
@@ -308,7 +304,7 @@ var JavaScript = Module("javascript", {
if (this._checkFunction(prev, dot, cacheKey)) if (this._checkFunction(prev, dot, cacheKey))
return []; return [];
if (prev != statement && obj == null) { if (prev != statement && obj == null) {
this.context.message = "Error: " + cacheKey.quote() + " is " + String(obj); this.context.message = /*L*/"Error: " + cacheKey.quote() + " is " + String(obj);
return []; return [];
} }
@@ -324,7 +320,7 @@ var JavaScript = Module("javascript", {
let end = (frame == -1 ? this._lastIdx : this._get(frame + 1).offset); let end = (frame == -1 ? this._lastIdx : this._get(frame + 1).offset);
this._cacheKey = null; this._cacheKey = null;
let obj = [[this.cache.evalContext, "Local Variables"]].concat(this.globals); let obj = [[this.cache.evalContext, /*L*/"Local Variables"]].concat(this.globals);
// Is this an object dereference? // Is this an object dereference?
if (dot < statement) // No. if (dot < statement) // No.
dot = statement - 1; dot = statement - 1;
@@ -339,7 +335,7 @@ var JavaScript = Module("javascript", {
const self = this; const self = this;
if (!getOwnPropertyNames && !services.debugger.isOn && !this.context.message) if (!getOwnPropertyNames && !services.debugger.isOn && !this.context.message)
this.context.message = "For better completion data, please enable the JavaScript debugger (:set jsdebugger)"; this.context.message = /*L*/"For better completion data, please enable the JavaScript debugger (:set jsdebugger)";
let base = this.context.fork("js", this._top.offset); let base = this.context.fork("js", this._top.offset);
base.forceAnchored = true; base.forceAnchored = true;
@@ -419,14 +415,14 @@ var JavaScript = Module("javascript", {
objects.forEach(function (obj) { objects.forEach(function (obj) {
obj.ctxt_p.split(obj[1] + "/anchored", this, function (context) { obj.ctxt_p.split(obj[1] + "/anchored", this, function (context) {
context.anchored = true; context.anchored = true;
context.title[0] += " (prototypes)"; context.title[0] += /*L*/" (prototypes)";
}); });
}); });
objects.forEach(function (obj) { objects.forEach(function (obj) {
obj.ctxt_t.split(obj[1] + "/unanchored", this, function (context) { obj.ctxt_t.split(obj[1] + "/unanchored", this, function (context) {
context.anchored = false; context.anchored = false;
context.title[0] += " (substrings)"; context.title[0] += /*L*/" (substrings)";
context.filters.push(unanchored); context.filters.push(unanchored);
}); });
}); });
@@ -434,7 +430,7 @@ var JavaScript = Module("javascript", {
objects.forEach(function (obj) { objects.forEach(function (obj) {
obj.ctxt_p.split(obj[1] + "/unanchored", this, function (context) { obj.ctxt_p.split(obj[1] + "/unanchored", this, function (context) {
context.anchored = false; context.anchored = false;
context.title[0] += " (prototype substrings)"; context.title[0] += /*L*/" (prototype substrings)";
context.filters.push(unanchored); context.filters.push(unanchored);
}); });
}); });
@@ -646,7 +642,6 @@ var JavaScript = Module("javascript", {
}, { }, {
EVAL_TMP: "__dactyl_eval_tmp", EVAL_TMP: "__dactyl_eval_tmp",
EVAL_EXPORT: "__dactyl_eval_export",
/** /**
* A map of argument completion functions for named methods. The * A map of argument completion functions for named methods. The
@@ -775,8 +770,8 @@ var JavaScript = Module("javascript", {
this.js.newContext = function newContext() modules.newContext(self.context, !sandbox); this.js.newContext = function newContext() modules.newContext(self.context, !sandbox);
this.js.globals = [ this.js.globals = [
[this.context, "REPL Variables"], [this.context, /*L*/"REPL Variables"],
[context, "REPL Global"] [context, /*L*/"REPL Global"]
].concat(this.js.globals.filter(function ([global]) isPrototypeOf.call(global, context))); ].concat(this.js.globals.filter(function ([global]) isPrototypeOf.call(global, context)));
if (!isPrototypeOf.call(modules.jsmodules, context)) if (!isPrototypeOf.call(modules.jsmodules, context))
@@ -790,13 +785,14 @@ var JavaScript = Module("javascript", {
this.repl = REPL(this.context); this.repl = REPL(this.context);
}, },
open: function open(context) { open: function open(context) {
this.updatePrompt();
modules.mow.echo(this.repl); modules.mow.echo(this.repl);
this.widgets.message = null; this.widgets.message = null;
open.superapply(this, arguments); open.superapply(this, arguments);
this.updatePrompt();
}, },
complete: function complete(context) { complete: function complete(context) {
@@ -807,6 +803,8 @@ var JavaScript = Module("javascript", {
mode: modes.REPL, mode: modes.REPL,
get completionList() this.widgets.statusbar.commandline.id,
accept: function accept() { accept: function accept() {
dactyl.trapErrors(function () { this.repl.addOutput(this.command) }, this); dactyl.trapErrors(function () { this.repl.addOutput(this.command) }, this);

View File

@@ -448,7 +448,7 @@ var Option = Class("Option", {
regexplist: function regexplist(k, default_) { regexplist: function regexplist(k, default_) {
for (let re in values(this.value)) for (let re in values(this.value))
if (re(k)) if ((re.test || re).call(re, k))
return re.result; return re.result;
return arguments.length > 1 ? default_ : null; return arguments.length > 1 ? default_ : null;
}, },
@@ -619,18 +619,23 @@ var Option = Class("Option", {
stringlist: function stringlist(operator, values, scope, invert) { stringlist: function stringlist(operator, values, scope, invert) {
values = Array.concat(values); values = Array.concat(values);
function uniq(ary) {
let seen = {};
return ary.filter(function (elem) !set.add(seen, elem));
}
switch (operator) { switch (operator) {
case "+": case "+":
return array.uniq(Array.concat(this.value, values), true); return uniq(Array.concat(this.value, values), true);
case "^": case "^":
// NOTE: Vim doesn't prepend if there's a match in the current value // NOTE: Vim doesn't prepend if there's a match in the current value
return array.uniq(Array.concat(values, this.value), true); return uniq(Array.concat(values, this.value), true);
case "-": case "-":
return this.value.filter(function (item) values.indexOf(item) == -1); return this.value.filter(function (item) !set.has(this, item), set(values));
case "=": case "=":
if (invert) { if (invert) {
let keepValues = this.value.filter(function (item) values.indexOf(item) == -1); let keepValues = this.value.filter(function (item) !set.has(this, item), set(values));
let addValues = values.filter(function (item) this.value.indexOf(item) == -1, this); let addValues = values.filter(function (item) !set.has(this, item), set(this.value));
return addValues.concat(keepValues); return addValues.concat(keepValues);
} }
return values; return values;
@@ -870,7 +875,7 @@ var Options = Module("options", {
allPrefs: deprecated("prefs.getNames", function allPrefs() prefs.getNames.apply(prefs, arguments)), allPrefs: deprecated("prefs.getNames", function allPrefs() prefs.getNames.apply(prefs, arguments)),
getPref: deprecated("prefs.get", function getPref() prefs.get.apply(prefs, arguments)), getPref: deprecated("prefs.get", function getPref() prefs.get.apply(prefs, arguments)),
invertPref: deprecated("prefs.invert", function invertPref() prefs.invert.apply(prefs, arguments)), invertPref: deprecated("prefs.invert", function invertPref() prefs.invert.apply(prefs, arguments)),
listPrefs: deprecated("prefs.list", function listPrefs() { commandline.commandOutput(prefs.list.apply(prefs, arguments)); }), listPrefs: deprecated("prefs.list", function listPrefs() { this.modules.commandline.commandOutput(prefs.list.apply(prefs, arguments)); }),
observePref: deprecated("prefs.observe", function observePref() prefs.observe.apply(prefs, arguments)), observePref: deprecated("prefs.observe", function observePref() prefs.observe.apply(prefs, arguments)),
popContext: deprecated("prefs.popContext", function popContext() prefs.popContext.apply(prefs, arguments)), popContext: deprecated("prefs.popContext", function popContext() prefs.popContext.apply(prefs, arguments)),
pushContext: deprecated("prefs.pushContext", function pushContext() prefs.pushContext.apply(prefs, arguments)), pushContext: deprecated("prefs.pushContext", function pushContext() prefs.pushContext.apply(prefs, arguments)),
@@ -1056,7 +1061,7 @@ var Options = Module("options", {
}, },
{ promptHighlight: "WarningMsg" }); { promptHighlight: "WarningMsg" });
else if (name == "all") else if (name == "all")
commandline.commandOutput(prefs.list(onlyNonDefault, "")); modules.commandline.commandOutput(prefs.list(onlyNonDefault, ""));
else if (reset) else if (reset)
prefs.reset(name); prefs.reset(name);
else if (invertBoolean) else if (invertBoolean)
@@ -1169,7 +1174,7 @@ var Options = Module("options", {
context.advance(context.filter.indexOf("=")); context.advance(context.filter.indexOf("="));
if (option.type == "boolean") if (option.type == "boolean")
return error(context.filter.length, _("error.trailing")); return error(context.filter.length, _("error.trailingCharacters"));
context.advance(1); context.advance(1);
if (opt.error) if (opt.error)
@@ -1235,7 +1240,7 @@ var Options = Module("options", {
if (str.text().length() == str.*.length()) if (str.text().length() == str.*.length())
dactyl.echomsg(_("variable.none")); dactyl.echomsg(_("variable.none"));
else else
dactyl.echo(str, commandline.FORCE_MULTILINE); dactyl.echo(str, modules.commandline.FORCE_MULTILINE);
return; return;
} }

View File

@@ -115,7 +115,7 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
} }
}; };
return template.options(config.host + " Preferences", prefs.call(this)); return template.options(/*L*/config.host + " Preferences", prefs.call(this));
}, },
/** /**
@@ -219,8 +219,8 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
function assertType(needType) function assertType(needType)
util.assert(type === Ci.nsIPrefBranch.PREF_INVALID || type === needType, util.assert(type === Ci.nsIPrefBranch.PREF_INVALID || type === needType,
type === Ci.nsIPrefBranch.PREF_INT type === Ci.nsIPrefBranch.PREF_INT
? "E521: Number required after =: " + name + "=" + value ? /*L*/"E521: Number required after =: " + name + "=" + value
: "E474: Invalid argument: " + name + "=" + value); : /*L*/"E474: Invalid argument: " + name + "=" + value);
let type = this.branch.getPrefType(name); let type = this.branch.getPrefType(name);
switch (typeof value) { switch (typeof value) {
@@ -288,7 +288,7 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
*/ */
toggle: function (name) { toggle: function (name) {
util.assert(this.branch.getPrefType(name) === Ci.nsIPrefBranch.PREF_BOOL, util.assert(this.branch.getPrefType(name) === Ci.nsIPrefBranch.PREF_BOOL,
_("error.trailing", name + "!")); _("error.trailingCharacters", name + "!"));
this.set(name, !this.get(name)); this.set(name, !this.get(name));
}, },

View File

@@ -183,7 +183,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
append: { append: {
SanitizeDialogPane: SanitizeDialogPane:
<groupbox orient="horizontal" xmlns={XUL}> <groupbox orient="horizontal" xmlns={XUL}>
<caption label={config.appName + " (see :help privacy)"}/> <caption label={config.appName + /*L*/" (see :help privacy)"}/>
<grid flex="1"> <grid flex="1">
<columns><column flex="1"/><column flex="1"/></columns> <columns><column flex="1"/><column flex="1"/></columns>
<rows>{ <rows>{
@@ -204,7 +204,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
function (win) prefOverlay(branch, false, { function (win) prefOverlay(branch, false, {
append: { append: {
itemList: <> itemList: <>
<listitem xmlns={XUL} label="See :help privacy for the following:" disabled="true" style="font-style: italic; font-weight: bold;"/> <listitem xmlns={XUL} label={/*L*/"See :help privacy for the following:"} disabled="true" style="font-style: italic; font-weight: bold;"/>
{ {
template.map(ourItems(), function ([item, desc]) template.map(ourItems(), function ([item, desc])
<listitem xmlns={XUL} type="checkbox" <listitem xmlns={XUL} type="checkbox"
@@ -343,16 +343,18 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
deny: 2, deny: 2,
session: 8 session: 8
}, },
UNPERMS: Class.memoize(function () iter(this.PERMS).map(Array.reverse).toObject()), UNPERMS: Class.memoize(function () iter(this.PERMS).map(Array.reverse).toObject()),
COMMANDS: { COMMANDS: {
unset: "Unset", unset: /*L*/"Unset",
allow: "Allowed", allow: /*L*/"Allowed",
deny: "Denied", deny: /*L*/"Denied",
session: "Allowed for the current session", session: /*L*/"Allowed for the current session",
list: "List all cookies for domain", list: /*L*/"List all cookies for domain",
clear: "Clear all cookies for domain", clear: /*L*/"Clear all cookies for domain",
"clear-persistent": "Clear all persistent cookies for domain", "clear-persistent": /*L*/"Clear all persistent cookies for domain",
"clear-session": "Clear all session cookies for domain" "clear-session": /*L*/"Clear all session cookies for domain"
}, },
argPrefMap: { argPrefMap: {
@@ -414,7 +416,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
args[0] = "all"; args[0] = "all";
if (args.bang) { if (args.bang) {
dactyl.assert(args.length == 0, _("error.trailing")); dactyl.assert(args.length == 0, _("error.trailingCharacters"));
items = Object.keys(sanitizer.itemMap).filter( items = Object.keys(sanitizer.itemMap).filter(
function (k) modules.options.get("sanitizeitems").has(k)); function (k) modules.options.get("sanitizeitems").has(k));
} }

View File

@@ -59,6 +59,7 @@ var Services = Module("Services", {
this.add("stylesheet", "@mozilla.org/content/style-sheet-service;1", "nsIStyleSheetService"); this.add("stylesheet", "@mozilla.org/content/style-sheet-service;1", "nsIStyleSheetService");
this.add("subscriptLoader", "@mozilla.org/moz/jssubscript-loader;1", "mozIJSSubScriptLoader"); this.add("subscriptLoader", "@mozilla.org/moz/jssubscript-loader;1", "mozIJSSubScriptLoader");
this.add("tagging", "@mozilla.org/browser/tagging-service;1", "nsITaggingService"); this.add("tagging", "@mozilla.org/browser/tagging-service;1", "nsITaggingService");
this.add("tld", "@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService");
this.add("threading", "@mozilla.org/thread-manager;1", "nsIThreadManager"); this.add("threading", "@mozilla.org/thread-manager;1", "nsIThreadManager");
this.add("urifixup", "@mozilla.org/docshell/urifixup;1", "nsIURIFixup"); this.add("urifixup", "@mozilla.org/docshell/urifixup;1", "nsIURIFixup");
this.add("versionCompare", "@mozilla.org/xpcom/version-comparator;1", "nsIVersionComparator"); this.add("versionCompare", "@mozilla.org/xpcom/version-comparator;1", "nsIVersionComparator");

View File

@@ -321,9 +321,9 @@ var File = Class("File", {
*/ */
iterDirectory: function () { iterDirectory: function () {
if (!this.exists()) if (!this.exists())
throw Error("File does not exist"); throw Error(/*L*/"File does not exist");
if (!this.isDirectory()) if (!this.isDirectory())
throw Error("Not a directory"); throw Error(/*L*/"Not a directory");
for (let file in iter(this.directoryEntries)) for (let file in iter(this.directoryEntries))
yield File(file); yield File(file);
}, },
@@ -362,7 +362,7 @@ var File = Class("File", {
*/ */
readDirectory: function (sort) { readDirectory: function (sort) {
if (!this.isDirectory()) if (!this.isDirectory())
throw Error("Not a directory"); throw Error(/*L*/"Not a directory");
let array = [e for (e in this.iterDirectory())]; let array = [e for (e in this.iterDirectory())];
if (sort) if (sort)
@@ -515,7 +515,7 @@ var File = Class("File", {
DoesNotExist: function (path, error) ({ DoesNotExist: function (path, error) ({
path: path, path: path,
exists: function () false, exists: function () false,
__noSuchMethod__: function () { throw error || Error("Does not exist"); } __noSuchMethod__: function () { throw error || Error(/*L*/"Does not exist"); }
}), }),
defaultEncoding: "UTF-8", defaultEncoding: "UTF-8",

View File

@@ -312,9 +312,9 @@ var Styles = Module("Styles", {
<tr highlight="Title"> <tr highlight="Title">
<td/> <td/>
<td/> <td/>
<td style="padding-right: 1em;">Name</td> <td style="padding-right: 1em;"><!--L-->Name</td>
<td style="padding-right: 1em;">Filter</td> <td style="padding-right: 1em;"><!--L-->Filter</td>
<td style="padding-right: 1em;">CSS</td> <td style="padding-right: 1em;"><!--L-->CSS</td>
</tr> </tr>
<col style="min-width: 4em; padding-right: 1em;"/> <col style="min-width: 4em; padding-right: 1em;"/>
<col style="min-width: 1em; text-align: center; color: red; font-weight: bold;"/> <col style="min-width: 1em; text-align: center; color: red; font-weight: bold;"/>
@@ -377,8 +377,8 @@ var Styles = Module("Styles", {
context.fork("current", 0, this, function (context) { context.fork("current", 0, this, function (context) {
context.title = ["Current Site"]; context.title = ["Current Site"];
context.completions = [ context.completions = [
[content.location.host, "Current Host"], [content.location.host, /*L*/"Current Host"],
[content.location.href, "Current URL"] [content.location.href, /*L*/"Current URL"]
]; ];
}); });
} }
@@ -389,7 +389,7 @@ var Styles = Module("Styles", {
context.generate = function () values(group.sites); context.generate = function () values(group.sites);
context.keys.text = util.identity; context.keys.text = util.identity;
context.keys.description = function (site) this.sheets.length + " sheet" + (this.sheets.length == 1 ? "" : "s") + ": " + context.keys.description = function (site) this.sheets.length + /*L*/" sheet" + (this.sheets.length == 1 ? "" : "s") + ": " +
array.compact(this.sheets.map(function (s) s.name)).join(", "); array.compact(this.sheets.map(function (s) s.name)).join(", ");
context.keys.sheets = function (site) group.sheets.filter(function (s) s.sites.indexOf(site) >= 0); context.keys.sheets = function (site) group.sheets.filter(function (s) s.sites.indexOf(site) >= 0);
context.keys.active = function (site) uris.some(Styles.matchFilter(site)); context.keys.active = function (site) uris.some(Styles.matchFilter(site));
@@ -434,7 +434,7 @@ var Styles = Module("Styles", {
for (let item in Iterator({ Active: true, Inactive: false })) { for (let item in Iterator({ Active: true, Inactive: false })) {
let [name, active] = item; let [name, active] = item;
context.split(name, null, function (context) { context.split(name, null, function (context) {
context.title[0] = name + " " + (title || "Sheets"); context.title[0] = /*L*/name + " " + (title || "Sheets");
context.filters.push(function (item) !!item.active == active); context.filters.push(function (item) !!item.active == active);
}); });
} }
@@ -584,7 +584,9 @@ var Styles = Module("Styles", {
} }
else if (args.completeArg == 1) { else if (args.completeArg == 1) {
if (sheet) if (sheet)
context.completions = [[sheet.css, "Current Value"]]; context.completions = [
[sheet.css, _("option.currentValue")]
];
context.fork("css", 0, modules.completion, "css"); context.fork("css", 0, modules.completion, "css");
} }
}, },

View File

@@ -363,7 +363,9 @@ var Template = Module("Template", {
// <e4x> // <e4x>
return <table> return <table>
<tr style="text-align: left;" highlight="Title"> <tr style="text-align: left;" highlight="Title">
<th colspan="2">jump</th><th>title</th><th>URI</th> <th colspan="2"><!--L-->Jump</th>
<th><!--L-->Title</th>
<th><!--L-->URI</th>
</tr> </tr>
{ {
this.map(Iterator(elems), function ([idx, val]) this.map(Iterator(elems), function ([idx, val])
@@ -494,7 +496,7 @@ var Template = Module("Template", {
let (name = item.name || item.names[0], frame = item.definedAt) let (name = item.name || item.names[0], frame = item.definedAt)
!frame ? name : !frame ? name :
template.helpLink(help(item), name, "Title") + template.helpLink(help(item), name, "Title") +
<span highlight="LinkInfo" xmlns:dactyl={NS}>Defined at {sourceLink(frame)}</span> <span highlight="LinkInfo" xmlns:dactyl={NS}><!--L-->Defined at {sourceLink(frame)}</span>
}</span> }</span>
</td> </td>
{ item.columns ? template.map(item.columns, function (c) <td>{c}</td>) : "" } { item.columns ? template.map(item.columns, function (c) <td>{c}</td>) : "" }

View File

@@ -182,12 +182,12 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
// check for chars not in the accepted range // check for chars not in the accepted range
this.assert(RegExp("^[" + accepted + "-]+$").test(list), this.assert(RegExp("^[" + accepted + "-]+$").test(list),
_("error.charsOutsideRange", accepted.quote())); _("error.charactersOutsideRange", accepted.quote()));
// check for illegal ranges // check for illegal ranges
for (let [match] in this.regexp.iterate(/.-./g, list)) for (let [match] in this.regexp.iterate(/.-./g, list))
this.assert(match.charCodeAt(0) <= match.charCodeAt(2), this.assert(match.charCodeAt(0) <= match.charCodeAt(2),
_("error.invalidCharRange", list.slice(list.indexOf(match)))); _("error.invalidCharacterRange", list.slice(list.indexOf(match))));
return RegExp("[" + util.regexp.escape(list) + "]"); return RegExp("[" + util.regexp.escape(list) + "]");
}, },
@@ -309,7 +309,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
else if (char === "]") { else if (char === "]") {
stack.pop(); stack.pop();
util.assert(stack.length, "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) obj[char];
@@ -328,7 +328,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
if (end < format.length) if (end < format.length)
stack.top.elements.push(format.substr(end)); stack.top.elements.push(format.substr(end));
util.assert(stack.length === 1, "Unmatched %[ in format"); util.assert(stack.length === 1, /*L*/"Unmatched %[ in format");
return stack.top; return stack.top;
}, },
@@ -375,7 +375,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
else if (close) { else if (close) {
stack.pop(); stack.pop();
util.assert(stack.length, "Unmatched %] in macro"); util.assert(stack.length, /*L*/"Unmatched %] in macro");
} }
else { else {
let [, flags, name] = /^((?:[a-z]-)*)(.*)/.exec(macro); let [, flags, name] = /^((?:[a-z]-)*)(.*)/.exec(macro);
@@ -402,7 +402,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
if (end < macro.length) if (end < macro.length)
stack.top.elements.push(macro.substr(end)); stack.top.elements.push(macro.substr(end));
util.assert(stack.length === 1, "Unmatched <{ in macro"); util.assert(stack.length === 1, /*L*/"Unmatched <{ in macro");
return stack.top; return stack.top;
}, },
@@ -759,12 +759,12 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
[hours, minutes] = div(minutes, 60); [hours, minutes] = div(minutes, 60);
[days, hours] = div(hours, 24); [days, hours] = div(hours, 24);
if (days) if (days)
return days + " days " + hours + " hours" return /*L*/days + " days " + hours + " hours"
if (hours) if (hours)
return hours + "h " + minutes + "m"; return /*L*/hours + "h " + minutes + "m";
if (minutes) if (minutes)
return minutes + ":" + pad(2, seconds); return /*L*/minutes + ":" + pad(2, seconds);
return seconds + "s"; return /*L*/seconds + "s";
}, },
/** /**
@@ -1246,7 +1246,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
let sentinel = "(function DactylOverlay() {}())" let sentinel = "(function DactylOverlay() {}())"
value.toString = function toString() toString.toString.call(this).replace(/\}?$/, sentinel + "; $&"); value.toString = function toString() toString.toString.call(this).replace(/\}?$/, sentinel + "; $&");
value.toSource = function toSource() toString.toSource.call(this).replace(/\}?$/, sentinel + "; $&"); value.toSource = function toSource() toSource.toSource.call(this).replace(/\}?$/, sentinel + "; $&");
delete desc.value; delete desc.value;
delete desc.writable; delete desc.writable;
@@ -1694,7 +1694,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
do { do {
mainThread.processNextEvent(!flush); mainThread.processNextEvent(!flush);
if (util.interrupted) if (util.interrupted)
throw new Error("Interrupted"); throw Error("Interrupted");
} }
while (flush === true && mainThread.hasPendingEvents()); while (flush === true && mainThread.hasPendingEvents());
} }

View File

@@ -9,6 +9,7 @@
[dactyl|highlight~=hints] { [dactyl|highlight~=hints] {
-moz-binding: url(resource://dactyl-content/bindings.xml#hints) !important; -moz-binding: url(resource://dactyl-content/bindings.xml#hints) !important;
position: static !important;
} }
[dactyl|highlight~=HintImage], [dactyl|highlight~=HintImage],

View File

@@ -301,7 +301,7 @@ var tests = {
}, },
if: {}, // Skip for now if: {}, // Skip for now
javascript: { javascript: {
noOutput: ["''", "'\\n'", "<pre>foo bar</pre>", "window"], noOutput: ["''", "'\\n'", "<pre>foo bar</pre>", "window", "<<EOF\n''\nEOF"],
completions: [ completions: [
["", hasItems], ["", hasItems],
["window", hasItems], ["window", hasItems],
@@ -545,7 +545,7 @@ var tests = {
set: { set: {
multiOutput: [ multiOutput: [
"vb?", "cpt?", "messages?", "titlestring?", "au?", "eht?", "vb?", "cpt?", "messages?", "titlestring?", "au?", "eht?",
"cpt", "messages", "titlestring", "au", "eht" "cpt", "messages", "titlestring", "au", "eht", "! "
], ],
noOutput: ["vb", "novb"], noOutput: ["vb", "novb"],
completions: [ completions: [

View File

@@ -31,7 +31,7 @@ var options = {};
function testCompleters() { function testCompleters() {
for (var option in dactyl.modules.options) for (var option in dactyl.modules.options)
for (var [,value] in Iterator([""].concat(options[option.name] || []))) { for (var [, value] in Iterator([""].concat(options[option.name] || []))) {
dump("OPT COMP " + option.name + " " + value + "\n"); dump("OPT COMP " + option.name + " " + value + "\n");
dactyl.testCompleter(option, "completer", value, "Option '" + option.name + "' completer failed"); dactyl.testCompleter(option, "completer", value, "Option '" + option.name + "' completer failed");
} }

View File

@@ -661,7 +661,7 @@ const Player = Module("player", {
let arg = args[0]; let arg = args[0];
dactyl.assert(arg, _("error.argumentRequired")); dactyl.assert(arg, _("error.argumentRequired"));
dactyl.assert(/^[+-]?\d+$/.test(arg), _("error.trailing")); dactyl.assert(/^[+-]?\d+$/.test(arg), _("error.trailingCharacters"));
let level = parseInt(arg, 10) / 100; let level = parseInt(arg, 10) / 100;

View File

@@ -6,7 +6,7 @@ FIREFOX ?= firefox
HOSTAPP ?= $(FIREFOX) HOSTAPP ?= $(FIREFOX)
PROFILEPATHS ?= "$$HOME/.mozilla/firefox" \ PROFILEPATHS ?= "$$HOME/.mozilla/firefox" \
"$$HOME/Library/Application Support/Firefox" \ "$$HOME/Library/Application Support/Firefox" \
"$$APPDATA/Mozilla/Firefox" \ "$$APPDATA/Mozilla/Firefox/Profiles" \
"$$AppData/Mozilla/Firefox" "$$AppData/Mozilla/Firefox/Profiles"
include ../common/Makefile include ../common/Makefile

View File

@@ -108,6 +108,7 @@
- Added several new options, including -javascript, to :abbreviate and - Added several new options, including -javascript, to :abbreviate and
:map. [b2] :map. [b2]
- Added :mksyntax command to auto-generate Vim syntax files. [b4] - Added :mksyntax command to auto-generate Vim syntax files. [b4]
- Added 's' flag to :pageinfo command. [b7]
- Added :pintab and :unpintab commands. [b7] - Added :pintab and :unpintab commands. [b7]
- :open now only opens files beginning with /, ./, ../, or ~/ [b1] - :open now only opens files beginning with /, ./, ../, or ~/ [b1]
- :saveas now provides completions for default file names, and - :saveas now provides completions for default file names, and
@@ -133,6 +134,7 @@
- CSS property name completion is now available. [b4] - CSS property name completion is now available. [b4]
- :delstyle, :styleenable, :styledisable and :styletoggle accept a ! - :delstyle, :styleenable, :styledisable and :styletoggle accept a !
to operate on all styles. [b6] to operate on all styles. [b6]
- Added Find group. [b7]
• IMPORTANT option changes: • IMPORTANT option changes:
- Option value quoting has changed. List options will - Option value quoting has changed. List options will
no longer be split at quoted commas and the option name, no longer be split at quoted commas and the option name,
@@ -178,9 +180,12 @@
- Replaced 'focuscontent' with 'strictfocus'. [b1] - Replaced 'focuscontent' with 'strictfocus'. [b1]
- 'complete' now defaults to "slf" but file completion only - 'complete' now defaults to "slf" but file completion only
triggers when the URL begins as above. [b1] triggers when the URL begins as above. [b1]
- Added 's' flag to 'pageinfo' and changed default value. [b7]
- Added 'passkeys' option. [b3] - Added 'passkeys' option. [b3]
- Added 'passunknown' option. [b7]
- Changed 'urlseparator' default value to "|". [b3] - Changed 'urlseparator' default value to "|". [b3]
- Added "passwords" and "venkman" dialogs to :dialog. [b2] - Added "passwords" and "venkman" dialogs to :dialog. [b2]
- Make 'showmode' a stringlist option. [b7]
- Added 'wildanchor' option. [b2] - Added 'wildanchor' option. [b2]
- Added 'cookies', 'cookieaccept', and 'cookielifetime' options. [b3] - Added 'cookies', 'cookieaccept', and 'cookielifetime' options. [b3]
• Added BookmarkChange, BookmarkRemove autocommands. [b2] • Added BookmarkChange, BookmarkRemove autocommands. [b2]