tag-soup
Version:
The fastest pure JS SAX/DOM XML/HTML parser.
60 lines (59 loc) • 2.04 kB
JavaScript
import { CDATASection, Comment, Document, DocumentFragment, DocumentType, Element, ProcessingInstruction, Text, } from 'flyweight-dom';
/**
* Serializes DOM node as HTML/XML string.
*
* @param node DOM node to serialize.
* @param options Serialization options.
*/
export function serializeMarkup(node, options) {
const { toHashCode, voidTags, areSelfClosingTagsSupported, encodeText = identity } = options;
if (node instanceof Element) {
let output = '<' + node.tagName;
for (const name in node.attributes) {
output += ' ' + name + '="' + encodeText(node.attributes[name]) + '"';
}
if (node.firstChild !== null) {
output += '>';
for (let child = node.firstChild; child !== null; child = child.nextSibling) {
output += serializeMarkup(child, options);
}
output += '</' + node.tagName + '>';
}
else if (voidTags !== undefined && voidTags.has(toHashCode(node.tagName))) {
output += '>';
}
else if (areSelfClosingTagsSupported) {
output += '/>';
}
else {
output += '></' + node.tagName + '>';
}
return output;
}
if (node instanceof CDATASection) {
return '<![CDATA[' + node.data + ']]>';
}
if (node instanceof Document || node instanceof DocumentFragment) {
let output = '';
for (let child = node.firstChild; child !== null; child = child.nextSibling) {
output += serializeMarkup(child, options);
}
return output;
}
if (node instanceof Comment) {
return '<!--' + node.data + '-->';
}
if (node instanceof DocumentType) {
return '<!DOCTYPE ' + node.name + '>';
}
if (node instanceof ProcessingInstruction) {
return '<?' + node.target + ' ' + node.data + '?>';
}
if (node instanceof Text) {
return encodeText(node.data);
}
return '';
}
function identity(value) {
return value;
}