UNPKG

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