"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const VoidElements_1 = __importDefault(require("../config/VoidElements")); const UnnestableElements_1 = __importDefault(require("../config/UnnestableElements")); const ChildLessElements_1 = __importDefault(require("../config/ChildLessElements")); const he_1 = require("he"); const NamespaceURI_1 = __importDefault(require("../config/NamespaceURI")); const PlainTextElements_1 = __importDefault(require("../config/PlainTextElements")); const CONDITION_COMMENT_REGEXP = //gi; const CONDITION_COMMENT_END_REGEXP = //gi; const MARKUP_REGEXP = /<(\/?)([a-z][-.0-9_a-z]*)\s*([^<>]*?)(\/?)>/gi; const COMMENT_REGEXP = /|<([!?])([^>]*)>/gi; const DOCUMENT_TYPE_ATTRIBUTE_REGEXP = /"([^"]+)"/gm; const ATTRIBUTE_REGEXP = /([^\s=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+)))/gms; /** * XML parser. */ class XMLParser { /** * Parses XML/HTML and returns a root element. * * @param document Document. * @param data HTML data. * @param [evaluateScripts = false] Set to "true" to enable script execution. * @returns Root element. */ static parse(document, data, evaluateScripts = false) { const root = document.createDocumentFragment(); const stack = [root]; const markupRegexp = new RegExp(MARKUP_REGEXP, 'gi'); let parent = root; let parentTagName = null; let parentUnnestableTagName = null; let lastTextIndex = 0; let match; if (data !== null && data !== undefined) { data = String(data); while ((match = markupRegexp.exec(data))) { const tagName = match[2].toLowerCase(); const isStartTag = !match[1]; if (parent && match.index !== lastTextIndex) { const text = data.substring(lastTextIndex, match.index); if (parentTagName && PlainTextElements_1.default.includes(parentTagName)) { parent.appendChild(document.createTextNode(text)); } else { let condCommMatch; let condCommEndMatch; const condCommRegexp = new RegExp(CONDITION_COMMENT_REGEXP, 'gi'); const condCommEndRegexp = new RegExp(CONDITION_COMMENT_END_REGEXP, 'gi'); // @Refer: https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/?redirectedfrom=MSDN if (isStartTag && (condCommMatch = condCommRegexp.exec(text)) && condCommMatch[0] && (condCommEndMatch = condCommEndRegexp.exec(data.substring(markupRegexp.lastIndex))) && condCommEndMatch[0]) { markupRegexp.lastIndex += condCommEndRegexp.lastIndex; continue; } else { this.appendTextAndCommentNodes(document, parent, text); } } } if (isStartTag) { const namespaceURI = tagName === 'svg' ? NamespaceURI_1.default.svg : parent.namespaceURI || NamespaceURI_1.default.html; const newElement = document.createElementNS(namespaceURI, tagName); // Scripts are not allowed to be executed when they are parsed using innerHTML, outerHTML, replaceWith() etc. // However, they are allowed to be executed when document.write() is used. // See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement if (tagName === 'script') { newElement._evaluateScript = evaluateScripts; } // An assumption that the same rule should be applied for the HTMLLinkElement is made here. if (tagName === 'link') { newElement._evaluateCSS = evaluateScripts; } this.setAttributes(newElement, match[3]); if (!match[4] && !VoidElements_1.default.includes(tagName)) { // Some elements are not allowed to be nested (e.g. "" is not allowed.). // Therefore we will auto-close the tag. if (parentUnnestableTagName === tagName) { stack.pop(); parent = parent.parentNode || root; } parent = parent.appendChild(newElement); parentTagName = tagName; parentUnnestableTagName = this.getUnnestableTagName(parent); stack.push(parent); } else { parent.appendChild(newElement); } lastTextIndex = markupRegexp.lastIndex; // Tags which contain non-parsed content // For example: