@oila/0account 3.4.7 → 3.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/cjs/{index-1e526aba.js → index-ef57218a.js} +370 -67
  2. package/dist/cjs/index-ef57218a.js.map +1 -0
  3. package/dist/cjs/loader.cjs.js +2 -2
  4. package/dist/cjs/loader.cjs.js.map +1 -1
  5. package/dist/cjs/qr-code_2.cjs.entry.js +358 -1278
  6. package/dist/cjs/qr-code_2.cjs.entry.js.map +1 -1
  7. package/dist/cjs/zero-account.cjs.js +2 -2
  8. package/dist/cjs/zero-account.cjs.js.map +1 -1
  9. package/dist/collection/collection-manifest.json +2 -2
  10. package/dist/collection/components/zero-account/enums.js +8 -8
  11. package/dist/collection/components/zero-account/enums.js.map +1 -1
  12. package/dist/collection/components/zero-account/logo.js +1 -1
  13. package/dist/collection/components/zero-account/logo.js.map +1 -1
  14. package/dist/collection/components/zero-account/qrcode.js +103 -103
  15. package/dist/collection/components/zero-account/qrcode.js.map +1 -1
  16. package/dist/collection/components/zero-account/websocket.js +149 -148
  17. package/dist/collection/components/zero-account/websocket.js.map +1 -1
  18. package/dist/collection/components/zero-account/zero-account.css +7 -0
  19. package/dist/collection/components/zero-account/zero-account.e2e.js +22 -22
  20. package/dist/collection/components/zero-account/zero-account.e2e.js.map +1 -1
  21. package/dist/collection/components/zero-account/zero-account.js +380 -379
  22. package/dist/collection/components/zero-account/zero-account.js.map +1 -1
  23. package/dist/collection/components/zero-account/zero-account.spec.js +13 -13
  24. package/dist/collection/components/zero-account/zero-account.spec.js.map +1 -1
  25. package/dist/collection/utils/request.js +37 -30
  26. package/dist/collection/utils/request.js.map +1 -1
  27. package/dist/collection/utils/utils.js +10 -10
  28. package/dist/collection/utils/utils.js.map +1 -1
  29. package/dist/collection/utils/utils.spec.js +6 -6
  30. package/dist/collection/utils/utils.spec.js.map +1 -1
  31. package/dist/components/index.d.ts +6 -0
  32. package/dist/components/index.js +1 -1
  33. package/dist/components/qr-code.d.ts +2 -2
  34. package/dist/components/qrcode.js +48 -48
  35. package/dist/components/qrcode.js.map +1 -1
  36. package/dist/components/zero-account.d.ts +2 -2
  37. package/dist/components/zero-account.js +359 -1279
  38. package/dist/components/zero-account.js.map +1 -1
  39. package/dist/esm/{index-09024c20.js → index-798be1d4.js} +370 -67
  40. package/dist/esm/index-798be1d4.js.map +1 -0
  41. package/dist/esm/loader.js +3 -3
  42. package/dist/esm/loader.js.map +1 -1
  43. package/dist/esm/qr-code_2.entry.js +358 -1278
  44. package/dist/esm/qr-code_2.entry.js.map +1 -1
  45. package/dist/esm/zero-account.js +3 -3
  46. package/dist/esm/zero-account.js.map +1 -1
  47. package/dist/types/components/zero-account/enums.d.ts +8 -8
  48. package/dist/types/components/zero-account/logo.d.ts +2 -2
  49. package/dist/types/components/zero-account/qrcode.d.ts +5 -5
  50. package/dist/types/components/zero-account/websocket.d.ts +27 -25
  51. package/dist/types/components/zero-account/zero-account.d.ts +39 -39
  52. package/dist/types/stencil-public-runtime.d.ts +46 -5
  53. package/dist/types/utils/request.d.ts +5 -5
  54. package/dist/types/utils/utils.d.ts +3 -3
  55. package/dist/zero-account/p-3b6bbcf5.js +3 -0
  56. package/dist/zero-account/p-3b6bbcf5.js.map +1 -0
  57. package/dist/zero-account/p-b6f591cf.entry.js +2 -0
  58. package/dist/zero-account/p-b6f591cf.entry.js.map +1 -0
  59. package/dist/zero-account/zero-account.esm.js +1 -1
  60. package/dist/zero-account/zero-account.esm.js.map +1 -1
  61. package/loader/index.d.ts +1 -1
  62. package/package.json +10 -10
  63. package/dist/cjs/index-1e526aba.js.map +0 -1
  64. package/dist/esm/index-09024c20.js.map +0 -1
  65. package/dist/zero-account/p-21f4994d.js +0 -3
  66. package/dist/zero-account/p-21f4994d.js.map +0 -1
  67. package/dist/zero-account/p-a29dc444.entry.js +0 -2
  68. package/dist/zero-account/p-a29dc444.entry.js.map +0 -1
@@ -32,6 +32,7 @@ const NAMESPACE = 'zero-account';
32
32
  */
33
33
  let scopeId;
34
34
  let hostTagName;
35
+ let useNativeShadowDom = false;
35
36
  let isSvgMode = false;
36
37
  let queuePending = false;
37
38
  const Build = {
@@ -55,6 +56,13 @@ const uniqueTime = (key, measureText) => {
55
56
  }
56
57
  };
57
58
  const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
59
+ /**
60
+ * Constant for styles to be globally applied to `slot-fb` elements for pseudo-slot behavior.
61
+ *
62
+ * Two cascading rules must be used instead of a `:not()` selector due to Stencil browser
63
+ * support as of Stencil v4.
64
+ */
65
+ const SLOT_FB_CSS = 'slot-fb{display:contents}slot-fb[hidden]{display:none}';
58
66
  /**
59
67
  * Default style mode id
60
68
  */
@@ -105,6 +113,7 @@ function queryNonceMetaTagContent(doc) {
105
113
  // export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
106
114
  const h = (nodeName, vnodeData, ...children) => {
107
115
  let child = null;
116
+ let key = null;
108
117
  let simple = false;
109
118
  let lastSimple = false;
110
119
  const vNodeChildren = [];
@@ -132,6 +141,10 @@ const h = (nodeName, vnodeData, ...children) => {
132
141
  };
133
142
  walk(children);
134
143
  if (vnodeData) {
144
+ if (vnodeData.key) {
145
+ key = vnodeData.key;
146
+ }
147
+ // normalize class / className attributes
135
148
  {
136
149
  const classData = vnodeData.className || vnodeData.class;
137
150
  if (classData) {
@@ -153,6 +166,9 @@ const h = (nodeName, vnodeData, ...children) => {
153
166
  if (vNodeChildren.length > 0) {
154
167
  vnode.$children$ = vNodeChildren;
155
168
  }
169
+ {
170
+ vnode.$key$ = key;
171
+ }
156
172
  return vnode;
157
173
  };
158
174
  /**
@@ -174,6 +190,9 @@ const newVNode = (tag, text) => {
174
190
  {
175
191
  vnode.$attrs$ = null;
176
192
  }
193
+ {
194
+ vnode.$key$ = null;
195
+ }
177
196
  return vnode;
178
197
  };
179
198
  const Host = {};
@@ -340,6 +359,10 @@ const addStyle = (styleContainerNode, cmpMeta, mode) => {
340
359
  }
341
360
  styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
342
361
  }
362
+ // Add styles for `slot-fb` elements if we're using slots outside the Shadow DOM
363
+ if (cmpMeta.$flags$ & 4 /* CMP_FLAGS.hasSlotRelocation */) {
364
+ styleElm.innerHTML += SLOT_FB_CSS;
365
+ }
343
366
  if (appliedStyles) {
344
367
  appliedStyles.add(scopeId);
345
368
  }
@@ -379,6 +402,21 @@ const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
379
402
  *
380
403
  * Modified for Stencil's compiler and vdom
381
404
  */
405
+ /**
406
+ * When running a VDom render set properties present on a VDom node onto the
407
+ * corresponding HTML element.
408
+ *
409
+ * Note that this function has special functionality for the `class`,
410
+ * `style`, `key`, and `ref` attributes, as well as event handlers (like
411
+ * `onClick`, etc). All others are just passed through as-is.
412
+ *
413
+ * @param elm the HTMLElement onto which attributes should be set
414
+ * @param memberName the name of the attribute to set
415
+ * @param oldValue the old value for the attribute
416
+ * @param newValue the new value for the attribute
417
+ * @param isSvg whether we're in an svg context or not
418
+ * @param flags bitflags for Vdom variables
419
+ */
382
420
  const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
383
421
  if (oldValue !== newValue) {
384
422
  let isProp = isMemberInElement(elm, memberName);
@@ -390,6 +428,8 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
390
428
  classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
391
429
  classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
392
430
  }
431
+ else if (memberName === 'key')
432
+ ;
393
433
  else if (memberName === 'ref') {
394
434
  // minifier will clean this up
395
435
  if (newValue) {
@@ -428,11 +468,19 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
428
468
  // except for the first character, we keep the event name case
429
469
  memberName = ln[2] + memberName.slice(3);
430
470
  }
431
- if (oldValue) {
432
- plt.rel(elm, memberName, oldValue, false);
433
- }
434
- if (newValue) {
435
- plt.ael(elm, memberName, newValue, false);
471
+ if (oldValue || newValue) {
472
+ // Need to account for "capture" events.
473
+ // If the event name ends with "Capture", we'll update the name to remove
474
+ // the "Capture" suffix and make sure the event listener is setup to handle the capture event.
475
+ const capture = memberName.endsWith(CAPTURE_EVENT_SUFFIX);
476
+ // Make sure we only replace the last instance of "Capture"
477
+ memberName = memberName.replace(CAPTURE_EVENT_REGEX, '');
478
+ if (oldValue) {
479
+ plt.rel(elm, memberName, oldValue, capture);
480
+ }
481
+ if (newValue) {
482
+ plt.ael(elm, memberName, newValue, capture);
483
+ }
436
484
  }
437
485
  }
438
486
  else {
@@ -454,7 +502,11 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
454
502
  elm[memberName] = newValue;
455
503
  }
456
504
  }
457
- catch (e) { }
505
+ catch (e) {
506
+ /**
507
+ * in case someone tries to set a read-only property, e.g. "namespaceURI", we just ignore it
508
+ */
509
+ }
458
510
  }
459
511
  if (newValue == null || newValue === false) {
460
512
  if (newValue !== false || elm.getAttribute(memberName) === '') {
@@ -473,7 +525,14 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
473
525
  }
474
526
  };
475
527
  const parseClassListRegex = /\s/;
528
+ /**
529
+ * Parsed a string of classnames into an array
530
+ * @param value className string, e.g. "foo bar baz"
531
+ * @returns list of classes, e.g. ["foo", "bar", "baz"]
532
+ */
476
533
  const parseClassList = (value) => (!value ? [] : value.split(parseClassListRegex));
534
+ const CAPTURE_EVENT_SUFFIX = 'Capture';
535
+ const CAPTURE_EVENT_REGEX = new RegExp(CAPTURE_EVENT_SUFFIX + '$');
477
536
  const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
478
537
  // if the element passed in is a shadow root, which is a document fragment
479
538
  // then we want to be adding attrs/props to the shadow root's "host" element
@@ -557,6 +616,9 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
557
616
  }
558
617
  }
559
618
  }
