UNPKG

6.33 kBJavaScriptView Raw
1"use strict";
2var __assign = (this && this.__assign) || function () {
3 __assign = Object.assign || function(t) {
4 for (var s, i = 1, n = arguments.length; i < n; i++) {
5 s = arguments[i];
6 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7 t[p] = s[p];
8 }
9 return t;
10 };
11 return __assign.apply(this, arguments);
12};
13var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14 if (k2 === undefined) k2 = k;
15 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
16}) : (function(o, m, k, k2) {
17 if (k2 === undefined) k2 = k;
18 o[k2] = m[k];
19}));
20var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21 Object.defineProperty(o, "default", { enumerable: true, value: v });
22}) : function(o, v) {
23 o["default"] = v;
24});
25var __importStar = (this && this.__importStar) || function (mod) {
26 if (mod && mod.__esModule) return mod;
27 var result = {};
28 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29 __setModuleDefault(result, mod);
30 return result;
31};
32Object.defineProperty(exports, "__esModule", { value: true });
33/*
34 * Module dependencies
35 */
36var ElementType = __importStar(require("domelementtype"));
37var entities_1 = require("entities");
38/**
39 * Mixed-case SVG and MathML tags & attributes
40 * recognized by the HTML parser.
41 *
42 * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign
43 */
44var foreignNames_1 = require("./foreignNames");
45var unencodedElements = new Set([
46 "style",
47 "script",
48 "xmp",
49 "iframe",
50 "noembed",
51 "noframes",
52 "plaintext",
53 "noscript",
54]);
55/**
56 * Format attributes
57 */
58function formatAttributes(attributes, opts) {
59 if (!attributes)
60 return;
61 return Object.keys(attributes)
62 .map(function (key) {
63 var _a, _b;
64 var value = (_a = attributes[key]) !== null && _a !== void 0 ? _a : "";
65 if (opts.xmlMode === "foreign") {
66 /* Fix up mixed-case attribute names */
67 key = (_b = foreignNames_1.attributeNames.get(key)) !== null && _b !== void 0 ? _b : key;
68 }
69 if (!opts.emptyAttrs && !opts.xmlMode && value === "") {
70 return key;
71 }
72 return key + "=\"" + (opts.decodeEntities !== false
73 ? entities_1.encodeXML(value)
74 : value.replace(/"/g, "&quot;")) + "\"";
75 })
76 .join(" ");
77}
78/**
79 * Self-enclosing tags
80 */
81var singleTag = new Set([
82 "area",
83 "base",
84 "basefont",
85 "br",
86 "col",
87 "command",
88 "embed",
89 "frame",
90 "hr",
91 "img",
92 "input",
93 "isindex",
94 "keygen",
95 "link",
96 "meta",
97 "param",
98 "source",
99 "track",
100 "wbr",
101]);
102/**
103 * Renders a DOM node or an array of DOM nodes to a string.
104 *
105 * Can be thought of as the equivalent of the `outerHTML` of the passed node(s).
106 *
107 * @param node Node to be rendered.
108 * @param options Changes serialization behavior
109 */
110function render(node, options) {
111 if (options === void 0) { options = {}; }
112 var nodes = "length" in node ? node : [node];
113 var output = "";
114 for (var i = 0; i < nodes.length; i++) {
115 output += renderNode(nodes[i], options);
116 }
117 return output;
118}
119exports.default = render;
120function renderNode(node, options) {
121 switch (node.type) {
122 case ElementType.Root:
123 return render(node.children, options);
124 case ElementType.Directive:
125 case ElementType.Doctype:
126 return renderDirective(node);
127 case ElementType.Comment:
128 return renderComment(node);
129 case ElementType.CDATA:
130 return renderCdata(node);
131 case ElementType.Script:
132 case ElementType.Style:
133 case ElementType.Tag:
134 return renderTag(node, options);
135 case ElementType.Text:
136 return renderText(node, options);
137 }
138}
139var foreignModeIntegrationPoints = new Set([
140 "mi",
141 "mo",
142 "mn",
143 "ms",
144 "mtext",
145 "annotation-xml",
146 "foreignObject",
147 "desc",
148 "title",
149]);
150var foreignElements = new Set(["svg", "math"]);
151function renderTag(elem, opts) {
152 var _a;
153 // Handle SVG / MathML in HTML
154 if (opts.xmlMode === "foreign") {
155 /* Fix up mixed-case element names */
156 elem.name = (_a = foreignNames_1.elementNames.get(elem.name)) !== null && _a !== void 0 ? _a : elem.name;
157 /* Exit foreign mode at integration points */
158 if (elem.parent &&
159 foreignModeIntegrationPoints.has(elem.parent.name)) {
160 opts = __assign(__assign({}, opts), { xmlMode: false });
161 }
162 }
163 if (!opts.xmlMode && foreignElements.has(elem.name)) {
164 opts = __assign(__assign({}, opts), { xmlMode: "foreign" });
165 }
166 var tag = "<" + elem.name;
167 var attribs = formatAttributes(elem.attribs, opts);
168 if (attribs) {
169 tag += " " + attribs;
170 }
171 if (elem.children.length === 0 &&
172 (opts.xmlMode
173 ? // In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags
174 opts.selfClosingTags !== false
175 : // User explicitly asked for self-closing tags, even in HTML mode
176 opts.selfClosingTags && singleTag.has(elem.name))) {
177 if (!opts.xmlMode)
178 tag += " ";
179 tag += "/>";
180 }
181 else {
182 tag += ">";
183 if (elem.children.length > 0) {
184 tag += render(elem.children, opts);
185 }
186 if (opts.xmlMode || !singleTag.has(elem.name)) {
187 tag += "</" + elem.name + ">";
188 }
189 }
190 return tag;
191}
192function renderDirective(elem) {
193 return "<" + elem.data + ">";
194}
195function renderText(elem, opts) {
196 var data = elem.data || "";
197 // If entities weren't decoded, no need to encode them back
198 if (opts.decodeEntities !== false &&
199 !(!opts.xmlMode &&
200 elem.parent &&
201 unencodedElements.has(elem.parent.name))) {
202 data = entities_1.encodeXML(data);
203 }
204 return data;
205}
206function renderCdata(elem) {
207 return "<![CDATA[" + elem.children[0].data + "]]>";
208}
209function renderComment(elem) {
210 return "<!--" + elem.data + "-->";
211}