UNPKG

@stencil/core

Version:

A Compiler for Web Components and Progressive Web Apps

1,733 lines (1,667 loc) • 467 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require; const vm = requireFunc('vm'); function createHydrateAppSandbox(win) { const appScript = loadHydrateAppScript(); const sandbox = createSandbox(win); const context = vm.createContext(sandbox); appScript.runInContext(context); return sandbox.StencilHydrateApp; } let cachedAppScript = null; function loadHydrateAppScript() { if (cachedAppScript == null) { const fs = requireFunc('fs'); const path = requireFunc('path'); const filePath = path.join(__dirname, 'app.js'); const appCode = fs.readFileSync(filePath, 'utf8'); const code = `StencilHydrateApp = (exports => {${appCode};return exports; })({});`; cachedAppScript = new vm.Script(code, { filename: filePath }); } return cachedAppScript; } function createSandbox(win) { const sandbox = { __filename: __filename, __dirname: __dirname, Buffer: Buffer, exports: exports, fetch: win.fetch, global: global, module: module, process: process, require: requireFunc, window: win }; WINDOW_PROPS.forEach(prop => { if (typeof win[prop] === 'function') { sandbox[prop] = win[prop].bind(win); } else { Object.defineProperty(sandbox, prop, { get() { return win[prop]; }, set(val) { win[prop] = val; }, configurable: true, enumerable: true }); } }); win.__clearInterval = clearInterval.bind(win); win.__clearTimeout = clearTimeout.bind(win); win.__setInterval = setInterval.bind(win); win.__setTimeout = setTimeout.bind(win); return sandbox; } const WINDOW_PROPS = [ 'addEventListener', 'alert', 'cancelAnimationFrame', 'cancelIdleCallback', 'clearInterval', 'clearTimeout', 'close', 'confirm', 'console', 'CSS', 'CustomEvent', 'customElements', 'devicePixelRatio', 'dispatchEvent', 'Event', 'document', 'getComputedStyle', 'globalThis', 'history', 'HTMLElement', 'innerHeight', 'innerWidth', 'localStorage', 'location', 'matchMedia', 'navigator', 'pageXOffset', 'pageYOffset', 'parent', 'performance', 'prompt', 'origin', 'removeEventListener', 'requestAnimationFrame', 'requestIdleCallback', 'screen', 'screenLeft', 'screenTop', 'screenX', 'screenY', 'scrollX', 'scrollY', 'self', 'sessionStorage', 'setInterval', 'setTimeout', 'top', 'URL' ]; function relocateMetaCharset(doc) { const head = doc.head; let charsetElm = head.querySelector('meta[charset]'); if (charsetElm == null) { charsetElm = doc.createElement('meta'); charsetElm.setAttribute('charset', 'utf-8'); } else { charsetElm.remove(); } head.insertBefore(charsetElm, head.firstChild); } const commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g; function parseCss(css, filePath) { var lineno = 1; var column = 1; var srcLines; function updatePosition(str) { const lines = str.match(/\n/g); if (lines) lineno += lines.length; const i = str.lastIndexOf('\n'); column = ~i ? str.length - i : column + str.length; } function position() { const start = { line: lineno, column: column }; return function (node) { node.position = new ParsePosition(start); whitespace(); return node; }; } class ParsePosition { constructor(start) { this.start = start; this.end = { line: lineno, column: column }; this.source = filePath; } } ParsePosition.prototype.content = css; const diagnostics = []; function error(msg) { if (!srcLines) { srcLines = css.split('\n'); } const d = { level: 'error', type: 'css', language: 'css', header: 'CSS Parse', messageText: msg, absFilePath: filePath, lines: [{ lineIndex: lineno - 1, lineNumber: lineno, errorCharStart: column, text: css[lineno - 1], }] }; if (lineno > 1) { const previousLine = { lineIndex: lineno - 1, lineNumber: lineno - 1, text: css[lineno - 2], errorCharStart: -1, errorLength: -1 }; d.lines.unshift(previousLine); } if (lineno + 2 < srcLines.length) { const nextLine = { lineIndex: lineno, lineNumber: lineno + 1, text: srcLines[lineno], errorCharStart: -1, errorLength: -1 }; d.lines.push(nextLine); } diagnostics.push(d); } function stylesheet() { const rulesList = rules(); return { type: 'stylesheet', stylesheet: { source: filePath, rules: rulesList, diagnostics: diagnostics } }; } function open() { return match(/^{\s*/); } function close() { return match(/^}/); } function rules() { var node; const rules = []; whitespace(); comments(rules); while (css.length && css.charAt(0) !== '}' && (node = atrule() || rule())) { if (node !== false) { rules.push(node); comments(rules); } } return rules; } function match(re) { const m = re.exec(css); if (!m) return; const str = m[0]; updatePosition(str); css = css.slice(str.length); return m; } function whitespace() { match(/^\s*/); } function comments(rules) { var c; rules = rules || []; while (c = comment()) { if (c !== false) { rules.push(c); } } return rules; } function comment() { const pos = position(); if ('/' !== css.charAt(0) || '*' !== css.charAt(1)) return; var i = 2; while ('' !== css.charAt(i) && ('*' !== css.charAt(i) || '/' !== css.charAt(i + 1))) ++i; i += 2; if ('' === css.charAt(i - 1)) { return error('End of comment missing'); } const str = css.slice(2, i - 2); column += 2; updatePosition(str); css = css.slice(i); column += 2; return pos({ type: 'comment', comment: str }); } function selector() { const m = match(/^([^{]+)/); if (!m) return; return trim(m[0]) .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '') .replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function (m) { return m.replace(/,/g, '\u200C'); }) .split(/\s*(?![^(]*\)),\s*/) .map(function (s) { return s.replace(/\u200C/g, ','); }); } function declaration() { const pos = position(); var prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/); if (!prop) return; prop = trim(prop[0]); if (!match(/^:\s*/)) return error(`property missing ':'`); const val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/); const ret = pos({ type: 'declaration', property: prop.replace(commentre, ''), value: val ? trim(val[0]).replace(commentre, '') : '' }); match(/^[;\s]*/); return ret; } function declarations() { const decls = []; if (!open()) return error(`missing '{'`); comments(decls); var decl; while (decl = declaration()) { if (decl !== false) { decls.push(decl); comments(decls); } } if (!close()) return error(`missing '}'`); return decls; } function keyframe() { var m; const vals = []; const pos = position(); while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) { vals.push(m[1]); match(/^,\s*/); } if (!vals.length) return; return pos({ type: 'keyframe', values: vals, declarations: declarations() }); } function atkeyframes() { const pos = position(); var m = match(/^@([-\w]+)?keyframes\s*/); if (!m) return; const vendor = m[1]; m = match(/^([-\w]+)\s*/); if (!m) return error(`@keyframes missing name`); const name = m[1]; if (!open()) return error(`@keyframes missing '{'`); var frame; var frames = comments(); while (frame = keyframe()) { frames.push(frame); frames = frames.concat(comments()); } if (!close()) return error(`@keyframes missing '}'`); return pos({ type: 'keyframes', name: name, vendor: vendor, keyframes: frames }); } function atsupports() { const pos = position(); const m = match(/^@supports *([^{]+)/); if (!m) return; const supports = trim(m[1]); if (!open()) return error(`@supports missing '{'`); const style = comments().concat(rules()); if (!close()) return error(`@supports missing '}'`); return pos({ type: 'supports', supports: supports, rules: style }); } function athost() { const pos = position(); const m = match(/^@host\s*/); if (!m) return; if (!open()) return error(`@host missing '{'`); const style = comments().concat(rules()); if (!close()) return error(`@host missing '}'`); return pos({ type: 'host', rules: style }); } function atmedia() { const pos = position(); const m = match(/^@media *([^{]+)/); if (!m) return; const media = trim(m[1]); if (!open()) return error(`@media missing '{'`); const style = comments().concat(rules()); if (!close()) return error(`@media missing '}'`); return pos({ type: 'media', media: media, rules: style }); } function atcustommedia() { const pos = position(); const m = match(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/); if (!m) return; return pos({ type: 'custom-media', name: trim(m[1]), media: trim(m[2]) }); } function atpage() { const pos = position(); const m = match(/^@page */); if (!m) return; const sel = selector() || []; if (!open()) return error(`@page missing '{'`); var decls = comments(); var decl; while (decl = declaration()) { decls.push(decl); decls = decls.concat(comments()); } if (!close()) return error(`@page missing '}'`); return pos({ type: 'page', selectors: sel, declarations: decls }); } function atdocument() { const pos = position(); const m = match(/^@([-\w]+)?document *([^{]+)/); if (!m) return; const vendor = trim(m[1]); const doc = trim(m[2]); if (!open()) return error(`@document missing '{'`); const style = comments().concat(rules()); if (!close()) return error(`@document missing '}'`); return pos({ type: 'document', document: doc, vendor: vendor, rules: style }); } function atfontface() { const pos = position(); const m = match(/^@font-face\s*/); if (!m) return; if (!open()) return error(`@font-face missing '{'`); var decls = comments(); var decl; while (decl = declaration()) { decls.push(decl); decls = decls.concat(comments()); } if (!close()) return error(`@font-face missing '}'`); return pos({ type: 'font-face', declarations: decls }); } const atimport = _compileAtrule('import'); const atcharset = _compileAtrule('charset'); const atnamespace = _compileAtrule('namespace'); function _compileAtrule(name) { const re = new RegExp('^@' + name + '\\s*([^;]+);'); return function () { const pos = position(); const m = match(re); if (!m) return; const ret = { type: name }; ret[name] = m[1].trim(); return pos(ret); }; } function atrule() { if (css[0] !== '@') return; return atkeyframes() || atmedia() || atcustommedia() || atsupports() || atimport() || atcharset() || atnamespace() || atdocument() || atpage() || athost() || atfontface(); } function rule() { const pos = position(); const sel = selector(); if (!sel) return error('selector missing'); comments(); return pos({ type: 'rule', selectors: sel, declarations: declarations() }); } return addParent(stylesheet()); } function trim(str) { return str ? str.trim() : ''; } function addParent(obj, parent) { const isNode = obj && typeof obj.type === 'string'; const childParent = isNode ? obj : parent; for (const k in obj) { const value = obj[k]; if (Array.isArray(value)) { value.forEach(function (v) { addParent(v, childParent); }); } else if (value && typeof value === 'object') { addParent(value, childParent); } } if (isNode) { Object.defineProperty(obj, 'parent', { configurable: true, writable: true, enumerable: false, value: parent || null }); } return obj; } function getSelectors(sel) { SELECTORS.all.length = SELECTORS.tags.length = SELECTORS.classNames.length = SELECTORS.ids.length = SELECTORS.attrs.length = 0; sel = sel.replace(/\./g, ' .') .replace(/\#/g, ' #') .replace(/\[/g, ' [') .replace(/\>/g, ' > ') .replace(/\+/g, ' + ') .replace(/\~/g, ' ~ ') .replace(/\*/g, ' * ') .replace(/\:not\((.*?)\)/g, ' '); const items = sel.split(' '); for (var i = 0; i < items.length; i++) { items[i] = items[i].split(':')[0]; if (items[i].length === 0) continue; if (items[i].charAt(0) === '.') { SELECTORS.classNames.push(items[i].substr(1)); } else if (items[i].charAt(0) === '#') { SELECTORS.ids.push(items[i].substr(1)); } else if (items[i].charAt(0) === '[') { items[i] = items[i].substr(1).split('=')[0].split(']')[0].trim(); SELECTORS.attrs.push(items[i].toLowerCase()); } else if (/[a-z]/g.test(items[i].charAt(0))) { SELECTORS.tags.push(items[i].toLowerCase()); } } SELECTORS.classNames = SELECTORS.classNames.sort((a, b) => { if (a.length < b.length) return -1; if (a.length > b.length) return 1; return 0; }); return SELECTORS; } const SELECTORS = { all: [], tags: [], classNames: [], ids: [], attrs: [] }; class StringifyCss { constructor(usedSelectors) { this.usedSelectors = usedSelectors; this.hasUsedAttrs = usedSelectors.attrs.size > 0; this.hasUsedClassNames = usedSelectors.classNames.size > 0; this.hasUsedIds = usedSelectors.ids.size > 0; this.hasUsedTags = usedSelectors.tags.size > 0; } visit(node) { return this[node.type](node); } mapVisit(nodes, delim) { let buf = ''; delim = delim || ''; for (let i = 0, length = nodes.length; i < length; i++) { buf += this.visit(nodes[i]); if (delim && i < length - 1) buf += delim; } return buf; } compile(node) { return node.stylesheet .rules.map(this.visit, this) .join(''); } comment() { return ''; } import(node) { return '@import ' + node.import + ';'; } media(node) { const mediaCss = this.mapVisit(node.rules); if (mediaCss === '') { return ''; } return '@media ' + node.media + '{' + this.mapVisit(node.rules) + '}'; } document(node) { const documentCss = this.mapVisit(node.rules); if (documentCss === '') { return ''; } const doc = '@' + (node.vendor || '') + 'document ' + node.document; return doc + '{' + documentCss + '}'; } charset(node) { return '@charset ' + node.charset + ';'; } namespace(node) { return '@namespace ' + node.namespace + ';'; } supports(node) { const supportsCss = this.mapVisit(node.rules); if (supportsCss === '') { return ''; } return '@supports ' + node.supports + '{' + supportsCss + '}'; } keyframes(node) { const keyframesCss = this.mapVisit(node.keyframes); if (keyframesCss === '') { return ''; } return '@' + (node.vendor || '') + 'keyframes ' + node.name + '{' + keyframesCss + '}'; } keyframe(node) { const decls = node.declarations; return node.values.join(',') + '{' + this.mapVisit(decls) + '}'; } page(node) { const sel = node.selectors.length ? node.selectors.join(', ') : ''; return '@page ' + sel + '{' + this.mapVisit(node.declarations) + '}'; } ['font-face'](node) { const fontCss = this.mapVisit(node.declarations); if (fontCss === '') { return ''; } return '@font-face{' + fontCss + '}'; } host(node) { return '@host{' + this.mapVisit(node.rules) + '}'; } ['custom-media'](node) { return '@custom-media ' + node.name + ' ' + node.media + ';'; } rule(node) { const decls = node.declarations; if (decls == null || decls.length === 0) { return ''; } const usedSelectors = this.usedSelectors; let i; let j; for (i = node.selectors.length - 1; i >= 0; i--) { const sel = getSelectors(node.selectors[i]); let include = true; let jlen = sel.classNames.length; if (jlen > 0 && this.hasUsedClassNames) { for (j = 0; j < jlen; j++) { if (!usedSelectors.classNames.has(sel.classNames[j])) { include = false; break; } } } if (include && this.hasUsedTags) { jlen = sel.tags.length; if (jlen > 0) { for (j = 0; j < jlen; j++) { if (!usedSelectors.tags.has(sel.tags[j])) { include = false; break; } } } } if (include && this.hasUsedAttrs) { jlen = sel.attrs.length; if (jlen > 0) { for (j = 0; j < jlen; j++) { if (!usedSelectors.attrs.has(sel.attrs[j])) { include = false; break; } } } } if (include && this.hasUsedIds) { jlen = sel.ids.length; if (jlen > 0) { for (j = 0; j < jlen; j++) { if (!usedSelectors.ids.has(sel.ids[j])) { include = false; break; } } } } if (!include) { node.selectors.splice(i, 1); } } if (node.selectors.length === 0) { return ''; } return `${node.selectors}{${this.mapVisit(decls)}}`; } declaration(node) { return node.property + ':' + node.value + ';'; } } class UsedSelectors { constructor(elm) { this.tags = new Set(); this.classNames = new Set(); this.ids = new Set(); this.attrs = new Set(); this.collectSelectors(elm); } collectSelectors(elm) { if (elm != null && elm.tagName) { const tagName = elm.tagName.toLowerCase(); this.tags.add(tagName); const attributes = elm.attributes; for (let i = 0, l = attributes.length; i < l; i++) { const attr = attributes.item(i); const attrName = attr.name.toLowerCase(); if (attrName === 'class') { const classList = elm.classList; for (let i = 0, l = classList.length; i < l; i++) { this.classNames.add(classList.item(i)); } } else if (attrName === 'style') { continue; } else if (attrName === 'id') { this.ids.add(attr.value); } else { this.attrs.add(attrName); } } for (let i = 0, l = elm.children.length; i < l; i++) { this.collectSelectors(elm.children[i]); } } } } function removeUnusedStyles(doc, results) { const styleElms = doc.head.querySelectorAll(`style[data-styles]`); if (styleElms.length > 0) { const usedSelectors = new UsedSelectors(doc.body); for (let i = 0; i < styleElms.length; i++) { removeUnusedStyleText(usedSelectors, results, styleElms[i]); } } } function removeUnusedStyleText(usedSelectors, results, styleElm) { try { const cssAst = parseCss(styleElm.innerHTML); if (cssAst.stylesheet.diagnostics.length > 0) { results.diagnostics.push(...cssAst.stylesheet.diagnostics); return; } try { const stringify = new StringifyCss(usedSelectors); styleElm.innerHTML = stringify.compile(cssAst); } catch (e) { results.diagnostics.push({ level: 'warn', type: 'css', header: 'CSS Stringify', messageText: e }); } } catch (e) { results.diagnostics.push({ level: 'warn', type: 'css', header: 'CSS Parse', messageText: e }); } } const URL_ = /*@__PURE__*/(function(){ if (typeof URL === 'function') { return URL; } const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require; if (typeof requireFunc === 'function') { try { return requireFunc('url').URL; } catch (e) {} } return function() {} })(); function normalizeHydrateOptions(inputOpts) { const outputOpts = Object.assign({}, inputOpts); if (typeof outputOpts.clientHydrateAnnotations !== 'boolean') { outputOpts.clientHydrateAnnotations = true; } if (typeof outputOpts.constrainTimeouts !== 'boolean') { outputOpts.constrainTimeouts = true; } if (typeof outputOpts.maxHydrateCount !== 'number') { outputOpts.maxHydrateCount = 300; } if (typeof outputOpts.timeout !== 'number') { outputOpts.timeout = 10000; } return outputOpts; } function generateHydrateResults(opts) { if (typeof opts.url !== 'string') { opts.url = `https://hydrate.stenciljs.com/`; } const results = { diagnostics: [], url: opts.url, host: null, hostname: null, href: null, port: null, pathname: null, search: null, hash: null, html: null, hydratedCount: 0, anchors: [], components: [], imgs: [], scripts: [], styles: [], title: null }; try { const url = new URL_(opts.url, `https://hydrate.stenciljs.com/`); results.url = url.href; results.host = url.host; results.hostname = url.hostname; results.href = url.href; results.port = url.port; results.pathname = url.pathname; results.search = url.search; results.hash = url.hash; } catch (e) { renderCatchError(results, e); } return results; } function renderBuildError(results, msg) { const diagnostic = { level: 'error', type: 'build', header: 'Hydrate Error', messageText: msg, relFilePath: null, absFilePath: null, lines: [] }; if (results.pathname) { if (results.pathname !== '/') { diagnostic.header += ': ' + results.pathname; } } else if (results.url) { diagnostic.header += ': ' + results.url; } results.diagnostics.push(diagnostic); return diagnostic; } function renderCatchError(results, err) { const diagnostic = renderBuildError(results, null); if (err != null) { if (err.stack != null) { diagnostic.messageText = err.stack.toString(); } else { if (err.message != null) { diagnostic.messageText = err.message.toString(); } else { diagnostic.messageText = err.toString(); } } } return diagnostic; } function updateCanonicalLink(doc, href) { let canonicalLinkElm = doc.head.querySelector('link[rel="canonical"]'); if (typeof href === 'string') { if (canonicalLinkElm == null) { canonicalLinkElm = doc.createElement('link'); canonicalLinkElm.setAttribute('rel', 'canonical'); doc.head.appendChild(canonicalLinkElm); } canonicalLinkElm.setAttribute('href', href); } else { if (canonicalLinkElm != null) { canonicalLinkElm.parentNode.removeChild(canonicalLinkElm); } } } function finalizeWindow(doc, opts, results) { if (opts.removeUnusedStyles !== false) { try { removeUnusedStyles(doc, results); } catch (e) { renderCatchError(results, e); } } if (typeof opts.title === 'string') { try { doc.title = opts.title; } catch (e) { renderCatchError(results, e); } } if (opts.removeScripts) { removeScripts(doc.documentElement); } try { updateCanonicalLink(doc, opts.canonicalUrl); } catch (e) { renderCatchError(results, e); } try { relocateMetaCharset(doc); } catch (e) { } try { getHttpStatus(doc, results); } catch (e) { } if (opts.clientHydrateAnnotations) { doc.documentElement.classList.add('hydrated'); } results.title = doc.title; } function removeScripts(elm) { const children = elm.children; for (let i = children.length - 1; i >= 0; i--) { const child = children[i]; removeScripts(child); if (child.nodeName === 'SCRIPT') { child.remove(); } else if (child.nodeName === 'LINK' && child.getAttribute('rel') === 'modulepreload') { child.remove(); } } } function getHttpStatus(doc, results) { const metaStatus = doc.head.querySelector('meta[http-equiv="status"]'); if (metaStatus != null) { const content = metaStatus.getAttribute('content'); if (content != null) { results.httpStatus = parseInt(content, 10); } } } 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) { 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) { 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': 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(cs