619
+ // This needs to always happen so we can hide nodes that are projected
620
+ // to another component but don't end up in a slot
621
+ elm['s-hn'] = hostTagName;
560
622
  return elm;
561
623
  };
562
624
  /**
@@ -681,10 +743,13 @@ const removeVnodes = (vnodes, startIdx, endIdx) => {
681
743
  * @param oldCh the old children of the parent node
682
744
  * @param newVNode the new VNode which will replace the parent
683
745
  * @param newCh the new children of the parent node
746
+ * @param isInitialRender whether or not this is the first render of the vdom
684
747
  */
685
- const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
748
+ const updateChildren = (parentElm, oldCh, newVNode, newCh, isInitialRender = false) => {
686
749
  let oldStartIdx = 0;
687
750
  let newStartIdx = 0;
751
+ let idxInOld = 0;
752
+ let i = 0;
688
753
  let oldEndIdx = oldCh.length - 1;
689
754
  let oldStartVnode = oldCh[0];
690
755
  let oldEndVnode = oldCh[oldEndIdx];
@@ -692,6 +757,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
692
757
  let newStartVnode = newCh[0];
693
758
  let newEndVnode = newCh[newEndIdx];
694
759
  let node;
760
+ let elmToMove;
695
761
  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
696
762
  if (oldStartVnode == null) {
697
763
  // VNode might have been moved left
@@ -706,25 +772,25 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
706
772
  else if (newEndVnode == null) {
707
773
  newEndVnode = newCh[--newEndIdx];
708
774
  }
709
- else if (isSameVnode(oldStartVnode, newStartVnode)) {
775
+ else if (isSameVnode(oldStartVnode, newStartVnode, isInitialRender)) {
710
776
  // if the start nodes are the same then we should patch the new VNode
711
777
  // onto the old one, and increment our `newStartIdx` and `oldStartIdx`
712
778
  // indices to reflect that. We don't need to move any DOM Nodes around
713
779
  // since things are matched up in order.
714
- patch(oldStartVnode, newStartVnode);
780
+ patch(oldStartVnode, newStartVnode, isInitialRender);
715
781
  oldStartVnode = oldCh[++oldStartIdx];
716
782
  newStartVnode = newCh[++newStartIdx];
717
783
  }
718
- else if (isSameVnode(oldEndVnode, newEndVnode)) {
784
+ else if (isSameVnode(oldEndVnode, newEndVnode, isInitialRender)) {
719
785
  // likewise, if the end nodes are the same we patch new onto old and
720
786
  // decrement our end indices, and also likewise in this case we don't
721
787
  // need to move any DOM Nodes.
722
- patch(oldEndVnode, newEndVnode);
788
+ patch(oldEndVnode, newEndVnode, isInitialRender);
723
789
  oldEndVnode = oldCh[--oldEndIdx];
724
790
  newEndVnode = newCh[--newEndIdx];
725
791
  }
726
- else if (isSameVnode(oldStartVnode, newEndVnode)) {
727
- patch(oldStartVnode, newEndVnode);
792
+ else if (isSameVnode(oldStartVnode, newEndVnode, isInitialRender)) {
793
+ patch(oldStartVnode, newEndVnode, isInitialRender);
728
794
  // We need to move the element for `oldStartVnode` into a position which
729
795
  // will be appropriate for `newEndVnode`. For this we can use
730
796
  // `.insertBefore` and `oldEndVnode.$elm$.nextSibling`. If there is a
@@ -746,8 +812,8 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
746
812
  oldStartVnode = oldCh[++oldStartIdx];
747
813
  newEndVnode = newCh[--newEndIdx];
748
814
  }
749
- else if (isSameVnode(oldEndVnode, newStartVnode)) {
750
- patch(oldEndVnode, newStartVnode);
815
+ else if (isSameVnode(oldEndVnode, newStartVnode, isInitialRender)) {
816
+ patch(oldEndVnode, newStartVnode, isInitialRender);
751
817
  // We've already checked above if `oldStartVnode` and `newStartVnode` are
752
818
  // the same node, so since we're here we know that they are not. Thus we
753
819
  // can move the element for `oldEndVnode` _before_ the element for
@@ -758,7 +824,41 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
758
824
  newStartVnode = newCh[++newStartIdx];
759
825
  }
760
826
  else {
827
+ // Here we do some checks to match up old and new nodes based on the
828
+ // `$key$` attribute, which is set by putting a `key="my-key"` attribute
829
+ // in the JSX for a DOM element in the implementation of a Stencil
830
+ // component.
831
+ //
832
+ // First we check to see if there are any nodes in the array of old
833
+ // children which have the same key as the first node in the new
834
+ // children.
835
+ idxInOld = -1;
761
836
  {
837
+ for (i = oldStartIdx; i <= oldEndIdx; ++i) {
838
+ if (oldCh[i] && oldCh[i].$key$ !== null && oldCh[i].$key$ === newStartVnode.$key$) {
839
+ idxInOld = i;
840
+ break;
841
+ }
842
+ }
843
+ }
844
+ if (idxInOld >= 0) {
845
+ // We found a node in the old children which matches up with the first
846
+ // node in the new children! So let's deal with that
847
+ elmToMove = oldCh[idxInOld];
848
+ if (elmToMove.$tag$ !== newStartVnode.$tag$) {
849
+ // the tag doesn't match so we'll need a new DOM element
850
+ node = createElm(oldCh && oldCh[newStartIdx], newVNode, idxInOld);
851
+ }
852
+ else {
853
+ patch(elmToMove, newStartVnode, isInitialRender);
854
+ // invalidate the matching old node so that we won't try to update it
855
+ // again later on
856
+ oldCh[idxInOld] = undefined;
857
+ node = elmToMove.$elm$;
858
+ }
859
+ newStartVnode = newCh[++newStartIdx];
860
+ }
861
+ else {
762
862
  // We either didn't find an element in the old children that matches
763
863
  // the key of the first new child OR the build is not using `key`
764
864
  // attributes at all. In either case we need to create a new element
@@ -801,12 +901,21 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
801
901
  *
802
902
  * @param leftVNode the first VNode to check
803
903
  * @param rightVNode the second VNode to check
904
+ * @param isInitialRender whether or not this is the first render of the vdom
804
905
  * @returns whether they're equal or not
805
906
  */
806
- const isSameVnode = (leftVNode, rightVNode) => {
907
+ const isSameVnode = (leftVNode, rightVNode, isInitialRender = false) => {
807
908
  // compare if two vnode to see if they're "technically" the same
808
909
  // need to have the same element tag, and same key to be the same
809
910
  if (leftVNode.$tag$ === rightVNode.$tag$) {
911
+ // this will be set if JSX tags in the build have `key` attrs set on them
912
+ // we only want to check this if we're not on the first render since on
913
+ // first render `leftVNode.$key$` will always be `null`, so we can be led
914
+ // astray and, for instance, accidentally delete a DOM node that we want to
915
+ // keep around.
916
+ if (!isInitialRender) {
917
+ return leftVNode.$key$ === rightVNode.$key$;
918
+ }
810
919
  return true;
811
920
  }
812
921
  return false;
@@ -818,8 +927,9 @@ const isSameVnode = (leftVNode, rightVNode) => {
818
927
  *
819
928
  * @param oldVNode an old VNode whose DOM element and children we want to update
820
929
  * @param newVNode a new VNode representing an updated version of the old one
930
+ * @param isInitialRender whether or not this is the first render of the vdom
821
931
  */
822
- const patch = (oldVNode, newVNode) => {
932
+ const patch = (oldVNode, newVNode, isInitialRender = false) => {
823
933
  const elm = (newVNode.$elm$ = oldVNode.$elm$);
824
934
  const oldChildren = oldVNode.$children$;
825
935
  const newChildren = newVNode.$children$;
@@ -832,8 +942,7 @@ const patch = (oldVNode, newVNode) => {
832
942
  isSvgMode = tag === 'svg' ? true : tag === 'foreignObject' ? false : isSvgMode;
833
943
  }
834
944
  {
835
- if (tag === 'slot')
836
- ;
945
+ if (tag === 'slot' && !useNativeShadowDom) ;
837
946
  else {
838
947
  // either this is the first render of an element OR it's an update
839
948
  // AND we already know it's possible it could have changed
@@ -844,7 +953,7 @@ const patch = (oldVNode, newVNode) => {
844
953
  if (oldChildren !== null && newChildren !== null) {
845
954
  // looks like there's child vnodes for both the old and new vnodes
846
955
  // so we need to call `updateChildren` to reconcile them
847
- updateChildren(elm, oldChildren, newVNode, newChildren);
956
+ updateChildren(elm, oldChildren, newVNode, newChildren, isInitialRender);
848
957
  }
849
958
  else if (newChildren !== null) {
850
959
  // no old child vnodes, but there are new child vnodes to add
@@ -870,9 +979,9 @@ const patch = (oldVNode, newVNode) => {
870
979
  }
871
980
  };
872
981
  /**
873
- * 'Nullify' any VDom `ref` callbacks on a VDom node or its children by
874
- * calling them with `null`. This signals that the DOM element corresponding to
875
- * the VDom node has been removed from the DOM.
982
+ * 'Nullify' any VDom `ref` callbacks on a VDom node or its children by calling
983
+ * them with `null`. This signals that the DOM element corresponding to the VDom
984
+ * node has been removed from the DOM.
876
985
  *
877
986
  * @param vNode a virtual DOM node
878
987
  */
@@ -893,12 +1002,40 @@ const nullifyVNodeRefs = (vNode) => {
893
1002
  * @param hostRef data needed to root and render the virtual DOM tree, such as
894
1003
  * the DOM node into which it should be rendered.
895
1004
  * @param renderFnResults the virtual DOM nodes to be rendered
1005
+ * @param isInitialLoad whether or not this is the first call after page load
896
1006
  */
897
- const renderVdom = (hostRef, renderFnResults) => {
1007
+ const renderVdom = (hostRef, renderFnResults, isInitialLoad = false) => {
898
1008
  const hostElm = hostRef.$hostElement$;
1009
+ const cmpMeta = hostRef.$cmpMeta$;
899
1010
  const oldVNode = hostRef.$vnode$ || newVNode(null, null);
1011
+ // if `renderFnResults` is a Host node then we can use it directly. If not,
1012
+ // we need to call `h` again to wrap the children of our component in a
1013
+ // 'dummy' Host node (well, an empty vnode) since `renderVdom` assumes
1014
+ // implicitly that the top-level vdom node is 1) an only child and 2)
1015
+ // contains attrs that need to be set on the host element.
900
1016
  const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
901
1017
  hostTagName = hostElm.tagName;
1018
+ // On the first render and *only* on the first render we want to check for
1019
+ // any attributes set on the host element which are also set on the vdom
1020
+ // node. If we find them, we override the value on the VDom node attrs with
1021
+ // the value from the host element, which allows developers building apps
1022
+ // with Stencil components to override e.g. the `role` attribute on a
1023
+ // component even if it's already set on the `Host`.
1024
+ if (isInitialLoad && rootVnode.$attrs$) {
1025
+ for (const key of Object.keys(rootVnode.$attrs$)) {
1026
+ // We have a special implementation in `setAccessor` for `style` and
1027
+ // `class` which reconciles values coming from the VDom with values
1028
+ // already present on the DOM element, so we don't want to override those
1029
+ // attributes on the VDom tree with values from the host element if they
1030
+ // are present.
1031
+ //
1032
+ // Likewise, `ref` and `key` are special internal values for the Stencil
1033
+ // runtime and we don't want to override those either.
1034
+ if (hostElm.hasAttribute(key) && !['key', 'ref', 'style', 'class'].includes(key)) {
1035
+ rootVnode.$attrs$[key] = hostElm[key];
1036
+ }
1037
+ }
1038
+ }
902
1039
  rootVnode.$tag$ = null;
903
1040
  rootVnode.$flags$ |= 4 /* VNODE_FLAGS.isHost */;
904
1041
  hostRef.$vnode$ = rootVnode;
@@ -906,8 +1043,9 @@ const renderVdom = (hostRef, renderFnResults) => {
906
1043
  {
907
1044
  scopeId = hostElm['s-sc'];
908
1045
  }
1046
+ useNativeShadowDom = (cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */) !== 0;
909
1047
  // synchronous patch
910
- patch(oldVNode, rootVnode);
1048
+ patch(oldVNode, rootVnode, isInitialLoad);
911
1049
  };
912
1050
  const attachToAncestor = (hostRef, ancestorComponent) => {
913
1051
  if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
@@ -1004,6 +1142,16 @@ const enqueue = (maybePromise, fn) => isPromisey(maybePromise) ? maybePromise.th
1004
1142
  */
1005
1143
  const isPromisey = (maybePromise) => maybePromise instanceof Promise ||
1006
1144
  (maybePromise && maybePromise.then && typeof maybePromise.then === 'function');
1145
+ /**
1146
+ * Update a component given reference to its host elements and so on.
1147
+ *
1148
+ * @param hostRef an object containing references to the element's host node,
1149
+ * VDom nodes, and other metadata
1150
+ * @param instance a reference to the underlying host element where it will be
1151
+ * rendered
1152
+ * @param isInitialLoad whether or not this function is being called as part of
1153
+ * the first render cycle
1154
+ */
1007
1155
  const updateComponent = async (hostRef, instance, isInitialLoad) => {
1008
1156
  var _a;
1009
1157
  const elm = hostRef.$hostElement$;
@@ -1015,7 +1163,7 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
1015
1163
  }
1016
1164
  const endRender = createTime('render', hostRef.$cmpMeta$.$tagName$);
1017
1165
  {
1018
- callRender(hostRef, instance);
1166
+ callRender(hostRef, instance, elm, isInitialLoad);
1019
1167
  }
1020
1168
  if (rc) {
1021
1169
  // ok, so turns out there are some child host elements
@@ -1039,8 +1187,24 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
1039
1187
  }
1040
1188
  }
1041
1189
  };
1042
- const callRender = (hostRef, instance, elm) => {
1190
+ /**
1191
+ * Handle making the call to the VDom renderer with the proper context given
1192
+ * various build variables
1193
+ *
1194
+ * @param hostRef an object containing references to the element's host node,
1195
+ * VDom nodes, and other metadata
1196
+ * @param instance a reference to the underlying host element where it will be
1197
+ * rendered
1198
+ * @param elm the Host element for the component
1199
+ * @param isInitialLoad whether or not this function is being called as part of
1200
+ * @returns an empty promise
1201
+ */
1202
+ const callRender = (hostRef, instance, elm, isInitialLoad) => {
1043
1203
  try {
1204
+ /**
1205
+ * minification optimization: `allRenderFn` is `true` if all components have a `render`
1206
+ * method, so we can call the method immediately. If not, check before calling it.
1207
+ */
1044
1208
  instance = instance.render() ;
1045
1209
  {
1046
1210
  hostRef.$flags$ &= ~16 /* HOST_FLAGS.isQueuedForUpdate */;
@@ -1054,7 +1218,7 @@ const callRender = (hostRef, instance, elm) => {
1054
1218
  // or we need to update the css class/attrs on the host element
1055
1219
  // DOM WRITE!
1056
1220
  {
1057
- renderVdom(hostRef, instance);
1221
+ renderVdom(hostRef, instance, isInitialLoad);
1058
1222
  }
1059
1223
  }
1060
1224
  }
@@ -1110,6 +1274,16 @@ const appDidLoad = (who) => {
1110
1274
  }
1111
1275
  nextTick(() => emitEvent(win, 'appload', { detail: { namespace: NAMESPACE } }));
1112
1276
  };
1277
+ /**
1278
+ * Allows to safely call a method, e.g. `componentDidLoad`, on an instance,
1279
+ * e.g. custom element node. If a build figures out that e.g. no component
1280
+ * has a `componentDidLoad` method, the instance method gets removed from the
1281
+ * output bundle and this function returns `undefined`.
1282
+ * @param instance any object that may or may not contain methods
1283
+ * @param method method name
1284
+ * @param arg single arbitrary argument
1285
+ * @returns result of method call if it exists, otherwise `undefined`
1286
+ */
1113
1287
  const safeCall = (instance, method, arg) => {
1114
1288
  if (instance && instance[method]) {
1115
1289
  try {
@@ -1160,10 +1334,11 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
1160
1334
  * @returns a reference to the same constructor passed in (but now mutated)
1161
1335
  */
1162
1336
  const proxyComponent = (Cstr, cmpMeta, flags) => {
1337
+ var _a;
1338
+ const prototype = Cstr.prototype;
1163
1339
  if (cmpMeta.$members$) {
1164
1340
  // It's better to have a const than two Object.entries()
1165
1341
  const members = Object.entries(cmpMeta.$members$);
1166
- const prototype = Cstr.prototype;
1167
1342
  members.map(([memberName, [memberFlags]]) => {
1168
1343
  if ((memberFlags & 31 /* MEMBER_FLAGS.Prop */ ||
1169
1344
  ((flags & 2 /* PROXY_FLAGS.proxyState */) && memberFlags & 32 /* MEMBER_FLAGS.State */))) {
@@ -1184,8 +1359,9 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1184
1359
  });
1185
1360
  if ((flags & 1 /* PROXY_FLAGS.isElementConstructor */)) {
1186
1361
  const attrNameToPropName = new Map();
1187
- prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
1362
+ prototype.attributeChangedCallback = function (attrName, oldValue, newValue) {
1188
1363
  plt.jmp(() => {
1364
+ var _a;
1189
1365
  const propName = attrNameToPropName.get(attrName);
1190
1366
  // In a web component lifecycle the attributeChangedCallback runs prior to connectedCallback
1191
1367
  // in the case where an attribute was set inline.
@@ -1207,12 +1383,12 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1207
1383
  // customElements.define('my-component', MyComponent);
1208
1384
  // </script>
1209
1385
  // ```
1210
- // In this case if we do not unshadow here and use the value of the shadowing property, attributeChangedCallback
1386
+ // In this case if we do not un-shadow here and use the value of the shadowing property, attributeChangedCallback
1211
1387
  // will be called with `newValue = "some-value"` and will set the shadowed property (this.someAttribute = "another-value")
1212
1388
  // to the value that was set inline i.e. "some-value" from above example. When
1213
- // the connectedCallback attempts to unshadow it will use "some-value" as the initial value rather than "another-value"
1389
+ // the connectedCallback attempts to un-shadow it will use "some-value" as the initial value rather than "another-value"
1214
1390
  //
1215
- // The case where the attribute was NOT set inline but was not set programmatically shall be handled/unshadowed
1391
+ // The case where the attribute was NOT set inline but was not set programmatically shall be handled/un-shadowed
1216
1392
  // by connectedCallback as this attributeChangedCallback will not fire.
1217
1393
  //
1218
1394
  // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
@@ -1232,23 +1408,63 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1232
1408
  // `propName` to be converted to a `DOMString`, which may not be what we want for other primitive props.
1233
1409
  return;
1234
1410
  }
1411
+ else if (propName == null) {
1412
+ // At this point we should know this is not a "member", so we can treat it like watching an attribute
1413
+ // on a vanilla web component
1414
+ const hostRef = getHostRef(this);
1415
+ const flags = hostRef === null || hostRef === void 0 ? void 0 : hostRef.$flags$;
1416
+ // We only want to trigger the callback(s) if:
1417
+ // 1. The instance is ready
1418
+ // 2. The watchers are ready
1419
+ // 3. The value has changed
1420
+ if (flags &&
1421
+ !(flags & 8 /* HOST_FLAGS.isConstructingInstance */) &&
1422
+ flags & 128 /* HOST_FLAGS.isWatchReady */ &&
1423
+ newValue !== oldValue) {
1424
+ const instance = hostRef.$lazyInstance$ ;
1425
+ const entry = (_a = cmpMeta.$watchers$) === null || _a === void 0 ? void 0 : _a[attrName];
1426
+ entry === null || entry === void 0 ? void 0 : entry.forEach((callbackName) => {
1427
+ if (instance[callbackName] != null) {
1428
+ instance[callbackName].call(instance, newValue, oldValue, attrName);
1429
+ }
1430
+ });
1431
+ }
1432
+ return;
1433
+ }
1235
1434
  this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
1236
1435
  });
1237
1436
  };
1238
- // create an array of attributes to observe
1239
- // and also create a map of html attribute name to js property name
1240
- Cstr.observedAttributes = members
1241
- .filter(([_, m]) => m[0] & 15 /* MEMBER_FLAGS.HasAttribute */) // filter to only keep props that should match attributes
1242
- .map(([propName, m]) => {
1243
- const attrName = m[1] || propName;
1244
- attrNameToPropName.set(attrName, propName);
1245
- return attrName;
1246
- });
1437
+ // Create an array of attributes to observe
1438
+ // This list in comprised of all strings used within a `@Watch()` decorator
1439
+ // on a component as well as any Stencil-specific "members" (`@Prop()`s and `@State()`s).
1440
+ // As such, there is no way to guarantee type-safety here that a user hasn't entered
1441
+ // an invalid attribute.
1442
+ Cstr.observedAttributes = Array.from(new Set([
1443
+ ...Object.keys((_a = cmpMeta.$watchers$) !== null && _a !== void 0 ? _a : {}),
1444
+ ...members
1445
+ .filter(([_, m]) => m[0] & 15 /* MEMBER_FLAGS.HasAttribute */)
1446
+ .map(([propName, m]) => {
1447
+ const attrName = m[1] || propName;
1448
+ attrNameToPropName.set(attrName, propName);
1449
+ return attrName;
1450
+ }),
1451
+ ]));
1247
1452
  }
1248
1453
  }
1249
1454
  return Cstr;
1250
1455
  };
1251
- const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
1456
+ /**
1457
+ * Initialize a Stencil component given a reference to its host element, its
1458
+ * runtime bookkeeping data structure, runtime metadata about the component,
1459
+ * and (optionally) an HMR version ID.
1460
+ *
1461
+ * @param elm a host element
1462
+ * @param hostRef the element's runtime bookkeeping object
1463
+ * @param cmpMeta runtime metadata for the Stencil component
1464
+ * @param hmrVersionId an (optional) HMR version ID
1465
+ */
1466
+ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
1467
+ let Cstr;
1252
1468
  // initializeComponent
1253
1469
  if ((hostRef.$flags$ & 32 /* HOST_FLAGS.hasInitializedComponent */) === 0) {
1254
1470
  // Let the runtime know that the component has been initialized
@@ -1367,23 +1583,35 @@ const connectedCallback = (elm) => {
1367
1583
  // since they would have been removed when disconnected
1368
1584
  addHostEventListeners(elm, hostRef, cmpMeta.$listeners$);
1369
1585
  // fire off connectedCallback() on component instance
1370
- fireConnectedCallback(hostRef.$lazyInstance$);
1586
+ if (hostRef === null || hostRef === void 0 ? void 0 : hostRef.$lazyInstance$) {
1587
+ fireConnectedCallback(hostRef.$lazyInstance$);
1588
+ }
1589
+ else if (hostRef === null || hostRef === void 0 ? void 0 : hostRef.$onReadyPromise$) {
1590
+ hostRef.$onReadyPromise$.then(() => fireConnectedCallback(hostRef.$lazyInstance$));
1591
+ }
1371
1592
  }
1372
1593
  endConnected();
1373
1594
  }
1374
1595
  };
1375
- const disconnectedCallback = (elm) => {
1596
+ const disconnectInstance = (instance) => {
1597
+ {
1598
+ safeCall(instance, 'disconnectedCallback');
1599
+ }
1600
+ };
1601
+ const disconnectedCallback = async (elm) => {
1376
1602
  if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
1377
1603
  const hostRef = getHostRef(elm);
1378
- const instance = hostRef.$lazyInstance$ ;
1379
1604
  {
1380
1605
  if (hostRef.$rmListeners$) {
1381
1606
  hostRef.$rmListeners$.map((rmListener) => rmListener());
1382
1607
  hostRef.$rmListeners$ = undefined;
1383
1608
  }
1384
1609
  }
1385
- {
1386
- safeCall(instance, 'disconnectedCallback');
1610
+ if (hostRef === null || hostRef === void 0 ? void 0 : hostRef.$lazyInstance$) {
1611
+ disconnectInstance(hostRef.$lazyInstance$);
1612
+ }
1613
+ else if (hostRef === null || hostRef === void 0 ? void 0 : hostRef.$onReadyPromise$) {
1614
+ hostRef.$onReadyPromise$.then(() => disconnectInstance(hostRef.$lazyInstance$));
1387
1615
  }
1388
1616
  }
1389
1617
  };
@@ -1395,12 +1623,13 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1395
1623
  const customElements = win.customElements;
1396
1624
  const head = doc.head;
1397
1625
  const metaCharset = /*@__PURE__*/ head.querySelector('meta[charset]');
1398
- const visibilityStyle = /*@__PURE__*/ doc.createElement('style');
1626
+ const dataStyles = /*@__PURE__*/ doc.createElement('style');
1399
1627
  const deferredConnectedCallbacks = [];
1400
1628
  let appLoadFallback;
1401
1629
  let isBootstrapping = true;
1402
1630
  Object.assign(plt, options);
1403
1631
  plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
1632
+ let hasSlotRelocation = false;
1404
1633
  lazyBundles.map((lazyBundle) => {
1405
1634
  lazyBundle[1].map((compactMeta) => {
1406
1635
  const cmpMeta = {
@@ -1409,6 +1638,11 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1409
1638
  $members$: compactMeta[2],
1410
1639
  $listeners$: compactMeta[3],
1411
1640
  };
1641
+ // Check if we are using slots outside the shadow DOM in this component.
1642
+ // We'll use this information later to add styles for `slot-fb` elements
1643
+ if (cmpMeta.$flags$ & 4 /* CMP_FLAGS.hasSlotRelocation */) {
1644
+ hasSlotRelocation = true;
1645
+ }
1412
1646
  {
1413
1647
  cmpMeta.$members$ = compactMeta[2];
1414
1648
  }
@@ -1462,15 +1696,29 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1462
1696
  }
1463
1697
  });
1464
1698
  });
1465
- {
1466
- visibilityStyle.innerHTML = cmpTags + HYDRATED_CSS;
1467
- visibilityStyle.setAttribute('data-styles', '');
1468
- // Apply CSP nonce to the style tag if it exists
1469
- const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
1470
- if (nonce != null) {
1471
- visibilityStyle.setAttribute('nonce', nonce);
1699
+ // Only bother generating CSS if we have components
1700
+ // TODO(STENCIL-1118): Add test cases for CSS content based on conditionals
1701
+ if (cmpTags.length > 0) {
1702
+ // Add styles for `slot-fb` elements if any of our components are using slots outside the Shadow DOM
1703
+ if (hasSlotRelocation) {
1704
+ dataStyles.innerHTML += SLOT_FB_CSS;
1705
+ }
1706
+ // Add hydration styles
1707
+ {
1708
+ dataStyles.innerHTML += cmpTags + HYDRATED_CSS;
1709
+ }
1710
+ // If we have styles, add them to the DOM
1711
+ if (dataStyles.innerHTML.length) {
1712
+ dataStyles.setAttribute('data-styles', '');
1713
+ // Apply CSP nonce to the style tag if it exists
1714
+ const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
1715
+ if (nonce != null) {
1716
+ dataStyles.setAttribute('nonce', nonce);
1717
+ }
1718
+ // Insert the styles into the document head
1719
+ // NOTE: this _needs_ to happen last so we can ensure the nonce (and other attributes) are applied
1720
+ head.insertBefore(dataStyles, metaCharset ? metaCharset.nextSibling : head.firstChild);
1472
1721
  }
1473
- head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
1474
1722
  }
1475
1723
  // Process deferred connectedCallbacks now all components have been registered
1476
1724
  isBootstrapping = false;
@@ -1518,7 +1766,12 @@ const getHostListenerTarget = (elm, flags) => {
1518
1766
  return elm;
1519
1767
  };
1520
1768
  // prettier-ignore
1521
- const hostListenerOpts = (flags) => (flags & 2 /* LISTENER_FLAGS.Capture */) !== 0;
1769
+ const hostListenerOpts = (flags) => supportsListenerOptions
1770
+ ? ({
1771
+ passive: (flags & 1 /* LISTENER_FLAGS.Passive */) !== 0,
1772
+ capture: (flags & 2 /* LISTENER_FLAGS.Capture */) !== 0,
1773
+ })
1774
+ : (flags & 2 /* LISTENER_FLAGS.Capture */) !== 0;
1522
1775
  /**
1523
1776
  * Assigns the given value to the nonce property on the runtime platform object.
1524
1777
  * During runtime, this value is used to set the nonce attribute on all dynamically created script and style tags.
@@ -1526,23 +1779,61 @@ const hostListenerOpts = (flags) => (flags & 2 /* LISTENER_FLAGS.Capture */) !==
1526
1779
  * @returns void
1527
1780
  */
1528
1781
  const setNonce = (nonce) => (plt.$nonce$ = nonce);
1529
- const hostRefs = /*@__PURE__*/ new WeakMap();
1782
+ /**
1783
+ * A WeakMap mapping runtime component references to their corresponding host reference
1784
+ * instances.
1785
+ *
1786
+ * **Note**: If we're in an HMR context we need to store a reference to this
1787
+ * value on `window` in order to maintain the mapping of {@link d.RuntimeRef}
1788
+ * to {@link d.HostRef} across HMR updates.
1789
+ *
1790
+ * This is necessary because when HMR updates for a component are processed by
1791
+ * the browser-side dev server client the JS bundle for that component is
1792
+ * re-fetched. Since the module containing {@link hostRefs} is included in
1793
+ * that bundle, if we do not store a reference to it the new iteration of the
1794
+ * component will not have access to the previous hostRef map, leading to a
1795
+ * bug where the new version of the component cannot properly initialize.
1796
+ */
1797
+ const hostRefs = new WeakMap();
1798
+ /**
1799
+ * Given a {@link d.RuntimeRef} retrieve the corresponding {@link d.HostRef}
1800
+ *
1801
+ * @param ref the runtime ref of interest
1802
+ * @returns the Host reference (if found) or undefined
1803
+ */
1530
1804
  const getHostRef = (ref) => hostRefs.get(ref);
1805
+ /**
1806
+ * Register a lazy instance with the {@link hostRefs} object so it's
1807
+ * corresponding {@link d.HostRef} can be retrieved later.
1808
+ *
1809
+ * @param lazyInstance the lazy instance of interest
1810
+ * @param hostRef that instances `HostRef` object
1811
+ * @returns a reference to the host ref WeakMap
1812
+ */
1531
1813
  const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
1532
- const registerHost = (elm, cmpMeta) => {
1814
+ /**
1815
+ * Register a host element for a Stencil component, setting up various metadata
1816
+ * and callbacks based on {@link BUILD} flags as well as the component's runtime
1817
+ * metadata.
1818
+ *
1819
+ * @param hostElement the host element to register
1820
+ * @param cmpMeta runtime metadata for that component
1821
+ * @returns a reference to the host ref WeakMap
1822
+ */
1823
+ const registerHost = (hostElement, cmpMeta) => {
1533
1824
  const hostRef = {
1534
1825
  $flags$: 0,
1535
- $hostElement$: elm,
1826
+ $hostElement$: hostElement,
1536
1827
  $cmpMeta$: cmpMeta,
1537
1828
  $instanceValues$: new Map(),
1538
1829
  };
1539
1830
  {
1540
1831
  hostRef.$onReadyPromise$ = new Promise((r) => (hostRef.$onReadyResolve$ = r));
1541
- elm['s-p'] = [];
1542
- elm['s-rc'] = [];
1832
+ hostElement['s-p'] = [];
1833
+ hostElement['s-rc'] = [];
1543
1834
  }
1544
- addHostEventListeners(elm, hostRef, cmpMeta.$listeners$);
1545
- return hostRefs.set(elm, hostRef);
1835
+ addHostEventListeners(hostElement, hostRef, cmpMeta.$listeners$);
1836
+ return hostRefs.set(hostElement, hostRef);
1546
1837
  };
1547
1838
  const isMemberInElement = (elm, memberName) => memberName in elm;
1548
1839
  const consoleError = (e, el) => (0, console.error)(e, el);
@@ -1580,6 +1871,18 @@ const plt = {
1580
1871
  rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
1581
1872
  ce: (eventName, opts) => new CustomEvent(eventName, opts),
1582
1873
  };
1874
+ const supportsListenerOptions = /*@__PURE__*/ (() => {
1875
+ let supportsListenerOptions = false;
1876
+ try {
1877
+ doc.addEventListener('e', null, Object.defineProperty({}, 'passive', {
1878
+ get() {
1879
+ supportsListenerOptions = true;
1880
+ },
1881
+ }));
1882
+ }
1883
+ catch (e) { }
1884
+ return supportsListenerOptions;
1885
+ })();
1583
1886
  const promiseResolve = (v) => Promise.resolve(v);
1584
1887
  const supportsConstructableStylesheets = /*@__PURE__*/ (() => {
1585
1888
  try {
@@ -1630,7 +1933,7 @@ const flush = () => {
1630
1933
  }
1631
1934
  }
1632
1935
  };
1633
- const nextTick = /*@__PURE__*/ (cb) => promiseResolve().then(cb);
1936
+ const nextTick = (cb) => promiseResolve().then(cb);
1634
1937
  const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
1635
1938
 
1636
1939
  exports.Build = Build;
@@ -1642,4 +1945,4 @@ exports.promiseResolve = promiseResolve;
1642
1945
  exports.registerInstance = registerInstance;
1643
1946
  exports.setNonce = setNonce;
1644
1947
 
1645
- //# sourceMappingURL=index-1e526aba.js.map
1948
+ //# sourceMappingURL=index-ef57218a.js.map