UNPKG

html-react-parser

Version:
1,750 lines (1,696 loc) 84.9 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) : typeof define === 'function' && define.amd ? define(['react'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.HTMLReactParser = factory(global.React)); })(this, (function (require$$0) { 'use strict'; function _mergeNamespaces(n, m) { m.forEach(function (e) { e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) { if (k !== 'default' && !(k in n)) { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); }); return Object.freeze(n); } function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function getAugmentedNamespace(n) { if (Object.prototype.hasOwnProperty.call(n, '__esModule')) return n; var f = n.default; if (typeof f == "function") { var a = function a () { var isInstance = false; try { isInstance = this instanceof a; } catch {} if (isInstance) { return Reflect.construct(f, arguments, this.constructor); } return f.apply(this, arguments); }; a.prototype = f.prototype; } else a = {}; Object.defineProperty(a, '__esModule', {value: true}); Object.keys(n).forEach(function (k) { var d = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d.get ? d : { enumerable: true, get: function () { return n[k]; } }); }); return a; } var lib$1 = {}; var htmlToDom = {}; var domparser = {}; var utilities$2 = {}; /** Types of elements found in htmlparser2's DOM */ var ElementType; (function (ElementType) { /** Type for the root element of a document */ ElementType["Root"] = "root"; /** Type for Text */ ElementType["Text"] = "text"; /** Type for <? ... ?> */ ElementType["Directive"] = "directive"; /** Type for <!-- ... --> */ ElementType["Comment"] = "comment"; /** Type for <script> tags */ ElementType["Script"] = "script"; /** Type for <style> tags */ ElementType["Style"] = "style"; /** Type for Any tag */ ElementType["Tag"] = "tag"; /** Type for <![CDATA[ ... ]]> */ ElementType["CDATA"] = "cdata"; /** Type for <!doctype ...> */ ElementType["Doctype"] = "doctype"; })(ElementType || (ElementType = {})); /** * Tests whether an element is a tag or not. * @param element Element to test * @param element.type Node type discriminator to check. */ function isTag$1(element) { return (element.type === ElementType.Tag || element.type === ElementType.Script || element.type === ElementType.Style); } // Exports for backwards compatibility /** Type for the root element of a document */ // eslint-disable-next-line prefer-destructuring ElementType.Root; /** Type for Text */ // eslint-disable-next-line prefer-destructuring ElementType.Text; /** Type for <? ... ?> */ // eslint-disable-next-line prefer-destructuring ElementType.Directive; /** Type for <!-- ... --> */ // eslint-disable-next-line prefer-destructuring ElementType.Comment; /** Type for <script> tags */ // eslint-disable-next-line prefer-destructuring ElementType.Script; /** Type for <style> tags */ // eslint-disable-next-line prefer-destructuring ElementType.Style; /** Type for Any tag */ // eslint-disable-next-line prefer-destructuring ElementType.Tag; /** Type for <![CDATA[ ... ]]> */ // eslint-disable-next-line prefer-destructuring ElementType.CDATA; /** Type for <!doctype ...> */ // eslint-disable-next-line prefer-destructuring ElementType.Doctype; /** * This object will be used as the prototype for Nodes when creating a * DOM-Level-1-compliant structure. */ class Node { /** Parent of the node */ parent = null; /** Previous sibling */ prev = null; /** Next sibling */ next = null; /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */ startIndex = null; /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */ endIndex = null; // Read-write aliases for properties /** * Same as {@link parent}. * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. */ get parentNode() { return this.parent; } set parentNode(parent) { this.parent = parent; } /** * Same as {@link prev}. * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. */ get previousSibling() { return this.prev; } set previousSibling(previous) { this.prev = previous; } /** * Same as {@link next}. * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. */ get nextSibling() { return this.next; } set nextSibling(next) { this.next = next; } /** * Clone this node, and optionally its children. * @param recursive Clone child nodes as well. * @returns A clone of the node. */ cloneNode(recursive = false) { return cloneNode(this, recursive); } } /** * A node that contains some data. */ class DataNode extends Node { data; /** * @param data The content of the data node */ constructor(data) { super(); this.data = data; } /** * Same as {@link data}. * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. */ get nodeValue() { return this.data; } set nodeValue(data) { this.data = data; } } /** * Text within the document. */ class Text extends DataNode { type = ElementType.Text; get nodeType() { return 3; } } /** * Comments within the document. */ class Comment extends DataNode { type = ElementType.Comment; get nodeType() { return 8; } } /** * Processing instructions, including doc types. */ class ProcessingInstruction extends DataNode { type = ElementType.Directive; name; constructor(name, data) { super(data); this.name = name; } get nodeType() { return 1; } /** If this is a doctype, the document type name (parse5 only). */ "x-name"; /** If this is a doctype, the document type public identifier (parse5 only). */ "x-publicId"; /** If this is a doctype, the document type system identifier (parse5 only). */ "x-systemId"; } /** * A node that can have children. */ class NodeWithChildren extends Node { children; /** * @param children Children of the node. Only certain node types can have children. */ constructor(children) { super(); this.children = children; } // Aliases /** First child of the node. */ get firstChild() { return this.children[0] ?? null; } /** Last child of the node. */ get lastChild() { return this.children.length > 0 ? this.children[this.children.length - 1] : null; } /** * Same as {@link children}. * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. */ get childNodes() { return this.children; } set childNodes(children) { this.children = children; } } /** * CDATA nodes. */ class CDATA extends NodeWithChildren { type = ElementType.CDATA; get nodeType() { return 4; } } /** * The root node of the document. */ class Document extends NodeWithChildren { type = ElementType.Root; get nodeType() { return 9; } } /** * An element within the DOM. */ class Element extends NodeWithChildren { name; attribs; type; /** * @param name Name of the tag, eg. `div`, `span`. * @param attribs Object mapping attribute names to attribute values. * @param children Children of the node. * @param type Node type used for the new node instance. */ constructor(name, attribs, children = [], type = name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag) { super(children); this.name = name; this.attribs = attribs; this.type = type; } get nodeType() { return 1; } // DOM Level 1 aliases /** * Same as {@link name}. * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. */ get tagName() { return this.name; } set tagName(name) { this.name = name; } get attributes() { return Object.keys(this.attribs).map((name) => ({ name, value: this.attribs[name], namespace: this["x-attribsNamespace"]?.[name], prefix: this["x-attribsPrefix"]?.[name], })); } /** Element namespace (parse5 only). */ namespace; /** Element attribute namespaces (parse5 only). */ "x-attribsNamespace"; /** Element attribute namespace-related prefixes (parse5 only). */ "x-attribsPrefix"; } /** * Checks if `node` is an element node. * @param node Node to check. * @returns `true` if the node is an element node. */ function isTag(node) { return isTag$1(node); } /** * Checks if `node` is a CDATA node. * @param node Node to check. * @returns `true` if the node is a CDATA node. */ function isCDATA(node) { return node.type === ElementType.CDATA; } /** * Checks if `node` is a text node. * @param node Node to check. * @returns `true` if the node is a text node. */ function isText(node) { return node.type === ElementType.Text; } /** * Checks if `node` is a comment node. * @param node Node to check. * @returns `true` if the node is a comment node. */ function isComment(node) { return node.type === ElementType.Comment; } /** * Checks if `node` is a directive node. * @param node Node to check. * @returns `true` if the node is a directive node. */ function isDirective(node) { return node.type === ElementType.Directive; } /** * Checks if `node` is a document node. * @param node Node to check. * @returns `true` if the node is a document node. */ function isDocument(node) { return node.type === ElementType.Root; } /** * Checks if `node` has children. * @param node Node to check. * @returns `true` if the node has children. */ function hasChildren(node) { return Object.hasOwn(node, "children"); } /** * Clone a node, and optionally its children. * @param node Node to clone. * @param recursive Clone child nodes as well. * @returns A clone of the node. */ function cloneNode(node, recursive = false) { let result; if (isText(node)) { result = new Text(node.data); } else if (isComment(node)) { result = new Comment(node.data); } else if (isTag(node)) { const children = recursive ? cloneChildren(node.children) : []; const clone = new Element(node.name, { ...node.attribs }, children); for (const child of children) { child.parent = clone; } if (node.namespace != null) { clone.namespace = node.namespace; } if (node["x-attribsNamespace"]) { clone["x-attribsNamespace"] = { ...node["x-attribsNamespace"] }; } if (node["x-attribsPrefix"]) { clone["x-attribsPrefix"] = { ...node["x-attribsPrefix"] }; } result = clone; } else if (isCDATA(node)) { const children = recursive ? cloneChildren(node.children) : []; const clone = new CDATA(children); for (const child of children) { child.parent = clone; } result = clone; } else if (isDocument(node)) { const children = recursive ? cloneChildren(node.children) : []; const clone = new Document(children); for (const child of children) { child.parent = clone; } if (node["x-mode"]) { clone["x-mode"] = node["x-mode"]; } result = clone; } else if (isDirective(node)) { const instruction = new ProcessingInstruction(node.name, node.data); if (node["x-name"] != null) { instruction["x-name"] = node["x-name"]; instruction["x-publicId"] = node["x-publicId"]; instruction["x-systemId"] = node["x-systemId"]; } result = instruction; } else { throw new Error(`Not implemented yet: ${node.type}`); } result.startIndex = node.startIndex; result.endIndex = node.endIndex; if (node.sourceCodeLocation != null) { result.sourceCodeLocation = node.sourceCodeLocation; } return result; } /** * Clone a list of child nodes. * @param childs The child nodes to clone. * @returns A list of cloned child nodes. */ function cloneChildren(childs) { const children = childs.map((child) => cloneNode(child, true)); for (let index = 1; index < children.length; index++) { children[index].prev = children[index - 1]; children[index - 1].next = children[index]; } return children; } // Default options const defaultOptions = { withStartIndices: false, withEndIndices: false, xmlMode: false, }; /** * Event-based handler that builds a DOM tree from parser callbacks. */ class DomHandler { /** The elements of the DOM */ dom = []; /** The root element for the DOM */ root = new Document(this.dom); /** Called once parsing has completed. */ callback; /** Settings for the handler. */ options; /** Callback whenever a tag is closed. */ elementCB; /** Indicated whether parsing has been completed. */ done = false; /** Stack of open tags. */ tagStack = [this.root]; /** A data node that is still being written to. */ lastNode = null; /** Reference to the parser instance. Used for location information. */ parser = null; /** * @param callback Called once parsing has completed. * @param options Settings for the handler. * @param elementCB Callback whenever a tag is closed. */ constructor(callback, options, elementCB) { // Make it possible to skip arguments, for backwards-compatibility if (typeof options === "function") { elementCB = options; options = defaultOptions; } if (typeof callback === "object") { options = callback; callback = undefined; } this.callback = callback ?? null; this.options = options ?? defaultOptions; this.elementCB = elementCB ?? null; } onparserinit(parser) { this.parser = parser; } // Resets the handler back to starting state onreset() { this.dom = []; this.root = new Document(this.dom); this.done = false; this.tagStack = [this.root]; this.lastNode = null; this.parser = null; } // Signals the handler that parsing is done onend() { if (this.done) return; this.done = true; this.parser = null; this.handleCallback(null); } onerror(error) { this.handleCallback(error); } onclosetag() { this.lastNode = null; const element = this.tagStack.pop(); if (this.options.withEndIndices && this.parser) { element.endIndex = this.parser.endIndex; } if (this.elementCB) this.elementCB(element); } onopentag(name, attribs) { const type = this.options.xmlMode ? ElementType.Tag : undefined; const element = new Element(name, attribs, undefined, type); this.addNode(element); this.tagStack.push(element); } ontext(data) { const { lastNode } = this; if (lastNode && lastNode.type === ElementType.Text) { lastNode.data += data; if (this.options.withEndIndices && this.parser) { lastNode.endIndex = this.parser.endIndex; } } else { const node = new Text(data); this.addNode(node); this.lastNode = node; } } oncomment(data) { if (this.lastNode && this.lastNode.type === ElementType.Comment) { this.lastNode.data += data; return; } const node = new Comment(data); this.addNode(node); this.lastNode = node; } oncommentend() { this.lastNode = null; } oncdatastart() { const text = new Text(""); const node = new CDATA([text]); this.addNode(node); text.parent = node; this.lastNode = text; } oncdataend() { this.lastNode = null; } onprocessinginstruction(name, data) { const node = new ProcessingInstruction(name, data); this.addNode(node); } handleCallback(error) { if (typeof this.callback === "function") { this.callback(error, this.dom); } else if (error) { throw error; } } addNode(node) { const parent = this.tagStack[this.tagStack.length - 1]; const previousSibling = parent.children[parent.children.length - 1]; if (this.options.withStartIndices && this.parser) { node.startIndex = this.parser.startIndex; } if (this.options.withEndIndices && this.parser) { node.endIndex = this.parser.endIndex; } parent.children.push(node); if (previousSibling) { node.prev = previousSibling; previousSibling.next = node; } node.parent = parent; this.lastNode = null; } } var dist = /*#__PURE__*/Object.freeze({ __proto__: null, CDATA: CDATA, Comment: Comment, DataNode: DataNode, Document: Document, DomHandler: DomHandler, Element: Element, Node: Node, NodeWithChildren: NodeWithChildren, ProcessingInstruction: ProcessingInstruction, Text: Text, cloneNode: cloneNode, default: DomHandler, hasChildren: hasChildren, isCDATA: isCDATA, isComment: isComment, isDirective: isDirective, isDocument: isDocument, isTag: isTag, isText: isText }); var require$$3 = /*@__PURE__*/getAugmentedNamespace(dist); var constants = {}; var hasRequiredConstants; function requireConstants () { if (hasRequiredConstants) return constants; hasRequiredConstants = 1; (function (exports$1) { Object.defineProperty(exports$1, "__esModule", { value: true }); exports$1.CASE_SENSITIVE_TAG_NAMES_MAP = exports$1.CASE_SENSITIVE_TAG_NAMES = void 0; /** * SVG elements are case-sensitive. * * @see https://developer.mozilla.org/docs/Web/SVG/Element#svg_elements_a_to_z */ exports$1.CASE_SENSITIVE_TAG_NAMES = [ 'animateMotion', 'animateTransform', 'clipPath', 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence', 'foreignObject', 'linearGradient', 'radialGradient', 'textPath', ]; exports$1.CASE_SENSITIVE_TAG_NAMES_MAP = exports$1.CASE_SENSITIVE_TAG_NAMES.reduce(function (accumulator, tagName) { accumulator[tagName.toLowerCase()] = tagName; return accumulator; }, {}); } (constants)); return constants; } var hasRequiredUtilities$2; function requireUtilities$2 () { if (hasRequiredUtilities$2) return utilities$2; hasRequiredUtilities$2 = 1; Object.defineProperty(utilities$2, "__esModule", { value: true }); utilities$2.hasOpenTag = hasOpenTag; utilities$2.escapeSpecialCharacters = escapeSpecialCharacters; utilities$2.revertEscapedCharacters = revertEscapedCharacters; utilities$2.formatDOM = formatDOM; var domhandler_1 = require$$3; var constants_1 = requireConstants(); var CARRIAGE_RETURN = '\r'; var CARRIAGE_RETURN_REGEX = new RegExp(CARRIAGE_RETURN, 'g'); var CARRIAGE_RETURN_PLACEHOLDER = "__HTML_DOM_PARSER_CARRIAGE_RETURN_PLACEHOLDER_".concat(Date.now().toString(), "__"); var CARRIAGE_RETURN_PLACEHOLDER_REGEX = new RegExp(CARRIAGE_RETURN_PLACEHOLDER, 'g'); /** * Gets case-sensitive tag name. * * @param tagName - Tag name in lowercase. * @returns - Case-sensitive tag name. */ function getCaseSensitiveTagName(tagName) { return constants_1.CASE_SENSITIVE_TAG_NAMES_MAP[tagName]; } /** * Formats DOM attributes to a hash map. * * @param attributes - List of attributes. * @returns - Map of attribute name to value. */ function formatAttributes(attributes) { var map = {}; var index = 0; var attributesLength = attributes.length; // `NamedNodeMap` is array-like for (; index < attributesLength; index++) { var attribute = attributes[index]; map[attribute.name] = attribute.value; } return map; } /** * Corrects the tag name if it is case-sensitive (SVG). * Otherwise, returns the lowercase tag name (HTML). * * @param tagName - Lowercase tag name. * @returns - Formatted tag name. */ function formatTagName(tagName) { tagName = tagName.toLowerCase(); var caseSensitiveTagName = getCaseSensitiveTagName(tagName); if (caseSensitiveTagName) { return caseSensitiveTagName; } return tagName; } /** * Checks if an HTML string contains an opening tag (case-insensitive). * * @param html - HTML string. * @param tagName - Tag name to search for (e.g., 'head' or 'body'). * @returns - Whether the tag is found. */ function hasOpenTag(html, tagName) { var openTag = '<' + tagName; var index = html.toLowerCase().indexOf(openTag); if (index === -1) { return false; } var char = html[index + openTag.length]; // the character after the tag name must be '>' or whitespace (for attributes) return (char === '>' || char === ' ' || char === '\t' || char === '\n' || char === '\r' || char === '/'); } /** * Escapes special characters before parsing. * * @param html - The HTML string. * @returns - HTML string with escaped special characters. */ function escapeSpecialCharacters(html) { return html.replace(CARRIAGE_RETURN_REGEX, CARRIAGE_RETURN_PLACEHOLDER); } /** * Reverts escaped special characters back to actual characters. * * @param text - The text with escaped characters. * @returns - Text with escaped characters reverted. */ function revertEscapedCharacters(text) { return text.replace(CARRIAGE_RETURN_PLACEHOLDER_REGEX, CARRIAGE_RETURN); } /** * Transforms DOM nodes to `domhandler` nodes. * * @param nodes - DOM nodes. * @param parent - Parent node. * @param directive - Directive. * @returns - Nodes. */ function formatDOM(nodes, parent, directive) { var _a, _b, _c, _d; if (parent === void 0) { parent = null; } var domNodes = []; var current; var index = 0; var nodesLength = nodes.length; for (; index < nodesLength; index++) { var node = nodes[index]; // set the node data given the type switch (node.nodeType) { case 1: { var tagName = formatTagName(node.nodeName); // script, style, or tag current = new domhandler_1.Element(tagName, formatAttributes(node.attributes)); current.children = formatDOM( // template children are on content tagName === 'template' ? node.content.childNodes : node.childNodes, current); break; } /* v8 ignore start */ case 3: current = new domhandler_1.Text(revertEscapedCharacters((_a = node.nodeValue) !== null && _a !== void 0 ? _a : '')); break; case 8: current = new domhandler_1.Comment((_b = node.nodeValue) !== null && _b !== void 0 ? _b : ''); break; /* v8 ignore stop */ default: continue; } // set previous node next var prev = (_c = domNodes[index - 1]) !== null && _c !== void 0 ? _c : null; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (prev) { prev.next = current; } // set properties for current node current.parent = parent; current.prev = prev; current.next = null; domNodes.push(current); } if (directive) { current = new domhandler_1.ProcessingInstruction(directive.substring(0, directive.indexOf(' ')).toLowerCase(), directive); current.next = (_d = domNodes[0]) !== null && _d !== void 0 ? _d : null; current.parent = parent; domNodes.unshift(current); if (domNodes[1]) { domNodes[1].prev = domNodes[0]; } } return domNodes; } return utilities$2; } var hasRequiredDomparser; function requireDomparser () { if (hasRequiredDomparser) return domparser; hasRequiredDomparser = 1; Object.defineProperty(domparser, "__esModule", { value: true }); domparser.default = domparser$1; var utilities_1 = requireUtilities$2(); // constants var HTML = 'html'; var HEAD = 'head'; var BODY = 'body'; var FIRST_TAG_REGEX = /<([a-zA-Z]+[0-9]?)/; // e.g., <h1> // falls back to `parseFromString` if `createHTMLDocument` cannot be used /* eslint-disable @typescript-eslint/no-unused-vars */ /* v8 ignore start */ var parseFromDocument = function (html, tagName) { throw new Error('This browser does not support `document.implementation.createHTMLDocument`'); }; var parseFromString = function (html, tagName) { throw new Error('This browser does not support `DOMParser.prototype.parseFromString`'); }; var DOMParser = typeof window === 'object' && window.DOMParser; /** * DOMParser (performance: slow). * * @see https://developer.mozilla.org/docs/Web/API/DOMParser#Parsing_an_SVG_or_HTML_document */ if (typeof DOMParser === 'function') { var domParser_1 = new DOMParser(); var mimeType_1 = 'text/html'; /** * Creates an HTML document using `DOMParser.parseFromString`. * * @param html - The HTML string. * @param tagName - The element to render the HTML (with 'body' as fallback). * @returns - Document. */ parseFromString = function (html, tagName) { if (tagName) { html = "<".concat(tagName, ">").concat(html, "</").concat(tagName, ">"); } return domParser_1.parseFromString(html, mimeType_1); }; parseFromDocument = parseFromString; } /** * DOMImplementation (performance: fair). * * @see https://developer.mozilla.org/docs/Web/API/DOMImplementation/createHTMLDocument */ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (typeof document === 'object' && document.implementation) { var htmlDocument_1 = document.implementation.createHTMLDocument(); /** * Use HTML document created by `document.implementation.createHTMLDocument`. * * @param html - The HTML string. * @param tagName - The element to render the HTML (with 'body' as fallback). * @returns - Document */ parseFromDocument = function (html, tagName) { if (tagName) { var element = htmlDocument_1.documentElement.querySelector(tagName); if (element) { element.innerHTML = html; } return htmlDocument_1; } htmlDocument_1.documentElement.innerHTML = html; return htmlDocument_1; }; } /** * Template (performance: fast). * * @see https://developer.mozilla.org/docs/Web/HTML/Element/template */ var template = typeof document === 'object' && document.createElement('template'); var parseFromTemplate; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (template && template.content) { /** * Uses a template element (content fragment) to parse HTML. * * @param html - HTML string. * @returns - Nodes. */ parseFromTemplate = function (html) { template.innerHTML = html; return template.content.childNodes; }; } var createNodeList = function () { return document.createDocumentFragment().childNodes; }; /* v8 ignore stop */ /** * Parses HTML string to DOM nodes. * * @param html - HTML markup. * @returns - DOM nodes. */ function domparser$1(html) { var _a, _b, _c, _d, _e, _f; // Escape special characters before parsing html = (0, utilities_1.escapeSpecialCharacters)(html); var match = FIRST_TAG_REGEX.exec(html); var firstTagName = (_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.toLowerCase(); switch (firstTagName) { case HTML: { var doc = parseFromString(html); // the created document may come with filler head/body elements, // so make sure to remove them if they don't actually exist if (!(0, utilities_1.hasOpenTag)(html, HEAD)) { var element = doc.querySelector(HEAD); (_b = element === null || element === void 0 ? void 0 : element.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(element); } if (!(0, utilities_1.hasOpenTag)(html, BODY)) { var element = doc.querySelector(BODY); (_c = element === null || element === void 0 ? void 0 : element.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(element); } return doc.querySelectorAll(HTML); } case HEAD: case BODY: { var elements = parseFromDocument(html).querySelectorAll(firstTagName); // if there's a sibling element, then return both elements /* v8 ignore next */ if ((0, utilities_1.hasOpenTag)(html, BODY) && (0, utilities_1.hasOpenTag)(html, HEAD)) { return (_e = (_d = elements[0].parentNode) === null || _d === void 0 ? void 0 : _d.childNodes) !== null && _e !== void 0 ? _e : createNodeList(); } return elements; } // low-level tag or text /* v8 ignore start */ default: { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (parseFromTemplate) { return parseFromTemplate(html); } var element = parseFromDocument(html, BODY).querySelector(BODY); return (_f = element === null || element === void 0 ? void 0 : element.childNodes) !== null && _f !== void 0 ? _f : createNodeList(); } /* v8 ignore stop */ } } return domparser; } var hasRequiredHtmlToDom; function requireHtmlToDom () { if (hasRequiredHtmlToDom) return htmlToDom; hasRequiredHtmlToDom = 1; var __importDefault = (htmlToDom && htmlToDom.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(htmlToDom, "__esModule", { value: true }); htmlToDom.default = HTMLDOMParser; var domparser_1 = __importDefault(requireDomparser()); var utilities_1 = requireUtilities$2(); var DIRECTIVE_REGEX = /<(![a-zA-Z\s]+)>/; // e.g., <!doctype html> /** * Parses HTML string to DOM nodes in browser. * * @param html - HTML markup. * @returns - DOM elements. */ function HTMLDOMParser(html) { if (typeof html !== 'string') { throw new TypeError('First argument must be a string'); } if (!html) { return []; } // match directive var match = DIRECTIVE_REGEX.exec(html); var directive = match ? match[1] : undefined; return (0, utilities_1.formatDOM)((0, domparser_1.default)(html), null, directive); } return htmlToDom; } var attributesToProps = {}; var lib = {}; var possibleStandardNamesOptimized = {}; var hasRequiredPossibleStandardNamesOptimized; function requirePossibleStandardNamesOptimized () { if (hasRequiredPossibleStandardNamesOptimized) return possibleStandardNamesOptimized; hasRequiredPossibleStandardNamesOptimized = 1; // An attribute in which the DOM/SVG standard name is the same as the React prop name (e.g., 'accept'). var SAME = 0; possibleStandardNamesOptimized.SAME = SAME; // An attribute in which the React prop name is the camelcased version of the DOM/SVG standard name (e.g., 'acceptCharset'). var CAMELCASE = 1; possibleStandardNamesOptimized.CAMELCASE = CAMELCASE; possibleStandardNamesOptimized.possibleStandardNames = { accept: 0, acceptCharset: 1, 'accept-charset': 'acceptCharset', accessKey: 1, action: 0, allowFullScreen: 1, alt: 0, as: 0, async: 0, autoCapitalize: 1, autoComplete: 1, autoCorrect: 1, autoFocus: 1, autoPlay: 1, autoSave: 1, capture: 0, cellPadding: 1, cellSpacing: 1, challenge: 0, charSet: 1, checked: 0, children: 0, cite: 0, class: 'className', classID: 1, className: 1, cols: 0, colSpan: 1, content: 0, contentEditable: 1, contextMenu: 1, controls: 0, controlsList: 1, coords: 0, crossOrigin: 1, dangerouslySetInnerHTML: 1, data: 0, dateTime: 1, default: 0, defaultChecked: 1, defaultValue: 1, defer: 0, dir: 0, disabled: 0, disablePictureInPicture: 1, disableRemotePlayback: 1, download: 0, draggable: 0, encType: 1, enterKeyHint: 1, for: 'htmlFor', form: 0, formMethod: 1, formAction: 1, formEncType: 1, formNoValidate: 1, formTarget: 1, frameBorder: 1, headers: 0, height: 0, hidden: 0, high: 0, href: 0, hrefLang: 1, htmlFor: 1, httpEquiv: 1, 'http-equiv': 'httpEquiv', icon: 0, id: 0, innerHTML: 1, inputMode: 1, integrity: 0, is: 0, itemID: 1, itemProp: 1, itemRef: 1, itemScope: 1, itemType: 1, keyParams: 1, keyType: 1, kind: 0, label: 0, lang: 0, list: 0, loop: 0, low: 0, manifest: 0, marginWidth: 1, marginHeight: 1, max: 0, maxLength: 1, media: 0, mediaGroup: 1, method: 0, min: 0, minLength: 1, multiple: 0, muted: 0, name: 0, noModule: 1, nonce: 0, noValidate: 1, open: 0, optimum: 0, pattern: 0, placeholder: 0, playsInline: 1, poster: 0, preload: 0, profile: 0, radioGroup: 1, readOnly: 1, referrerPolicy: 1, rel: 0, required: 0, reversed: 0, role: 0, rows: 0, rowSpan: 1, sandbox: 0, scope: 0, scoped: 0, scrolling: 0, seamless: 0, selected: 0, shape: 0, size: 0, sizes: 0, span: 0, spellCheck: 1, src: 0, srcDoc: 1, srcLang: 1, srcSet: 1, start: 0, step: 0, style: 0, summary: 0, tabIndex: 1, target: 0, title: 0, type: 0, useMap: 1, value: 0, width: 0, wmode: 0, wrap: 0, about: 0, accentHeight: 1, 'accent-height': 'accentHeight', accumulate: 0, additive: 0, alignmentBaseline: 1, 'alignment-baseline': 'alignmentBaseline', allowReorder: 1, alphabetic: 0, amplitude: 0, arabicForm: 1, 'arabic-form': 'arabicForm', ascent: 0, attributeName: 1, attributeType: 1, autoReverse: 1, azimuth: 0, baseFrequency: 1, baselineShift: 1, 'baseline-shift': 'baselineShift', baseProfile: 1, bbox: 0, begin: 0, bias: 0, by: 0, calcMode: 1, capHeight: 1, 'cap-height': 'capHeight', clip: 0, clipPath: 1, 'clip-path': 'clipPath', clipPathUnits: 1, clipRule: 1, 'clip-rule': 'clipRule', color: 0, colorInterpolation: 1, 'color-interpolation': 'colorInterpolation', colorInterpolationFilters: 1, 'color-interpolation-filters': 'colorInterpolationFilters', colorProfile: 1, 'color-profile': 'colorProfile', colorRendering: 1, 'color-rendering': 'colorRendering', contentScriptType: 1, contentStyleType: 1, cursor: 0, cx: 0, cy: 0, d: 0, datatype: 0, decelerate: 0, descent: 0, diffuseConstant: 1, direction: 0, display: 0, divisor: 0, dominantBaseline: 1, 'dominant-baseline': 'dominantBaseline', dur: 0, dx: 0, dy: 0, edgeMode: 1, elevation: 0, enableBackground: 1, 'enable-background': 'enableBackground', end: 0, exponent: 0, externalResourcesRequired: 1, fill: 0, fillOpacity: 1, 'fill-opacity': 'fillOpacity', fillRule: 1, 'fill-rule': 'fillRule', filter: 0, filterRes: 1, filterUnits: 1, floodOpacity: 1, 'flood-opacity': 'floodOpacity', floodColor: 1, 'flood-color': 'floodColor', focusable: 0, fontFamily: 1, 'font-family': 'fontFamily', fontSize: 1, 'font-size': 'fontSize', fontSizeAdjust: 1, 'font-size-adjust': 'fontSizeAdjust', fontStretch: 1, 'font-stretch': 'fontStretch', fontStyle: 1, 'font-style': 'fontStyle', fontVariant: 1, 'font-variant': 'fontVariant', fontWeight: 1, 'font-weight': 'fontWeight', format: 0, from: 0, fx: 0, fy: 0, g1: 0, g2: 0, glyphName: 1, 'glyph-name': 'glyphName', glyphOrientationHorizontal: 1, 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', glyphOrientationVertical: 1, 'glyph-orientation-vertical': 'glyphOrientationVertical', glyphRef: 1, gradientTransform: 1, gradientUnits: 1, hanging: 0, horizAdvX: 1, 'horiz-adv-x': 'horizAdvX', horizOriginX: 1, 'horiz-origin-x': 'horizOriginX', ideographic: 0, imageRendering: 1, 'image-rendering': 'imageRendering', in2: 0, in: 0, inlist: 0, intercept: 0, k1: 0, k2: 0, k3: 0, k4: 0, k: 0, kernelMatrix: 1, kernelUnitLength: 1, kerning: 0, keyPoints: 1, keySplines: 1, keyTimes: 1, lengthAdjust: 1, letterSpacing: 1, 'letter-spacing': 'letterSpacing', lightingColor: 1, 'lighting-color': 'lightingColor', limitingConeAngle: 1, local: 0, markerEnd: 1, 'marker-end': 'markerEnd', markerHeight: 1, markerMid: 1, 'marker-mid': 'markerMid', markerStart: 1, 'marker-start': 'markerStart', markerUnits: 1, markerWidth: 1, mask: 0, maskContentUnits: 1, maskUnits: 1, mathematical: 0, mode: 0, numOctaves: 1, offset: 0, opacity: 0, operator: 0, order: 0, orient: 0, orientation: 0, origin: 0, overflow: 0, overlinePosition: 1, 'overline-position': 'overlinePosition', overlineThickness: 1, 'overline-thickness': 'overlineThickness', paintOrder: 1, 'paint-order': 'paintOrder', panose1: 0, 'panose-1': 'panose1', pathLength: 1, patternContentUnits: 1, patternTransform: 1, patternUnits: 1, pointerEvents: 1, 'pointer-events': 'pointerEvents', points: 0, pointsAtX: 1, pointsAtY: 1, pointsAtZ: 1, prefix: 0, preserveAlpha: 1, preserveAspectRatio: 1, primitiveUnits: 1, property: 0, r: 0, radius: 0, refX: 1, refY: 1, renderingIntent: 1, 'rendering-intent': 'renderingIntent', repeatCount: 1, repeatDur: 1, requiredExtensions: 1, requiredFeatures: 1, resource: 0, restart: 0, result: 0, results: 0, rotate: 0, rx: 0, ry: 0, scale: 0, security: 0, seed: 0, shapeRendering: 1, 'shape-rendering': 'shapeRendering', slope: 0, spacing: 0, specularConstant: 1, specularExponent: 1, speed: 0, spreadMethod: 1, startOffset: 1, stdDeviation: 1, stemh: 0, stemv: 0, stitchTiles: 1, stopColor: 1, 'stop-color': 'stopColor', stopOpacity: 1, 'stop-opacity': 'stopOpacity', strikethroughPosition: 1, 'strikethrough-position': 'strikethroughPosition', strikethroughThickness: 1, 'strikethrough-thickness': 'strikethroughThickness', string: 0, stroke: 0, strokeDasharray: 1, 'stroke-dasharray': 'strokeDasharray', strokeDashoffset: 1, 'stroke-dashoffset': 'strokeDashoffset', strokeLinecap: 1, 'stroke-linecap': 'strokeLinecap', strokeLinejoin: 1, 'stroke-linejoin': 'strokeLinejoin', strokeMiterlimit: 1, 'stroke-miterlimit': 'strokeMiterlimit', strokeWidth: 1, 'stroke-width': 'strokeWidth', strokeOpacity: 1, 'stroke-opacity': 'strokeOpacity', suppressContentEditableWarning: 1, suppressHydrationWarning: 1, surfaceScale: 1, systemLanguage: 1, tableValues: 1, targetX: 1, targetY: 1, textAnchor: 1, 'text-anchor': 'textAnchor', textDecoration: 1, 'text-decoration': 'textDecoration', textLength: 1, textRendering: 1, 'text-rendering': 'textRendering', to: 0, transform: 0, typeof: 0, u1: 0, u2: 0, underlinePosition: 1, 'underline-position': 'underlinePosition', underlineThickness: 1, 'underline-thickness': 'underlineThickness', unicode: 0, unicodeBidi: 1, 'unicode-bidi': 'unicodeBidi', unicodeRange: 1, 'unicode-range': 'unicodeRange', unitsPerEm: 1, 'units-per-em': 'unitsPerEm', unselectable: 0, vAlphabetic: 1, 'v-alphabetic': 'vAlphabetic', values: 0, vectorEffect: 1, 'vector-effect': 'vectorEffect', version: 0, vertAdvY: 1, 'vert-adv-y': 'vertAdvY', vertOriginX: 1, 'vert-origin-x': 'vertOriginX', vertOriginY: 1, 'vert-origin-y': 'vertOriginY', vHanging: 1, 'v-hanging': 'vHanging', vIdeographic: 1, 'v-ideographic': 'vIdeographic', viewBox: 1, viewTarget: 1, visibility: 0, vMathematical: 1, 'v-mathematical': 'vMathematical', vocab: 0, widths: 0, wordSpacing: 1, 'word-spacing': 'wordSpacing', writingMode: 1, 'writing-mode': 'writingMode', x1: 0, x2: 0, x: 0, xChannelSelector: 1, xHeight: 1, 'x-height': 'xHeight', xlinkActuate: 1, 'xlink:actuate': 'xlinkActuate', xlinkArcrole: 1, 'xlink:arcrole': 'xlinkArcrole', xlinkHref: 1, 'xlink:href': 'xlinkHref', xlinkRole: 1, 'xlink:role': 'xlinkRole', xlinkShow: 1, 'xlink:show': 'xlinkShow', xlinkTitle: 1, 'xlink:title': 'xlinkTitle', xlinkType: 1, 'xlink:type': 'xlinkType', xmlBase: 1, 'xml:base': 'xmlBase', xmlLang: 1, 'xml:lang': 'xmlLang', xmlns: 0, 'xml:space': 'xmlSpace', xmlnsXlink: 1, 'xmlns:xlink': 'xmlnsXlink', xmlSpace: 1, y1: 0, y2: 0, y: 0, yChannelSelector: 1, z: 0, zoomAndPan: 1 }; return possibleStandardNamesOptimized; } var hasRequiredLib$1; function requireLib$1 () { if (hasRequiredLib$1) return lib; hasRequiredLib$1 = 1; /** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ // A reserved attribute. // It is handled by React separately and shouldn't be written to the DOM. const RESERVED = 0; // A simple string attribute. // Attributes that aren't in the filter are presumed to have this type. const STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called // "enumerated" attributes with "true" and "false" as possible values. // When true, it should be set to a "true" string. // When false, it should be set to a "false" string. const BOOLEANISH_STRING = 2; // A real boolean attribute. // When true, it should be present (set either to an empty string or its name). // When false, it should be omitted. const BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value. // When true, it should be present (set either to an empty string or its name). // When false, it should be omitted. // For any other value, should be present with that value. const OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric. // When falsy, it should be removed. const NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric. // When falsy, it should be removed. const POSITIVE_NUMERIC = 6; function getPropertyInfo(name) { return properties.hasOwnProperty(name) ? properties[name] : null; } function PropertyInfoRecord( name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString, ) { this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; this.attributeName = attributeName; this.attributeNamespace = attributeNamespace; this.mustUseProperty = mustUseProperty; this.propertyName = name; this.type = type; this.sanitizeURL = sanitizeURL; this.removeEmptyString = removeEmptyString; } // When adding attributes to this list, be sure to also add them to // the `possibleStandardNames` module to ensure casing and incorrect // name warnings. const properties = {}; // These props are reserved by React. They shouldn't be written to the DOM. const reservedProps = [ 'children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular // elements (not just inputs). Now that ReactDOMInput assigns to the // defaultValue property -- do we need this? 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style', ]; reservedProps.forEach(name => { properties[name] = new PropertyInfoRecord( name, RESERVED, false, // mustUseProperty name, // attributeName null, // attributeNamespace false, // sanitizeURL false, // removeEmptyString ); }); // A few React string attributes have a different name. // This is a mapping from React prop names to the attribute names. [ ['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv'], ].forEach(([name, attributeName]) => { properties[name] = new PropertyInfoRecord( name, STRING, false, // mustUseProperty attributeName, // attributeName null, // attributeNamespace false, // sanitizeURL false, // removeEmptyString ); }); // These are "enumerated" HTML attributes that accept "true" and "false". // In React, we let users pass `true` and `false` even though technically // these aren't boolean attributes (they are coerced to strings). ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(name => { properties[name] = new PropertyInfoRecord( name, BOOLEANISH_STRING, false, // mustUseProperty name.toLowerCase(), // attributeName null, // attributeNamespace false, // sanitizeURL false, // removeEmptyString ); }); // These are "enumerated" SVG attributes that accept "true" and "false". // In React, we let users pass `true` and `false` even though technically // these aren't boolean attributes (they are coerced to strings). // Since these are SVG attributes, their attribute names are case-sensitive. [ 'autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha', ].forEach(name => { properties[name] = new PropertyInfoRecord( name, BOOLEANISH_STRING, false, // mustUseProperty name, // attributeName null, // attributeNamespace false, // sanitizeURL false, // removeEmptyString ); }); // These are HTML boolean attributes. [ 'allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM // on the client side because the browsers are inconsistent. Instead we call focus(). 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemo