You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
6.2 KiB
211 lines
6.2 KiB
"use strict"; |
|
var __assign = (this && this.__assign) || function () { |
|
__assign = Object.assign || function(t) { |
|
for (var s, i = 1, n = arguments.length; i < n; i++) { |
|
s = arguments[i]; |
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) |
|
t[p] = s[p]; |
|
} |
|
return t; |
|
}; |
|
return __assign.apply(this, arguments); |
|
}; |
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { |
|
if (k2 === undefined) k2 = k; |
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); |
|
}) : (function(o, m, k, k2) { |
|
if (k2 === undefined) k2 = k; |
|
o[k2] = m[k]; |
|
})); |
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { |
|
Object.defineProperty(o, "default", { enumerable: true, value: v }); |
|
}) : function(o, v) { |
|
o["default"] = v; |
|
}); |
|
var __importStar = (this && this.__importStar) || function (mod) { |
|
if (mod && mod.__esModule) return mod; |
|
var result = {}; |
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); |
|
__setModuleDefault(result, mod); |
|
return result; |
|
}; |
|
Object.defineProperty(exports, "__esModule", { value: true }); |
|
/* |
|
* Module dependencies |
|
*/ |
|
var ElementType = __importStar(require("domelementtype")); |
|
var entities_1 = require("entities"); |
|
/** |
|
* Mixed-case SVG and MathML tags & attributes |
|
* recognized by the HTML parser. |
|
* |
|
* @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign |
|
*/ |
|
var foreignNames_1 = require("./foreignNames"); |
|
var unencodedElements = new Set([ |
|
"style", |
|
"script", |
|
"xmp", |
|
"iframe", |
|
"noembed", |
|
"noframes", |
|
"plaintext", |
|
"noscript", |
|
]); |
|
/** |
|
* Format attributes |
|
*/ |
|
function formatAttributes(attributes, opts) { |
|
if (!attributes) |
|
return; |
|
return Object.keys(attributes) |
|
.map(function (key) { |
|
var _a, _b; |
|
var value = (_a = attributes[key]) !== null && _a !== void 0 ? _a : ""; |
|
if (opts.xmlMode === "foreign") { |
|
/* Fix up mixed-case attribute names */ |
|
key = (_b = foreignNames_1.attributeNames.get(key)) !== null && _b !== void 0 ? _b : key; |
|
} |
|
if (!opts.emptyAttrs && !opts.xmlMode && value === "") { |
|
return key; |
|
} |
|
return key + "=\"" + (opts.decodeEntities !== false |
|
? entities_1.encodeXML(value) |
|
: value.replace(/"/g, """)) + "\""; |
|
}) |
|
.join(" "); |
|
} |
|
/** |
|
* Self-enclosing tags |
|
*/ |
|
var singleTag = new Set([ |
|
"area", |
|
"base", |
|
"basefont", |
|
"br", |
|
"col", |
|
"command", |
|
"embed", |
|
"frame", |
|
"hr", |
|
"img", |
|
"input", |
|
"isindex", |
|
"keygen", |
|
"link", |
|
"meta", |
|
"param", |
|
"source", |
|
"track", |
|
"wbr", |
|
]); |
|
/** |
|
* Renders a DOM node or an array of DOM nodes to a string. |
|
* |
|
* Can be thought of as the equivalent of the `outerHTML` of the passed node(s). |
|
* |
|
* @param node Node to be rendered. |
|
* @param options Changes serialization behavior |
|
*/ |
|
function render(node, options) { |
|
if (options === void 0) { options = {}; } |
|
var nodes = "length" in node ? node : [node]; |
|
var output = ""; |
|
for (var i = 0; i < nodes.length; i++) { |
|
output += renderNode(nodes[i], options); |
|
} |
|
return output; |
|
} |
|
exports.default = render; |
|
function renderNode(node, options) { |
|
switch (node.type) { |
|
case ElementType.Root: |
|
return render(node.children, options); |
|
case ElementType.Directive: |
|
case ElementType.Doctype: |
|
return renderDirective(node); |
|
case ElementType.Comment: |
|
return renderComment(node); |
|
case ElementType.CDATA: |
|
return renderCdata(node); |
|
case ElementType.Script: |
|
case ElementType.Style: |
|
case ElementType.Tag: |
|
return renderTag(node, options); |
|
case ElementType.Text: |
|
return renderText(node, options); |
|
} |
|
} |
|
var foreignModeIntegrationPoints = new Set([ |
|
"mi", |
|
"mo", |
|
"mn", |
|
"ms", |
|
"mtext", |
|
"annotation-xml", |
|
"foreignObject", |
|
"desc", |
|
"title", |
|
]); |
|
var foreignElements = new Set(["svg", "math"]); |
|
function renderTag(elem, opts) { |
|
var _a; |
|
// Handle SVG / MathML in HTML |
|
if (opts.xmlMode === "foreign") { |
|
/* Fix up mixed-case element names */ |
|
elem.name = (_a = foreignNames_1.elementNames.get(elem.name)) !== null && _a !== void 0 ? _a : elem.name; |
|
/* Exit foreign mode at integration points */ |
|
if (elem.parent && |
|
foreignModeIntegrationPoints.has(elem.parent.name)) { |
|
opts = __assign(__assign({}, opts), { xmlMode: false }); |
|
} |
|
} |
|
if (!opts.xmlMode && foreignElements.has(elem.name)) { |
|
opts = __assign(__assign({}, opts), { xmlMode: "foreign" }); |
|
} |
|
var tag = "<" + elem.name; |
|
var attribs = formatAttributes(elem.attribs, opts); |
|
if (attribs) { |
|
tag += " " + attribs; |
|
} |
|
if (elem.children.length === 0 && |
|
(opts.xmlMode |
|
? // In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags |
|
opts.selfClosingTags !== false |
|
: // User explicitly asked for self-closing tags, even in HTML mode |
|
opts.selfClosingTags && singleTag.has(elem.name))) { |
|
if (!opts.xmlMode) |
|
tag += " "; |
|
tag += "/>"; |
|
} |
|
else { |
|
tag += ">"; |
|
if (elem.children.length > 0) { |
|
tag += render(elem.children, opts); |
|
} |
|
if (opts.xmlMode || !singleTag.has(elem.name)) { |
|
tag += "</" + elem.name + ">"; |
|
} |
|
} |
|
return tag; |
|
} |
|
function renderDirective(elem) { |
|
return "<" + elem.data + ">"; |
|
} |
|
function renderText(elem, opts) { |
|
var data = elem.data || ""; |
|
// If entities weren't decoded, no need to encode them back |
|
if (opts.decodeEntities !== false && |
|
!(!opts.xmlMode && |
|
elem.parent && |
|
unencodedElements.has(elem.parent.name))) { |
|
data = entities_1.encodeXML(data); |
|
} |
|
return data; |
|
} |
|
function renderCdata(elem) { |
|
return "<![CDATA[" + elem.children[0].data + "]]>"; |
|
} |
|
function renderComment(elem) { |
|
return "<!--" + elem.data + "-->"; |
|
}
|
|
|