/*\ title: js/HTML.js Represents a fragment of HTML as a JavaScript object tree structure. Helper methods are provided to simplify constructing HTML trees and to render the tree as an HTML string. The nodes in the tree have a `type` field that is the name of the node for HTML elements: {type: "br", attributes: {name: "value"}} Attributes values can be strings, arrays of strings or hashmaps. String arrays are rendered by joining them together with a space. Hashmaps are rendered as `attr="name1:value1;name2:value2;"`. Elements with child nodes are expressed as: {type: "div", children: []} Text nodes are represented as: {type: "text", value: "A string"} HTML entities are represented as: {type: "entity", value: "quot"} It is sometimes useful to be able to mix raw strings of HTML too: {type: "raw", value: "
Something
"} Other types of node can also be placed in the tree, but they will be ignored by the built-in render function. For example, nodes of type `"macro"` are used by the WikiTextParser. \*/ (function(){ /*jslint node: true */ "use strict"; var utils = require("./Utils.js"); /* Constructs an HTMLParseTree from a tree of nodes. A single node or an array of nodes can be passed. As a shortcut, the constructor can be called as an ordinary function without the new keyword, in which case it automatically returns the `text/html` rendering of the tree. */ var HTML = function(tree,type) { if(this instanceof HTML) { // Called as a constructor this.tree = tree; } else { // Called as a function type = type || "text/html"; return (new HTML(tree)).render(type); } }; /* Static method to simplify constructing an HTML element node type: element name attributes: hashmap of element attributes to add options: hashmap of options The attributes hashmap can contain strings or hashmaps of strings, (they are processed to attr="name1:value1;name2:value2;") The options include: content: a string to include as content in the element (also generates closing tag) classes: an array of classnames to apply to the element selfClosing: causes the element to be rendered with a trailing /, as in
insertAfterAttributes: a string to insert after the attribute section of the element */ HTML.elem = function(type,attributes,children) { var e = {type: type}; if(attributes) { e.attributes = attributes; } if(children) { e.children = children; } return e; }; /* Static method to construct a text node */ HTML.text = function(value) { return {type: "text", value: value}; }; /* Static method to construct an entity */ HTML.entity = function(value) { return {type: "entity", value: value}; }; /* Static method to construct a raw HTML node */ HTML.raw = function(value) { return {type: "raw", value: value}; }; /* Static method to construct a macro call */ HTML.macro = function(name,params,children,dependencies) { var m = {type: "macro", name: name, params: params, dependencies: dependencies}; if(children) { m.children = children; } return m; }; /* Static method to construct a split label */ HTML.splitLabel = function(type,left,right,classes) { classes = (classes || []).slice(0); classes.push("splitLabel"); return HTML.elem("span",{ "class": classes },[ HTML.elem("span",{ "class": ["splitLabelLeft"], "data-tw-label-type": type },left), HTML.elem("span",{ "class": ["splitLabelRight"] },right) ]); }; /* Static method to construct a slider */ HTML.slider = function(type,label,tooltip,body) { var attributes = { "class": "tw-slider", "data-tw-slider-type": type }; if(tooltip) { attributes.alt = tooltip; attributes.title = tooltip; } return HTML.elem("div", attributes, [ HTML.elem("a", { "class": ["tw-slider-label"] },[ HTML.text(label) ] ), HTML.elem("div", { "class": ["tw-slider-body"], "style": {"display": "none"} }, body ) ] ); }; /* Render the HTML tree to a string, either of "text/html" or "text/plain" */ HTML.prototype.render = function(targetType) { if(targetType == "text/plain") { return this.renderPlain().join(""); } else if(targetType == "text/html") { return this.renderHtml().join(""); } else { return null; } }; /* Render the HTML tree to a "text/html" string, returned as a string array */ HTML.prototype.renderHtml = function(output,node) { output = output || []; node = node || this.tree; if(node instanceof Array) { for(var t=0; t"); if(node.children) { this.renderHtml(output,node.children); output.push(""); } break; } } return output; }; /* Render the HTML tree to a "text/plain" string, returned as a string array */ HTML.prototype.renderPlain = function(output,node) { output = output || []; node = node || this.tree; if(node instanceof Array) { for(var t=0; t