domtohtml.js
var singleTags = {
area: 1,
base: 1,
basefont: 1,
br: 1,
col: 1,
frame: 1,
hr: 1,
img: 1,
input: 1,
isindex: 1,
link: 1,
meta: 1,
param: 1,
embed: 1
};
var expr = {
upperCaseChars: /([A-Z])/g,
breakBetweenTags: /(<(\/?\w+).*?>)(?=<(?!\/\2))/gi,
singleTag: (function() {
var tags = [];
for (var i in singleTags) {
tags.push(i);
}
return new RegExp('<' + tags.join('|<'), 'i');
})()
};
var uncanon = function(str, letter) {
return '-' + letter.toLowerCase();
};
var HTMLEncode = require('./htmlencoding').HTMLEncode;
exports.stringifyElement = function stringifyElement(element) {
var tagName = element.tagName.toLowerCase(),
ret = {
start: "<" + tagName,
end:''
},
attributes = [],
i,
attribute = null;
if (element.attributes.length) {
ret.start += " ";
for (i = 0; i<element.attributes.length; i++) {
attribute = element.attributes.item(i);
attributes.push(attribute.name + '="' +
HTMLEncode(attribute.nodeValue, true) + '"');
}
}
ret.start += attributes.join(" ");
if (singleTags[tagName]) {
ret.start += " />";
ret.end = '';
} else {
ret.start += ">";
ret.end = "</" + tagName + ">";
}
return ret;
};
var rawTextElements = /SCRIPT|STYLE/i;
function stringifyDoctype (doctype) {
if (doctype.ownerDocument && doctype.ownerDocument._fullDT) {
return doctype.ownerDocument._fullDT;
}
var dt = '<!DOCTYPE ' + doctype.name;
if (doctype.publicId) {
dt += ' PUBLIC "' + doctype.publicId + '" ';
}
if (!doctype.publicId && doctype.systemId) {
dt += ' SYSTEM ';
}
if (doctype.systemId) {
if (doctype.systemId.indexOf('"') > -1) {
dt += "'" + doctype.systemId + "'";
} else {
dt += '"' + doctype.systemId + '"';
}
}
dt += '>';
return dt;
}
exports.makeHtmlGenerator = function makeHtmlGenerator(indentUnit, eol) {
indentUnit = indentUnit || "";
eol = eol || "";
return function generateHtmlRecursive(node, rawText, curIndent) {
var ret = "", parent, current, i;
curIndent = curIndent || "";
if (node) {
if (node.nodeType &&
node.nodeType === node.ENTITY_REFERENCE_NODE) {
node = node._entity;
}
var childNodesRawText = rawText || rawTextElements.test(node.nodeName);
switch (node.nodeType) {
case node.ELEMENT_NODE:
current = exports.stringifyElement(node);
if (childNodesRawText) {
ret += curIndent + current.start;
} else {
ret += curIndent + current.start;
}
if (node._childNodes.length > 0) {
if (node._childNodes[0].nodeType !== node.TEXT_NODE) {
ret += eol;
}
for (i=0; i<node._childNodes.length; i++) {
ret += generateHtmlRecursive(node._childNodes[i], childNodesRawText, curIndent + indentUnit);
}
if (node._childNodes[node._childNodes.length - 1].nodeType !== node.TEXT_NODE) {
ret += curIndent;
}
ret += current.end + eol;
} else {
ret += ((rawText ? node.nodeValue : HTMLEncode(node.nodeValue, false)) || '') + current.end + eol;
}
break;
case node.TEXT_NODE:
if (!indentUnit || !/^[\s\n]*$/.test(node.nodeValue)) {
ret += (rawText ? node.nodeValue : HTMLEncode(node.nodeValue, false)) || '';
}
break;
case node.COMMENT_NODE:
ret += curIndent + '<!--' + node.nodeValue + '-->' + eol;
break;
case node.DOCUMENT_NODE:
for (i=0; i<node._childNodes.length; i++) {
ret += generateHtmlRecursive(node._childNodes[i], childNodesRawText, curIndent);
}
break;
case node.DOCUMENT_TYPE_NODE:
ret += stringifyDoctype(node);
break;
}
}
return ret;
};
};
exports.domToHtml = function(dom, noformat, raw) {
var htmlGenerator = exports.makeHtmlGenerator(noformat ? "" : " ",
noformat ? "" : "\n");
if (dom.toArray) {
dom = dom.toArray();
}
if (typeof dom.length !== 'undefined') {
var ret = "";
for (var i=0,len=dom.length; i<len; i++) {
ret += htmlGenerator(dom[i], raw);
}
return ret;
} else {
return htmlGenerator(dom, raw);
}
};