UNPKG

62.1 kBJavaScriptView Raw
1'use strict';
2
3const BUILD = {"allRenderFn":false,"cmpDidLoad":true,"cmpDidUnload":true,"cmpDidUpdate":true,"cmpDidRender":false,"cmpWillLoad":true,"cmpWillUpdate":false,"cmpWillRender":false,"connectedCallback":true,"disconnectedCallback":true,"element":false,"event":false,"hasRenderFn":true,"lifecycle":true,"hostListener":false,"hostListenerTargetWindow":false,"hostListenerTargetDocument":false,"hostListenerTargetBody":false,"hostListenerTargetParent":false,"hostListenerTarget":false,"member":true,"method":false,"mode":false,"noVdomRender":false,"observeAttribute":true,"prop":true,"propBoolean":true,"propNumber":true,"propString":true,"propMutable":true,"reflect":true,"scoped":false,"shadowDom":false,"slot":true,"slotRelocation":true,"state":true,"style":true,"svg":false,"updatable":true,"vdomAttribute":true,"vdomClass":true,"vdomFunctional":true,"vdomKey":true,"vdomListener":true,"vdomRef":true,"vdomRender":true,"vdomStyle":true,"vdomText":true,"watchCallback":true,"taskQueue":true,"lazyLoad":true,"hydrateServerSide":false,"cssVarShim":true,"hydrateClientSide":false,"isDebug":false,"isDev":false,"lifecycleDOMEvents":false,"profile":false,"hotModuleReplacement":false,"constructableCSS":true,"cssAnnotations":true};
4const NAMESPACE = 'stencilrouter';
5
6const win = window;
7const doc = document;
8const plt = {
9 $flags$: 0,
10 $resourcesUrl$: '',
11 raf: (h) => requestAnimationFrame(h),
12 ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
13 rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
14};
15const supportsShadowDom = false;
16const supportsConstructibleStylesheets = (() => {
17 try {
18 new CSSStyleSheet();
19 return true;
20 }
21 catch (e) { }
22 return false;
23})();
24
25const Context = {};
26
27const hostRefs = new WeakMap();
28const getHostRef = (ref) => hostRefs.get(ref);
29const registerInstance = (lazyInstance, hostRef) => hostRefs.set(hostRef.$lazyInstance$ = lazyInstance, hostRef);
30const registerHost = (elm) => {
31 {
32 const hostRef = {
33 $flags$: 0,
34 $hostElement$: elm,
35 $instanceValues$: new Map()
36 };
37 hostRef.$onReadyPromise$ = new Promise(r => hostRef.$onReadyResolve$ = r);
38 return hostRefs.set(elm, hostRef);
39 }
40};
41const isMemberInElement = (elm, memberName) => memberName in elm;
42
43const consoleError = (e) => console.error(e);
44
45const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
46 // loadModuleImport
47 const bundleId = cmpMeta.$lazyBundleIds$;
48 return Promise.resolve(require(
49 /* webpackInclude: /\.entry\.js$/ */
50 /* webpackExclude: /\.(system|cjs)\.entry\.js$/ */
51 /* webpackMode: "lazy" */
52 `./${bundleId}.entry.js${''}`)).then(importedModule => importedModule[cmpMeta.$tagName$.replace(/-/g, '_')], consoleError);
53};
54
55const styles = new Map();
56const cssVarShim = win.__stencil_cssshim;
57
58let queueCongestion = 0;
59let queuePending = false;
60const queueDomReads = [];
61const queueDomWrites = [];
62const queueDomWritesLow = [];
63const queueTask = (queue) => (cb) => {
64 // queue dom reads
65 queue.push(cb);
66 if (!queuePending) {
67 queuePending = true;
68 plt.raf(flush);
69 }
70};
71const consume = (queue) => {
72 for (let i = 0; i < queue.length; i++) {
73 try {
74 queue[i](performance.now());
75 }
76 catch (e) {
77 consoleError(e);
78 }
79 }
80 queue.length = 0;
81};
82const consumeTimeout = (queue, timeout) => {
83 let i = 0;
84 let ts = 0;
85 while (i < queue.length && (ts = performance.now()) < timeout) {
86 try {
87 queue[i++](ts);
88 }
89 catch (e) {
90 consoleError(e);
91 }
92 }
93 if (i === queue.length) {
94 queue.length = 0;
95 }
96 else if (i !== 0) {
97 queue.splice(0, i);
98 }
99};
100const flush = () => {
101 queueCongestion++;
102 // always force a bunch of medium callbacks to run, but still have
103 // a throttle on how many can run in a certain time
104 // DOM READS!!!
105 consume(queueDomReads);
106 const timeout = (plt.$flags$ & 6 /* queueMask */) === 2 /* appLoaded */
107 ? performance.now() + (7 * Math.ceil(queueCongestion * (1.0 / 22.0)))
108 : Infinity;
109 // DOM WRITES!!!
110 consumeTimeout(queueDomWrites, timeout);
111 consumeTimeout(queueDomWritesLow, timeout);
112 if (queueDomWrites.length > 0) {
113 queueDomWritesLow.push(...queueDomWrites);
114 queueDomWrites.length = 0;
115 }
116 if (queuePending = ((queueDomReads.length + queueDomWrites.length + queueDomWritesLow.length) > 0)) {
117 // still more to do yet, but we've run out of time
118 // let's let this thing cool off and try again in the next tick
119 plt.raf(flush);
120 }
121 else {
122 queueCongestion = 0;
123 }
124};
125const nextTick = /*@__PURE__*/ (cb) => Promise.resolve().then(cb);
126const readTask = /*@__PURE__*/ queueTask(queueDomReads);
127const writeTask = /*@__PURE__*/ queueTask(queueDomWrites);
128
129/**
130 * Default style mode id
131 */
132/**
133 * Reusable empty obj/array
134 * Don't add values to these!!
135 */
136const EMPTY_OBJ = {};
137
138const isDef = (v) => v != null;
139const toLowerCase = (str) => str.toLowerCase();
140const isComplexType = (o) => ['object', 'function'].includes(typeof o);
141
142function getDynamicImportFunction(namespace) {
143 return `__sc_import_${namespace.replace(/\s|-/g, '_')}`;
144}
145
146const patchEsm = () => {
147 // @ts-ignore
148 if (!(win.CSS && win.CSS.supports && win.CSS.supports('color', 'var(--c)'))) {
149 // @ts-ignore
150 return Promise.resolve(require('./css-shim-f7ddb189-673dd43d.js'));
151 }
152 return Promise.resolve();
153};
154const patchBrowser = async () => {
155 // @ts-ignore
156 const importMeta = (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('stencilrouter-a3d77a87.js', document.baseURI).href));
157 if (importMeta !== '') {
158 return Promise.resolve(new URL('.', importMeta).href);
159 }
160 else {
161 const scriptElm = Array.from(doc.querySelectorAll('script')).find(s => (s.src.includes(`/${NAMESPACE}.esm.js`) ||
162 s.getAttribute('data-namespace') === NAMESPACE));
163 const resourcesUrl = new URL('.', new URL(scriptElm.getAttribute('data-resources-url') || scriptElm.src, win.location.href));
164 patchDynamicImport(resourcesUrl.href);
165 if (!window.customElements) {
166 // @ts-ignore
167 await Promise.resolve(require('./dom-a0c82e31-d4621515.js'));
168 }
169 return resourcesUrl.href;
170 }
171};
172const patchDynamicImport = (base) => {
173 const importFunctionName = getDynamicImportFunction(NAMESPACE);
174 try {
175 win[importFunctionName] = new Function('w', 'return import(w);');
176 }
177 catch (e) {
178 const moduleMap = new Map();
179 win[importFunctionName] = (src) => {
180 const url = new URL(src, base).href;
181 let mod = moduleMap.get(url);
182 if (!mod) {
183 const script = doc.createElement('script');
184 script.type = 'module';
185 script.src = URL.createObjectURL(new Blob([`import * as m from '${url}'; window.${importFunctionName}.m = m;`], { type: 'application/javascript' }));
186 mod = new Promise(resolve => {
187 script.onload = () => {
188 resolve(win[importFunctionName].m);
189 script.remove();
190 };
191 });
192 moduleMap.set(url, mod);
193 doc.head.appendChild(script);
194 }
195 return mod;
196 };
197 }
198};
199const HYDRATED_CLASS = 'hydrated';
200
201const rootAppliedStyles = new WeakMap();
202const registerStyle = (scopeId, cssText) => {
203 let style = styles.get(scopeId);
204 if (supportsConstructibleStylesheets) {
205 style = (style || new CSSStyleSheet());
206 style.replace(cssText);
207 }
208 else {
209 style = cssText;
210 }
211 styles.set(scopeId, style);
212};
213const addStyle = (styleContainerNode, tagName, mode, hostElm) => {
214 let scopeId = getScopeId(tagName);
215 let style = styles.get(scopeId);
216 // if an element is NOT connected then getRootNode() will return the wrong root node
217 // so the fallback is to always use the document for the root node in those cases
218 styleContainerNode = (styleContainerNode.nodeType === 11 /* DocumentFragment */ ? styleContainerNode : doc);
219 if (style) {
220 if (typeof style === 'string') {
221 styleContainerNode = styleContainerNode.head || styleContainerNode;
222 let appliedStyles = rootAppliedStyles.get(styleContainerNode);
223 let styleElm;
224 if (!appliedStyles) {
225 rootAppliedStyles.set(styleContainerNode, appliedStyles = new Set());
226 }
227 if (!appliedStyles.has(scopeId)) {
228 {
229 if (cssVarShim) {
230 styleElm = cssVarShim.createHostStyle(hostElm, scopeId, style);
231 const newScopeId = styleElm['s-sc'];
232 if (newScopeId) {
233 scopeId = newScopeId;
234 // we don't want to add this styleID to the appliedStyles Set
235 // since the cssVarShim might need to apply several different
236 // stylesheets for the same component
237 appliedStyles = null;
238 }
239 }
240 else {
241 styleElm = doc.createElement('style');
242 styleElm.innerHTML = style;
243 }
244 styleContainerNode.appendChild(styleElm);
245 }
246 if (appliedStyles) {
247 appliedStyles.add(scopeId);
248 }
249 }
250 }
251 else if (!styleContainerNode.adoptedStyleSheets.includes(style)) {
252 styleContainerNode.adoptedStyleSheets = [
253 ...styleContainerNode.adoptedStyleSheets,
254 style
255 ];
256 }
257 }
258 return scopeId;
259};
260const attachStyles = (elm, cmpMeta, mode) => {
261 const styleId = addStyle(elm.getRootNode(), cmpMeta.$tagName$, mode, elm);
262};
263const getScopeId = (tagName, mode) => 'sc-' + (tagName);
264
265/**
266 * Production h() function based on Preact by
267 * Jason Miller (@developit)
268 * Licensed under the MIT License
269 * https://github.com/developit/preact/blob/master/LICENSE
270 *
271 * Modified for Stencil's compiler and vdom
272 */
273// const stack: any[] = [];
274// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, child?: d.ChildType): d.VNode;
275// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
276const h = (nodeName, vnodeData, ...children) => {
277 let child = null;
278 let simple = false;
279 let lastSimple = false;
280 let key;
281 let slotName;
282 let vNodeChildren = [];
283 const walk = (c) => {
284 for (let i = 0; i < c.length; i++) {
285 child = c[i];
286 if (Array.isArray(child)) {
287 walk(child);
288 }
289 else if (child != null && typeof child !== 'boolean') {
290 if (simple = typeof nodeName !== 'function' && !isComplexType(child)) {
291 child = String(child);
292 }
293 if (simple && lastSimple) {
294 // If the previous child was simple (string), we merge both
295 vNodeChildren[vNodeChildren.length - 1].$text$ += child;
296 }
297 else {
298 // Append a new vNode, if it's text, we create a text vNode
299 vNodeChildren.push(simple ? { $flags$: 0, $text$: child } : child);
300 }
301 lastSimple = simple;
302 }
303 }
304 };
305 walk(children);
306 if (vnodeData) {
307 // normalize class / classname attributes
308 {
309 key = vnodeData.key || undefined;
310 }
311 {
312 slotName = vnodeData.name;
313 }
314 {
315 const classData = vnodeData.className || vnodeData.class;
316 if (classData) {
317 vnodeData.class = typeof classData !== 'object'
318 ? classData
319 : Object.keys(classData)
320 .filter(k => classData[k])
321 .join(' ');
322 }
323 }
324 }
325 if (typeof nodeName === 'function') {
326 // nodeName is a functional component
327 return nodeName(vnodeData, vNodeChildren, vdomFnUtils);
328 }
329 const vnode = {
330 $flags$: 0,
331 $tag$: nodeName,
332 $children$: vNodeChildren.length > 0 ? vNodeChildren : null,
333 $elm$: undefined,
334 $attrs$: vnodeData,
335 };
336 {
337 vnode.$key$ = key;
338 }
339 {
340 vnode.$name$ = slotName;
341 }
342 return vnode;
343};
344const Host = {};
345const vdomFnUtils = {
346 'forEach': (children, cb) => children.map(convertToPublic).forEach(cb),
347 'map': (children, cb) => children.map(convertToPublic).map(cb).map(convertToPrivate)
348};
349const convertToPublic = (node) => {
350 return {
351 vattrs: node.$attrs$,
352 vchildren: node.$children$,
353 vkey: node.$key$,
354 vname: node.$name$,
355 vtag: node.$tag$,
356 vtext: node.$text$
357 };
358};
359const convertToPrivate = (node) => {
360 return {
361 $flags$: 0,
362 $attrs$: node.vattrs,
363 $children$: node.vchildren,
364 $key$: node.vkey,
365 $name$: node.vname,
366 $tag$: node.vtag,
367 $text$: node.vtext
368 };
369};
370
371/**
372 * Production setAccessor() function based on Preact by
373 * Jason Miller (@developit)
374 * Licensed under the MIT License
375 * https://github.com/developit/preact/blob/master/LICENSE
376 *
377 * Modified for Stencil's compiler and vdom
378 */
379const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
380 if (oldValue === newValue) {
381 return;
382 }
383 if (memberName === 'class' && !isSvg) {
384 // Class
385 {
386 const oldList = parseClassList(oldValue);
387 const baseList = parseClassList(elm.className).filter(item => !oldList.includes(item));
388 elm.className = baseList.concat(parseClassList(newValue).filter(item => !baseList.includes(item))).join(' ');
389 }
390 }
391 else if (memberName === 'style') {
392 // update style attribute, css properties and values
393 {
394 for (const prop in oldValue) {
395 if (!newValue || newValue[prop] == null) {
396 if (prop.includes('-')) {
397 elm.style.removeProperty(prop);
398 }
399 else {
400 elm.style[prop] = '';
401 }
402 }
403 }
404 }
405 for (const prop in newValue) {
406 if (!oldValue || newValue[prop] !== oldValue[prop]) {
407 if (prop.includes('-')) {
408 elm.style.setProperty(prop, newValue[prop]);
409 }
410 else {
411 elm.style[prop] = newValue[prop];
412 }
413 }
414 }
415 }
416 else if (memberName === 'key') ;
417 else if (memberName === 'ref') {
418 // minifier will clean this up
419 if (newValue) {
420 newValue(elm);
421 }
422 }
423 else if (memberName.startsWith('on') && !isMemberInElement(elm, memberName)) {
424 // Event Handlers
425 // so if the member name starts with "on" and the 3rd characters is
426 // a capital letter, and it's not already a member on the element,
427 // then we're assuming it's an event listener
428 if (isMemberInElement(elm, toLowerCase(memberName))) {
429 // standard event
430 // the JSX attribute could have been "onMouseOver" and the
431 // member name "onmouseover" is on the element's prototype
432 // so let's add the listener "mouseover", which is all lowercased
433 memberName = toLowerCase(memberName.substring(2));
434 }
435 else {
436 // custom event
437 // the JSX attribute could have been "onMyCustomEvent"
438 // so let's trim off the "on" prefix and lowercase the first character
439 // and add the listener "myCustomEvent"
440 // except for the first character, we keep the event name case
441 memberName = toLowerCase(memberName[2]) + memberName.substring(3);
442 }
443 if (oldValue) {
444 plt.rel(elm, memberName, oldValue, false);
445 }
446 if (newValue) {
447 plt.ael(elm, memberName, newValue, false);
448 }
449 }
450 else {
451 // Set property if it exists and it's not a SVG
452 const isProp = isMemberInElement(elm, memberName);
453 const isComplex = isComplexType(newValue);
454 if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
455 try {
456 elm[memberName] = newValue == null && elm.tagName.indexOf('-') === -1 ? '' : newValue;
457 }
458 catch (e) { }
459 }
460 if (newValue == null || newValue === false) {
461 {
462 elm.removeAttribute(memberName);
463 }
464 }
465 else if ((!isProp || (flags & 4 /* isHost */) || isSvg) && !isComplex) {
466 newValue = newValue === true ? '' : newValue.toString();
467 {
468 elm.setAttribute(memberName, newValue);
469 }
470 }
471 }
472};
473const parseClassList = (value) => (!value) ? [] : value.split(' ');
474
475const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
476 // if the element passed in is a shadow root, which is a document fragment
477 // then we want to be adding attrs/props to the shadow root's "host" element
478 // if it's not a shadow root, then we add attrs/props to the same element
479 const elm = (newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host) ? newVnode.$elm$.host : newVnode.$elm$;
480 const oldVnodeAttrs = (oldVnode && oldVnode.$attrs$) || EMPTY_OBJ;
481 const newVnodeAttrs = newVnode.$attrs$ || EMPTY_OBJ;
482 {
483 // remove attributes no longer present on the vnode by setting them to undefined
484 for (memberName in oldVnodeAttrs) {
485 if (newVnodeAttrs[memberName] == null && oldVnodeAttrs[memberName] != null) {
486 setAccessor(elm, memberName, oldVnodeAttrs[memberName], undefined, isSvgMode, newVnode.$flags$);
487 }
488 }
489 }
490 // add new & update changed attributes
491 for (memberName in newVnodeAttrs) {
492 setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode, newVnode.$flags$);
493 }
494};
495
496let scopeId;
497let contentRef;
498let hostTagName;
499let useNativeShadowDom = false;
500let checkSlotFallbackVisibility = false;
501let checkSlotRelocate = false;
502let isSvgMode = false;
503const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
504 // tslint:disable-next-line: prefer-const
505 let newVNode = newParentVNode.$children$[childIndex];
506 let i = 0;
507 let elm;
508 let childNode;
509 let oldVNode;
510 if (!useNativeShadowDom) {
511 // remember for later we need to check to relocate nodes
512 checkSlotRelocate = true;
513 if (newVNode.$tag$ === 'slot') {
514 if (scopeId) {
515 // scoped css needs to add its scoped id to the parent element
516 parentElm.classList.add(scopeId + '-s');
517 }
518 if (!newVNode.$children$) {
519 // slot element does not have fallback content
520 // create an html comment we'll use to always reference
521 // where actual slot content should sit next to
522 newVNode.$flags$ |= 1 /* isSlotReference */;
523 }
524 else {
525 // slot element has fallback content
526 // still create an element that "mocks" the slot element
527 newVNode.$flags$ |= 2 /* isSlotFallback */;
528 }
529 }
530 }
531 if (isDef(newVNode.$text$)) {
532 // create text node
533 newVNode.$elm$ = doc.createTextNode(newVNode.$text$);
534 }
535 else if (newVNode.$flags$ & 1 /* isSlotReference */) {
536 // create a slot reference node
537 newVNode.$elm$ = doc.createTextNode('');
538 }
539 else {
540 // create element
541 elm = newVNode.$elm$ = (doc.createElement((newVNode.$flags$ & 2 /* isSlotFallback */) ? 'slot-fb' : newVNode.$tag$));
542 // add css classes, attrs, props, listeners, etc.
543 {
544 updateElement(null, newVNode, isSvgMode);
545 }
546 if (newVNode.$children$) {
547 for (i = 0; i < newVNode.$children$.length; ++i) {
548 // create the node
549 childNode = createElm(oldParentVNode, newVNode, i, elm);
550 // return node could have been null
551 if (childNode) {
552 // append our new node
553 elm.appendChild(childNode);
554 }
555 }
556 }
557 }
558 {
559 newVNode.$elm$['s-hn'] = hostTagName;
560 if (newVNode.$flags$ & (2 /* isSlotFallback */ | 1 /* isSlotReference */)) {
561 // remember the content reference comment
562 newVNode.$elm$['s-sr'] = true;
563 // remember the content reference comment
564 newVNode.$elm$['s-cr'] = contentRef;
565 // remember the slot name, or empty string for default slot
566 newVNode.$elm$['s-sn'] = newVNode.$name$ || '';
567 // check if we've got an old vnode for this slot
568 oldVNode = oldParentVNode && oldParentVNode.$children$ && oldParentVNode.$children$[childIndex];
569 if (oldVNode && oldVNode.$tag$ === newVNode.$tag$ && oldParentVNode.$elm$) {
570 // we've got an old slot vnode and the wrapper is being replaced
571 // so let's move the old slot content back to it's original location
572 putBackInOriginalLocation(oldParentVNode.$elm$, false);
573 }
574 }
575 }
576 return newVNode.$elm$;
577};
578const putBackInOriginalLocation = (parentElm, recursive) => {
579 plt.$flags$ |= 1 /* isTmpDisconnected */;
580 const oldSlotChildNodes = parentElm.childNodes;
581 for (let i = oldSlotChildNodes.length - 1; i >= 0; i--) {
582 const childNode = oldSlotChildNodes[i];
583 if (childNode['s-hn'] !== hostTagName && childNode['s-ol']) {
584 // // this child node in the old element is from another component
585 // // remove this node from the old slot's parent
586 // childNode.remove();
587 // and relocate it back to it's original location
588 parentReferenceNode(childNode).insertBefore(childNode, referenceNode(childNode));
589 // remove the old original location comment entirely
590 // later on the patch function will know what to do
591 // and move this to the correct spot in need be
592 childNode['s-ol'].remove();
593 childNode['s-ol'] = undefined;
594 checkSlotRelocate = true;
595 }
596 if (recursive) {
597 putBackInOriginalLocation(childNode, recursive);
598 }
599 }
600 plt.$flags$ &= ~1 /* isTmpDisconnected */;
601};
602const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
603 let containerElm = ((parentElm['s-cr'] && parentElm['s-cr'].parentNode) || parentElm);
604 let childNode;
605 for (; startIdx <= endIdx; ++startIdx) {
606 if (vnodes[startIdx]) {
607 childNode = createElm(null, parentVNode, startIdx, parentElm);
608 if (childNode) {
609 vnodes[startIdx].$elm$ = childNode;
610 containerElm.insertBefore(childNode, referenceNode(before));
611 }
612 }
613 }
614};
615const removeVnodes = (vnodes, startIdx, endIdx, elm) => {
616 for (; startIdx <= endIdx; ++startIdx) {
617 if (isDef(vnodes[startIdx])) {
618 elm = vnodes[startIdx].$elm$;
619 callNodeRefs(vnodes[startIdx], true);
620 {
621 // we're removing this element
622 // so it's possible we need to show slot fallback content now
623 checkSlotFallbackVisibility = true;
624 if (elm['s-ol']) {
625 // remove the original location comment
626 elm['s-ol'].remove();
627 }
628 else {
629 // it's possible that child nodes of the node
630 // that's being removed are slot nodes
631 putBackInOriginalLocation(elm, true);
632 }
633 }
634 // remove the vnode's element from the dom
635 elm.remove();
636 }
637 }
638};
639const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
640 let oldStartIdx = 0;
641 let newStartIdx = 0;
642 let idxInOld = 0;
643 let i = 0;
644 let oldEndIdx = oldCh.length - 1;
645 let oldStartVnode = oldCh[0];
646 let oldEndVnode = oldCh[oldEndIdx];
647 let newEndIdx = newCh.length - 1;
648 let newStartVnode = newCh[0];
649 let newEndVnode = newCh[newEndIdx];
650 let node;
651 let elmToMove;
652 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
653 if (oldStartVnode == null) {
654 // Vnode might have been moved left
655 oldStartVnode = oldCh[++oldStartIdx];
656 }
657 else if (oldEndVnode == null) {
658 oldEndVnode = oldCh[--oldEndIdx];
659 }
660 else if (newStartVnode == null) {
661 newStartVnode = newCh[++newStartIdx];
662 }
663 else if (newEndVnode == null) {
664 newEndVnode = newCh[--newEndIdx];
665 }
666 else if (isSameVnode(oldStartVnode, newStartVnode)) {
667 patch(oldStartVnode, newStartVnode);
668 oldStartVnode = oldCh[++oldStartIdx];
669 newStartVnode = newCh[++newStartIdx];
670 }
671 else if (isSameVnode(oldEndVnode, newEndVnode)) {
672 patch(oldEndVnode, newEndVnode);
673 oldEndVnode = oldCh[--oldEndIdx];
674 newEndVnode = newCh[--newEndIdx];
675 }
676 else if (isSameVnode(oldStartVnode, newEndVnode)) {
677 // Vnode moved right
678 if (oldStartVnode.$tag$ === 'slot' || newEndVnode.$tag$ === 'slot') {
679 putBackInOriginalLocation(oldStartVnode.$elm$.parentNode, false);
680 }
681 patch(oldStartVnode, newEndVnode);
682 parentElm.insertBefore(oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
683 oldStartVnode = oldCh[++oldStartIdx];
684 newEndVnode = newCh[--newEndIdx];
685 }
686 else if (isSameVnode(oldEndVnode, newStartVnode)) {
687 // Vnode moved left
688 if (oldStartVnode.$tag$ === 'slot' || newEndVnode.$tag$ === 'slot') {
689 putBackInOriginalLocation(oldEndVnode.$elm$.parentNode, false);
690 }
691 patch(oldEndVnode, newStartVnode);
692 parentElm.insertBefore(oldEndVnode.$elm$, oldStartVnode.$elm$);
693 oldEndVnode = oldCh[--oldEndIdx];
694 newStartVnode = newCh[++newStartIdx];
695 }
696 else {
697 // createKeyToOldIdx
698 idxInOld = -1;
699 {
700 for (i = oldStartIdx; i <= oldEndIdx; ++i) {
701 if (oldCh[i] && isDef(oldCh[i].$key$) && oldCh[i].$key$ === newStartVnode.$key$) {
702 idxInOld = i;
703 break;
704 }
705 }
706 }
707 if (idxInOld >= 0) {
708 elmToMove = oldCh[idxInOld];
709 if (elmToMove.$tag$ !== newStartVnode.$tag$) {
710 node = createElm(oldCh && oldCh[newStartIdx], newVNode, idxInOld, parentElm);
711 }
712 else {
713 patch(elmToMove, newStartVnode);
714 oldCh[idxInOld] = undefined;
715 node = elmToMove.$elm$;
716 }
717 newStartVnode = newCh[++newStartIdx];
718 }
719 else {
720 // new element
721 node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx, parentElm);
722 newStartVnode = newCh[++newStartIdx];
723 }
724 if (node) {
725 {
726 parentReferenceNode(oldStartVnode.$elm$).insertBefore(node, referenceNode(oldStartVnode.$elm$));
727 }
728 }
729 }
730 }
731 if (oldStartIdx > oldEndIdx) {
732 addVnodes(parentElm, (newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$), newVNode, newCh, newStartIdx, newEndIdx);
733 }
734 else if (newStartIdx > newEndIdx) {
735 removeVnodes(oldCh, oldStartIdx, oldEndIdx);
736 }
737};
738const isSameVnode = (vnode1, vnode2) => {
739 // compare if two vnode to see if they're "technically" the same
740 // need to have the same element tag, and same key to be the same
741 if (vnode1.$tag$ === vnode2.$tag$) {
742 if (vnode1.$tag$ === 'slot') {
743 return vnode1.$name$ === vnode2.$name$;
744 }
745 {
746 return vnode1.$key$ === vnode2.$key$;
747 }
748 return true;
749 }
750 return false;
751};
752const referenceNode = (node) => {
753 // this node was relocated to a new location in the dom
754 // because of some other component's slot
755 // but we still have an html comment in place of where
756 // it's original location was according to it's original vdom
757 return (node && node['s-ol']) || node;
758};
759const parentReferenceNode = (node) => (node['s-ol'] ? node['s-ol'] : node).parentNode;
760const patch = (oldVNode, newVNode) => {
761 const elm = newVNode.$elm$ = oldVNode.$elm$;
762 const oldChildren = oldVNode.$children$;
763 const newChildren = newVNode.$children$;
764 let defaultHolder;
765 if (!isDef(newVNode.$text$)) {
766 // element node
767 {
768 if (newVNode.$tag$ === 'slot') ;
769 else {
770 // either this is the first render of an element OR it's an update
771 // AND we already know it's possible it could have changed
772 // this updates the element's css classes, attrs, props, listeners, etc.
773 updateElement(oldVNode, newVNode, isSvgMode);
774 }
775 }
776 if (isDef(oldChildren) && isDef(newChildren)) {
777 // looks like there's child vnodes for both the old and new vnodes
778 updateChildren(elm, oldChildren, newVNode, newChildren);
779 }
780 else if (isDef(newChildren)) {
781 // no old child vnodes, but there are new child vnodes to add
782 if (isDef(oldVNode.$text$)) {
783 // the old vnode was text, so be sure to clear it out
784 elm.textContent = '';
785 }
786 // add the new vnode children
787 addVnodes(elm, null, newVNode, newChildren, 0, newChildren.length - 1);
788 }
789 else if (isDef(oldChildren)) {
790 // no new child vnodes, but there are old child vnodes to remove
791 removeVnodes(oldChildren, 0, oldChildren.length - 1);
792 }
793 }
794 else if (defaultHolder = elm['s-cr']) {
795 // this element has slotted content
796 defaultHolder.parentNode.textContent = newVNode.$text$;
797 }
798 else if (oldVNode.$text$ !== newVNode.$text$) {
799 // update the text content for the text only vnode
800 // and also only if the text is different than before
801 elm.textContent = newVNode.$text$;
802 }
803};
804const updateFallbackSlotVisibility = (elm, childNode, childNodes, i, ilen, j, slotNameAttr, nodeType) => {
805 childNodes = elm.childNodes;
806 for (i = 0, ilen = childNodes.length; i < ilen; i++) {
807 childNode = childNodes[i];
808 if (childNode.nodeType === 1 /* ElementNode */) {
809 if (childNode['s-sr']) {
810 // this is a slot fallback node
811 // get the slot name for this slot reference node
812 slotNameAttr = childNode['s-sn'];
813 // by default always show a fallback slot node
814 // then hide it if there are other slots in the light dom
815 childNode.hidden = false;
816 for (j = 0; j < ilen; j++) {
817 if (childNodes[j]['s-hn'] !== childNode['s-hn']) {
818 // this sibling node is from a different component
819 nodeType = childNodes[j].nodeType;
820 if (slotNameAttr !== '') {
821 // this is a named fallback slot node
822 if (nodeType === 1 /* ElementNode */ && slotNameAttr === childNodes[j].getAttribute('slot')) {
823 childNode.hidden = true;
824 break;
825 }
826 }
827 else {
828 // this is a default fallback slot node
829 // any element or text node (with content)
830 // should hide the default fallback slot node
831 if (nodeType === 1 /* ElementNode */ || (nodeType === 3 /* TextNode */ && childNodes[j].textContent.trim() !== '')) {
832 childNode.hidden = true;
833 break;
834 }
835 }
836 }
837 }
838 }
839 // keep drilling down
840 updateFallbackSlotVisibility(childNode);
841 }
842 }
843};
844const relocateNodes = [];
845const relocateSlotContent = (elm) => {
846 // tslint:disable-next-line: prefer-const
847 let childNodes = elm.childNodes;
848 let ilen = childNodes.length;
849 let i = 0;
850 let j = 0;
851 let nodeType = 0;
852 let childNode;
853 let node;
854 let hostContentNodes;
855 let slotNameAttr;
856 for (ilen = childNodes.length; i < ilen; i++) {
857 childNode = childNodes[i];
858 if (childNode['s-sr'] && (node = childNode['s-cr'])) {
859 // first got the content reference comment node
860 // then we got it's parent, which is where all the host content is in now
861 hostContentNodes = node.parentNode.childNodes;
862 slotNameAttr = childNode['s-sn'];
863 for (j = hostContentNodes.length - 1; j >= 0; j--) {
864 node = hostContentNodes[j];
865 if (!node['s-cn'] && !node['s-nr'] && node['s-hn'] !== childNode['s-hn']) {
866 // let's do some relocating to its new home
867 // but never relocate a content reference node
868 // that is suppose to always represent the original content location
869 nodeType = node.nodeType;
870 if (((nodeType === 3 /* TextNode */ || nodeType === 8 /* CommentNode */) && slotNameAttr === '') ||
871 (nodeType === 1 /* ElementNode */ && node.getAttribute('slot') === null && slotNameAttr === '') ||
872 (nodeType === 1 /* ElementNode */ && node.getAttribute('slot') === slotNameAttr)) {
873 // it's possible we've already decided to relocate this node
874 if (!relocateNodes.some(r => r.nodeToRelocate === node)) {
875 // made some changes to slots
876 // let's make sure we also double check
877 // fallbacks are correctly hidden or shown
878 checkSlotFallbackVisibility = true;
879 node['s-sn'] = slotNameAttr;
880 // add to our list of nodes to relocate
881 relocateNodes.push({
882 slotRefNode: childNode,
883 nodeToRelocate: node
884 });
885 }
886 }
887 }
888 }
889 }
890 if (childNode.nodeType === 1 /* ElementNode */) {
891 relocateSlotContent(childNode);
892 }
893 }
894};
895const callNodeRefs = (vNode, isDestroy) => {
896 if (vNode) {
897 vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(isDestroy ? null : vNode.$elm$);
898 vNode.$children$ && vNode.$children$.forEach(vChild => {
899 callNodeRefs(vChild, isDestroy);
900 });
901 }
902};
903const isHost = (node) => {
904 return node && node.$tag$ === Host;
905};
906const renderVdom = (hostElm, hostRef, cmpMeta, renderFnResults) => {
907 const oldVNode = hostRef.$vnode$ || { $flags$: 0 };
908 hostTagName = toLowerCase(hostElm.tagName);
909 if (isHost(renderFnResults)) {
910 renderFnResults.$tag$ = null;
911 }
912 else {
913 renderFnResults = h(null, null, renderFnResults);
914 }
915 if (BUILD.reflect && cmpMeta.$attrsToReflect$) {
916 renderFnResults.$attrs$ = renderFnResults.$attrs$ || {};
917 cmpMeta.$attrsToReflect$.forEach(([propName, attribute]) => renderFnResults.$attrs$[attribute] = hostElm[propName]);
918 }
919 renderFnResults.$flags$ |= 4 /* isHost */;
920 hostRef.$vnode$ = renderFnResults;
921 renderFnResults.$elm$ = oldVNode.$elm$ = (BUILD.shadowDom ? hostElm.shadowRoot || hostElm : hostElm);
922 if (BUILD.scoped || BUILD.shadowDom) {
923 scopeId = hostElm['s-sc'];
924 }
925 if (BUILD.slotRelocation) {
926 contentRef = hostElm['s-cr'];
927 useNativeShadowDom = supportsShadowDom && (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) !== 0;
928 // always reset
929 checkSlotRelocate = checkSlotFallbackVisibility = false;
930 }
931 // synchronous patch
932 patch(oldVNode, renderFnResults);
933 if (BUILD.slotRelocation) {
934 if (checkSlotRelocate) {
935 relocateSlotContent(renderFnResults.$elm$);
936 for (let i = 0; i < relocateNodes.length; i++) {
937 const relocateNode = relocateNodes[i];
938 if (!relocateNode.nodeToRelocate['s-ol']) {
939 // add a reference node marking this node's original location
940 // keep a reference to this node for later lookups
941 const orgLocationNode = (BUILD.isDebug || BUILD.hydrateServerSide)
942 ? doc.createComment(`org-loc`)
943 : doc.createTextNode('');
944 orgLocationNode['s-nr'] = relocateNode.nodeToRelocate;
945 relocateNode.nodeToRelocate.parentNode.insertBefore((relocateNode.nodeToRelocate['s-ol'] = orgLocationNode), relocateNode.nodeToRelocate);
946 }
947 }
948 // while we're moving nodes around existing nodes, temporarily disable
949 // the disconnectCallback from working
950 plt.$flags$ |= 1 /* isTmpDisconnected */;
951 for (let i = 0; i < relocateNodes.length; i++) {
952 const relocateNode = relocateNodes[i];
953 // by default we're just going to insert it directly
954 // after the slot reference node
955 const parentNodeRef = relocateNode.slotRefNode.parentNode;
956 let insertBeforeNode = relocateNode.slotRefNode.nextSibling;
957 let orgLocationNode = relocateNode.nodeToRelocate['s-ol'];
958 while (orgLocationNode = orgLocationNode.previousSibling) {
959 let refNode = orgLocationNode['s-nr'];
960 if (refNode && refNode) {
961 if (refNode['s-sn'] === relocateNode.nodeToRelocate['s-sn']) {
962 if (parentNodeRef === refNode.parentNode) {
963 if ((refNode = refNode.nextSibling) && refNode && !refNode['s-nr']) {
964 insertBeforeNode = refNode;
965 break;
966 }
967 }
968 }
969 }
970 }
971 if ((!insertBeforeNode && parentNodeRef !== relocateNode.nodeToRelocate.parentNode) ||
972 (relocateNode.nodeToRelocate.nextSibling !== insertBeforeNode)) {
973 // we've checked that it's worth while to relocate
974 // since that the node to relocate
975 // has a different next sibling or parent relocated
976 if (relocateNode.nodeToRelocate !== insertBeforeNode) {
977 // add it back to the dom but in its new home
978 parentNodeRef.insertBefore(relocateNode.nodeToRelocate, insertBeforeNode);
979 }
980 }
981 }
982 // done moving nodes around
983 // allow the disconnect callback to work again
984 plt.$flags$ &= ~1 /* isTmpDisconnected */;
985 }
986 if (checkSlotFallbackVisibility) {
987 updateFallbackSlotVisibility(renderFnResults.$elm$);
988 }
989 // always reset
990 relocateNodes.length = 0;
991 }
992};
993
994const safeCall = async (instance, method) => {
995 if (instance && instance[method]) {
996 try {
997 await instance[method]();
998 }
999 catch (e) {
1000 consoleError(e);
1001 }
1002 }
1003};
1004const scheduleUpdate = async (elm, hostRef, cmpMeta, isInitialLoad) => {
1005 {
1006 hostRef.$flags$ |= 16 /* isQueuedForUpdate */;
1007 }
1008 const instance = hostRef.$lazyInstance$;
1009 if (isInitialLoad) {
1010 {
1011 await safeCall(instance, 'componentWillLoad');
1012 }
1013 }
1014 // there is no ancestorc omponent or the ancestor component
1015 // has already fired off its lifecycle update then
1016 // fire off the initial update
1017 {
1018 writeTask(() => updateComponent(elm, hostRef, cmpMeta, instance, isInitialLoad));
1019 }
1020};
1021const updateComponent = (elm, hostRef, cmpMeta, instance, isInitialLoad) => {
1022 // updateComponent
1023 {
1024 hostRef.$flags$ &= ~16 /* isQueuedForUpdate */;
1025 }
1026 {
1027 elm['s-lr'] = false;
1028 }
1029 if (isInitialLoad) {
1030 // DOM WRITE!
1031 attachStyles(elm, cmpMeta, hostRef.$modeName$);
1032 }
1033 {
1034 {
1035 // tell the platform we're actively rendering
1036 // if a value is changed within a render() then
1037 // this tells the platform not to queue the change
1038 hostRef.$flags$ |= 4 /* isActiveRender */;
1039 try {
1040 // looks like we've got child nodes to render into this host element
1041 // or we need to update the css class/attrs on the host element
1042 // DOM WRITE!
1043 renderVdom(elm, hostRef, cmpMeta, (BUILD.allRenderFn) ? instance.render() : (instance.render && instance.render()));
1044 }
1045 catch (e) {
1046 consoleError(e);
1047 }
1048 hostRef.$flags$ &= ~4 /* isActiveRender */;
1049 }
1050 }
1051 if (cssVarShim) {
1052 cssVarShim.updateHost(elm);
1053 }
1054 // set that this component lifecycle rendering has completed
1055 {
1056 elm['s-lr'] = true;
1057 }
1058 {
1059 hostRef.$flags$ |= 2 /* hasRendered */;
1060 }
1061 if (elm['s-rc'].length > 0) {
1062 // ok, so turns out there are some child host elements
1063 // waiting on this parent element to load
1064 // let's fire off all update callbacks waiting
1065 elm['s-rc'].forEach(cb => cb());
1066 elm['s-rc'].length = 0;
1067 }
1068 postUpdateComponent(elm, hostRef);
1069};
1070const postUpdateComponent = (elm, hostRef, ancestorsActivelyLoadingChildren) => {
1071 if (!elm['s-al']) {
1072 const instance = hostRef.$lazyInstance$;
1073 const ancestorComponent = hostRef.$ancestorComponent$;
1074 if (!(hostRef.$flags$ & 512 /* hasLoadedComponent */)) {
1075 hostRef.$flags$ |= 512 /* hasLoadedComponent */;
1076 {
1077 // DOM WRITE!
1078 // add the css class that this element has officially hydrated
1079 elm.classList.add(HYDRATED_CLASS);
1080 }
1081 {
1082 safeCall(instance, 'componentDidLoad');
1083 }
1084 {
1085 hostRef.$onReadyResolve$(elm);
1086 }
1087 if (!ancestorComponent) {
1088 // on appload
1089 // we have finish the first big initial render
1090 doc.documentElement.classList.add(HYDRATED_CLASS);
1091 {
1092 setTimeout(() => plt.$flags$ |= 2 /* appLoaded */, 999);
1093 }
1094 }
1095 }
1096 else {
1097 {
1098 // we've already loaded this component
1099 // fire off the user's componentDidUpdate method (if one was provided)
1100 // componentDidUpdate runs AFTER render() has been called
1101 // and all child components have finished updating
1102 safeCall(instance, 'componentDidUpdate');
1103 }
1104 }
1105 // load events fire from bottom to top
1106 // the deepest elements load first then bubbles up
1107 if (ancestorComponent) {
1108 // ok so this element already has a known ancestor component
1109 // let's make sure we remove this element from its ancestor's
1110 // known list of child elements which are actively loading
1111 if (ancestorsActivelyLoadingChildren = ancestorComponent['s-al']) {
1112 // remove this element from the actively loading map
1113 ancestorsActivelyLoadingChildren.delete(elm);
1114 // the ancestor's initializeComponent method will do the actual checks
1115 // to see if the ancestor is actually loaded or not
1116 // then let's call the ancestor's initializeComponent method if there's no length
1117 // (which actually ends up as this method again but for the ancestor)
1118 if (ancestorsActivelyLoadingChildren.size === 0) {
1119 ancestorComponent['s-al'] = undefined;
1120 ancestorComponent['s-init']();
1121 }
1122 }
1123 hostRef.$ancestorComponent$ = undefined;
1124 }
1125 // ( •_•)
1126 // ( •_•)>⌐■-■
1127 // (⌐■_■)
1128 }
1129};
1130
1131const disconnectedCallback = (elm) => {
1132 if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
1133 const hostRef = getHostRef(elm);
1134 // clear CSS var-shim tracking
1135 if (cssVarShim) {
1136 cssVarShim.removeHost(elm);
1137 }
1138 const instance = hostRef.$lazyInstance$;
1139 {
1140 safeCall(instance, 'disconnectedCallback');
1141 }
1142 {
1143 safeCall(instance, 'componentDidUnload');
1144 }
1145 }
1146};
1147
1148const parsePropertyValue = (propValue, propType) => {
1149 // ensure this value is of the correct prop type
1150 if (propValue != null && !isComplexType(propValue)) {
1151 if (propType & 4 /* Boolean */) {
1152 // per the HTML spec, any string value means it is a boolean true value
1153 // but we'll cheat here and say that the string "false" is the boolean false
1154 return (propValue === 'false' ? false : propValue === '' || !!propValue);
1155 }
1156 if (propType & 2 /* Number */) {
1157 // force it to be a number
1158 return parseFloat(propValue);
1159 }
1160 if (propType & 1 /* String */) {
1161 // could have been passed as a number or boolean
1162 // but we still want it as a string
1163 return String(propValue);
1164 }
1165 // redundant return here for better minification
1166 return propValue;
1167 }
1168 // not sure exactly what type we want
1169 // so no need to change to a different type
1170 return propValue;
1171};
1172
1173const getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
1174const setValue = (ref, propName, newVal, cmpMeta) => {
1175 // check our new property value against our internal value
1176 const hostRef = getHostRef(ref);
1177 const elm = hostRef.$hostElement$;
1178 const oldVal = hostRef.$instanceValues$.get(propName);
1179 const flags = hostRef.$flags$;
1180 newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
1181 if (newVal !== oldVal && (!(flags & 8 /* isConstructingInstance */) || oldVal === undefined)) {
1182 // gadzooks! the property's value has changed!!
1183 // set our new value!
1184 hostRef.$instanceValues$.set(propName, newVal);
1185 if (hostRef.$lazyInstance$) {
1186 // get an array of method names of watch functions to call
1187 if (cmpMeta.$watchers$ &&
1188 (flags & (1 /* hasConnected */ | 8 /* isConstructingInstance */)) === 1 /* hasConnected */) {
1189 const watchMethods = cmpMeta.$watchers$[propName];
1190 if (watchMethods) {
1191 // this instance is watching for when this property changed
1192 watchMethods.forEach(watchMethodName => {
1193 try {
1194 // fire off each of the watch methods that are watching this property
1195 (BUILD.lazyLoad ? hostRef.$lazyInstance$ : elm)[watchMethodName].call((BUILD.lazyLoad ? hostRef.$lazyInstance$ : elm), newVal, oldVal, propName);
1196 }
1197 catch (e) {
1198 consoleError(e);
1199 }
1200 });
1201 }
1202 }
1203 if ((flags & (4 /* isActiveRender */ | 2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
1204 // looks like this value actually changed, so we've got work to do!
1205 // but only if we've already rendered, otherwise just chill out
1206 // queue that we need to do an update, but don't worry about queuing
1207 // up millions cuz this function ensures it only runs once
1208 scheduleUpdate(elm, hostRef, cmpMeta, false);
1209 }
1210 }
1211 }
1212};
1213
1214const proxyComponent = (Cstr, cmpMeta, flags) => {
1215 if (cmpMeta.$members$) {
1216 if (Cstr.watchers) {
1217 cmpMeta.$watchers$ = Cstr.watchers;
1218 }
1219 // It's better to have a const than two Object.entries()
1220 const members = Object.entries(cmpMeta.$members$);
1221 const prototype = Cstr.prototype;
1222 members.forEach(([memberName, [memberFlags]]) => {
1223 if ((memberFlags & 31) || (flags & 2 && (memberFlags & 32 /* State */))) {
1224 // proxyComponent - prop
1225 Object.defineProperty(prototype, memberName, {
1226 get() {
1227 // proxyComponent, get value
1228 return getValue(this, memberName);
1229 },
1230 set(newValue) {
1231 // proxyComponent, set value
1232 setValue(this, memberName, newValue, cmpMeta);
1233 },
1234 configurable: true,
1235 enumerable: true
1236 });
1237 }
1238 });
1239 if (flags & 1) {
1240 const attrNameToPropName = new Map();
1241 prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
1242 const propName = attrNameToPropName.get(attrName);
1243 this[propName] = newValue === null && typeof this[propName] === 'boolean'
1244 ? false
1245 : newValue;
1246 };
1247 // create an array of attributes to observe
1248 // and also create a map of html attribute name to js property name
1249 Cstr.observedAttributes = members
1250 .filter(([_, m]) => m[0] & 15 /* HasAttribute */) // filter to only keep props that should match attributes
1251 .map(([propName, m]) => {
1252 const attrName = m[1] || propName;
1253 attrNameToPropName.set(attrName, propName);
1254 if (m[0] & 512 /* ReflectAttr */) {
1255 cmpMeta.$attrsToReflect$.push([propName, attrName]);
1256 }
1257 return attrName;
1258 });
1259 }
1260 }
1261 return Cstr;
1262};
1263
1264const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
1265 // initializeComponent
1266 if ((hostRef.$flags$ & 256 /* hasInitializedComponent */) === 0) {
1267 // we haven't initialized this element yet
1268 hostRef.$flags$ |= 256 /* hasInitializedComponent */;
1269 {
1270 // lazy loaded components
1271 // request the component's implementation to be
1272 // wired up with the host element
1273 Cstr = await loadModule(cmpMeta);
1274 if (!Cstr.isProxied) {
1275 // we'eve never proxied this Constructor before
1276 // let's add the getters/setters to its prototype before
1277 // the first time we create an instance of the implementation
1278 {
1279 cmpMeta.$watchers$ = Cstr.watchers;
1280 }
1281 proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
1282 Cstr.isProxied = true;
1283 }
1284 // ok, time to construct the instance
1285 // but let's keep track of when we start and stop
1286 // so that the getters/setters don't incorrectly step on data
1287 {
1288 hostRef.$flags$ |= 8 /* isConstructingInstance */;
1289 }
1290 // construct the lazy-loaded component implementation
1291 // passing the hostRef is very important during
1292 // construction in order to directly wire together the
1293 // host element and the lazy-loaded instance
1294 try {
1295 new Cstr(hostRef);
1296 }
1297 catch (e) {
1298 consoleError(e);
1299 }
1300 {
1301 hostRef.$flags$ &= ~8 /* isConstructingInstance */;
1302 }
1303 fireConnectedCallback(hostRef.$lazyInstance$);
1304 }
1305 if (!Cstr.isStyleRegistered && Cstr.style) {
1306 // this component has styles but we haven't registered them yet
1307 let style = Cstr.style;
1308 let scopeId = getScopeId(cmpMeta.$tagName$);
1309 registerStyle(scopeId, style);
1310 Cstr.isStyleRegistered = true;
1311 }
1312 }
1313 // we've successfully created a lazy instance
1314 const ancestorComponent = hostRef.$ancestorComponent$;
1315 if (ancestorComponent && !ancestorComponent['s-lr'] && ancestorComponent['s-rc']) {
1316 // this is the intial load and this component it has an ancestor component
1317 // but the ancestor component has NOT fired its will update lifecycle yet
1318 // so let's just cool our jets and wait for the ancestor to continue first
1319 ancestorComponent['s-rc'].push(() =>
1320 // this will get fired off when the ancestor component
1321 // finally gets around to rendering its lazy self
1322 // fire off the initial update
1323 initializeComponent(elm, hostRef, cmpMeta));
1324 }
1325 else {
1326 scheduleUpdate(elm, hostRef, cmpMeta, true);
1327 }
1328};
1329
1330const fireConnectedCallback = (instance) => {
1331 {
1332 safeCall(instance, 'connectedCallback');
1333 }
1334};
1335const connectedCallback = (elm, cmpMeta) => {
1336 if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
1337 // connectedCallback
1338 const hostRef = getHostRef(elm);
1339 if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
1340 // first time this component has connected
1341 hostRef.$flags$ |= 1 /* hasConnected */;
1342 let hostId;
1343 if (!hostId) {
1344 // initUpdate
1345 // if the slot polyfill is required we'll need to put some nodes
1346 // in here to act as original content anchors as we move nodes around
1347 // host element has been connected to the DOM
1348 if (cmpMeta.$flags$ & 4 ||
1349 (BUILD.shadowDom && cmpMeta.$flags$ & 8 /* needsShadowDomShim */)) {
1350 setContentReference(elm);
1351 }
1352 }
1353 {
1354 // find the first ancestor component (if there is one) and register
1355 // this component as one of the actively loading child components for its ancestor
1356 let ancestorComponent = elm;
1357 while ((ancestorComponent = (ancestorComponent.parentNode || ancestorComponent.host))) {
1358 // climb up the ancestors looking for the first
1359 // component that hasn't finished its lifecycle update yet
1360 if ((ancestorComponent['s-init'] && !ancestorComponent['s-lr']) || (BUILD.hydrateClientSide && ancestorComponent.nodeType === 1 /* ElementNode */ && ancestorComponent.hasAttribute('s-id'))) {
1361 // we found this components first ancestor component
1362 // keep a reference to this component's ancestor component
1363 hostRef.$ancestorComponent$ = ancestorComponent;
1364 // ensure there is an array to contain a reference to each of the child components
1365 // and set this component as one of the ancestor's child components it should wait on
1366 (ancestorComponent['s-al'] = ancestorComponent['s-al'] || new Set()).add(elm);
1367 break;
1368 }
1369 }
1370 }
1371 // Lazy properties
1372 // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
1373 if (cmpMeta.$members$) {
1374 Object.entries(cmpMeta.$members$).forEach(([memberName, [memberFlags]]) => {
1375 if (memberFlags & 31 /* Prop */ && elm.hasOwnProperty(memberName)) {
1376 const value = elm[memberName];
1377 delete elm[memberName];
1378 elm[memberName] = value;
1379 }
1380 });
1381 }
1382 {
1383 initializeComponent(elm, hostRef, cmpMeta);
1384 }
1385 }
1386 fireConnectedCallback(hostRef.$lazyInstance$);
1387 }
1388};
1389const setContentReference = (elm, contentRefElm) => {
1390 // only required when we're NOT using native shadow dom (slot)
1391 // or this browser doesn't support native shadow dom
1392 // and this host element was NOT created with SSR
1393 // let's pick out the inner content for slot projection
1394 // create a node to represent where the original
1395 // content was first placed, which is useful later on
1396 let crName;
1397 {
1398 crName = '';
1399 }
1400 contentRefElm = elm['s-cr'] = doc.createComment(crName);
1401 contentRefElm['s-cn'] = true;
1402 elm.insertBefore(contentRefElm, elm.firstChild);
1403};
1404
1405const bootstrapLazy = (lazyBundles, options = {}) => {
1406 const cmpTags = [];
1407 const exclude = options.exclude || [];
1408 const head = doc.head;
1409 const customElements = win.customElements;
1410 const y = /*@__PURE__*/ head.querySelector('meta[charset]');
1411 const visibilityStyle = /*@__PURE__*/ doc.createElement('style');
1412 Object.assign(plt, options);
1413 plt.$resourcesUrl$ = new URL(options.resourcesUrl || '/', win.location.href).href;
1414 if (options.syncQueue) {
1415 plt.$flags$ |= 4 /* queueSync */;
1416 }
1417 lazyBundles.forEach(lazyBundle => lazyBundle[1].forEach(compactMeta => {
1418 const cmpMeta = {
1419 $flags$: compactMeta[0],
1420 $tagName$: compactMeta[1],
1421 $members$: compactMeta[2],
1422 $listeners$: compactMeta[3],
1423 };
1424 {
1425 cmpMeta.$attrsToReflect$ = [];
1426 }
1427 {
1428 cmpMeta.$watchers$ = {};
1429 }
1430 const tagName = cmpMeta.$tagName$;
1431 const HostElement = class extends HTMLElement {
1432 // StencilLazyHost
1433 constructor(self) {
1434 // @ts-ignore
1435 super(self);
1436 self = this;
1437 {
1438 this['s-lr'] = false;
1439 this['s-rc'] = [];
1440 }
1441 registerHost(self);
1442 }
1443 connectedCallback() {
1444 connectedCallback(this, cmpMeta);
1445 }
1446 disconnectedCallback() {
1447 disconnectedCallback(this);
1448 }
1449 's-init'() {
1450 const hostRef = getHostRef(this);
1451 if (hostRef.$lazyInstance$) {
1452 postUpdateComponent(this, hostRef);
1453 }
1454 }
1455 's-hmr'(hmrVersionId) {
1456 }
1457 forceUpdate() {
1458 {
1459 const hostRef = getHostRef(this);
1460 scheduleUpdate(this, hostRef, cmpMeta, false);
1461 }
1462 }
1463 componentOnReady() {
1464 return getHostRef(this).$onReadyPromise$;
1465 }
1466 };
1467 cmpMeta.$lazyBundleIds$ = lazyBundle[0];
1468 if (!exclude.includes(tagName) && !customElements.get(tagName)) {
1469 cmpTags.push(tagName);
1470 customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* isElementConstructor */));
1471 }
1472 }));
1473 // visibilityStyle.innerHTML = cmpTags.map(t => `${t}:not(.hydrated)`) + '{display:none}';
1474 visibilityStyle.innerHTML = cmpTags + '{visibility:hidden}.hydrated{visibility:inherit}';
1475 visibilityStyle.setAttribute('data-styles', '');
1476 head.insertBefore(visibilityStyle, y ? y.nextSibling : head.firstChild);
1477};
1478
1479const getAssetPath = (path) => {
1480 const assetUrl = new URL(path, plt.$resourcesUrl$);
1481 return (assetUrl.origin !== win.location.origin)
1482 ? assetUrl.href
1483 : assetUrl.pathname;
1484};
1485
1486const getContext = (_elm, context) => {
1487 if (context in Context) {
1488 return Context[context];
1489 }
1490 else if (context === 'window') {
1491 return win;
1492 }
1493 else if (context === 'document') {
1494 return doc;
1495 }
1496 else if (context === 'isServer' || context === 'isPrerender') {
1497 return !!BUILD.hydrateServerSide;
1498 }
1499 else if (context === 'isClient') {
1500 return !BUILD.hydrateServerSide;
1501 }
1502 else if (context === 'resourcesUrl' || context === 'publicPath') {
1503 return getAssetPath('.');
1504 }
1505 else if (context === 'queue') {
1506 return {
1507 write: writeTask,
1508 read: readTask,
1509 tick: {
1510 then(cb) {
1511 return nextTick(cb);
1512 }
1513 }
1514 };
1515 }
1516 return undefined;
1517};
1518
1519const getElement = (ref) => getHostRef(ref).$hostElement$;
1520
1521exports.bootstrapLazy = bootstrapLazy;
1522exports.getContext = getContext;
1523exports.getElement = getElement;
1524exports.h = h;
1525exports.patchBrowser = patchBrowser;
1526exports.patchEsm = patchEsm;
1527exports.registerInstance = registerInstance;