- initHelp: function (force) {
- if (force || !this.helpInitialized) {
- if ("noscriptOverlay" in window) {
- noscriptOverlay.safeAllow("chrome-data:", true, false);
- noscriptOverlay.safeAllow("dactyl:", true, false);
- }
-
- // Find help and overlay files with the given name.
- let findHelpFile = function findHelpFile(file) {
- let result = [];
- for (let [, namespace] in Iterator(namespaces)) {
- let url = ["dactyl://", namespace, "/", file, ".xml"].join("");
- let res = util.httpGet(url);
- if (res) {
- if (res.responseXML.documentElement.localName == "document")
- fileMap[file] = url;
- if (res.responseXML.documentElement.localName == "overlay")
- overlayMap[file] = url;
- result.push(res.responseXML);
- }
- }
- return result;
- };
- // Find the tags in the document.
- let addTags = function addTags(file, doc) {
- for (let elem in util.evaluateXPath("//@tag|//dactyl:tags/text()|//dactyl:tag/text()", doc))
- for (let tag in values((elem.value || elem.textContent).split(/\s+/)))
- tagMap[tag] = file;
- };
-
- let namespaces = ["locale-local", "locale"];
- services["dactyl:"].init({});
-
- let tagMap = services["dactyl:"].HELP_TAGS;
- let fileMap = services["dactyl:"].FILE_MAP;
- let overlayMap = services["dactyl:"].OVERLAY_MAP;
-
- // Scrape the list of help files from all.xml
- // Manually process main and overlay files, since XSLTProcessor and
- // XMLHttpRequest don't allow access to chrome documents.
- tagMap["all"] = tagMap["all.xml"] = "all";
- tagMap["versions"] = tagMap["versions.xml"] = "versions";
- let files = findHelpFile("all").map(function (doc)
- [f.value for (f in util.evaluateXPath("//dactyl:include/@href", doc))]);
-
- // Scrape the tags from the rest of the help files.
- array.flatten(files).forEach(function (file) {
- tagMap[file + ".xml"] = file;
- findHelpFile(file).forEach(function (doc) {
- addTags(file, doc);
- });
- });
-
- // Process plugin help entries.
- XML.ignoreWhiteSpace = XML.prettyPrinting = false;
-
- let body = XML();
- for (let [, context] in Iterator(plugins.contexts))
- if (context && context.INFO instanceof XML) {
- let info = context.INFO;
- if (info.*.@lang.length()) {
- let lang = config.bestLocale(String(a) for each (a in info.*.@lang));
-
- info.* = info.*.(function::attribute("lang").length() == 0 || @lang == lang);
-
- for each (let elem in info.NS::info)
- for each (let attr in ["@name", "@summary", "@href"])
- if (elem[attr].length())
- info[attr] = elem[attr];
- }
- body += <h2 xmlns={NS.uri} tag={context.INFO.@name + '-plugin'}>{context.INFO.@summary}</h2> +
- context.INFO;
- }
-
- let help =
- '<?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' +
- unescape(encodeURI( // UTF-8 handling hack.
- <document xmlns={NS}
- name="plugins" title={config.appName + " Plugins"}>
- <h1 tag="using-plugins">Using Plugins</h1>
- <toc start="2"/>
-
- {body}
- </document>.toXMLString()));
- fileMap["plugins"] = function () ['text/xml;charset=UTF-8', help];
-
- fileMap["versions"] = function () {
- let NEWS = util.httpGet(config.addon.getResourceURI("NEWS").spec,
- { mimeType: "text/plain;charset=UTF-8" })
- .responseText;
-
- let re = util.regexp(<![CDATA[
- ^ (?P<comment> \s* # .*\n)
-
- | ^ (?P<space> \s*)
- (?P<char> [-•*+]) \ //
- (?P<content> .*\n
- (?: \2\ \ .*\n | \s*\n)* )
-
- | (?P<par>
- (?: ^ [^\S\n]*
- (?:[^-•*+\s] | [-•*+]\S)
- .*\n
- )+
- )
-
- | (?: ^ [^\S\n]* \n) +
- ]]>, "gmxy");
-
- let betas = util.regexp(/\[(b\d)\]/, "gx");
-
- let beta = array(betas.iterate(NEWS))
- .map(function (m) m[1]).uniq().slice(-1)[0];
-
- default xml namespace = NS;
- function rec(text, level, li) {
- 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;
- }
- 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]);
-
- let group = !tags.length ? "" :
- !tags.some(function (t) t == beta) ? "HelpNewsOld" : "HelpNewsNew";
- if (i === 0 && li) {
- li.@highlight = group;
- group = "";
- }
-
- list = null;
- if (level == 0 && /^.*:\n$/.test(match.par))
- res += <h2>{template.linkifyHelp(par.slice(0, -1), true)}</h2>;
- 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>;
- }
- }
- i++;
- }
- for each (let attr in res..@highlight) {
- attr.parent().@NS::highlight = attr;
- delete attr.parent().@highlight;
- }
- return res;
- }
-
- 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";
- }
- }
-
- XML.prettyPrinting = XML.ignoreWhitespace = false;
- return ["application/xml",
- '<?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' +
- unescape(encodeURI( // UTF-8 handling hack.
- <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()))
- ];
- }
- addTags("versions", util.httpGet("dactyl://help/versions").responseXML);
- addTags("plugins", util.httpGet("dactyl://help/plugins").responseXML);
-
- default xml namespace = NS;
-
- overlayMap["index"] = ['text/xml;charset=UTF-8',
- '<?xml version="1.0"?>\n' +
- '<overlay xmlns="' + NS + '">\n' +
- unescape(encodeURI( // UTF-8 handling hack.
- template.map(dactyl.indices, function ([name, iter])
- <dl insertafter={name + "-index"}>{
- template.map(iter(), util.identity)
- }</dl>, <>{"\n\n"}</>))) +
- '\n</overlay>'];