-// Copyright (c) 2008-2011 by Kris Maglione <maglione.k@gmail.com>
+// Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-/* use strict */
+"use strict";
-Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("help", {
exports: ["help"],
require: ["cache", "dom", "protocol", "services", "util"]
-}, this);
+});
-this.lazyRequire("completion", ["completion"]);
-this.lazyRequire("overlay", ["overlay"]);
+lazyRequire("completion", ["completion"]);
+lazyRequire("overlay", ["overlay"]);
+lazyRequire("template", ["template"]);
var HelpBuilder = Class("HelpBuilder", {
init: function init() {
// Scrape the list of help files from all.xml
this.tags["all"] = this.tags["all.xml"] = "all";
- let files = this.findHelpFile("all").map(function (doc)
+ let files = this.findHelpFile("all").map(doc =>
[f.value for (f in DOM.XPath("//dactyl:include/@href", doc))]);
// Scrape the tags from the rest of the help files.
}
update(services["dactyl:"].providers, {
- "help": Loop(function (uri, path) help.files[path]),
- "help-overlay": Loop(function (uri, path) help.overlays[path]),
+ "help": Loop((uri, path) => help.files[path]),
+ "help-overlay": Loop((uri, path) => help.overlays[path]),
"help-tag": Loop(function (uri, path) {
let tag = decodeURIComponent(path);
if (tag in help.files)
{ mimeType: "text/plain;charset=UTF-8" })
.responseText;
- let re = util.regexp(UTF8(<![CDATA[
+ let re = util.regexp(UTF8(literal(/*
^ (?P<comment> \s* # .*\n)
| ^ (?P<space> \s*)
)
| (?: ^ [^\S\n]* \n) +
- ]]>), "gmxy");
+ */)), "gmxy");
let betas = util.regexp(/\[((?:b|rc)\d)\]/, "gx");
let beta = array(betas.iterate(NEWS))
- .map(function (m) m[1]).uniq().slice(-1)[0];
-
+ .map(m => m[1]).uniq().slice(-1)[0];
- default xml namespace = NS;
function rec(text, level, li) {
- XML.ignoreWhitespace = XML.prettyPrinting = false;
-
- let res = <></>;
+ let res = [];
let list, space, i = 0;
-
for (let match in re.iterate(text)) {
if (match.comment)
continue;
else if (match.char) {
if (!list)
- res += list = <ul/>;
- let li = <li/>;
- li.* += rec(match.content.replace(RegExp("^" + match.space, "gm"), ""), level + 1, li);
- list.* += li;
+ res.push(list = ["ul", {}]);
+ let li = ["li", {}];
+ li.push(rec(match.content
+ .replace(RegExp("^" + match.space, "gm"), ""),
+ level + 1,
+ li));
+ list.push(li);
}
else if (match.par) {
let [, par, tags] = /([^]*?)\s*((?:\[[^\]]+\])*)\n*$/.exec(match.par);
let t = tags;
- tags = array(betas.iterate(tags)).map(function (m) m[1]);
+ tags = array(betas.iterate(tags)).map(m => m[1]);
- let group = !tags.length ? "" :
- !tags.some(function (t) t == beta) ? "HelpNewsOld" : "HelpNewsNew";
+ let group = !tags.length ? "" :
+ !tags.some(t => t == beta) ? "HelpNewsOld" : "HelpNewsNew";
if (i === 0 && li) {
- li.@highlight = group;
+ li[1]["dactyl:highlight"] = group;
group = "";
}
list = null;
if (level == 0 && /^.*:\n$/.test(match.par)) {
let text = par.slice(0, -1);
- res += <h2 tag={"news-" + text}>{template.linkifyHelp(text, true)}</h2>;
+ res.push(["h2", { tag: "news-" + text },
+ template.linkifyHelp(text, true)]);
}
else {
let [, a, b] = /^(IMPORTANT:?)?([^]*)/.exec(par);
- res += <p highlight={group + " HelpNews"}>{
- !tags.length ? "" :
- <hl key="HelpNewsTag">{tags.join(" ")}</hl>
- }{
- a ? <hl key="HelpWarning">{a}</hl> : ""
- }{
- template.linkifyHelp(b, true)
- }</p>;
+
+ res.push(["p", { "dactyl:highlight": group + " HelpNews" },
+ !tags.length ? "" : ["hl", { key: "HelpNewsTag" }, tags.join(" ")],
+ a ? ["hl", { key: "HelpWarning" }, a] : "",
+ template.linkifyHelp(b, true)]);
}
}
i++;
}
- for each (let attr in res..@highlight) {
- attr.parent().@NS::highlight = attr;
- delete attr.parent().@highlight;
- }
+
return res;
}
- XML.ignoreWhitespace = XML.prettyPrinting = false;
let body = rec(NEWS, 0);
- for each (let li in body..li) {
- let list = li..li.(@NS::highlight == "HelpNewsOld");
- if (list.length() && list.length() == li..li.(@NS::highlight != "").length()) {
- for each (let li in list)
- li.@NS::highlight = "";
- li.@NS::highlight = "HelpNewsOld";
- }
- }
+ // E4X-FIXME
+ // for each (let li in body..li) {
+ // let list = li..li.(@NS::highlight == "HelpNewsOld");
+ // if (list.length() && list.length() == li..li.(@NS::highlight != "").length()) {
+ // for each (let li in list)
+ // li.@NS::highlight = "";
+ // li.@NS::highlight = "HelpNewsOld";
+ // }
+ // }
return '<?xml version="1.0"?>\n' +
'<?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>\n' +
- '<!DOCTYPE document SYSTEM "resource://dactyl-content/dactyl.dtd">\n' +
- <document xmlns={NS} xmlns:dactyl={NS}
- name="versions" title={config.appName + " Versions"}>
- <h1 tag="versions news NEWS">{config.appName} Versions</h1>
- <toc start="2"/>
-
- {body}
- </document>.toXMLString()
- });
+ DOM.toXML(["document", { xmlns: "dactyl", name: "versions",
+ title: config.appName + " Versions" },
+ ["h1", { tag: "versions news NEWS" }, config.appName + " Versions"],
+ ["toc", { start: "2" }],
+
+ body]);
+ }, true);
},
initialize: function initialize() {
init: function init() {
dactyl.commands["dactyl.help"] = function (event) {
let elem = event.originalTarget;
- help.help(elem.getAttribute("tag") || elem.textContent);
+ modules.help.help(elem.getAttribute("tag") || elem.textContent);
};
},
* @returns {string}
*/
findHelp: function (topic, consolidated) {
- if (!consolidated && Set.has(help.files, topic))
+ if (!consolidated && hasOwnProperty(help.files, topic))
return topic;
let items = modules.completion._runCompleter("help", topic, null, !!consolidated).items;
let partialMatch = null;
if (!topic) {
let helpFile = consolidated ? "all" : modules.options["helpfile"];
- if (Set.has(help.files, helpFile))
+ if (hasOwnProperty(help.files, helpFile))
dactyl.open("dactyl://help/" + helpFile, { from: "help" });
else
dactyl.echomsg(_("help.noFile", helpFile.quote()));
var addURIEntry = function addURIEntry(file, uri) addDataEntry(file, util.httpGet(uri).responseText);
}
else {
- var zip = services.ZipWriter(FILE, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
+ var zip = services.ZipWriter(FILE.file, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
addURIEntry = function addURIEntry(file, uri)
zip.addEntryChannel(PATH + file, TIME, 9,
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
}
- let empty = Set("area base basefont br col frame hr img input isindex link meta param"
+ let empty = RealSet("area base basefont br col frame hr img input isindex link meta param"
.split(" "));
function fix(node) {
- switch(node.nodeType) {
+ switch (node.nodeType) {
case Ci.nsIDOMNode.ELEMENT_NODE:
if (isinstance(node, [Ci.nsIDOMHTMLBaseElement]))
return;
- data.push("<"); data.push(node.localName);
+ data.push("<", node.localName);
if (node instanceof Ci.nsIDOMHTMLHtmlElement)
- data.push(" xmlns=" + XHTML.uri.quote(),
- " xmlns:dactyl=" + NS.uri.quote());
+ data.push(" xmlns=" + XHTML.quote(),
+ " xmlns:dactyl=" + NS.quote());
for (let { name, value } in array.iterValues(node.attributes)) {
if (name == "dactyl:highlight") {
- Set.add(styles, value);
+ styles.add(value);
name = "class";
value = "hl-" + value;
}
if (name == "href") {
value = node.href || value;
- if (value.indexOf("dactyl://help-tag/") == 0) {
+ if (value.startsWith("dactyl://help-tag/")) {
try {
let uri = services.io.newChannel(value, null, null).originalURI;
value = uri.spec == value ? "javascript:;" : uri.path.substr(1);
value = value.replace(/.*\//, "");
}
- data.push(" ", name, '="',
- <>{value}</>.toXMLString().replace(/"/g, """),
- '"');
+ data.push(" ", name, '="', DOM.escapeHTML(value), '"');
}
- if (node.localName in empty)
+ if (empty.has(node.localName))
data.push(" />");
else {
data.push(">");
if (node instanceof Ci.nsIDOMHTMLHeadElement)
- data.push(<link rel="stylesheet" type="text/css" href="help.css"/>.toXMLString());
+ data.push('<link rel="stylesheet" type="text/css" href="help.css"/>');
Array.map(node.childNodes, fix);
data.push("</", node.localName, ">");
}
break;
case Ci.nsIDOMNode.TEXT_NODE:
- data.push(<>{node.textContent}</>.toXMLString());
+ data.push(DOM.escapeHTML(node.textContent, true));
}
}
let { buffer, content, events } = modules;
let chromeFiles = {};
- let styles = {};
+ let styles = RealSet();
for (let [file, ] in Iterator(help.files)) {
let url = "dactyl://help/" + file;
dactyl.open(url);
- util.waitFor(function () content.location.href == url && buffer.loaded
- && content.document.documentElement instanceof Ci.nsIDOMHTMLHtmlElement,
+ util.waitFor(() => (content.location.href == url && buffer.loaded &&
+ content.document.documentElement instanceof Ci.nsIDOMHTMLHtmlElement),
15000);
events.waitForPageLoad();
var data = [
addDataEntry(file + ".xhtml", data.join(""));
}
- let data = [h for (h in highlight) if (Set.has(styles, h.class) || /^Help/.test(h.class))]
- .map(function (h) h.selector
- .replace(/^\[.*?=(.*?)\]/, ".hl-$1")
- .replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}")
+ let data = [h for (h in highlight) if (styles.has(h.class) || /^Help/.test(h.class))]
+ .map(h => h.selector
+ .replace(/^\[.*?=(.*?)\]/, ".hl-$1")
+ .replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}")
.join("\n");
addDataEntry("help.css", data.replace(/chrome:[^ ")]+\//g, ""));
})
}, {
}, {
- commands: function init_commands(dactyl, modules, window) {
+ commands: function initCommands(dactyl, modules, window) {
const { commands, completion, help } = modules;
[
});
});
},
- completion: function init_completion(dactyl, modules, window) {
+ completion: function initCompletion(dactyl, modules, window) {
const { completion } = modules;
completion.help = function completion_help(context, consolidated) {
context.keys = { text: 0, description: function () "all" };
};
},
- mappings: function init_mappings(dactyl, modules, window) {
- const { help, mappings, modes } = modules;
-
- mappings.add([modes.MAIN], ["<open-help>", "<F1>"],
- "Open the introductory help page",
- function () { help.help(); });
-
- mappings.add([modes.MAIN], ["<open-single-help>", "<A-F1>"],
- "Open the single, consolidated help page",
- function () { modules.ex.helpall(); });
- },
- javascript: function init_javascript(dactyl, modules, window) {
+ javascript: function initJavascript(dactyl, modules, window) {
modules.JavaScript.setCompleter([modules.help.exportHelp],
- [function (context, args) overlay.activeModules.completion.file(context)]);
+ [(context, args) => overlay.activeModules.completion.file(context)]);
+ },
+ options: function initOptions(dactyl, modules, window) {
+ const { options } = modules;
+
+ options.add(["helpfile", "hf"],
+ "Name of the main help file",
+ "string", "intro");
}
});
endModule();
-// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
+// vim: set fdm=marker sw=4 sts=4 ts=8 et ft=javascript: