"use strict";
var runtimeHtmlHelpers = require("marko/runtime/html/helpers");
var escapeXml = runtimeHtmlHelpers.x;
var escapeXmlAttr = runtimeHtmlHelpers.xa;
var escapeScript = runtimeHtmlHelpers.xs;
var escapeStyle = runtimeHtmlHelpers.xc;
var openTagOnly = {};
[
"base",
"br",
"col",
"hr",
"embed",
"img",
"input",
"keygen",
"link",
"meta",
"param",
"source",
"track",
"wbr",
].forEach(function (tagName) {
openTagOnly[tagName] = true;
});
function getNodeValue(node) {
return node.___nodeValue || node.nodeValue;
}
function getFirstChild(node) {
return node.___firstChild || node.firstChild;
}
function getNextSibling(node) {
return node.___nextSibling || node.nextSibling;
}
function vdomToHTML(node, options) {
// NOTE: We don't use XMLSerializer because we need to sort the attributes to correctly compare output HTML strings
// BAD: return (new XMLSerializer()).serializeToString(node);
var html = "";
function serializeHelper(node) {
var nodeType = node.nodeType || node.___nodeType;
if (nodeType === 1) {
serializeElHelper(node);
} else if (nodeType === 3) {
serializeTextHelper(node);
} else if (nodeType === 8) {
serializeCommentHelper(node);
} else {
html += `INVALID NODE TYPE ${nodeType}\n`;
}
}
function serializeElHelper(el) {
var tagName = el.nodeName;
html += "<" + tagName;
var attributes = el.attributes;
var attributesArray = [];
var attrName;
if (typeof attributes.length === "number") {
for (var i = 0; i < attributes.length; i++) {
var attr = attributes[i];
attrName = attr.name;
if (attrName === "data-marko-const") {
continue;
}
attributesArray.push(
" " + attrName + '="' + escapeXmlAttr(attr.value) + '"',
);
}
} else {
for (attrName in attributes) {
if (attrName === "data-marko-const") {
continue;
}
var attrValue = attributes[attrName];
if (typeof attrValue !== "string") {
if (attrValue === true) {
attrValue = "";
} else if (!attrValue) {
continue;
}
}
if (attrName === "xlink:href") {
attrName = "http://www.w3.org/1999/xlink:href";
}
attributesArray.push(
" " + attrName + '="' + escapeXmlAttr(attrValue) + '"',
);
}
}
attributesArray.sort();
html += attributesArray.join("");
html += ">";
var hasEndTag = true;
if (tagName.toUpperCase() === "TEXTAREA") {
html += el.value;
} else {
var curChild = getFirstChild(el);
if (curChild) {
while (curChild) {
let nodeType = curChild.nodeType || curChild.___nodeType;
if (nodeType === 3) {
let tag = tagName.toUpperCase();
let escapeText =
tag === "SCRIPT"
? escapeScript
: tag === "STYLE"
? escapeStyle
: escapeXml;
serializeTextHelper(curChild, escapeText);
} else {
serializeHelper(curChild);
}
curChild = getNextSibling(curChild);
}
} else if (openTagOnly[tagName.toLowerCase()]) {
hasEndTag = false;
}
}
if (hasEndTag) {
html += "" + tagName + ">";
}
}
function serializeTextHelper(node, escape) {
escape = escape || escapeXml;
html += escape(getNodeValue(node));
}
function serializeCommentHelper(node) {
html += "";
}
let nodeType = node.nodeType || node.___nodeType;
if (
nodeType === 11 /* DocumentFragment */ ||
(options && options.childrenOnly)
) {
var curChild = getFirstChild(node);
while (curChild) {
serializeHelper(curChild);
curChild = getNextSibling(curChild);
}
} else {
serializeHelper(node);
}
return html;
}
module.exports = vdomToHTML;