@jumpgroup/jump-design-system 0.1.3 → 0.1.5
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/app-globals-3a1e7e63.js +7 -0
- package/dist/cjs/app-globals-3a1e7e63.js.map +1 -0
- package/dist/cjs/{index-168ed626.js → index-46644e39.js} +503 -152
- package/dist/cjs/index-46644e39.js.map +1 -0
- package/dist/cjs/jump-button.cjs.entry.js +35 -0
- package/dist/cjs/jump-button.cjs.entry.js.map +1 -0
- package/dist/cjs/jump-design-system.cjs.js +6 -4
- package/dist/cjs/jump-design-system.cjs.js.map +1 -1
- package/dist/cjs/{app-icon.cjs.entry.js → jump-icon.cjs.entry.js} +22 -33
- package/dist/cjs/jump-icon.cjs.entry.js.map +1 -0
- package/dist/cjs/jump-pagination.cjs.entry.js +35 -0
- package/dist/cjs/jump-pagination.cjs.entry.js.map +1 -0
- package/dist/cjs/loader.cjs.js +6 -4
- package/dist/cjs/loader.cjs.js.map +1 -1
- package/dist/collection/collection-manifest.json +5 -4
- package/dist/collection/components/app-icon/{app-icon.css → jump-icon.css} +2 -2
- package/dist/collection/components/app-icon/jump-icon.js +64 -0
- package/dist/collection/components/app-icon/jump-icon.js.map +1 -0
- package/dist/collection/components/app-icon/jump-icon.stories.js +25 -0
- package/dist/collection/components/app-icon/jump-icon.stories.js.map +1 -0
- package/dist/collection/components/app-icon/test/jump-icon.e2e.js +10 -0
- package/dist/collection/components/app-icon/test/jump-icon.e2e.js.map +1 -0
- package/dist/collection/components/app-icon/test/jump-icon.spec.js +18 -0
- package/dist/collection/components/app-icon/test/jump-icon.spec.js.map +1 -0
- package/dist/collection/components/jump-button/jump-button.css +107 -0
- package/dist/collection/components/jump-button/jump-button.js +270 -0
- package/dist/collection/components/jump-button/jump-button.js.map +1 -0
- package/dist/collection/components/jump-button/jump-button.stories.js +344 -0
- package/dist/collection/components/jump-button/jump-button.stories.js.map +1 -0
- package/dist/collection/components/jump-button/test/jump-button.e2e.js +10 -0
- package/dist/collection/components/jump-button/test/jump-button.e2e.js.map +1 -0
- package/dist/collection/components/jump-button/test/jump-button.spec.js +18 -0
- package/dist/collection/components/jump-button/test/jump-button.spec.js.map +1 -0
- package/dist/collection/components/jump-pagination/jump-pagination.css +43 -0
- package/dist/collection/components/jump-pagination/jump-pagination.js +180 -0
- package/dist/collection/components/jump-pagination/jump-pagination.js.map +1 -0
- package/dist/collection/components/jump-pagination/jump-pagination.stories.js +116 -0
- package/dist/collection/components/jump-pagination/jump-pagination.stories.js.map +1 -0
- package/dist/collection/components/jump-pagination/test/jump-pagination.e2e.js +10 -0
- package/dist/collection/components/jump-pagination/test/jump-pagination.e2e.js.map +1 -0
- package/dist/collection/components/jump-pagination/test/jump-pagination.spec.js +18 -0
- package/dist/collection/components/jump-pagination/test/jump-pagination.spec.js.map +1 -0
- package/dist/collection/utils/utils.js +1 -1
- package/dist/collection/utils/utils.js.map +1 -1
- package/dist/collection/utils/utils.spec.js +12 -12
- package/dist/collection/utils/utils.spec.js.map +1 -1
- package/dist/components/index.d.ts +6 -0
- package/dist/components/index.js +1 -1
- package/dist/components/{app-button.d.ts → jump-button.d.ts} +4 -4
- package/dist/components/jump-button.js +62 -0
- package/dist/components/jump-button.js.map +1 -0
- package/dist/components/{app-icon.d.ts → jump-icon.d.ts} +4 -4
- package/dist/components/jump-icon.js +8 -0
- package/dist/components/jump-icon.js.map +1 -0
- package/dist/components/{app-icon.js → jump-icon2.js} +39 -53
- package/dist/components/jump-icon2.js.map +1 -0
- package/dist/components/jump-pagination.d.ts +11 -0
- package/dist/components/jump-pagination.js +63 -0
- package/dist/components/jump-pagination.js.map +1 -0
- package/dist/esm/app-globals-0f993ce5.js +5 -0
- package/dist/esm/app-globals-0f993ce5.js.map +1 -0
- package/dist/esm/{index-330d1de1.js → index-b0176170.js} +503 -152
- package/dist/esm/index-b0176170.js.map +1 -0
- package/dist/esm/jump-button.entry.js +31 -0
- package/dist/esm/jump-button.entry.js.map +1 -0
- package/dist/esm/jump-design-system.js +7 -5
- package/dist/esm/jump-design-system.js.map +1 -1
- package/dist/esm/{app-icon.entry.js → jump-icon.entry.js} +22 -33
- package/dist/esm/jump-icon.entry.js.map +1 -0
- package/dist/esm/jump-pagination.entry.js +31 -0
- package/dist/esm/jump-pagination.entry.js.map +1 -0
- package/dist/esm/loader.js +7 -5
- package/dist/esm/loader.js.map +1 -1
- package/dist/jump-design-system/jump-design-system.esm.js +1 -1
- package/dist/jump-design-system/jump-design-system.esm.js.map +1 -1
- package/dist/jump-design-system/p-0d2b55a8.entry.js +2 -0
- package/dist/jump-design-system/p-0d2b55a8.entry.js.map +1 -0
- package/dist/jump-design-system/{p-e8515cce.entry.js → p-3cbc3a68.entry.js} +3 -3
- package/dist/jump-design-system/p-3cbc3a68.entry.js.map +1 -0
- package/dist/jump-design-system/p-68bce598.js +3 -0
- package/dist/jump-design-system/p-68bce598.js.map +1 -0
- package/dist/jump-design-system/p-9e6ea006.entry.js +2 -0
- package/dist/jump-design-system/p-9e6ea006.entry.js.map +1 -0
- package/dist/jump-design-system/p-e1255160.js +2 -0
- package/dist/jump-design-system/p-e1255160.js.map +1 -0
- package/dist/jump-design-system-elements.json +92 -3
- package/dist/types/components/app-icon/jump-icon.d.ts +12 -0
- package/dist/types/components/app-icon/jump-icon.stories.d.ts +19 -0
- package/dist/types/components/jump-button/jump-button.d.ts +55 -0
- package/dist/types/components/jump-button/jump-button.stories.d.ts +157 -0
- package/dist/types/components/jump-pagination/jump-pagination.d.ts +26 -0
- package/dist/types/components/jump-pagination/jump-pagination.stories.d.ts +71 -0
- package/dist/types/components.d.ts +123 -22
- package/dist/types/stencil-public-runtime.d.ts +46 -5
- package/loader/index.d.ts +1 -1
- package/package.json +2 -2
- package/readme.md +33 -66
- package/dist/cjs/app-button.cjs.entry.js +0 -28
- package/dist/cjs/app-button.cjs.entry.js.map +0 -1
- package/dist/cjs/app-icon.cjs.entry.js.map +0 -1
- package/dist/cjs/index-168ed626.js.map +0 -1
- package/dist/collection/components/app-button/app-button.css +0 -107
- package/dist/collection/components/app-button/app-button.js +0 -157
- package/dist/collection/components/app-button/app-button.js.map +0 -1
- package/dist/collection/components/app-button/app-button.stories.js +0 -227
- package/dist/collection/components/app-button/app-button.stories.js.map +0 -1
- package/dist/collection/components/app-button/test/app-button.e2e.js +0 -10
- package/dist/collection/components/app-button/test/app-button.e2e.js.map +0 -1
- package/dist/collection/components/app-button/test/app-button.spec.js +0 -18
- package/dist/collection/components/app-button/test/app-button.spec.js.map +0 -1
- package/dist/collection/components/app-icon/app-icon.js +0 -64
- package/dist/collection/components/app-icon/app-icon.js.map +0 -1
- package/dist/collection/components/app-icon/app-icon.stories.js +0 -25
- package/dist/collection/components/app-icon/app-icon.stories.js.map +0 -1
- package/dist/collection/components/app-icon/test/app-icon.e2e.js +0 -10
- package/dist/collection/components/app-icon/test/app-icon.e2e.js.map +0 -1
- package/dist/collection/components/app-icon/test/app-icon.spec.js +0 -18
- package/dist/collection/components/app-icon/test/app-icon.spec.js.map +0 -1
- package/dist/components/app-button.js +0 -49
- package/dist/components/app-button.js.map +0 -1
- package/dist/components/app-icon.js.map +0 -1
- package/dist/esm/app-button.entry.js +0 -24
- package/dist/esm/app-button.entry.js.map +0 -1
- package/dist/esm/app-icon.entry.js.map +0 -1
- package/dist/esm/index-330d1de1.js.map +0 -1
- package/dist/jump-design-system/p-28b9ffd5.js +0 -3
- package/dist/jump-design-system/p-28b9ffd5.js.map +0 -1
- package/dist/jump-design-system/p-da4d9423.entry.js +0 -2
- package/dist/jump-design-system/p-da4d9423.entry.js.map +0 -1
- package/dist/jump-design-system/p-e8515cce.entry.js.map +0 -1
- package/dist/types/components/app-button/app-button.d.ts +0 -31
- package/dist/types/components/app-button/app-button.stories.d.ts +0 -95
- package/dist/types/components/app-icon/app-icon.d.ts +0 -12
- package/dist/types/components/app-icon/app-icon.stories.d.ts +0 -19
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const NAMESPACE = 'jump-design-system';
|
|
2
|
+
const BUILD = /* jump-design-system */ { allRenderFn: true, appendChildSlotFix: false, asyncLoading: true, asyncQueue: false, attachStyles: true, cloneNodeFix: false, cmpDidLoad: true, cmpDidRender: false, cmpDidUnload: false, cmpDidUpdate: false, cmpShouldUpdate: false, cmpWillLoad: false, cmpWillRender: false, cmpWillUpdate: false, connectedCallback: false, constructableCSS: true, cssAnnotations: true, devTools: false, disconnectedCallback: false, element: false, event: false, experimentalScopedSlotChanges: false, experimentalSlotFixes: false, formAssociated: false, hasRenderFn: true, hostListener: false, hostListenerTarget: false, hostListenerTargetBody: false, hostListenerTargetDocument: false, hostListenerTargetParent: false, hostListenerTargetWindow: false, hotModuleReplacement: false, hydrateClientSide: false, hydrateServerSide: false, hydratedAttribute: false, hydratedClass: true, initializeNextTick: false, invisiblePrehydration: true, isDebug: false, isDev: false, isTesting: false, lazyLoad: true, lifecycle: true, lifecycleDOMEvents: false, member: true, method: false, mode: false, observeAttribute: true, profile: false, prop: true, propBoolean: true, propMutable: false, propNumber: true, propString: true, reflect: true, scoped: false, scopedSlotTextContentFix: false, scriptDataOpts: false, shadowDelegatesFocus: false, shadowDom: false, slot: true, slotChildNodesFix: false, slotRelocation: true, state: false, style: true, svg: false, taskQueue: true, transformTagName: false, updatable: true, vdomAttribute: true, vdomClass: true, vdomFunctional: false, vdomKey: true, vdomListener: false, vdomPropOrAttr: true, vdomRef: false, vdomRender: true, vdomStyle: false, vdomText: true, vdomXlink: false, watchCallback: false };
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Virtual DOM patching algorithm based on Snabbdom by
|
|
@@ -30,6 +31,13 @@ const uniqueTime = (key, measureText) => {
|
|
|
30
31
|
}
|
|
31
32
|
};
|
|
32
33
|
const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
|
|
34
|
+
/**
|
|
35
|
+
* Constant for styles to be globally applied to `slot-fb` elements for pseudo-slot behavior.
|
|
36
|
+
*
|
|
37
|
+
* Two cascading rules must be used instead of a `:not()` selector due to Stencil browser
|
|
38
|
+
* support as of Stencil v4.
|
|
39
|
+
*/
|
|
40
|
+
const SLOT_FB_CSS = 'slot-fb{display:contents}slot-fb[hidden]{display:none}';
|
|
33
41
|
/**
|
|
34
42
|
* Default style mode id
|
|
35
43
|
*/
|
|
@@ -74,6 +82,7 @@ function queryNonceMetaTagContent(doc) {
|
|
|
74
82
|
// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
|
|
75
83
|
const h = (nodeName, vnodeData, ...children) => {
|
|
76
84
|
let child = null;
|
|
85
|
+
let key = null;
|
|
77
86
|
let slotName = null;
|
|
78
87
|
let simple = false;
|
|
79
88
|
let lastSimple = false;
|
|
@@ -102,9 +111,13 @@ const h = (nodeName, vnodeData, ...children) => {
|
|
|
102
111
|
};
|
|
103
112
|
walk(children);
|
|
104
113
|
if (vnodeData) {
|
|
114
|
+
if (vnodeData.key) {
|
|
115
|
+
key = vnodeData.key;
|
|
116
|
+
}
|
|
105
117
|
if (vnodeData.name) {
|
|
106
118
|
slotName = vnodeData.name;
|
|
107
119
|
}
|
|
120
|
+
// normalize class / className attributes
|
|
108
121
|
{
|
|
109
122
|
const classData = vnodeData.className || vnodeData.class;
|
|
110
123
|
if (classData) {
|
|
@@ -122,6 +135,9 @@ const h = (nodeName, vnodeData, ...children) => {
|
|
|
122
135
|
if (vNodeChildren.length > 0) {
|
|
123
136
|
vnode.$children$ = vNodeChildren;
|
|
124
137
|
}
|
|
138
|
+
{
|
|
139
|
+
vnode.$key$ = key;
|
|
140
|
+
}
|
|
125
141
|
{
|
|
126
142
|
vnode.$name$ = slotName;
|
|
127
143
|
}
|
|
@@ -146,6 +162,9 @@ const newVNode = (tag, text) => {
|
|
|
146
162
|
{
|
|
147
163
|
vnode.$attrs$ = null;
|
|
148
164
|
}
|
|
165
|
+
{
|
|
166
|
+
vnode.$key$ = null;
|
|
167
|
+
}
|
|
149
168
|
{
|
|
150
169
|
vnode.$name$ = null;
|
|
151
170
|
}
|
|
@@ -190,6 +209,10 @@ const parsePropertyValue = (propValue, propType) => {
|
|
|
190
209
|
// but we'll cheat here and say that the string "false" is the boolean false
|
|
191
210
|
return propValue === 'false' ? false : propValue === '' || !!propValue;
|
|
192
211
|
}
|
|
212
|
+
if (propType & 2 /* MEMBER_FLAGS.Number */) {
|
|
213
|
+
// force it to be a number
|
|
214
|
+
return parseFloat(propValue);
|
|
215
|
+
}
|
|
193
216
|
if (propType & 1 /* MEMBER_FLAGS.String */) {
|
|
194
217
|
// could have been passed as a number or boolean
|
|
195
218
|
// but we still want it as a string
|
|
@@ -257,6 +280,10 @@ const addStyle = (styleContainerNode, cmpMeta, mode) => {
|
|
|
257
280
|
}
|
|
258
281
|
styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
|
|
259
282
|
}
|
|
283
|
+
// Add styles for `slot-fb` elements if we're using slots outside the Shadow DOM
|
|
284
|
+
if (cmpMeta.$flags$ & 4 /* CMP_FLAGS.hasSlotRelocation */) {
|
|
285
|
+
styleElm.innerHTML += SLOT_FB_CSS;
|
|
286
|
+
}
|
|
260
287
|
if (appliedStyles) {
|
|
261
288
|
appliedStyles.add(scopeId);
|
|
262
289
|
}
|
|
@@ -284,6 +311,21 @@ const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
|
|
|
284
311
|
*
|
|
285
312
|
* Modified for Stencil's compiler and vdom
|
|
286
313
|
*/
|
|
314
|
+
/**
|
|
315
|
+
* When running a VDom render set properties present on a VDom node onto the
|
|
316
|
+
* corresponding HTML element.
|
|
317
|
+
*
|
|
318
|
+
* Note that this function has special functionality for the `class`,
|
|
319
|
+
* `style`, `key`, and `ref` attributes, as well as event handlers (like
|
|
320
|
+
* `onClick`, etc). All others are just passed through as-is.
|
|
321
|
+
*
|
|
322
|
+
* @param elm the HTMLElement onto which attributes should be set
|
|
323
|
+
* @param memberName the name of the attribute to set
|
|
324
|
+
* @param oldValue the old value for the attribute
|
|
325
|
+
* @param newValue the new value for the attribute
|
|
326
|
+
* @param isSvg whether we're in an svg context or not
|
|
327
|
+
* @param flags bitflags for Vdom variables
|
|
328
|
+
*/
|
|
287
329
|
const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
288
330
|
if (oldValue !== newValue) {
|
|
289
331
|
let isProp = isMemberInElement(elm, memberName);
|
|
@@ -295,6 +337,8 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
295
337
|
classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
|
|
296
338
|
classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
|
|
297
339
|
}
|
|
340
|
+
else if (memberName === 'key')
|
|
341
|
+
;
|
|
298
342
|
else {
|
|
299
343
|
// Set property if it exists and it's not a SVG
|
|
300
344
|
const isComplex = isComplexType(newValue);
|
|
@@ -314,7 +358,11 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
314
358
|
elm[memberName] = newValue;
|
|
315
359
|
}
|
|
316
360
|
}
|
|
317
|
-
catch (e) {
|
|
361
|
+
catch (e) {
|
|
362
|
+
/**
|
|
363
|
+
* in case someone tries to set a read-only property, e.g. "namespaceURI", we just ignore it
|
|
364
|
+
*/
|
|
365
|
+
}
|
|
318
366
|
}
|
|
319
367
|
if (newValue == null || newValue === false) {
|
|
320
368
|
if (newValue !== false || elm.getAttribute(memberName) === '') {
|
|
@@ -333,6 +381,11 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
333
381
|
}
|
|
334
382
|
};
|
|
335
383
|
const parseClassListRegex = /\s/;
|
|
384
|
+
/**
|
|
385
|
+
* Parsed a string of classnames into an array
|
|
386
|
+
* @param value className string, e.g. "foo bar baz"
|
|
387
|
+
* @returns list of classes, e.g. ["foo", "bar", "baz"]
|
|
388
|
+
*/
|
|
336
389
|
const parseClassList = (value) => (!value ? [] : value.split(parseClassListRegex));
|
|
337
390
|
const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
|
|
338
391
|
// if the element passed in is a shadow root, which is a document fragment
|
|
@@ -414,8 +467,10 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
|
|
|
414
467
|
}
|
|
415
468
|
}
|
|
416
469
|
}
|
|
470
|
+
// This needs to always happen so we can hide nodes that are projected
|
|
471
|
+
// to another component but don't end up in a slot
|
|
472
|
+
elm['s-hn'] = hostTagName;
|
|
417
473
|
{
|
|
418
|
-
elm['s-hn'] = hostTagName;
|
|
419
474
|
if (newVNode.$flags$ & (2 /* VNODE_FLAGS.isSlotFallback */ | 1 /* VNODE_FLAGS.isSlotReference */)) {
|
|
420
475
|
// remember the content reference comment
|
|
421
476
|
elm['s-sr'] = true;
|
|
@@ -426,9 +481,11 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
|
|
|
426
481
|
// check if we've got an old vnode for this slot
|
|
427
482
|
oldVNode = oldParentVNode && oldParentVNode.$children$ && oldParentVNode.$children$[childIndex];
|
|
428
483
|
if (oldVNode && oldVNode.$tag$ === newVNode.$tag$ && oldParentVNode.$elm$) {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
484
|
+
{
|
|
485
|
+
// we've got an old slot vnode and the wrapper is being replaced
|
|
486
|
+
// so let's move the old slot content back to its original location
|
|
487
|
+
putBackInOriginalLocation(oldParentVNode.$elm$, false);
|
|
488
|
+
}
|
|
432
489
|
}
|
|
433
490
|
}
|
|
434
491
|
}
|
|
@@ -440,16 +497,15 @@ const putBackInOriginalLocation = (parentElm, recursive) => {
|
|
|
440
497
|
for (let i = oldSlotChildNodes.length - 1; i >= 0; i--) {
|
|
441
498
|
const childNode = oldSlotChildNodes[i];
|
|
442
499
|
if (childNode['s-hn'] !== hostTagName && childNode['s-ol']) {
|
|
443
|
-
// // this child node in the old element is from another component
|
|
444
|
-
// // remove this node from the old slot's parent
|
|
445
|
-
// childNode.remove();
|
|
446
500
|
// and relocate it back to it's original location
|
|
447
501
|
parentReferenceNode(childNode).insertBefore(childNode, referenceNode(childNode));
|
|
448
502
|
// remove the old original location comment entirely
|
|
449
503
|
// later on the patch function will know what to do
|
|
450
|
-
// and move this to the correct spot
|
|
504
|
+
// and move this to the correct spot if need be
|
|
451
505
|
childNode['s-ol'].remove();
|
|
452
506
|
childNode['s-ol'] = undefined;
|
|
507
|
+
// Reset so we can correctly move the node around again.
|
|
508
|
+
childNode['s-sh'] = undefined;
|
|
453
509
|
checkSlotRelocate = true;
|
|
454
510
|
}
|
|
455
511
|
if (recursive) {
|
|
@@ -590,10 +646,13 @@ const removeVnodes = (vnodes, startIdx, endIdx) => {
|
|
|
590
646
|
* @param oldCh the old children of the parent node
|
|
591
647
|
* @param newVNode the new VNode which will replace the parent
|
|
592
648
|
* @param newCh the new children of the parent node
|
|
649
|
+
* @param isInitialRender whether or not this is the first render of the vdom
|
|
593
650
|
*/
|
|
594
|
-
const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
651
|
+
const updateChildren = (parentElm, oldCh, newVNode, newCh, isInitialRender = false) => {
|
|
595
652
|
let oldStartIdx = 0;
|
|
596
653
|
let newStartIdx = 0;
|
|
654
|
+
let idxInOld = 0;
|
|
655
|
+
let i = 0;
|
|
597
656
|
let oldEndIdx = oldCh.length - 1;
|
|
598
657
|
let oldStartVnode = oldCh[0];
|
|
599
658
|
let oldEndVnode = oldCh[oldEndIdx];
|
|
@@ -601,6 +660,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
601
660
|
let newStartVnode = newCh[0];
|
|
602
661
|
let newEndVnode = newCh[newEndIdx];
|
|
603
662
|
let node;
|
|
663
|
+
let elmToMove;
|
|
604
664
|
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
|
|
605
665
|
if (oldStartVnode == null) {
|
|
606
666
|
// VNode might have been moved left
|
|
@@ -615,24 +675,24 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
615
675
|
else if (newEndVnode == null) {
|
|
616
676
|
newEndVnode = newCh[--newEndIdx];
|
|
617
677
|
}
|
|
618
|
-
else if (isSameVnode(oldStartVnode, newStartVnode)) {
|
|
678
|
+
else if (isSameVnode(oldStartVnode, newStartVnode, isInitialRender)) {
|
|
619
679
|
// if the start nodes are the same then we should patch the new VNode
|
|
620
680
|
// onto the old one, and increment our `newStartIdx` and `oldStartIdx`
|
|
621
681
|
// indices to reflect that. We don't need to move any DOM Nodes around
|
|
622
682
|
// since things are matched up in order.
|
|
623
|
-
patch(oldStartVnode, newStartVnode);
|
|
683
|
+
patch(oldStartVnode, newStartVnode, isInitialRender);
|
|
624
684
|
oldStartVnode = oldCh[++oldStartIdx];
|
|
625
685
|
newStartVnode = newCh[++newStartIdx];
|
|
626
686
|
}
|
|
627
|
-
else if (isSameVnode(oldEndVnode, newEndVnode)) {
|
|
687
|
+
else if (isSameVnode(oldEndVnode, newEndVnode, isInitialRender)) {
|
|
628
688
|
// likewise, if the end nodes are the same we patch new onto old and
|
|
629
689
|
// decrement our end indices, and also likewise in this case we don't
|
|
630
690
|
// need to move any DOM Nodes.
|
|
631
|
-
patch(oldEndVnode, newEndVnode);
|
|
691
|
+
patch(oldEndVnode, newEndVnode, isInitialRender);
|
|
632
692
|
oldEndVnode = oldCh[--oldEndIdx];
|
|
633
693
|
newEndVnode = newCh[--newEndIdx];
|
|
634
694
|
}
|
|
635
|
-
else if (isSameVnode(oldStartVnode, newEndVnode)) {
|
|
695
|
+
else if (isSameVnode(oldStartVnode, newEndVnode, isInitialRender)) {
|
|
636
696
|
// case: "Vnode moved right"
|
|
637
697
|
//
|
|
638
698
|
// We've found that the last node in our window on the new children is
|
|
@@ -650,7 +710,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
650
710
|
if ((oldStartVnode.$tag$ === 'slot' || newEndVnode.$tag$ === 'slot')) {
|
|
651
711
|
putBackInOriginalLocation(oldStartVnode.$elm$.parentNode, false);
|
|
652
712
|
}
|
|
653
|
-
patch(oldStartVnode, newEndVnode);
|
|
713
|
+
patch(oldStartVnode, newEndVnode, isInitialRender);
|
|
654
714
|
// We need to move the element for `oldStartVnode` into a position which
|
|
655
715
|
// will be appropriate for `newEndVnode`. For this we can use
|
|
656
716
|
// `.insertBefore` and `oldEndVnode.$elm$.nextSibling`. If there is a
|
|
@@ -672,7 +732,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
672
732
|
oldStartVnode = oldCh[++oldStartIdx];
|
|
673
733
|
newEndVnode = newCh[--newEndIdx];
|
|
674
734
|
}
|
|
675
|
-
else if (isSameVnode(oldEndVnode, newStartVnode)) {
|
|
735
|
+
else if (isSameVnode(oldEndVnode, newStartVnode, isInitialRender)) {
|
|
676
736
|
// case: "Vnode moved left"
|
|
677
737
|
//
|
|
678
738
|
// We've found that the first node in our window on the new children is
|
|
@@ -691,7 +751,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
691
751
|
if ((oldStartVnode.$tag$ === 'slot' || newEndVnode.$tag$ === 'slot')) {
|
|
692
752
|
putBackInOriginalLocation(oldEndVnode.$elm$.parentNode, false);
|
|
693
753
|
}
|
|
694
|
-
patch(oldEndVnode, newStartVnode);
|
|
754
|
+
patch(oldEndVnode, newStartVnode, isInitialRender);
|
|
695
755
|
// We've already checked above if `oldStartVnode` and `newStartVnode` are
|
|
696
756
|
// the same node, so since we're here we know that they are not. Thus we
|
|
697
757
|
// can move the element for `oldEndVnode` _before_ the element for
|
|
@@ -702,7 +762,41 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
702
762
|
newStartVnode = newCh[++newStartIdx];
|
|
703
763
|
}
|
|
704
764
|
else {
|
|
765
|
+
// Here we do some checks to match up old and new nodes based on the
|
|
766
|
+
// `$key$` attribute, which is set by putting a `key="my-key"` attribute
|
|
767
|
+
// in the JSX for a DOM element in the implementation of a Stencil
|
|
768
|
+
// component.
|
|
769
|
+
//
|
|
770
|
+
// First we check to see if there are any nodes in the array of old
|
|
771
|
+
// children which have the same key as the first node in the new
|
|
772
|
+
// children.
|
|
773
|
+
idxInOld = -1;
|
|
705
774
|
{
|
|
775
|
+
for (i = oldStartIdx; i <= oldEndIdx; ++i) {
|
|
776
|
+
if (oldCh[i] && oldCh[i].$key$ !== null && oldCh[i].$key$ === newStartVnode.$key$) {
|
|
777
|
+
idxInOld = i;
|
|
778
|
+
break;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
if (idxInOld >= 0) {
|
|
783
|
+
// We found a node in the old children which matches up with the first
|
|
784
|
+
// node in the new children! So let's deal with that
|
|
785
|
+
elmToMove = oldCh[idxInOld];
|
|
786
|
+
if (elmToMove.$tag$ !== newStartVnode.$tag$) {
|
|
787
|
+
// the tag doesn't match so we'll need a new DOM element
|
|
788
|
+
node = createElm(oldCh && oldCh[newStartIdx], newVNode, idxInOld);
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
patch(elmToMove, newStartVnode, isInitialRender);
|
|
792
|
+
// invalidate the matching old node so that we won't try to update it
|
|
793
|
+
// again later on
|
|
794
|
+
oldCh[idxInOld] = undefined;
|
|
795
|
+
node = elmToMove.$elm$;
|
|
796
|
+
}
|
|
797
|
+
newStartVnode = newCh[++newStartIdx];
|
|
798
|
+
}
|
|
799
|
+
else {
|
|
706
800
|
// We either didn't find an element in the old children that matches
|
|
707
801
|
// the key of the first new child OR the build is not using `key`
|
|
708
802
|
// attributes at all. In either case we need to create a new element
|
|
@@ -745,15 +839,24 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
745
839
|
*
|
|
746
840
|
* @param leftVNode the first VNode to check
|
|
747
841
|
* @param rightVNode the second VNode to check
|
|
842
|
+
* @param isInitialRender whether or not this is the first render of the vdom
|
|
748
843
|
* @returns whether they're equal or not
|
|
749
844
|
*/
|
|
750
|
-
const isSameVnode = (leftVNode, rightVNode) => {
|
|
845
|
+
const isSameVnode = (leftVNode, rightVNode, isInitialRender = false) => {
|
|
751
846
|
// compare if two vnode to see if they're "technically" the same
|
|
752
847
|
// need to have the same element tag, and same key to be the same
|
|
753
848
|
if (leftVNode.$tag$ === rightVNode.$tag$) {
|
|
754
849
|
if (leftVNode.$tag$ === 'slot') {
|
|
755
850
|
return leftVNode.$name$ === rightVNode.$name$;
|
|
756
851
|
}
|
|
852
|
+
// this will be set if JSX tags in the build have `key` attrs set on them
|
|
853
|
+
// we only want to check this if we're not on the first render since on
|
|
854
|
+
// first render `leftVNode.$key$` will always be `null`, so we can be led
|
|
855
|
+
// astray and, for instance, accidentally delete a DOM node that we want to
|
|
856
|
+
// keep around.
|
|
857
|
+
if (!isInitialRender) {
|
|
858
|
+
return leftVNode.$key$ === rightVNode.$key$;
|
|
859
|
+
}
|
|
757
860
|
return true;
|
|
758
861
|
}
|
|
759
862
|
return false;
|
|
@@ -773,8 +876,9 @@ const parentReferenceNode = (node) => (node['s-ol'] ? node['s-ol'] : node).paren
|
|
|
773
876
|
*
|
|
774
877
|
* @param oldVNode an old VNode whose DOM element and children we want to update
|
|
775
878
|
* @param newVNode a new VNode representing an updated version of the old one
|
|
879
|
+
* @param isInitialRender whether or not this is the first render of the vdom
|
|
776
880
|
*/
|
|
777
|
-
const patch = (oldVNode, newVNode) => {
|
|
881
|
+
const patch = (oldVNode, newVNode, isInitialRender = false) => {
|
|
778
882
|
const elm = (newVNode.$elm$ = oldVNode.$elm$);
|
|
779
883
|
const oldChildren = oldVNode.$children$;
|
|
780
884
|
const newChildren = newVNode.$children$;
|
|
@@ -783,8 +887,7 @@ const patch = (oldVNode, newVNode) => {
|
|
|
783
887
|
let defaultHolder;
|
|
784
888
|
if (text === null) {
|
|
785
889
|
{
|
|
786
|
-
if (tag === 'slot')
|
|
787
|
-
;
|
|
890
|
+
if (tag === 'slot' && !useNativeShadowDom) ;
|
|
788
891
|
else {
|
|
789
892
|
// either this is the first render of an element OR it's an update
|
|
790
893
|
// AND we already know it's possible it could have changed
|
|
@@ -795,7 +898,7 @@ const patch = (oldVNode, newVNode) => {
|
|
|
795
898
|
if (oldChildren !== null && newChildren !== null) {
|
|
796
899
|
// looks like there's child vnodes for both the old and new vnodes
|
|
797
900
|
// so we need to call `updateChildren` to reconcile them
|
|
798
|
-
updateChildren(elm, oldChildren, newVNode, newChildren);
|
|
901
|
+
updateChildren(elm, oldChildren, newVNode, newChildren, isInitialRender);
|
|
799
902
|
}
|
|
800
903
|
else if (newChildren !== null) {
|
|
801
904
|
// no old child vnodes, but there are new child vnodes to add
|
|
@@ -821,42 +924,53 @@ const patch = (oldVNode, newVNode) => {
|
|
|
821
924
|
elm.data = text;
|
|
822
925
|
}
|
|
823
926
|
};
|
|
927
|
+
/**
|
|
928
|
+
* Adjust the `.hidden` property as-needed on any nodes in a DOM subtree which
|
|
929
|
+
* are slot fallbacks nodes.
|
|
930
|
+
*
|
|
931
|
+
* A slot fallback node should be visible by default. Then, it should be
|
|
932
|
+
* conditionally hidden if:
|
|
933
|
+
*
|
|
934
|
+
* - it has a sibling with a `slot` property set to its slot name or if
|
|
935
|
+
* - it is a default fallback slot node, in which case we hide if it has any
|
|
936
|
+
* content
|
|
937
|
+
*
|
|
938
|
+
* @param elm the element of interest
|
|
939
|
+
*/
|
|
824
940
|
const updateFallbackSlotVisibility = (elm) => {
|
|
825
|
-
// tslint:disable-next-line: prefer-const
|
|
826
941
|
const childNodes = elm.childNodes;
|
|
827
|
-
|
|
828
|
-
let i;
|
|
829
|
-
let ilen;
|
|
830
|
-
let j;
|
|
831
|
-
let slotNameAttr;
|
|
832
|
-
let nodeType;
|
|
833
|
-
for (i = 0, ilen = childNodes.length; i < ilen; i++) {
|
|
834
|
-
childNode = childNodes[i];
|
|
942
|
+
for (const childNode of childNodes) {
|
|
835
943
|
if (childNode.nodeType === 1 /* NODE_TYPE.ElementNode */) {
|
|
836
944
|
if (childNode['s-sr']) {
|
|
837
945
|
// this is a slot fallback node
|
|
838
946
|
// get the slot name for this slot reference node
|
|
839
|
-
|
|
947
|
+
const slotName = childNode['s-sn'];
|
|
840
948
|
// by default always show a fallback slot node
|
|
841
949
|
// then hide it if there are other slots in the light dom
|
|
842
950
|
childNode.hidden = false;
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
951
|
+
// we need to check all of its sibling nodes in order to see if
|
|
952
|
+
// `childNode` should be hidden
|
|
953
|
+
for (const siblingNode of childNodes) {
|
|
954
|
+
// Don't check the node against itself
|
|
955
|
+
if (siblingNode !== childNode) {
|
|
956
|
+
if (siblingNode['s-hn'] !== childNode['s-hn'] || slotName !== '') {
|
|
957
|
+
// this sibling node is from a different component OR is a named
|
|
958
|
+
// fallback slot node
|
|
959
|
+
if (siblingNode.nodeType === 1 /* NODE_TYPE.ElementNode */ &&
|
|
960
|
+
(slotName === siblingNode.getAttribute('slot') || slotName === siblingNode['s-sn'])) {
|
|
961
|
+
childNode.hidden = true;
|
|
962
|
+
break;
|
|
963
|
+
}
|
|
850
964
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
965
|
+
else {
|
|
966
|
+
// this is a default fallback slot node
|
|
967
|
+
// any element or text node (with content)
|
|
968
|
+
// should hide the default fallback slot node
|
|
969
|
+
if (siblingNode.nodeType === 1 /* NODE_TYPE.ElementNode */ ||
|
|
970
|
+
(siblingNode.nodeType === 3 /* NODE_TYPE.TextNode */ && siblingNode.textContent.trim() !== '')) {
|
|
971
|
+
childNode.hidden = true;
|
|
972
|
+
break;
|
|
973
|
+
}
|
|
860
974
|
}
|
|
861
975
|
}
|
|
862
976
|
}
|
|
@@ -866,45 +980,67 @@ const updateFallbackSlotVisibility = (elm) => {
|
|
|
866
980
|
}
|
|
867
981
|
}
|
|
868
982
|
};
|
|
983
|
+
/**
|
|
984
|
+
* Component-global information about nodes which are either currently being
|
|
985
|
+
* relocated or will be shortly.
|
|
986
|
+
*/
|
|
869
987
|
const relocateNodes = [];
|
|
870
|
-
|
|
988
|
+
/**
|
|
989
|
+
* Mark the contents of a slot for relocation via adding references to them to
|
|
990
|
+
* the {@link relocateNodes} data structure. The actual work of relocating them
|
|
991
|
+
* will then be handled in {@link renderVdom}.
|
|
992
|
+
*
|
|
993
|
+
* @param elm a render node whose child nodes need to be relocated
|
|
994
|
+
*/
|
|
995
|
+
const markSlotContentForRelocation = (elm) => {
|
|
871
996
|
// tslint:disable-next-line: prefer-const
|
|
872
|
-
let childNode;
|
|
873
997
|
let node;
|
|
874
998
|
let hostContentNodes;
|
|
875
|
-
let slotNameAttr;
|
|
876
|
-
let relocateNodeData;
|
|
877
999
|
let j;
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
for (; i < ilen; i++) {
|
|
882
|
-
childNode = childNodes[i];
|
|
1000
|
+
for (const childNode of elm.childNodes) {
|
|
1001
|
+
// we need to find child nodes which are slot references so we can then try
|
|
1002
|
+
// to match them up with nodes that need to be relocated
|
|
883
1003
|
if (childNode['s-sr'] && (node = childNode['s-cr']) && node.parentNode) {
|
|
884
|
-
// first
|
|
885
|
-
//
|
|
1004
|
+
// first get the content reference comment node ('s-cr'), then we get
|
|
1005
|
+
// its parent, which is where all the host content is now
|
|
886
1006
|
hostContentNodes = node.parentNode.childNodes;
|
|
887
|
-
|
|
1007
|
+
const slotName = childNode['s-sn'];
|
|
1008
|
+
// iterate through all the nodes under the location where the host was
|
|
1009
|
+
// originally rendered
|
|
888
1010
|
for (j = hostContentNodes.length - 1; j >= 0; j--) {
|
|
889
1011
|
node = hostContentNodes[j];
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1012
|
+
// check that the node is not a content reference node or a node
|
|
1013
|
+
// reference and then check that the host name does not match that of
|
|
1014
|
+
// childNode.
|
|
1015
|
+
// In addition, check that the slot either has not already been relocated, or
|
|
1016
|
+
// that its current location's host is not childNode's host. This is essentially
|
|
1017
|
+
// a check so that we don't try to relocate (and then hide) a node that is already
|
|
1018
|
+
// where it should be.
|
|
1019
|
+
if (!node['s-cn'] &&
|
|
1020
|
+
!node['s-nr'] &&
|
|
1021
|
+
node['s-hn'] !== childNode['s-hn'] &&
|
|
1022
|
+
(!BUILD.experimentalSlotFixes )) {
|
|
1023
|
+
// if `node` is located in the slot that `childNode` refers to (via the
|
|
1024
|
+
// `'s-sn'` property) then we need to relocate it from it's current spot
|
|
1025
|
+
// (under the host element parent) to the right slot location
|
|
1026
|
+
if (isNodeLocatedInSlot(node, slotName)) {
|
|
895
1027
|
// it's possible we've already decided to relocate this node
|
|
896
|
-
relocateNodeData = relocateNodes.find((r) => r.$nodeToRelocate$ === node);
|
|
1028
|
+
let relocateNodeData = relocateNodes.find((r) => r.$nodeToRelocate$ === node);
|
|
897
1029
|
// made some changes to slots
|
|
898
1030
|
// let's make sure we also double check
|
|
899
1031
|
// fallbacks are correctly hidden or shown
|
|
900
1032
|
checkSlotFallbackVisibility = true;
|
|
901
|
-
|
|
1033
|
+
// ensure that the slot-name attr is correct
|
|
1034
|
+
node['s-sn'] = node['s-sn'] || slotName;
|
|
902
1035
|
if (relocateNodeData) {
|
|
903
|
-
|
|
904
|
-
//
|
|
1036
|
+
relocateNodeData.$nodeToRelocate$['s-sh'] = childNode['s-hn'];
|
|
1037
|
+
// we marked this node for relocation previously but didn't find
|
|
1038
|
+
// out the slot reference node to which it needs to be relocated
|
|
1039
|
+
// so write it down now!
|
|
905
1040
|
relocateNodeData.$slotRefNode$ = childNode;
|
|
906
1041
|
}
|
|
907
1042
|
else {
|
|
1043
|
+
node['s-sh'] = childNode['s-hn'];
|
|
908
1044
|
// add to our list of nodes to relocate
|
|
909
1045
|
relocateNodes.push({
|
|
910
1046
|
$slotRefNode$: childNode,
|
|
@@ -923,8 +1059,10 @@ const relocateSlotContent = (elm) => {
|
|
|
923
1059
|
}
|
|
924
1060
|
}
|
|
925
1061
|
else if (!relocateNodes.some((r) => r.$nodeToRelocate$ === node)) {
|
|
926
|
-
//
|
|
927
|
-
//
|
|
1062
|
+
// the node is not found within the slot (`childNode`) that we're
|
|
1063
|
+
// currently looking at, so we stick it into `relocateNodes` to
|
|
1064
|
+
// handle later. If we never find a home for this element then
|
|
1065
|
+
// we'll need to hide it
|
|
928
1066
|
relocateNodes.push({
|
|
929
1067
|
$nodeToRelocate$: node,
|
|
930
1068
|
});
|
|
@@ -932,25 +1070,36 @@ const relocateSlotContent = (elm) => {
|
|
|
932
1070
|
}
|
|
933
1071
|
}
|
|
934
1072
|
}
|
|
1073
|
+
// if we're dealing with any type of element (capable of itself being a
|
|
1074
|
+
// slot reference or containing one) then we recur
|
|
935
1075
|
if (childNode.nodeType === 1 /* NODE_TYPE.ElementNode */) {
|
|
936
|
-
|
|
1076
|
+
markSlotContentForRelocation(childNode);
|
|
937
1077
|
}
|
|
938
1078
|
}
|
|
939
1079
|
};
|
|
940
|
-
|
|
1080
|
+
/**
|
|
1081
|
+
* Check whether a node is located in a given named slot.
|
|
1082
|
+
*
|
|
1083
|
+
* @param nodeToRelocate the node of interest
|
|
1084
|
+
* @param slotName the slot name to check
|
|
1085
|
+
* @returns whether the node is located in the slot or not
|
|
1086
|
+
*/
|
|
1087
|
+
const isNodeLocatedInSlot = (nodeToRelocate, slotName) => {
|
|
941
1088
|
if (nodeToRelocate.nodeType === 1 /* NODE_TYPE.ElementNode */) {
|
|
942
|
-
if (nodeToRelocate.getAttribute('slot') === null &&
|
|
1089
|
+
if (nodeToRelocate.getAttribute('slot') === null && slotName === '') {
|
|
1090
|
+
// if the node doesn't have a slot attribute, and the slot we're checking
|
|
1091
|
+
// is not a named slot, then we assume the node should be within the slot
|
|
943
1092
|
return true;
|
|
944
1093
|
}
|
|
945
|
-
if (nodeToRelocate.getAttribute('slot') ===
|
|
1094
|
+
if (nodeToRelocate.getAttribute('slot') === slotName) {
|
|
946
1095
|
return true;
|
|
947
1096
|
}
|
|
948
1097
|
return false;
|
|
949
1098
|
}
|
|
950
|
-
if (nodeToRelocate['s-sn'] ===
|
|
1099
|
+
if (nodeToRelocate['s-sn'] === slotName) {
|
|
951
1100
|
return true;
|
|
952
1101
|
}
|
|
953
|
-
return
|
|
1102
|
+
return slotName === '';
|
|
954
1103
|
};
|
|
955
1104
|
/**
|
|
956
1105
|
* The main entry point for Stencil's virtual DOM-based rendering engine
|
|
@@ -963,71 +1112,104 @@ const isNodeLocatedInSlot = (nodeToRelocate, slotNameAttr) => {
|
|
|
963
1112
|
* @param hostRef data needed to root and render the virtual DOM tree, such as
|
|
964
1113
|
* the DOM node into which it should be rendered.
|
|
965
1114
|
* @param renderFnResults the virtual DOM nodes to be rendered
|
|
1115
|
+
* @param isInitialLoad whether or not this is the first call after page load
|
|
966
1116
|
*/
|
|
967
|
-
const renderVdom = (hostRef, renderFnResults) => {
|
|
1117
|
+
const renderVdom = (hostRef, renderFnResults, isInitialLoad = false) => {
|
|
1118
|
+
var _a, _b, _c, _d;
|
|
968
1119
|
const hostElm = hostRef.$hostElement$;
|
|
969
1120
|
const cmpMeta = hostRef.$cmpMeta$;
|
|
970
1121
|
const oldVNode = hostRef.$vnode$ || newVNode(null, null);
|
|
1122
|
+
// if `renderFnResults` is a Host node then we can use it directly. If not,
|
|
1123
|
+
// we need to call `h` again to wrap the children of our component in a
|
|
1124
|
+
// 'dummy' Host node (well, an empty vnode) since `renderVdom` assumes
|
|
1125
|
+
// implicitly that the top-level vdom node is 1) an only child and 2)
|
|
1126
|
+
// contains attrs that need to be set on the host element.
|
|
971
1127
|
const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
|
|
972
1128
|
hostTagName = hostElm.tagName;
|
|
973
1129
|
if (cmpMeta.$attrsToReflect$) {
|
|
974
1130
|
rootVnode.$attrs$ = rootVnode.$attrs$ || {};
|
|
975
1131
|
cmpMeta.$attrsToReflect$.map(([propName, attribute]) => (rootVnode.$attrs$[attribute] = hostElm[propName]));
|
|
976
1132
|
}
|
|
1133
|
+
// On the first render and *only* on the first render we want to check for
|
|
1134
|
+
// any attributes set on the host element which are also set on the vdom
|
|
1135
|
+
// node. If we find them, we override the value on the VDom node attrs with
|
|
1136
|
+
// the value from the host element, which allows developers building apps
|
|
1137
|
+
// with Stencil components to override e.g. the `role` attribute on a
|
|
1138
|
+
// component even if it's already set on the `Host`.
|
|
1139
|
+
if (isInitialLoad && rootVnode.$attrs$) {
|
|
1140
|
+
for (const key of Object.keys(rootVnode.$attrs$)) {
|
|
1141
|
+
// We have a special implementation in `setAccessor` for `style` and
|
|
1142
|
+
// `class` which reconciles values coming from the VDom with values
|
|
1143
|
+
// already present on the DOM element, so we don't want to override those
|
|
1144
|
+
// attributes on the VDom tree with values from the host element if they
|
|
1145
|
+
// are present.
|
|
1146
|
+
//
|
|
1147
|
+
// Likewise, `ref` and `key` are special internal values for the Stencil
|
|
1148
|
+
// runtime and we don't want to override those either.
|
|
1149
|
+
if (hostElm.hasAttribute(key) && !['key', 'ref', 'style', 'class'].includes(key)) {
|
|
1150
|
+
rootVnode.$attrs$[key] = hostElm[key];
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
977
1154
|
rootVnode.$tag$ = null;
|
|
978
1155
|
rootVnode.$flags$ |= 4 /* VNODE_FLAGS.isHost */;
|
|
979
1156
|
hostRef.$vnode$ = rootVnode;
|
|
980
1157
|
rootVnode.$elm$ = oldVNode.$elm$ = (hostElm);
|
|
1158
|
+
useNativeShadowDom = (cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */) !== 0;
|
|
981
1159
|
{
|
|
982
1160
|
contentRef = hostElm['s-cr'];
|
|
983
|
-
useNativeShadowDom = (cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */) !== 0;
|
|
984
1161
|
// always reset
|
|
985
1162
|
checkSlotFallbackVisibility = false;
|
|
986
1163
|
}
|
|
987
1164
|
// synchronous patch
|
|
988
|
-
patch(oldVNode, rootVnode);
|
|
1165
|
+
patch(oldVNode, rootVnode, isInitialLoad);
|
|
989
1166
|
{
|
|
990
1167
|
// while we're moving nodes around existing nodes, temporarily disable
|
|
991
1168
|
// the disconnectCallback from working
|
|
992
1169
|
plt.$flags$ |= 1 /* PLATFORM_FLAGS.isTmpDisconnected */;
|
|
993
1170
|
if (checkSlotRelocate) {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
let orgLocationNode;
|
|
998
|
-
let parentNodeRef;
|
|
999
|
-
let insertBeforeNode;
|
|
1000
|
-
let refNode;
|
|
1001
|
-
let i = 0;
|
|
1002
|
-
for (; i < relocateNodes.length; i++) {
|
|
1003
|
-
relocateData = relocateNodes[i];
|
|
1004
|
-
nodeToRelocate = relocateData.$nodeToRelocate$;
|
|
1171
|
+
markSlotContentForRelocation(rootVnode.$elm$);
|
|
1172
|
+
for (const relocateData of relocateNodes) {
|
|
1173
|
+
const nodeToRelocate = relocateData.$nodeToRelocate$;
|
|
1005
1174
|
if (!nodeToRelocate['s-ol']) {
|
|
1006
1175
|
// add a reference node marking this node's original location
|
|
1007
1176
|
// keep a reference to this node for later lookups
|
|
1008
|
-
orgLocationNode =
|
|
1009
|
-
doc.createTextNode('');
|
|
1177
|
+
const orgLocationNode = doc.createTextNode('');
|
|
1010
1178
|
orgLocationNode['s-nr'] = nodeToRelocate;
|
|
1011
1179
|
nodeToRelocate.parentNode.insertBefore((nodeToRelocate['s-ol'] = orgLocationNode), nodeToRelocate);
|
|
1012
1180
|
}
|
|
1013
1181
|
}
|
|
1014
|
-
for (
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
if (
|
|
1018
|
-
|
|
1019
|
-
//
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1182
|
+
for (const relocateData of relocateNodes) {
|
|
1183
|
+
const nodeToRelocate = relocateData.$nodeToRelocate$;
|
|
1184
|
+
const slotRefNode = relocateData.$slotRefNode$;
|
|
1185
|
+
if (slotRefNode) {
|
|
1186
|
+
const parentNodeRef = slotRefNode.parentNode;
|
|
1187
|
+
// When determining where to insert content, the most simple case would be
|
|
1188
|
+
// to relocate the node immediately following the slot reference node. We do this
|
|
1189
|
+
// by getting a reference to the node immediately following the slot reference node
|
|
1190
|
+
// since we will use `insertBefore` to manipulate the DOM.
|
|
1191
|
+
//
|
|
1192
|
+
// If there is no node immediately following the slot reference node, then we will just
|
|
1193
|
+
// end up appending the node as the last child of the parent.
|
|
1194
|
+
let insertBeforeNode = slotRefNode.nextSibling;
|
|
1195
|
+
// If the node we're currently planning on inserting the new node before is an element,
|
|
1196
|
+
// we need to do some additional checks to make sure we're inserting the node in the correct order.
|
|
1197
|
+
// The use case here would be that we have multiple nodes being relocated to the same slot. So, we want
|
|
1198
|
+
// to make sure they get inserted into their new how in the same order they were declared in their original location.
|
|
1199
|
+
//
|
|
1200
|
+
// TODO(STENCIL-914): Remove `experimentalSlotFixes` check
|
|
1201
|
+
{
|
|
1202
|
+
let orgLocationNode = (_a = nodeToRelocate['s-ol']) === null || _a === void 0 ? void 0 : _a.previousSibling;
|
|
1203
|
+
while (orgLocationNode) {
|
|
1204
|
+
let refNode = (_b = orgLocationNode['s-nr']) !== null && _b !== void 0 ? _b : null;
|
|
1205
|
+
if (refNode && refNode['s-sn'] === nodeToRelocate['s-sn'] && parentNodeRef === refNode.parentNode) {
|
|
1206
|
+
refNode = refNode.nextSibling;
|
|
1207
|
+
if (!refNode || !refNode['s-nr']) {
|
|
1208
|
+
insertBeforeNode = refNode;
|
|
1209
|
+
break;
|
|
1210
|
+
}
|
|
1030
1211
|
}
|
|
1212
|
+
orgLocationNode = orgLocationNode.previousSibling;
|
|
1031
1213
|
}
|
|
1032
1214
|
}
|
|
1033
1215
|
if ((!insertBeforeNode && parentNodeRef !== nodeToRelocate.parentNode) ||
|
|
@@ -1037,17 +1219,32 @@ const renderVdom = (hostRef, renderFnResults) => {
|
|
|
1037
1219
|
// has a different next sibling or parent relocated
|
|
1038
1220
|
if (nodeToRelocate !== insertBeforeNode) {
|
|
1039
1221
|
if (!nodeToRelocate['s-hn'] && nodeToRelocate['s-ol']) {
|
|
1040
|
-
// probably a component in the index.html that doesn't have
|
|
1222
|
+
// probably a component in the index.html that doesn't have its hostname set
|
|
1041
1223
|
nodeToRelocate['s-hn'] = nodeToRelocate['s-ol'].parentNode.nodeName;
|
|
1042
1224
|
}
|
|
1043
|
-
//
|
|
1225
|
+
// Add it back to the dom but in its new home
|
|
1226
|
+
// If we get to this point and `insertBeforeNode` is `null`, that means
|
|
1227
|
+
// we're just going to append the node as the last child of the parent. Passing
|
|
1228
|
+
// `null` as the second arg here will trigger that behavior.
|
|
1044
1229
|
parentNodeRef.insertBefore(nodeToRelocate, insertBeforeNode);
|
|
1230
|
+
// Reset the `hidden` value back to what it was defined as originally
|
|
1231
|
+
// This solves a problem where a `slot` is dynamically rendered and `hidden` may have
|
|
1232
|
+
// been set on content originally, but now it has a slot to go to so it should have
|
|
1233
|
+
// the value it was defined as having in the DOM, not what we overrode it to.
|
|
1234
|
+
if (nodeToRelocate.nodeType === 1 /* NODE_TYPE.ElementNode */) {
|
|
1235
|
+
nodeToRelocate.hidden = (_c = nodeToRelocate['s-ih']) !== null && _c !== void 0 ? _c : false;
|
|
1236
|
+
}
|
|
1045
1237
|
}
|
|
1046
1238
|
}
|
|
1047
1239
|
}
|
|
1048
1240
|
else {
|
|
1049
1241
|
// this node doesn't have a slot home to go to, so let's hide it
|
|
1050
1242
|
if (nodeToRelocate.nodeType === 1 /* NODE_TYPE.ElementNode */) {
|
|
1243
|
+
// Store the initial value of `hidden` so we can reset it later when
|
|
1244
|
+
// moving nodes around.
|
|
1245
|
+
if (isInitialLoad) {
|
|
1246
|
+
nodeToRelocate['s-ih'] = (_d = nodeToRelocate.hidden) !== null && _d !== void 0 ? _d : false;
|
|
1247
|
+
}
|
|
1051
1248
|
nodeToRelocate.hidden = true;
|
|
1052
1249
|
}
|
|
1053
1250
|
}
|
|
@@ -1062,6 +1259,8 @@ const renderVdom = (hostRef, renderFnResults) => {
|
|
|
1062
1259
|
// always reset
|
|
1063
1260
|
relocateNodes.length = 0;
|
|
1064
1261
|
}
|
|
1262
|
+
// Clear the content ref so we don't create a memory leak
|
|
1263
|
+
contentRef = undefined;
|
|
1065
1264
|
};
|
|
1066
1265
|
const attachToAncestor = (hostRef, ancestorComponent) => {
|
|
1067
1266
|
if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
|
|
@@ -1141,6 +1340,16 @@ const enqueue = (maybePromise, fn) => isPromisey(maybePromise) ? maybePromise.th
|
|
|
1141
1340
|
*/
|
|
1142
1341
|
const isPromisey = (maybePromise) => maybePromise instanceof Promise ||
|
|
1143
1342
|
(maybePromise && maybePromise.then && typeof maybePromise.then === 'function');
|
|
1343
|
+
/**
|
|
1344
|
+
* Update a component given reference to its host elements and so on.
|
|
1345
|
+
*
|
|
1346
|
+
* @param hostRef an object containing references to the element's host node,
|
|
1347
|
+
* VDom nodes, and other metadata
|
|
1348
|
+
* @param instance a reference to the underlying host element where it will be
|
|
1349
|
+
* rendered
|
|
1350
|
+
* @param isInitialLoad whether or not this function is being called as part of
|
|
1351
|
+
* the first render cycle
|
|
1352
|
+
*/
|
|
1144
1353
|
const updateComponent = async (hostRef, instance, isInitialLoad) => {
|
|
1145
1354
|
var _a;
|
|
1146
1355
|
const elm = hostRef.$hostElement$;
|
|
@@ -1152,7 +1361,7 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
|
|
|
1152
1361
|
}
|
|
1153
1362
|
const endRender = createTime('render', hostRef.$cmpMeta$.$tagName$);
|
|
1154
1363
|
{
|
|
1155
|
-
callRender(hostRef, instance);
|
|
1364
|
+
callRender(hostRef, instance, elm, isInitialLoad);
|
|
1156
1365
|
}
|
|
1157
1366
|
if (rc) {
|
|
1158
1367
|
// ok, so turns out there are some child host elements
|
|
@@ -1176,8 +1385,24 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
|
|
|
1176
1385
|
}
|
|
1177
1386
|
}
|
|
1178
1387
|
};
|
|
1179
|
-
|
|
1388
|
+
/**
|
|
1389
|
+
* Handle making the call to the VDom renderer with the proper context given
|
|
1390
|
+
* various build variables
|
|
1391
|
+
*
|
|
1392
|
+
* @param hostRef an object containing references to the element's host node,
|
|
1393
|
+
* VDom nodes, and other metadata
|
|
1394
|
+
* @param instance a reference to the underlying host element where it will be
|
|
1395
|
+
* rendered
|
|
1396
|
+
* @param elm the Host element for the component
|
|
1397
|
+
* @param isInitialLoad whether or not this function is being called as part of
|
|
1398
|
+
* @returns an empty promise
|
|
1399
|
+
*/
|
|
1400
|
+
const callRender = (hostRef, instance, elm, isInitialLoad) => {
|
|
1180
1401
|
try {
|
|
1402
|
+
/**
|
|
1403
|
+
* minification optimization: `allRenderFn` is `true` if all components have a `render`
|
|
1404
|
+
* method, so we can call the method immediately. If not, check before calling it.
|
|
1405
|
+
*/
|
|
1181
1406
|
instance = instance.render() ;
|
|
1182
1407
|
{
|
|
1183
1408
|
hostRef.$flags$ &= ~16 /* HOST_FLAGS.isQueuedForUpdate */;
|
|
@@ -1191,7 +1416,7 @@ const callRender = (hostRef, instance, elm) => {
|
|
|
1191
1416
|
// or we need to update the css class/attrs on the host element
|
|
1192
1417
|
// DOM WRITE!
|
|
1193
1418
|
{
|
|
1194
|
-
renderVdom(hostRef, instance);
|
|
1419
|
+
renderVdom(hostRef, instance, isInitialLoad);
|
|
1195
1420
|
}
|
|
1196
1421
|
}
|
|
1197
1422
|
}
|
|
@@ -1251,6 +1476,16 @@ const appDidLoad = (who) => {
|
|
|
1251
1476
|
}
|
|
1252
1477
|
nextTick(() => emitEvent(win, 'appload', { detail: { namespace: NAMESPACE } }));
|
|
1253
1478
|
};
|
|
1479
|
+
/**
|
|
1480
|
+
* Allows to safely call a method, e.g. `componentDidLoad`, on an instance,
|
|
1481
|
+
* e.g. custom element node. If a build figures out that e.g. no component
|
|
1482
|
+
* has a `componentDidLoad` method, the instance method gets removed from the
|
|
1483
|
+
* output bundle and this function returns `undefined`.
|
|
1484
|
+
* @param instance any object that may or may not contain methods
|
|
1485
|
+
* @param method method name
|
|
1486
|
+
* @param arg single arbitrary argument
|
|
1487
|
+
* @returns result of method call if it exists, otherwise `undefined`
|
|
1488
|
+
*/
|
|
1254
1489
|
const safeCall = (instance, method, arg) => {
|
|
1255
1490
|
if (instance && instance[method]) {
|
|
1256
1491
|
try {
|
|
@@ -1301,10 +1536,11 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
|
|
|
1301
1536
|
* @returns a reference to the same constructor passed in (but now mutated)
|
|
1302
1537
|
*/
|
|
1303
1538
|
const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
1539
|
+
var _a;
|
|
1540
|
+
const prototype = Cstr.prototype;
|
|
1304
1541
|
if (cmpMeta.$members$) {
|
|
1305
1542
|
// It's better to have a const than two Object.entries()
|
|
1306
1543
|
const members = Object.entries(cmpMeta.$members$);
|
|
1307
|
-
const prototype = Cstr.prototype;
|
|
1308
1544
|
members.map(([memberName, [memberFlags]]) => {
|
|
1309
1545
|
if ((memberFlags & 31 /* MEMBER_FLAGS.Prop */ ||
|
|
1310
1546
|
((flags & 2 /* PROXY_FLAGS.proxyState */) && memberFlags & 32 /* MEMBER_FLAGS.State */))) {
|
|
@@ -1325,8 +1561,9 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
1325
1561
|
});
|
|
1326
1562
|
if ((flags & 1 /* PROXY_FLAGS.isElementConstructor */)) {
|
|
1327
1563
|
const attrNameToPropName = new Map();
|
|
1328
|
-
prototype.attributeChangedCallback = function (attrName,
|
|
1564
|
+
prototype.attributeChangedCallback = function (attrName, oldValue, newValue) {
|
|
1329
1565
|
plt.jmp(() => {
|
|
1566
|
+
var _a;
|
|
1330
1567
|
const propName = attrNameToPropName.get(attrName);
|
|
1331
1568
|
// In a web component lifecycle the attributeChangedCallback runs prior to connectedCallback
|
|
1332
1569
|
// in the case where an attribute was set inline.
|
|
@@ -1348,12 +1585,12 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
1348
1585
|
// customElements.define('my-component', MyComponent);
|
|
1349
1586
|
// </script>
|
|
1350
1587
|
// ```
|
|
1351
|
-
// In this case if we do not
|
|
1588
|
+
// In this case if we do not un-shadow here and use the value of the shadowing property, attributeChangedCallback
|
|
1352
1589
|
// will be called with `newValue = "some-value"` and will set the shadowed property (this.someAttribute = "another-value")
|
|
1353
1590
|
// to the value that was set inline i.e. "some-value" from above example. When
|
|
1354
|
-
// the connectedCallback attempts to
|
|
1591
|
+
// the connectedCallback attempts to un-shadow it will use "some-value" as the initial value rather than "another-value"
|
|
1355
1592
|
//
|
|
1356
|
-
// The case where the attribute was NOT set inline but was not set programmatically shall be handled/
|
|
1593
|
+
// The case where the attribute was NOT set inline but was not set programmatically shall be handled/un-shadowed
|
|
1357
1594
|
// by connectedCallback as this attributeChangedCallback will not fire.
|
|
1358
1595
|
//
|
|
1359
1596
|
// https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
|
|
@@ -1373,26 +1610,67 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
1373
1610
|
// `propName` to be converted to a `DOMString`, which may not be what we want for other primitive props.
|
|
1374
1611
|
return;
|
|
1375
1612
|
}
|
|
1613
|
+
else if (propName == null) {
|
|
1614
|
+
// At this point we should know this is not a "member", so we can treat it like watching an attribute
|
|
1615
|
+
// on a vanilla web component
|
|
1616
|
+
const hostRef = getHostRef(this);
|
|
1617
|
+
const flags = hostRef === null || hostRef === void 0 ? void 0 : hostRef.$flags$;
|
|
1618
|
+
// We only want to trigger the callback(s) if:
|
|
1619
|
+
// 1. The instance is ready
|
|
1620
|
+
// 2. The watchers are ready
|
|
1621
|
+
// 3. The value has changed
|
|
1622
|
+
if (flags &&
|
|
1623
|
+
!(flags & 8 /* HOST_FLAGS.isConstructingInstance */) &&
|
|
1624
|
+
flags & 128 /* HOST_FLAGS.isWatchReady */ &&
|
|
1625
|
+
newValue !== oldValue) {
|
|
1626
|
+
const instance = hostRef.$lazyInstance$ ;
|
|
1627
|
+
const entry = (_a = cmpMeta.$watchers$) === null || _a === void 0 ? void 0 : _a[attrName];
|
|
1628
|
+
entry === null || entry === void 0 ? void 0 : entry.forEach((callbackName) => {
|
|
1629
|
+
if (instance[callbackName] != null) {
|
|
1630
|
+
instance[callbackName].call(instance, newValue, oldValue, attrName);
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
1634
|
+
return;
|
|
1635
|
+
}
|
|
1376
1636
|
this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
|
|
1377
1637
|
});
|
|
1378
1638
|
};
|
|
1379
|
-
//
|
|
1380
|
-
//
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1639
|
+
// Create an array of attributes to observe
|
|
1640
|
+
// This list in comprised of all strings used within a `@Watch()` decorator
|
|
1641
|
+
// on a component as well as any Stencil-specific "members" (`@Prop()`s and `@State()`s).
|
|
1642
|
+
// As such, there is no way to guarantee type-safety here that a user hasn't entered
|
|
1643
|
+
// an invalid attribute.
|
|
1644
|
+
Cstr.observedAttributes = Array.from(new Set([
|
|
1645
|
+
...Object.keys((_a = cmpMeta.$watchers$) !== null && _a !== void 0 ? _a : {}),
|
|
1646
|
+
...members
|
|
1647
|
+
.filter(([_, m]) => m[0] & 15 /* MEMBER_FLAGS.HasAttribute */)
|
|
1648
|
+
.map(([propName, m]) => {
|
|
1649
|
+
var _a;
|
|
1650
|
+
const attrName = m[1] || propName;
|
|
1651
|
+
attrNameToPropName.set(attrName, propName);
|
|
1652
|
+
if (m[0] & 512 /* MEMBER_FLAGS.ReflectAttr */) {
|
|
1653
|
+
(_a = cmpMeta.$attrsToReflect$) === null || _a === void 0 ? void 0 : _a.push([propName, attrName]);
|
|
1654
|
+
}
|
|
1655
|
+
return attrName;
|
|
1656
|
+
}),
|
|
1657
|
+
]));
|
|
1391
1658
|
}
|
|
1392
1659
|
}
|
|
1393
1660
|
return Cstr;
|
|
1394
1661
|
};
|
|
1395
|
-
|
|
1662
|
+
/**
|
|
1663
|
+
* Initialize a Stencil component given a reference to its host element, its
|
|
1664
|
+
* runtime bookkeeping data structure, runtime metadata about the component,
|
|
1665
|
+
* and (optionally) an HMR version ID.
|
|
1666
|
+
*
|
|
1667
|
+
* @param elm a host element
|
|
1668
|
+
* @param hostRef the element's runtime bookkeeping object
|
|
1669
|
+
* @param cmpMeta runtime metadata for the Stencil component
|
|
1670
|
+
* @param hmrVersionId an (optional) HMR version ID
|
|
1671
|
+
*/
|
|
1672
|
+
const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
|
|
1673
|
+
let Cstr;
|
|
1396
1674
|
// initializeComponent
|
|
1397
1675
|
if ((hostRef.$flags$ & 32 /* HOST_FLAGS.hasInitializedComponent */) === 0) {
|
|
1398
1676
|
// Let the runtime know that the component has been initialized
|
|
@@ -1461,6 +1739,8 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
1461
1739
|
schedule();
|
|
1462
1740
|
}
|
|
1463
1741
|
};
|
|
1742
|
+
const fireConnectedCallback = (instance) => {
|
|
1743
|
+
};
|
|
1464
1744
|
const connectedCallback = (elm) => {
|
|
1465
1745
|
if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
|
|
1466
1746
|
const hostRef = getHostRef(elm);
|
|
@@ -1509,6 +1789,13 @@ const connectedCallback = (elm) => {
|
|
|
1509
1789
|
initializeComponent(elm, hostRef, cmpMeta);
|
|
1510
1790
|
}
|
|
1511
1791
|
}
|
|
1792
|
+
else {
|
|
1793
|
+
// fire off connectedCallback() on component instance
|
|
1794
|
+
if (hostRef === null || hostRef === void 0 ? void 0 : hostRef.$lazyInstance$) ;
|
|
1795
|
+
else if (hostRef === null || hostRef === void 0 ? void 0 : hostRef.$onReadyPromise$) {
|
|
1796
|
+
hostRef.$onReadyPromise$.then(() => fireConnectedCallback());
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1512
1799
|
endConnected();
|
|
1513
1800
|
}
|
|
1514
1801
|
};
|
|
@@ -1523,9 +1810,15 @@ const setContentReference = (elm) => {
|
|
|
1523
1810
|
contentRefElm['s-cn'] = true;
|
|
1524
1811
|
elm.insertBefore(contentRefElm, elm.firstChild);
|
|
1525
1812
|
};
|
|
1526
|
-
const
|
|
1813
|
+
const disconnectInstance = (instance) => {
|
|
1814
|
+
};
|
|
1815
|
+
const disconnectedCallback = async (elm) => {
|
|
1527
1816
|
if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
|
|
1528
|
-
getHostRef(elm);
|
|
1817
|
+
const hostRef = getHostRef(elm);
|
|
1818
|
+
if (hostRef === null || hostRef === void 0 ? void 0 : hostRef.$lazyInstance$) ;
|
|
1819
|
+
else if (hostRef === null || hostRef === void 0 ? void 0 : hostRef.$onReadyPromise$) {
|
|
1820
|
+
hostRef.$onReadyPromise$.then(() => disconnectInstance());
|
|
1821
|
+
}
|
|
1529
1822
|
}
|
|
1530
1823
|
};
|
|
1531
1824
|
const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
@@ -1536,12 +1829,13 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
1536
1829
|
const customElements = win.customElements;
|
|
1537
1830
|
const head = doc.head;
|
|
1538
1831
|
const metaCharset = /*@__PURE__*/ head.querySelector('meta[charset]');
|
|
1539
|
-
const
|
|
1832
|
+
const dataStyles = /*@__PURE__*/ doc.createElement('style');
|
|
1540
1833
|
const deferredConnectedCallbacks = [];
|
|
1541
1834
|
let appLoadFallback;
|
|
1542
1835
|
let isBootstrapping = true;
|
|
1543
1836
|
Object.assign(plt, options);
|
|
1544
1837
|
plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
|
|
1838
|
+
let hasSlotRelocation = false;
|
|
1545
1839
|
lazyBundles.map((lazyBundle) => {
|
|
1546
1840
|
lazyBundle[1].map((compactMeta) => {
|
|
1547
1841
|
const cmpMeta = {
|
|
@@ -1550,6 +1844,11 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
1550
1844
|
$members$: compactMeta[2],
|
|
1551
1845
|
$listeners$: compactMeta[3],
|
|
1552
1846
|
};
|
|
1847
|
+
// Check if we are using slots outside the shadow DOM in this component.
|
|
1848
|
+
// We'll use this information later to add styles for `slot-fb` elements
|
|
1849
|
+
if (cmpMeta.$flags$ & 4 /* CMP_FLAGS.hasSlotRelocation */) {
|
|
1850
|
+
hasSlotRelocation = true;
|
|
1851
|
+
}
|
|
1553
1852
|
{
|
|
1554
1853
|
cmpMeta.$members$ = compactMeta[2];
|
|
1555
1854
|
}
|
|
@@ -1592,15 +1891,29 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
1592
1891
|
}
|
|
1593
1892
|
});
|
|
1594
1893
|
});
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
//
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1894
|
+
// Only bother generating CSS if we have components
|
|
1895
|
+
// TODO(STENCIL-1118): Add test cases for CSS content based on conditionals
|
|
1896
|
+
if (cmpTags.length > 0) {
|
|
1897
|
+
// Add styles for `slot-fb` elements if any of our components are using slots outside the Shadow DOM
|
|
1898
|
+
if (hasSlotRelocation) {
|
|
1899
|
+
dataStyles.textContent += SLOT_FB_CSS;
|
|
1900
|
+
}
|
|
1901
|
+
// Add hydration styles
|
|
1902
|
+
{
|
|
1903
|
+
dataStyles.textContent += cmpTags + HYDRATED_CSS;
|
|
1904
|
+
}
|
|
1905
|
+
// If we have styles, add them to the DOM
|
|
1906
|
+
if (dataStyles.innerHTML.length) {
|
|
1907
|
+
dataStyles.setAttribute('data-styles', '');
|
|
1908
|
+
// Apply CSP nonce to the style tag if it exists
|
|
1909
|
+
const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
|
|
1910
|
+
if (nonce != null) {
|
|
1911
|
+
dataStyles.setAttribute('nonce', nonce);
|
|
1912
|
+
}
|
|
1913
|
+
// Insert the styles into the document head
|
|
1914
|
+
// NOTE: this _needs_ to happen last so we can ensure the nonce (and other attributes) are applied
|
|
1915
|
+
head.insertBefore(dataStyles, metaCharset ? metaCharset.nextSibling : head.firstChild);
|
|
1602
1916
|
}
|
|
1603
|
-
head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
|
|
1604
1917
|
}
|
|
1605
1918
|
// Process deferred connectedCallbacks now all components have been registered
|
|
1606
1919
|
isBootstrapping = false;
|
|
@@ -1622,22 +1935,60 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
1622
1935
|
* @returns void
|
|
1623
1936
|
*/
|
|
1624
1937
|
const setNonce = (nonce) => (plt.$nonce$ = nonce);
|
|
1625
|
-
|
|
1938
|
+
/**
|
|
1939
|
+
* A WeakMap mapping runtime component references to their corresponding host reference
|
|
1940
|
+
* instances.
|
|
1941
|
+
*
|
|
1942
|
+
* **Note**: If we're in an HMR context we need to store a reference to this
|
|
1943
|
+
* value on `window` in order to maintain the mapping of {@link d.RuntimeRef}
|
|
1944
|
+
* to {@link d.HostRef} across HMR updates.
|
|
1945
|
+
*
|
|
1946
|
+
* This is necessary because when HMR updates for a component are processed by
|
|
1947
|
+
* the browser-side dev server client the JS bundle for that component is
|
|
1948
|
+
* re-fetched. Since the module containing {@link hostRefs} is included in
|
|
1949
|
+
* that bundle, if we do not store a reference to it the new iteration of the
|
|
1950
|
+
* component will not have access to the previous hostRef map, leading to a
|
|
1951
|
+
* bug where the new version of the component cannot properly initialize.
|
|
1952
|
+
*/
|
|
1953
|
+
const hostRefs = new WeakMap();
|
|
1954
|
+
/**
|
|
1955
|
+
* Given a {@link d.RuntimeRef} retrieve the corresponding {@link d.HostRef}
|
|
1956
|
+
*
|
|
1957
|
+
* @param ref the runtime ref of interest
|
|
1958
|
+
* @returns the Host reference (if found) or undefined
|
|
1959
|
+
*/
|
|
1626
1960
|
const getHostRef = (ref) => hostRefs.get(ref);
|
|
1961
|
+
/**
|
|
1962
|
+
* Register a lazy instance with the {@link hostRefs} object so it's
|
|
1963
|
+
* corresponding {@link d.HostRef} can be retrieved later.
|
|
1964
|
+
*
|
|
1965
|
+
* @param lazyInstance the lazy instance of interest
|
|
1966
|
+
* @param hostRef that instances `HostRef` object
|
|
1967
|
+
* @returns a reference to the host ref WeakMap
|
|
1968
|
+
*/
|
|
1627
1969
|
const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
|
|
1628
|
-
|
|
1970
|
+
/**
|
|
1971
|
+
* Register a host element for a Stencil component, setting up various metadata
|
|
1972
|
+
* and callbacks based on {@link BUILD} flags as well as the component's runtime
|
|
1973
|
+
* metadata.
|
|
1974
|
+
*
|
|
1975
|
+
* @param hostElement the host element to register
|
|
1976
|
+
* @param cmpMeta runtime metadata for that component
|
|
1977
|
+
* @returns a reference to the host ref WeakMap
|
|
1978
|
+
*/
|
|
1979
|
+
const registerHost = (hostElement, cmpMeta) => {
|
|
1629
1980
|
const hostRef = {
|
|
1630
1981
|
$flags$: 0,
|
|
1631
|
-
$hostElement$:
|
|
1982
|
+
$hostElement$: hostElement,
|
|
1632
1983
|
$cmpMeta$: cmpMeta,
|
|
1633
1984
|
$instanceValues$: new Map(),
|
|
1634
1985
|
};
|
|
1635
1986
|
{
|
|
1636
1987
|
hostRef.$onReadyPromise$ = new Promise((r) => (hostRef.$onReadyResolve$ = r));
|
|
1637
|
-
|
|
1638
|
-
|
|
1988
|
+
hostElement['s-p'] = [];
|
|
1989
|
+
hostElement['s-rc'] = [];
|
|
1639
1990
|
}
|
|
1640
|
-
return hostRefs.set(
|
|
1991
|
+
return hostRefs.set(hostElement, hostRef);
|
|
1641
1992
|
};
|
|
1642
1993
|
const isMemberInElement = (elm, memberName) => memberName in elm;
|
|
1643
1994
|
const consoleError = (e, el) => (0, console.error)(e, el);
|
|
@@ -1725,9 +2076,9 @@ const flush = () => {
|
|
|
1725
2076
|
}
|
|
1726
2077
|
}
|
|
1727
2078
|
};
|
|
1728
|
-
const nextTick =
|
|
2079
|
+
const nextTick = (cb) => promiseResolve().then(cb);
|
|
1729
2080
|
const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
|
|
1730
2081
|
|
|
1731
2082
|
export { Host as H, bootstrapLazy as b, h, promiseResolve as p, registerInstance as r, setNonce as s };
|
|
1732
2083
|
|
|
1733
|
-
//# sourceMappingURL=index-
|
|
2084
|
+
//# sourceMappingURL=index-b0176170.js.map
|