Skip to content

Commit

Permalink
landing a better html serialization utility
Browse files Browse the repository at this point in the history
  • Loading branch information
tmpvar committed Apr 22, 2011
2 parents 9dcf58e + aa3bfa6 commit 2205d21
Showing 1 changed file with 63 additions and 85 deletions.
148 changes: 63 additions & 85 deletions lib/jsdom/browser/domtohtml.js
Expand Up @@ -23,9 +23,6 @@ var singleTags = {
var expr = {
upperCaseChars: /([A-Z])/g,
breakBetweenTags: /(<(\/?\w+).*?>)(?=<(?!\/\2))/gi,
endsWithEndTag: /.+<\/\w[^>]*>$/,
startsWithEndTag: /^<\/\w/,
startsWithStartTag: /^<\w[^>]*[^\/]>.*$/,
singleTag: (function() {
var tags = [];
for (var i in singleTags) {
Expand Down Expand Up @@ -104,39 +101,6 @@ exports.stringifyElement = function stringifyElement(element) {
return ret;
};

exports.formatHTML = function formatHTML(html) {
var formatted = '',
pad = 0;

html = html.replace(expr.breakBetweenTags, '$1\r\n');
html.split('\r\n').forEach(function(node, index) {
var indent = 0, padding = '', i;

if (node.match(expr.endsWithEndTag)) {
indent = 0;
} else if (node.match(expr.startsWithEndTag)) {
if (pad != 0) {
pad -= 1;
}
} else if (node.match(expr.startsWithStartTag)) {
if (!expr.singleTag.exec(node)) {
indent = 1;
}
} else {
indent = 0;
}

for (i = 0; i < pad; i++) {
padding += ' ';
}

formatted += padding + node + '\r\n';
pad += indent;
});

return formatted;
};

var rawTextElements = /SCRIPT|STYLE/i;

function stringifyDoctype (doctype) {
Expand Down Expand Up @@ -164,72 +128,86 @@ function stringifyDoctype (doctype) {
return dt;
}

exports.generateHtmlRecursive = function generateHtmlRecursive(node, rawText) {
var ret = "", parent, current, i;
if (node) {
if (node.nodeType &&
node.nodeType === node.ENTITY_REFERENCE_NODE)
{
node = node._entity;
}

if (!rawText && node._parentNode) {
rawText = rawTextElements.test(node._parentNode.nodeName);
}
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;
}

switch (node.nodeType) {
case node.ELEMENT_NODE:
current = exports.stringifyElement(node);
ret += current.start;
var childNodesRawText = rawText || rawTextElements.test(node.nodeName);

if (node._childNodes.length > 0) {
for (i=0; i<node._childNodes.length; i++) {
ret += exports.generateHtmlRecursive(node._childNodes[i], rawText);
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);
ret += (node.nodeValue || '') + current.end + eol;
}
} else {
break;
case node.TEXT_NODE:
//ret += rawText ? node.nodeValue : HTMLEncode(node.nodeValue);
ret += node.nodeValue || '';
}
ret += current.end;
break;
case node.TEXT_NODE:
//ret += rawText ? node.nodeValue : HTMLEncode(node.nodeValue);
ret += node.nodeValue;
break;
case node.COMMENT_NODE:
ret += '<!--' + node.nodeValue + '-->';
break;
case node.DOCUMENT_NODE:
for (i=0; i<node._childNodes.length; i++) {
ret += exports.generateHtmlRecursive(node._childNodes[i], rawText);
}
// Skip pure whitespace nodes if we're indenting
if (!indentUnit || !/^[\s\n]*$/.test(node.nodeValue)) {
ret += node.nodeValue || '';
}
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;
case node.DOCUMENT_TYPE_NODE:
ret += stringifyDoctype(node);
break;
}
}
}
//require('sys').puts(require('sys').inspect(ret));
return ret;
//require('sys').puts(require('sys').inspect(ret));
return ret;
};
};

exports.domToHtml = function(dom, noformat, raw) {
var ret = "";
var htmlGenerator = exports.makeHtmlGenerator(noformat ? "" : " ",
noformat ? "" : "\n");
if (dom.toArray) {
// node list
dom = dom.toArray();
}
if (Array.isArray(dom)) {
var ret = "";
for (var i=0,len=dom.length; i<len; i++) {
ret += exports.generateHtmlRecursive(dom[i], raw);
ret += htmlGenerator(dom[i], raw);
}
} else {
// single node
ret = exports.generateHtmlRecursive(dom, raw);
}
if (noformat) {
return ret;
} else {
return exports.formatHTML(ret);
// single node
return htmlGenerator(dom, raw);
}
};

0 comments on commit 2205d21

Please sign in to comment.