vviinn-widgets 2.18.21 → 2.19.1

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 (183) hide show
  1. package/dist/cjs/{index-cb410762.js → Campaign-a94a827a.js} +17 -1
  2. package/dist/cjs/cropper-handler_29.cjs.entry.js +1418 -0
  3. package/dist/cjs/{imageSearch.store-98824653.js → index-48c94264.js} +16016 -11171
  4. package/dist/cjs/{index-7f1325a7.js → index-a4becaff.js} +683 -303
  5. package/dist/cjs/loader.cjs.js +4 -3
  6. package/dist/cjs/{vviinn-carousel_3.cjs.entry.js → vviinn-carousel_2.cjs.entry.js} +150 -270
  7. package/dist/cjs/vviinn-recommendations-sidebar.cjs.entry.js +14 -8
  8. package/dist/cjs/vviinn-vpr-button.cjs.entry.js +12 -14
  9. package/dist/cjs/vviinn-widgets.cjs.js +10 -3
  10. package/dist/collection/Image/sizing.spec.js +66 -0
  11. package/dist/collection/collection-manifest.json +2 -2
  12. package/dist/collection/components/image-search/image-view/highlight-box/highlight-box.css +2 -16
  13. package/dist/collection/components/image-search/image-view/highlight-box/highlight-box.js +11 -7
  14. package/dist/collection/components/image-search/image-view/image-cropper/cropper-handler/cropper-handler.css +0 -1
  15. package/dist/collection/components/image-search/image-view/image-cropper/cropper-handler/cropper-handler.js +40 -37
  16. package/dist/collection/components/image-search/image-view/image-cropper/image-cropper.js +73 -67
  17. package/dist/collection/components/image-search/search-filters/search-filters.css +4 -23
  18. package/dist/collection/components/image-search/search-filters/search-filters.js +97 -91
  19. package/dist/collection/components/vviinn-button/vviinn-button.js +34 -31
  20. package/dist/collection/components/vviinn-carousel/vviinn-carousel.css +1 -2
  21. package/dist/collection/components/vviinn-carousel/vviinn-carousel.js +161 -156
  22. package/dist/collection/components/vviinn-error/vviinn-empty-results/vviinn-empty-results.js +12 -14
  23. package/dist/collection/components/vviinn-error/vviinn-error.js +12 -12
  24. package/dist/collection/components/vviinn-error/vviinn-server-error/vviinn-server-error.js +35 -30
  25. package/dist/collection/components/vviinn-error/vviinn-wrong-format/vviinn-wrong-format.js +35 -30
  26. package/dist/collection/components/vviinn-example-images/vviinn-example-image/vviinn-example-image.js +129 -121
  27. package/dist/collection/components/vviinn-example-images/vviinn-example-images.js +75 -75
  28. package/dist/collection/components/vviinn-icons/index.js +10 -27
  29. package/dist/collection/components/vviinn-image-selector/vviinn-image-selector.js +120 -67
  30. package/dist/collection/components/vviinn-image-view/vviinn-detected-object/vviinn-detected-object.js +81 -69
  31. package/dist/collection/components/vviinn-image-view/vviinn-image-view.css +0 -1
  32. package/dist/collection/components/vviinn-image-view/vviinn-image-view.js +27 -28
  33. package/dist/collection/components/vviinn-modal/vviinn-modal.css +7 -36
  34. package/dist/collection/components/vviinn-modal/vviinn-modal.js +115 -93
  35. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-1/vviinn-onboarding-card-1.js +12 -14
  36. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-2/vviinn-onboarding-card-2.js +12 -14
  37. package/dist/collection/components/vviinn-onboarding/onboarding-cards/vviinn-onboarding-card-3/vviinn-onboarding-card-3.js +12 -14
  38. package/dist/collection/components/vviinn-onboarding/vviinn-onboarding.js +12 -17
  39. package/dist/collection/components/vviinn-overlay/vviinn-overlay.css +1 -12
  40. package/dist/collection/components/vviinn-overlay/vviinn-overlay.js +12 -9
  41. package/dist/collection/components/vviinn-overlayed-modal/vviinn-overlayed-modal.js +107 -78
  42. package/dist/collection/components/vviinn-preloader/vviinn-preloader.css +1 -11
  43. package/dist/collection/components/vviinn-preloader/vviinn-preloader.js +11 -7
  44. package/dist/collection/components/vviinn-privacy-badge/vviinn-privacy-badge.css +0 -1
  45. package/dist/collection/components/vviinn-privacy-badge/vviinn-privacy-badge.js +12 -16
  46. package/dist/collection/components/vviinn-product-card/render-helpers.js +6 -14
  47. package/dist/collection/components/vviinn-product-card/vviinn-product-card.js +425 -415
  48. package/dist/collection/components/vviinn-slider/arrow.js +1 -2
  49. package/dist/collection/components/vviinn-slider/vviinn-slide/vviinn-slide.js +12 -9
  50. package/dist/collection/components/vviinn-slider/vviinn-slider.css +0 -1
  51. package/dist/collection/components/vviinn-slider/vviinn-slider.js +87 -82
  52. package/dist/collection/components/vviinn-teaser/vviinn-teaser.js +12 -18
  53. package/dist/collection/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.css +12 -64
  54. package/dist/collection/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.js +371 -360
  55. package/dist/collection/components/vviinn-vpr-button/vviinn-vpr-button.js +448 -444
  56. package/dist/collection/components/vviinn-vpr-widget/vviinn-vpr-vidget.js +545 -542
  57. package/dist/collection/components/vviinn-vps-button/stories/vviinn-vps-button.stories.js +2 -0
  58. package/dist/collection/components/vviinn-vps-button/vviinn-vps-button.js +368 -332
  59. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.css +0 -5
  60. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.e2e.js +26 -0
  61. package/dist/collection/components/vviinn-vps-widget/vviinn-vps-widget.js +502 -425
  62. package/dist/collection/geometry/Clip.spec.js +16 -0
  63. package/dist/collection/geometry/Rectangle.spec.js +66 -0
  64. package/dist/collection/geometry/Sized.spec.js +16 -0
  65. package/dist/collection/interfaces/generated.js +0 -4
  66. package/dist/collection/network/ion/Form.spec.js +43 -0
  67. package/dist/esm/{index-b31d86ce.js → Campaign-4aa53f29.js} +15 -2
  68. package/dist/esm/cropper-handler_29.entry.js +1386 -0
  69. package/dist/esm/{index-590cb67e.js → index-48ef9564.js} +683 -304
  70. package/dist/esm/{imageSearch.store-9dde5360.js → index-976acf7e.js} +16124 -11292
  71. package/dist/esm/loader.js +4 -3
  72. package/dist/esm/polyfills/css-shim.js +1 -1
  73. package/dist/esm/{vviinn-carousel_3.entry.js → vviinn-carousel_2.entry.js} +106 -225
  74. package/dist/esm/vviinn-recommendations-sidebar.entry.js +13 -7
  75. package/dist/esm/vviinn-vpr-button.entry.js +11 -13
  76. package/dist/esm/vviinn-widgets.js +7 -3
  77. package/dist/loader/index.d.ts +9 -0
  78. package/dist/loader/package.json +1 -0
  79. package/dist/types/Image/sizing.d.ts +4 -4
  80. package/dist/types/campaign/Campaign.d.ts +5 -5
  81. package/dist/types/campaign/VCSCampaignResponse.d.ts +1 -1
  82. package/dist/types/components/vviinn-carousel/vviinn-carousel.d.ts +2 -2
  83. package/dist/types/components/vviinn-image-selector/vviinn-image-selector.d.ts +4 -0
  84. package/dist/types/components/vviinn-modal/vviinn-modal.d.ts +2 -0
  85. package/dist/types/components/vviinn-overlayed-modal/vviinn-overlayed-modal.d.ts +2 -0
  86. package/dist/types/components/vviinn-product-card/render-helpers.d.ts +3 -3
  87. package/dist/types/components/vviinn-slider/arrow.d.ts +2 -2
  88. package/dist/types/components/vviinn-vpr-button/recommendations-sidebar/recommendations-sidebar.d.ts +2 -2
  89. package/dist/types/components/vviinn-vps-button/vviinn-vps-button.d.ts +9 -4
  90. package/dist/types/components/vviinn-vps-widget/vviinn-vps-widget.d.ts +8 -0
  91. package/dist/types/components.d.ts +154 -54
  92. package/dist/types/error.d.ts +1 -1
  93. package/dist/types/geometry/Point.d.ts +1 -1
  94. package/dist/types/geometry/Rectangle.d.ts +1 -1
  95. package/dist/types/geometry/Sized.d.ts +1 -1
  96. package/dist/types/interfaces/generated.d.ts +192 -371
  97. package/dist/types/network/ion/File.d.ts +2 -2
  98. package/dist/types/network/ion/Form.d.ts +5 -5
  99. package/dist/types/network/ion/Link.d.ts +1 -1
  100. package/dist/types/network/ion/ValueObject.d.ts +4 -4
  101. package/dist/types/network/utils.d.ts +3 -3
  102. package/dist/types/recommendation/events.d.ts +5 -5
  103. package/dist/types/recommendation/recommendation.d.ts +1 -1
  104. package/dist/types/searchSession/searchSession.d.ts +7 -7
  105. package/dist/types/slider/GridMode.d.ts +1 -1
  106. package/dist/types/stencil-public-runtime.d.ts +98 -23
  107. package/dist/types/store/imageSearch.store.d.ts +1 -1
  108. package/dist/types/tracking/models.d.ts +2 -2
  109. package/dist/types/utils/event/Events.d.ts +1 -1
  110. package/dist/vviinn-widgets/p-312b0eb7.entry.js +1 -0
  111. package/dist/vviinn-widgets/p-414b2291.js +1 -0
  112. package/dist/vviinn-widgets/p-5b50c7e5.entry.js +1 -0
  113. package/dist/vviinn-widgets/p-8deaa5da.entry.js +1 -0
  114. package/dist/vviinn-widgets/p-c6209bc1.entry.js +1 -0
  115. package/{www/build/p-2f9ee951.js → dist/vviinn-widgets/p-d08ce429.js} +1 -1
  116. package/dist/vviinn-widgets/p-fa17e81f.js +2 -0
  117. package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
  118. package/package.json +12 -12
  119. package/www/build/p-312b0eb7.entry.js +1 -0
  120. package/www/build/p-414b2291.js +1 -0
  121. package/www/build/p-5b50c7e5.entry.js +1 -0
  122. package/www/build/p-8deaa5da.entry.js +1 -0
  123. package/www/build/p-c6209bc1.entry.js +1 -0
  124. package/{dist/vviinn-widgets/p-2f9ee951.js → www/build/p-d08ce429.js} +1 -1
  125. package/www/build/p-d39b7d70.js +161 -0
  126. package/www/build/p-fa17e81f.js +2 -0
  127. package/www/build/vviinn-widgets.esm.js +1 -1
  128. package/www/index.html +2 -2
  129. package/dist/cjs/Campaign-13258569.js +0 -18
  130. package/dist/cjs/Handler-176539c8.js +0 -331
  131. package/dist/cjs/cropper-handler.cjs.entry.js +0 -27
  132. package/dist/cjs/customized-slots-6e56c354.js +0 -54
  133. package/dist/cjs/highlight-box_22.cjs.entry.js +0 -770
  134. package/dist/cjs/index-a99edb90.js +0 -3235
  135. package/dist/cjs/vviinn-button.cjs.entry.js +0 -21
  136. package/dist/cjs/vviinn-error.cjs.entry.js +0 -19
  137. package/dist/cjs/vviinn-preloader.cjs.entry.js +0 -26
  138. package/dist/cjs/vviinn-vps-button.cjs.entry.js +0 -65
  139. package/dist/cjs/vviinn-vps-widget.cjs.entry.js +0 -251
  140. package/dist/esm/Campaign-90ba7e06.js +0 -14
  141. package/dist/esm/Handler-f9b8735c.js +0 -309
  142. package/dist/esm/cropper-handler.entry.js +0 -23
  143. package/dist/esm/customized-slots-00afe247.js +0 -51
  144. package/dist/esm/highlight-box_22.entry.js +0 -745
  145. package/dist/esm/index-4d5b52ba.js +0 -3224
  146. package/dist/esm/vviinn-button.entry.js +0 -17
  147. package/dist/esm/vviinn-error.entry.js +0 -15
  148. package/dist/esm/vviinn-preloader.entry.js +0 -22
  149. package/dist/esm/vviinn-vps-button.entry.js +0 -61
  150. package/dist/esm/vviinn-vps-widget.entry.js +0 -247
  151. package/dist/vviinn-widgets/p-11f61564.js +0 -1
  152. package/dist/vviinn-widgets/p-12851e97.entry.js +0 -1
  153. package/dist/vviinn-widgets/p-18fd769b.js +0 -1
  154. package/dist/vviinn-widgets/p-339c6838.js +0 -1
  155. package/dist/vviinn-widgets/p-3b2c91c0.entry.js +0 -1
  156. package/dist/vviinn-widgets/p-45df9f28.entry.js +0 -1
  157. package/dist/vviinn-widgets/p-57ed5303.entry.js +0 -1
  158. package/dist/vviinn-widgets/p-69850e5b.js +0 -1
  159. package/dist/vviinn-widgets/p-7c2f762a.entry.js +0 -1
  160. package/dist/vviinn-widgets/p-7c3b7388.entry.js +0 -1
  161. package/dist/vviinn-widgets/p-85006f41.entry.js +0 -1
  162. package/dist/vviinn-widgets/p-8a3dd76d.entry.js +0 -1
  163. package/dist/vviinn-widgets/p-99e58be7.entry.js +0 -1
  164. package/dist/vviinn-widgets/p-a2b450b6.entry.js +0 -1
  165. package/dist/vviinn-widgets/p-bcc1ccf0.js +0 -1
  166. package/dist/vviinn-widgets/p-e6fee8d2.js +0 -1
  167. package/www/build/p-11f61564.js +0 -1
  168. package/www/build/p-12851e97.entry.js +0 -1
  169. package/www/build/p-18fd769b.js +0 -1
  170. package/www/build/p-339c6838.js +0 -1
  171. package/www/build/p-3b2c91c0.entry.js +0 -1
  172. package/www/build/p-45df9f28.entry.js +0 -1
  173. package/www/build/p-57ed5303.entry.js +0 -1
  174. package/www/build/p-69850e5b.js +0 -1
  175. package/www/build/p-7c2f762a.entry.js +0 -1
  176. package/www/build/p-7c3b7388.entry.js +0 -1
  177. package/www/build/p-85006f41.entry.js +0 -1
  178. package/www/build/p-8a3dd76d.entry.js +0 -1
  179. package/www/build/p-99e58be7.entry.js +0 -1
  180. package/www/build/p-9e2c131a.js +0 -125
  181. package/www/build/p-a2b450b6.entry.js +0 -1
  182. package/www/build/p-bcc1ccf0.js +0 -1
  183. package/www/build/p-e6fee8d2.js +0 -1
