jsdom-jscore-rn
Version:
A fork of brentvatne/jsdom-jscore to run within react-native
159 lines (145 loc) • 4.36 kB
JavaScript
//List from node-htmlparser
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 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) {
// Public ID may never contain double quotes, so this is always safe.
dt += ' PUBLIC "' + doctype.publicId + '" ';
}
if (!doctype.publicId && doctype.systemId) {
dt += ' SYSTEM ';
}
if (doctype.systemId) {
// System ID may contain double quotes OR single quotes, not never both.
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 = '', 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;
}
var len = node._childNodes.length;
if (len > 0) {
if (node._childNodes[0].nodeType !== node.TEXT_NODE) {
ret += eol;
}
for (i=0; i<len; i++) {
ret += generateHtmlRecursive(node._childNodes[i], childNodesRawText, curIndent + indentUnit);
}
if (node._childNodes[len - 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:
// Skip pure whitespace nodes if we're indenting
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) {
// node list
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 {
// single node
return htmlGenerator(dom, raw);
}
};