source: imaps-frontend/node_modules/dom-serializer/lib/esm/index.js

main
Last change on this file was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

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