@@ -1,66 +1,18 @@
1
1
  const NAMESPACE = 'vviinn-widgets';
2
2
 
3
+ /**
4
+ * Virtual DOM patching algorithm based on Snabbdom by
5
+ * Simon Friis Vindum (@paldepind)
6
+ * Licensed under the MIT License
7
+ * https://github.com/snabbdom/snabbdom/blob/master/LICENSE
8
+ *
9
+ * Modified for Stencil's renderer and slot projection
10
+ */
3
11
  let scopeId;
4
12
  let hostTagName;
5
13
  let isSvgMode = false;
6
14
  let renderingRef = null;
7
15
  let queuePending = false;
8
- const win = typeof window !== 'undefined' ? window : {};
9
- const doc = win.document || { head: {} };
10
- const plt = {
11
- $flags$: 0,
12
- $resourcesUrl$: '',
13
- jmp: (h) => h(),
14
- raf: (h) => requestAnimationFrame(h),
15
- ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
16
- rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
17
- ce: (eventName, opts) => new CustomEvent(eventName, opts),
18
- };
19
- const promiseResolve = (v) => Promise.resolve(v);
20
- const supportsConstructibleStylesheets = /*@__PURE__*/ (() => {
21
- try {
22
- new CSSStyleSheet();
23
- return typeof new CSSStyleSheet().replace === 'function';
24
- }
25
- catch (e) { }
26
- return false;
27
- })()
28
- ;
29
- const addHostEventListeners = (elm, hostRef, listeners, attachParentListeners) => {
30
- if (listeners) {
31
- listeners.map(([flags, name, method]) => {
32
- const target = getHostListenerTarget(elm, flags) ;
33
- const handler = hostListenerProxy(hostRef, method);
34
- const opts = hostListenerOpts(flags);
35
- plt.ael(target, name, handler, opts);
36
- (hostRef.$rmListeners$ = hostRef.$rmListeners$ || []).push(() => plt.rel(target, name, handler, opts));
37
- });
38
- }
39
- };
40
- const hostListenerProxy = (hostRef, methodName) => (ev) => {
41
- try {
42
- {
43
- if (hostRef.$flags$ & 256 /* isListenReady */) {
44
- // instance is ready, let's call it's member method for this event
45
- hostRef.$lazyInstance$[methodName](ev);
46
- }
47
- else {
48
- (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
49
- }
50
- }
51
- }
52
- catch (e) {
53
- consoleError(e);
54
- }
55
- };
56
- const getHostListenerTarget = (elm, flags) => {
57
- if (flags & 16 /* TargetBody */)
58
- return doc.body;
59
- return elm;
60
- };
61
- // prettier-ignore
62
- const hostListenerOpts = (flags) => (flags & 2 /* Capture */) !== 0;
63
- const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
64
16
  const createTime = (fnName, tagName = '') => {
65
17
  {
66
18
  return () => {
@@ -75,71 +27,7 @@ const uniqueTime = (key, measureText) => {
75
27
  };
76
28
  }
77
29
  };
78
- const rootAppliedStyles = new WeakMap();
79
- const registerStyle = (scopeId, cssText, allowCS) => {
80
- let style = styles.get(scopeId);
81
- if (supportsConstructibleStylesheets && allowCS) {
82
- style = (style || new CSSStyleSheet());
83
- style.replace(cssText);
84
- }
85
- else {
86
- style = cssText;
87
- }
88
- styles.set(scopeId, style);
89
- };
90
- const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
91
- let scopeId = getScopeId(cmpMeta);
92
- let style = styles.get(scopeId);
93
- // if an element is NOT connected then getRootNode() will return the wrong root node
94
- // so the fallback is to always use the document for the root node in those cases
95
- styleContainerNode = styleContainerNode.nodeType === 11 /* DocumentFragment */ ? styleContainerNode : doc;
96
- if (style) {
97
- if (typeof style === 'string') {
98
- styleContainerNode = styleContainerNode.head || styleContainerNode;
99
- let appliedStyles = rootAppliedStyles.get(styleContainerNode);
100
- let styleElm;
101
- if (!appliedStyles) {
102
- rootAppliedStyles.set(styleContainerNode, (appliedStyles = new Set()));
103
- }
104
- if (!appliedStyles.has(scopeId)) {
105
- {
106
- {
107
- styleElm = doc.createElement('style');
108
- styleElm.innerHTML = style;
109
- }
110
- styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
111
- }
112
- if (appliedStyles) {
113
- appliedStyles.add(scopeId);
114
- }
115
- }
116
- }
117
- else if (!styleContainerNode.adoptedStyleSheets.includes(style)) {
118
- styleContainerNode.adoptedStyleSheets = [...styleContainerNode.adoptedStyleSheets, style];
119
- }
120
- }
121
- return scopeId;
122
- };
123
- const attachStyles = (hostRef) => {
124
- const cmpMeta = hostRef.$cmpMeta$;
125
- const elm = hostRef.$hostElement$;
126
- const flags = cmpMeta.$flags$;
127
- const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
128
- const scopeId = addStyle(elm.shadowRoot ? elm.shadowRoot : elm.getRootNode(), cmpMeta);
129
- if (flags & 10 /* needsScopedEncapsulation */) {
130
- // only required when we're NOT using native shadow dom (slot)
131
- // or this browser doesn't support native shadow dom
132
- // and this host element was NOT created with SSR
133
- // let's pick out the inner content for slot projection
134
- // create a node to represent where the original
135
- // content was first placed, which is useful later on
136
- // DOM WRITE!!
137
- elm['s-sc'] = scopeId;
138
- elm.classList.add(scopeId + '-h');
139
- }
140
- endAttachStyles();
141
- };
142
- const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
30
+ const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
143
31
  /**
144
32
  * Default style mode id
145
33
  */
@@ -154,11 +42,30 @@ const EMPTY_OBJ = {};
154
42
  const SVG_NS = 'http://www.w3.org/2000/svg';
155
43
  const HTML_NS = 'http://www.w3.org/1999/xhtml';
156
44
  const isDef = (v) => v != null;
45
+ /**
46
+ * Check whether a value is a 'complex type', defined here as an object or a
47
+ * function.
48
+ *
49
+ * @param o the value to check
50
+ * @returns whether it's a complex type or not
51
+ */
157
52
  const isComplexType = (o) => {
158
53
  // https://jsperf.com/typeof-fn-object/5
159
54
  o = typeof o;
160
55
  return o === 'object' || o === 'function';
161
56
  };
57
+ /**
58
+ * Helper method for querying a `meta` tag that contains a nonce value
59
+ * out of a DOM's head.
60
+ *
61
+ * @param doc The DOM containing the `head` to query against
62
+ * @returns The content of the meta tag representing the nonce value, or `undefined` if no tag
63
+ * exists or the tag has no content.
64
+ */
65
+ function queryNonceMetaTagContent(doc) {
66
+ var _a, _b, _c;
67
+ return (_c = (_b = (_a = doc.head) === null || _a === void 0 ? void 0 : _a.querySelector('meta[name="csp-nonce"]')) === null || _b === void 0 ? void 0 : _b.getAttribute('content')) !== null && _c !== void 0 ? _c : undefined;
68
+ }
162
69
  /**
163
70
  * Production h() function based on Preact by
164
71
  * Jason Miller (@developit)
@@ -167,7 +74,6 @@ const isComplexType = (o) => {
167
74
  *
168
75
  * Modified for Stencil's compiler and vdom
169
76
  */
170
- // const stack: any[] = [];
171
77
  // export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, child?: d.ChildType): d.VNode;
172
78
  // export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
173
79
  const h = (nodeName, vnodeData, ...children) => {
@@ -175,7 +81,7 @@ const h = (nodeName, vnodeData, ...children) => {
175
81
  let key = null;
176
82
  let simple = false;
177
83
  let lastSimple = false;
178
- let vNodeChildren = [];
84
+ const vNodeChildren = [];
179
85
  const walk = (c) => {
180
86
  for (let i = 0; i < c.length; i++) {
181
87
  child = c[i];
@@ -230,6 +136,14 @@ const h = (nodeName, vnodeData, ...children) => {
230
136
  }
231
137
  return vnode;
232
138
  };
139
+ /**
140
+ * A utility function for creating a virtual DOM node from a tag and some
141
+ * possible text content.
142
+ *
143
+ * @param tag the tag for this element
144
+ * @param text possible text content for the node
145
+ * @returns a newly-minted virtual DOM node
146
+ */
233
147
  const newVNode = (tag, text) => {
234
148
  const vnode = {
235
149
  $flags$: 0,
@@ -247,11 +161,31 @@ const newVNode = (tag, text) => {
247
161
  return vnode;
248
162
  };
249
163
  const Host = {};
164
+ /**
165
+ * Check whether a given node is a Host node or not
166
+ *
167
+ * @param node the virtual DOM node to check
168
+ * @returns whether it's a Host node or not
169
+ */
250
170
  const isHost = (node) => node && node.$tag$ === Host;
171
+ /**
172
+ * Implementation of {@link d.FunctionalUtilities} for Stencil's VDom.
173
+ *
174
+ * Note that these functions convert from {@link d.VNode} to
175
+ * {@link d.ChildNode} to give functional component developers a friendly
176
+ * interface.
177
+ */
251
178
  const vdomFnUtils = {
252
179
  forEach: (children, cb) => children.map(convertToPublic).forEach(cb),
253
180
  map: (children, cb) => children.map(convertToPublic).map(cb).map(convertToPrivate),
254
181
  };
182
+ /**
183
+ * Convert a {@link d.VNode} to a {@link d.ChildNode} in order to present a
184
+ * friendlier public interface (hence, 'convertToPublic').
185
+ *
186
+ * @param node the virtual DOM node to convert
187
+ * @returns a converted child node
188
+ */
255
189
  const convertToPublic = (node) => ({
256
190
  vattrs: node.$attrs$,
257
191
  vchildren: node.$children$,
@@ -260,6 +194,15 @@ const convertToPublic = (node) => ({
260
194
  vtag: node.$tag$,
261
195
  vtext: node.$text$,
262
196
  });
197
+ /**
198
+ * Convert a {@link d.ChildNode} back to an equivalent {@link d.VNode} in
199
+ * order to use the resulting object in the virtual DOM. The initial object was
200
+ * likely created as part of presenting a public API, so converting it back
201
+ * involved making it 'private' again (hence, `convertToPrivate`).
202
+ *
203
+ * @param node the child node to convert
204
+ * @returns a converted virtual DOM node
205
+ */
263
206
  const convertToPrivate = (node) => {
264
207
  if (typeof node.vtag === 'function') {
265
208
  const vnodeData = Object.assign({}, node.vattrs);
@@ -278,6 +221,157 @@ const convertToPrivate = (node) => {
278
221
  vnode.$name$ = node.vname;
279
222
  return vnode;
280
223
  };
224
+ /**
225
+ * Parse a new property value for a given property type.
226
+ *
227
+ * While the prop value can reasonably be expected to be of `any` type as far as TypeScript's type checker is concerned,
228
+ * it is not safe to assume that the string returned by evaluating `typeof propValue` matches:
229
+ * 1. `any`, the type given to `propValue` in the function signature
230
+ * 2. the type stored from `propType`.
231
+ *
232
+ * This function provides the capability to parse/coerce a property's value to potentially any other JavaScript type.
233
+ *
234
+ * Property values represented in TSX preserve their type information. In the example below, the number 0 is passed to
235
+ * a component. This `propValue` will preserve its type information (`typeof propValue === 'number'`). Note that is
236
+ * based on the type of the value being passed in, not the type declared of the class member decorated with `@Prop`.
237
+ * ```tsx
238
+ * <my-cmp prop-val={0}></my-cmp>
239
+ * ```
240
+ *
241
+ * HTML prop values on the other hand, will always a string
242
+ *
243
+ * @param propValue the new value to coerce to some type
244
+ * @param propType the type of the prop, expressed as a binary number
245
+ * @returns the parsed/coerced value
246
+ */
247
+ const parsePropertyValue = (propValue, propType) => {
248
+ // ensure this value is of the correct prop type
249
+ if (propValue != null && !isComplexType(propValue)) {
250
+ if (propType & 4 /* MEMBER_FLAGS.Boolean */) {
251
+ // per the HTML spec, any string value means it is a boolean true value
252
+ // but we'll cheat here and say that the string "false" is the boolean false
253
+ return propValue === 'false' ? false : propValue === '' || !!propValue;
254
+ }
255
+ if (propType & 2 /* MEMBER_FLAGS.Number */) {
256
+ // force it to be a number
257
+ return parseFloat(propValue);
258
+ }
259
+ if (propType & 1 /* MEMBER_FLAGS.String */) {
260
+ // could have been passed as a number or boolean
261
+ // but we still want it as a string
262
+ return String(propValue);
263
+ }
264
+ // redundant return here for better minification
265
+ return propValue;
266
+ }
267
+ // not sure exactly what type we want
268
+ // so no need to change to a different type
269
+ return propValue;
270
+ };
271
+ const getElement = (ref) => (getHostRef(ref).$hostElement$ );
272
+ const createEvent = (ref, name, flags) => {
273
+ const elm = getElement(ref);
274
+ return {
275
+ emit: (detail) => {
276
+ return emitEvent(elm, name, {
277
+ bubbles: !!(flags & 4 /* EVENT_FLAGS.Bubbles */),
278
+ composed: !!(flags & 2 /* EVENT_FLAGS.Composed */),
279
+ cancelable: !!(flags & 1 /* EVENT_FLAGS.Cancellable */),
280
+ detail,
281
+ });
282
+ },
283
+ };
284
+ };
285
+ /**
286
+ * Helper function to create & dispatch a custom Event on a provided target
287
+ * @param elm the target of the Event
288
+ * @param name the name to give the custom Event
289
+ * @param opts options for configuring a custom Event
290
+ * @returns the custom Event
291
+ */
292
+ const emitEvent = (elm, name, opts) => {
293
+ const ev = plt.ce(name, opts);
294
+ elm.dispatchEvent(ev);
295
+ return ev;
296
+ };
297
+ const rootAppliedStyles = /*@__PURE__*/ new WeakMap();
298
+ const registerStyle = (scopeId, cssText, allowCS) => {
299
+ let style = styles.get(scopeId);
300
+ if (supportsConstructableStylesheets && allowCS) {
301
+ style = (style || new CSSStyleSheet());
302
+ if (typeof style === 'string') {
303
+ style = cssText;
304
+ }
305
+ else {
306
+ style.replaceSync(cssText);
307
+ }
308
+ }
309
+ else {
310
+ style = cssText;
311
+ }
312
+ styles.set(scopeId, style);
313
+ };
314
+ const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
315
+ var _a;
316
+ let scopeId = getScopeId(cmpMeta);
317
+ const style = styles.get(scopeId);
318
+ // if an element is NOT connected then getRootNode() will return the wrong root node
319
+ // so the fallback is to always use the document for the root node in those cases
320
+ styleContainerNode = styleContainerNode.nodeType === 11 /* NODE_TYPE.DocumentFragment */ ? styleContainerNode : doc;
321
+ if (style) {
322
+ if (typeof style === 'string') {
323
+ styleContainerNode = styleContainerNode.head || styleContainerNode;
324
+ let appliedStyles = rootAppliedStyles.get(styleContainerNode);
325
+ let styleElm;
326
+ if (!appliedStyles) {
327
+ rootAppliedStyles.set(styleContainerNode, (appliedStyles = new Set()));
328
+ }
329
+ if (!appliedStyles.has(scopeId)) {
330
+ {
331
+ // TODO(STENCIL-659): Remove code implementing the CSS variable shim
332
+ {
333
+ styleElm = doc.createElement('style');
334
+ styleElm.innerHTML = style;
335
+ }
336
+ // Apply CSP nonce to the style tag if it exists
337
+ const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
338
+ if (nonce != null) {
339
+ styleElm.setAttribute('nonce', nonce);
340
+ }
341
+ styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
342
+ }
343
+ if (appliedStyles) {
344
+ appliedStyles.add(scopeId);
345
+ }
346
+ }
347
+ }
348
+ else if (!styleContainerNode.adoptedStyleSheets.includes(style)) {
349
+ styleContainerNode.adoptedStyleSheets = [...styleContainerNode.adoptedStyleSheets, style];
350
+ }
351
+ }
352
+ return scopeId;
353
+ };
354
+ const attachStyles = (hostRef) => {
355
+ const cmpMeta = hostRef.$cmpMeta$;
356
+ const elm = hostRef.$hostElement$;
357
+ const flags = cmpMeta.$flags$;
358
+ const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
359
+ const scopeId = addStyle(elm.shadowRoot ? elm.shadowRoot : elm.getRootNode(), cmpMeta);
360
+ // TODO(STENCIL-662): Remove code related to deprecated shadowDomShim field
361
+ if (flags & 10 /* CMP_FLAGS.needsScopedEncapsulation */) {
362
+ // only required when we're NOT using native shadow dom (slot)
363
+ // or this browser doesn't support native shadow dom
364
+ // and this host element was NOT created with SSR
365
+ // let's pick out the inner content for slot projection
366
+ // create a node to represent where the original
367
+ // content was first placed, which is useful later on
368
+ // DOM WRITE!!
369
+ elm['s-sc'] = scopeId;
370
+ elm.classList.add(scopeId + '-h');
371
+ }
372
+ endAttachStyles();
373
+ };
374
+ const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
281
375
  /**
282
376
  * Production setAccessor() function based on Preact by
283
377
  * Jason Miller (@developit)
@@ -375,11 +469,10 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
375
469
  if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
376
470
  try {
377
471
  if (!elm.tagName.includes('-')) {
378
- let n = newValue == null ? '' : newValue;
472
+ const n = newValue == null ? '' : newValue;
379
473
  // Workaround for Safari, moving the <input> caret when re-assigning the same valued
380
474
  if (memberName === 'list') {
381
475
  isProp = false;
382
- // tslint:disable-next-line: triple-equals
383
476
  }
384
477
  else if (oldValue == null || elm[memberName] != n) {
385
478
  elm[memberName] = n;
@@ -398,7 +491,7 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
398
491
  }
399
492
  }
400
493
  }
401
- else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex) {
494
+ else if ((!isProp || flags & 4 /* VNODE_FLAGS.isHost */ || isSvg) && !isComplex) {
402
495
  newValue = newValue === true ? '' : newValue;
403
496
  {
404
497
  elm.setAttribute(memberName, newValue);
@@ -413,7 +506,7 @@ const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
413
506
  // if the element passed in is a shadow root, which is a document fragment
414
507
  // then we want to be adding attrs/props to the shadow root's "host" element
415
508
  // if it's not a shadow root, then we add attrs/props to the same element
416
- const elm = newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host
509
+ const elm = newVnode.$elm$.nodeType === 11 /* NODE_TYPE.DocumentFragment */ && newVnode.$elm$.host
417
510
  ? newVnode.$elm$.host
418
511
  : newVnode.$elm$;
419
512
  const oldVnodeAttrs = (oldVnode && oldVnode.$attrs$) || EMPTY_OBJ;
@@ -431,9 +524,19 @@ const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
431
524
  setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode, newVnode.$flags$);
432
525
  }
433
526
  };
527
+ /**
528
+ * Create a DOM Node corresponding to one of the children of a given VNode.
529
+ *
530
+ * @param oldParentVNode the parent VNode from the previous render
531
+ * @param newParentVNode the parent VNode from the current render
532
+ * @param childIndex the index of the VNode, in the _new_ parent node's
533
+ * children, for which we will create a new DOM node
534
+ * @param parentElm the parent DOM node which our new node will be a child of
535
+ * @returns the newly created node
536
+ */
434
537
  const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
435
538
  // tslint:disable-next-line: prefer-const
436
- let newVNode = newParentVNode.$children$[childIndex];
539
+ const newVNode = newParentVNode.$children$[childIndex];
437
540
  let i = 0;
438
541
  let elm;
439
542
  let childNode;
@@ -484,6 +587,21 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
484
587
  }
485
588
  return elm;
486
589
  };
590
+ /**
591
+ * Create DOM nodes corresponding to a list of {@link d.Vnode} objects and
592
+ * add them to the DOM in the appropriate place.
593
+ *
594
+ * @param parentElm the DOM node which should be used as a parent for the new
595
+ * DOM nodes
596
+ * @param before a child of the `parentElm` which the new children should be
597
+ * inserted before (optional)
598
+ * @param parentVNode the parent virtual DOM node
599
+ * @param vnodes the new child virtual DOM nodes to produce DOM nodes for
600
+ * @param startIdx the index in the child virtual DOM nodes at which to start
601
+ * creating DOM nodes (inclusive)
602
+ * @param endIdx the index in the child virtual DOM nodes at which to stop
603
+ * creating DOM nodes (inclusive)
604
+ */
487
605
  const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
488
606
  let containerElm = (parentElm);
489
607
  let childNode;
@@ -500,16 +618,98 @@ const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) =>
500
618
  }
501
619
  }
502
620
  };
