UNPKG

40.3 kBJavaScriptView Raw
1const NAMESPACE = 'ionicons';
2
3let scopeId;
4let hostTagName;
5let isSvgMode = false;
6let queuePending = false;
7const win = typeof window !== 'undefined' ? window : {};
8const doc = win.document || { head: {} };
9const plt = {
10 $flags$: 0,
11 $resourcesUrl$: '',
12 jmp: h => h(),
13 raf: h => requestAnimationFrame(h),
14 ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
15 rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
16 ce: (eventName, opts) => new CustomEvent(eventName, opts),
17};
18const promiseResolve = (v) => Promise.resolve(v);
19const supportsConstructibleStylesheets = /*@__PURE__*/ (() => {
20 try {
21 new CSSStyleSheet();
22 return typeof (new CSSStyleSheet()).replace === 'function';
23 }
24 catch (e) { }
25 return false;
26 })()
27 ;
28const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
29const createTime = (fnName, tagName = '') => {
30 {
31 return () => {
32 return;
33 };
34 }
35};
36const uniqueTime = (key, measureText) => {
37 {
38 return () => {
39 return;
40 };
41 }
42};
43const rootAppliedStyles = new WeakMap();
44const registerStyle = (scopeId, cssText, allowCS) => {
45 let style = styles.get(scopeId);
46 if (supportsConstructibleStylesheets && allowCS) {
47 style = (style || new CSSStyleSheet());
48 style.replace(cssText);
49 }
50 else {
51 style = cssText;
52 }
53 styles.set(scopeId, style);
54};
55const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
56 let scopeId = getScopeId(cmpMeta);
57 let style = styles.get(scopeId);
58 // if an element is NOT connected then getRootNode() will return the wrong root node
59 // so the fallback is to always use the document for the root node in those cases
60 styleContainerNode = styleContainerNode.nodeType === 11 /* DocumentFragment */ ? styleContainerNode : doc;
61 if (style) {
62 if (typeof style === 'string') {
63 styleContainerNode = styleContainerNode.head || styleContainerNode;
64 let appliedStyles = rootAppliedStyles.get(styleContainerNode);
65 let styleElm;
66 if (!appliedStyles) {
67 rootAppliedStyles.set(styleContainerNode, (appliedStyles = new Set()));
68 }
69 if (!appliedStyles.has(scopeId)) {
70 {
71 {
72 styleElm = doc.createElement('style');
73 styleElm.innerHTML = style;
74 }
75 styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
76 }
77 if (appliedStyles) {
78 appliedStyles.add(scopeId);
79 }
80 }
81 }
82 else if (!styleContainerNode.adoptedStyleSheets.includes(style)) {
83 styleContainerNode.adoptedStyleSheets = [...styleContainerNode.adoptedStyleSheets, style];
84 }
85 }
86 return scopeId;
87};
88const attachStyles = (hostRef) => {
89 const cmpMeta = hostRef.$cmpMeta$;
90 const elm = hostRef.$hostElement$;
91 const flags = cmpMeta.$flags$;
92 const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
93 const scopeId = addStyle(elm.shadowRoot ? elm.shadowRoot : elm.getRootNode(), cmpMeta);
94 if (flags & 10 /* needsScopedEncapsulation */) {
95 // only required when we're NOT using native shadow dom (slot)
96 // or this browser doesn't support native shadow dom
97 // and this host element was NOT created with SSR
98 // let's pick out the inner content for slot projection
99 // create a node to represent where the original
100 // content was first placed, which is useful later on
101 // DOM WRITE!!
102 elm['s-sc'] = scopeId;
103 elm.classList.add(scopeId + '-h');
104 }
105 endAttachStyles();
106};
107const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
108/**
109 * Default style mode id
110 */
111/**
112 * Reusable empty obj/array
113 * Don't add values to these!!
114 */
115const EMPTY_OBJ = {};
116const isDef = (v) => v != null;
117const isComplexType = (o) => {
118 // https://jsperf.com/typeof-fn-object/5
119 o = typeof o;
120 return o === 'object' || o === 'function';
121};
122/**
123 * Production h() function based on Preact by
124 * Jason Miller (@developit)
125 * Licensed under the MIT License
126 * https://github.com/developit/preact/blob/master/LICENSE
127 *
128 * Modified for Stencil's compiler and vdom
129 */
130// const stack: any[] = [];
131// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, child?: d.ChildType): d.VNode;
132// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
133const h = (nodeName, vnodeData, ...children) => {
134 let child = null;
135 let simple = false;
136 let lastSimple = false;
137 let vNodeChildren = [];
138 const walk = (c) => {
139 for (let i = 0; i < c.length; i++) {
140 child = c[i];
141 if (Array.isArray(child)) {
142 walk(child);
143 }
144 else if (child != null && typeof child !== 'boolean') {
145 if ((simple = typeof nodeName !== 'function' && !isComplexType(child))) {
146 child = String(child);
147 }
148 if (simple && lastSimple) {
149 // If the previous child was simple (string), we merge both
150 vNodeChildren[vNodeChildren.length - 1].$text$ += child;
151 }
152 else {
153 // Append a new vNode, if it's text, we create a text vNode
154 vNodeChildren.push(simple ? newVNode(null, child) : child);
155 }
156 lastSimple = simple;
157 }
158 }
159 };
160 walk(children);
161 if (vnodeData) {
162 {
163 const classData = vnodeData.className || vnodeData.class;
164 if (classData) {
165 vnodeData.class =
166 typeof classData !== 'object'
167 ? classData
168 : Object.keys(classData)
169 .filter(k => classData[k])
170 .join(' ');
171 }
172 }
173 }
174 const vnode = newVNode(nodeName, null);
175 vnode.$attrs$ = vnodeData;
176 if (vNodeChildren.length > 0) {
177 vnode.$children$ = vNodeChildren;
178 }
179 return vnode;
180};
181const newVNode = (tag, text) => {
182 const vnode = {
183 $flags$: 0,
184 $tag$: tag,
185 $text$: text,
186 $elm$: null,
187 $children$: null,
188 };
189 {
190 vnode.$attrs$ = null;
191 }
192 return vnode;
193};
194const Host = {};
195const isHost = (node) => node && node.$tag$ === Host;
196/**
197 * Production setAccessor() function based on Preact by
198 * Jason Miller (@developit)
199 * Licensed under the MIT License
200 * https://github.com/developit/preact/blob/master/LICENSE
201 *
202 * Modified for Stencil's compiler and vdom
203 */
204const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
205 if (oldValue !== newValue) {
206 let isProp = isMemberInElement(elm, memberName);
207 memberName.toLowerCase();
208 if (memberName === 'class') {
209 const classList = elm.classList;
210 const oldClasses = parseClassList(oldValue);
211 const newClasses = parseClassList(newValue);
212 classList.remove(...oldClasses.filter(c => c && !newClasses.includes(c)));
213 classList.add(...newClasses.filter(c => c && !oldClasses.includes(c)));
214 }
215 else {
216 // Set property if it exists and it's not a SVG
217 const isComplex = isComplexType(newValue);
218 if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
219 try {
220 if (!elm.tagName.includes('-')) {
221 let n = newValue == null ? '' : newValue;
222 // Workaround for Safari, moving the <input> caret when re-assigning the same valued
223 if (memberName === 'list') {
224 isProp = false;
225 // tslint:disable-next-line: triple-equals
226 }
227 else if (oldValue == null || elm[memberName] != n) {
228 elm[memberName] = n;
229 }
230 }
231 else {
232 elm[memberName] = newValue;
233 }
234 }
235 catch (e) { }
236 }
237 if (newValue == null || newValue === false) {
238 if (newValue !== false || elm.getAttribute(memberName) === '') {
239 {
240 elm.removeAttribute(memberName);
241 }
242 }
243 }
244 else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex) {
245 newValue = newValue === true ? '' : newValue;
246 {
247 elm.setAttribute(memberName, newValue);
248 }
249 }
250 }
251 }
252};
253const parseClassListRegex = /\s/;
254const parseClassList = (value) => (!value ? [] : value.split(parseClassListRegex));
255const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
256 // if the element passed in is a shadow root, which is a document fragment
257 // then we want to be adding attrs/props to the shadow root's "host" element
258 // if it's not a shadow root, then we add attrs/props to the same element
259 const elm = newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host ? newVnode.$elm$.host : newVnode.$elm$;
260 const oldVnodeAttrs = (oldVnode && oldVnode.$attrs$) || EMPTY_OBJ;
261 const newVnodeAttrs = newVnode.$attrs$ || EMPTY_OBJ;
262 {
263 // remove attributes no longer present on the vnode by setting them to undefined
264 for (memberName in oldVnodeAttrs) {
265 if (!(memberName in newVnodeAttrs)) {
266 setAccessor(elm, memberName, oldVnodeAttrs[memberName], undefined, isSvgMode, newVnode.$flags$);
267 }
268 }
269 }
270 // add new & update changed attributes
271 for (memberName in newVnodeAttrs) {
272 setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode, newVnode.$flags$);
273 }
274};
275const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
276 // tslint:disable-next-line: prefer-const
277 let newVNode = newParentVNode.$children$[childIndex];
278 let i = 0;
279 let elm;
280 let childNode;
281 if (newVNode.$text$ !== null) {
282 // create text node
283 elm = newVNode.$elm$ = doc.createTextNode(newVNode.$text$);
284 }
285 else {
286 // create element
287 elm = newVNode.$elm$ = (doc.createElement(newVNode.$tag$));
288 // add css classes, attrs, props, listeners, etc.
289 {
290 updateElement(null, newVNode, isSvgMode);
291 }
292 if (isDef(scopeId) && elm['s-si'] !== scopeId) {
293 // if there is a scopeId and this is the initial render
294 // then let's add the scopeId as a css class
295 elm.classList.add((elm['s-si'] = scopeId));
296 }
297 if (newVNode.$children$) {
298 for (i = 0; i < newVNode.$children$.length; ++i) {
299 // create the node
300 childNode = createElm(oldParentVNode, newVNode, i);
301 // return node could have been null
302 if (childNode) {
303 // append our new node
304 elm.appendChild(childNode);
305 }
306 }
307 }
308 }
309 return elm;
310};
311const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
312 let containerElm = (parentElm);
313 let childNode;
314 if (containerElm.shadowRoot && containerElm.tagName === hostTagName) {
315 containerElm = containerElm.shadowRoot;
316 }
317 for (; startIdx <= endIdx; ++startIdx) {
318 if (vnodes[startIdx]) {
319 childNode = createElm(null, parentVNode, startIdx);
320 if (childNode) {
321 vnodes[startIdx].$elm$ = childNode;
322 containerElm.insertBefore(childNode, before);
323 }
324 }
325 }
326};
327const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
328 for (; startIdx <= endIdx; ++startIdx) {
329 if ((vnode = vnodes[startIdx])) {
330 elm = vnode.$elm$;
331 // remove the vnode's element from the dom
332 elm.remove();
333 }
334 }
335};
336const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
337 let oldStartIdx = 0;
338 let newStartIdx = 0;
339 let oldEndIdx = oldCh.length - 1;
340 let oldStartVnode = oldCh[0];
341 let oldEndVnode = oldCh[oldEndIdx];
342 let newEndIdx = newCh.length - 1;
343 let newStartVnode = newCh[0];
344 let newEndVnode = newCh[newEndIdx];
345 let node;
346 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
347 if (oldStartVnode == null) {
348 // Vnode might have been moved left
349 oldStartVnode = oldCh[++oldStartIdx];
350 }
351 else if (oldEndVnode == null) {
352 oldEndVnode = oldCh[--oldEndIdx];
353 }
354 else if (newStartVnode == null) {
355 newStartVnode = newCh[++newStartIdx];
356 }
357 else if (newEndVnode == null) {
358 newEndVnode = newCh[--newEndIdx];
359 }
360 else if (isSameVnode(oldStartVnode, newStartVnode)) {
361 patch(oldStartVnode, newStartVnode);
362 oldStartVnode = oldCh[++oldStartIdx];
363 newStartVnode = newCh[++newStartIdx];
364 }
365 else if (isSameVnode(oldEndVnode, newEndVnode)) {
366 patch(oldEndVnode, newEndVnode);
367 oldEndVnode = oldCh[--oldEndIdx];
368 newEndVnode = newCh[--newEndIdx];
369 }
370 else if (isSameVnode(oldStartVnode, newEndVnode)) {
371 patch(oldStartVnode, newEndVnode);
372 parentElm.insertBefore(oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
373 oldStartVnode = oldCh[++oldStartIdx];
374 newEndVnode = newCh[--newEndIdx];
375 }
376 else if (isSameVnode(oldEndVnode, newStartVnode)) {
377 patch(oldEndVnode, newStartVnode);
378 parentElm.insertBefore(oldEndVnode.$elm$, oldStartVnode.$elm$);
379 oldEndVnode = oldCh[--oldEndIdx];
380 newStartVnode = newCh[++newStartIdx];
381 }
382 else {
383 {
384 // new element
385 node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx);
386 newStartVnode = newCh[++newStartIdx];
387 }
388 if (node) {
389 {
390 oldStartVnode.$elm$.parentNode.insertBefore(node, oldStartVnode.$elm$);
391 }
392 }
393 }
394 }
395 if (oldStartIdx > oldEndIdx) {
396 addVnodes(parentElm, newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$, newVNode, newCh, newStartIdx, newEndIdx);
397 }
398 else if (newStartIdx > newEndIdx) {
399 removeVnodes(oldCh, oldStartIdx, oldEndIdx);
400 }
401};
402const isSameVnode = (vnode1, vnode2) => {
403 // compare if two vnode to see if they're "technically" the same
404 // need to have the same element tag, and same key to be the same
405 if (vnode1.$tag$ === vnode2.$tag$) {
406 return true;
407 }
408 return false;
409};
410const patch = (oldVNode, newVNode) => {
411 const elm = (newVNode.$elm$ = oldVNode.$elm$);
412 const oldChildren = oldVNode.$children$;
413 const newChildren = newVNode.$children$;
414 const text = newVNode.$text$;
415 if (text === null) {
416 // element node
417 {
418 {
419 // either this is the first render of an element OR it's an update
420 // AND we already know it's possible it could have changed
421 // this updates the element's css classes, attrs, props, listeners, etc.
422 updateElement(oldVNode, newVNode, isSvgMode);
423 }
424 }
425 if (oldChildren !== null && newChildren !== null) {
426 // looks like there's child vnodes for both the old and new vnodes
427 updateChildren(elm, oldChildren, newVNode, newChildren);
428 }
429 else if (newChildren !== null) {
430 // no old child vnodes, but there are new child vnodes to add
431 if (oldVNode.$text$ !== null) {
432 // the old vnode was text, so be sure to clear it out
433 elm.textContent = '';
434 }
435 // add the new vnode children
436 addVnodes(elm, null, newVNode, newChildren, 0, newChildren.length - 1);
437 }
438 else if (oldChildren !== null) {
439 // no new child vnodes, but there are old child vnodes to remove
440 removeVnodes(oldChildren, 0, oldChildren.length - 1);
441 }
442 }
443 else if (oldVNode.$text$ !== text) {
444 // update the text content for the text only vnode
445 // and also only if the text is different than before
446 elm.data = text;
447 }
448};
449const renderVdom = (hostRef, renderFnResults) => {
450 const hostElm = hostRef.$hostElement$;
451 const cmpMeta = hostRef.$cmpMeta$;
452 const oldVNode = hostRef.$vnode$ || newVNode(null, null);
453 const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
454 hostTagName = hostElm.tagName;
455 if (cmpMeta.$attrsToReflect$) {
456 rootVnode.$attrs$ = rootVnode.$attrs$ || {};
457 cmpMeta.$attrsToReflect$.map(([propName, attribute]) => (rootVnode.$attrs$[attribute] = hostElm[propName]));
458 }
459 rootVnode.$tag$ = null;
460 rootVnode.$flags$ |= 4 /* isHost */;
461 hostRef.$vnode$ = rootVnode;
462 rootVnode.$elm$ = oldVNode.$elm$ = (hostElm.shadowRoot || hostElm );
463 {
464 scopeId = hostElm['s-sc'];
465 }
466 // synchronous patch
467 patch(oldVNode, rootVnode);
468};
469const getElement = (ref) => (getHostRef(ref).$hostElement$ );
470const emitEvent = (elm, name, opts) => {
471 const ev = plt.ce(name, opts);
472 elm.dispatchEvent(ev);
473 return ev;
474};
475const attachToAncestor = (hostRef, ancestorComponent) => {
476 if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
477 ancestorComponent['s-p'].push(new Promise(r => (hostRef.$onRenderResolve$ = r)));
478 }
479};
480const scheduleUpdate = (hostRef, isInitialLoad) => {
481 {
482 hostRef.$flags$ |= 16 /* isQueuedForUpdate */;
483 }
484 if (hostRef.$flags$ & 4 /* isWaitingForChildren */) {
485 hostRef.$flags$ |= 512 /* needsRerender */;
486 return;
487 }
488 attachToAncestor(hostRef, hostRef.$ancestorComponent$);
489 // there is no ancestor component or the ancestor component
490 // has already fired off its lifecycle update then
491 // fire off the initial update
492 const dispatch = () => dispatchHooks(hostRef, isInitialLoad);
493 return writeTask(dispatch) ;
494};
495const dispatchHooks = (hostRef, isInitialLoad) => {
496 const endSchedule = createTime('scheduleUpdate', hostRef.$cmpMeta$.$tagName$);
497 const instance = hostRef.$lazyInstance$ ;
498 let promise;
499 endSchedule();
500 return then(promise, () => updateComponent(hostRef, instance, isInitialLoad));
501};
502const updateComponent = async (hostRef, instance, isInitialLoad) => {
503 // updateComponent
504 const elm = hostRef.$hostElement$;
505 const endUpdate = createTime('update', hostRef.$cmpMeta$.$tagName$);
506 const rc = elm['s-rc'];
507 if (isInitialLoad) {
508 // DOM WRITE!
509 attachStyles(hostRef);
510 }
511 const endRender = createTime('render', hostRef.$cmpMeta$.$tagName$);
512 {
513 callRender(hostRef, instance);
514 }
515 if (rc) {
516 // ok, so turns out there are some child host elements
517 // waiting on this parent element to load
518 // let's fire off all update callbacks waiting
519 rc.map(cb => cb());
520 elm['s-rc'] = undefined;
521 }
522 endRender();
523 endUpdate();
524 {
525 const childrenPromises = elm['s-p'];
526 const postUpdate = () => postUpdateComponent(hostRef);
527 if (childrenPromises.length === 0) {
528 postUpdate();
529 }
530 else {
531 Promise.all(childrenPromises).then(postUpdate);
532 hostRef.$flags$ |= 4 /* isWaitingForChildren */;
533 childrenPromises.length = 0;
534 }
535 }
536};
537const callRender = (hostRef, instance, elm) => {
538 try {
539 instance = instance.render() ;
540 {
541 hostRef.$flags$ &= ~16 /* isQueuedForUpdate */;
542 }
543 {
544 hostRef.$flags$ |= 2 /* hasRendered */;
545 }
546 {
547 {
548 // looks like we've got child nodes to render into this host element
549 // or we need to update the css class/attrs on the host element
550 // DOM WRITE!
551 {
552 renderVdom(hostRef, instance);
553 }
554 }
555 }
556 }
557 catch (e) {
558 consoleError(e, hostRef.$hostElement$);
559 }
560 return null;
561};
562const postUpdateComponent = (hostRef) => {
563 const tagName = hostRef.$cmpMeta$.$tagName$;
564 const elm = hostRef.$hostElement$;
565 const endPostUpdate = createTime('postUpdate', tagName);
566 const ancestorComponent = hostRef.$ancestorComponent$;
567 if (!(hostRef.$flags$ & 64 /* hasLoadedComponent */)) {
568 hostRef.$flags$ |= 64 /* hasLoadedComponent */;
569 {
570 // DOM WRITE!
571 addHydratedFlag(elm);
572 }
573 endPostUpdate();
574 {
575 hostRef.$onReadyResolve$(elm);
576 if (!ancestorComponent) {
577 appDidLoad();
578 }
579 }
580 }
581 else {
582 endPostUpdate();
583 }
584 // load events fire from bottom to top
585 // the deepest elements load first then bubbles up
586 {
587 if (hostRef.$onRenderResolve$) {
588 hostRef.$onRenderResolve$();
589 hostRef.$onRenderResolve$ = undefined;
590 }
591 if (hostRef.$flags$ & 512 /* needsRerender */) {
592 nextTick(() => scheduleUpdate(hostRef, false));
593 }
594 hostRef.$flags$ &= ~(4 /* isWaitingForChildren */ | 512 /* needsRerender */);
595 }
596 // ( •_•)
597 // ( •_•)>⌐■-■
598 // (⌐■_■)
599};
600const appDidLoad = (who) => {
601 // on appload
602 // we have finish the first big initial render
603 {
604 addHydratedFlag(doc.documentElement);
605 }
606 nextTick(() => emitEvent(win, 'appload', { detail: { namespace: NAMESPACE } }));
607};
608const safeCall = (instance, method, arg) => {
609 if (instance && instance[method]) {
610 try {
611 return instance[method](arg);
612 }
613 catch (e) {
614 consoleError(e);
615 }
616 }
617 return undefined;
618};
619const then = (promise, thenFn) => {
620 return promise && promise.then ? promise.then(thenFn) : thenFn();
621};
622const addHydratedFlag = (elm) => (elm.classList.add('hydrated') );
623const parsePropertyValue = (propValue, propType) => {
624 // ensure this value is of the correct prop type
625 if (propValue != null && !isComplexType(propValue)) {
626 if (propType & 4 /* Boolean */) {
627 // per the HTML spec, any string value means it is a boolean true value
628 // but we'll cheat here and say that the string "false" is the boolean false
629 return propValue === 'false' ? false : propValue === '' || !!propValue;
630 }
631 if (propType & 1 /* String */) {
632 // could have been passed as a number or boolean
633 // but we still want it as a string
634 return String(propValue);
635 }
636 // redundant return here for better minification
637 return propValue;
638 }
639 // not sure exactly what type we want
640 // so no need to change to a different type
641 return propValue;
642};
643const getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
644const setValue = (ref, propName, newVal, cmpMeta) => {
645 // check our new property value against our internal value
646 const hostRef = getHostRef(ref);
647 const elm = hostRef.$hostElement$ ;
648 const oldVal = hostRef.$instanceValues$.get(propName);
649 const flags = hostRef.$flags$;
650 const instance = hostRef.$lazyInstance$ ;
651 newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
652 if ((!(flags & 8 /* isConstructingInstance */) || oldVal === undefined) && newVal !== oldVal) {
653 // gadzooks! the property's value has changed!!
654 // set our new value!
655 hostRef.$instanceValues$.set(propName, newVal);
656 if (instance) {
657 // get an array of method names of watch functions to call
658 if (cmpMeta.$watchers$ && flags & 128 /* isWatchReady */) {
659 const watchMethods = cmpMeta.$watchers$[propName];
660 if (watchMethods) {
661 // this instance is watching for when this property changed
662 watchMethods.map(watchMethodName => {
663 try {
664 // fire off each of the watch methods that are watching this property
665 instance[watchMethodName](newVal, oldVal, propName);
666 }
667 catch (e) {
668 consoleError(e, elm);
669 }
670 });
671 }
672 }
673 if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
674 // looks like this value actually changed, so we've got work to do!
675 // but only if we've already rendered, otherwise just chill out
676 // queue that we need to do an update, but don't worry about queuing
677 // up millions cuz this function ensures it only runs once
678 scheduleUpdate(hostRef, false);
679 }
680 }
681 }
682};
683const proxyComponent = (Cstr, cmpMeta, flags) => {
684 if (cmpMeta.$members$) {
685 if (Cstr.watchers) {
686 cmpMeta.$watchers$ = Cstr.watchers;
687 }
688 // It's better to have a const than two Object.entries()
689 const members = Object.entries(cmpMeta.$members$);
690 const prototype = Cstr.prototype;
691 members.map(([memberName, [memberFlags]]) => {
692 if ((memberFlags & 31 /* Prop */ || ((flags & 2 /* proxyState */) && memberFlags & 32 /* State */))) {
693 // proxyComponent - prop
694 Object.defineProperty(prototype, memberName, {
695 get() {
696 // proxyComponent, get value
697 return getValue(this, memberName);
698 },
699 set(newValue) {
700 // proxyComponent, set value
701 setValue(this, memberName, newValue, cmpMeta);
702 },
703 configurable: true,
704 enumerable: true,
705 });
706 }
707 });
708 if ((flags & 1 /* isElementConstructor */)) {
709 const attrNameToPropName = new Map();
710 prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
711 plt.jmp(() => {
712 const propName = attrNameToPropName.get(attrName);
713 this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
714 });
715 };
716 // create an array of attributes to observe
717 // and also create a map of html attribute name to js property name
718 Cstr.observedAttributes = members
719 .filter(([_, m]) => m[0] & 15 /* HasAttribute */) // filter to only keep props that should match attributes
720 .map(([propName, m]) => {
721 const attrName = m[1] || propName;
722 attrNameToPropName.set(attrName, propName);
723 if (m[0] & 512 /* ReflectAttr */) {
724 cmpMeta.$attrsToReflect$.push([propName, attrName]);
725 }
726 return attrName;
727 });
728 }
729 }
730 return Cstr;
731};
732const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
733 // initializeComponent
734 if ((hostRef.$flags$ & 32 /* hasInitializedComponent */) === 0) {
735 {
736 // we haven't initialized this element yet
737 hostRef.$flags$ |= 32 /* hasInitializedComponent */;
738 // lazy loaded components
739 // request the component's implementation to be
740 // wired up with the host element
741 Cstr = loadModule(cmpMeta);
742 if (Cstr.then) {
743 // Await creates a micro-task avoid if possible
744 const endLoad = uniqueTime();
745 Cstr = await Cstr;
746 endLoad();
747 }
748 if (!Cstr.isProxied) {
749 // we'eve never proxied this Constructor before
750 // let's add the getters/setters to its prototype before
751 // the first time we create an instance of the implementation
752 {
753 cmpMeta.$watchers$ = Cstr.watchers;
754 }
755 proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
756 Cstr.isProxied = true;
757 }
758 const endNewInstance = createTime('createInstance', cmpMeta.$tagName$);
759 // ok, time to construct the instance
760 // but let's keep track of when we start and stop
761 // so that the getters/setters don't incorrectly step on data
762 {
763 hostRef.$flags$ |= 8 /* isConstructingInstance */;
764 }
765 // construct the lazy-loaded component implementation
766 // passing the hostRef is very important during
767 // construction in order to directly wire together the
768 // host element and the lazy-loaded instance
769 try {
770 new Cstr(hostRef);
771 }
772 catch (e) {
773 consoleError(e);
774 }
775 {
776 hostRef.$flags$ &= ~8 /* isConstructingInstance */;
777 }
778 {
779 hostRef.$flags$ |= 128 /* isWatchReady */;
780 }
781 endNewInstance();
782 fireConnectedCallback(hostRef.$lazyInstance$);
783 }
784 if (Cstr.style) {
785 // this component has styles but we haven't registered them yet
786 let style = Cstr.style;
787 const scopeId = getScopeId(cmpMeta);
788 if (!styles.has(scopeId)) {
789 const endRegisterStyles = createTime('registerStyles', cmpMeta.$tagName$);
790 registerStyle(scopeId, style, !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */));
791 endRegisterStyles();
792 }
793 }
794 }
795 // we've successfully created a lazy instance
796 const ancestorComponent = hostRef.$ancestorComponent$;
797 const schedule = () => scheduleUpdate(hostRef, true);
798 if (ancestorComponent && ancestorComponent['s-rc']) {
799 // this is the intial load and this component it has an ancestor component
800 // but the ancestor component has NOT fired its will update lifecycle yet
801 // so let's just cool our jets and wait for the ancestor to continue first
802 // this will get fired off when the ancestor component
803 // finally gets around to rendering its lazy self
804 // fire off the initial update
805 ancestorComponent['s-rc'].push(schedule);
806 }
807 else {
808 schedule();
809 }
810};
811const fireConnectedCallback = (instance) => {
812 {
813 safeCall(instance, 'connectedCallback');
814 }
815};
816const connectedCallback = (elm) => {
817 if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
818 const hostRef = getHostRef(elm);
819 const cmpMeta = hostRef.$cmpMeta$;
820 const endConnected = createTime('connectedCallback', cmpMeta.$tagName$);
821 if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
822 // first time this component has connected
823 hostRef.$flags$ |= 1 /* hasConnected */;
824 {
825 // find the first ancestor component (if there is one) and register
826 // this component as one of the actively loading child components for its ancestor
827 let ancestorComponent = elm;
828 while ((ancestorComponent = ancestorComponent.parentNode || ancestorComponent.host)) {
829 // climb up the ancestors looking for the first
830 // component that hasn't finished its lifecycle update yet
831 if (ancestorComponent['s-p']) {
832 // we found this components first ancestor component
833 // keep a reference to this component's ancestor component
834 attachToAncestor(hostRef, (hostRef.$ancestorComponent$ = ancestorComponent));
835 break;
836 }
837 }
838 }
839 // Lazy properties
840 // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
841 if (cmpMeta.$members$) {
842 Object.entries(cmpMeta.$members$).map(([memberName, [memberFlags]]) => {
843 if (memberFlags & 31 /* Prop */ && elm.hasOwnProperty(memberName)) {
844 const value = elm[memberName];
845 delete elm[memberName];
846 elm[memberName] = value;
847 }
848 });
849 }
850 {
851 initializeComponent(elm, hostRef, cmpMeta);
852 }
853 }
854 else {
855 // fire off connectedCallback() on component instance
856 fireConnectedCallback(hostRef.$lazyInstance$);
857 }
858 endConnected();
859 }
860};
861const disconnectedCallback = (elm) => {
862 if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
863 const hostRef = getHostRef(elm);
864 const instance = hostRef.$lazyInstance$ ;
865 {
866 safeCall(instance, 'disconnectedCallback');
867 }
868 }
869};
870const bootstrapLazy = (lazyBundles, options = {}) => {
871 const endBootstrap = createTime();
872 const cmpTags = [];
873 const exclude = options.exclude || [];
874 const customElements = win.customElements;
875 const head = doc.head;
876 const metaCharset = /*@__PURE__*/ head.querySelector('meta[charset]');
877 const visibilityStyle = /*@__PURE__*/ doc.createElement('style');
878 const deferredConnectedCallbacks = [];
879 let appLoadFallback;
880 let isBootstrapping = true;
881 Object.assign(plt, options);
882 plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
883 lazyBundles.map(lazyBundle => lazyBundle[1].map(compactMeta => {
884 const cmpMeta = {
885 $flags$: compactMeta[0],
886 $tagName$: compactMeta[1],
887 $members$: compactMeta[2],
888 $listeners$: compactMeta[3],
889 };
890 {
891 cmpMeta.$members$ = compactMeta[2];
892 }
893 {
894 cmpMeta.$attrsToReflect$ = [];
895 }
896 {
897 cmpMeta.$watchers$ = {};
898 }
899 const tagName = cmpMeta.$tagName$;
900 const HostElement = class extends HTMLElement {
901 // StencilLazyHost
902 constructor(self) {
903 // @ts-ignore
904 super(self);
905 self = this;
906 registerHost(self, cmpMeta);
907 if (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) {
908 // this component is using shadow dom
909 // and this browser supports shadow dom
910 // add the read-only property "shadowRoot" to the host element
911 // adding the shadow root build conditionals to minimize runtime
912 {
913 {
914 self.attachShadow({ mode: 'open' });
915 }
916 }
917 }
918 }
919 connectedCallback() {
920 if (appLoadFallback) {
921 clearTimeout(appLoadFallback);
922 appLoadFallback = null;
923 }
924 if (isBootstrapping) {
925 // connectedCallback will be processed once all components have been registered
926 deferredConnectedCallbacks.push(this);
927 }
928 else {
929 plt.jmp(() => connectedCallback(this));
930 }
931 }
932 disconnectedCallback() {
933 plt.jmp(() => disconnectedCallback(this));
934 }
935 componentOnReady() {
936 return getHostRef(this).$onReadyPromise$;
937 }
938 };
939 cmpMeta.$lazyBundleId$ = lazyBundle[0];
940 if (!exclude.includes(tagName) && !customElements.get(tagName)) {
941 cmpTags.push(tagName);
942 customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* isElementConstructor */));
943 }
944 }));
945 {
946 visibilityStyle.innerHTML = cmpTags + HYDRATED_CSS;
947 visibilityStyle.setAttribute('data-styles', '');
948 head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
949 }
950 // Process deferred connectedCallbacks now all components have been registered
951 isBootstrapping = false;
952 if (deferredConnectedCallbacks.length) {
953 deferredConnectedCallbacks.map(host => host.connectedCallback());
954 }
955 else {
956 {
957 plt.jmp(() => (appLoadFallback = setTimeout(appDidLoad, 30)));
958 }
959 }
960 // Fallback appLoad event
961 endBootstrap();
962};
963const getAssetPath = (path) => {
964 const assetUrl = new URL(path, plt.$resourcesUrl$);
965 return assetUrl.origin !== win.location.origin ? assetUrl.href : assetUrl.pathname;
966};
967const hostRefs = new WeakMap();
968const getHostRef = (ref) => hostRefs.get(ref);
969const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
970const registerHost = (elm, cmpMeta) => {
971 const hostRef = {
972 $flags$: 0,
973 $hostElement$: elm,
974 $cmpMeta$: cmpMeta,
975 $instanceValues$: new Map(),
976 };
977 {
978 hostRef.$onReadyPromise$ = new Promise(r => (hostRef.$onReadyResolve$ = r));
979 elm['s-p'] = [];
980 elm['s-rc'] = [];
981 }
982 return hostRefs.set(elm, hostRef);
983};
984const isMemberInElement = (elm, memberName) => memberName in elm;
985const consoleError = (e, el) => (0, console.error)(e, el);
986const cmpModules = /*@__PURE__*/ new Map();
987const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
988 // loadModuleImport
989 const exportName = cmpMeta.$tagName$.replace(/-/g, '_');
990 const bundleId = cmpMeta.$lazyBundleId$;
991 const module = cmpModules.get(bundleId) ;
992 if (module) {
993 return module[exportName];
994 }
995 return import(
996 /* webpackInclude: /\.entry\.js$/ */
997 /* webpackExclude: /\.system\.entry\.js$/ */
998 /* webpackMode: "lazy" */
999 `./${bundleId}.entry.js${''}`).then(importedModule => {
1000 {
1001 cmpModules.set(bundleId, importedModule);
1002 }
1003 return importedModule[exportName];
1004 }, consoleError);
1005};
1006const styles = new Map();
1007const queueDomReads = [];
1008const queueDomWrites = [];
1009const queueTask = (queue, write) => (cb) => {
1010 queue.push(cb);
1011 if (!queuePending) {
1012 queuePending = true;
1013 if (write && plt.$flags$ & 4 /* queueSync */) {
1014 nextTick(flush);
1015 }
1016 else {
1017 plt.raf(flush);
1018 }
1019 }
1020};
1021const consume = (queue) => {
1022 for (let i = 0; i < queue.length; i++) {
1023 try {
1024 queue[i](performance.now());
1025 }
1026 catch (e) {
1027 consoleError(e);
1028 }
1029 }
1030 queue.length = 0;
1031};
1032const flush = () => {
1033 // always force a bunch of medium callbacks to run, but still have
1034 // a throttle on how many can run in a certain time
1035 // DOM READS!!!
1036 consume(queueDomReads);
1037 // DOM WRITES!!!
1038 {
1039 consume(queueDomWrites);
1040 if ((queuePending = queueDomReads.length > 0)) {
1041 // still more to do yet, but we've run out of time
1042 // let's let this thing cool off and try again in the next tick
1043 plt.raf(flush);
1044 }
1045 }
1046};
1047const nextTick = /*@__PURE__*/ (cb) => promiseResolve().then(cb);
1048const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
1049
1050export { Host as H, getElement as a, bootstrapLazy as b, getAssetPath as g, h, promiseResolve as p, registerInstance as r };