UNPKG

@stencil/core

Version:

A Compiler for Web Components and Progressive Web Apps

1,357 lines (1,297 loc) 298 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const CONTENT_REF_ID = 'r'; const ORG_LOCATION_ID = 'o'; const SLOT_NODE_ID = 's'; const TEXT_NODE_ID = 't'; const XLINK_NS = 'http://www.w3.org/1999/xlink'; class MockAttributeMap { constructor(caseInsensitive = false) { this.caseInsensitive = caseInsensitive; this.items = []; } get length() { return this.items.length; } item(index) { return this.items[index] || null; } setNamedItem(attr) { attr.namespaceURI = null; this.setNamedItemNS(attr); } setNamedItemNS(attr) { if (attr != null && attr.value != null) { attr.value = String(attr.value); } const existingAttr = this.items.find(a => a.name === attr.name && a.namespaceURI === attr.namespaceURI); if (existingAttr != null) { existingAttr.value = attr.value; } else { this.items.push(attr); } } getNamedItem(attrName) { if (this.caseInsensitive) { attrName = attrName.toLowerCase(); } return this.getNamedItemNS(null, attrName); } getNamedItemNS(namespaceURI, attrName) { namespaceURI = getNamespaceURI(namespaceURI); return this.items.find(attr => attr.name === attrName && getNamespaceURI(attr.namespaceURI) === namespaceURI) || null; } removeNamedItem(attr) { this.removeNamedItemNS(attr); } removeNamedItemNS(attr) { for (let i = 0, ii = this.items.length; i < ii; i++) { if (this.items[i].name === attr.name && this.items[i].namespaceURI === attr.namespaceURI) { this.items.splice(i, 1); break; } } } } function getNamespaceURI(namespaceURI) { return namespaceURI === XLINK_NS ? null : namespaceURI; } function cloneAttributes(srcAttrs, sortByName = false) { const dstAttrs = new MockAttributeMap(srcAttrs.caseInsensitive); if (srcAttrs != null) { const attrLen = srcAttrs.length; if (sortByName && attrLen > 1) { const sortedAttrs = []; for (let i = 0; i < attrLen; i++) { const srcAttr = srcAttrs.item(i); const dstAttr = new MockAttr(srcAttr.name, srcAttr.value, srcAttr.namespaceURI); sortedAttrs.push(dstAttr); } sortedAttrs.sort(sortAttributes).forEach(attr => { dstAttrs.setNamedItemNS(attr); }); } else { for (let i = 0; i < attrLen; i++) { const srcAttr = srcAttrs.item(i); const dstAttr = new MockAttr(srcAttr.name, srcAttr.value, srcAttr.namespaceURI); dstAttrs.setNamedItemNS(dstAttr); } } } return dstAttrs; } function sortAttributes(a, b) { if (a.name < b.name) return -1; if (a.name > b.name) return 1; return 0; } class MockAttr { constructor(attrName, attrValue = '', namespaceURI = null) { this._name = attrName; this._value = String(attrValue || ''); this._namespaceURI = namespaceURI; } get name() { return this._name; } set name(value) { this._name = value.toLowerCase(); } get value() { return this._value; } set value(value) { this._value = String(value || ''); } get nodeName() { return this._name; } set nodeName(value) { this._name = value; } get nodeValue() { return this._value; } set nodeValue(value) { this._value = String(value || ''); } get namespaceURI() { return this._namespaceURI; } set namespaceURI(namespaceURI) { this._namespaceURI = namespaceURI; } } const registryMap = new WeakMap(); const whenDefinedResolvesMap = new WeakMap(); class MockCustomElementRegistry { constructor(win) { this.win = win; } define(tagName, cstr, options) { if (tagName.toLowerCase() !== tagName) { throw new Error(`Failed to execute 'define' on 'CustomElementRegistry': "${tagName}" is not a valid custom element name`); } let registry = registryMap.get(this); if (registry == null) { registry = new Map(); registryMap.set(this, registry); } registry.set(tagName, { cstr, options }); const whenDefinedResolves = whenDefinedResolvesMap.get(this); if (whenDefinedResolves != null) { const whenDefinedResolveFns = whenDefinedResolves.get(tagName); if (whenDefinedResolveFns != null) { whenDefinedResolveFns.forEach(whenDefinedResolveFn => { whenDefinedResolveFn(); }); whenDefinedResolveFns.length = 0; whenDefinedResolves.delete(tagName); } } const doc = this.win.document; if (doc != null) { const hosts = doc.querySelectorAll(tagName); hosts.forEach(host => { if (upgradedElements.has(host) === false) { tempDisableCallbacks.add(doc); const upgradedCmp = createCustomElement(this, doc, tagName); for (let i = 0; i < host.childNodes.length; i++) { const childNode = host.childNodes[i]; childNode.remove(); upgradedCmp.appendChild(childNode); } tempDisableCallbacks.delete(doc); if (proxyElements.has(host)) { proxyElements.set(host, upgradedCmp); } } fireConnectedCallback(host); }); } } get(tagName) { const registry = registryMap.get(this); if (registry != null) { const def = registry.get(tagName.toLowerCase()); if (def != null) { return def.cstr; } } return undefined; } upgrade(_rootNode) { // } whenDefined(tagName) { tagName = tagName.toLowerCase(); const registry = registryMap.get(this); if (registry != null && registry.has(tagName) === true) { return Promise.resolve(); } return new Promise(resolve => { let whenDefinedResolves = whenDefinedResolvesMap.get(this); if (whenDefinedResolves == null) { whenDefinedResolves = new Map(); whenDefinedResolvesMap.set(this, whenDefinedResolves); } let whenDefinedResolveFns = whenDefinedResolves.get(tagName); if (whenDefinedResolveFns == null) { whenDefinedResolveFns = []; whenDefinedResolves.set(tagName, whenDefinedResolveFns); } whenDefinedResolveFns.push(resolve); }); } } function resetCustomElementRegistry(customElements) { if (customElements != null) { const registry = registryMap.get(customElements); if (registry != null) { registry.clear(); } const whenDefinedResolves = whenDefinedResolvesMap.get(customElements); if (whenDefinedResolves != null) { whenDefinedResolves.clear(); } } } function createCustomElement(customElements, ownerDocument, tagName) { const Cstr = customElements.get(tagName); if (Cstr != null) { const cmp = new Cstr(ownerDocument); cmp.nodeName = tagName.toUpperCase(); upgradedElements.add(cmp); return cmp; } const host = new Proxy({}, { get(obj, prop) { const elm = proxyElements.get(host); if (elm != null) { return elm[prop]; } return obj[prop]; }, set(obj, prop, val) { const elm = proxyElements.get(host); if (elm != null) { elm[prop] = val; } else { obj[prop] = val; } return true; }, has(obj, prop) { const elm = proxyElements.get(host); if (prop in elm) { return true; } if (prop in obj) { return true; } return false; } }); const elm = new MockHTMLElement(ownerDocument, tagName); proxyElements.set(host, elm); return host; } const proxyElements = new WeakMap(); const upgradedElements = new WeakSet(); function connectNode(ownerDocument, node) { node.ownerDocument = ownerDocument; if (node.nodeType === 1 /* ELEMENT_NODE */) { if (ownerDocument != null && node.nodeName.includes('-')) { const win = ownerDocument.defaultView; if (win != null && win.customElements != null) { if (typeof node.connectedCallback === 'function' && node.isConnected) { fireConnectedCallback(node); } } const shadowRoot = node.shadowRoot; if (shadowRoot != null) { shadowRoot.childNodes.forEach(childNode => { connectNode(ownerDocument, childNode); }); } } node.childNodes.forEach(childNode => { connectNode(ownerDocument, childNode); }); } else { node.childNodes.forEach(childNode => { childNode.ownerDocument = ownerDocument; }); } } function fireConnectedCallback(node) { if (typeof node.connectedCallback === 'function') { if (tempDisableCallbacks.has(node.ownerDocument) === false) { try { node.connectedCallback(); } catch (e) { console.error(e); } } } } function disconnectNode(node) { if (node.nodeType === 1 /* ELEMENT_NODE */) { if (node.nodeName.includes('-') === true && typeof node.disconnectedCallback === 'function') { if (tempDisableCallbacks.has(node.ownerDocument) === false) { try { node.disconnectedCallback(); } catch (e) { console.error(e); } } } node.childNodes.forEach(disconnectNode); } } function attributeChanged(node, attrName, oldValue, newValue) { attrName = attrName.toLowerCase(); const observedAttributes = node.constructor.observedAttributes; if (Array.isArray(observedAttributes) === true && observedAttributes.some(obs => obs.toLowerCase() === attrName) === true) { try { node.attributeChangedCallback(attrName, oldValue, newValue); } catch (e) { console.error(e); } } } function checkAttributeChanged(node) { return (node.nodeName.includes('-') === true && typeof node.attributeChangedCallback === 'function'); } const tempDisableCallbacks = new Set(); var cssWhat = parse; var re_name = /^(?:\\.|[\w\-\u00b0-\uFFFF])+/, re_escape = /\\([\da-f]{1,6}\s?|(\s)|.)/ig, //modified version of https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L87 re_attr = /^\s*((?:\\.|[\w\u00b0-\uFFFF\-])+)\s*(?:(\S?)=\s*(?:(['"])([^]*?)\3|(#?(?:\\.|[\w\u00b0-\uFFFF\-])*)|)|)\s*(i)?\]/; var actionTypes = { __proto__: null, "undefined": "exists", "": "equals", "~": "element", "^": "start", "$": "end", "*": "any", "!": "not", "|": "hyphen" }; var simpleSelectors = { __proto__: null, ">": "child", "<": "parent", "~": "sibling", "+": "adjacent" }; var attribSelectors = { __proto__: null, "#": ["id", "equals"], ".": ["class", "element"] }; //pseudos, whose data-property is parsed as well var unpackPseudos = { __proto__: null, "has": true, "not": true, "matches": true }; var stripQuotesFromPseudos = { __proto__: null, "contains": true, "icontains": true }; var quotes = { __proto__: null, "\"": true, "'": true }; //unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L139 function funescape( _, escaped, escapedWhitespace ) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint // Support: Firefox // Workaround erroneous numeric interpretation of +"0x" return high !== high || escapedWhitespace ? escaped : // BMP codepoint high < 0 ? String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); } function unescapeCSS(str){ return str.replace(re_escape, funescape); } function isWhitespace(c){ return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r"; } function parse(selector, options){ var subselects = []; selector = parseSelector(subselects, selector + "", options); if(selector !== ""){ throw new SyntaxError("Unmatched selector: " + selector); } return subselects; } function parseSelector(subselects, selector, options){ var tokens = [], sawWS = false, data, firstChar, name, quot; function getName(){ var sub = selector.match(re_name)[0]; selector = selector.substr(sub.length); return unescapeCSS(sub); } function stripWhitespace(start){ while(isWhitespace(selector.charAt(start))) start++; selector = selector.substr(start); } function isEscaped(pos) { var slashCount = 0; while (selector.charAt(--pos) === "\\") slashCount++; return (slashCount & 1) === 1; } stripWhitespace(0); while(selector !== ""){ firstChar = selector.charAt(0); if(isWhitespace(firstChar)){ sawWS = true; stripWhitespace(1); } else if(firstChar in simpleSelectors){ tokens.push({type: simpleSelectors[firstChar]}); sawWS = false; stripWhitespace(1); } else if(firstChar === ","){ if(tokens.length === 0){ throw new SyntaxError("empty sub-selector"); } subselects.push(tokens); tokens = []; sawWS = false; stripWhitespace(1); } else { if(sawWS){ if(tokens.length > 0){ tokens.push({type: "descendant"}); } sawWS = false; } if(firstChar === "*"){ selector = selector.substr(1); tokens.push({type: "universal"}); } else if(firstChar in attribSelectors){ selector = selector.substr(1); tokens.push({ type: "attribute", name: attribSelectors[firstChar][0], action: attribSelectors[firstChar][1], value: getName(), ignoreCase: false }); } else if(firstChar === "["){ selector = selector.substr(1); data = selector.match(re_attr); if(!data){ throw new SyntaxError("Malformed attribute selector: " + selector); } selector = selector.substr(data[0].length); name = unescapeCSS(data[1]); if( !options || ( "lowerCaseAttributeNames" in options ? options.lowerCaseAttributeNames : !options.xmlMode ) ){ name = name.toLowerCase(); } tokens.push({ type: "attribute", name: name, action: actionTypes[data[2]], value: unescapeCSS(data[4] || data[5] || ""), ignoreCase: !!data[6] }); } else if(firstChar === ":"){ if(selector.charAt(1) === ":"){ selector = selector.substr(2); tokens.push({type: "pseudo-element", name: getName().toLowerCase()}); continue; } selector = selector.substr(1); name = getName().toLowerCase(); data = null; if(selector.charAt(0) === "("){ if(name in unpackPseudos){ quot = selector.charAt(1); var quoted = quot in quotes; selector = selector.substr(quoted + 1); data = []; selector = parseSelector(data, selector, options); if(quoted){ if(selector.charAt(0) !== quot){ throw new SyntaxError("unmatched quotes in :" + name); } else { selector = selector.substr(1); } } if(selector.charAt(0) !== ")"){ throw new SyntaxError("missing closing parenthesis in :" + name + " " + selector); } selector = selector.substr(1); } else { var pos = 1, counter = 1; for(; counter > 0 && pos < selector.length; pos++){ if(selector.charAt(pos) === "(" && !isEscaped(pos)) counter++; else if(selector.charAt(pos) === ")" && !isEscaped(pos)) counter--; } if(counter){ throw new SyntaxError("parenthesis not matched"); } data = selector.substr(1, pos - 2); selector = selector.substr(pos); if(name in stripQuotesFromPseudos){ quot = data.charAt(0); if(quot === data.slice(-1) && quot in quotes){ data = data.slice(1, -1); } data = unescapeCSS(data); } } } tokens.push({type: "pseudo", name: name, data: data}); } else if(re_name.test(selector)){ name = getName(); if(!options || ("lowerCaseTags" in options ? options.lowerCaseTags : !options.xmlMode)){ name = name.toLowerCase(); } tokens.push({type: "tag", name: name}); } else { if(tokens.length && tokens[tokens.length - 1].type === "descendant"){ tokens.pop(); } addToken(subselects, tokens); return selector; } } } addToken(subselects, tokens); return selector; } function addToken(subselects, tokens){ if(subselects.length > 0 && tokens.length === 0){ throw new SyntaxError("empty sub-selector"); } subselects.push(tokens); } function closest(selector, elm) { while (elm != null) { if (elm.matches(selector)) { return elm; } elm = elm.parentNode; } return null; } function matches(selector, elm) { const selectors = cssWhat(selector); return matchesSelectors(selectors, elm); } function selectOne(selector, elm) { const selectors = cssWhat(selector); return selectOneRecursion(selectors, elm); } function selectOneRecursion(selectors, elm) { const children = elm.children; for (let i = 0, ii = children.length; i < ii; i++) { if (matchesSelectors(selectors, children[i]) === true) { return children[i]; } const childMatch = selectOneRecursion(selectors, children[i]); if (childMatch != null) { return childMatch; } } return null; } function selectAll(selector, elm) { const selectors = cssWhat(selector); const foundElms = []; selectAllRecursion(selectors, elm, foundElms); return foundElms; } function selectAllRecursion(selectors, elm, found) { const children = elm.children; for (let i = 0, ii = children.length; i < ii; i++) { if (matchesSelectors(selectors, children[i]) === true) { found.push(children[i]); } selectAllRecursion(selectors, children[i], found); } } function matchesSelectors(selectors, elm) { for (let i = 0, ii = selectors.length; i < ii; i++) { if (matchesEverySelector(selectors[i], elm) === true) { return true; } } return false; } function matchesEverySelector(selectorData, elm) { for (let i = 0, ii = selectorData.length; i < ii; i++) { if (matchesSelector(selectorData[i], elm) === false) { return false; } } return true; } function matchesSelector(selectorData, elm) { switch (selectorData.type) { case 'tag': return elm.nodeName.toLowerCase() === selectorData.name.toLowerCase(); case 'attribute': if (selectorData.name === 'class') { return elm.classList.contains(selectorData.value); } if (selectorData.action === 'exists') { return elm.hasAttribute(selectorData.name); } if (selectorData.action === 'equals') { return elm.getAttribute(selectorData.name) === selectorData.value; } return false; case 'child': // TODO return true; } return false; } class CSSStyleDeclaration { constructor() { this._styles = new Map(); } setProperty(prop, value) { prop = jsCaseToCssCase(prop); if (value == null || value === '') { this._styles.delete(prop); } else { this._styles.set(prop, String(value)); } } getPropertyValue(prop) { prop = jsCaseToCssCase(prop); return String(this._styles.get(prop) || ''); } removeProperty(prop) { prop = jsCaseToCssCase(prop); this._styles.delete(prop); } get length() { return this._styles.size; } get cssText() { const cssText = []; this._styles.forEach((value, prop) => { cssText.push(`${prop}: ${value};`); }); return cssText.join(' ').trim(); } set cssText(cssText) { if (cssText == null || cssText === '') { this._styles.clear(); return; } cssText.split(';').forEach(rule => { rule = rule.trim(); if (rule.length > 0) { const splt = rule.split(':'); if (splt.length > 1) { const prop = splt[0].trim(); const value = splt[1].trim(); if (prop !== '' && value !== '') { this._styles.set(jsCaseToCssCase(prop), value); } } } }); } } function createCSSStyleDeclaration() { return new Proxy(new CSSStyleDeclaration(), cssProxyHandler); } const cssProxyHandler = { get(cssStyle, prop) { if (prop in cssStyle) { return cssStyle[prop]; } prop = cssCaseToJsCase(prop); return cssStyle.getPropertyValue(prop); }, set(cssStyle, prop, value) { if (prop in cssStyle) { cssStyle[prop] = value; } else { cssStyle.setProperty(prop, value); } return true; } }; function cssCaseToJsCase(str) { // font-size to fontSize if (str.length > 1 && str.includes('-') === true) { str = str.toLowerCase().split('-').map(segment => segment.charAt(0).toUpperCase() + segment.slice(1)).join(''); str = str.substr(0, 1).toLowerCase() + str.substr(1); } return str; } function jsCaseToCssCase(str) { // fontSize to font-size if (str.length > 1 && (str.includes('-') === false && /[A-Z]/.test(str) === true)) { str = str.replace(/([A-Z])/g, g => ' ' + g[0]).trim().replace(/ /g, '-').toLowerCase(); } return str; } function dataset(elm) { const ds = {}; const attributes = elm.attributes; const attrLen = attributes.length; for (let i = 0; i < attrLen; i++) { const attr = attributes.item(i); const nodeName = attr.nodeName; if (nodeName.startsWith('data-')) { ds[dashToPascalCase(nodeName)] = attr.nodeValue; } } return new Proxy(ds, { get(_obj, camelCaseProp) { return ds[camelCaseProp]; }, set(_obj, camelCaseProp, value) { const dataAttr = toDataAttribute(camelCaseProp); elm.setAttribute(dataAttr, value); return true; } }); } function toDataAttribute(str) { return 'data-' + String(str).replace(/([A-Z0-9])/g, g => ' ' + g[0]).trim().replace(/ /g, '-').toLowerCase(); } function dashToPascalCase(str) { str = String(str).substr(5); return str.split('-').map((segment, index) => { if (index === 0) { return segment.charAt(0).toLowerCase() + segment.slice(1); } return segment.charAt(0).toUpperCase() + segment.slice(1); }).join(''); } class MockClassList { constructor(elm) { this.elm = elm; } add(...className) { const clsNames = getItems(this.elm); let updated = false; className.forEach(className => { if (clsNames.includes(className) === false) { clsNames.push(className); updated = true; } }); if (updated) { this.elm.setAttributeNS(null, 'class', clsNames.join(' ')); } } remove(...className) { const clsNames = getItems(this.elm); let updated = false; className.forEach(className => { const index = clsNames.indexOf(className); if (index > -1) { clsNames.splice(index, 1); updated = true; } }); if (updated) { this.elm.setAttributeNS(null, 'class', clsNames.filter(c => c.length > 0).join(' ')); } } contains(className) { return getItems(this.elm).includes(className); } toggle(className) { if (this.contains(className) === true) { this.remove(className); } else { this.add(className); } } get length() { return getItems(this.elm).length; } item(index) { return getItems(this.elm)[index]; } toString() { return getItems(this.elm).join(' '); } } function getItems(elm) { const className = elm.getAttribute('class'); if (typeof className === 'string' && className.length > 0) { return className.trim().split(' ').filter(c => c.length > 0); } return []; } class MockEvent { constructor(type, eventInitDict) { this.bubbles = false; this.cancelBubble = false; this.cancelable = false; this.composed = false; this.currentTarget = null; this.defaultPrevented = false; this.srcElement = null; this.target = null; if (typeof type !== 'string') { throw new Error(`Event type required`); } this.type = type; this.timeStamp = Date.now(); if (eventInitDict != null) { Object.assign(this, eventInitDict); } } preventDefault() { this.defaultPrevented = true; } stopPropagation() { this.cancelBubble = true; } stopImmediatePropagation() { this.cancelBubble = true; } } class MockCustomEvent extends MockEvent { constructor(type, customEventInitDic) { super(type); this.detail = null; if (customEventInitDic != null) { Object.assign(this, customEventInitDic); } } } class MockKeyboardEvent extends MockEvent { constructor(type, keyboardEventInitDic) { super(type); this.code = ''; this.key = ''; this.altKey = false; this.ctrlKey = false; this.metaKey = false; this.shiftKey = false; this.location = 0; this.repeat = false; if (keyboardEventInitDic != null) { Object.assign(this, keyboardEventInitDic); } } } class MockEventListener { constructor(type, handler) { this.type = type; this.handler = handler; } } function addEventListener(elm, type, handler) { const target = elm; if (target.__listeners == null) { target.__listeners = []; } target.__listeners.push(new MockEventListener(type, handler)); } function removeEventListener(elm, type, handler) { const target = elm; if (target != null && Array.isArray(target.__listeners) === true) { const elmListener = target.__listeners.find(e => e.type === type && e.handler === handler); if (elmListener != null) { const index = target.__listeners.indexOf(elmListener); target.__listeners.splice(index, 1); } } } function resetEventListeners(target) { if (target != null && target.__listeners != null) { target.__listeners = null; } } function triggerEventListener(elm, ev) { if (elm == null || ev.cancelBubble === true) { return; } const target = elm; ev.currentTarget = elm; if (Array.isArray(target.__listeners) === true) { const listeners = target.__listeners.filter(e => e.type === ev.type); listeners.forEach(listener => { try { listener.handler.call(target, ev); } catch (err) { console.error(err); } }); } if (ev.bubbles === false) { return; } if (elm.nodeName === "#document" /* DOCUMENT_NODE */) { triggerEventListener(elm.defaultView, ev); } else { triggerEventListener(elm.parentElement, ev); } } function dispatchEvent(currentTarget, ev) { ev.target = currentTarget; triggerEventListener(currentTarget, ev); return true; } function serializeNodeToHtml(elm, opts = {}) { const output = { currentLineWidth: 0, indent: 0, isWithinBody: false, text: [], }; if (opts.prettyHtml) { if (typeof opts.indentSpaces !== 'number') { opts.indentSpaces = 2; } if (typeof opts.newLines !== 'boolean') { opts.newLines = true; } opts.approximateLineWidth = -1; } else { opts.prettyHtml = false; if (typeof opts.newLines !== 'boolean') { opts.newLines = false; } if (typeof opts.indentSpaces !== 'number') { opts.indentSpaces = 0; } } if (typeof opts.approximateLineWidth !== 'number') { opts.approximateLineWidth = -1; } if (typeof opts.removeEmptyAttributes !== 'boolean') { opts.removeEmptyAttributes = true; } if (typeof opts.removeAttributeQuotes !== 'boolean') { opts.removeAttributeQuotes = false; } if (typeof opts.removeBooleanAttributeQuotes !== 'boolean') { opts.removeBooleanAttributeQuotes = false; } if (typeof opts.removeHtmlComments !== 'boolean') { opts.removeHtmlComments = false; } if (typeof opts.serializeShadowRoot !== 'boolean') { opts.serializeShadowRoot = false; } if (opts.outerHtml) { serializeToHtml(elm, opts, output, false); } else { for (let i = 0, ii = elm.childNodes.length; i < ii; i++) { serializeToHtml(elm.childNodes[i], opts, output, false); } } if (output.text[0] === '\n') { output.text.shift(); } if (output.text[output.text.length - 1] === '\n') { output.text.pop(); } return output.text.join(''); } function serializeToHtml(node, opts, output, isShadowRoot) { if (node.nodeType === 1 /* ELEMENT_NODE */ || isShadowRoot) { const tagName = isShadowRoot ? 'mock:shadow-root' : node.nodeName.toLowerCase(); if (tagName === 'body') { output.isWithinBody = true; } const ignoreTag = (opts.excludeTags != null && opts.excludeTags.includes(tagName)); if (ignoreTag === false) { if (opts.newLines) { output.text.push('\n'); output.currentLineWidth = 0; } if (opts.indentSpaces > 0) { for (let i = 0; i < output.indent; i++) { output.text.push(' '); } output.currentLineWidth += output.indent; } output.text.push('<' + tagName); output.currentLineWidth += (tagName.length + 1); const attrsLength = node.attributes.length; const attributes = (opts.prettyHtml && attrsLength > 1) ? cloneAttributes(node.attributes, true) : node.attributes; for (let i = 0; i < attrsLength; i++) { const attr = attributes.item(i); const attrName = attr.name; if (attrName === 'style') { continue; } let attrValue = attr.value; if (opts.removeEmptyAttributes && attrValue === '' && REMOVE_EMPTY_ATTR.has(attrName)) { continue; } const attrNamespaceURI = attr.namespaceURI; if (attrNamespaceURI == null) { output.currentLineWidth += (attrName.length + 1); if (opts.approximateLineWidth > 0 && output.currentLineWidth > opts.approximateLineWidth) { output.text.push('\n' + attrName); output.currentLineWidth = 0; } else { output.text.push(' ' + attrName); } } else if (attrNamespaceURI === 'http://www.w3.org/XML/1998/namespace') { output.text.push(' xml:' + attrName); output.currentLineWidth += (attrName.length + 5); } else if (attrNamespaceURI === 'http://www.w3.org/2000/xmlns/') { if (attrName !== 'xmlns') { output.text.push(' xmlns:' + attrName); output.currentLineWidth += (attrName.length + 7); } else { output.text.push(' ' + attrName); output.currentLineWidth += (attrName.length + 1); } } else if (attrNamespaceURI === XLINK_NS) { output.text.push(' xlink:' + attrName); output.currentLineWidth += (attrName.length + 7); } else { output.text.push(' ' + attrNamespaceURI + ':' + attrName); output.currentLineWidth += (attrNamespaceURI.length + attrName.length + 2); } if (opts.prettyHtml && attrName === 'class') { attrValue = attr.value = attrValue.split(' ').filter(t => t !== '').sort().join(' ').trim(); } if (attrValue === '') { if (opts.removeBooleanAttributeQuotes && BOOLEAN_ATTR.has(attrName)) { continue; } if (opts.removeEmptyAttributes && attrName.startsWith('data-')) { continue; } } if (opts.removeAttributeQuotes && CAN_REMOVE_ATTR_QUOTES.test(attrValue)) { output.text.push('=' + escapeString(attrValue, true)); output.currentLineWidth += (attrValue.length + 1); } else { output.text.push('="' + escapeString(attrValue, true) + '"'); output.currentLineWidth += (attrValue.length + 3); } } if (node.hasAttribute('style')) { const cssText = node.style.cssText; if (opts.approximateLineWidth > 0 && (output.currentLineWidth + cssText.length + 10) > opts.approximateLineWidth) { output.text.push(`\nstyle="${cssText}">`); output.currentLineWidth = 0; } else { output.text.push(` style="${cssText}">`); output.currentLineWidth += (cssText.length + 10); } } else { output.text.push('>'); output.currentLineWidth += 1; } } if (EMPTY_ELEMENTS.has(tagName) === false) { if (opts.serializeShadowRoot && node.shadowRoot != null) { output.indent = output.indent + opts.indentSpaces; serializeToHtml(node.shadowRoot, opts, output, true); output.indent = output.indent - opts.indentSpaces; if (opts.newLines && (node.childNodes.length === 0 || (node.childNodes.length === 1 && node.childNodes[0].nodeType === 3 /* TEXT_NODE */ && node.childNodes[0].nodeValue.trim() === ''))) { output.text.push('\n'); output.currentLineWidth = 0; for (let i = 0; i < output.indent; i++) { output.text.push(' '); } output.currentLineWidth += output.indent; } } if (opts.excludeTagContent == null || opts.excludeTagContent.includes(tagName) === false) { const childNodes = tagName === 'template' ? node.content.childNodes : (node.childNodes); const childNodeLength = childNodes.length; if (childNodeLength > 0) { if (childNodeLength === 1 && childNodes[0].nodeType === 3 /* TEXT_NODE */ && (typeof childNodes[0].nodeValue !== 'string' || childNodes[0].nodeValue.trim() === '')) ; else { if (opts.indentSpaces > 0 && ignoreTag === false) { output.indent = output.indent + opts.indentSpaces; } for (let i = 0; i < childNodeLength; i++) { serializeToHtml(childNodes[i], opts, output, false); } if (ignoreTag === false) { if (opts.newLines) { output.text.push('\n'); output.currentLineWidth = 0; } if (opts.indentSpaces > 0) { output.indent = output.indent - opts.indentSpaces; for (let i = 0; i < output.indent; i++) { output.text.push(' '); } output.currentLineWidth += output.indent; } } } } if (ignoreTag === false) { output.text.push('</' + tagName + '>'); output.currentLineWidth += (tagName.length + 3); } } } if (opts.approximateLineWidth > 0 && STRUCTURE_ELEMENTS.has(tagName)) { output.text.push('\n'); output.currentLineWidth = 0; } if (tagName === 'body') { output.isWithinBody = false; } } else if (node.nodeType === 3 /* TEXT_NODE */) { let textContent = node.nodeValue; if (typeof textContent === 'string') { if (textContent.trim() === '') { // this text node is whitespace only if (isWithinWhitespaceSensitive(node)) { // whitespace matters within this element // just add the exact text we were given output.text.push(textContent); output.currentLineWidth += textContent.length; } else if (opts.approximateLineWidth > 0 && !output.isWithinBody) ; else if (!opts.prettyHtml) { // this text node is only whitespace, and it's not // within a whitespace sensitive element like <pre> or <code> // so replace the entire white space with a single new line output.currentLineWidth += 1; if (opts.approximateLineWidth > 0 && output.currentLineWidth > opts.approximateLineWidth) { // good enough for a new line // for perf these are all just estimates // we don't care to ensure exact line lengths output.text.push('\n'); output.currentLineWidth = 0; } else { // let's keep it all on the same line yet output.text.push(' '); } } } else { // this text node has text content if (opts.newLines) { output.text.push('\n'); output.currentLineWidth = 0; } if (opts.indentSpaces > 0) { for (let i = 0; i < output.indent; i++) { output.text.push(' '); } output.currentLineWidth += output.indent; } let textContentLength = textContent.length; if (textContentLength > 0) { // this text node has text content const parentTagName = (node.parentNode != null && node.parentNode.nodeType === 1 /* ELEMENT_NODE */ ? node.parentNode.nodeName : null); if (NON_ESCAPABLE_CONTENT.has(parentTagName)) { // this text node cannot have its content escaped since it's going // into an element like <style> or <script> output.text.push(textContent); output.currentLineWidth += textContentLength; } else { // this text node is going into a normal element and html can be escaped if (opts.prettyHtml) { // pretty print the text node output.text.push(escapeString(textContent.replace(/\s\s+/g, ' ').trim(), false)); output.currentLineWidth += textContentLength; } else { // not pretty printing the text node if (isWithinWhitespaceSensitive(node)) { output.currentLineWidth += textContentLength; } else { // this element is not a whitespace sensitive one, like <pre> or <code> so // any whitespace at the start and end can be cleaned up to just be one space if (/\s/.test(textContent.charAt(0))) { textContent = ' ' + textContent.trimLeft(); } textContentLength = textContent.length; if (textContentLength > 1) { if (/\s/.test(textContent.charAt(textContentLength - 1))) { if (opts.approximateLineWidth > 0 && (output.currentLineWidth + textContentLength) > opts.approximateLineWidth) { textContent = textContent.trimRight() + '\n'; output.currentLineWidth = 0; } else { textContent = textContent.trimRight() + ' '; } } } output.currentLineWidth += textContentLength; } output.text.push(escapeString(textContent, false)); } } } } } } else if (node.nodeType === 8 /* COMMENT_NODE */) { const nodeValue = node.nodeValue; if (opts.removeHtmlComments) { const isHydrateAnnotation = nodeValue.startsWith(CONTENT_REF_ID + '.') || nodeValue.startsWith(ORG_LOCATION_ID + '.') || nodeValue.startsWith(SLOT_NODE_ID + '.') || nodeValue.startsWith(TEXT_NODE_ID + '.'); if (!isHydrateAnnotation) { return; } } if (opts.newLines) { output.text.push('\n'); output.currentLineWidth = 0; } if (opts.indentSpaces > 0) { for (let i = 0; i < output.indent; i++) { output.text.push(' '); } output.currentLineWidth += output.indent; } output.text.push('<!--' + nodeValue + '-->'); output.currentLineWidth += (nodeValue.length + 7); } else if (node.nodeType === 10 /* DOCUMENT_TYPE_NODE */) { output.text.push('<!doctype html>'); } } const AMP_REGEX = /&/g; const NBSP_REGEX = /\u00a0/g; const DOUBLE_QUOTE_REGEX = /"/g; const LT_REGEX = /</g; const GT_REGEX = />/g; const CAN_REMOVE_ATTR_QUOTES = /^[^ \t\n\f\r"'`=<>\/\\-]+$/; function escapeString(str, attrMode) { str = str.replace(AMP_REGEX, '&amp;').replace(NBSP_REGEX, '&nbsp;'); if (attrMode) { return str.replace(DOUBLE_QUOTE_REGEX, '&quot;'); } return str.replace(LT_REGEX, '&lt;').replace(GT_REGEX, '&gt;'); } function isWithinWhitespaceSensitive(node) { while (node != null) { if (WHITESPACE_SENSITIVE.has(node.nodeName)) { return true; } node = node.parentNode; } return false; } /*@__PURE__*/ const NON_ESCAPABLE_CONTENT = new Set(['STYLE', 'SCRIPT', 'IFRAME', 'NOSCRIPT', 'XMP', 'NOEMBED', 'NOFRAMES', 'PLAINTEXT']); /*@__PURE__*/ const WHITESPACE_SENSITIVE = new Set(['CODE', 'OUTPUT', 'PLAINTEXT', 'PRE', 'TEMPLATE', 'TEXTAREA']); /*@__PURE__*/ const EMPTY_ELEMENTS = new Set(['area', 'base', 'basefont', 'bgsound', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'trace', 'wbr']); /*@__PURE__*/ const REMOVE_EMPTY_ATTR = new Set(['class', 'dir', 'id', 'lang', 'name', 'title']); /*@__PURE__*/ const BOOLEAN_ATTR = new Set(['allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'compact', 'controls', 'declare', 'default', 'defaultchecked', 'defaultmuted', 'defaultselected', 'defer', 'disabled', 'enabled', 'formnovalidate', 'hidden', 'indeterminate', 'inert', 'ismap', 'itemscope', 'loop', 'multiple', 'muted', 'nohref', 'nomodule', 'noresize', 'noshade', 'novalidate', 'nowrap', 'open', 'pauseonexit', 'readonly', 'required', 'reversed', 'scoped', 'seamless', 'selected', 'sortable', 'truespeed', 'typemustmatch', 'visible']); /*@__PURE__*/ const STRUCTURE_ELEMENTS = new Set(['html', 'body', 'head', 'iframe', 'meta', 'link', 'title', 'script', 'style']); const parse5=/*@__PURE__*/function(e){const t=[65534,65535,131070,131071,196606,196607,262142,262143,327678,327679,393214,393215,458750,458751,524286,524287,589822,589823,655358,655359,720894,720895,786430,786431,851966,851967,917502,917503,983038,983039,1048574,1048575,1114110,1114111];var n={REPLACEMENT_CHARACTER:"�",CODE_POINTS:{EOF:-1,NULL:0,TABULATION:9,CARRIAGE_RETURN:13,LINE_FEED:10,FORM_FEED:12,SPACE:32,EXCLAMATION_MARK:33,QUOTATION_MARK:34,NUMBER_SIGN:35,AMPERSAND:38,APOSTROPHE:39,HYPHEN_MINUS:45,SOLIDUS:47,DIGIT_0:48,DIGIT_9:57,SEMICOLON:59,LESS_THAN_SIGN:60,EQUALS_SIGN:61,GREATER_THAN_SIGN:62,QUESTION_MARK:63,LATIN_CAPITAL_A:65,LATIN_CAPITAL_F:70,LATIN_CAPITAL_X:88,LATIN_CAPITAL_Z:90,RIGHT_SQUARE_BRACKET:93,GRAVE_ACCENT:96,LATIN_SMALL_A:97,LATIN_SMALL_F:102,LATIN_SMALL_X:120,LATIN_SMALL_Z:122,REPLACEMENT_CHARACTER:65533},CODE_POINT_SEQUENCES:{DASH_DASH_STRING:[45,45],DOCTYPE_STRING:[68,79,67,84,89,80,69],CDATA_START_STRING:[91,67,68,65,84,65,91],SCRIPT_STRING:[115,99,114,105,112,116],PUBLIC_STRING:[80,85,66,76,73,67],SYSTEM_STRING:[83,89,83,84,69,77]},isSurrogate:function(e){return e>=55296&&e<=57343},isSurrogatePair:function(e){return e>=56320&&e<=57343},getSurrogatePairCodePoint:function(e,t){return 1024*(e-55296)+9216+t},isControlCodePoint:function(e){return 32!==e&&10!==e&&13!==e&&9!==e&&12!==e&&e>=1&&e<=31||e>=127&&e<=159},isUndefinedCodePoint:function(e){return e>=64976&&e<=65007||t.indexOf(e)>-1}},s={controlCharacterInInputStream:"control-character-in-input-stream",noncharacterInInputStream:"noncharacter-in-input-stream",surrogateInInputStream:"surrogate-in-input-stream",nonVoidHtmlElementStartTagWithTrailingSolidus:"non-void-html-element-start-tag-with-trailing-solidus",endTagWithAttributes:"end-tag-with-attributes",endTagWithTrailingSolidus:"end-tag-with-trailing-solidus",unexpectedSolidusInTag:"unexpected-solidus-in-tag",unexpectedNullCharacter:"unexpected-null-character",unexpectedQuestionMarkInsteadOfTagName:"unexpected-question-mark-instead-of-tag-name",invalidFirstCharacterOfTagName:"invalid-first-character-of-tag-name",unexpectedEqualsSignBeforeAttributeName:"unexpected-equals-sign-before-attribute-name",missingEndTagName:"missing-end-tag-name",unexpectedCharacterInAttributeName:"unexpected-character-in-attribute-name",unknownNamedCharacterReference:"unknown-named-character-reference",missingSemicolonAfterCharacterReference:"missing-semicolon-after-character-reference",unexpectedCharacterAfterDoctypeSystemIdentifier:"unexpected-character-after-doctype-system-identifier",unexpectedCharacterInUnquotedAttributeValue:"unexpected-character-in-unquoted-attribute-value",eofBeforeTagName:"eof-before-tag-name",eofInTag:"eof-in-tag",missingAttributeValue:"missing-attribute-value",missingWhitespaceBetweenAttributes:"missing-whitespace-between-attributes",missingWhitespaceAfterDoctypePublicKeyword:"missing-whitespace-after-doctype-public-keyword",missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers:"missing-whitespace-between-doctype-public-and-system-identifiers",missingWhitespaceAfterDoctypeSystemKeyword:"missing-whitespace-after-doctype-system-keyword",missingQuoteBeforeDoctypePublicIdentifier:"missing-quote-before-doctype-public-identifier",missingQuoteBeforeDoctypeSystemIdentifier:"missing-quote-before-doctype-system-identifier",missingDoctypePublicIdentifier:"missing-doctype-public-identifier",missingDoctypeSystemIdentifier:"missing-doctype-system-identifier",abruptDoctypePublicIdentifier:"abrupt-doctype-public-identifier",abruptDoctypeSystemIdentifier:"abrupt-doctype-system-identifier",cdataInHtmlContent:"cdata-in-html-content",incorrectlyOpenedComment:"incorrectly-opened-comment",eofInScriptHtmlComme