503
- const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
504
- for (; startIdx <= endIdx; ++startIdx) {
505
- if ((vnode = vnodes[startIdx])) {
506
- elm = vnode.$elm$;
507
- callNodeRefs(vnode);
508
- // remove the vnode's element from the dom
509
- elm.remove();
621
+ /**
622
+ * Remove the DOM elements corresponding to a list of {@link d.VNode} objects.
623
+ * This can be used to, for instance, clean up after a list of children which
624
+ * should no longer be shown.
625
+ *
626
+ * This function also handles some of Stencil's slot relocation logic.
627
+ *
628
+ * @param vnodes a list of virtual DOM nodes to remove
629
+ * @param startIdx the index at which to start removing nodes (inclusive)
630
+ * @param endIdx the index at which to stop removing nodes (inclusive)
631
+ */
632
+ const removeVnodes = (vnodes, startIdx, endIdx) => {
633
+ for (let index = startIdx; index <= endIdx; ++index) {
634
+ const vnode = vnodes[index];
635
+ if (vnode) {
636
+ const elm = vnode.$elm$;
637
+ nullifyVNodeRefs(vnode);
638
+ if (elm) {
639
+ // remove the vnode's element from the dom
640
+ elm.remove();
641
+ }
510
642
  }
511
643
  }
512
644
  };
645
+ /**
646
+ * Reconcile the children of a new VNode with the children of an old VNode by
647
+ * traversing the two collections of children, identifying nodes that are
648
+ * conserved or changed, calling out to `patch` to make any necessary
649
+ * updates to the DOM, and rearranging DOM nodes as needed.
650
+ *
651
+ * The algorithm for reconciling children works by analyzing two 'windows' onto
652
+ * the two arrays of children (`oldCh` and `newCh`). We keep track of the
653
+ * 'windows' by storing start and end indices and references to the
654
+ * corresponding array entries. Initially the two 'windows' are basically equal
655
+ * to the entire array, but we progressively narrow the windows until there are
656
+ * no children left to update by doing the following:
657
+ *
658
+ * 1. Skip any `null` entries at the beginning or end of the two arrays, so
659
+ * that if we have an initial array like the following we'll end up dealing
660
+ * only with a window bounded by the highlighted elements:
661
+ *
662
+ * [null, null, VNode1 , ... , VNode2, null, null]
663
+ * ^^^^^^ ^^^^^^
664
+ *
665
+ * 2. Check to see if the elements at the head and tail positions are equal
666
+ * across the windows. This will basically detect elements which haven't
667
+ * been added, removed, or changed position, i.e. if you had the following
668
+ * VNode elements (represented as HTML):
669
+ *
670
+ * oldVNode: `<div><p><span>HEY</span></p></div>`
671
+ * newVNode: `<div><p><span>THERE</span></p></div>`
672
+ *
673
+ * Then when comparing the children of the `<div>` tag we check the equality
674
+ * of the VNodes corresponding to the `<p>` tags and, since they are the
675
+ * same tag in the same position, we'd be able to avoid completely
676
+ * re-rendering the subtree under them with a new DOM element and would just
677
+ * call out to `patch` to handle reconciling their children and so on.
678
+ *
679
+ * 3. Check, for both windows, to see if the element at the beginning of the
680
+ * window corresponds to the element at the end of the other window. This is
681
+ * a heuristic which will let us identify _some_ situations in which
682
+ * elements have changed position, for instance it _should_ detect that the
683
+ * children nodes themselves have not changed but merely moved in the
684
+ * following example:
685
+ *
686
+ * oldVNode: `<div><element-one /><element-two /></div>`
687
+ * newVNode: `<div><element-two /><element-one /></div>`
688
+ *
689
+ * If we find cases like this then we also need to move the concrete DOM
690
+ * elements corresponding to the moved children to write the re-order to the
691
+ * DOM.
692
+ *
693
+ * 4. Finally, if VNodes have the `key` attribute set on them we check for any
694
+ * nodes in the old children which have the same key as the first element in
695
+ * our window on the new children. If we find such a node we handle calling
696
+ * out to `patch`, moving relevant DOM nodes, and so on, in accordance with
697
+ * what we find.
698
+ *
699
+ * Finally, once we've narrowed our 'windows' to the point that either of them
700
+ * collapse (i.e. they have length 0) we then handle any remaining VNode
701
+ * insertion or deletion that needs to happen to get a DOM state that correctly
702
+ * reflects the new child VNodes. If, for instance, after our window on the old
703
+ * children has collapsed we still have more nodes on the new children that
704
+ * we haven't dealt with yet then we need to add them, or if the new children
705
+ * collapse but we still have unhandled _old_ children then we need to make
706
+ * sure the corresponding DOM nodes are removed.
707
+ *
708
+ * @param parentElm the node into which the parent VNode is rendered
709
+ * @param oldCh the old children of the parent node
710
+ * @param newVNode the new VNode which will replace the parent
711
+ * @param newCh the new children of the parent node
712
+ */
513
713
  const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
514
714
  let oldStartIdx = 0;
515
715
  let newStartIdx = 0;
@@ -525,7 +725,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
525
725
  let elmToMove;
526
726
  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
527
727
  if (oldStartVnode == null) {
528
- // Vnode might have been moved left
728
+ // VNode might have been moved left
529
729
  oldStartVnode = oldCh[++oldStartIdx];
530
730
  }
531
731
  else if (oldEndVnode == null) {
@@ -538,29 +738,65 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
538
738
  newEndVnode = newCh[--newEndIdx];
539
739
  }
540
740
  else if (isSameVnode(oldStartVnode, newStartVnode)) {
741
+ // if the start nodes are the same then we should patch the new VNode
742
+ // onto the old one, and increment our `newStartIdx` and `oldStartIdx`
743
+ // indices to reflect that. We don't need to move any DOM Nodes around
744
+ // since things are matched up in order.
541
745
  patch(oldStartVnode, newStartVnode);
542
746
  oldStartVnode = oldCh[++oldStartIdx];
543
747
  newStartVnode = newCh[++newStartIdx];
544
748
  }
545
749
  else if (isSameVnode(oldEndVnode, newEndVnode)) {
750
+ // likewise, if the end nodes are the same we patch new onto old and
751
+ // decrement our end indices, and also likewise in this case we don't
752
+ // need to move any DOM Nodes.
546
753
  patch(oldEndVnode, newEndVnode);
547
754
  oldEndVnode = oldCh[--oldEndIdx];
548
755
  newEndVnode = newCh[--newEndIdx];
549
756
  }
550
757
  else if (isSameVnode(oldStartVnode, newEndVnode)) {
551
758
  patch(oldStartVnode, newEndVnode);
759
+ // We need to move the element for `oldStartVnode` into a position which
760
+ // will be appropriate for `newEndVnode`. For this we can use
761
+ // `.insertBefore` and `oldEndVnode.$elm$.nextSibling`. If there is a
762
+ // sibling for `oldEndVnode.$elm$` then we want to move the DOM node for
763
+ // `oldStartVnode` between `oldEndVnode` and it's sibling, like so:
764
+ //
765
+ // <old-start-node />
766
+ // <some-intervening-node />
767
+ // <old-end-node />
768
+ // <!-- -> <-- `oldStartVnode.$elm$` should be inserted here
769
+ // <next-sibling />
770
+ //
771
+ // If instead `oldEndVnode.$elm$` has no sibling then we just want to put
772
+ // the node for `oldStartVnode` at the end of the children of
773
+ // `parentElm`. Luckily, `Node.nextSibling` will return `null` if there
774
+ // aren't any siblings, and passing `null` to `Node.insertBefore` will
775
+ // append it to the children of the parent element.
552
776
  parentElm.insertBefore(oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
553
777
  oldStartVnode = oldCh[++oldStartIdx];
554
778
  newEndVnode = newCh[--newEndIdx];
555
779
  }
556
780
  else if (isSameVnode(oldEndVnode, newStartVnode)) {
557
781
  patch(oldEndVnode, newStartVnode);
782
+ // We've already checked above if `oldStartVnode` and `newStartVnode` are
783
+ // the same node, so since we're here we know that they are not. Thus we
784
+ // can move the element for `oldEndVnode` _before_ the element for
785
+ // `oldStartVnode`, leaving `oldStartVnode` to be reconciled in the
786
+ // future.
558
787
  parentElm.insertBefore(oldEndVnode.$elm$, oldStartVnode.$elm$);
559
788
  oldEndVnode = oldCh[--oldEndIdx];
560
789
  newStartVnode = newCh[++newStartIdx];
561
790
  }
562
791
  else {
563
- // createKeyToOldIdx
792
+ // Here we do some checks to match up old and new nodes based on the
793
+ // `$key$` attribute, which is set by putting a `key="my-key"` attribute
794
+ // in the JSX for a DOM element in the implementation of a Stencil
795
+ // component.
796
+ //
797
+ // First we check to see if there are any nodes in the array of old
798
+ // children which have the same key as the first node in the new
799
+ // children.
564
800
  idxInOld = -1;
565
801
  {
566
802
  for (i = oldStartIdx; i <= oldEndIdx; ++i) {
@@ -571,23 +807,32 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
571
807
  }
572
808
  }
573
809
  if (idxInOld >= 0) {
810
+ // We found a node in the old children which matches up with the first
811
+ // node in the new children! So let's deal with that
574
812
  elmToMove = oldCh[idxInOld];
575
813
  if (elmToMove.$tag$ !== newStartVnode.$tag$) {
814
+ // the tag doesn't match so we'll need a new DOM element
576
815
  node = createElm(oldCh && oldCh[newStartIdx], newVNode, idxInOld);
577
816
  }
578
817
  else {
579
818
  patch(elmToMove, newStartVnode);
819
+ // invalidate the matching old node so that we won't try to update it
820
+ // again later on
580
821
  oldCh[idxInOld] = undefined;
581
822
  node = elmToMove.$elm$;
582
823
  }
583
824
  newStartVnode = newCh[++newStartIdx];
584
825
  }
585
826
  else {
586
- // new element
827
+ // We either didn't find an element in the old children that matches
828
+ // the key of the first new child OR the build is not using `key`
829
+ // attributes at all. In either case we need to create a new element
830
+ // for the new node.
587
831
  node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx);
588
832
  newStartVnode = newCh[++newStartIdx];
589
833
  }
590
834
  if (node) {
835
+ // if we created a new node then handle inserting it to the DOM
591
836
  {
592
837
  oldStartVnode.$elm$.parentNode.insertBefore(node, oldStartVnode.$elm$);
593
838
  }
@@ -595,22 +840,53 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
595
840
  }
596
841
  }
597
842
  if (oldStartIdx > oldEndIdx) {
843
+ // we have some more new nodes to add which don't match up with old nodes
598
844
  addVnodes(parentElm, newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$, newVNode, newCh, newStartIdx, newEndIdx);
599
845
  }
600
846
  else if (newStartIdx > newEndIdx) {
847
+ // there are nodes in the `oldCh` array which no longer correspond to nodes
848
+ // in the new array, so lets remove them (which entails cleaning up the
849
+ // relevant DOM nodes)
601
850
  removeVnodes(oldCh, oldStartIdx, oldEndIdx);
602
851
  }
603
852
  };
604
- const isSameVnode = (vnode1, vnode2) => {
853
+ /**
854
+ * Compare two VNodes to determine if they are the same
855
+ *
856
+ * **NB**: This function is an equality _heuristic_ based on the available
857
+ * information set on the two VNodes and can be misleading under certain
858
+ * circumstances. In particular, if the two nodes do not have `key` attrs
859
+ * (available under `$key$` on VNodes) then the function falls back on merely
860
+ * checking that they have the same tag.
861
+ *
862
+ * So, in other words, if `key` attrs are not set on VNodes which may be
863
+ * changing order within a `children` array or something along those lines then
864
+ * we could obtain a false negative and then have to do needless re-rendering
865
+ * (i.e. we'd say two VNodes aren't equal when in fact they should be).
866
+ *
867
+ * @param leftVNode the first VNode to check
868
+ * @param rightVNode the second VNode to check
869
+ * @returns whether they're equal or not
870
+ */
871
+ const isSameVnode = (leftVNode, rightVNode) => {
605
872
  // compare if two vnode to see if they're "technically" the same
606
873
  // need to have the same element tag, and same key to be the same
607
- if (vnode1.$tag$ === vnode2.$tag$) {
874
+ if (leftVNode.$tag$ === rightVNode.$tag$) {
875
+ // this will be set if components in the build have `key` attrs set on them
608
876
  {
609
- return vnode1.$key$ === vnode2.$key$;
877
+ return leftVNode.$key$ === rightVNode.$key$;
610
878
  }
611
879
  }
612
880
  return false;
613
881
  };
882
+ /**
883
+ * Handle reconciling an outdated VNode with a new one which corresponds to
884
+ * it. This function handles flushing updates to the DOM and reconciling the
885
+ * children of the two nodes (if any).
886
+ *
887
+ * @param oldVNode an old VNode whose DOM element and children we want to update
888
+ * @param newVNode a new VNode representing an updated version of the old one
889
+ */
614
890
  const patch = (oldVNode, newVNode) => {
615
891
  const elm = (newVNode.$elm$ = oldVNode.$elm$);
616
892
  const oldChildren = oldVNode.$children$;
@@ -623,7 +899,6 @@ const patch = (oldVNode, newVNode) => {
623
899
  // only add this to the when the compiler sees we're using an svg somewhere
624
900
  isSvgMode = tag === 'svg' ? true : tag === 'foreignObject' ? false : isSvgMode;
625
901
  }
626
- // element node
627
902
  {
628
903
  if (tag === 'slot')
629
904
  ;
@@ -636,6 +911,7 @@ const patch = (oldVNode, newVNode) => {
636
911
  }
637
912
  if (oldChildren !== null && newChildren !== null) {
638
913
  // looks like there's child vnodes for both the old and new vnodes
914
+ // so we need to call `updateChildren` to reconcile them
639
915
  updateChildren(elm, oldChildren, newVNode, newChildren);
640
916
  }
641
917
  else if (newChildren !== null) {
@@ -661,12 +937,31 @@ const patch = (oldVNode, newVNode) => {
661
937
  elm.data = text;
662
938
  }
663
939
  };
664
- const callNodeRefs = (vNode) => {
940
+ /**
941
+ * 'Nullify' any VDom `ref` callbacks on a VDom node or its children by
942
+ * calling them with `null`. This signals that the DOM element corresponding to
943
+ * the VDom node has been removed from the DOM.
944
+ *
945
+ * @param vNode a virtual DOM node
946
+ */
947
+ const nullifyVNodeRefs = (vNode) => {
665
948
  {
666
949
  vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(null);
667
- vNode.$children$ && vNode.$children$.map(callNodeRefs);
950
+ vNode.$children$ && vNode.$children$.map(nullifyVNodeRefs);
668
951
  }
669
952
  };
953
+ /**
954
+ * The main entry point for Stencil's virtual DOM-based rendering engine
955
+ *
956
+ * Given a {@link d.HostRef} container and some virtual DOM nodes, this
957
+ * function will handle creating a virtual DOM tree with a single root, patching
958
+ * the current virtual DOM tree onto an old one (if any), dealing with slot
959
+ * relocation, and reflecting attributes.
960
+ *
961
+ * @param hostRef data needed to root and render the virtual DOM tree, such as
962
+ * the DOM node into which it should be rendered.
963
+ * @param renderFnResults the virtual DOM nodes to be rendered
964
+ */
670
965
  const renderVdom = (hostRef, renderFnResults) => {
671
966
  const hostElm = hostRef.$hostElement$;
672
967
  const cmpMeta = hostRef.$cmpMeta$;
@@ -678,7 +973,7 @@ const renderVdom = (hostRef, renderFnResults) => {
678
973
  cmpMeta.$attrsToReflect$.map(([propName, attribute]) => (rootVnode.$attrs$[attribute] = hostElm[propName]));
679
974
  }
680
975
  rootVnode.$tag$ = null;
681
- rootVnode.$flags$ |= 4 /* isHost */;
976
+ rootVnode.$flags$ |= 4 /* VNODE_FLAGS.isHost */;
682
977
  hostRef.$vnode$ = rootVnode;
683
978
  rootVnode.$elm$ = oldVNode.$elm$ = (hostElm.shadowRoot || hostElm );
684
979
  {
@@ -687,32 +982,6 @@ const renderVdom = (hostRef, renderFnResults) => {
687
982
  // synchronous patch
688
983
  patch(oldVNode, rootVnode);
689
984
  };
690
- const getElement = (ref) => (getHostRef(ref).$hostElement$ );
691
- const createEvent = (ref, name, flags) => {
692
- const elm = getElement(ref);
693
- return {
694
- emit: (detail) => {
695
- return emitEvent(elm, name, {
696
- bubbles: !!(flags & 4 /* Bubbles */),
697
- composed: !!(flags & 2 /* Composed */),
698
- cancelable: !!(flags & 1 /* Cancellable */),
699
- detail,
700
- });
701
- },
702
- };
703
- };
704
- /**
705
- * Helper function to create & dispatch a custom Event on a provided target
706
- * @param elm the target of the Event
707
- * @param name the name to give the custom Event
708
- * @param opts options for configuring a custom Event
709
- * @returns the custom Event
710
- */
711
- const emitEvent = (elm, name, opts) => {
712
- const ev = plt.ce(name, opts);
713
- elm.dispatchEvent(ev);
714
- return ev;
715
- };
716
985
  const attachToAncestor = (hostRef, ancestorComponent) => {
717
986
  if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
718
987
  ancestorComponent['s-p'].push(new Promise((r) => (hostRef.$onRenderResolve$ = r)));
@@ -720,10 +989,10 @@ const attachToAncestor = (hostRef, ancestorComponent) => {
720
989
  };
721
990
  const scheduleUpdate = (hostRef, isInitialLoad) => {
722
991
  {
723
- hostRef.$flags$ |= 16 /* isQueuedForUpdate */;
992
+ hostRef.$flags$ |= 16 /* HOST_FLAGS.isQueuedForUpdate */;
724
993
  }
725
- if (hostRef.$flags$ & 4 /* isWaitingForChildren */) {
726
- hostRef.$flags$ |= 512 /* needsRerender */;
994
+ if (hostRef.$flags$ & 4 /* HOST_FLAGS.isWaitingForChildren */) {
995
+ hostRef.$flags$ |= 512 /* HOST_FLAGS.needsRerender */;
727
996
  return;
728
997
  }
729
998
  attachToAncestor(hostRef, hostRef.$ancestorComponent$);
@@ -733,27 +1002,71 @@ const scheduleUpdate = (hostRef, isInitialLoad) => {
733
1002
  const dispatch = () => dispatchHooks(hostRef, isInitialLoad);
734
1003
  return writeTask(dispatch) ;
735
1004
  };
1005
+ /**
1006
+ * Dispatch initial-render and update lifecycle hooks, enqueuing calls to
1007
+ * component lifecycle methods like `componentWillLoad` as well as
1008
+ * {@link updateComponent}, which will kick off the virtual DOM re-render.
1009
+ *
1010
+ * @param hostRef a reference to a host DOM node
1011
+ * @param isInitialLoad whether we're on the initial load or not
1012
+ * @returns an empty Promise which is used to enqueue a series of operations for
1013
+ * the component
1014
+ */
736
1015
  const dispatchHooks = (hostRef, isInitialLoad) => {
737
1016
  const endSchedule = createTime('scheduleUpdate', hostRef.$cmpMeta$.$tagName$);
738
1017
  const instance = hostRef.$lazyInstance$ ;
739
- let promise;
1018
+ // We're going to use this variable together with `enqueue` to implement a
1019
+ // little promise-based queue. We start out with it `undefined`. When we add
1020
+ // the first function to the queue we'll set this variable to be that
1021
+ // function's return value. When we attempt to add subsequent values to the
1022
+ // queue we'll check that value and, if it was a `Promise`, we'll then chain
1023
+ // the new function off of that `Promise` using `.then()`. This will give our
1024
+ // queue two nice properties:
1025
+ //
1026
+ // 1. If all functions added to the queue are synchronous they'll be called
1027
+ // synchronously right away.
1028
+ // 2. If all functions added to the queue are asynchronous they'll all be
1029
+ // called in order after `dispatchHooks` exits.
1030
+ let maybePromise;
740
1031
  if (isInitialLoad) {
741
1032
  {
742
- hostRef.$flags$ |= 256 /* isListenReady */;
1033
+ hostRef.$flags$ |= 256 /* HOST_FLAGS.isListenReady */;
743
1034
  if (hostRef.$queuedListeners$) {
744
1035
  hostRef.$queuedListeners$.map(([methodName, event]) => safeCall(instance, methodName, event));
745
- hostRef.$queuedListeners$ = null;
1036
+ hostRef.$queuedListeners$ = undefined;
746
1037
  }
747
1038
  }
748
1039
  {
749
- promise = safeCall(instance, 'componentWillLoad');
1040
+ // If `componentWillLoad` returns a `Promise` then we want to wait on
1041
+ // whatever's going on in that `Promise` before we launch into
1042
+ // rendering the component, doing other lifecycle stuff, etc. So
1043
+ // in that case we assign the returned promise to the variable we
1044
+ // declared above to hold a possible 'queueing' Promise
1045
+ maybePromise = safeCall(instance, 'componentWillLoad');
750
1046
  }
751
1047
  }
752
1048
  endSchedule();
753
- return then(promise, () => updateComponent(hostRef, instance, isInitialLoad));
1049
+ return enqueue(maybePromise, () => updateComponent(hostRef, instance, isInitialLoad));
754
1050
  };
1051
+ /**
1052
+ * This function uses a Promise to implement a simple first-in, first-out queue
1053
+ * of functions to be called.
1054
+ *
1055
+ * The queue is ordered on the basis of the first argument. If it's
1056
+ * `undefined`, then nothing is on the queue yet, so the provided function can
1057
+ * be called synchronously (although note that this function may return a
1058
+ * `Promise`). The idea is that then the return value of that enqueueing
1059
+ * operation is kept around, so that if it was a `Promise` then subsequent
1060
+ * functions can be enqueued by calling this function again with that `Promise`
1061
+ * as the first argument.
1062
+ *
1063
+ * @param maybePromise either a `Promise` which should resolve before the next function is called or an 'empty' sentinel
1064
+ * @param fn a function to enqueue
1065
+ * @returns either a `Promise` or the return value of the provided function
1066
+ */
1067
+ const enqueue = (maybePromise, fn) => maybePromise instanceof Promise ? maybePromise.then(fn) : fn();
755
1068
  const updateComponent = async (hostRef, instance, isInitialLoad) => {
756
- // updateComponent
1069
+ var _a;
757
1070
  const elm = hostRef.$hostElement$;
758
1071
  const endUpdate = createTime('update', hostRef.$cmpMeta$.$tagName$);
759
1072
  const rc = elm['s-rc'];
@@ -775,14 +1088,14 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
775
1088
  endRender();
776
1089
  endUpdate();
777
1090
  {
778
- const childrenPromises = elm['s-p'];
1091
+ const childrenPromises = (_a = elm['s-p']) !== null && _a !== void 0 ? _a : [];
779
1092
  const postUpdate = () => postUpdateComponent(hostRef);
780
1093
  if (childrenPromises.length === 0) {
781
1094
  postUpdate();
782
1095
  }
783
1096
  else {
784
1097
  Promise.all(childrenPromises).then(postUpdate);
785
- hostRef.$flags$ |= 4 /* isWaitingForChildren */;
1098
+ hostRef.$flags$ |= 4 /* HOST_FLAGS.isWaitingForChildren */;
786
1099
  childrenPromises.length = 0;
787
1100
  }
788
1101
  }
@@ -792,10 +1105,10 @@ const callRender = (hostRef, instance, elm) => {
792
1105
  renderingRef = instance;
793
1106
  instance = instance.render() ;
794
1107
  {
795
- hostRef.$flags$ &= ~16 /* isQueuedForUpdate */;
1108
+ hostRef.$flags$ &= ~16 /* HOST_FLAGS.isQueuedForUpdate */;
796
1109
  }
797
1110
  {
798
- hostRef.$flags$ |= 2 /* hasRendered */;
1111
+ hostRef.$flags$ |= 2 /* HOST_FLAGS.hasRendered */;
799
1112
  }
800
1113
  {
801
1114
  {
@@ -821,8 +1134,8 @@ const postUpdateComponent = (hostRef) => {
821
1134
  const endPostUpdate = createTime('postUpdate', tagName);
822
1135
  const instance = hostRef.$lazyInstance$ ;
823
1136
  const ancestorComponent = hostRef.$ancestorComponent$;
824
- if (!(hostRef.$flags$ & 64 /* hasLoadedComponent */)) {
825
- hostRef.$flags$ |= 64 /* hasLoadedComponent */;
1137
+ if (!(hostRef.$flags$ & 64 /* HOST_FLAGS.hasLoadedComponent */)) {
1138
+ hostRef.$flags$ |= 64 /* HOST_FLAGS.hasLoadedComponent */;
826
1139
  {
827
1140
  // DOM WRITE!
828
1141
  addHydratedFlag(elm);
@@ -848,10 +1161,10 @@ const postUpdateComponent = (hostRef) => {
848
1161
  hostRef.$onRenderResolve$();
849
1162
  hostRef.$onRenderResolve$ = undefined;
850
1163
  }
851
- if (hostRef.$flags$ & 512 /* needsRerender */) {
1164
+ if (hostRef.$flags$ & 512 /* HOST_FLAGS.needsRerender */) {
852
1165
  nextTick(() => scheduleUpdate(hostRef, false));
853
1166
  }
854
- hostRef.$flags$ &= ~(4 /* isWaitingForChildren */ | 512 /* needsRerender */);
1167
+ hostRef.$flags$ &= ~(4 /* HOST_FLAGS.isWaitingForChildren */ | 512 /* HOST_FLAGS.needsRerender */);
855
1168
  }
856
1169
  // ( •_•)
857
1170
  // ( •_•)>⌐■-■
@@ -862,7 +1175,7 @@ const forceUpdate = (ref) => {
862
1175
  const hostRef = getHostRef(ref);
863
1176
  const isConnected = hostRef.$hostElement$.isConnected;
864
1177
  if (isConnected &&
865
- (hostRef.$flags$ & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
1178
+ (hostRef.$flags$ & (2 /* HOST_FLAGS.hasRendered */ | 16 /* HOST_FLAGS.isQueuedForUpdate */)) === 2 /* HOST_FLAGS.hasRendered */) {
866
1179
  scheduleUpdate(hostRef, false);
867
1180
  }
868
1181
  // Returns "true" when the forced update was successfully scheduled
@@ -888,35 +1201,8 @@ const safeCall = (instance, method, arg) => {
888
1201
  }
889
1202
  return undefined;
890
1203
  };
891
- const then = (promise, thenFn) => {
892
- return promise && promise.then ? promise.then(thenFn) : thenFn();
893
- };
894
1204
  const addHydratedFlag = (elm) => elm.classList.add('hydrated')
895
1205
  ;
896
- const parsePropertyValue = (propValue, propType) => {
897
- // ensure this value is of the correct prop type
898
- if (propValue != null && !isComplexType(propValue)) {
899
- if (propType & 4 /* Boolean */) {
900
- // per the HTML spec, any string value means it is a boolean true value
901
- // but we'll cheat here and say that the string "false" is the boolean false
902
- return propValue === 'false' ? false : propValue === '' || !!propValue;
903
- }
904
- if (propType & 2 /* Number */) {
905
- // force it to be a number
906
- return parseFloat(propValue);
907
- }
908
- if (propType & 1 /* String */) {
909
- // could have been passed as a number or boolean
910
- // but we still want it as a string
911
- return String(propValue);
912
- }
913
- // redundant return here for better minification
914
- return propValue;
915
- }
916
- // not sure exactly what type we want
917
- // so no need to change to a different type
918
- return propValue;
919
- };
920
1206
  const getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
921
1207
  const setValue = (ref, propName, newVal, cmpMeta) => {
922
1208
  // check our new property value against our internal value
@@ -926,13 +1212,16 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
926
1212
  const flags = hostRef.$flags$;
927
1213
  const instance = hostRef.$lazyInstance$ ;
928
1214
  newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
929
- if ((!(flags & 8 /* isConstructingInstance */) || oldVal === undefined) && newVal !== oldVal) {
1215
+ // explicitly check for NaN on both sides, as `NaN === NaN` is always false
1216
+ const areBothNaN = Number.isNaN(oldVal) && Number.isNaN(newVal);
1217
+ const didValueChange = newVal !== oldVal && !areBothNaN;
1218
+ if ((!(flags & 8 /* HOST_FLAGS.isConstructingInstance */) || oldVal === undefined) && didValueChange) {
930
1219
  // gadzooks! the property's value has changed!!
931
1220
  // set our new value!
932
1221
  hostRef.$instanceValues$.set(propName, newVal);
933
1222
  if (instance) {
934
1223
  // get an array of method names of watch functions to call
935
- if (cmpMeta.$watchers$ && flags & 128 /* isWatchReady */) {
1224
+ if (cmpMeta.$watchers$ && flags & 128 /* HOST_FLAGS.isWatchReady */) {
936
1225
  const watchMethods = cmpMeta.$watchers$[propName];
937
1226
  if (watchMethods) {
938
1227
  // this instance is watching for when this property changed
@@ -947,7 +1236,7 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
947
1236
  });
948
1237
  }
949
1238
  }
950
- if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
1239
+ if ((flags & (2 /* HOST_FLAGS.hasRendered */ | 16 /* HOST_FLAGS.isQueuedForUpdate */)) === 2 /* HOST_FLAGS.hasRendered */) {
951
1240
  // looks like this value actually changed, so we've got work to do!
952
1241
  // but only if we've already rendered, otherwise just chill out
953
1242
  // queue that we need to do an update, but don't worry about queuing
@@ -957,6 +1246,16 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
957
1246
  }
958
1247
  }
959
1248
  };
1249
+ /**
1250
+ * Attach a series of runtime constructs to a compiled Stencil component
1251
+ * constructor, including getters and setters for the `@Prop` and `@State`
1252
+ * decorators, callbacks for when attributes change, and so on.
1253
+ *
1254
+ * @param Cstr the constructor for a component that we need to process
1255
+ * @param cmpMeta metadata collected previously about the component
1256
+ * @param flags a number used to store a series of bit flags
1257
+ * @returns a reference to the same constructor passed in (but now mutated)
1258
+ */
960
1259
  const proxyComponent = (Cstr, cmpMeta, flags) => {
961
1260
  if (cmpMeta.$members$) {
962
1261
  if (Cstr.watchers) {
@@ -966,8 +1265,8 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
966
1265
  const members = Object.entries(cmpMeta.$members$);
967
1266
  const prototype = Cstr.prototype;
968
1267
  members.map(([memberName, [memberFlags]]) => {
969
- if ((memberFlags & 31 /* Prop */ ||
970
- ((flags & 2 /* proxyState */) && memberFlags & 32 /* State */))) {
1268
+ if ((memberFlags & 31 /* MEMBER_FLAGS.Prop */ ||
1269
+ ((flags & 2 /* PROXY_FLAGS.proxyState */) && memberFlags & 32 /* MEMBER_FLAGS.State */))) {
971
1270
  // proxyComponent - prop
972
1271
  Object.defineProperty(prototype, memberName, {
973
1272
  get() {
@@ -983,19 +1282,19 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
983
1282
  });
984
1283
  }
985
1284
  });
986
- if ((flags & 1 /* isElementConstructor */)) {
1285
+ if ((flags & 1 /* PROXY_FLAGS.isElementConstructor */)) {
987
1286
  const attrNameToPropName = new Map();
988
1287
  prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
989
1288
  plt.jmp(() => {
990
1289
  const propName = attrNameToPropName.get(attrName);
991
- // In a webcomponent lifecyle the attributeChangedCallback runs prior to connectedCallback
1290
+ // In a web component lifecycle the attributeChangedCallback runs prior to connectedCallback
992
1291
  // in the case where an attribute was set inline.
993
1292
  // ```html
994
1293
  // <my-component some-attribute="some-value"></my-component>
995
1294
  // ```
996
1295
  //
997
- // There is an edge case where a developer sets the attribute inline on a custom element and then programatically
998
- // changes it before it has been upgraded as shown below:
1296
+ // There is an edge case where a developer sets the attribute inline on a custom element and then
1297
+ // programmatically changes it before it has been upgraded as shown below:
999
1298
  //
1000
1299
  // ```html
1001
1300
  // <!-- this component has _not_ been upgraded yet -->
@@ -1005,13 +1304,13 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1005
1304
  // el = document.querySelector("#test");
1006
1305
  // el.someAttribute = "another-value";
1007
1306
  // // upgrade component
1008
- // cutsomElements.define('my-component', MyComponent);
1307
+ // customElements.define('my-component', MyComponent);
1009
1308
  // </script>
1010
1309
  // ```
1011
1310
  // In this case if we do not unshadow here and use the value of the shadowing property, attributeChangedCallback
1012
1311
  // will be called with `newValue = "some-value"` and will set the shadowed property (this.someAttribute = "another-value")
1013
1312
  // to the value that was set inline i.e. "some-value" from above example. When
1014
- // the connectedCallback attempts to unshadow it will use "some-value" as the intial value rather than "another-value"
1313
+ // the connectedCallback attempts to unshadow it will use "some-value" as the initial value rather than "another-value"
1015
1314
  //
1016
1315
  // The case where the attribute was NOT set inline but was not set programmatically shall be handled/unshadowed
1017
1316
  // by connectedCallback as this attributeChangedCallback will not fire.
@@ -1025,17 +1324,25 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1025
1324
  newValue = this[propName];
1026
1325
  delete this[propName];
1027
1326
  }
1327
+ else if (prototype.hasOwnProperty(propName) &&
1328
+ typeof this[propName] === 'number' &&
1329
+ this[propName] == newValue) {
1330
+ // if the propName exists on the prototype of `Cstr`, this update may be a result of Stencil using native
1331
+ // APIs to reflect props as attributes. Calls to `setAttribute(someElement, propName)` will result in
1332
+ // `propName` to be converted to a `DOMString`, which may not be what we want for other primitive props.
1333
+ return;
1334
+ }
1028
1335
  this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
1029
1336
  });
1030
1337
  };
1031
1338
  // create an array of attributes to observe
1032
1339
  // and also create a map of html attribute name to js property name
1033
1340
  Cstr.observedAttributes = members
1034
- .filter(([_, m]) => m[0] & 15 /* HasAttribute */) // filter to only keep props that should match attributes
1341
+ .filter(([_, m]) => m[0] & 15 /* MEMBER_FLAGS.HasAttribute */) // filter to only keep props that should match attributes
1035
1342
  .map(([propName, m]) => {
1036
1343
  const attrName = m[1] || propName;
1037
1344
  attrNameToPropName.set(attrName, propName);
1038
- if (m[0] & 512 /* ReflectAttr */) {
1345
+ if (m[0] & 512 /* MEMBER_FLAGS.ReflectAttr */) {
1039
1346
  cmpMeta.$attrsToReflect$.push([propName, attrName]);
1040
1347
  }
1041
1348
  return attrName;
@@ -1046,10 +1353,10 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1046
1353
  };
1047
1354
  const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
1048
1355
  // initializeComponent
1049
- if ((hostRef.$flags$ & 32 /* hasInitializedComponent */) === 0) {
1356
+ if ((hostRef.$flags$ & 32 /* HOST_FLAGS.hasInitializedComponent */) === 0) {
1357
+ // Let the runtime know that the component has been initialized
1358
+ hostRef.$flags$ |= 32 /* HOST_FLAGS.hasInitializedComponent */;
1050
1359
  {
1051
- // we haven't initialized this element yet
1052
- hostRef.$flags$ |= 32 /* hasInitializedComponent */;
1053
1360
  // lazy loaded components
1054
1361
  // request the component's implementation to be
1055
1362
  // wired up with the host element
@@ -1067,7 +1374,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1067
1374
  {
1068
1375
  cmpMeta.$watchers$ = Cstr.watchers;
1069
1376
  }
1070
- proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
1377
+ proxyComponent(Cstr, cmpMeta, 2 /* PROXY_FLAGS.proxyState */);
1071
1378
  Cstr.isProxied = true;
1072
1379
  }
1073
1380
  const endNewInstance = createTime('createInstance', cmpMeta.$tagName$);
@@ -1075,7 +1382,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1075
1382
  // but let's keep track of when we start and stop
1076
1383
  // so that the getters/setters don't incorrectly step on data
1077
1384
  {
1078
- hostRef.$flags$ |= 8 /* isConstructingInstance */;
1385
+ hostRef.$flags$ |= 8 /* HOST_FLAGS.isConstructingInstance */;
1079
1386
  }
1080
1387
  // construct the lazy-loaded component implementation
1081
1388
  // passing the hostRef is very important during
@@ -1088,10 +1395,10 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1088
1395
  consoleError(e);
1089
1396
  }
1090
1397
  {
1091
- hostRef.$flags$ &= ~8 /* isConstructingInstance */;
1398
+ hostRef.$flags$ &= ~8 /* HOST_FLAGS.isConstructingInstance */;
1092
1399
  }
1093
1400
  {
1094
- hostRef.$flags$ |= 128 /* isWatchReady */;
1401
+ hostRef.$flags$ |= 128 /* HOST_FLAGS.isWatchReady */;
1095
1402
  }
1096
1403
  endNewInstance();
1097
1404
  fireConnectedCallback(hostRef.$lazyInstance$);
@@ -1102,7 +1409,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1102
1409
  const scopeId = getScopeId(cmpMeta);
1103
1410
  if (!styles.has(scopeId)) {
1104
1411
  const endRegisterStyles = createTime('registerStyles', cmpMeta.$tagName$);
1105
- registerStyle(scopeId, style, !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */));
1412
+ registerStyle(scopeId, style, !!(cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */));
1106
1413
  endRegisterStyles();
1107
1414
  }
1108
1415
  }
@@ -1111,7 +1418,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1111
1418
  const ancestorComponent = hostRef.$ancestorComponent$;
1112
1419
  const schedule = () => scheduleUpdate(hostRef, true);
1113
1420
  if (ancestorComponent && ancestorComponent['s-rc']) {
1114
- // this is the intial load and this component it has an ancestor component
1421
+ // this is the initial load and this component it has an ancestor component
1115
1422
  // but the ancestor component has NOT fired its will update lifecycle yet
1116
1423
  // so let's just cool our jets and wait for the ancestor to continue first
1117
1424
  // this will get fired off when the ancestor component
@@ -1129,13 +1436,13 @@ const fireConnectedCallback = (instance) => {
1129
1436
  }
1130
1437
  };
1131
1438
  const connectedCallback = (elm) => {
1132
- if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
1439
+ if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
1133
1440
  const hostRef = getHostRef(elm);
1134
1441
  const cmpMeta = hostRef.$cmpMeta$;
1135
1442
  const endConnected = createTime('connectedCallback', cmpMeta.$tagName$);
1136
- if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
1443
+ if (!(hostRef.$flags$ & 1 /* HOST_FLAGS.hasConnected */)) {
1137
1444
  // first time this component has connected
1138
- hostRef.$flags$ |= 1 /* hasConnected */;
1445
+ hostRef.$flags$ |= 1 /* HOST_FLAGS.hasConnected */;
1139
1446
  {
1140
1447
  // find the first ancestor component (if there is one) and register
1141
1448
  // this component as one of the actively loading child components for its ancestor
@@ -1155,7 +1462,7 @@ const connectedCallback = (elm) => {
1155
1462
  // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
1156
1463
  if (cmpMeta.$members$) {
1157
1464
  Object.entries(cmpMeta.$members$).map(([memberName, [memberFlags]]) => {
1158
- if (memberFlags & 31 /* Prop */ && elm.hasOwnProperty(memberName)) {
1465
+ if (memberFlags & 31 /* MEMBER_FLAGS.Prop */ && elm.hasOwnProperty(memberName)) {
1159
1466
  const value = elm[memberName];
1160
1467
  delete elm[memberName];
1161
1468
  elm[memberName] = value;
@@ -1178,7 +1485,7 @@ const connectedCallback = (elm) => {
1178
1485
  }
1179
1486
  };
1180
1487
  const disconnectedCallback = (elm) => {
1181
- if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
1488
+ if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
1182
1489
  const hostRef = getHostRef(elm);
1183
1490
  const instance = hostRef.$lazyInstance$ ;
1184
1491
  {
@@ -1193,6 +1500,7 @@ const disconnectedCallback = (elm) => {
1193
1500
  }
1194
1501
  };
1195
1502
  const bootstrapLazy = (lazyBundles, options = {}) => {
1503
+ var _a;
1196
1504
  const endBootstrap = createTime();
1197
1505
  const cmpTags = [];
1198
1506
  const exclude = options.exclude || [];
@@ -1205,74 +1513,81 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1205
1513
  let isBootstrapping = true;
1206
1514
  Object.assign(plt, options);
1207
1515
  plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
1208
- lazyBundles.map((lazyBundle) => lazyBundle[1].map((compactMeta) => {
1209
- const cmpMeta = {
1210
- $flags$: compactMeta[0],
1211
- $tagName$: compactMeta[1],
1212
- $members$: compactMeta[2],
1213
- $listeners$: compactMeta[3],
1214
- };
1215
- {
1216
- cmpMeta.$members$ = compactMeta[2];
1217
- }
1218
- {
1219
- cmpMeta.$listeners$ = compactMeta[3];
1220
- }
1221
- {
1222
- cmpMeta.$attrsToReflect$ = [];
1223
- }
1224
- {
1225
- cmpMeta.$watchers$ = {};
1226
- }
1227
- const tagName = cmpMeta.$tagName$;
1228
- const HostElement = class extends HTMLElement {
1229
- // StencilLazyHost
1230
- constructor(self) {
1231
- // @ts-ignore
1232
- super(self);
1233
- self = this;
1234
- registerHost(self, cmpMeta);
1235
- if (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) {
1236
- // this component is using shadow dom
1237
- // and this browser supports shadow dom
1238
- // add the read-only property "shadowRoot" to the host element
1239
- // adding the shadow root build conditionals to minimize runtime
1240
- {
1516
+ lazyBundles.map((lazyBundle) => {
1517
+ lazyBundle[1].map((compactMeta) => {
1518
+ const cmpMeta = {
1519
+ $flags$: compactMeta[0],
1520
+ $tagName$: compactMeta[1],
1521
+ $members$: compactMeta[2],
1522
+ $listeners$: compactMeta[3],
1523
+ };
1524
+ {
1525
+ cmpMeta.$members$ = compactMeta[2];
1526
+ }
1527
+ {
1528
+ cmpMeta.$listeners$ = compactMeta[3];
1529
+ }
1530
+ {
1531
+ cmpMeta.$attrsToReflect$ = [];
1532
+ }
1533
+ {
1534
+ cmpMeta.$watchers$ = {};
1535
+ }
1536
+ const tagName = cmpMeta.$tagName$;
1537
+ const HostElement = class extends HTMLElement {
1538
+ // StencilLazyHost
1539
+ constructor(self) {
1540
+ // @ts-ignore
1541
+ super(self);
1542
+ self = this;
1543
+ registerHost(self, cmpMeta);
1544
+ if (cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */) {
1545
+ // this component is using shadow dom
1546
+ // and this browser supports shadow dom
1547
+ // add the read-only property "shadowRoot" to the host element
1548
+ // adding the shadow root build conditionals to minimize runtime
1241
1549
  {
1242
- self.attachShadow({ mode: 'open' });
1550
+ {
1551
+ self.attachShadow({ mode: 'open' });
1552
+ }
1243
1553
  }
1244
1554
  }
1245
1555
  }
1246
- }
1247
- connectedCallback() {
1248
- if (appLoadFallback) {
1249
- clearTimeout(appLoadFallback);
1250
- appLoadFallback = null;
1556
+ connectedCallback() {
1557
+ if (appLoadFallback) {
1558
+ clearTimeout(appLoadFallback);
1559
+ appLoadFallback = null;
1560
+ }
1561
+ if (isBootstrapping) {
1562
+ // connectedCallback will be processed once all components have been registered
1563
+ deferredConnectedCallbacks.push(this);
1564
+ }
1565
+ else {
1566
+ plt.jmp(() => connectedCallback(this));
1567
+ }
1251
1568
  }
1252
- if (isBootstrapping) {
1253
- // connectedCallback will be processed once all components have been registered
1254
- deferredConnectedCallbacks.push(this);
1569
+ disconnectedCallback() {
1570
+ plt.jmp(() => disconnectedCallback(this));
1255
1571
  }
1256
- else {
1257
- plt.jmp(() => connectedCallback(this));
1572
+ componentOnReady() {
1573
+ return getHostRef(this).$onReadyPromise$;
1258
1574
  }
1575
+ };
1576
+ cmpMeta.$lazyBundleId$ = lazyBundle[0];
1577
+ if (!exclude.includes(tagName) && !customElements.get(tagName)) {
1578
+ cmpTags.push(tagName);
1579
+ customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* PROXY_FLAGS.isElementConstructor */));
1259
1580
  }
1260
- disconnectedCallback() {
1261
- plt.jmp(() => disconnectedCallback(this));
1262
- }
1263
- componentOnReady() {
1264
- return getHostRef(this).$onReadyPromise$;
1265
- }
1266
- };
1267
- cmpMeta.$lazyBundleId$ = lazyBundle[0];
1268
- if (!exclude.includes(tagName) && !customElements.get(tagName)) {
1269
- cmpTags.push(tagName);
1270
- customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* isElementConstructor */));
1271
- }
1272
- }));
1581
+ });
1582
+ });
1273
1583
  {
1274
1584
  visibilityStyle.innerHTML = cmpTags + HYDRATED_CSS;
1275
1585
  visibilityStyle.setAttribute('data-styles', '');
1586
+ // Apply CSP nonce to the style tag if it exists
1587
+ const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
1588
+ if (nonce != null) {
1589
+ visibilityStyle.setAttribute('nonce', nonce);
1590
+ }
1276
1591
  head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
1277
1592
  }
1278
1593
  // Process deferred connectedCallbacks now all components have been registered
@@ -1289,7 +1604,48 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1289
1604
  endBootstrap();
1290
1605
  };
1291
1606
  const Fragment = (_, children) => children;
1292
- const hostRefs = new WeakMap();
1607
+ const addHostEventListeners = (elm, hostRef, listeners, attachParentListeners) => {
1608
+ if (listeners) {
1609
+ listeners.map(([flags, name, method]) => {
1610
+ const target = getHostListenerTarget(elm, flags) ;
1611
+ const handler = hostListenerProxy(hostRef, method);
1612
+ const opts = hostListenerOpts(flags);
1613
+ plt.ael(target, name, handler, opts);
1614
+ (hostRef.$rmListeners$ = hostRef.$rmListeners$ || []).push(() => plt.rel(target, name, handler, opts));
1615
+ });
1616
+ }
1617
+ };
1618
+ const hostListenerProxy = (hostRef, methodName) => (ev) => {
1619
+ try {
1620
+ {
1621
+ if (hostRef.$flags$ & 256 /* HOST_FLAGS.isListenReady */) {
1622
+ // instance is ready, let's call it's member method for this event
1623
+ hostRef.$lazyInstance$[methodName](ev);
1624
+ }
1625
+ else {
1626
+ (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
1627
+ }
1628
+ }
1629
+ }
1630
+ catch (e) {
1631
+ consoleError(e);
1632
+ }
1633
+ };
1634
+ const getHostListenerTarget = (elm, flags) => {
1635
+ if (flags & 16 /* LISTENER_FLAGS.TargetBody */)
1636
+ return doc.body;
1637
+ return elm;
1638
+ };
1639
+ // prettier-ignore
1640
+ const hostListenerOpts = (flags) => (flags & 2 /* LISTENER_FLAGS.Capture */) !== 0;
1641
+ /**
1642
+ * Assigns the given value to the nonce property on the runtime platform object.
1643
+ * During runtime, this value is used to set the nonce attribute on all dynamically created script and style tags.
1644
+ * @param nonce The value to be assigned to the platform nonce property.
1645
+ * @returns void
1646
+ */
1647
+ const setNonce = (nonce) => (plt.$nonce$ = nonce);
1648
+ const hostRefs = /*@__PURE__*/ new WeakMap();
1293
1649
  const getHostRef = (ref) => hostRefs.get(ref);
1294
1650
  const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
1295
1651
  const registerHost = (elm, cmpMeta) => {
@@ -1318,7 +1674,9 @@ const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
1318
1674
  if (module) {
1319
1675
  return module[exportName];
1320
1676
  }
1677
+ /*!__STENCIL_STATIC_IMPORT_SWITCH__*/
1321
1678
  return import(
1679
+ /* @vite-ignore */
1322
1680
  /* webpackInclude: /\.entry\.js$/ */
1323
1681
  /* webpackExclude: /\.system\.entry\.js$/ */
1324
1682
  /* webpackMode: "lazy" */
@@ -1329,14 +1687,35 @@ const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
1329
1687
  return importedModule[exportName];
1330
1688
  }, consoleError);
1331
1689
  };
1332
- const styles = new Map();
1690
+ const styles = /*@__PURE__*/ new Map();
1691
+ const win = typeof window !== 'undefined' ? window : {};
1692
+ const doc = win.document || { head: {} };
1693
+ const plt = {
1694
+ $flags$: 0,
1695
+ $resourcesUrl$: '',
1696
+ jmp: (h) => h(),
1697
+ raf: (h) => requestAnimationFrame(h),
1698
+ ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
1699
+ rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
1700
+ ce: (eventName, opts) => new CustomEvent(eventName, opts),
1701
+ };
1702
+ const promiseResolve = (v) => Promise.resolve(v);
1703
+ const supportsConstructableStylesheets = /*@__PURE__*/ (() => {
1704
+ try {
1705
+ new CSSStyleSheet();
1706
+ return typeof new CSSStyleSheet().replaceSync === 'function';
1707
+ }
1708
+ catch (e) { }
1709
+ return false;
1710
+ })()
1711
+ ;
1333
1712
  const queueDomReads = [];
1334
1713
  const queueDomWrites = [];
1335
1714
  const queueTask = (queue, write) => (cb) => {
1336
1715
  queue.push(cb);
1337
1716
  if (!queuePending) {
1338
1717
  queuePending = true;
1339
- if (write && plt.$flags$ & 4 /* queueSync */) {
1718
+ if (write && plt.$flags$ & 4 /* PLATFORM_FLAGS.queueSync */) {
1340
1719
  nextTick(flush);
1341
1720
  }
1342
1721
  else {
@@ -1373,4 +1752,4 @@ const flush = () => {
1373
1752
  const nextTick = /*@__PURE__*/ (cb) => promiseResolve().then(cb);
1374
1753
  const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
1375
1754
 
1376
- export { Fragment as F, Host as H, getRenderingRef as a, bootstrapLazy as b, createEvent as c, forceUpdate as f, getElement as g, h, promiseResolve as p, registerInstance as r };
1755
+ export { Fragment as F, Host as H, getRenderingRef as a, bootstrapLazy as b, createEvent as c, forceUpdate as f, getElement as g, h, promiseResolve as p, registerInstance as r, setNonce as s };