1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-22 23:07:59 +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>
<tr highlight="Title">
<td/>
<td style="padding-right: 1em;">Mode</td>
<td style="padding-right: 1em;">Abbrev</td>
<td style="padding-right: 1em;">Replacement</td>
<td style="padding-right: 1em;"><!--L-->Mode</td>
<td style="padding-right: 1em;"><!--L-->Abbrev</td>
<td style="padding-right: 1em;"><!--L-->Replacement</td>
</tr>
<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
if (list.*.length() === list.text().length() + 2)
dactyl.echomsg(_("abbrev.none"));
dactyl.echomsg(_("abbreviation.none"));
else
commandline.commandOutput(list);
}
@@ -301,7 +301,7 @@ var Abbreviations = Module("abbreviations", {
if (args.bang)
args["-group"].clear(modes);
else if (!args["-group"].remove(modes, args[0]))
return dactyl.echoerr(_("abbrev.noSuch"));
return dactyl.echoerr(_("abbreviation.noSuch"));
}, {
argCount: "?",
bang: true,

View File

@@ -404,7 +404,7 @@ var Bookmarks = Module("bookmarks", {
let frames = buffer.allFrames();
if (!args.bang)
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))];
context.keys.text = "title";
context.keys.description = "url";
@@ -464,7 +464,7 @@ var Bookmarks = Module("bookmarks", {
context.title = ["Page URL"];
let frames = buffer.allFrames();
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))];
return;
}
@@ -511,7 +511,7 @@ var Bookmarks = Module("bookmarks", {
function (resp) {
if (resp && resp.match(/^y(es)?$/i)) {
bookmarks.remove(Object.keys(bookmarkcache.bookmarks));
dactyl.echomsg(_("bookmark.allGone"));
dactyl.echomsg(_("bookmark.allDeleted"));
}
});
else {
@@ -626,7 +626,7 @@ var Bookmarks = Module("bookmarks", {
if (item && item.url.indexOf("%s") > -1)
context.fork("keyword/" + keyword, keyword.length + space.length, null, function (context) {
context.format = history.format;
context.title = [keyword + " Quick Search"];
context.title = [/*L*/keyword + " Quick Search"];
// context.background = true;
context.compare = CompletionContext.Sort.unsorted;
context.generate = function () {
@@ -671,7 +671,7 @@ var Bookmarks = Module("bookmarks", {
return;
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.compare = CompletionContext.Sort.unsorted;
ctxt.filterFunc = null;

View File

@@ -75,7 +75,7 @@ var Buffer = Module("buffer", {
}
if (!verbose && nFeed)
yield nFeed + " feed" + (nFeed > 1 ? "s" : "");
yield nFeed + /*L*/" feed" + (nFeed > 1 ? "s" : "");
});
this.addPageInfoSection("g", "General Info", function (verbose) {
@@ -110,7 +110,7 @@ var Buffer = Module("buffer", {
if (!verbose) {
if (pageSize[0])
yield (pageSize[1] || pageSize[0]) + " bytes";
yield (pageSize[1] || pageSize[0]) + /*L*/" bytes";
yield lastMod;
return;
}
@@ -141,6 +141,41 @@ var Buffer = Module("buffer", {
.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) {
let elem = event.originalTarget;
buffer.viewSource([elem.getAttribute("href"), Number(elem.getAttribute("line"))]);
@@ -544,9 +579,7 @@ var Buffer = Module("buffer", {
* @property {nsISelectionController} The current document's selection
* controller.
*/
get selectionController() config.browser.docShell
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController),
get selectionController() util.selectionController(this.focusedFrame),
/**
* Opens the appropriate context menu for *elem*.
@@ -572,7 +605,7 @@ var Buffer = Module("buffer", {
try {
window.urlSecurityCheck(uri.spec, doc.nodePrincipal);
io.CommandFileMode("Save link: ", {
io.CommandFileMode(_("buffer.prompt.saveLink") + " ", {
onSubmit: function (path) {
let file = io.File(path);
if (file.exists() && file.isDirectory())
@@ -796,7 +829,7 @@ var Buffer = Module("buffer", {
* @param {Node} elem The element to query.
*/
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)),
scrollPages: deprecated("buffer.scrollHorizontal", function scrollPages(pages) buffer.scrollVertical("pages", pages)),
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")
.localize("title"),
@@ -1090,13 +1123,13 @@ var Buffer = Module("buffer", {
var names = [];
if (node.title)
names.push([node.title, "Page Name"]);
names.push([node.title, /*L*/"Page Name"]);
if (node.alt)
names.push([node.alt, "Alternate Text"]);
names.push([node.alt, /*L*/"Alternate Text"]);
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"]);
@@ -1249,7 +1282,7 @@ var Buffer = Module("buffer", {
// FIXME: arg handling is a bit of a mess, check for filename
dactyl.assert(!arg || arg[0] == ">" && !util.OS.isWindows,
_("error.trailing"));
_("error.trailingCharacters"));
prefs.withContext(function () {
if (arg) {
@@ -1428,7 +1461,7 @@ var Buffer = Module("buffer", {
level = Math.constrain(level, Buffer.ZOOM_MIN, Buffer.ZOOM_MAX);
}
else
dactyl.assert(false, _("error.trailing"));
dactyl.assert(false, _("error.trailingCharacters"));
buffer.setZoom(level, args.bang);
},
@@ -1499,7 +1532,7 @@ var Buffer = Module("buffer", {
i = i + 1;
return {
text: [i + ": " + (tab.label || "(Untitled)"), i + ": " + url],
text: [i + ": " + (tab.label || /*L*/"(Untitled)"), i + ": " + url],
tab: tab,
id: i - 1,
url: url,
@@ -1850,7 +1883,7 @@ var Buffer = Module("buffer", {
options.add(["pageinfo", "pa"],
"Define which sections are shown by the :pageinfo command",
"charlist", "gfm",
"charlist", "gsfm",
{ get values() values(buffer.pageInfo).toObject() });
options.add(["scroll", "scr"],

View File

@@ -301,7 +301,7 @@ var CommandWidgets = Class("CommandWidgets", {
});
var CommandMode = Class("CommandMode", {
init: function init() {
init: function CM_init() {
this.keepCommand = userContext.hidden_option_command_afterimage;
},
@@ -311,9 +311,9 @@ var CommandMode = Class("CommandMode", {
get prompt() this.widgets.prompt,
set prompt(val) this.widgets.prompt = val,
open: function (command) {
open: function CM_open(command) {
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;
modes.push(this.mode, this.extendedMode, this.closure);
@@ -341,7 +341,7 @@ var CommandMode = Class("CommandMode", {
get widgets() commandline.widgets,
enter: function (stack) {
enter: function CM_enter(stack) {
commandline.commandSession = this;
if (stack.pop && 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) {
commandline.commandSession = null;
this.input.dactylKeyPress = undefined;
@@ -375,7 +375,7 @@ var CommandMode = Class("CommandMode", {
},
events: {
input: function onInput(event) {
input: function CM_onInput(event) {
if (this.completions) {
this.resetCompletions();
@@ -383,7 +383,7 @@ var CommandMode = Class("CommandMode", {
}
this.onChange(commandline.command);
},
keyup: function onKeyUp(event) {
keyup: function CM_onKeyUp(event) {
let key = events.toString(event);
if (/-?Tab>$/.test(key) && this.completions)
this.completions.tabTimer.flush();
@@ -392,7 +392,7 @@ var CommandMode = Class("CommandMode", {
keepCommand: false,
onKeyPress: function onKeyPress(events) {
onKeyPress: function CM_onKeyPress(events) {
if (this.completions)
this.completions.previewClear();
@@ -407,7 +407,7 @@ var CommandMode = Class("CommandMode", {
onSubmit: function (value) {},
resetCompletions: function resetCompletions() {
resetCompletions: function CM_resetCompletions() {
if (this.completions) {
this.completions.context.cancelAll();
this.completions.wildIndex = -1;
@@ -426,12 +426,12 @@ var CommandExMode = Class("CommandExMode", CommandMode, {
prompt: ["Normal", ":"],
complete: function complete(context) {
complete: function CEM_complete(context) {
context.fork("ex", 0, completion, "ex");
},
onSubmit: function onSubmit(command) {
contexts.withContext({ file: "[Command Line]", line: 1 },
onSubmit: function CEM_onSubmit(command) {
contexts.withContext({ file: /*L*/"[Command Line]", line: 1 },
function _onSubmit() {
io.withSavedValues(["readHeredoc"], function _onSubmit() {
this.readHeredoc = commandline.readHeredoc;
@@ -449,7 +449,7 @@ var CommandPromptMode = Class("CommandPromptMode", CommandMode, {
init.supercall(this);
},
complete: function (context) {
complete: function CPM_complete(context) {
if (this.completer)
context.forkapply("prompt", 0, this, "completer", Array.slice(arguments, 1));
},
@@ -586,6 +586,9 @@ var CommandLine = Module("commandline", {
get completionList() {
let node = this.widgets.active.commandline;
if (this.commandSession && this.commandSession.completionList)
node = document.getElementById(this.commandSession.completionList);
if (!node.completionList) {
let elem = document.getElementById("dactyl-completions-" + node.id);
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.
*/
commandOutput: function commandOutput(xml) {
XML.ignoreWhitespace = false;
XML.prettyPrinting = false;
XML.ignoreWhitespace = XML.prettyPrinting = false;
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
this.echo(xml, this.HIGHLIGHT_NORMAL, this.FORCE_MULTILINE);
this.command = null;
@@ -1627,7 +1629,7 @@ var ItemList = Class("ItemList", {
_init: function _init() {
this._div = this._dom(
<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 highlight="Completions">
{

View File

@@ -197,7 +197,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
argCount: "*",
completer: function (context, args) {
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 = {};
context.completions = array(item.description.toLowerCase().split(/[()\s]+/)
for (item in params.iterate(args)))
@@ -605,6 +605,10 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* Initialize the help system.
*/
initHelp: function (force) {
// Waits for the add-on to become available, if necessary.
config.addon;
config.version;
if (force || !this.helpInitialized) {
if ("noscriptOverlay" in window) {
noscriptOverlay.safeAllow("chrome-data:", true, false);
@@ -685,7 +689,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
unescape(encodeURI( // UTF-8 handling hack.
<document xmlns={NS}
name="plugins" title={config.appName + " Plugins"}>
<h1 tag="using-plugins">Using Plugins</h1>
<h1 tag="using-plugins"><!--L-->Using Plugins</h1>
<toc start="2"/>
{body}
@@ -1010,7 +1014,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
<description>{
obj.description ? br + <p>{template.linkifyHelp(obj.description.replace(/\.?$/, "."), true)}</p> : "" }{
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>
</item></>;
@@ -1073,7 +1077,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* These are set and accessed with the "g:" prefix.
*/
_globalVariables: {},
globalVariables: deprecated("the options system", {
globalVariables: deprecated(/*L*/"the options system", {
get: function globalVariables() this._globalVariables
}),
@@ -1160,7 +1164,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
onExecute: function onExecute(event) {
let cmd = event.originalTarget.getAttribute("dactyl-execute");
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(
<table>
<tr highlight="Title" align="left">
<th colspan="3">Code execution summary</th>
<th colspan="3"><!--L-->Code execution summary</th>
</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>

View File

@@ -243,7 +243,7 @@ var Editor = Module("editor", {
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);
},
@@ -272,10 +272,10 @@ var Editor = Module("editor", {
column = 1 + pre.replace(/[^]*\n/, "").length;
}
else {
var editor = window.GetCurrentEditor ? GetCurrentEditor()
: Editor.getEditor(document.commandDispatcher.focusedWindow);
dactyl.assert(editor);
text = Array.map(editor.rootElement.childNodes, function (e) util.domToString(e, true)).join("");
var editor_ = window.GetCurrentEditor ? GetCurrentEditor()
: Editor.getEditor(document.commandDispatcher.focusedWindow);
dactyl.assert(editor_);
text = Array.map(editor_.rootElement.childNodes, function (e) util.domToString(e, true)).join("");
}
let origGroup = textBox && textBox.getAttributeNS(NS, "highlight") || "";
@@ -312,16 +312,16 @@ var Editor = Module("editor", {
if (textBox)
textBox.value = val;
else {
while (editor.rootElement.firstChild)
editor.rootElement.removeChild(editor.rootElement.firstChild);
editor.rootElement.innerHTML = val;
while (editor_.rootElement.firstChild)
editor_.rootElement.removeChild(editor_.rootElement.firstChild);
editor_.rootElement.innerHTML = val;
}
}
try {
var tmpfile = io.createTempFile();
if (!tmpfile)
throw Error("Couldn't create temporary file");
throw Error(/*L*/"Couldn't create temporary file");
if (textBox) {
highlight.highlightNode(textBox, origGroup + " EditorEditing");
@@ -329,7 +329,7 @@ var Editor = Module("editor", {
}
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");
var lastUpdate = Date.now();

View File

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

View File

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

View File

@@ -472,7 +472,7 @@ var HintSession = Class("HintSession", CommandMode, {
else if (n)
hints.setClass(elem, n % 2);
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--)
this.timeout(next, 50);
@@ -1189,7 +1189,7 @@ var Hints = Module("hints", {
"XPath or CSS selector strings of hintable elements for extended hint modes",
"regexpmap", {
"[iI]": "img",
"[asOTivVWy]": ["a[href]", "area[href]", "img[src]", "iframe[src]"],
"[asOTvVWy]": ["a[href]", "area[href]", "img[src]", "iframe[src]"],
"[f]": "body",
"[F]": ["body", "code", "div", "html", "p", "pre", "span"],
"[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",
completer: function (context, args) {
context.compare = CompletionContext.Sort.unsorted;
return array.flatten([
return /*L*/array.flatten([
"annotation",
"date",
"date added",

View File

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

View File

@@ -146,7 +146,7 @@ var Marks = Module("marks", {
let mark = (this._localMarks.get(this.localURI) || {})[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);
}
else
@@ -249,7 +249,7 @@ var Marks = Module("marks", {
"Mark current location within the web page",
function (args) {
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"));
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() {
modes.reset();
@@ -278,9 +323,13 @@ var Modes = Module("modes", {
// show the current mode string in the command line
show: function show() {
if (!loaded.modes)
return;
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();
if (msg || loaded.commandline)
commandline.widgets.mode = msg || null;
},
@@ -397,19 +446,22 @@ var Modes = Module("modes", {
while (this._modeStack.length > 1 && this.main != mode) {
let a = this._modeStack.pop();
this.set(this.topOfStack.main, this.topOfStack.extended, this.topOfStack.params,
update({ pop: a }, args || {}));
update({ pop: a },
args || {}));
if (mode == null)
return;
}
},
replace: function replace(mode, oldMode) {
replace: function replace(mode, oldMode, args) {
while (oldMode && this._modeStack.length > 1 && this.main != oldMode)
this.pop();
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);
},
@@ -452,7 +504,7 @@ var Modes = Module("modes", {
this === obj || this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj,
allBases: Class.memoize(function () {
let seen = {}, res = [], queue = this.bases;
let seen = {}, res = [], queue = this.bases.slice();
for (let mode in array.iterValues(queue))
if (!set.add(seen, mode)) {
res.push(mode);
@@ -552,45 +604,47 @@ var Modes = Module("modes", {
function () { events.feedkeys("<Esc>"); });
},
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",
"stringlist", "!text_edit,!input,base",
{
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)])
});
opts);
options.add(["showmode", "smd"],
"Show the current mode in the command line when it matches this expression",
"regexplist", "!^normal$",
{ regexpFlags: "i" });
"stringlist", "caret,output_multiline,!normal,base",
opts);
},
prefs: function initPrefs() {
prefs.watch("accessibility.browsewithcaret", function () modes.onCaretChange.apply(modes, arguments));

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "dactyl://content/dtd">
<!DOCTYPE document SYSTEM "dactyl://content/modes.dtd">
<document
name="map"
@@ -75,6 +75,15 @@
saved via the <ex>:mk&dactyl.name;rc</ex> command.
</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>
<item>

View File

@@ -1,13 +1,12 @@
# TODO: normalize this debacle of Vim legacy messages
# : are we losing the error code prefixes? --djk
abbrev.noSuch = No such abbreviation
abbrev.none = No abbreviations found
abbreviation.noSuch = No such abbreviation
abbreviation.none = No abbreviations found
addon.check-1 = Checking updates for addons: %S
addon.cantInstallDir-1 = Cannot install a directory: %S
addon.unavailable = Don't have add-on yet
addon.uknownCommand = Unknown command
addon.unknownCommand = Unknown command
addon.commandNotAllowed = Command not allowed
addon.installingUpdates-1 = Installing updates for addons: %S
addon.noUpdates = No addon updates found
@@ -15,9 +14,9 @@ addon.error-3 = Add-on %S %S: %S
addon.action.On = On 
addon.action.Off = Off
addon.action.Del = Del
addon.action.Upd = Upd
addon.action.Opt = Opt
addon.action.Delete = Del
addon.action.Update = Upd
addon.action.Options = Opt
AddonManager.ERROR_NETWORK_FAILURE = A network error occurred
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.none = No bookmarks set
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.added-1 = Added bookmark: %S
bookmark.deleted-1 = %S bookmark(s) deleted
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.fewerTabs-1 = %S fewer tabs
buffer.cantDetatchLast = Can't detach the last tab
@@ -50,12 +50,15 @@ buffer.noClosed = No matching closed tab
buffer.noAlternate = No alternate page
buffer.backgroundLoaded = Background tab loaded: %S
# TODO: categorise these
buffer.noTitle = [No Title]
buffer.noName = [No Name]
buffer.help = [Help]
buffer.bookmarked = bookmarked
buffer.prompt.uploadFile = Upload file:
buffer.prompt.saveLink = Save link:
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.conditional.illegal = Invalid use of conditional
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.undefinedVar-1 = E121: Undefined variable: %S
command.let.invalidExpression-1 = E15: Invalid expression: %S
command.yank.yankedLine-1 = Yanked %S line
command.yank.yankedLines-1 = Yanked %S lines
command.let.noSuch-1 = E108: No such variable: %S
command.let.undefinedVar-1 = E121: Undefined variable: %S
command.let.unexpectedChar = E18: Unexpected characters in :let
command.run.noPrevious = E34: No previous command
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.numberRequired-2 = E521: Number required after =: %S=%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.waitingForKeyPress = Waiting for key press
@@ -117,9 +121,9 @@ dactyl.yank-1 = Yank %S
dialog.notAvailable-1 = Dialog %S not available
# TODO: merge with addon.*?
download.uknownCommand = Unknown command
download.unknownCommand = Unknown command
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.Remove = Remove
@@ -128,7 +132,6 @@ download.action.Retry = Retry
download.action.Cancel = Cancel
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]):
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-2 = Searching for %S in %S
io.downloadFinished-2 = Download of %S to %S finished
io.shellReturn-1 = shell returned %S
macro.canceled-1 = Canceled playback of 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.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-1 = No such option: %S
option.replaceExisting-1 = Warning: %S already exists: replacing existing option
option.intRequired = Integer value required
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.defaultValue = Default Value
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
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.guioptions.safeSet = See 'guioptions' scrollbar flags.
option.showtabline.safeSet = See 'showtabline' option.
option.visualbell.safeSet = See 'visualbell' option.
pageinfo.s.ownerUnverified = %S (unverified)
plugin.searchingFor-1 = Searching for %S
plugin.searchingForIn-2 = Searching for %S in %S
plugin.notReplacingContext-1 = Not replacing plugin context for %S
@@ -269,8 +281,8 @@ error.error-1 = Error: %S
error.interrupted = Interrupted
error.invalidSort-1 = Invalid sort order: %S
error.missingQuote-1 = E114: Missing quote: %S
error.trailing = Trailing characters
error.trailing-1 = Trailing characters: %S
error.trailingCharacters = Trailing characters
error.trailingCharacters-1 = Trailing characters: %S
error.invalid-1 = Invalid %S
error.invalidArgument = Invalid argument
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.nullComputedStyle-1 = Computed style is null: %S
error.syntaxError = Syntax error
error.charsOutsideRange-1 = Character list outside the range %S
error.invalidCharRange = Invalid character range: %S
error.charactersOutsideRange-1 = Character list outside the range %S
error.invalidCharacterRange = Invalid character range: %S
error.notWriteable-2 = Could not write to %S: %S
warn.deprecated-2 = %S is deprecated: Please use %S instead.

View File

@@ -635,7 +635,7 @@
<spec>'extendedhinttags' 'eht'</spec>
<strut/>
<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,code,div,html,p,pre,span,
[iI]:img,
@@ -1103,6 +1103,7 @@
<dt>g</dt> <dd>General info</dd>
<dt>f</dt> <dd>Feeds</dd>
<dt>m</dt> <dd>Meta tags</dd>
<dt>s</dt> <dd>Security information</dd>
</dl>
<p>
@@ -1142,6 +1143,21 @@
</description>
</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>
<tags>'pps' 'popups'</tags>
<spec>'popups' 'pps'</spec>
@@ -1329,13 +1345,17 @@
</item>
<item>
<tags>'nosmd' 'noshowmode'</tags>
<tags>'smd' 'showmode'</tags>
<spec>'showmode' 'smd'</spec>
<type>&option.showmode.type;</type>
<default>&option.showmode.default;</default>
<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>
</item>

View File

@@ -92,7 +92,7 @@
<note>
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>.
Conversely, <em>host</em> and <em>options</em> are never cleared
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>ErrorMsg</dt> <dd>Error messages</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>Function</dt> <dd>A JavaScript Function object</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>
<item>
<tags>pin pintab</tags>
<tags>:pin :pintab</tags>
<spec><oa>count</oa>pin<oa>tab</oa><oa>!</oa> <oa>arg</oa></spec>
<description>
<p>
@@ -396,7 +396,7 @@
</item>
<item>
<tags>unpin unpintab</tags>
<tags>:unpin :unpintab</tags>
<spec><oa>count</oa>pin<oa>tab</oa> <oa>arg</oa></spec>
<description>
<p>

View File

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

View File

@@ -142,6 +142,7 @@ function defineModule(name, params, module) {
use[mod].push(module);
}
currentModule = module;
module.startTime = Date.now();
}
defineModule.loadLog = [];
@@ -163,7 +164,6 @@ defineModule.dump = function dump_() {
.replace(/^./gm, name + ": $&"));
}
defineModule.modules = [];
defineModule.times = { all: 0 };
defineModule.time = function time(major, minor, func, self) {
let time = Date.now();
if (typeof func !== "function")
@@ -176,13 +176,7 @@ defineModule.time = function time(major, minor, func, self) {
loaded.util && util.reportError(e);
}
let delta = 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;
}
JSMLoader.times.add(major, minor, Date.now() - time);
return res;
}
@@ -211,7 +205,7 @@ function require(obj, name, from) {
if (loaded.util)
util.reportError(e);
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",
"array", "bind", "call", "callable", "ctypes", "curry", "debuggerProperties", "defineModule",
"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"
],
use: ["config", "services", "util"]
@@ -479,9 +473,13 @@ function curry(fn, length, self, acc) {
}
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
var bind = function bind(func, self) {
if (!callable(func))
func = self[func];
let args = Array.slice(arguments, bind.length);
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;
},
// Should be made thread safe.
load: function load() {
let bookmarks = {};

View File

@@ -32,6 +32,26 @@ else
manager: Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar),
stale: JSMLoader ? JSMLoader.stale : {},
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) {
this.initialized = true;
this.suffix = suffix || "";
@@ -41,6 +61,7 @@ else
this.global.JSMLoader = this;
base.JSMLoader = this;
},
getTarget: function getTarget(url) {
if (url.indexOf(":") === -1)
url = "resource://dactyl" + this.suffix + "/" + url;
@@ -49,6 +70,7 @@ else
chan.cancel(Components.results.NS_BINDING_ABORTED);
return chan.name;
},
load: function load(name, target) {
let url = name;
if (url.indexOf(":") === -1)
@@ -68,7 +90,12 @@ else
}
try {
let now = Date.now();
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;
}
catch (e) {
@@ -76,11 +103,18 @@ else
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() {
for each (let factory in this.factories.splice(0))
this.manager.unregisterFactory(factory.classID, factory);
},
purge: function purge() {
dump("dactyl: JSMLoader: purge\n");

View File

@@ -310,7 +310,7 @@ var Command = Class("Command", {
util.assert((this.length == 0 || this.command.argCount !== "0") &&
(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.
*
* @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;
function completerToString(completer) {
if (completer)
return [k for ([k, v] in Iterator(config.completers)) if (completer == completion.closure[v])][0] || "custom";
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"));
else
commandline.commandOutput(
<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>);
commandline.commandOutput(list);
}
}),
@@ -863,7 +871,7 @@ var Commands = Module("commands", {
let [count, arg, quote] = Commands.parseArg(str, null, _keepQuotes);
if (quote == "\\" && !complete)
return [, , , _("error.trailing", "\\")];
return [, , , _("error.trailingCharacters", "\\")];
if (quote && !complete)
return [, , , _("error.missingQuote", quote)];
return [count, arg, quote];
@@ -1382,8 +1390,6 @@ var Commands = Module("commands", {
commands: function initCommands(dactyl, modules, window) {
const { commands, contexts } = modules;
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
// specified - useful?
commands.add(["com[mand]"],
"List or define commands",
function (args) {
@@ -1392,8 +1398,8 @@ var Commands = Module("commands", {
util.assert(!cmd || cmd.split(",").every(commands.validName.closure.test),
_("command.invalidName", cmd));
if (!args.literalArg)
commands.list();
if (args.length <= 1)
commands.list(cmd);
else {
util.assert(args["-group"].modifiable,
_("group.cantChangeBuiltin", _("command.commands")));
@@ -1488,7 +1494,7 @@ var Commands = Module("commands", {
},
{
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
},
{
@@ -1573,7 +1579,7 @@ var Commands = Module("commands", {
]
})),
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: {
headings: ["Command", "Group", "Description"],
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.fork("additional", 0, this, function (context) {
context.title[0] += " (additional)";
context.title[0] += /*L*/" (additional)";
context.filter = context.parent.filter; // FIXME
context.completions = context.parent.completions;
// 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", {
exports: ["ConfigBase", "Config", "config"],
require: ["services", "storage", "util", "template"],
use: ["io", "messages", "prefs"]
use: ["io", "messages", "prefs", "styles"]
}, this);
var ConfigBase = Class("ConfigBase", {
@@ -33,9 +33,12 @@ var ConfigBase = Class("ConfigBase", {
loadStyles: function loadStyles() {
const { highlight } = require("highlight");
highlight.styleableChrome = this.styleableChrome;
highlight.loadCSS(this.CSS);
highlight.loadCSS(this.helpCSS);
if (!util.haveGecko("2b"))
highlight.loadCSS(<![CDATA[
!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;
}
]]>);
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",
@@ -132,7 +154,7 @@ var ConfigBase = Class("ConfigBase", {
*/
VCSPath: Class.memoize(function () {
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 &&
uri.file.exists() &&
io.pathSearch("hg"))
@@ -159,7 +181,7 @@ var ConfigBase = Class("ConfigBase", {
"--template=hg{rev}-" + this.branch + " ({date|isodate})"]).output;
let version = this.addon.version;
if ("@DATE@" !== "@" + "DATE@")
version += " (created: @DATE@)";
version += /*L*/" (created: @DATE@)";
return version;
}),
@@ -206,7 +228,7 @@ var ConfigBase = Class("ConfigBase", {
"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() {
if (!this.helpStyled) {
const { highlight } = require("highlight");
@@ -428,7 +450,6 @@ var ConfigBase = Class("ConfigBase", {
CmdInput;.dactyl-commandline-command
CmdOutput white-space: pre;
CompGroup
CompGroup:not(:first-of-type) margin-top: .5em;
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::after content: "⌄";
Dense margin-top: 0; margin-bottom: 0;
EditorEditing;;* background: #bbb !important; -moz-user-input: none !important; -moz-user-modify: read-only !important;
EditorError;;* background: red !important;
@@ -624,7 +646,7 @@ var ConfigBase = Class("ConfigBase", {
HelpEx;;;FontCode display: inline-block; color: #527BBD;
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;
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;
HelpListItem;html|li;dactyl://help/* display: list-item;
HelpNote color: red; font-weight: bold;
HelpOpt;;;FontCode color: #106326;
@@ -708,7 +729,6 @@ var ConfigBase = Class("ConfigBase", {
HelpHead4;html|h4;dactyl://help/* {
}
HelpTab;html|dl;dactyl://help/* {
display: table;
width: 100%;

View File

@@ -137,7 +137,7 @@ var Download = Class("Download", {
if (this.timeRemaining)
this.nodes.time.textContent = util.formatSeconds(this.timeRemaining);
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 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}>
<tr highlight="DownloadHead">
<span>Title</span>
<span>Status</span>
<span><!--L-->Title</span>
<span><!--L-->Status</span>
<span/>
<span>Progress</span>
<span><!--L-->Progress</span>
<span/>
<span>Time remaining</span>
<span>Source</span>
<span><!--L-->Time remaining</span>
<span><!--L-->Source</span>
</tr>
<tr highlight="Download"><span><div style="min-height: 1ex; /* FIXME */"/></span></tr>
<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 highlight="DownloadButtons">
<a highlight="Button" key="clear">Clear</a>
<a highlight="Button" key="clear"><!--L-->Clear</a>
</td>
<td highlight="DownloadProgress" key="progress">
<span highlight="DownloadProgressHave" key="progressHave"
@@ -277,7 +277,7 @@ var DownloadList = Class("DownloadList",
let active = downloads.filter(function (dl) dl.alive).length;
if (active)
this.nodes.total.textContent = active + " active";
this.nodes.total.textContent = /*L*/active + " active";
else for (let key in values(["total", "percent", "time"]))
this.nodes[key].textContent = "";
},

View File

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

View File

@@ -116,7 +116,7 @@ var IO = Module("io", {
outer:
for (let dir in values(dirs)) {
for (let [,path] in Iterator(paths)) {
for (let [, path] in Iterator(paths)) {
let file = dir.child(path);
dactyl.echomsg(_("io.searchingFor", file.path.quote()), 3);
@@ -208,7 +208,7 @@ var IO = Module("io", {
}
catch (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)
dactyl.echoerr(message);
}
@@ -783,9 +783,13 @@ unlet s:cpo_save
commands.add(["scrip[tnames]"],
"List all sourced script names",
function () {
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?
if (!io._scriptNames.length)
dactyl.echomsg(_("command.scriptnames.none"));
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" });
@@ -831,7 +835,7 @@ unlet s:cpo_save
let result = io.system(arg);
if (result.returnValue != 0)
result.output += "\nshell returned " + result.returnValue;
result.output += "\n" + _("io.shellReturn", result.returnValue);
modules.commandline.command = "!" + arg;
modules.commandline.commandOutput(<span highlight="CmdOutput">{result.output}</span>);
@@ -981,9 +985,9 @@ unlet s:cpo_save
context.key = match.prefix;
context.advance(match.prefix.length + 1);
context.generate = function () iter({
content: "Chrome content",
locale: "Locale-specific content",
skin: "Theme-specific content"
content: /*L*/"Chrome content",
locale: /*L*/"Locale-specific content",
skin: /*L*/"Theme-specific content"
});
}
}

View File

@@ -45,7 +45,7 @@ var JavaScript = Module("javascript", {
}),
globals: Class.memoize(function () [
[this.modules.userContext, "Global Variables"],
[this.modules.userContext, /*L*/"Global Variables"],
[this.modules, "modules"],
[this.window, "window"]
]),
@@ -117,12 +117,8 @@ var JavaScript = Module("javascript", {
return cache[key];
context[JavaScript.EVAL_TMP] = tmp;
context[JavaScript.EVAL_EXPORT] = function export_(obj) cache[key] = obj;
try {
if (tmp != null) // Temporary hack until bug 609949 is fixed.
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);
cache[key] = this.modules.dactyl.userEval(arg, context, /*L*/"[Command Line Completion]", 1);
return cache[key];
}
@@ -170,7 +166,7 @@ var JavaScript = Module("javascript", {
if (this._top.char != arg) {
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
@@ -308,7 +304,7 @@ var JavaScript = Module("javascript", {
if (this._checkFunction(prev, dot, cacheKey))
return [];
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 [];
}
@@ -324,7 +320,7 @@ var JavaScript = Module("javascript", {
let end = (frame == -1 ? this._lastIdx : this._get(frame + 1).offset);
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?
if (dot < statement) // No.
dot = statement - 1;
@@ -339,7 +335,7 @@ var JavaScript = Module("javascript", {
const self = this;
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);
base.forceAnchored = true;
@@ -419,14 +415,14 @@ var JavaScript = Module("javascript", {
objects.forEach(function (obj) {
obj.ctxt_p.split(obj[1] + "/anchored", this, function (context) {
context.anchored = true;
context.title[0] += " (prototypes)";
context.title[0] += /*L*/" (prototypes)";
});
});
objects.forEach(function (obj) {
obj.ctxt_t.split(obj[1] + "/unanchored", this, function (context) {
context.anchored = false;
context.title[0] += " (substrings)";
context.title[0] += /*L*/" (substrings)";
context.filters.push(unanchored);
});
});
@@ -434,7 +430,7 @@ var JavaScript = Module("javascript", {
objects.forEach(function (obj) {
obj.ctxt_p.split(obj[1] + "/unanchored", this, function (context) {
context.anchored = false;
context.title[0] += " (prototype substrings)";
context.title[0] += /*L*/" (prototype substrings)";
context.filters.push(unanchored);
});
});
@@ -646,7 +642,6 @@ var JavaScript = Module("javascript", {
}, {
EVAL_TMP: "__dactyl_eval_tmp",
EVAL_EXPORT: "__dactyl_eval_export",
/**
* 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.globals = [
[this.context, "REPL Variables"],
[context, "REPL Global"]
[this.context, /*L*/"REPL Variables"],
[context, /*L*/"REPL Global"]
].concat(this.js.globals.filter(function ([global]) isPrototypeOf.call(global, context)));
if (!isPrototypeOf.call(modules.jsmodules, context))
@@ -790,13 +785,14 @@ var JavaScript = Module("javascript", {
this.repl = REPL(this.context);
},
open: function open(context) {
this.updatePrompt();
modules.mow.echo(this.repl);
this.widgets.message = null;
open.superapply(this, arguments);
this.updatePrompt();
},
complete: function complete(context) {
@@ -807,6 +803,8 @@ var JavaScript = Module("javascript", {
mode: modes.REPL,
get completionList() this.widgets.statusbar.commandline.id,
accept: function accept() {
dactyl.trapErrors(function () { this.repl.addOutput(this.command) }, this);

View File

@@ -448,7 +448,7 @@ var Option = Class("Option", {
regexplist: function regexplist(k, default_) {
for (let re in values(this.value))
if (re(k))
if ((re.test || re).call(re, k))
return re.result;
return arguments.length > 1 ? default_ : null;
},
@@ -619,18 +619,23 @@ var Option = Class("Option", {
stringlist: function stringlist(operator, values, scope, invert) {
values = Array.concat(values);
function uniq(ary) {
let seen = {};
return ary.filter(function (elem) !set.add(seen, elem));
}
switch (operator) {
case "+":
return array.uniq(Array.concat(this.value, values), true);
return uniq(Array.concat(this.value, values), true);
case "^":
// 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 "-":
return this.value.filter(function (item) values.indexOf(item) == -1);
return this.value.filter(function (item) !set.has(this, item), set(values));
case "=":
if (invert) {
let keepValues = this.value.filter(function (item) values.indexOf(item) == -1);
let addValues = values.filter(function (item) this.value.indexOf(item) == -1, this);
let keepValues = this.value.filter(function (item) !set.has(this, item), set(values));
let addValues = values.filter(function (item) !set.has(this, item), set(this.value));
return addValues.concat(keepValues);
}
return values;
@@ -870,7 +875,7 @@ var Options = Module("options", {
allPrefs: deprecated("prefs.getNames", function allPrefs() prefs.getNames.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)),
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)),
popContext: deprecated("prefs.popContext", function popContext() prefs.popContext.apply(prefs, arguments)),
pushContext: deprecated("prefs.pushContext", function pushContext() prefs.pushContext.apply(prefs, arguments)),
@@ -1056,7 +1061,7 @@ var Options = Module("options", {
},
{ promptHighlight: "WarningMsg" });
else if (name == "all")
commandline.commandOutput(prefs.list(onlyNonDefault, ""));
modules.commandline.commandOutput(prefs.list(onlyNonDefault, ""));
else if (reset)
prefs.reset(name);
else if (invertBoolean)
@@ -1169,7 +1174,7 @@ var Options = Module("options", {
context.advance(context.filter.indexOf("="));
if (option.type == "boolean")
return error(context.filter.length, _("error.trailing"));
return error(context.filter.length, _("error.trailingCharacters"));
context.advance(1);
if (opt.error)
@@ -1235,7 +1240,7 @@ var Options = Module("options", {
if (str.text().length() == str.*.length())
dactyl.echomsg(_("variable.none"));
else
dactyl.echo(str, commandline.FORCE_MULTILINE);
dactyl.echo(str, modules.commandline.FORCE_MULTILINE);
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)
util.assert(type === Ci.nsIPrefBranch.PREF_INVALID || type === needType,
type === Ci.nsIPrefBranch.PREF_INT
? "E521: Number required after =: " + name + "=" + value
: "E474: Invalid argument: " + name + "=" + value);
? /*L*/"E521: Number required after =: " + name + "=" + value
: /*L*/"E474: Invalid argument: " + name + "=" + value);
let type = this.branch.getPrefType(name);
switch (typeof value) {
@@ -288,7 +288,7 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
*/
toggle: function (name) {
util.assert(this.branch.getPrefType(name) === Ci.nsIPrefBranch.PREF_BOOL,
_("error.trailing", name + "!"));
_("error.trailingCharacters", name + "!"));
this.set(name, !this.get(name));
},

View File

@@ -183,7 +183,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
append: {
SanitizeDialogPane:
<groupbox orient="horizontal" xmlns={XUL}>
<caption label={config.appName + " (see :help privacy)"}/>
<caption label={config.appName + /*L*/" (see :help privacy)"}/>
<grid flex="1">
<columns><column flex="1"/><column flex="1"/></columns>
<rows>{
@@ -204,7 +204,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
function (win) prefOverlay(branch, false, {
append: {
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])
<listitem xmlns={XUL} type="checkbox"
@@ -343,16 +343,18 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
deny: 2,
session: 8
},
UNPERMS: Class.memoize(function () iter(this.PERMS).map(Array.reverse).toObject()),
COMMANDS: {
unset: "Unset",
allow: "Allowed",
deny: "Denied",
session: "Allowed for the current session",
list: "List all cookies for domain",
clear: "Clear all cookies for domain",
"clear-persistent": "Clear all persistent cookies for domain",
"clear-session": "Clear all session cookies for domain"
unset: /*L*/"Unset",
allow: /*L*/"Allowed",
deny: /*L*/"Denied",
session: /*L*/"Allowed for the current session",
list: /*L*/"List all cookies for domain",
clear: /*L*/"Clear all cookies for domain",
"clear-persistent": /*L*/"Clear all persistent cookies for domain",
"clear-session": /*L*/"Clear all session cookies for domain"
},
argPrefMap: {
@@ -414,7 +416,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef
args[0] = "all";
if (args.bang) {
dactyl.assert(args.length == 0, _("error.trailing"));
dactyl.assert(args.length == 0, _("error.trailingCharacters"));
items = Object.keys(sanitizer.itemMap).filter(
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("subscriptLoader", "@mozilla.org/moz/jssubscript-loader;1", "mozIJSSubScriptLoader");
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("urifixup", "@mozilla.org/docshell/urifixup;1", "nsIURIFixup");
this.add("versionCompare", "@mozilla.org/xpcom/version-comparator;1", "nsIVersionComparator");

View File

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

View File

@@ -312,9 +312,9 @@ var Styles = Module("Styles", {
<tr highlight="Title">
<td/>
<td/>
<td style="padding-right: 1em;">Name</td>
<td style="padding-right: 1em;">Filter</td>
<td style="padding-right: 1em;">CSS</td>
<td style="padding-right: 1em;"><!--L-->Name</td>
<td style="padding-right: 1em;"><!--L-->Filter</td>
<td style="padding-right: 1em;"><!--L-->CSS</td>
</tr>
<col style="min-width: 4em; padding-right: 1em;"/>
<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.title = ["Current Site"];
context.completions = [
[content.location.host, "Current Host"],
[content.location.href, "Current URL"]
[content.location.host, /*L*/"Current Host"],
[content.location.href, /*L*/"Current URL"]
];
});
}
@@ -389,7 +389,7 @@ var Styles = Module("Styles", {
context.generate = function () values(group.sites);
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(", ");
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));
@@ -434,7 +434,7 @@ var Styles = Module("Styles", {
for (let item in Iterator({ Active: true, Inactive: false })) {
let [name, active] = item;
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);
});
}
@@ -584,7 +584,9 @@ var Styles = Module("Styles", {
}
else if (args.completeArg == 1) {
if (sheet)
context.completions = [[sheet.css, "Current Value"]];
context.completions = [
[sheet.css, _("option.currentValue")]
];
context.fork("css", 0, modules.completion, "css");
}
},

View File

@@ -363,7 +363,9 @@ var Template = Module("Template", {
// <e4x>
return <table>
<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>
{
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)
!frame ? name :
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>
</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
this.assert(RegExp("^[" + accepted + "-]+$").test(list),
_("error.charsOutsideRange", accepted.quote()));
_("error.charactersOutsideRange", accepted.quote()));
// check for illegal ranges
for (let [match] in this.regexp.iterate(/.-./g, list))
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) + "]");
},
@@ -309,7 +309,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
}
else if (char === "]") {
stack.pop();
util.assert(stack.length, "Unmatched %] in format");
util.assert(stack.length, /*L*/"Unmatched %] in format");
}
else {
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)
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;
},
@@ -375,7 +375,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
}
else if (close) {
stack.pop();
util.assert(stack.length, "Unmatched %] in macro");
util.assert(stack.length, /*L*/"Unmatched %] in macro");
}
else {
let [, flags, name] = /^((?:[a-z]-)*)(.*)/.exec(macro);
@@ -402,7 +402,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
if (end < macro.length)
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;
},
@@ -759,12 +759,12 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
[hours, minutes] = div(minutes, 60);
[days, hours] = div(hours, 24);
if (days)
return days + " days " + hours + " hours"
return /*L*/days + " days " + hours + " hours"
if (hours)
return hours + "h " + minutes + "m";
return /*L*/hours + "h " + minutes + "m";
if (minutes)
return minutes + ":" + pad(2, seconds);
return seconds + "s";
return /*L*/minutes + ":" + pad(2, seconds);
return /*L*/seconds + "s";
},
/**
@@ -1246,7 +1246,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
let sentinel = "(function DactylOverlay() {}())"
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.writable;
@@ -1694,7 +1694,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
do {
mainThread.processNextEvent(!flush);
if (util.interrupted)
throw new Error("Interrupted");
throw Error("Interrupted");
}
while (flush === true && mainThread.hasPendingEvents());
}

View File

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

View File

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

View File

@@ -31,7 +31,7 @@ var options = {};
function testCompleters() {
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");
dactyl.testCompleter(option, "completer", value, "Option '" + option.name + "' completer failed");
}

View File

@@ -661,7 +661,7 @@ const Player = Module("player", {
let arg = args[0];
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;

View File

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

View File

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