const template = { add: function add(a, b) a + b, join: function join(c) function (a, b) a + c + b, map: function map(iter, fn, sep) { if (iter.length) /* Kludge? */ iter = util.Array.iterator(iter); let ret = <>; let n = 0; for each (let i in Iterator(iter)) { let val = fn(i); if (val == undefined) continue; if (sep && n++) ret += sep; ret += val; } return ret; }, maybeXML: function maybeXML(xml) { if (typeof xml == "xml") return xml; try { return new XMLList(xml); } catch (e) {} return <>{xml}; }, completionRow: function completionRow(context, item, class) { let text = item.text || item[0] || ""; let description = item.description || item[1] || ""; let icon = item.icon || item[2]; /* Kludge until we have completion contexts. */ let map = completion.filterMap; if (map) { text = map[0] ? map[0](text) : text; description = map[1] ? map[1](description) : description; } // FIXME: Move. let filter = context.filter; if (filter) { text = template.highlightFilter(text, filter); description = template.highlightFilter(description, filter); } if (typeof icon == "function") icon = icon(); return ; }, filter: function (str) {str}, // if "processStrings" is true, any passed strings will be surrounded by " and // any line breaks are displayed as \n highlight: function highlight(arg, processStrings, clip) { // some objects like window.JSON or getBrowsers()._browsers need the try/catch let str = clip ? util.clip(String(arg), clip) : String(arg); try { switch (arg == null ? "undefined" : typeof arg) { case "number": return {str}; case "string": if (processStrings) str = <>{util.escapeString(str)}; return {str}; case "boolean": return {str}; case "function": // Vim generally doesn't like /foo*/, because */ looks like a comment terminator. // Using /foo*(:?)/ instead. if (processStrings) return {str.replace(/\{(.|\n)*(?:)/g, "{ ... }")}; return <>{arg}; case "undefined": return {arg}; case "object": // for java packages value.toString() would crash so badly // that we cannot even try/catch it if (/^\[JavaPackage.*\]$/.test(arg)) return <>[JavaPackage]; if (processStrings && false) str = template.highlightFilter(str, "\n", function () ^J); return {str}; case "xml": return arg; default: return ]]>; } } catch (e) { return]]>; } }, highlightFilter: function highlightFilter(str, filter, highlight) { if (typeof str == "xml") return str; return this.highlightSubstrings(str, (function () { let lcstr = String.toLowerCase(str); let lcfilter = filter.toLowerCase(); let start = 0; while ((start = lcstr.indexOf(lcfilter, start)) > -1) { yield [start, filter.length]; start += filter.length; } })(), highlight || template.filter); }, highlightRegexp: function highlightRegexp(str, re, highlight) { if (typeof str == "xml") return str; return this.highlightSubstrings(str, (function () { while (res = re.exec(str)) yield [res.index, res[0].length]; })(), highlight || template.filter); }, highlightSubstrings: function highlightSubstrings(str, iter, highlight) { if (typeof str == "xml") return str; if (str == "") return <>{str}; str = String(str).replace(" ", "\u00a0"); let s = <>; let start = 0; for (let [i, length] in iter) { XML.ignoreWhitespace = false; s += <>{str.substring(start, i)}; s += highlight(str.substr(i, length)); start = i + length; } return s + <>{str.substr(start)}; }, highlightURL: function highlightURL(str, force) { if (force || /^[a-zA-Z]+:\/\//.test(str)) return {str}; else return str; }, generic: function generic(xml) { return <>:{commandline.getCommand()}
+ xml; }, // every item must have a .xml property which defines how to draw itself // @param headers is an array of strings, the text for the header columns genericTable: function genericTable(headers, items) { return this.generic( { headers.reduce(function (prev, cur) prev + , <>) } { this.map(items, function (item) item.xml) }
{cur}
); }, // returns a single row for a bookmark or history item bookmarkItem: function bookmarkItem(item) { var extra = []; if (item.keyword) extra.push(['keyword', item.keyword, "hl-Keyword"]); if (item.tags && item.tags.length > 0) extra.push(["tags", item.tags.join(","), "hl-Tag"]); // no space, otherwise it looks strange, since we just have spaces to seperate tags from keywords return }, jumps: function jumps(index, elems) { return this.generic( { this.map(Iterator(elems), function ([idx, val]) ) }
jumptitleURI
{idx == index ? ">" : ""} {Math.abs(idx - index)} {val.title} {val.URI.spec}
); }, options: function options(title, opts) { return this.generic( { this.map(opts, function (opt) ) }
--- {title} ---
{opt.pre}{opt.name}{opt.value} {opt.isDefault || opt.default == null ? "" : (default: {opt.default})}
); }, table: function table(title, data, indent) { let table = { this.map(data, function (datum) ) }
{title}
{datum[0]} {template.maybeXML(datum[1])}
; if (table.tr.length() > 1) return table; }, tabular: function tabular(headings, style, iter) { /* This might be mind-bogglingly slow. We'll see. */ return this.generic( { this.map(headings, function (h) ) } { this.map(iter, function (row) { template.map(Iterator(row), function ([i, d]) ) } ) }
{h}
{d}
); }, usage: function usage(iter) { return this.generic( { this.map(iter, function (item) ) }
{item.name || item.names[0]} {item.description}
); } }; // vim: set fdm=marker sw=4 ts=4 et: