reneco-hierarchized-picker 0.2.0 → 0.2.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.
- package/dist/cjs/{index-63f1dfbb.js → index-55df525c.js} +589 -253
- package/dist/cjs/loader.cjs.js +3 -2
- package/dist/cjs/reneco-hierarchized-picker.cjs.entry.js +68 -37
- package/dist/cjs/reneco-hierarchized-picker.cjs.js +8 -4
- package/dist/collection/collection-manifest.json +2 -2
- package/dist/collection/components/hierarchized-picker/hierarchized-picker.css +16 -2
- package/dist/collection/components/hierarchized-picker/hierarchized-picker.js +336 -309
- package/dist/collection/components/hierarchized-picker/treejs/index.js +20 -17
- package/dist/custom-elements/index.js +68 -37
- package/dist/esm/{index-92a3fee2.js → index-ef964604.js} +589 -254
- package/dist/esm/loader.js +3 -2
- package/dist/esm/polyfills/css-shim.js +1 -1
- package/dist/esm/reneco-hierarchized-picker.entry.js +68 -37
- package/dist/esm/reneco-hierarchized-picker.js +5 -4
- package/dist/esm-es5/index-ef964604.js +2 -0
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/reneco-hierarchized-picker.entry.js +2 -2
- package/dist/esm-es5/reneco-hierarchized-picker.js +1 -1
- package/dist/reneco-hierarchized-picker/p-73168a50.system.js +1 -0
- package/dist/reneco-hierarchized-picker/p-9833af17.entry.js +1 -0
- package/dist/reneco-hierarchized-picker/p-9bcf4c87.js +2 -0
- package/dist/reneco-hierarchized-picker/p-cd66fa48.system.entry.js +3 -0
- package/dist/reneco-hierarchized-picker/p-ffa47dcf.system.js +2 -0
- package/dist/reneco-hierarchized-picker/reneco-hierarchized-picker.esm.js +1 -1
- package/dist/reneco-hierarchized-picker/reneco-hierarchized-picker.js +2 -1
- package/dist/types/components/hierarchized-picker/hierarchized-picker.d.ts +4 -1
- package/dist/types/components.d.ts +7 -3
- package/dist/types/stencil-public-runtime.d.ts +275 -193
- package/dist/types/utils/utils.d.ts +1 -1
- package/loader/index.d.ts +9 -1
- package/loader/package.json +1 -0
- package/package.json +1 -1
- package/dist/esm-es5/index-92a3fee2.js +0 -1
- package/dist/reneco-hierarchized-picker/p-338c16c4.system.entry.js +0 -3
- package/dist/reneco-hierarchized-picker/p-37fdba59.system.js +0 -1
- package/dist/reneco-hierarchized-picker/p-4e73196c.js +0 -1
- package/dist/reneco-hierarchized-picker/p-5db9a5c2.entry.js +0 -1
- package/dist/reneco-hierarchized-picker/p-64551bc4.system.js +0 -1
|
@@ -22,30 +22,16 @@ function _interopNamespace(e) {
|
|
|
22
22
|
|
|
23
23
|
const NAMESPACE = 'reneco-hierarchized-picker';
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Virtual DOM patching algorithm based on Snabbdom by
|
|
27
|
+
* Simon Friis Vindum (@paldepind)
|
|
28
|
+
* Licensed under the MIT License
|
|
29
|
+
* https://github.com/snabbdom/snabbdom/blob/master/LICENSE
|
|
30
|
+
*
|
|
31
|
+
* Modified for Stencil's renderer and slot projection
|
|
32
|
+
*/
|
|
25
33
|
let isSvgMode = false;
|
|
26
34
|
let queuePending = false;
|
|
27
|
-
const win = typeof window !== 'undefined' ? window : {};
|
|
28
|
-
const doc = win.document || { head: {} };
|
|
29
|
-
const plt = {
|
|
30
|
-
$flags$: 0,
|
|
31
|
-
$resourcesUrl$: '',
|
|
32
|
-
jmp: h => h(),
|
|
33
|
-
raf: h => requestAnimationFrame(h),
|
|
34
|
-
ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
|
|
35
|
-
rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
|
|
36
|
-
ce: (eventName, opts) => new CustomEvent(eventName, opts),
|
|
37
|
-
};
|
|
38
|
-
const promiseResolve = (v) => Promise.resolve(v);
|
|
39
|
-
const supportsConstructibleStylesheets = /*@__PURE__*/ (() => {
|
|
40
|
-
try {
|
|
41
|
-
new CSSStyleSheet();
|
|
42
|
-
return typeof (new CSSStyleSheet()).replace === 'function';
|
|
43
|
-
}
|
|
44
|
-
catch (e) { }
|
|
45
|
-
return false;
|
|
46
|
-
})()
|
|
47
|
-
;
|
|
48
|
-
const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
|
|
49
35
|
const createTime = (fnName, tagName = '') => {
|
|
50
36
|
{
|
|
51
37
|
return () => {
|
|
@@ -60,59 +46,7 @@ const uniqueTime = (key, measureText) => {
|
|
|
60
46
|
};
|
|
61
47
|
}
|
|
62
48
|
};
|
|
63
|
-
const
|
|
64
|
-
const registerStyle = (scopeId, cssText, allowCS) => {
|
|
65
|
-
let style = styles.get(scopeId);
|
|
66
|
-
if (supportsConstructibleStylesheets && allowCS) {
|
|
67
|
-
style = (style || new CSSStyleSheet());
|
|
68
|
-
style.replace(cssText);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
style = cssText;
|
|
72
|
-
}
|
|
73
|
-
styles.set(scopeId, style);
|
|
74
|
-
};
|
|
75
|
-
const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
|
|
76
|
-
let scopeId = getScopeId(cmpMeta);
|
|
77
|
-
let style = styles.get(scopeId);
|
|
78
|
-
// if an element is NOT connected then getRootNode() will return the wrong root node
|
|
79
|
-
// so the fallback is to always use the document for the root node in those cases
|
|
80
|
-
styleContainerNode = styleContainerNode.nodeType === 11 /* DocumentFragment */ ? styleContainerNode : doc;
|
|
81
|
-
if (style) {
|
|
82
|
-
if (typeof style === 'string') {
|
|
83
|
-
styleContainerNode = styleContainerNode.head || styleContainerNode;
|
|
84
|
-
let appliedStyles = rootAppliedStyles.get(styleContainerNode);
|
|
85
|
-
let styleElm;
|
|
86
|
-
if (!appliedStyles) {
|
|
87
|
-
rootAppliedStyles.set(styleContainerNode, (appliedStyles = new Set()));
|
|
88
|
-
}
|
|
89
|
-
if (!appliedStyles.has(scopeId)) {
|
|
90
|
-
{
|
|
91
|
-
{
|
|
92
|
-
styleElm = doc.createElement('style');
|
|
93
|
-
styleElm.innerHTML = style;
|
|
94
|
-
}
|
|
95
|
-
styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
|
|
96
|
-
}
|
|
97
|
-
if (appliedStyles) {
|
|
98
|
-
appliedStyles.add(scopeId);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
else if ( !styleContainerNode.adoptedStyleSheets.includes(style)) {
|
|
103
|
-
styleContainerNode.adoptedStyleSheets = [...styleContainerNode.adoptedStyleSheets, style];
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return scopeId;
|
|
107
|
-
};
|
|
108
|
-
const attachStyles = (hostRef) => {
|
|
109
|
-
const cmpMeta = hostRef.$cmpMeta$;
|
|
110
|
-
const elm = hostRef.$hostElement$;
|
|
111
|
-
const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
|
|
112
|
-
const scopeId = addStyle( elm.getRootNode(), cmpMeta);
|
|
113
|
-
endAttachStyles();
|
|
114
|
-
};
|
|
115
|
-
const getScopeId = (cmp, mode) => 'sc-' + ( cmp.$tagName$);
|
|
49
|
+
const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
|
|
116
50
|
/**
|
|
117
51
|
* Default style mode id
|
|
118
52
|
*/
|
|
@@ -126,6 +60,18 @@ const isComplexType = (o) => {
|
|
|
126
60
|
o = typeof o;
|
|
127
61
|
return o === 'object' || o === 'function';
|
|
128
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Helper method for querying a `meta` tag that contains a nonce value
|
|
65
|
+
* out of a DOM's head.
|
|
66
|
+
*
|
|
67
|
+
* @param doc The DOM containing the `head` to query against
|
|
68
|
+
* @returns The content of the meta tag representing the nonce value, or `undefined` if no tag
|
|
69
|
+
* exists or the tag has no content.
|
|
70
|
+
*/
|
|
71
|
+
function queryNonceMetaTagContent(doc) {
|
|
72
|
+
var _a, _b, _c;
|
|
73
|
+
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;
|
|
74
|
+
}
|
|
129
75
|
/**
|
|
130
76
|
* Production h() function based on Preact by
|
|
131
77
|
* Jason Miller (@developit)
|
|
@@ -134,14 +80,13 @@ const isComplexType = (o) => {
|
|
|
134
80
|
*
|
|
135
81
|
* Modified for Stencil's compiler and vdom
|
|
136
82
|
*/
|
|
137
|
-
// const stack: any[] = [];
|
|
138
83
|
// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, child?: d.ChildType): d.VNode;
|
|
139
84
|
// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
|
|
140
85
|
const h = (nodeName, vnodeData, ...children) => {
|
|
141
86
|
let child = null;
|
|
142
87
|
let simple = false;
|
|
143
88
|
let lastSimple = false;
|
|
144
|
-
|
|
89
|
+
const vNodeChildren = [];
|
|
145
90
|
const walk = (c) => {
|
|
146
91
|
for (let i = 0; i < c.length; i++) {
|
|
147
92
|
child = c[i];
|
|
@@ -173,7 +118,7 @@ const h = (nodeName, vnodeData, ...children) => {
|
|
|
173
118
|
typeof classData !== 'object'
|
|
174
119
|
? classData
|
|
175
120
|
: Object.keys(classData)
|
|
176
|
-
.filter(k => classData[k])
|
|
121
|
+
.filter((k) => classData[k])
|
|
177
122
|
.join(' ');
|
|
178
123
|
}
|
|
179
124
|
}
|
|
@@ -185,6 +130,14 @@ const h = (nodeName, vnodeData, ...children) => {
|
|
|
185
130
|
}
|
|
186
131
|
return vnode;
|
|
187
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* A utility function for creating a virtual DOM node from a tag and some
|
|
135
|
+
* possible text content.
|
|
136
|
+
*
|
|
137
|
+
* @param tag the tag for this element
|
|
138
|
+
* @param text possible text content for the node
|
|
139
|
+
* @returns a newly-minted virtual DOM node
|
|
140
|
+
*/
|
|
188
141
|
const newVNode = (tag, text) => {
|
|
189
142
|
const vnode = {
|
|
190
143
|
$flags$: 0,
|
|
@@ -199,7 +152,146 @@ const newVNode = (tag, text) => {
|
|
|
199
152
|
return vnode;
|
|
200
153
|
};
|
|
201
154
|
const Host = {};
|
|
155
|
+
/**
|
|
156
|
+
* Check whether a given node is a Host node or not
|
|
157
|
+
*
|
|
158
|
+
* @param node the virtual DOM node to check
|
|
159
|
+
* @returns whether it's a Host node or not
|
|
160
|
+
*/
|
|
202
161
|
const isHost = (node) => node && node.$tag$ === Host;
|
|
162
|
+
/**
|
|
163
|
+
* Parse a new property value for a given property type.
|
|
164
|
+
*
|
|
165
|
+
* While the prop value can reasonably be expected to be of `any` type as far as TypeScript's type checker is concerned,
|
|
166
|
+
* it is not safe to assume that the string returned by evaluating `typeof propValue` matches:
|
|
167
|
+
* 1. `any`, the type given to `propValue` in the function signature
|
|
168
|
+
* 2. the type stored from `propType`.
|
|
169
|
+
*
|
|
170
|
+
* This function provides the capability to parse/coerce a property's value to potentially any other JavaScript type.
|
|
171
|
+
*
|
|
172
|
+
* Property values represented in TSX preserve their type information. In the example below, the number 0 is passed to
|
|
173
|
+
* a component. This `propValue` will preserve its type information (`typeof propValue === 'number'`). Note that is
|
|
174
|
+
* based on the type of the value being passed in, not the type declared of the class member decorated with `@Prop`.
|
|
175
|
+
* ```tsx
|
|
176
|
+
* <my-cmp prop-val={0}></my-cmp>
|
|
177
|
+
* ```
|
|
178
|
+
*
|
|
179
|
+
* HTML prop values on the other hand, will always a string
|
|
180
|
+
*
|
|
181
|
+
* @param propValue the new value to coerce to some type
|
|
182
|
+
* @param propType the type of the prop, expressed as a binary number
|
|
183
|
+
* @returns the parsed/coerced value
|
|
184
|
+
*/
|
|
185
|
+
const parsePropertyValue = (propValue, propType) => {
|
|
186
|
+
// ensure this value is of the correct prop type
|
|
187
|
+
if (propValue != null && !isComplexType(propValue)) {
|
|
188
|
+
if (propType & 4 /* MEMBER_FLAGS.Boolean */) {
|
|
189
|
+
// per the HTML spec, any string value means it is a boolean true value
|
|
190
|
+
// but we'll cheat here and say that the string "false" is the boolean false
|
|
191
|
+
return propValue === 'false' ? false : propValue === '' || !!propValue;
|
|
192
|
+
}
|
|
193
|
+
if (propType & 1 /* MEMBER_FLAGS.String */) {
|
|
194
|
+
// could have been passed as a number or boolean
|
|
195
|
+
// but we still want it as a string
|
|
196
|
+
return String(propValue);
|
|
197
|
+
}
|
|
198
|
+
// redundant return here for better minification
|
|
199
|
+
return propValue;
|
|
200
|
+
}
|
|
201
|
+
// not sure exactly what type we want
|
|
202
|
+
// so no need to change to a different type
|
|
203
|
+
return propValue;
|
|
204
|
+
};
|
|
205
|
+
const getElement = (ref) => (getHostRef(ref).$hostElement$ );
|
|
206
|
+
const createEvent = (ref, name, flags) => {
|
|
207
|
+
const elm = getElement(ref);
|
|
208
|
+
return {
|
|
209
|
+
emit: (detail) => {
|
|
210
|
+
return emitEvent(elm, name, {
|
|
211
|
+
bubbles: !!(flags & 4 /* EVENT_FLAGS.Bubbles */),
|
|
212
|
+
composed: !!(flags & 2 /* EVENT_FLAGS.Composed */),
|
|
213
|
+
cancelable: !!(flags & 1 /* EVENT_FLAGS.Cancellable */),
|
|
214
|
+
detail,
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Helper function to create & dispatch a custom Event on a provided target
|
|
221
|
+
* @param elm the target of the Event
|
|
222
|
+
* @param name the name to give the custom Event
|
|
223
|
+
* @param opts options for configuring a custom Event
|
|
224
|
+
* @returns the custom Event
|
|
225
|
+
*/
|
|
226
|
+
const emitEvent = (elm, name, opts) => {
|
|
227
|
+
const ev = plt.ce(name, opts);
|
|
228
|
+
elm.dispatchEvent(ev);
|
|
229
|
+
return ev;
|
|
230
|
+
};
|
|
231
|
+
const rootAppliedStyles = /*@__PURE__*/ new WeakMap();
|
|
232
|
+
const registerStyle = (scopeId, cssText, allowCS) => {
|
|
233
|
+
let style = styles.get(scopeId);
|
|
234
|
+
if (supportsConstructableStylesheets && allowCS) {
|
|
235
|
+
style = (style || new CSSStyleSheet());
|
|
236
|
+
if (typeof style === 'string') {
|
|
237
|
+
style = cssText;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
style.replaceSync(cssText);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
style = cssText;
|
|
245
|
+
}
|
|
246
|
+
styles.set(scopeId, style);
|
|
247
|
+
};
|
|
248
|
+
const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
|
|
249
|
+
var _a;
|
|
250
|
+
let scopeId = getScopeId(cmpMeta);
|
|
251
|
+
const style = styles.get(scopeId);
|
|
252
|
+
// if an element is NOT connected then getRootNode() will return the wrong root node
|
|
253
|
+
// so the fallback is to always use the document for the root node in those cases
|
|
254
|
+
styleContainerNode = styleContainerNode.nodeType === 11 /* NODE_TYPE.DocumentFragment */ ? styleContainerNode : doc;
|
|
255
|
+
if (style) {
|
|
256
|
+
if (typeof style === 'string') {
|
|
257
|
+
styleContainerNode = styleContainerNode.head || styleContainerNode;
|
|
258
|
+
let appliedStyles = rootAppliedStyles.get(styleContainerNode);
|
|
259
|
+
let styleElm;
|
|
260
|
+
if (!appliedStyles) {
|
|
261
|
+
rootAppliedStyles.set(styleContainerNode, (appliedStyles = new Set()));
|
|
262
|
+
}
|
|
263
|
+
if (!appliedStyles.has(scopeId)) {
|
|
264
|
+
{
|
|
265
|
+
{
|
|
266
|
+
styleElm = doc.createElement('style');
|
|
267
|
+
styleElm.innerHTML = style;
|
|
268
|
+
}
|
|
269
|
+
// Apply CSP nonce to the style tag if it exists
|
|
270
|
+
const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
|
|
271
|
+
if (nonce != null) {
|
|
272
|
+
styleElm.setAttribute('nonce', nonce);
|
|
273
|
+
}
|
|
274
|
+
styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
|
|
275
|
+
}
|
|
276
|
+
if (appliedStyles) {
|
|
277
|
+
appliedStyles.add(scopeId);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else if (!styleContainerNode.adoptedStyleSheets.includes(style)) {
|
|
282
|
+
styleContainerNode.adoptedStyleSheets = [...styleContainerNode.adoptedStyleSheets, style];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return scopeId;
|
|
286
|
+
};
|
|
287
|
+
const attachStyles = (hostRef) => {
|
|
288
|
+
const cmpMeta = hostRef.$cmpMeta$;
|
|
289
|
+
const elm = hostRef.$hostElement$;
|
|
290
|
+
const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
|
|
291
|
+
addStyle(elm.getRootNode(), cmpMeta);
|
|
292
|
+
endAttachStyles();
|
|
293
|
+
};
|
|
294
|
+
const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
|
|
203
295
|
/**
|
|
204
296
|
* Production setAccessor() function based on Preact by
|
|
205
297
|
* Jason Miller (@developit)
|
|
@@ -212,19 +304,19 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
212
304
|
if (oldValue !== newValue) {
|
|
213
305
|
let isProp = isMemberInElement(elm, memberName);
|
|
214
306
|
let ln = memberName.toLowerCase();
|
|
215
|
-
if (
|
|
307
|
+
if (memberName === 'class') {
|
|
216
308
|
const classList = elm.classList;
|
|
217
309
|
const oldClasses = parseClassList(oldValue);
|
|
218
310
|
const newClasses = parseClassList(newValue);
|
|
219
|
-
classList.remove(...oldClasses.filter(c => c && !newClasses.includes(c)));
|
|
220
|
-
classList.add(...newClasses.filter(c => c && !oldClasses.includes(c)));
|
|
311
|
+
classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
|
|
312
|
+
classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
|
|
221
313
|
}
|
|
222
|
-
else if (
|
|
314
|
+
else if (memberName === 'style') {
|
|
223
315
|
// update style attribute, css properties and values
|
|
224
316
|
{
|
|
225
317
|
for (const prop in oldValue) {
|
|
226
318
|
if (!newValue || newValue[prop] == null) {
|
|
227
|
-
if (
|
|
319
|
+
if (prop.includes('-')) {
|
|
228
320
|
elm.style.removeProperty(prop);
|
|
229
321
|
}
|
|
230
322
|
else {
|
|
@@ -235,7 +327,7 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
235
327
|
}
|
|
236
328
|
for (const prop in newValue) {
|
|
237
329
|
if (!oldValue || newValue[prop] !== oldValue[prop]) {
|
|
238
|
-
if (
|
|
330
|
+
if (prop.includes('-')) {
|
|
239
331
|
elm.style.setProperty(prop, newValue[prop]);
|
|
240
332
|
}
|
|
241
333
|
else {
|
|
@@ -244,13 +336,15 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
244
336
|
}
|
|
245
337
|
}
|
|
246
338
|
}
|
|
247
|
-
else if (
|
|
339
|
+
else if (memberName === 'ref') {
|
|
248
340
|
// minifier will clean this up
|
|
249
341
|
if (newValue) {
|
|
250
342
|
newValue(elm);
|
|
251
343
|
}
|
|
252
344
|
}
|
|
253
|
-
else if (
|
|
345
|
+
else if ((!isProp ) &&
|
|
346
|
+
memberName[0] === 'o' &&
|
|
347
|
+
memberName[1] === 'n') {
|
|
254
348
|
// Event Handlers
|
|
255
349
|
// so if the member name starts with "on" and the 3rd characters is
|
|
256
350
|
// a capital letter, and it's not already a member on the element,
|
|
@@ -293,11 +387,10 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
293
387
|
if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
|
|
294
388
|
try {
|
|
295
389
|
if (!elm.tagName.includes('-')) {
|
|
296
|
-
|
|
390
|
+
const n = newValue == null ? '' : newValue;
|
|
297
391
|
// Workaround for Safari, moving the <input> caret when re-assigning the same valued
|
|
298
392
|
if (memberName === 'list') {
|
|
299
393
|
isProp = false;
|
|
300
|
-
// tslint:disable-next-line: triple-equals
|
|
301
394
|
}
|
|
302
395
|
else if (oldValue == null || elm[memberName] != n) {
|
|
303
396
|
elm[memberName] = n;
|
|
@@ -316,7 +409,7 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
316
409
|
}
|
|
317
410
|
}
|
|
318
411
|
}
|
|
319
|
-
else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex) {
|
|
412
|
+
else if ((!isProp || flags & 4 /* VNODE_FLAGS.isHost */ || isSvg) && !isComplex) {
|
|
320
413
|
newValue = newValue === true ? '' : newValue;
|
|
321
414
|
{
|
|
322
415
|
elm.setAttribute(memberName, newValue);
|
|
@@ -331,7 +424,9 @@ const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
|
|
|
331
424
|
// if the element passed in is a shadow root, which is a document fragment
|
|
332
425
|
// then we want to be adding attrs/props to the shadow root's "host" element
|
|
333
426
|
// if it's not a shadow root, then we add attrs/props to the same element
|
|
334
|
-
const elm = newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host
|
|
427
|
+
const elm = newVnode.$elm$.nodeType === 11 /* NODE_TYPE.DocumentFragment */ && newVnode.$elm$.host
|
|
428
|
+
? newVnode.$elm$.host
|
|
429
|
+
: newVnode.$elm$;
|
|
335
430
|
const oldVnodeAttrs = (oldVnode && oldVnode.$attrs$) || EMPTY_OBJ;
|
|
336
431
|
const newVnodeAttrs = newVnode.$attrs$ || EMPTY_OBJ;
|
|
337
432
|
{
|
|
@@ -347,19 +442,29 @@ const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
|
|
|
347
442
|
setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode, newVnode.$flags$);
|
|
348
443
|
}
|
|
349
444
|
};
|
|
445
|
+
/**
|
|
446
|
+
* Create a DOM Node corresponding to one of the children of a given VNode.
|
|
447
|
+
*
|
|
448
|
+
* @param oldParentVNode the parent VNode from the previous render
|
|
449
|
+
* @param newParentVNode the parent VNode from the current render
|
|
450
|
+
* @param childIndex the index of the VNode, in the _new_ parent node's
|
|
451
|
+
* children, for which we will create a new DOM node
|
|
452
|
+
* @param parentElm the parent DOM node which our new node will be a child of
|
|
453
|
+
* @returns the newly created node
|
|
454
|
+
*/
|
|
350
455
|
const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
|
|
351
456
|
// tslint:disable-next-line: prefer-const
|
|
352
|
-
|
|
457
|
+
const newVNode = newParentVNode.$children$[childIndex];
|
|
353
458
|
let i = 0;
|
|
354
459
|
let elm;
|
|
355
460
|
let childNode;
|
|
356
|
-
if (
|
|
461
|
+
if (newVNode.$text$ !== null) {
|
|
357
462
|
// create text node
|
|
358
463
|
elm = newVNode.$elm$ = doc.createTextNode(newVNode.$text$);
|
|
359
464
|
}
|
|
360
465
|
else {
|
|
361
466
|
// create element
|
|
362
|
-
elm = newVNode.$elm$ = (
|
|
467
|
+
elm = newVNode.$elm$ = (doc.createElement(newVNode.$tag$));
|
|
363
468
|
// add css classes, attrs, props, listeners, etc.
|
|
364
469
|
{
|
|
365
470
|
updateElement(null, newVNode, isSvgMode);
|
|
@@ -378,19 +483,47 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
|
|
|
378
483
|
}
|
|
379
484
|
return elm;
|
|
380
485
|
};
|
|
486
|
+
/**
|
|
487
|
+
* Create DOM nodes corresponding to a list of {@link d.Vnode} objects and
|
|
488
|
+
* add them to the DOM in the appropriate place.
|
|
489
|
+
*
|
|
490
|
+
* @param parentElm the DOM node which should be used as a parent for the new
|
|
491
|
+
* DOM nodes
|
|
492
|
+
* @param before a child of the `parentElm` which the new children should be
|
|
493
|
+
* inserted before (optional)
|
|
494
|
+
* @param parentVNode the parent virtual DOM node
|
|
495
|
+
* @param vnodes the new child virtual DOM nodes to produce DOM nodes for
|
|
496
|
+
* @param startIdx the index in the child virtual DOM nodes at which to start
|
|
497
|
+
* creating DOM nodes (inclusive)
|
|
498
|
+
* @param endIdx the index in the child virtual DOM nodes at which to stop
|
|
499
|
+
* creating DOM nodes (inclusive)
|
|
500
|
+
*/
|
|
381
501
|
const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
|
|
382
|
-
let containerElm = (
|
|
502
|
+
let containerElm = (parentElm);
|
|
383
503
|
let childNode;
|
|
384
504
|
for (; startIdx <= endIdx; ++startIdx) {
|
|
385
505
|
if (vnodes[startIdx]) {
|
|
386
506
|
childNode = createElm(null, parentVNode, startIdx);
|
|
387
507
|
if (childNode) {
|
|
388
508
|
vnodes[startIdx].$elm$ = childNode;
|
|
389
|
-
containerElm.insertBefore(childNode,
|
|
509
|
+
containerElm.insertBefore(childNode, before);
|
|
390
510
|
}
|
|
391
511
|
}
|
|
392
512
|
}
|
|
393
513
|
};
|
|
514
|
+
/**
|
|
515
|
+
* Remove the DOM elements corresponding to a list of {@link d.VNode} objects.
|
|
516
|
+
* This can be used to, for instance, clean up after a list of children which
|
|
517
|
+
* should no longer be shown.
|
|
518
|
+
*
|
|
519
|
+
* This function also handles some of Stencil's slot relocation logic.
|
|
520
|
+
*
|
|
521
|
+
* @param vnodes a list of virtual DOM nodes to remove
|
|
522
|
+
* @param startIdx the index at which to start removing nodes (inclusive)
|
|
523
|
+
* @param endIdx the index at which to stop removing nodes (inclusive)
|
|
524
|
+
* @param vnode a VNode
|
|
525
|
+
* @param elm an element
|
|
526
|
+
*/
|
|
394
527
|
const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
|
|
395
528
|
for (; startIdx <= endIdx; ++startIdx) {
|
|
396
529
|
if ((vnode = vnodes[startIdx])) {
|
|
@@ -401,6 +534,74 @@ const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
|
|
|
401
534
|
}
|
|
402
535
|
}
|
|
403
536
|
};
|
|
537
|
+
/**
|
|
538
|
+
* Reconcile the children of a new VNode with the children of an old VNode by
|
|
539
|
+
* traversing the two collections of children, identifying nodes that are
|
|
540
|
+
* conserved or changed, calling out to `patch` to make any necessary
|
|
541
|
+
* updates to the DOM, and rearranging DOM nodes as needed.
|
|
542
|
+
*
|
|
543
|
+
* The algorithm for reconciling children works by analyzing two 'windows' onto
|
|
544
|
+
* the two arrays of children (`oldCh` and `newCh`). We keep track of the
|
|
545
|
+
* 'windows' by storing start and end indices and references to the
|
|
546
|
+
* corresponding array entries. Initially the two 'windows' are basically equal
|
|
547
|
+
* to the entire array, but we progressively narrow the windows until there are
|
|
548
|
+
* no children left to update by doing the following:
|
|
549
|
+
*
|
|
550
|
+
* 1. Skip any `null` entries at the beginning or end of the two arrays, so
|
|
551
|
+
* that if we have an initial array like the following we'll end up dealing
|
|
552
|
+
* only with a window bounded by the highlighted elements:
|
|
553
|
+
*
|
|
554
|
+
* [null, null, VNode1 , ... , VNode2, null, null]
|
|
555
|
+
* ^^^^^^ ^^^^^^
|
|
556
|
+
*
|
|
557
|
+
* 2. Check to see if the elements at the head and tail positions are equal
|
|
558
|
+
* across the windows. This will basically detect elements which haven't
|
|
559
|
+
* been added, removed, or changed position, i.e. if you had the following
|
|
560
|
+
* VNode elements (represented as HTML):
|
|
561
|
+
*
|
|
562
|
+
* oldVNode: `<div><p><span>HEY</span></p></div>`
|
|
563
|
+
* newVNode: `<div><p><span>THERE</span></p></div>`
|
|
564
|
+
*
|
|
565
|
+
* Then when comparing the children of the `<div>` tag we check the equality
|
|
566
|
+
* of the VNodes corresponding to the `<p>` tags and, since they are the
|
|
567
|
+
* same tag in the same position, we'd be able to avoid completely
|
|
568
|
+
* re-rendering the subtree under them with a new DOM element and would just
|
|
569
|
+
* call out to `patch` to handle reconciling their children and so on.
|
|
570
|
+
*
|
|
571
|
+
* 3. Check, for both windows, to see if the element at the beginning of the
|
|
572
|
+
* window corresponds to the element at the end of the other window. This is
|
|
573
|
+
* a heuristic which will let us identify _some_ situations in which
|
|
574
|
+
* elements have changed position, for instance it _should_ detect that the
|
|
575
|
+
* children nodes themselves have not changed but merely moved in the
|
|
576
|
+
* following example:
|
|
577
|
+
*
|
|
578
|
+
* oldVNode: `<div><element-one /><element-two /></div>`
|
|
579
|
+
* newVNode: `<div><element-two /><element-one /></div>`
|
|
580
|
+
*
|
|
581
|
+
* If we find cases like this then we also need to move the concrete DOM
|
|
582
|
+
* elements corresponding to the moved children to write the re-order to the
|
|
583
|
+
* DOM.
|
|
584
|
+
*
|
|
585
|
+
* 4. Finally, if VNodes have the `key` attribute set on them we check for any
|
|
586
|
+
* nodes in the old children which have the same key as the first element in
|
|
587
|
+
* our window on the new children. If we find such a node we handle calling
|
|
588
|
+
* out to `patch`, moving relevant DOM nodes, and so on, in accordance with
|
|
589
|
+
* what we find.
|
|
590
|
+
*
|
|
591
|
+
* Finally, once we've narrowed our 'windows' to the point that either of them
|
|
592
|
+
* collapse (i.e. they have length 0) we then handle any remaining VNode
|
|
593
|
+
* insertion or deletion that needs to happen to get a DOM state that correctly
|
|
594
|
+
* reflects the new child VNodes. If, for instance, after our window on the old
|
|
595
|
+
* children has collapsed we still have more nodes on the new children that
|
|
596
|
+
* we haven't dealt with yet then we need to add them, or if the new children
|
|
597
|
+
* collapse but we still have unhandled _old_ children then we need to make
|
|
598
|
+
* sure the corresponding DOM nodes are removed.
|
|
599
|
+
*
|
|
600
|
+
* @param parentElm the node into which the parent VNode is rendered
|
|
601
|
+
* @param oldCh the old children of the parent node
|
|
602
|
+
* @param newVNode the new VNode which will replace the parent
|
|
603
|
+
* @param newCh the new children of the parent node
|
|
604
|
+
*/
|
|
404
605
|
const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
405
606
|
let oldStartIdx = 0;
|
|
406
607
|
let newStartIdx = 0;
|
|
@@ -413,7 +614,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
413
614
|
let node;
|
|
414
615
|
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
|
|
415
616
|
if (oldStartVnode == null) {
|
|
416
|
-
//
|
|
617
|
+
// VNode might have been moved left
|
|
417
618
|
oldStartVnode = oldCh[++oldStartIdx];
|
|
418
619
|
}
|
|
419
620
|
else if (oldEndVnode == null) {
|
|
@@ -426,34 +627,67 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
426
627
|
newEndVnode = newCh[--newEndIdx];
|
|
427
628
|
}
|
|
428
629
|
else if (isSameVnode(oldStartVnode, newStartVnode)) {
|
|
630
|
+
// if the start nodes are the same then we should patch the new VNode
|
|
631
|
+
// onto the old one, and increment our `newStartIdx` and `oldStartIdx`
|
|
632
|
+
// indices to reflect that. We don't need to move any DOM Nodes around
|
|
633
|
+
// since things are matched up in order.
|
|
429
634
|
patch(oldStartVnode, newStartVnode);
|
|
430
635
|
oldStartVnode = oldCh[++oldStartIdx];
|
|
431
636
|
newStartVnode = newCh[++newStartIdx];
|
|
432
637
|
}
|
|
433
638
|
else if (isSameVnode(oldEndVnode, newEndVnode)) {
|
|
639
|
+
// likewise, if the end nodes are the same we patch new onto old and
|
|
640
|
+
// decrement our end indices, and also likewise in this case we don't
|
|
641
|
+
// need to move any DOM Nodes.
|
|
434
642
|
patch(oldEndVnode, newEndVnode);
|
|
435
643
|
oldEndVnode = oldCh[--oldEndIdx];
|
|
436
644
|
newEndVnode = newCh[--newEndIdx];
|
|
437
645
|
}
|
|
438
646
|
else if (isSameVnode(oldStartVnode, newEndVnode)) {
|
|
439
647
|
patch(oldStartVnode, newEndVnode);
|
|
648
|
+
// We need to move the element for `oldStartVnode` into a position which
|
|
649
|
+
// will be appropriate for `newEndVnode`. For this we can use
|
|
650
|
+
// `.insertBefore` and `oldEndVnode.$elm$.nextSibling`. If there is a
|
|
651
|
+
// sibling for `oldEndVnode.$elm$` then we want to move the DOM node for
|
|
652
|
+
// `oldStartVnode` between `oldEndVnode` and it's sibling, like so:
|
|
653
|
+
//
|
|
654
|
+
// <old-start-node />
|
|
655
|
+
// <some-intervening-node />
|
|
656
|
+
// <old-end-node />
|
|
657
|
+
// <!-- -> <-- `oldStartVnode.$elm$` should be inserted here
|
|
658
|
+
// <next-sibling />
|
|
659
|
+
//
|
|
660
|
+
// If instead `oldEndVnode.$elm$` has no sibling then we just want to put
|
|
661
|
+
// the node for `oldStartVnode` at the end of the children of
|
|
662
|
+
// `parentElm`. Luckily, `Node.nextSibling` will return `null` if there
|
|
663
|
+
// aren't any siblings, and passing `null` to `Node.insertBefore` will
|
|
664
|
+
// append it to the children of the parent element.
|
|
440
665
|
parentElm.insertBefore(oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
|
|
441
666
|
oldStartVnode = oldCh[++oldStartIdx];
|
|
442
667
|
newEndVnode = newCh[--newEndIdx];
|
|
443
668
|
}
|
|
444
669
|
else if (isSameVnode(oldEndVnode, newStartVnode)) {
|
|
445
670
|
patch(oldEndVnode, newStartVnode);
|
|
671
|
+
// We've already checked above if `oldStartVnode` and `newStartVnode` are
|
|
672
|
+
// the same node, so since we're here we know that they are not. Thus we
|
|
673
|
+
// can move the element for `oldEndVnode` _before_ the element for
|
|
674
|
+
// `oldStartVnode`, leaving `oldStartVnode` to be reconciled in the
|
|
675
|
+
// future.
|
|
446
676
|
parentElm.insertBefore(oldEndVnode.$elm$, oldStartVnode.$elm$);
|
|
447
677
|
oldEndVnode = oldCh[--oldEndIdx];
|
|
448
678
|
newStartVnode = newCh[++newStartIdx];
|
|
449
679
|
}
|
|
450
680
|
else {
|
|
451
681
|
{
|
|
452
|
-
//
|
|
682
|
+
// We either didn't find an element in the old children that matches
|
|
683
|
+
// the key of the first new child OR the build is not using `key`
|
|
684
|
+
// attributes at all. In either case we need to create a new element
|
|
685
|
+
// for the new node.
|
|
453
686
|
node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx);
|
|
454
687
|
newStartVnode = newCh[++newStartIdx];
|
|
455
688
|
}
|
|
456
689
|
if (node) {
|
|
690
|
+
// if we created a new node then handle inserting it to the DOM
|
|
457
691
|
{
|
|
458
692
|
oldStartVnode.$elm$.parentNode.insertBefore(node, oldStartVnode.$elm$);
|
|
459
693
|
}
|
|
@@ -461,27 +695,56 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
461
695
|
}
|
|
462
696
|
}
|
|
463
697
|
if (oldStartIdx > oldEndIdx) {
|
|
698
|
+
// we have some more new nodes to add which don't match up with old nodes
|
|
464
699
|
addVnodes(parentElm, newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$, newVNode, newCh, newStartIdx, newEndIdx);
|
|
465
700
|
}
|
|
466
|
-
else if (
|
|
701
|
+
else if (newStartIdx > newEndIdx) {
|
|
702
|
+
// there are nodes in the `oldCh` array which no longer correspond to nodes
|
|
703
|
+
// in the new array, so lets remove them (which entails cleaning up the
|
|
704
|
+
// relevant DOM nodes)
|
|
467
705
|
removeVnodes(oldCh, oldStartIdx, oldEndIdx);
|
|
468
706
|
}
|
|
469
707
|
};
|
|
470
|
-
|
|
708
|
+
/**
|
|
709
|
+
* Compare two VNodes to determine if they are the same
|
|
710
|
+
*
|
|
711
|
+
* **NB**: This function is an equality _heuristic_ based on the available
|
|
712
|
+
* information set on the two VNodes and can be misleading under certain
|
|
713
|
+
* circumstances. In particular, if the two nodes do not have `key` attrs
|
|
714
|
+
* (available under `$key$` on VNodes) then the function falls back on merely
|
|
715
|
+
* checking that they have the same tag.
|
|
716
|
+
*
|
|
717
|
+
* So, in other words, if `key` attrs are not set on VNodes which may be
|
|
718
|
+
* changing order within a `children` array or something along those lines then
|
|
719
|
+
* we could obtain a false negative and then have to do needless re-rendering
|
|
720
|
+
* (i.e. we'd say two VNodes aren't equal when in fact they should be).
|
|
721
|
+
*
|
|
722
|
+
* @param leftVNode the first VNode to check
|
|
723
|
+
* @param rightVNode the second VNode to check
|
|
724
|
+
* @returns whether they're equal or not
|
|
725
|
+
*/
|
|
726
|
+
const isSameVnode = (leftVNode, rightVNode) => {
|
|
471
727
|
// compare if two vnode to see if they're "technically" the same
|
|
472
728
|
// need to have the same element tag, and same key to be the same
|
|
473
|
-
if (
|
|
729
|
+
if (leftVNode.$tag$ === rightVNode.$tag$) {
|
|
474
730
|
return true;
|
|
475
731
|
}
|
|
476
732
|
return false;
|
|
477
733
|
};
|
|
734
|
+
/**
|
|
735
|
+
* Handle reconciling an outdated VNode with a new one which corresponds to
|
|
736
|
+
* it. This function handles flushing updates to the DOM and reconciling the
|
|
737
|
+
* children of the two nodes (if any).
|
|
738
|
+
*
|
|
739
|
+
* @param oldVNode an old VNode whose DOM element and children we want to update
|
|
740
|
+
* @param newVNode a new VNode representing an updated version of the old one
|
|
741
|
+
*/
|
|
478
742
|
const patch = (oldVNode, newVNode) => {
|
|
479
743
|
const elm = (newVNode.$elm$ = oldVNode.$elm$);
|
|
480
744
|
const oldChildren = oldVNode.$children$;
|
|
481
745
|
const newChildren = newVNode.$children$;
|
|
482
746
|
const text = newVNode.$text$;
|
|
483
|
-
if (
|
|
484
|
-
// element node
|
|
747
|
+
if (text === null) {
|
|
485
748
|
{
|
|
486
749
|
{
|
|
487
750
|
// either this is the first render of an element OR it's an update
|
|
@@ -490,25 +753,26 @@ const patch = (oldVNode, newVNode) => {
|
|
|
490
753
|
updateElement(oldVNode, newVNode, isSvgMode);
|
|
491
754
|
}
|
|
492
755
|
}
|
|
493
|
-
if (
|
|
756
|
+
if (oldChildren !== null && newChildren !== null) {
|
|
494
757
|
// looks like there's child vnodes for both the old and new vnodes
|
|
758
|
+
// so we need to call `updateChildren` to reconcile them
|
|
495
759
|
updateChildren(elm, oldChildren, newVNode, newChildren);
|
|
496
760
|
}
|
|
497
761
|
else if (newChildren !== null) {
|
|
498
762
|
// no old child vnodes, but there are new child vnodes to add
|
|
499
|
-
if (
|
|
763
|
+
if (oldVNode.$text$ !== null) {
|
|
500
764
|
// the old vnode was text, so be sure to clear it out
|
|
501
765
|
elm.textContent = '';
|
|
502
766
|
}
|
|
503
767
|
// add the new vnode children
|
|
504
768
|
addVnodes(elm, null, newVNode, newChildren, 0, newChildren.length - 1);
|
|
505
769
|
}
|
|
506
|
-
else if (
|
|
770
|
+
else if (oldChildren !== null) {
|
|
507
771
|
// no new child vnodes, but there are old child vnodes to remove
|
|
508
772
|
removeVnodes(oldChildren, 0, oldChildren.length - 1);
|
|
509
773
|
}
|
|
510
774
|
}
|
|
511
|
-
else if (
|
|
775
|
+
else if (oldVNode.$text$ !== text) {
|
|
512
776
|
// update the text content for the text only vnode
|
|
513
777
|
// and also only if the text is different than before
|
|
514
778
|
elm.data = text;
|
|
@@ -520,47 +784,40 @@ const callNodeRefs = (vNode) => {
|
|
|
520
784
|
vNode.$children$ && vNode.$children$.map(callNodeRefs);
|
|
521
785
|
}
|
|
522
786
|
};
|
|
787
|
+
/**
|
|
788
|
+
* The main entry point for Stencil's virtual DOM-based rendering engine
|
|
789
|
+
*
|
|
790
|
+
* Given a {@link d.HostRef} container and some virtual DOM nodes, this
|
|
791
|
+
* function will handle creating a virtual DOM tree with a single root, patching
|
|
792
|
+
* the current virtual DOM tree onto an old one (if any), dealing with slot
|
|
793
|
+
* relocation, and reflecting attributes.
|
|
794
|
+
*
|
|
795
|
+
* @param hostRef data needed to root and render the virtual DOM tree, such as
|
|
796
|
+
* the DOM node into which it should be rendered.
|
|
797
|
+
* @param renderFnResults the virtual DOM nodes to be rendered
|
|
798
|
+
*/
|
|
523
799
|
const renderVdom = (hostRef, renderFnResults) => {
|
|
524
800
|
const hostElm = hostRef.$hostElement$;
|
|
525
801
|
const oldVNode = hostRef.$vnode$ || newVNode(null, null);
|
|
526
802
|
const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
|
|
527
803
|
rootVnode.$tag$ = null;
|
|
528
|
-
rootVnode.$flags$ |= 4 /* isHost */;
|
|
804
|
+
rootVnode.$flags$ |= 4 /* VNODE_FLAGS.isHost */;
|
|
529
805
|
hostRef.$vnode$ = rootVnode;
|
|
530
|
-
rootVnode.$elm$ = oldVNode.$elm$ = (
|
|
806
|
+
rootVnode.$elm$ = oldVNode.$elm$ = (hostElm);
|
|
531
807
|
// synchronous patch
|
|
532
808
|
patch(oldVNode, rootVnode);
|
|
533
809
|
};
|
|
534
|
-
const getElement = (ref) => ( getHostRef(ref).$hostElement$ );
|
|
535
|
-
const createEvent = (ref, name, flags) => {
|
|
536
|
-
const elm = getElement(ref);
|
|
537
|
-
return {
|
|
538
|
-
emit: (detail) => {
|
|
539
|
-
return emitEvent(elm, name, {
|
|
540
|
-
bubbles: !!(flags & 4 /* Bubbles */),
|
|
541
|
-
composed: !!(flags & 2 /* Composed */),
|
|
542
|
-
cancelable: !!(flags & 1 /* Cancellable */),
|
|
543
|
-
detail,
|
|
544
|
-
});
|
|
545
|
-
},
|
|
546
|
-
};
|
|
547
|
-
};
|
|
548
|
-
const emitEvent = (elm, name, opts) => {
|
|
549
|
-
const ev = plt.ce(name, opts);
|
|
550
|
-
elm.dispatchEvent(ev);
|
|
551
|
-
return ev;
|
|
552
|
-
};
|
|
553
810
|
const attachToAncestor = (hostRef, ancestorComponent) => {
|
|
554
|
-
if (
|
|
555
|
-
ancestorComponent['s-p'].push(new Promise(r => (hostRef.$onRenderResolve$ = r)));
|
|
811
|
+
if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
|
|
812
|
+
ancestorComponent['s-p'].push(new Promise((r) => (hostRef.$onRenderResolve$ = r)));
|
|
556
813
|
}
|
|
557
814
|
};
|
|
558
815
|
const scheduleUpdate = (hostRef, isInitialLoad) => {
|
|
559
816
|
{
|
|
560
|
-
hostRef.$flags$ |= 16 /* isQueuedForUpdate */;
|
|
817
|
+
hostRef.$flags$ |= 16 /* HOST_FLAGS.isQueuedForUpdate */;
|
|
561
818
|
}
|
|
562
|
-
if (
|
|
563
|
-
hostRef.$flags$ |= 512 /* needsRerender */;
|
|
819
|
+
if (hostRef.$flags$ & 4 /* HOST_FLAGS.isWaitingForChildren */) {
|
|
820
|
+
hostRef.$flags$ |= 512 /* HOST_FLAGS.needsRerender */;
|
|
564
821
|
return;
|
|
565
822
|
}
|
|
566
823
|
attachToAncestor(hostRef, hostRef.$ancestorComponent$);
|
|
@@ -568,11 +825,11 @@ const scheduleUpdate = (hostRef, isInitialLoad) => {
|
|
|
568
825
|
// has already fired off its lifecycle update then
|
|
569
826
|
// fire off the initial update
|
|
570
827
|
const dispatch = () => dispatchHooks(hostRef, isInitialLoad);
|
|
571
|
-
return
|
|
828
|
+
return writeTask(dispatch) ;
|
|
572
829
|
};
|
|
573
830
|
const dispatchHooks = (hostRef, isInitialLoad) => {
|
|
574
831
|
const endSchedule = createTime('scheduleUpdate', hostRef.$cmpMeta$.$tagName$);
|
|
575
|
-
const instance =
|
|
832
|
+
const instance = hostRef.$lazyInstance$ ;
|
|
576
833
|
let promise;
|
|
577
834
|
if (isInitialLoad) {
|
|
578
835
|
{
|
|
@@ -590,7 +847,7 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
|
|
|
590
847
|
const elm = hostRef.$hostElement$;
|
|
591
848
|
const endUpdate = createTime('update', hostRef.$cmpMeta$.$tagName$);
|
|
592
849
|
const rc = elm['s-rc'];
|
|
593
|
-
if (
|
|
850
|
+
if (isInitialLoad) {
|
|
594
851
|
// DOM WRITE!
|
|
595
852
|
attachStyles(hostRef);
|
|
596
853
|
}
|
|
@@ -598,11 +855,11 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
|
|
|
598
855
|
{
|
|
599
856
|
callRender(hostRef, instance);
|
|
600
857
|
}
|
|
601
|
-
if (
|
|
858
|
+
if (rc) {
|
|
602
859
|
// ok, so turns out there are some child host elements
|
|
603
860
|
// waiting on this parent element to load
|
|
604
861
|
// let's fire off all update callbacks waiting
|
|
605
|
-
rc.map(cb => cb());
|
|
862
|
+
rc.map((cb) => cb());
|
|
606
863
|
elm['s-rc'] = undefined;
|
|
607
864
|
}
|
|
608
865
|
endRender();
|
|
@@ -615,19 +872,19 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
|
|
|
615
872
|
}
|
|
616
873
|
else {
|
|
617
874
|
Promise.all(childrenPromises).then(postUpdate);
|
|
618
|
-
hostRef.$flags$ |= 4 /* isWaitingForChildren */;
|
|
875
|
+
hostRef.$flags$ |= 4 /* HOST_FLAGS.isWaitingForChildren */;
|
|
619
876
|
childrenPromises.length = 0;
|
|
620
877
|
}
|
|
621
878
|
}
|
|
622
879
|
};
|
|
623
880
|
const callRender = (hostRef, instance, elm) => {
|
|
624
881
|
try {
|
|
625
|
-
instance =
|
|
882
|
+
instance = instance.render() ;
|
|
626
883
|
{
|
|
627
|
-
hostRef.$flags$ &= ~16 /* isQueuedForUpdate */;
|
|
884
|
+
hostRef.$flags$ &= ~16 /* HOST_FLAGS.isQueuedForUpdate */;
|
|
628
885
|
}
|
|
629
886
|
{
|
|
630
|
-
hostRef.$flags$ |= 2 /* hasRendered */;
|
|
887
|
+
hostRef.$flags$ |= 2 /* HOST_FLAGS.hasRendered */;
|
|
631
888
|
}
|
|
632
889
|
{
|
|
633
890
|
{
|
|
@@ -649,13 +906,13 @@ const postUpdateComponent = (hostRef) => {
|
|
|
649
906
|
const tagName = hostRef.$cmpMeta$.$tagName$;
|
|
650
907
|
const elm = hostRef.$hostElement$;
|
|
651
908
|
const endPostUpdate = createTime('postUpdate', tagName);
|
|
652
|
-
const instance =
|
|
909
|
+
const instance = hostRef.$lazyInstance$ ;
|
|
653
910
|
const ancestorComponent = hostRef.$ancestorComponent$;
|
|
654
911
|
{
|
|
655
912
|
safeCall(instance, 'componentDidRender');
|
|
656
913
|
}
|
|
657
|
-
if (!(hostRef.$flags$ & 64 /* hasLoadedComponent */)) {
|
|
658
|
-
hostRef.$flags$ |= 64 /* hasLoadedComponent */;
|
|
914
|
+
if (!(hostRef.$flags$ & 64 /* HOST_FLAGS.hasLoadedComponent */)) {
|
|
915
|
+
hostRef.$flags$ |= 64 /* HOST_FLAGS.hasLoadedComponent */;
|
|
659
916
|
{
|
|
660
917
|
// DOM WRITE!
|
|
661
918
|
addHydratedFlag(elm);
|
|
@@ -684,10 +941,10 @@ const postUpdateComponent = (hostRef) => {
|
|
|
684
941
|
hostRef.$onRenderResolve$();
|
|
685
942
|
hostRef.$onRenderResolve$ = undefined;
|
|
686
943
|
}
|
|
687
|
-
if (hostRef.$flags$ & 512 /* needsRerender */) {
|
|
944
|
+
if (hostRef.$flags$ & 512 /* HOST_FLAGS.needsRerender */) {
|
|
688
945
|
nextTick(() => scheduleUpdate(hostRef, false));
|
|
689
946
|
}
|
|
690
|
-
hostRef.$flags$ &= ~(4 /* isWaitingForChildren */ | 512 /* needsRerender */);
|
|
947
|
+
hostRef.$flags$ &= ~(4 /* HOST_FLAGS.isWaitingForChildren */ | 512 /* HOST_FLAGS.needsRerender */);
|
|
691
948
|
}
|
|
692
949
|
// ( •_•)
|
|
693
950
|
// ( •_•)>⌐■-■
|
|
@@ -715,47 +972,31 @@ const safeCall = (instance, method, arg) => {
|
|
|
715
972
|
const then = (promise, thenFn) => {
|
|
716
973
|
return promise && promise.then ? promise.then(thenFn) : thenFn();
|
|
717
974
|
};
|
|
718
|
-
const addHydratedFlag = (elm) =>
|
|
719
|
-
|
|
720
|
-
// ensure this value is of the correct prop type
|
|
721
|
-
if (propValue != null && !isComplexType(propValue)) {
|
|
722
|
-
if ( propType & 4 /* Boolean */) {
|
|
723
|
-
// per the HTML spec, any string value means it is a boolean true value
|
|
724
|
-
// but we'll cheat here and say that the string "false" is the boolean false
|
|
725
|
-
return propValue === 'false' ? false : propValue === '' || !!propValue;
|
|
726
|
-
}
|
|
727
|
-
if ( propType & 1 /* String */) {
|
|
728
|
-
// could have been passed as a number or boolean
|
|
729
|
-
// but we still want it as a string
|
|
730
|
-
return String(propValue);
|
|
731
|
-
}
|
|
732
|
-
// redundant return here for better minification
|
|
733
|
-
return propValue;
|
|
734
|
-
}
|
|
735
|
-
// not sure exactly what type we want
|
|
736
|
-
// so no need to change to a different type
|
|
737
|
-
return propValue;
|
|
738
|
-
};
|
|
975
|
+
const addHydratedFlag = (elm) => elm.classList.add('hydrated')
|
|
976
|
+
;
|
|
739
977
|
const getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
|
|
740
978
|
const setValue = (ref, propName, newVal, cmpMeta) => {
|
|
741
979
|
// check our new property value against our internal value
|
|
742
980
|
const hostRef = getHostRef(ref);
|
|
743
|
-
const elm =
|
|
981
|
+
const elm = hostRef.$hostElement$ ;
|
|
744
982
|
const oldVal = hostRef.$instanceValues$.get(propName);
|
|
745
983
|
const flags = hostRef.$flags$;
|
|
746
|
-
const instance =
|
|
984
|
+
const instance = hostRef.$lazyInstance$ ;
|
|
747
985
|
newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
|
|
748
|
-
|
|
986
|
+
// explicitly check for NaN on both sides, as `NaN === NaN` is always false
|
|
987
|
+
const areBothNaN = Number.isNaN(oldVal) && Number.isNaN(newVal);
|
|
988
|
+
const didValueChange = newVal !== oldVal && !areBothNaN;
|
|
989
|
+
if ((!(flags & 8 /* HOST_FLAGS.isConstructingInstance */) || oldVal === undefined) && didValueChange) {
|
|
749
990
|
// gadzooks! the property's value has changed!!
|
|
750
991
|
// set our new value!
|
|
751
992
|
hostRef.$instanceValues$.set(propName, newVal);
|
|
752
|
-
if (
|
|
993
|
+
if (instance) {
|
|
753
994
|
// get an array of method names of watch functions to call
|
|
754
|
-
if (
|
|
995
|
+
if (cmpMeta.$watchers$ && flags & 128 /* HOST_FLAGS.isWatchReady */) {
|
|
755
996
|
const watchMethods = cmpMeta.$watchers$[propName];
|
|
756
997
|
if (watchMethods) {
|
|
757
998
|
// this instance is watching for when this property changed
|
|
758
|
-
watchMethods.map(watchMethodName => {
|
|
999
|
+
watchMethods.map((watchMethodName) => {
|
|
759
1000
|
try {
|
|
760
1001
|
// fire off each of the watch methods that are watching this property
|
|
761
1002
|
instance[watchMethodName](newVal, oldVal, propName);
|
|
@@ -766,7 +1007,7 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
|
|
|
766
1007
|
});
|
|
767
1008
|
}
|
|
768
1009
|
}
|
|
769
|
-
if (
|
|
1010
|
+
if ((flags & (2 /* HOST_FLAGS.hasRendered */ | 16 /* HOST_FLAGS.isQueuedForUpdate */)) === 2 /* HOST_FLAGS.hasRendered */) {
|
|
770
1011
|
// looks like this value actually changed, so we've got work to do!
|
|
771
1012
|
// but only if we've already rendered, otherwise just chill out
|
|
772
1013
|
// queue that we need to do an update, but don't worry about queuing
|
|
@@ -776,16 +1017,27 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
|
|
|
776
1017
|
}
|
|
777
1018
|
}
|
|
778
1019
|
};
|
|
1020
|
+
/**
|
|
1021
|
+
* Attach a series of runtime constructs to a compiled Stencil component
|
|
1022
|
+
* constructor, including getters and setters for the `@Prop` and `@State`
|
|
1023
|
+
* decorators, callbacks for when attributes change, and so on.
|
|
1024
|
+
*
|
|
1025
|
+
* @param Cstr the constructor for a component that we need to process
|
|
1026
|
+
* @param cmpMeta metadata collected previously about the component
|
|
1027
|
+
* @param flags a number used to store a series of bit flags
|
|
1028
|
+
* @returns a reference to the same constructor passed in (but now mutated)
|
|
1029
|
+
*/
|
|
779
1030
|
const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
780
|
-
if (
|
|
781
|
-
if (
|
|
1031
|
+
if (cmpMeta.$members$) {
|
|
1032
|
+
if (Cstr.watchers) {
|
|
782
1033
|
cmpMeta.$watchers$ = Cstr.watchers;
|
|
783
1034
|
}
|
|
784
1035
|
// It's better to have a const than two Object.entries()
|
|
785
1036
|
const members = Object.entries(cmpMeta.$members$);
|
|
786
1037
|
const prototype = Cstr.prototype;
|
|
787
1038
|
members.map(([memberName, [memberFlags]]) => {
|
|
788
|
-
if (
|
|
1039
|
+
if ((memberFlags & 31 /* MEMBER_FLAGS.Prop */ ||
|
|
1040
|
+
((flags & 2 /* PROXY_FLAGS.proxyState */) && memberFlags & 32 /* MEMBER_FLAGS.State */))) {
|
|
789
1041
|
// proxyComponent - prop
|
|
790
1042
|
Object.defineProperty(prototype, memberName, {
|
|
791
1043
|
get() {
|
|
@@ -800,7 +1052,8 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
800
1052
|
enumerable: true,
|
|
801
1053
|
});
|
|
802
1054
|
}
|
|
803
|
-
else if (
|
|
1055
|
+
else if (flags & 1 /* PROXY_FLAGS.isElementConstructor */ &&
|
|
1056
|
+
memberFlags & 64 /* MEMBER_FLAGS.Method */) {
|
|
804
1057
|
// proxyComponent - method
|
|
805
1058
|
Object.defineProperty(prototype, memberName, {
|
|
806
1059
|
value(...args) {
|
|
@@ -810,18 +1063,63 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
810
1063
|
});
|
|
811
1064
|
}
|
|
812
1065
|
});
|
|
813
|
-
if (
|
|
1066
|
+
if ((flags & 1 /* PROXY_FLAGS.isElementConstructor */)) {
|
|
814
1067
|
const attrNameToPropName = new Map();
|
|
815
1068
|
prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
|
|
816
1069
|
plt.jmp(() => {
|
|
817
1070
|
const propName = attrNameToPropName.get(attrName);
|
|
1071
|
+
// In a web component lifecycle the attributeChangedCallback runs prior to connectedCallback
|
|
1072
|
+
// in the case where an attribute was set inline.
|
|
1073
|
+
// ```html
|
|
1074
|
+
// <my-component some-attribute="some-value"></my-component>
|
|
1075
|
+
// ```
|
|
1076
|
+
//
|
|
1077
|
+
// There is an edge case where a developer sets the attribute inline on a custom element and then
|
|
1078
|
+
// programmatically changes it before it has been upgraded as shown below:
|
|
1079
|
+
//
|
|
1080
|
+
// ```html
|
|
1081
|
+
// <!-- this component has _not_ been upgraded yet -->
|
|
1082
|
+
// <my-component id="test" some-attribute="some-value"></my-component>
|
|
1083
|
+
// <script>
|
|
1084
|
+
// // grab non-upgraded component
|
|
1085
|
+
// el = document.querySelector("#test");
|
|
1086
|
+
// el.someAttribute = "another-value";
|
|
1087
|
+
// // upgrade component
|
|
1088
|
+
// customElements.define('my-component', MyComponent);
|
|
1089
|
+
// </script>
|
|
1090
|
+
// ```
|
|
1091
|
+
// In this case if we do not unshadow here and use the value of the shadowing property, attributeChangedCallback
|
|
1092
|
+
// will be called with `newValue = "some-value"` and will set the shadowed property (this.someAttribute = "another-value")
|
|
1093
|
+
// to the value that was set inline i.e. "some-value" from above example. When
|
|
1094
|
+
// the connectedCallback attempts to unshadow it will use "some-value" as the initial value rather than "another-value"
|
|
1095
|
+
//
|
|
1096
|
+
// The case where the attribute was NOT set inline but was not set programmatically shall be handled/unshadowed
|
|
1097
|
+
// by connectedCallback as this attributeChangedCallback will not fire.
|
|
1098
|
+
//
|
|
1099
|
+
// https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
|
|
1100
|
+
//
|
|
1101
|
+
// TODO(STENCIL-16) we should think about whether or not we actually want to be reflecting the attributes to
|
|
1102
|
+
// properties here given that this goes against best practices outlined here
|
|
1103
|
+
// https://developers.google.com/web/fundamentals/web-components/best-practices#avoid-reentrancy
|
|
1104
|
+
if (this.hasOwnProperty(propName)) {
|
|
1105
|
+
newValue = this[propName];
|
|
1106
|
+
delete this[propName];
|
|
1107
|
+
}
|
|
1108
|
+
else if (prototype.hasOwnProperty(propName) &&
|
|
1109
|
+
typeof this[propName] === 'number' &&
|
|
1110
|
+
this[propName] == newValue) {
|
|
1111
|
+
// if the propName exists on the prototype of `Cstr`, this update may be a result of Stencil using native
|
|
1112
|
+
// APIs to reflect props as attributes. Calls to `setAttribute(someElement, propName)` will result in
|
|
1113
|
+
// `propName` to be converted to a `DOMString`, which may not be what we want for other primitive props.
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
818
1116
|
this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
|
|
819
1117
|
});
|
|
820
1118
|
};
|
|
821
1119
|
// create an array of attributes to observe
|
|
822
1120
|
// and also create a map of html attribute name to js property name
|
|
823
1121
|
Cstr.observedAttributes = members
|
|
824
|
-
.filter(([_, m]) => m[0] & 15 /* HasAttribute */) // filter to only keep props that should match attributes
|
|
1122
|
+
.filter(([_, m]) => m[0] & 15 /* MEMBER_FLAGS.HasAttribute */) // filter to only keep props that should match attributes
|
|
825
1123
|
.map(([propName, m]) => {
|
|
826
1124
|
const attrName = m[1] || propName;
|
|
827
1125
|
attrNameToPropName.set(attrName, propName);
|
|
@@ -833,10 +1131,10 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
833
1131
|
};
|
|
834
1132
|
const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
|
|
835
1133
|
// initializeComponent
|
|
836
|
-
if (
|
|
1134
|
+
if ((hostRef.$flags$ & 32 /* HOST_FLAGS.hasInitializedComponent */) === 0) {
|
|
837
1135
|
{
|
|
838
1136
|
// we haven't initialized this element yet
|
|
839
|
-
hostRef.$flags$ |= 32 /* hasInitializedComponent */;
|
|
1137
|
+
hostRef.$flags$ |= 32 /* HOST_FLAGS.hasInitializedComponent */;
|
|
840
1138
|
// lazy loaded components
|
|
841
1139
|
// request the component's implementation to be
|
|
842
1140
|
// wired up with the host element
|
|
@@ -847,14 +1145,14 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
847
1145
|
Cstr = await Cstr;
|
|
848
1146
|
endLoad();
|
|
849
1147
|
}
|
|
850
|
-
if (
|
|
851
|
-
// we'
|
|
1148
|
+
if (!Cstr.isProxied) {
|
|
1149
|
+
// we've never proxied this Constructor before
|
|
852
1150
|
// let's add the getters/setters to its prototype before
|
|
853
1151
|
// the first time we create an instance of the implementation
|
|
854
1152
|
{
|
|
855
1153
|
cmpMeta.$watchers$ = Cstr.watchers;
|
|
856
1154
|
}
|
|
857
|
-
proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
|
|
1155
|
+
proxyComponent(Cstr, cmpMeta, 2 /* PROXY_FLAGS.proxyState */);
|
|
858
1156
|
Cstr.isProxied = true;
|
|
859
1157
|
}
|
|
860
1158
|
const endNewInstance = createTime('createInstance', cmpMeta.$tagName$);
|
|
@@ -862,7 +1160,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
862
1160
|
// but let's keep track of when we start and stop
|
|
863
1161
|
// so that the getters/setters don't incorrectly step on data
|
|
864
1162
|
{
|
|
865
|
-
hostRef.$flags$ |= 8 /* isConstructingInstance */;
|
|
1163
|
+
hostRef.$flags$ |= 8 /* HOST_FLAGS.isConstructingInstance */;
|
|
866
1164
|
}
|
|
867
1165
|
// construct the lazy-loaded component implementation
|
|
868
1166
|
// passing the hostRef is very important during
|
|
@@ -875,20 +1173,20 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
875
1173
|
consoleError(e);
|
|
876
1174
|
}
|
|
877
1175
|
{
|
|
878
|
-
hostRef.$flags$ &= ~8 /* isConstructingInstance */;
|
|
1176
|
+
hostRef.$flags$ &= ~8 /* HOST_FLAGS.isConstructingInstance */;
|
|
879
1177
|
}
|
|
880
1178
|
{
|
|
881
|
-
hostRef.$flags$ |= 128 /* isWatchReady */;
|
|
1179
|
+
hostRef.$flags$ |= 128 /* HOST_FLAGS.isWatchReady */;
|
|
882
1180
|
}
|
|
883
1181
|
endNewInstance();
|
|
884
1182
|
}
|
|
885
|
-
if (
|
|
1183
|
+
if (Cstr.style) {
|
|
886
1184
|
// this component has styles but we haven't registered them yet
|
|
887
1185
|
let style = Cstr.style;
|
|
888
1186
|
const scopeId = getScopeId(cmpMeta);
|
|
889
1187
|
if (!styles.has(scopeId)) {
|
|
890
1188
|
const endRegisterStyles = createTime('registerStyles', cmpMeta.$tagName$);
|
|
891
|
-
registerStyle(scopeId, style, !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */));
|
|
1189
|
+
registerStyle(scopeId, style, !!(cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */));
|
|
892
1190
|
endRegisterStyles();
|
|
893
1191
|
}
|
|
894
1192
|
}
|
|
@@ -896,8 +1194,8 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
896
1194
|
// we've successfully created a lazy instance
|
|
897
1195
|
const ancestorComponent = hostRef.$ancestorComponent$;
|
|
898
1196
|
const schedule = () => scheduleUpdate(hostRef, true);
|
|
899
|
-
if (
|
|
900
|
-
// this is the
|
|
1197
|
+
if (ancestorComponent && ancestorComponent['s-rc']) {
|
|
1198
|
+
// this is the initial load and this component it has an ancestor component
|
|
901
1199
|
// but the ancestor component has NOT fired its will update lifecycle yet
|
|
902
1200
|
// so let's just cool our jets and wait for the ancestor to continue first
|
|
903
1201
|
// this will get fired off when the ancestor component
|
|
@@ -910,13 +1208,13 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
910
1208
|
}
|
|
911
1209
|
};
|
|
912
1210
|
const connectedCallback = (elm) => {
|
|
913
|
-
if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
|
|
1211
|
+
if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
|
|
914
1212
|
const hostRef = getHostRef(elm);
|
|
915
1213
|
const cmpMeta = hostRef.$cmpMeta$;
|
|
916
1214
|
const endConnected = createTime('connectedCallback', cmpMeta.$tagName$);
|
|
917
|
-
if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
|
|
1215
|
+
if (!(hostRef.$flags$ & 1 /* HOST_FLAGS.hasConnected */)) {
|
|
918
1216
|
// first time this component has connected
|
|
919
|
-
hostRef.$flags$ |= 1 /* hasConnected */;
|
|
1217
|
+
hostRef.$flags$ |= 1 /* HOST_FLAGS.hasConnected */;
|
|
920
1218
|
{
|
|
921
1219
|
// find the first ancestor component (if there is one) and register
|
|
922
1220
|
// this component as one of the actively loading child components for its ancestor
|
|
@@ -924,8 +1222,7 @@ const connectedCallback = (elm) => {
|
|
|
924
1222
|
while ((ancestorComponent = ancestorComponent.parentNode || ancestorComponent.host)) {
|
|
925
1223
|
// climb up the ancestors looking for the first
|
|
926
1224
|
// component that hasn't finished its lifecycle update yet
|
|
927
|
-
if (
|
|
928
|
-
ancestorComponent['s-p']) {
|
|
1225
|
+
if (ancestorComponent['s-p']) {
|
|
929
1226
|
// we found this components first ancestor component
|
|
930
1227
|
// keep a reference to this component's ancestor component
|
|
931
1228
|
attachToAncestor(hostRef, (hostRef.$ancestorComponent$ = ancestorComponent));
|
|
@@ -935,9 +1232,9 @@ const connectedCallback = (elm) => {
|
|
|
935
1232
|
}
|
|
936
1233
|
// Lazy properties
|
|
937
1234
|
// https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
|
|
938
|
-
if (
|
|
1235
|
+
if (cmpMeta.$members$) {
|
|
939
1236
|
Object.entries(cmpMeta.$members$).map(([memberName, [memberFlags]]) => {
|
|
940
|
-
if (memberFlags & 31 /* Prop */ && elm.hasOwnProperty(memberName)) {
|
|
1237
|
+
if (memberFlags & 31 /* MEMBER_FLAGS.Prop */ && elm.hasOwnProperty(memberName)) {
|
|
941
1238
|
const value = elm[memberName];
|
|
942
1239
|
delete elm[memberName];
|
|
943
1240
|
elm[memberName] = value;
|
|
@@ -952,11 +1249,12 @@ const connectedCallback = (elm) => {
|
|
|
952
1249
|
}
|
|
953
1250
|
};
|
|
954
1251
|
const disconnectedCallback = (elm) => {
|
|
955
|
-
if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
|
|
956
|
-
|
|
1252
|
+
if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
|
|
1253
|
+
getHostRef(elm);
|
|
957
1254
|
}
|
|
958
1255
|
};
|
|
959
1256
|
const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
1257
|
+
var _a;
|
|
960
1258
|
const endBootstrap = createTime();
|
|
961
1259
|
const cmpTags = [];
|
|
962
1260
|
const exclude = options.exclude || [];
|
|
@@ -969,63 +1267,70 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
969
1267
|
let isBootstrapping = true;
|
|
970
1268
|
Object.assign(plt, options);
|
|
971
1269
|
plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
|
|
972
|
-
lazyBundles.map(lazyBundle =>
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
const tagName = cmpMeta.$tagName$;
|
|
986
|
-
const HostElement = class extends HTMLElement {
|
|
987
|
-
// StencilLazyHost
|
|
988
|
-
constructor(self) {
|
|
989
|
-
// @ts-ignore
|
|
990
|
-
super(self);
|
|
991
|
-
self = this;
|
|
992
|
-
registerHost(self, cmpMeta);
|
|
1270
|
+
lazyBundles.map((lazyBundle) => {
|
|
1271
|
+
lazyBundle[1].map((compactMeta) => {
|
|
1272
|
+
const cmpMeta = {
|
|
1273
|
+
$flags$: compactMeta[0],
|
|
1274
|
+
$tagName$: compactMeta[1],
|
|
1275
|
+
$members$: compactMeta[2],
|
|
1276
|
+
$listeners$: compactMeta[3],
|
|
1277
|
+
};
|
|
1278
|
+
{
|
|
1279
|
+
cmpMeta.$members$ = compactMeta[2];
|
|
1280
|
+
}
|
|
1281
|
+
{
|
|
1282
|
+
cmpMeta.$watchers$ = {};
|
|
993
1283
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1284
|
+
const tagName = cmpMeta.$tagName$;
|
|
1285
|
+
const HostElement = class extends HTMLElement {
|
|
1286
|
+
// StencilLazyHost
|
|
1287
|
+
constructor(self) {
|
|
1288
|
+
// @ts-ignore
|
|
1289
|
+
super(self);
|
|
1290
|
+
self = this;
|
|
1291
|
+
registerHost(self, cmpMeta);
|
|
998
1292
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1293
|
+
connectedCallback() {
|
|
1294
|
+
if (appLoadFallback) {
|
|
1295
|
+
clearTimeout(appLoadFallback);
|
|
1296
|
+
appLoadFallback = null;
|
|
1297
|
+
}
|
|
1298
|
+
if (isBootstrapping) {
|
|
1299
|
+
// connectedCallback will be processed once all components have been registered
|
|
1300
|
+
deferredConnectedCallbacks.push(this);
|
|
1301
|
+
}
|
|
1302
|
+
else {
|
|
1303
|
+
plt.jmp(() => connectedCallback(this));
|
|
1304
|
+
}
|
|
1002
1305
|
}
|
|
1003
|
-
|
|
1004
|
-
plt.jmp(() =>
|
|
1306
|
+
disconnectedCallback() {
|
|
1307
|
+
plt.jmp(() => disconnectedCallback(this));
|
|
1005
1308
|
}
|
|
1309
|
+
componentOnReady() {
|
|
1310
|
+
return getHostRef(this).$onReadyPromise$;
|
|
1311
|
+
}
|
|
1312
|
+
};
|
|
1313
|
+
cmpMeta.$lazyBundleId$ = lazyBundle[0];
|
|
1314
|
+
if (!exclude.includes(tagName) && !customElements.get(tagName)) {
|
|
1315
|
+
cmpTags.push(tagName);
|
|
1316
|
+
customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* PROXY_FLAGS.isElementConstructor */));
|
|
1006
1317
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
}
|
|
1010
|
-
componentOnReady() {
|
|
1011
|
-
return getHostRef(this).$onReadyPromise$;
|
|
1012
|
-
}
|
|
1013
|
-
};
|
|
1014
|
-
cmpMeta.$lazyBundleId$ = lazyBundle[0];
|
|
1015
|
-
if (!exclude.includes(tagName) && !customElements.get(tagName)) {
|
|
1016
|
-
cmpTags.push(tagName);
|
|
1017
|
-
customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* isElementConstructor */));
|
|
1018
|
-
}
|
|
1019
|
-
}));
|
|
1318
|
+
});
|
|
1319
|
+
});
|
|
1020
1320
|
{
|
|
1021
1321
|
visibilityStyle.innerHTML = cmpTags + HYDRATED_CSS;
|
|
1022
1322
|
visibilityStyle.setAttribute('data-styles', '');
|
|
1323
|
+
// Apply CSP nonce to the style tag if it exists
|
|
1324
|
+
const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
|
|
1325
|
+
if (nonce != null) {
|
|
1326
|
+
visibilityStyle.setAttribute('nonce', nonce);
|
|
1327
|
+
}
|
|
1023
1328
|
head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
|
|
1024
1329
|
}
|
|
1025
1330
|
// Process deferred connectedCallbacks now all components have been registered
|
|
1026
1331
|
isBootstrapping = false;
|
|
1027
1332
|
if (deferredConnectedCallbacks.length) {
|
|
1028
|
-
deferredConnectedCallbacks.map(host => host.connectedCallback());
|
|
1333
|
+
deferredConnectedCallbacks.map((host) => host.connectedCallback());
|
|
1029
1334
|
}
|
|
1030
1335
|
else {
|
|
1031
1336
|
{
|
|
@@ -1035,7 +1340,14 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
1035
1340
|
// Fallback appLoad event
|
|
1036
1341
|
endBootstrap();
|
|
1037
1342
|
};
|
|
1038
|
-
|
|
1343
|
+
/**
|
|
1344
|
+
* Assigns the given value to the nonce property on the runtime platform object.
|
|
1345
|
+
* During runtime, this value is used to set the nonce attribute on all dynamically created script and style tags.
|
|
1346
|
+
* @param nonce The value to be assigned to the platform nonce property.
|
|
1347
|
+
* @returns void
|
|
1348
|
+
*/
|
|
1349
|
+
const setNonce = (nonce) => (plt.$nonce$ = nonce);
|
|
1350
|
+
const hostRefs = /*@__PURE__*/ new WeakMap();
|
|
1039
1351
|
const getHostRef = (ref) => hostRefs.get(ref);
|
|
1040
1352
|
const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
|
|
1041
1353
|
const registerHost = (elm, cmpMeta) => {
|
|
@@ -1046,45 +1358,68 @@ const registerHost = (elm, cmpMeta) => {
|
|
|
1046
1358
|
$instanceValues$: new Map(),
|
|
1047
1359
|
};
|
|
1048
1360
|
{
|
|
1049
|
-
hostRef.$onInstancePromise$ = new Promise(r => (hostRef.$onInstanceResolve$ = r));
|
|
1361
|
+
hostRef.$onInstancePromise$ = new Promise((r) => (hostRef.$onInstanceResolve$ = r));
|
|
1050
1362
|
}
|
|
1051
1363
|
{
|
|
1052
|
-
hostRef.$onReadyPromise$ = new Promise(r => (hostRef.$onReadyResolve$ = r));
|
|
1364
|
+
hostRef.$onReadyPromise$ = new Promise((r) => (hostRef.$onReadyResolve$ = r));
|
|
1053
1365
|
elm['s-p'] = [];
|
|
1054
1366
|
elm['s-rc'] = [];
|
|
1055
1367
|
}
|
|
1056
1368
|
return hostRefs.set(elm, hostRef);
|
|
1057
1369
|
};
|
|
1058
1370
|
const isMemberInElement = (elm, memberName) => memberName in elm;
|
|
1059
|
-
const consoleError = (e, el) => (
|
|
1371
|
+
const consoleError = (e, el) => (0, console.error)(e, el);
|
|
1060
1372
|
const cmpModules = /*@__PURE__*/ new Map();
|
|
1061
1373
|
const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
|
|
1062
1374
|
// loadModuleImport
|
|
1063
1375
|
const exportName = cmpMeta.$tagName$.replace(/-/g, '_');
|
|
1064
1376
|
const bundleId = cmpMeta.$lazyBundleId$;
|
|
1065
|
-
const module =
|
|
1377
|
+
const module = cmpModules.get(bundleId) ;
|
|
1066
1378
|
if (module) {
|
|
1067
1379
|
return module[exportName];
|
|
1068
1380
|
}
|
|
1381
|
+
/*!__STENCIL_STATIC_IMPORT_SWITCH__*/
|
|
1069
1382
|
return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(
|
|
1383
|
+
/* @vite-ignore */
|
|
1070
1384
|
/* webpackInclude: /\.entry\.js$/ */
|
|
1071
1385
|
/* webpackExclude: /\.system\.entry\.js$/ */
|
|
1072
1386
|
/* webpackMode: "lazy" */
|
|
1073
|
-
`./${bundleId}.entry.js${
|
|
1387
|
+
`./${bundleId}.entry.js${''}`)); }).then((importedModule) => {
|
|
1074
1388
|
{
|
|
1075
1389
|
cmpModules.set(bundleId, importedModule);
|
|
1076
1390
|
}
|
|
1077
1391
|
return importedModule[exportName];
|
|
1078
1392
|
}, consoleError);
|
|
1079
1393
|
};
|
|
1080
|
-
const styles = new Map();
|
|
1394
|
+
const styles = /*@__PURE__*/ new Map();
|
|
1395
|
+
const win = typeof window !== 'undefined' ? window : {};
|
|
1396
|
+
const doc = win.document || { head: {} };
|
|
1397
|
+
const plt = {
|
|
1398
|
+
$flags$: 0,
|
|
1399
|
+
$resourcesUrl$: '',
|
|
1400
|
+
jmp: (h) => h(),
|
|
1401
|
+
raf: (h) => requestAnimationFrame(h),
|
|
1402
|
+
ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
|
|
1403
|
+
rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
|
|
1404
|
+
ce: (eventName, opts) => new CustomEvent(eventName, opts),
|
|
1405
|
+
};
|
|
1406
|
+
const promiseResolve = (v) => Promise.resolve(v);
|
|
1407
|
+
const supportsConstructableStylesheets = /*@__PURE__*/ (() => {
|
|
1408
|
+
try {
|
|
1409
|
+
new CSSStyleSheet();
|
|
1410
|
+
return typeof new CSSStyleSheet().replaceSync === 'function';
|
|
1411
|
+
}
|
|
1412
|
+
catch (e) { }
|
|
1413
|
+
return false;
|
|
1414
|
+
})()
|
|
1415
|
+
;
|
|
1081
1416
|
const queueDomReads = [];
|
|
1082
1417
|
const queueDomWrites = [];
|
|
1083
1418
|
const queueTask = (queue, write) => (cb) => {
|
|
1084
1419
|
queue.push(cb);
|
|
1085
1420
|
if (!queuePending) {
|
|
1086
1421
|
queuePending = true;
|
|
1087
|
-
if (write && plt.$flags$ & 4 /* queueSync */) {
|
|
1422
|
+
if (write && plt.$flags$ & 4 /* PLATFORM_FLAGS.queueSync */) {
|
|
1088
1423
|
nextTick(flush);
|
|
1089
1424
|
}
|
|
1090
1425
|
else {
|
|
@@ -1127,3 +1462,4 @@ exports.getElement = getElement;
|
|
|
1127
1462
|
exports.h = h;
|
|
1128
1463
|
exports.promiseResolve = promiseResolve;
|
|
1129
1464
|
exports.registerInstance = registerInstance;
|
|
1465
|
+
exports.setNonce = setNonce;
|