@xplortech/apollo-core 1.0.0-beta.6 → 1.0.0-beta.8

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 (138) hide show
  1. package/LICENSE +21 -0
  2. package/build/style.css +4 -55
  3. package/dist/apollo-core/apollo-core.css +5 -5
  4. package/dist/apollo-core/apollo-core.esm.js +1 -1
  5. package/dist/apollo-core/p-10f00380.entry.js +1 -0
  6. package/dist/apollo-core/p-26ec64fe.entry.js +1 -0
  7. package/dist/apollo-core/p-2f90296c.js +2 -2
  8. package/dist/apollo-core/p-31acfdb4.entry.js +1 -0
  9. package/dist/apollo-core/p-4184ac44.entry.js +1 -0
  10. package/dist/apollo-core/{p-dad11011.entry.js → p-4fa14839.entry.js} +1 -1
  11. package/dist/apollo-core/p-55b87345.js +2 -0
  12. package/dist/apollo-core/p-63a6c98a.entry.js +1 -0
  13. package/dist/apollo-core/p-68c33b77.entry.js +1 -0
  14. package/dist/apollo-core/{p-a7cc4114.entry.js → p-78d07caf.entry.js} +1 -1
  15. package/dist/apollo-core/p-796957d3.entry.js +1 -0
  16. package/dist/apollo-core/p-88160d68.entry.js +1 -0
  17. package/dist/apollo-core/p-9ec318bb.entry.js +1 -0
  18. package/dist/apollo-core/p-a2a34e44.entry.js +1 -0
  19. package/dist/apollo-core/p-beea2502.entry.js +1 -0
  20. package/dist/apollo-core/p-d499e43f.entry.js +1 -0
  21. package/dist/apollo-core/{p-c8af4ed6.entry.js → p-d8a3d94c.entry.js} +1 -1
  22. package/dist/apollo-core/p-e047b446.entry.js +1 -0
  23. package/dist/cjs/apollo-core.cjs.js +6 -2
  24. package/dist/cjs/{index-acf3dd7a.js → index-2ab4832e.js} +592 -215
  25. package/dist/cjs/loader.cjs.js +3 -2
  26. package/dist/cjs/xpl-application-shell.cjs.entry.js +2 -13
  27. package/dist/cjs/xpl-avatar_12.cjs.entry.js +72 -38
  28. package/dist/cjs/xpl-backdrop.cjs.entry.js +1 -5
  29. package/dist/cjs/xpl-button-row.cjs.entry.js +4 -1
  30. package/dist/cjs/xpl-choicelist.cjs.entry.js +8 -1
  31. package/dist/cjs/xpl-divider.cjs.entry.js +2 -1
  32. package/dist/cjs/xpl-dropdown-group_3.cjs.entry.js +7 -1
  33. package/dist/cjs/xpl-dropdown_2.cjs.entry.js +8 -9
  34. package/dist/cjs/xpl-grid-item.cjs.entry.js +1 -1
  35. package/dist/cjs/xpl-grid.cjs.entry.js +1 -1
  36. package/dist/cjs/xpl-input.cjs.entry.js +615 -501
  37. package/dist/cjs/xpl-list.cjs.entry.js +1 -23
  38. package/dist/cjs/xpl-main-nav.cjs.entry.js +1 -4
  39. package/dist/cjs/xpl-pagination.cjs.entry.js +5 -2
  40. package/dist/cjs/xpl-select.cjs.entry.js +7 -22
  41. package/dist/cjs/xpl-toggle.cjs.entry.js +7 -4
  42. package/dist/collection/collection-manifest.json +2 -2
  43. package/dist/collection/components/xpl-application-shell/xpl-application-shell.js +118 -132
  44. package/dist/collection/components/xpl-avatar/xpl-avatar.js +150 -144
  45. package/dist/collection/components/xpl-backdrop/xpl-backdrop.js +26 -28
  46. package/dist/collection/components/xpl-badge/xpl-badge.js +43 -39
  47. package/dist/collection/components/xpl-breadcrumbs/xpl-breadcrumb-item/xpl-breadcrumb-item.js +2 -5
  48. package/dist/collection/components/xpl-breadcrumbs/xpl-breadcrumbs/xpl-breadcrumbs.js +2 -5
  49. package/dist/collection/components/xpl-button/xpl-button.js +204 -205
  50. package/dist/collection/components/xpl-button-row/xpl-button-row.js +105 -104
  51. package/dist/collection/components/xpl-checkbox/xpl-checkbox.js +181 -171
  52. package/dist/collection/components/xpl-choicelist/xpl-choicelist.js +133 -126
  53. package/dist/collection/components/xpl-content-area/xpl-content-area.js +27 -31
  54. package/dist/collection/components/xpl-divider/xpl-divider.js +26 -23
  55. package/dist/collection/components/xpl-dropdown/xpl-dropdown-group/xpl-dropdown-group.js +46 -42
  56. package/dist/collection/components/xpl-dropdown/xpl-dropdown-heading/xpl-dropdown-heading.js +26 -22
  57. package/dist/collection/components/xpl-dropdown/xpl-dropdown-option/xpl-dropdown-option.js +60 -54
  58. package/dist/collection/components/xpl-dropdown/xpl-dropdown.js +170 -167
  59. package/dist/collection/components/xpl-grid/xpl-grid.js +1 -1
  60. package/dist/collection/components/xpl-grid-item/xpl-grid-item.js +75 -74
  61. package/dist/collection/components/xpl-input/xpl-input.js +404 -417
  62. package/dist/collection/components/xpl-list/xpl-list.js +42 -75
  63. package/dist/collection/components/xpl-main-nav/xpl-main-nav.js +47 -54
  64. package/dist/collection/components/xpl-nav-item/xpl-nav-item.js +47 -49
  65. package/dist/collection/components/xpl-pagination/xpl-pagination.js +116 -128
  66. package/dist/collection/components/xpl-radio/xpl-radio.js +157 -148
  67. package/dist/collection/components/xpl-secondary-nav/xpl-secondary-nav.js +2 -4
  68. package/dist/collection/components/xpl-select/xpl-select.js +212 -238
  69. package/dist/collection/components/xpl-table/xpl-table.js +168 -151
  70. package/dist/collection/components/xpl-tag/xpl-tag.js +24 -25
  71. package/dist/collection/components/xpl-toggle/xpl-toggle.js +137 -135
  72. package/dist/collection/components/xpl-utility-bar/xpl-utility-bar.js +73 -70
  73. package/dist/custom-elements/index.js +756 -641
  74. package/dist/esm/apollo-core.js +3 -2
  75. package/dist/esm/{index-e3c4bb97.js → index-392b5b96.js} +592 -216
  76. package/dist/esm/loader.js +3 -2
  77. package/dist/esm/polyfills/css-shim.js +1 -1
  78. package/dist/esm/xpl-application-shell.entry.js +2 -13
  79. package/dist/esm/xpl-avatar_12.entry.js +72 -38
  80. package/dist/esm/xpl-backdrop.entry.js +1 -5
  81. package/dist/esm/xpl-button-row.entry.js +4 -1
  82. package/dist/esm/xpl-choicelist.entry.js +8 -1
  83. package/dist/esm/xpl-divider.entry.js +2 -1
  84. package/dist/esm/xpl-dropdown-group_3.entry.js +7 -1
  85. package/dist/esm/xpl-dropdown_2.entry.js +8 -9
  86. package/dist/esm/xpl-grid-item.entry.js +1 -1
  87. package/dist/esm/xpl-grid.entry.js +1 -1
  88. package/dist/esm/xpl-input.entry.js +615 -501
  89. package/dist/esm/xpl-list.entry.js +1 -23
  90. package/dist/esm/xpl-main-nav.entry.js +1 -4
  91. package/dist/esm/xpl-pagination.entry.js +5 -2
  92. package/dist/esm/xpl-select.entry.js +7 -22
  93. package/dist/esm/xpl-toggle.entry.js +7 -4
  94. package/dist/types/components/xpl-dropdown/dropdownoption.d.ts +1 -1
  95. package/dist/types/components/xpl-table/xpl-table.d.ts +2 -0
  96. package/dist/types/components.d.ts +47 -11
  97. package/dist/types/stencil-public-runtime.d.ts +85 -11
  98. package/loader/index.d.ts +9 -1
  99. package/loader/package.json +1 -0
  100. package/package.json +1 -1
  101. package/dist/apollo-core/p-25f84d39.entry.js +0 -1
  102. package/dist/apollo-core/p-2ce2fe5c.entry.js +0 -1
  103. package/dist/apollo-core/p-3ff1ff38.entry.js +0 -1
  104. package/dist/apollo-core/p-63dd9a65.entry.js +0 -1
  105. package/dist/apollo-core/p-6c3c1e3d.entry.js +0 -1
  106. package/dist/apollo-core/p-81a6ce4c.entry.js +0 -1
  107. package/dist/apollo-core/p-918b0731.entry.js +0 -1
  108. package/dist/apollo-core/p-a43e2d1f.entry.js +0 -1
  109. package/dist/apollo-core/p-b6d1b135.entry.js +0 -1
  110. package/dist/apollo-core/p-bc0ebed2.entry.js +0 -1
  111. package/dist/apollo-core/p-d4aa2fa9.js +0 -1
  112. package/dist/apollo-core/p-d4e5d3aa.entry.js +0 -1
  113. package/dist/apollo-core/p-db74c99c.entry.js +0 -1
  114. package/dist/apollo-core/p-ee16942f.entry.js +0 -1
  115. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/application-shell.stories.d.ts +0 -0
  116. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/avatar.stories.d.ts +0 -0
  117. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/backdrop.stories.d.ts +0 -0
  118. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/badge.stories.d.ts +0 -0
  119. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/breadcrumbs.stories.d.ts +0 -0
  120. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/button-row.stories.d.ts +0 -0
  121. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/button.stories.d.ts +0 -0
  122. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/checkbox.stories.d.ts +0 -0
  123. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/choicelist.stories.d.ts +0 -0
  124. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/content-area.stories.d.ts +0 -0
  125. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/divider.stories.d.ts +0 -0
  126. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/dropdown.stories.d.ts +0 -0
  127. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/grid.stories.d.ts +0 -0
  128. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/input.stories.d.ts +0 -0
  129. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/list.stories.d.ts +0 -0
  130. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/main-nav.stories.d.ts +0 -0
  131. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/pagination.stories.d.ts +0 -0
  132. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/radio.stories.d.ts +0 -0
  133. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/secondary-nav.stories.d.ts +0 -0
  134. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/select.stories.d.ts +0 -0
  135. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/table.stories.d.ts +0 -0
  136. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/tabs.stories.d.ts +0 -0
  137. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/toggle.stories.d.ts +0 -0
  138. /package/dist/types/Users/{roc/Sites → fernandogelin/Xplor}/apollo/.stencil/stories/utility-bar.stories.d.ts +0 -0
@@ -1,5 +1,13 @@
1
1
  const NAMESPACE = 'apollo-core';
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 contentRef;
4
12
  let hostTagName;
5
13
  let useNativeShadowDom = false;
@@ -7,54 +15,6 @@ let checkSlotFallbackVisibility = false;
7
15
  let checkSlotRelocate = false;
8
16
  let isSvgMode = false;
9
17
  let queuePending = false;
10
- const win = typeof window !== 'undefined' ? window : {};
11
- const doc = win.document || { head: {} };
12
- const plt = {
13
- $flags$: 0,
14
- $resourcesUrl$: '',
15
- jmp: (h) => h(),
16
- raf: (h) => requestAnimationFrame(h),
17
- ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
18
- rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
19
- ce: (eventName, opts) => new CustomEvent(eventName, opts),
20
- };
21
- const promiseResolve = (v) => Promise.resolve(v);
22
- const addHostEventListeners = (elm, hostRef, listeners, attachParentListeners) => {
23
- if (listeners) {
24
- listeners.map(([flags, name, method]) => {
25
- const target = getHostListenerTarget(elm, flags) ;
26
- const handler = hostListenerProxy(hostRef, method);
27
- const opts = hostListenerOpts(flags);
28
- plt.ael(target, name, handler, opts);
29
- (hostRef.$rmListeners$ = hostRef.$rmListeners$ || []).push(() => plt.rel(target, name, handler, opts));
30
- });
31
- }
32
- };
33
- const hostListenerProxy = (hostRef, methodName) => (ev) => {
34
- try {
35
- {
36
- if (hostRef.$flags$ & 256 /* isListenReady */) {
37
- // instance is ready, let's call it's member method for this event
38
- hostRef.$lazyInstance$[methodName](ev);
39
- }
40
- else {
41
- (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
42
- }
43
- }
44
- }
45
- catch (e) {
46
- consoleError(e);
47
- }
48
- };
49
- const getHostListenerTarget = (elm, flags) => {
50
- if (flags & 8 /* TargetWindow */)
51
- return win;
52
- return elm;
53
- };
54
- // prettier-ignore
55
- const hostListenerOpts = (flags) => (flags & 2 /* Capture */) !== 0;
56
- const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
57
- const XLINK_NS = 'http://www.w3.org/1999/xlink';
58
18
  const createTime = (fnName, tagName = '') => {
59
19
  {
60
20
  return () => {
@@ -69,6 +29,8 @@ const uniqueTime = (key, measureText) => {
69
29
  };
70
30
  }
71
31
  };
32
+ const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
33
+ const XLINK_NS = 'http://www.w3.org/1999/xlink';
72
34
  /**
73
35
  * Default style mode id
74
36
  */
@@ -87,6 +49,18 @@ const isComplexType = (o) => {
87
49
  o = typeof o;
88
50
  return o === 'object' || o === 'function';
89
51
  };
52
+ /**
53
+ * Helper method for querying a `meta` tag that contains a nonce value
54
+ * out of a DOM's head.
55
+ *
56
+ * @param doc The DOM containing the `head` to query against
57
+ * @returns The content of the meta tag representing the nonce value, or `undefined` if no tag
58
+ * exists or the tag has no content.
59
+ */
60
+ function queryNonceMetaTagContent(doc) {
61
+ var _a, _b, _c;
62
+ 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;
63
+ }
90
64
  /**
91
65
  * Production h() function based on Preact by
92
66
  * Jason Miller (@developit)
@@ -95,7 +69,6 @@ const isComplexType = (o) => {
95
69
  *
96
70
  * Modified for Stencil's compiler and vdom
97
71
  */
98
- // const stack: any[] = [];
99
72
  // export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, child?: d.ChildType): d.VNode;
100
73
  // export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
101
74
  const h = (nodeName, vnodeData, ...children) => {
@@ -104,7 +77,7 @@ const h = (nodeName, vnodeData, ...children) => {
104
77
  let slotName = null;
105
78
  let simple = false;
106
79
  let lastSimple = false;
107
- let vNodeChildren = [];
80
+ const vNodeChildren = [];
108
81
  const walk = (c) => {
109
82
  for (let i = 0; i < c.length; i++) {
110
83
  child = c[i];
@@ -165,6 +138,14 @@ const h = (nodeName, vnodeData, ...children) => {
165
138
  }
166
139
  return vnode;
167
140
  };
141
+ /**
142
+ * A utility function for creating a virtual DOM node from a tag and some
143
+ * possible text content.
144
+ *
145
+ * @param tag the tag for this element
146
+ * @param text possible text content for the node
147
+ * @returns a newly-minted virtual DOM node
148
+ */
168
149
  const newVNode = (tag, text) => {
169
150
  const vnode = {
170
151
  $flags$: 0,
@@ -185,11 +166,31 @@ const newVNode = (tag, text) => {
185
166
  return vnode;
186
167
  };
187
168
  const Host = {};
169
+ /**
170
+ * Check whether a given node is a Host node or not
171
+ *
172
+ * @param node the virtual DOM node to check
173
+ * @returns whether it's a Host node or not
174
+ */
188
175
  const isHost = (node) => node && node.$tag$ === Host;
176
+ /**
177
+ * Implementation of {@link d.FunctionalUtilities} for Stencil's VDom.
178
+ *
179
+ * Note that these functions convert from {@link d.VNode} to
180
+ * {@link d.ChildNode} to give functional component developers a friendly
181
+ * interface.
182
+ */
189
183
  const vdomFnUtils = {
190
184
  forEach: (children, cb) => children.map(convertToPublic).forEach(cb),
191
185
  map: (children, cb) => children.map(convertToPublic).map(cb).map(convertToPrivate),
192
186
  };
187
+ /**
188
+ * Convert a {@link d.VNode} to a {@link d.ChildNode} in order to present a
189
+ * friendlier public interface (hence, 'convertToPublic').
190
+ *
191
+ * @param node the virtual DOM node to convert
192
+ * @returns a converted child node
193
+ */
193
194
  const convertToPublic = (node) => ({
194
195
  vattrs: node.$attrs$,
195
196
  vchildren: node.$children$,
@@ -198,6 +199,15 @@ const convertToPublic = (node) => ({
198
199
  vtag: node.$tag$,
199
200
  vtext: node.$text$,
200
201
  });
202
+ /**
203
+ * Convert a {@link d.ChildNode} back to an equivalent {@link d.VNode} in
204
+ * order to use the resulting object in the virtual DOM. The initial object was
205
+ * likely created as part of presenting a public API, so converting it back
206
+ * involved making it 'private' again (hence, `convertToPrivate`).
207
+ *
208
+ * @param node the child node to convert
209
+ * @returns a converted virtual DOM node
210
+ */
201
211
  const convertToPrivate = (node) => {
202
212
  if (typeof node.vtag === 'function') {
203
213
  const vnodeData = Object.assign({}, node.vattrs);
@@ -216,6 +226,79 @@ const convertToPrivate = (node) => {
216
226
  vnode.$name$ = node.vname;
217
227
  return vnode;
218
228
  };
229
+ /**
230
+ * Parse a new property value for a given property type.
231
+ *
232
+ * While the prop value can reasonably be expected to be of `any` type as far as TypeScript's type checker is concerned,
233
+ * it is not safe to assume that the string returned by evaluating `typeof propValue` matches:
234
+ * 1. `any`, the type given to `propValue` in the function signature
235
+ * 2. the type stored from `propType`.
236
+ *
237
+ * This function provides the capability to parse/coerce a property's value to potentially any other JavaScript type.
238
+ *
239
+ * Property values represented in TSX preserve their type information. In the example below, the number 0 is passed to
240
+ * a component. This `propValue` will preserve its type information (`typeof propValue === 'number'`). Note that is
241
+ * based on the type of the value being passed in, not the type declared of the class member decorated with `@Prop`.
242
+ * ```tsx
243
+ * <my-cmp prop-val={0}></my-cmp>
244
+ * ```
245
+ *
246
+ * HTML prop values on the other hand, will always a string
247
+ *
248
+ * @param propValue the new value to coerce to some type
249
+ * @param propType the type of the prop, expressed as a binary number
250
+ * @returns the parsed/coerced value
251
+ */
252
+ const parsePropertyValue = (propValue, propType) => {
253
+ // ensure this value is of the correct prop type
254
+ if (propValue != null && !isComplexType(propValue)) {
255
+ if (propType & 4 /* MEMBER_FLAGS.Boolean */) {
256
+ // per the HTML spec, any string value means it is a boolean true value
257
+ // but we'll cheat here and say that the string "false" is the boolean false
258
+ return propValue === 'false' ? false : propValue === '' || !!propValue;
259
+ }
260
+ if (propType & 2 /* MEMBER_FLAGS.Number */) {
261
+ // force it to be a number
262
+ return parseFloat(propValue);
263
+ }
264
+ if (propType & 1 /* MEMBER_FLAGS.String */) {
265
+ // could have been passed as a number or boolean
266
+ // but we still want it as a string
267
+ return String(propValue);
268
+ }
269
+ // redundant return here for better minification
270
+ return propValue;
271
+ }
272
+ // not sure exactly what type we want
273
+ // so no need to change to a different type
274
+ return propValue;
275
+ };
276
+ const getElement = (ref) => (getHostRef(ref).$hostElement$ );
277
+ const createEvent = (ref, name, flags) => {
278
+ const elm = getElement(ref);
279
+ return {
280
+ emit: (detail) => {
281
+ return emitEvent(elm, name, {
282
+ bubbles: !!(flags & 4 /* EVENT_FLAGS.Bubbles */),
283
+ composed: !!(flags & 2 /* EVENT_FLAGS.Composed */),
284
+ cancelable: !!(flags & 1 /* EVENT_FLAGS.Cancellable */),
285
+ detail,
286
+ });
287
+ },
288
+ };
289
+ };
290
+ /**
291
+ * Helper function to create & dispatch a custom Event on a provided target
292
+ * @param elm the target of the Event
293
+ * @param name the name to give the custom Event
294
+ * @param opts options for configuring a custom Event
295
+ * @returns the custom Event
296
+ */
297
+ const emitEvent = (elm, name, opts) => {
298
+ const ev = plt.ce(name, opts);
299
+ elm.dispatchEvent(ev);
300
+ return ev;
301
+ };
219
302
  /**
220
303
  * Production setAccessor() function based on Preact by
221
304
  * Jason Miller (@developit)
@@ -313,11 +396,10 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
313
396
  if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
314
397
  try {
315
398
  if (!elm.tagName.includes('-')) {
316
- let n = newValue == null ? '' : newValue;
399
+ const n = newValue == null ? '' : newValue;
317
400
  // Workaround for Safari, moving the <input> caret when re-assigning the same valued
318
401
  if (memberName === 'list') {
319
402
  isProp = false;
320
- // tslint:disable-next-line: triple-equals
321
403
  }
322
404
  else if (oldValue == null || elm[memberName] != n) {
323
405
  elm[memberName] = n;
@@ -353,7 +435,7 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
353
435
  }
354
436
  }
355
437
  }
356
- else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex) {
438
+ else if ((!isProp || flags & 4 /* VNODE_FLAGS.isHost */ || isSvg) && !isComplex) {
357
439
  newValue = newValue === true ? '' : newValue;
358
440
  if (xlink) {
359
441
  elm.setAttributeNS(XLINK_NS, memberName, newValue);
@@ -371,7 +453,7 @@ const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
371
453
  // if the element passed in is a shadow root, which is a document fragment
372
454
  // then we want to be adding attrs/props to the shadow root's "host" element
373
455
  // if it's not a shadow root, then we add attrs/props to the same element
374
- const elm = newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host
456
+ const elm = newVnode.$elm$.nodeType === 11 /* NODE_TYPE.DocumentFragment */ && newVnode.$elm$.host
375
457
  ? newVnode.$elm$.host
376
458
  : newVnode.$elm$;
377
459
  const oldVnodeAttrs = (oldVnode && oldVnode.$attrs$) || EMPTY_OBJ;
@@ -389,9 +471,19 @@ const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
389
471
  setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode, newVnode.$flags$);
390
472
  }
391
473
  };
474
+ /**
475
+ * Create a DOM Node corresponding to one of the children of a given VNode.
476
+ *
477
+ * @param oldParentVNode the parent VNode from the previous render
478
+ * @param newParentVNode the parent VNode from the current render
479
+ * @param childIndex the index of the VNode, in the _new_ parent node's
480
+ * children, for which we will create a new DOM node
481
+ * @param parentElm the parent DOM node which our new node will be a child of
482
+ * @returns the newly created node
483
+ */
392
484
  const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
393
485
  // tslint:disable-next-line: prefer-const
394
- let newVNode = newParentVNode.$children$[childIndex];
486
+ const newVNode = newParentVNode.$children$[childIndex];
395
487
  let i = 0;
396
488
  let elm;
397
489
  let childNode;
@@ -402,16 +494,16 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
402
494
  if (newVNode.$tag$ === 'slot') {
403
495
  newVNode.$flags$ |= newVNode.$children$
404
496
  ? // slot element has fallback content
405
- 2 /* isSlotFallback */
497
+ 2 /* VNODE_FLAGS.isSlotFallback */
406
498
  : // slot element does not have fallback content
407
- 1 /* isSlotReference */;
499
+ 1 /* VNODE_FLAGS.isSlotReference */;
408
500
  }
409
501
  }
410
502
  if (newVNode.$text$ !== null) {
411
503
  // create text node
412
504
  elm = newVNode.$elm$ = doc.createTextNode(newVNode.$text$);
413
505
  }
414
- else if (newVNode.$flags$ & 1 /* isSlotReference */) {
506
+ else if (newVNode.$flags$ & 1 /* VNODE_FLAGS.isSlotReference */) {
415
507
  // create a slot reference node
416
508
  elm = newVNode.$elm$ =
417
509
  doc.createTextNode('');
@@ -421,7 +513,7 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
421
513
  isSvgMode = newVNode.$tag$ === 'svg';
422
514
  }
423
515
  // create element
424
- elm = newVNode.$elm$ = (doc.createElementNS(isSvgMode ? SVG_NS : HTML_NS, newVNode.$flags$ & 2 /* isSlotFallback */
516
+ elm = newVNode.$elm$ = (doc.createElementNS(isSvgMode ? SVG_NS : HTML_NS, newVNode.$flags$ & 2 /* VNODE_FLAGS.isSlotFallback */
425
517
  ? 'slot-fb'
426
518
  : newVNode.$tag$)
427
519
  );
@@ -456,7 +548,7 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
456
548
  }
457
549
  {
458
550
  elm['s-hn'] = hostTagName;
459
- if (newVNode.$flags$ & (2 /* isSlotFallback */ | 1 /* isSlotReference */)) {
551
+ if (newVNode.$flags$ & (2 /* VNODE_FLAGS.isSlotFallback */ | 1 /* VNODE_FLAGS.isSlotReference */)) {
460
552
  // remember the content reference comment
461
553
  elm['s-sr'] = true;
462
554
  // remember the content reference comment
@@ -475,7 +567,7 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
475
567
  return elm;
476
568
  };
477
569
  const putBackInOriginalLocation = (parentElm, recursive) => {
478
- plt.$flags$ |= 1 /* isTmpDisconnected */;
570
+ plt.$flags$ |= 1 /* PLATFORM_FLAGS.isTmpDisconnected */;
479
571
  const oldSlotChildNodes = parentElm.childNodes;
480
572
  for (let i = oldSlotChildNodes.length - 1; i >= 0; i--) {
481
573
  const childNode = oldSlotChildNodes[i];
@@ -496,8 +588,23 @@ const putBackInOriginalLocation = (parentElm, recursive) => {
496
588
  putBackInOriginalLocation(childNode, recursive);
497
589
  }
498
590
  }
499
- plt.$flags$ &= ~1 /* isTmpDisconnected */;
591
+ plt.$flags$ &= ~1 /* PLATFORM_FLAGS.isTmpDisconnected */;
500
592
  };
593
+ /**
594
+ * Create DOM nodes corresponding to a list of {@link d.Vnode} objects and
595
+ * add them to the DOM in the appropriate place.
596
+ *
597
+ * @param parentElm the DOM node which should be used as a parent for the new
598
+ * DOM nodes
599
+ * @param before a child of the `parentElm` which the new children should be
600
+ * inserted before (optional)
601
+ * @param parentVNode the parent virtual DOM node
602
+ * @param vnodes the new child virtual DOM nodes to produce DOM nodes for
603
+ * @param startIdx the index in the child virtual DOM nodes at which to start
604
+ * creating DOM nodes (inclusive)
605
+ * @param endIdx the index in the child virtual DOM nodes at which to stop
606
+ * creating DOM nodes (inclusive)
607
+ */
501
608
  const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
502
609
  let containerElm = ((parentElm['s-cr'] && parentElm['s-cr'].parentNode) || parentElm);
503
610
  let childNode;
@@ -511,6 +618,19 @@ const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) =>
511
618
  }
512
619
  }
513
620
  };
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
+ * @param vnode a VNode
632
+ * @param elm an element
633
+ */
514
634
  const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
515
635
  for (; startIdx <= endIdx; ++startIdx) {
516
636
  if ((vnode = vnodes[startIdx])) {
@@ -535,6 +655,74 @@ const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
535
655
  }
536
656
  }
537
657
  };
658
+ /**
659
+ * Reconcile the children of a new VNode with the children of an old VNode by
660
+ * traversing the two collections of children, identifying nodes that are
661
+ * conserved or changed, calling out to `patch` to make any necessary
662
+ * updates to the DOM, and rearranging DOM nodes as needed.
663
+ *
664
+ * The algorithm for reconciling children works by analyzing two 'windows' onto
665
+ * the two arrays of children (`oldCh` and `newCh`). We keep track of the
666
+ * 'windows' by storing start and end indices and references to the
667
+ * corresponding array entries. Initially the two 'windows' are basically equal
668
+ * to the entire array, but we progressively narrow the windows until there are
669
+ * no children left to update by doing the following:
670
+ *
671
+ * 1. Skip any `null` entries at the beginning or end of the two arrays, so
672
+ * that if we have an initial array like the following we'll end up dealing
673
+ * only with a window bounded by the highlighted elements:
674
+ *
675
+ * [null, null, VNode1 , ... , VNode2, null, null]
676
+ * ^^^^^^ ^^^^^^
677
+ *
678
+ * 2. Check to see if the elements at the head and tail positions are equal
679
+ * across the windows. This will basically detect elements which haven't
680
+ * been added, removed, or changed position, i.e. if you had the following
681
+ * VNode elements (represented as HTML):
682
+ *
683
+ * oldVNode: `<div><p><span>HEY</span></p></div>`
684
+ * newVNode: `<div><p><span>THERE</span></p></div>`
685
+ *
686
+ * Then when comparing the children of the `<div>` tag we check the equality
687
+ * of the VNodes corresponding to the `<p>` tags and, since they are the
688
+ * same tag in the same position, we'd be able to avoid completely
689
+ * re-rendering the subtree under them with a new DOM element and would just
690
+ * call out to `patch` to handle reconciling their children and so on.
691
+ *
692
+ * 3. Check, for both windows, to see if the element at the beginning of the
693
+ * window corresponds to the element at the end of the other window. This is
694
+ * a heuristic which will let us identify _some_ situations in which
695
+ * elements have changed position, for instance it _should_ detect that the
696
+ * children nodes themselves have not changed but merely moved in the
697
+ * following example:
698
+ *
699
+ * oldVNode: `<div><element-one /><element-two /></div>`
700
+ * newVNode: `<div><element-two /><element-one /></div>`
701
+ *
702
+ * If we find cases like this then we also need to move the concrete DOM
703
+ * elements corresponding to the moved children to write the re-order to the
704
+ * DOM.
705
+ *
706
+ * 4. Finally, if VNodes have the `key` attribute set on them we check for any
707
+ * nodes in the old children which have the same key as the first element in
708
+ * our window on the new children. If we find such a node we handle calling
709
+ * out to `patch`, moving relevant DOM nodes, and so on, in accordance with
710
+ * what we find.
711
+ *
712
+ * Finally, once we've narrowed our 'windows' to the point that either of them
713
+ * collapse (i.e. they have length 0) we then handle any remaining VNode
714
+ * insertion or deletion that needs to happen to get a DOM state that correctly
715
+ * reflects the new child VNodes. If, for instance, after our window on the old
716
+ * children has collapsed we still have more nodes on the new children that
717
+ * we haven't dealt with yet then we need to add them, or if the new children
718
+ * collapse but we still have unhandled _old_ children then we need to make
719
+ * sure the corresponding DOM nodes are removed.
720
+ *
721
+ * @param parentElm the node into which the parent VNode is rendered
722
+ * @param oldCh the old children of the parent node
723
+ * @param newVNode the new VNode which will replace the parent
724
+ * @param newCh the new children of the parent node
725
+ */
538
726
  const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
539
727
  let oldStartIdx = 0;
540
728
  let newStartIdx = 0;
@@ -550,7 +738,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
550
738
  let elmToMove;
551
739
  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
552
740
  if (oldStartVnode == null) {
553
- // Vnode might have been moved left
741
+ // VNode might have been moved left
554
742
  oldStartVnode = oldCh[++oldStartIdx];
555
743
  }
556
744
  else if (oldEndVnode == null) {
@@ -563,37 +751,100 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
563
751
  newEndVnode = newCh[--newEndIdx];
564
752
  }
565
753
  else if (isSameVnode(oldStartVnode, newStartVnode)) {
754
+ // if the start nodes are the same then we should patch the new VNode
755
+ // onto the old one, and increment our `newStartIdx` and `oldStartIdx`
756
+ // indices to reflect that. We don't need to move any DOM Nodes around
757
+ // since things are matched up in order.
566
758
  patch(oldStartVnode, newStartVnode);
567
759
  oldStartVnode = oldCh[++oldStartIdx];
568
760
  newStartVnode = newCh[++newStartIdx];
569
761
  }
570
762
  else if (isSameVnode(oldEndVnode, newEndVnode)) {
763
+ // likewise, if the end nodes are the same we patch new onto old and
764
+ // decrement our end indices, and also likewise in this case we don't
765
+ // need to move any DOM Nodes.
571
766
  patch(oldEndVnode, newEndVnode);
572
767
  oldEndVnode = oldCh[--oldEndIdx];
573
768
  newEndVnode = newCh[--newEndIdx];
574
769
  }
575
770
  else if (isSameVnode(oldStartVnode, newEndVnode)) {
576
- // Vnode moved right
771
+ // case: "Vnode moved right"
772
+ //
773
+ // We've found that the last node in our window on the new children is
774
+ // the same VNode as the _first_ node in our window on the old children
775
+ // we're dealing with now. Visually, this is the layout of these two
776
+ // nodes:
777
+ //
778
+ // newCh: [..., newStartVnode , ... , newEndVnode , ...]
779
+ // ^^^^^^^^^^^
780
+ // oldCh: [..., oldStartVnode , ... , oldEndVnode , ...]
781
+ // ^^^^^^^^^^^^^
782
+ //
783
+ // In this situation we need to patch `newEndVnode` onto `oldStartVnode`
784
+ // and move the DOM element for `oldStartVnode`.
577
785
  if ((oldStartVnode.$tag$ === 'slot' || newEndVnode.$tag$ === 'slot')) {
578
786
  putBackInOriginalLocation(oldStartVnode.$elm$.parentNode, false);
579
787
  }
580
788
  patch(oldStartVnode, newEndVnode);
789
+ // We need to move the element for `oldStartVnode` into a position which
790
+ // will be appropriate for `newEndVnode`. For this we can use
791
+ // `.insertBefore` and `oldEndVnode.$elm$.nextSibling`. If there is a
792
+ // sibling for `oldEndVnode.$elm$` then we want to move the DOM node for
793
+ // `oldStartVnode` between `oldEndVnode` and it's sibling, like so:
794
+ //
795
+ // <old-start-node />
796
+ // <some-intervening-node />
797
+ // <old-end-node />
798
+ // <!-- -> <-- `oldStartVnode.$elm$` should be inserted here
799
+ // <next-sibling />
800
+ //
801
+ // If instead `oldEndVnode.$elm$` has no sibling then we just want to put
802
+ // the node for `oldStartVnode` at the end of the children of
803
+ // `parentElm`. Luckily, `Node.nextSibling` will return `null` if there
804
+ // aren't any siblings, and passing `null` to `Node.insertBefore` will
805
+ // append it to the children of the parent element.
581
806
  parentElm.insertBefore(oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
582
807
  oldStartVnode = oldCh[++oldStartIdx];
583
808
  newEndVnode = newCh[--newEndIdx];
584
809
  }
585
810
  else if (isSameVnode(oldEndVnode, newStartVnode)) {
586
- // Vnode moved left
811
+ // case: "Vnode moved left"
812
+ //
813
+ // We've found that the first node in our window on the new children is
814
+ // the same VNode as the _last_ node in our window on the old children.
815
+ // Visually, this is the layout of these two nodes:
816
+ //
817
+ // newCh: [..., newStartVnode , ... , newEndVnode , ...]
818
+ // ^^^^^^^^^^^^^
819
+ // oldCh: [..., oldStartVnode , ... , oldEndVnode , ...]
820
+ // ^^^^^^^^^^^
821
+ //
822
+ // In this situation we need to patch `newStartVnode` onto `oldEndVnode`
823
+ // (which will handle updating any changed attributes, reconciling their
824
+ // children etc) but we also need to move the DOM node to which
825
+ // `oldEndVnode` corresponds.
587
826
  if ((oldStartVnode.$tag$ === 'slot' || newEndVnode.$tag$ === 'slot')) {
588
827
  putBackInOriginalLocation(oldEndVnode.$elm$.parentNode, false);
589
828
  }
590
829
  patch(oldEndVnode, newStartVnode);
830
+ // We've already checked above if `oldStartVnode` and `newStartVnode` are
831
+ // the same node, so since we're here we know that they are not. Thus we
832
+ // can move the element for `oldEndVnode` _before_ the element for
833
+ // `oldStartVnode`, leaving `oldStartVnode` to be reconciled in the
834
+ // future.
591
835
  parentElm.insertBefore(oldEndVnode.$elm$, oldStartVnode.$elm$);
592
836
  oldEndVnode = oldCh[--oldEndIdx];
593
837
  newStartVnode = newCh[++newStartIdx];
594
838
  }
595
839
  else {
596
- // createKeyToOldIdx
840
+ // Here we do some checks to match up old and new nodes based on the
841
+ // `$key$` attribute, which is set by putting a `key="my-key"` attribute
842
+ // in the JSX for a DOM element in the implementation of a Stencil
843
+ // component.
844
+ //
845
+ // First we check to see if there are any nodes in the array of old
846
+ // children which have the same key as the first node in the new
847
+ // children.
597
848
  idxInOld = -1;
598
849
  {
599
850
  for (i = oldStartIdx; i <= oldEndIdx; ++i) {
@@ -604,23 +855,32 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
604
855
  }
605
856
  }
606
857
  if (idxInOld >= 0) {
858
+ // We found a node in the old children which matches up with the first
859
+ // node in the new children! So let's deal with that
607
860
  elmToMove = oldCh[idxInOld];
608
861
  if (elmToMove.$tag$ !== newStartVnode.$tag$) {
862
+ // the tag doesn't match so we'll need a new DOM element
609
863
  node = createElm(oldCh && oldCh[newStartIdx], newVNode, idxInOld);
610
864
  }
611
865
  else {
612
866
  patch(elmToMove, newStartVnode);
867
+ // invalidate the matching old node so that we won't try to update it
868
+ // again later on
613
869
  oldCh[idxInOld] = undefined;
614
870
  node = elmToMove.$elm$;
615
871
  }
616
872
  newStartVnode = newCh[++newStartIdx];
617
873
  }
618
874
  else {
619
- // new element
875
+ // We either didn't find an element in the old children that matches
876
+ // the key of the first new child OR the build is not using `key`
877
+ // attributes at all. In either case we need to create a new element
878
+ // for the new node.
620
879
  node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx);
621
880
  newStartVnode = newCh[++newStartIdx];
622
881
  }
623
882
  if (node) {
883
+ // if we created a new node then handle inserting it to the DOM
624
884
  {
625
885
  parentReferenceNode(oldStartVnode.$elm$).insertBefore(node, referenceNode(oldStartVnode.$elm$));
626
886
  }
@@ -628,21 +888,44 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
628
888
  }
629
889
  }
630
890
  if (oldStartIdx > oldEndIdx) {
891
+ // we have some more new nodes to add which don't match up with old nodes
631
892
  addVnodes(parentElm, newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$, newVNode, newCh, newStartIdx, newEndIdx);
632
893
  }
633
894
  else if (newStartIdx > newEndIdx) {
895
+ // there are nodes in the `oldCh` array which no longer correspond to nodes
896
+ // in the new array, so lets remove them (which entails cleaning up the
897
+ // relevant DOM nodes)
634
898
  removeVnodes(oldCh, oldStartIdx, oldEndIdx);
635
899
  }
636
900
  };
637
- const isSameVnode = (vnode1, vnode2) => {
901
+ /**
902
+ * Compare two VNodes to determine if they are the same
903
+ *
904
+ * **NB**: This function is an equality _heuristic_ based on the available
905
+ * information set on the two VNodes and can be misleading under certain
906
+ * circumstances. In particular, if the two nodes do not have `key` attrs
907
+ * (available under `$key$` on VNodes) then the function falls back on merely
908
+ * checking that they have the same tag.
909
+ *
910
+ * So, in other words, if `key` attrs are not set on VNodes which may be
911
+ * changing order within a `children` array or something along those lines then
912
+ * we could obtain a false negative and then have to do needless re-rendering
913
+ * (i.e. we'd say two VNodes aren't equal when in fact they should be).
914
+ *
915
+ * @param leftVNode the first VNode to check
916
+ * @param rightVNode the second VNode to check
917
+ * @returns whether they're equal or not
918
+ */
919
+ const isSameVnode = (leftVNode, rightVNode) => {
638
920
  // compare if two vnode to see if they're "technically" the same
639
921
  // need to have the same element tag, and same key to be the same
640
- if (vnode1.$tag$ === vnode2.$tag$) {
641
- if (vnode1.$tag$ === 'slot') {
642
- return vnode1.$name$ === vnode2.$name$;
922
+ if (leftVNode.$tag$ === rightVNode.$tag$) {
923
+ if (leftVNode.$tag$ === 'slot') {
924
+ return leftVNode.$name$ === rightVNode.$name$;
643
925
  }
926
+ // this will be set if components in the build have `key` attrs set on them
644
927
  {
645
- return vnode1.$key$ === vnode2.$key$;
928
+ return leftVNode.$key$ === rightVNode.$key$;
646
929
  }
647
930
  }
648
931
  return false;
@@ -655,6 +938,14 @@ const referenceNode = (node) => {
655
938
  return (node && node['s-ol']) || node;
656
939
  };
657
940
  const parentReferenceNode = (node) => (node['s-ol'] ? node['s-ol'] : node).parentNode;
941
+ /**
942
+ * Handle reconciling an outdated VNode with a new one which corresponds to
943
+ * it. This function handles flushing updates to the DOM and reconciling the
944
+ * children of the two nodes (if any).
945
+ *
946
+ * @param oldVNode an old VNode whose DOM element and children we want to update
947
+ * @param newVNode a new VNode representing an updated version of the old one
948
+ */
658
949
  const patch = (oldVNode, newVNode) => {
659
950
  const elm = (newVNode.$elm$ = oldVNode.$elm$);
660
951
  const oldChildren = oldVNode.$children$;
@@ -668,7 +959,6 @@ const patch = (oldVNode, newVNode) => {
668
959
  // only add this to the when the compiler sees we're using an svg somewhere
669
960
  isSvgMode = tag === 'svg' ? true : tag === 'foreignObject' ? false : isSvgMode;
670
961
  }
671
- // element node
672
962
  {
673
963
  if (tag === 'slot')
674
964
  ;
@@ -681,6 +971,7 @@ const patch = (oldVNode, newVNode) => {
681
971
  }
682
972
  if (oldChildren !== null && newChildren !== null) {
683
973
  // looks like there's child vnodes for both the old and new vnodes
974
+ // so we need to call `updateChildren` to reconcile them
684
975
  updateChildren(elm, oldChildren, newVNode, newChildren);
685
976
  }
686
977
  else if (newChildren !== null) {
@@ -712,7 +1003,7 @@ const patch = (oldVNode, newVNode) => {
712
1003
  };
713
1004
  const updateFallbackSlotVisibility = (elm) => {
714
1005
  // tslint:disable-next-line: prefer-const
715
- let childNodes = elm.childNodes;
1006
+ const childNodes = elm.childNodes;
716
1007
  let childNode;
717
1008
  let i;
718
1009
  let ilen;
@@ -721,7 +1012,7 @@ const updateFallbackSlotVisibility = (elm) => {
721
1012
  let nodeType;
722
1013
  for (i = 0, ilen = childNodes.length; i < ilen; i++) {
723
1014
  childNode = childNodes[i];
724
- if (childNode.nodeType === 1 /* ElementNode */) {
1015
+ if (childNode.nodeType === 1 /* NODE_TYPE.ElementNode */) {
725
1016
  if (childNode['s-sr']) {
726
1017
  // this is a slot fallback node
727
1018
  // get the slot name for this slot reference node
@@ -733,7 +1024,7 @@ const updateFallbackSlotVisibility = (elm) => {
733
1024
  nodeType = childNodes[j].nodeType;
734
1025
  if (childNodes[j]['s-hn'] !== childNode['s-hn'] || slotNameAttr !== '') {
735
1026
  // this sibling node is from a different component OR is a named fallback slot node
736
- if (nodeType === 1 /* ElementNode */ && slotNameAttr === childNodes[j].getAttribute('slot')) {
1027
+ if (nodeType === 1 /* NODE_TYPE.ElementNode */ && slotNameAttr === childNodes[j].getAttribute('slot')) {
737
1028
  childNode.hidden = true;
738
1029
  break;
739
1030
  }
@@ -742,8 +1033,8 @@ const updateFallbackSlotVisibility = (elm) => {
742
1033
  // this is a default fallback slot node
743
1034
  // any element or text node (with content)
744
1035
  // should hide the default fallback slot node
745
- if (nodeType === 1 /* ElementNode */ ||
746
- (nodeType === 3 /* TextNode */ && childNodes[j].textContent.trim() !== '')) {
1036
+ if (nodeType === 1 /* NODE_TYPE.ElementNode */ ||
1037
+ (nodeType === 3 /* NODE_TYPE.TextNode */ && childNodes[j].textContent.trim() !== '')) {
747
1038
  childNode.hidden = true;
748
1039
  break;
749
1040
  }
@@ -765,8 +1056,8 @@ const relocateSlotContent = (elm) => {
765
1056
  let relocateNodeData;
766
1057
  let j;
767
1058
  let i = 0;
768
- let childNodes = elm.childNodes;
769
- let ilen = childNodes.length;
1059
+ const childNodes = elm.childNodes;
1060
+ const ilen = childNodes.length;
770
1061
  for (; i < ilen; i++) {
771
1062
  childNode = childNodes[i];
772
1063
  if (childNode['s-sr'] && (node = childNode['s-cr']) && node.parentNode) {
@@ -821,13 +1112,13 @@ const relocateSlotContent = (elm) => {
821
1112
  }
822
1113
  }
823
1114
  }
824
- if (childNode.nodeType === 1 /* ElementNode */) {
1115
+ if (childNode.nodeType === 1 /* NODE_TYPE.ElementNode */) {
825
1116
  relocateSlotContent(childNode);
826
1117
  }
827
1118
  }
828
1119
  };
829
1120
  const isNodeLocatedInSlot = (nodeToRelocate, slotNameAttr) => {
830
- if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
1121
+ if (nodeToRelocate.nodeType === 1 /* NODE_TYPE.ElementNode */) {
831
1122
  if (nodeToRelocate.getAttribute('slot') === null && slotNameAttr === '') {
832
1123
  return true;
833
1124
  }
@@ -847,6 +1138,18 @@ const callNodeRefs = (vNode) => {
847
1138
  vNode.$children$ && vNode.$children$.map(callNodeRefs);
848
1139
  }
849
1140
  };
1141
+ /**
1142
+ * The main entry point for Stencil's virtual DOM-based rendering engine
1143
+ *
1144
+ * Given a {@link d.HostRef} container and some virtual DOM nodes, this
1145
+ * function will handle creating a virtual DOM tree with a single root, patching
1146
+ * the current virtual DOM tree onto an old one (if any), dealing with slot
1147
+ * relocation, and reflecting attributes.
1148
+ *
1149
+ * @param hostRef data needed to root and render the virtual DOM tree, such as
1150
+ * the DOM node into which it should be rendered.
1151
+ * @param renderFnResults the virtual DOM nodes to be rendered
1152
+ */
850
1153
  const renderVdom = (hostRef, renderFnResults) => {
851
1154
  const hostElm = hostRef.$hostElement$;
852
1155
  const cmpMeta = hostRef.$cmpMeta$;
@@ -858,12 +1161,12 @@ const renderVdom = (hostRef, renderFnResults) => {
858
1161
  cmpMeta.$attrsToReflect$.map(([propName, attribute]) => (rootVnode.$attrs$[attribute] = hostElm[propName]));
859
1162
  }
860
1163
  rootVnode.$tag$ = null;
861
- rootVnode.$flags$ |= 4 /* isHost */;
1164
+ rootVnode.$flags$ |= 4 /* VNODE_FLAGS.isHost */;
862
1165
  hostRef.$vnode$ = rootVnode;
863
1166
  rootVnode.$elm$ = oldVNode.$elm$ = (hostElm);
864
1167
  {
865
1168
  contentRef = hostElm['s-cr'];
866
- useNativeShadowDom = (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) !== 0;
1169
+ useNativeShadowDom = (cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */) !== 0;
867
1170
  // always reset
868
1171
  checkSlotFallbackVisibility = false;
869
1172
  }
@@ -872,7 +1175,7 @@ const renderVdom = (hostRef, renderFnResults) => {
872
1175
  {
873
1176
  // while we're moving nodes around existing nodes, temporarily disable
874
1177
  // the disconnectCallback from working
875
- plt.$flags$ |= 1 /* isTmpDisconnected */;
1178
+ plt.$flags$ |= 1 /* PLATFORM_FLAGS.isTmpDisconnected */;
876
1179
  if (checkSlotRelocate) {
877
1180
  relocateSlotContent(rootVnode.$elm$);
878
1181
  let relocateData;
@@ -930,7 +1233,7 @@ const renderVdom = (hostRef, renderFnResults) => {
930
1233
  }
931
1234
  else {
932
1235
  // this node doesn't have a slot home to go to, so let's hide it
933
- if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
1236
+ if (nodeToRelocate.nodeType === 1 /* NODE_TYPE.ElementNode */) {
934
1237
  nodeToRelocate.hidden = true;
935
1238
  }
936
1239
  }
@@ -941,30 +1244,11 @@ const renderVdom = (hostRef, renderFnResults) => {
941
1244
  }
942
1245
  // done moving nodes around
943
1246
  // allow the disconnect callback to work again
944
- plt.$flags$ &= ~1 /* isTmpDisconnected */;
1247
+ plt.$flags$ &= ~1 /* PLATFORM_FLAGS.isTmpDisconnected */;
945
1248
  // always reset
946
1249
  relocateNodes.length = 0;
947
1250
  }
948
1251
  };
949
- const getElement = (ref) => (getHostRef(ref).$hostElement$ );
950
- const createEvent = (ref, name, flags) => {
951
- const elm = getElement(ref);
952
- return {
953
- emit: (detail) => {
954
- return emitEvent(elm, name, {
955
- bubbles: !!(flags & 4 /* Bubbles */),
956
- composed: !!(flags & 2 /* Composed */),
957
- cancelable: !!(flags & 1 /* Cancellable */),
958
- detail,
959
- });
960
- },
961
- };
962
- };
963
- const emitEvent = (elm, name, opts) => {
964
- const ev = plt.ce(name, opts);
965
- elm.dispatchEvent(ev);
966
- return ev;
967
- };
968
1252
  const attachToAncestor = (hostRef, ancestorComponent) => {
969
1253
  if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
970
1254
  ancestorComponent['s-p'].push(new Promise((r) => (hostRef.$onRenderResolve$ = r)));
@@ -972,10 +1256,10 @@ const attachToAncestor = (hostRef, ancestorComponent) => {
972
1256
  };
973
1257
  const scheduleUpdate = (hostRef, isInitialLoad) => {
974
1258
  {
975
- hostRef.$flags$ |= 16 /* isQueuedForUpdate */;
1259
+ hostRef.$flags$ |= 16 /* HOST_FLAGS.isQueuedForUpdate */;
976
1260
  }
977
- if (hostRef.$flags$ & 4 /* isWaitingForChildren */) {
978
- hostRef.$flags$ |= 512 /* needsRerender */;
1261
+ if (hostRef.$flags$ & 4 /* HOST_FLAGS.isWaitingForChildren */) {
1262
+ hostRef.$flags$ |= 512 /* HOST_FLAGS.needsRerender */;
979
1263
  return;
980
1264
  }
981
1265
  attachToAncestor(hostRef, hostRef.$ancestorComponent$);
@@ -991,7 +1275,7 @@ const dispatchHooks = (hostRef, isInitialLoad) => {
991
1275
  let promise;
992
1276
  if (isInitialLoad) {
993
1277
  {
994
- hostRef.$flags$ |= 256 /* isListenReady */;
1278
+ hostRef.$flags$ |= 256 /* HOST_FLAGS.isListenReady */;
995
1279
  if (hostRef.$queuedListeners$) {
996
1280
  hostRef.$queuedListeners$.map(([methodName, event]) => safeCall(instance, methodName, event));
997
1281
  hostRef.$queuedListeners$ = null;
@@ -1030,7 +1314,7 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
1030
1314
  }
1031
1315
  else {
1032
1316
  Promise.all(childrenPromises).then(postUpdate);
1033
- hostRef.$flags$ |= 4 /* isWaitingForChildren */;
1317
+ hostRef.$flags$ |= 4 /* HOST_FLAGS.isWaitingForChildren */;
1034
1318
  childrenPromises.length = 0;
1035
1319
  }
1036
1320
  }
@@ -1039,10 +1323,10 @@ const callRender = (hostRef, instance, elm) => {
1039
1323
  try {
1040
1324
  instance = instance.render() ;
1041
1325
  {
1042
- hostRef.$flags$ &= ~16 /* isQueuedForUpdate */;
1326
+ hostRef.$flags$ &= ~16 /* HOST_FLAGS.isQueuedForUpdate */;
1043
1327
  }
1044
1328
  {
1045
- hostRef.$flags$ |= 2 /* hasRendered */;
1329
+ hostRef.$flags$ |= 2 /* HOST_FLAGS.hasRendered */;
1046
1330
  }
1047
1331
  {
1048
1332
  {
@@ -1069,8 +1353,8 @@ const postUpdateComponent = (hostRef) => {
1069
1353
  {
1070
1354
  safeCall(instance, 'componentDidRender');
1071
1355
  }
1072
- if (!(hostRef.$flags$ & 64 /* hasLoadedComponent */)) {
1073
- hostRef.$flags$ |= 64 /* hasLoadedComponent */;
1356
+ if (!(hostRef.$flags$ & 64 /* HOST_FLAGS.hasLoadedComponent */)) {
1357
+ hostRef.$flags$ |= 64 /* HOST_FLAGS.hasLoadedComponent */;
1074
1358
  {
1075
1359
  // DOM WRITE!
1076
1360
  addHydratedFlag(elm);
@@ -1102,10 +1386,10 @@ const postUpdateComponent = (hostRef) => {
1102
1386
  hostRef.$onRenderResolve$();
1103
1387
  hostRef.$onRenderResolve$ = undefined;
1104
1388
  }
1105
- if (hostRef.$flags$ & 512 /* needsRerender */) {
1389
+ if (hostRef.$flags$ & 512 /* HOST_FLAGS.needsRerender */) {
1106
1390
  nextTick(() => scheduleUpdate(hostRef, false));
1107
1391
  }
1108
- hostRef.$flags$ &= ~(4 /* isWaitingForChildren */ | 512 /* needsRerender */);
1392
+ hostRef.$flags$ &= ~(4 /* HOST_FLAGS.isWaitingForChildren */ | 512 /* HOST_FLAGS.needsRerender */);
1109
1393
  }
1110
1394
  // ( •_•)
1111
1395
  // ( •_•)>⌐■-■
@@ -1135,44 +1419,40 @@ const then = (promise, thenFn) => {
1135
1419
  };
1136
1420
  const addHydratedFlag = (elm) => elm.classList.add('hydrated')
1137
1421
  ;
1138
- const parsePropertyValue = (propValue, propType) => {
1139
- // ensure this value is of the correct prop type
1140
- if (propValue != null && !isComplexType(propValue)) {
1141
- if (propType & 4 /* Boolean */) {
1142
- // per the HTML spec, any string value means it is a boolean true value
1143
- // but we'll cheat here and say that the string "false" is the boolean false
1144
- return propValue === 'false' ? false : propValue === '' || !!propValue;
1145
- }
1146
- if (propType & 2 /* Number */) {
1147
- // force it to be a number
1148
- return parseFloat(propValue);
1149
- }
1150
- if (propType & 1 /* String */) {
1151
- // could have been passed as a number or boolean
1152
- // but we still want it as a string
1153
- return String(propValue);
1154
- }
1155
- // redundant return here for better minification
1156
- return propValue;
1157
- }
1158
- // not sure exactly what type we want
1159
- // so no need to change to a different type
1160
- return propValue;
1161
- };
1162
1422
  const getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
1163
1423
  const setValue = (ref, propName, newVal, cmpMeta) => {
1164
1424
  // check our new property value against our internal value
1165
1425
  const hostRef = getHostRef(ref);
1426
+ const elm = hostRef.$hostElement$ ;
1166
1427
  const oldVal = hostRef.$instanceValues$.get(propName);
1167
1428
  const flags = hostRef.$flags$;
1168
1429
  const instance = hostRef.$lazyInstance$ ;
1169
1430
  newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
1170
- if ((!(flags & 8 /* isConstructingInstance */) || oldVal === undefined) && newVal !== oldVal) {
1431
+ // explicitly check for NaN on both sides, as `NaN === NaN` is always false
1432
+ const areBothNaN = Number.isNaN(oldVal) && Number.isNaN(newVal);
1433
+ const didValueChange = newVal !== oldVal && !areBothNaN;
1434
+ if ((!(flags & 8 /* HOST_FLAGS.isConstructingInstance */) || oldVal === undefined) && didValueChange) {
1171
1435
  // gadzooks! the property's value has changed!!
1172
1436
  // set our new value!
1173
1437
  hostRef.$instanceValues$.set(propName, newVal);
1174
1438
  if (instance) {
1175
- if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
1439
+ // get an array of method names of watch functions to call
1440
+ if (cmpMeta.$watchers$ && flags & 128 /* HOST_FLAGS.isWatchReady */) {
1441
+ const watchMethods = cmpMeta.$watchers$[propName];
1442
+ if (watchMethods) {
1443
+ // this instance is watching for when this property changed
1444
+ watchMethods.map((watchMethodName) => {
1445
+ try {
1446
+ // fire off each of the watch methods that are watching this property
1447
+ instance[watchMethodName](newVal, oldVal, propName);
1448
+ }
1449
+ catch (e) {
1450
+ consoleError(e, elm);
1451
+ }
1452
+ });
1453
+ }
1454
+ }
1455
+ if ((flags & (2 /* HOST_FLAGS.hasRendered */ | 16 /* HOST_FLAGS.isQueuedForUpdate */)) === 2 /* HOST_FLAGS.hasRendered */) {
1176
1456
  // looks like this value actually changed, so we've got work to do!
1177
1457
  // but only if we've already rendered, otherwise just chill out
1178
1458
  // queue that we need to do an update, but don't worry about queuing
@@ -1182,14 +1462,27 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
1182
1462
  }
1183
1463
  }
1184
1464
  };
1465
+ /**
1466
+ * Attach a series of runtime constructs to a compiled Stencil component
1467
+ * constructor, including getters and setters for the `@Prop` and `@State`
1468
+ * decorators, callbacks for when attributes change, and so on.
1469
+ *
1470
+ * @param Cstr the constructor for a component that we need to process
1471
+ * @param cmpMeta metadata collected previously about the component
1472
+ * @param flags a number used to store a series of bit flags
1473
+ * @returns a reference to the same constructor passed in (but now mutated)
1474
+ */
1185
1475
  const proxyComponent = (Cstr, cmpMeta, flags) => {
1186
1476
  if (cmpMeta.$members$) {
1477
+ if (Cstr.watchers) {
1478
+ cmpMeta.$watchers$ = Cstr.watchers;
1479
+ }
1187
1480
  // It's better to have a const than two Object.entries()
1188
1481
  const members = Object.entries(cmpMeta.$members$);
1189
1482
  const prototype = Cstr.prototype;
1190
1483
  members.map(([memberName, [memberFlags]]) => {
1191
- if ((memberFlags & 31 /* Prop */ ||
1192
- ((flags & 2 /* proxyState */) && memberFlags & 32 /* State */))) {
1484
+ if ((memberFlags & 31 /* MEMBER_FLAGS.Prop */ ||
1485
+ ((flags & 2 /* PROXY_FLAGS.proxyState */) && memberFlags & 32 /* MEMBER_FLAGS.State */))) {
1193
1486
  // proxyComponent - prop
1194
1487
  Object.defineProperty(prototype, memberName, {
1195
1488
  get() {
@@ -1204,8 +1497,8 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1204
1497
  enumerable: true,
1205
1498
  });
1206
1499
  }
1207
- else if (flags & 1 /* isElementConstructor */ &&
1208
- memberFlags & 64 /* Method */) {
1500
+ else if (flags & 1 /* PROXY_FLAGS.isElementConstructor */ &&
1501
+ memberFlags & 64 /* MEMBER_FLAGS.Method */) {
1209
1502
  // proxyComponent - method
1210
1503
  Object.defineProperty(prototype, memberName, {
1211
1504
  value(...args) {
@@ -1215,19 +1508,19 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1215
1508
  });
1216
1509
  }
1217
1510
  });
1218
- if ((flags & 1 /* isElementConstructor */)) {
1511
+ if ((flags & 1 /* PROXY_FLAGS.isElementConstructor */)) {
1219
1512
  const attrNameToPropName = new Map();
1220
1513
  prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
1221
1514
  plt.jmp(() => {
1222
1515
  const propName = attrNameToPropName.get(attrName);
1223
- // In a webcomponent lifecyle the attributeChangedCallback runs prior to connectedCallback
1516
+ // In a web component lifecycle the attributeChangedCallback runs prior to connectedCallback
1224
1517
  // in the case where an attribute was set inline.
1225
1518
  // ```html
1226
1519
  // <my-component some-attribute="some-value"></my-component>
1227
1520
  // ```
1228
1521
  //
1229
- // There is an edge case where a developer sets the attribute inline on a custom element and then programatically
1230
- // changes it before it has been upgraded as shown below:
1522
+ // There is an edge case where a developer sets the attribute inline on a custom element and then
1523
+ // programmatically changes it before it has been upgraded as shown below:
1231
1524
  //
1232
1525
  // ```html
1233
1526
  // <!-- this component has _not_ been upgraded yet -->
@@ -1237,13 +1530,13 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1237
1530
  // el = document.querySelector("#test");
1238
1531
  // el.someAttribute = "another-value";
1239
1532
  // // upgrade component
1240
- // cutsomElements.define('my-component', MyComponent);
1533
+ // customElements.define('my-component', MyComponent);
1241
1534
  // </script>
1242
1535
  // ```
1243
1536
  // In this case if we do not unshadow here and use the value of the shadowing property, attributeChangedCallback
1244
1537
  // will be called with `newValue = "some-value"` and will set the shadowed property (this.someAttribute = "another-value")
1245
1538
  // to the value that was set inline i.e. "some-value" from above example. When
1246
- // the connectedCallback attempts to unshadow it will use "some-value" as the intial value rather than "another-value"
1539
+ // the connectedCallback attempts to unshadow it will use "some-value" as the initial value rather than "another-value"
1247
1540
  //
1248
1541
  // The case where the attribute was NOT set inline but was not set programmatically shall be handled/unshadowed
1249
1542
  // by connectedCallback as this attributeChangedCallback will not fire.
@@ -1257,17 +1550,25 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1257
1550
  newValue = this[propName];
1258
1551
  delete this[propName];
1259
1552
  }
1553
+ else if (prototype.hasOwnProperty(propName) &&
1554
+ typeof this[propName] === 'number' &&
1555
+ this[propName] == newValue) {
1556
+ // if the propName exists on the prototype of `Cstr`, this update may be a result of Stencil using native
1557
+ // APIs to reflect props as attributes. Calls to `setAttribute(someElement, propName)` will result in
1558
+ // `propName` to be converted to a `DOMString`, which may not be what we want for other primitive props.
1559
+ return;
1560
+ }
1260
1561
  this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
1261
1562
  });
1262
1563
  };
1263
1564
  // create an array of attributes to observe
1264
1565
  // and also create a map of html attribute name to js property name
1265
1566
  Cstr.observedAttributes = members
1266
- .filter(([_, m]) => m[0] & 15 /* HasAttribute */) // filter to only keep props that should match attributes
1567
+ .filter(([_, m]) => m[0] & 15 /* MEMBER_FLAGS.HasAttribute */) // filter to only keep props that should match attributes
1267
1568
  .map(([propName, m]) => {
1268
1569
  const attrName = m[1] || propName;
1269
1570
  attrNameToPropName.set(attrName, propName);
1270
- if (m[0] & 512 /* ReflectAttr */) {
1571
+ if (m[0] & 512 /* MEMBER_FLAGS.ReflectAttr */) {
1271
1572
  cmpMeta.$attrsToReflect$.push([propName, attrName]);
1272
1573
  }
1273
1574
  return attrName;
@@ -1278,10 +1579,10 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1278
1579
  };
1279
1580
  const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
1280
1581
  // initializeComponent
1281
- if ((hostRef.$flags$ & 32 /* hasInitializedComponent */) === 0) {
1582
+ if ((hostRef.$flags$ & 32 /* HOST_FLAGS.hasInitializedComponent */) === 0) {
1282
1583
  {
1283
1584
  // we haven't initialized this element yet
1284
- hostRef.$flags$ |= 32 /* hasInitializedComponent */;
1585
+ hostRef.$flags$ |= 32 /* HOST_FLAGS.hasInitializedComponent */;
1285
1586
  // lazy loaded components
1286
1587
  // request the component's implementation to be
1287
1588
  // wired up with the host element
@@ -1293,7 +1594,13 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1293
1594
  endLoad();
1294
1595
  }
1295
1596
  if (!Cstr.isProxied) {
1296
- proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
1597
+ // we've never proxied this Constructor before
1598
+ // let's add the getters/setters to its prototype before
1599
+ // the first time we create an instance of the implementation
1600
+ {
1601
+ cmpMeta.$watchers$ = Cstr.watchers;
1602
+ }
1603
+ proxyComponent(Cstr, cmpMeta, 2 /* PROXY_FLAGS.proxyState */);
1297
1604
  Cstr.isProxied = true;
1298
1605
  }
1299
1606
  const endNewInstance = createTime('createInstance', cmpMeta.$tagName$);
@@ -1301,7 +1608,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1301
1608
  // but let's keep track of when we start and stop
1302
1609
  // so that the getters/setters don't incorrectly step on data
1303
1610
  {
1304
- hostRef.$flags$ |= 8 /* isConstructingInstance */;
1611
+ hostRef.$flags$ |= 8 /* HOST_FLAGS.isConstructingInstance */;
1305
1612
  }
1306
1613
  // construct the lazy-loaded component implementation
1307
1614
  // passing the hostRef is very important during
@@ -1314,7 +1621,10 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1314
1621
  consoleError(e);
1315
1622
  }
1316
1623
  {
1317
- hostRef.$flags$ &= ~8 /* isConstructingInstance */;
1624
+ hostRef.$flags$ &= ~8 /* HOST_FLAGS.isConstructingInstance */;
1625
+ }
1626
+ {
1627
+ hostRef.$flags$ |= 128 /* HOST_FLAGS.isWatchReady */;
1318
1628
  }
1319
1629
  endNewInstance();
1320
1630
  fireConnectedCallback(hostRef.$lazyInstance$);
@@ -1324,7 +1634,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
1324
1634
  const ancestorComponent = hostRef.$ancestorComponent$;
1325
1635
  const schedule = () => scheduleUpdate(hostRef, true);
1326
1636
  if (ancestorComponent && ancestorComponent['s-rc']) {
1327
- // this is the intial load and this component it has an ancestor component
1637
+ // this is the initial load and this component it has an ancestor component
1328
1638
  // but the ancestor component has NOT fired its will update lifecycle yet
1329
1639
  // so let's just cool our jets and wait for the ancestor to continue first
1330
1640
  // this will get fired off when the ancestor component
@@ -1342,19 +1652,19 @@ const fireConnectedCallback = (instance) => {
1342
1652
  }
1343
1653
  };
1344
1654
  const connectedCallback = (elm) => {
1345
- if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
1655
+ if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
1346
1656
  const hostRef = getHostRef(elm);
1347
1657
  const cmpMeta = hostRef.$cmpMeta$;
1348
1658
  const endConnected = createTime('connectedCallback', cmpMeta.$tagName$);
1349
- if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
1659
+ if (!(hostRef.$flags$ & 1 /* HOST_FLAGS.hasConnected */)) {
1350
1660
  // first time this component has connected
1351
- hostRef.$flags$ |= 1 /* hasConnected */;
1661
+ hostRef.$flags$ |= 1 /* HOST_FLAGS.hasConnected */;
1352
1662
  {
1353
1663
  // initUpdate
1354
1664
  // if the slot polyfill is required we'll need to put some nodes
1355
1665
  // in here to act as original content anchors as we move nodes around
1356
1666
  // host element has been connected to the DOM
1357
- if ((cmpMeta.$flags$ & (4 /* hasSlotRelocation */ | 8 /* needsShadowDomShim */))) {
1667
+ if ((cmpMeta.$flags$ & (4 /* CMP_FLAGS.hasSlotRelocation */ | 8 /* CMP_FLAGS.needsShadowDomShim */))) {
1358
1668
  setContentReference(elm);
1359
1669
  }
1360
1670
  }
@@ -1377,7 +1687,7 @@ const connectedCallback = (elm) => {
1377
1687
  // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
1378
1688
  if (cmpMeta.$members$) {
1379
1689
  Object.entries(cmpMeta.$members$).map(([memberName, [memberFlags]]) => {
1380
- if (memberFlags & 31 /* Prop */ && elm.hasOwnProperty(memberName)) {
1690
+ if (memberFlags & 31 /* MEMBER_FLAGS.Prop */ && elm.hasOwnProperty(memberName)) {
1381
1691
  const value = elm[memberName];
1382
1692
  delete elm[memberName];
1383
1693
  elm[memberName] = value;
@@ -1411,7 +1721,7 @@ const setContentReference = (elm) => {
1411
1721
  elm.insertBefore(contentRefElm, elm.firstChild);
1412
1722
  };
1413
1723
  const disconnectedCallback = (elm) => {
1414
- if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
1724
+ if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
1415
1725
  const hostRef = getHostRef(elm);
1416
1726
  const instance = hostRef.$lazyInstance$ ;
1417
1727
  {
@@ -1426,6 +1736,7 @@ const disconnectedCallback = (elm) => {
1426
1736
  }
1427
1737
  };
1428
1738
  const bootstrapLazy = (lazyBundles, options = {}) => {
1739
+ var _a;
1429
1740
  const endBootstrap = createTime();
1430
1741
  const cmpTags = [];
1431
1742
  const exclude = options.exclude || [];
@@ -1438,60 +1749,70 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1438
1749
  let isBootstrapping = true;
1439
1750
  Object.assign(plt, options);
1440
1751
  plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
1441
- lazyBundles.map((lazyBundle) => lazyBundle[1].map((compactMeta) => {
1442
- const cmpMeta = {
1443
- $flags$: compactMeta[0],
1444
- $tagName$: compactMeta[1],
1445
- $members$: compactMeta[2],
1446
- $listeners$: compactMeta[3],
1447
- };
1448
- {
1449
- cmpMeta.$members$ = compactMeta[2];
1450
- }
1451
- {
1452
- cmpMeta.$listeners$ = compactMeta[3];
1453
- }
1454
- {
1455
- cmpMeta.$attrsToReflect$ = [];
1456
- }
1457
- const tagName = cmpMeta.$tagName$;
1458
- const HostElement = class extends HTMLElement {
1459
- // StencilLazyHost
1460
- constructor(self) {
1461
- // @ts-ignore
1462
- super(self);
1463
- self = this;
1464
- registerHost(self, cmpMeta);
1752
+ lazyBundles.map((lazyBundle) => {
1753
+ lazyBundle[1].map((compactMeta) => {
1754
+ const cmpMeta = {
1755
+ $flags$: compactMeta[0],
1756
+ $tagName$: compactMeta[1],
1757
+ $members$: compactMeta[2],
1758
+ $listeners$: compactMeta[3],
1759
+ };
1760
+ {
1761
+ cmpMeta.$members$ = compactMeta[2];
1465
1762
  }
1466
- connectedCallback() {
1467
- if (appLoadFallback) {
1468
- clearTimeout(appLoadFallback);
1469
- appLoadFallback = null;
1763
+ {
1764
+ cmpMeta.$listeners$ = compactMeta[3];
1765
+ }
1766
+ {
1767
+ cmpMeta.$attrsToReflect$ = [];
1768
+ }
1769
+ {
1770
+ cmpMeta.$watchers$ = {};
1771
+ }
1772
+ const tagName = cmpMeta.$tagName$;
1773
+ const HostElement = class extends HTMLElement {
1774
+ // StencilLazyHost
1775
+ constructor(self) {
1776
+ // @ts-ignore
1777
+ super(self);
1778
+ self = this;
1779
+ registerHost(self, cmpMeta);
1470
1780
  }
1471
- if (isBootstrapping) {
1472
- // connectedCallback will be processed once all components have been registered
1473
- deferredConnectedCallbacks.push(this);
1781
+ connectedCallback() {
1782
+ if (appLoadFallback) {
1783
+ clearTimeout(appLoadFallback);
1784
+ appLoadFallback = null;
1785
+ }
1786
+ if (isBootstrapping) {
1787
+ // connectedCallback will be processed once all components have been registered
1788
+ deferredConnectedCallbacks.push(this);
1789
+ }
1790
+ else {
1791
+ plt.jmp(() => connectedCallback(this));
1792
+ }
1474
1793
  }
1475
- else {
1476
- plt.jmp(() => connectedCallback(this));
1794
+ disconnectedCallback() {
1795
+ plt.jmp(() => disconnectedCallback(this));
1477
1796
  }
1797
+ componentOnReady() {
1798
+ return getHostRef(this).$onReadyPromise$;
1799
+ }
1800
+ };
1801
+ cmpMeta.$lazyBundleId$ = lazyBundle[0];
1802
+ if (!exclude.includes(tagName) && !customElements.get(tagName)) {
1803
+ cmpTags.push(tagName);
1804
+ customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* PROXY_FLAGS.isElementConstructor */));
1478
1805
  }
1479
- disconnectedCallback() {
1480
- plt.jmp(() => disconnectedCallback(this));
1481
- }
1482
- componentOnReady() {
1483
- return getHostRef(this).$onReadyPromise$;
1484
- }
1485
- };
1486
- cmpMeta.$lazyBundleId$ = lazyBundle[0];
1487
- if (!exclude.includes(tagName) && !customElements.get(tagName)) {
1488
- cmpTags.push(tagName);
1489
- customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* isElementConstructor */));
1490
- }
1491
- }));
1806
+ });
1807
+ });
1492
1808
  {
1493
1809
  visibilityStyle.innerHTML = cmpTags + HYDRATED_CSS;
1494
1810
  visibilityStyle.setAttribute('data-styles', '');
1811
+ // Apply CSP nonce to the style tag if it exists
1812
+ const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
1813
+ if (nonce != null) {
1814
+ visibilityStyle.setAttribute('nonce', nonce);
1815
+ }
1495
1816
  head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
1496
1817
  }
1497
1818
  // Process deferred connectedCallbacks now all components have been registered
@@ -1508,7 +1829,48 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1508
1829
  endBootstrap();
1509
1830
  };
1510
1831
  const Fragment = (_, children) => children;
1511
- const hostRefs = new WeakMap();
1832
+ const addHostEventListeners = (elm, hostRef, listeners, attachParentListeners) => {
1833
+ if (listeners) {
1834
+ listeners.map(([flags, name, method]) => {
1835
+ const target = getHostListenerTarget(elm, flags) ;
1836
+ const handler = hostListenerProxy(hostRef, method);
1837
+ const opts = hostListenerOpts(flags);
1838
+ plt.ael(target, name, handler, opts);
1839
+ (hostRef.$rmListeners$ = hostRef.$rmListeners$ || []).push(() => plt.rel(target, name, handler, opts));
1840
+ });
1841
+ }
1842
+ };
1843
+ const hostListenerProxy = (hostRef, methodName) => (ev) => {
1844
+ try {
1845
+ {
1846
+ if (hostRef.$flags$ & 256 /* HOST_FLAGS.isListenReady */) {
1847
+ // instance is ready, let's call it's member method for this event
1848
+ hostRef.$lazyInstance$[methodName](ev);
1849
+ }
1850
+ else {
1851
+ (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
1852
+ }
1853
+ }
1854
+ }
1855
+ catch (e) {
1856
+ consoleError(e);
1857
+ }
1858
+ };
1859
+ const getHostListenerTarget = (elm, flags) => {
1860
+ if (flags & 8 /* LISTENER_FLAGS.TargetWindow */)
1861
+ return win;
1862
+ return elm;
1863
+ };
1864
+ // prettier-ignore
1865
+ const hostListenerOpts = (flags) => (flags & 2 /* LISTENER_FLAGS.Capture */) !== 0;
1866
+ /**
1867
+ * Assigns the given value to the nonce property on the runtime platform object.
1868
+ * During runtime, this value is used to set the nonce attribute on all dynamically created script and style tags.
1869
+ * @param nonce The value to be assigned to the platform nonce property.
1870
+ * @returns void
1871
+ */
1872
+ const setNonce = (nonce) => (plt.$nonce$ = nonce);
1873
+ const hostRefs = /*@__PURE__*/ new WeakMap();
1512
1874
  const getHostRef = (ref) => hostRefs.get(ref);
1513
1875
  const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
1514
1876
  const registerHost = (elm, cmpMeta) => {
@@ -1540,7 +1902,9 @@ const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
1540
1902
  if (module) {
1541
1903
  return module[exportName];
1542
1904
  }
1905
+ /*!__STENCIL_STATIC_IMPORT_SWITCH__*/
1543
1906
  return import(
1907
+ /* @vite-ignore */
1544
1908
  /* webpackInclude: /\.entry\.js$/ */
1545
1909
  /* webpackExclude: /\.system\.entry\.js$/ */
1546
1910
  /* webpackMode: "lazy" */
@@ -1551,13 +1915,25 @@ const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
1551
1915
  return importedModule[exportName];
1552
1916
  }, consoleError);
1553
1917
  };
1918
+ const win = typeof window !== 'undefined' ? window : {};
1919
+ const doc = win.document || { head: {} };
1920
+ const plt = {
1921
+ $flags$: 0,
1922
+ $resourcesUrl$: '',
1923
+ jmp: (h) => h(),
1924
+ raf: (h) => requestAnimationFrame(h),
1925
+ ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
1926
+ rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
1927
+ ce: (eventName, opts) => new CustomEvent(eventName, opts),
1928
+ };
1929
+ const promiseResolve = (v) => Promise.resolve(v);
1554
1930
  const queueDomReads = [];
1555
1931
  const queueDomWrites = [];
1556
1932
  const queueTask = (queue, write) => (cb) => {
1557
1933
  queue.push(cb);
1558
1934
  if (!queuePending) {
1559
1935
  queuePending = true;
1560
- if (write && plt.$flags$ & 4 /* queueSync */) {
1936
+ if (write && plt.$flags$ & 4 /* PLATFORM_FLAGS.queueSync */) {
1561
1937
  nextTick(flush);
1562
1938
  }
1563
1939
  else {
@@ -1594,4 +1970,4 @@ const flush = () => {
1594
1970
  const nextTick = /*@__PURE__*/ (cb) => promiseResolve().then(cb);
1595
1971
  const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
1596
1972
 
1597
- export { Fragment as F, Host as H, bootstrapLazy as b, createEvent as c, getElement as g, h, promiseResolve as p, registerInstance as r };
1973
+ export { Fragment as F, Host as H, bootstrapLazy as b, createEvent as c, getElement as g, h, promiseResolve as p, registerInstance as r, setNonce as s };