favesalon-embed 0.0.3 → 0.0.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/LICENSE +21 -0
- package/dist/cjs/_commonjsHelpers-5cfcba41.js +36 -0
- package/dist/cjs/chat-button.cjs.entry.js +118 -0
- package/dist/cjs/colors-38421769.js +69 -0
- package/dist/cjs/favesalon-embed.cjs.js +24 -0
- package/dist/cjs/google-map_5.cjs.entry.js +310 -0
- package/{cjs/index-7d179a70.js → dist/cjs/index-47c2a5f6.js} +587 -199
- package/dist/cjs/index-7f190886.js +4396 -0
- package/dist/cjs/loader.cjs.js +23 -0
- package/dist/cjs/relativeTime-3721080d.js +9 -0
- package/dist/cjs/salon-booking-modal.cjs.entry.js +30 -0
- package/dist/cjs/salon-booking.cjs.entry.js +51 -0
- package/dist/cjs/salon-gift-card-modal.cjs.entry.js +29 -0
- package/dist/cjs/salon-gift-card.cjs.entry.js +51 -0
- package/dist/cjs/salon-latest-reviews.cjs.entry.js +97 -0
- package/dist/cjs/salon-lookbook.cjs.entry.js +222 -0
- package/dist/cjs/salon-ranking.cjs.entry.js +60 -0
- package/dist/cjs/salon-reviews.cjs.entry.js +193 -0
- package/dist/cjs/salon-services.cjs.entry.js +81 -0
- package/dist/cjs/salon-stylists.cjs.entry.js +118 -0
- package/dist/cjs/services-125c82d8.js +21492 -0
- package/dist/cjs/style-detail.cjs.entry.js +312 -0
- package/dist/cjs/user-avatar.cjs.entry.js +45 -0
- package/dist/cjs/utils-c5a33b3c.js +23 -0
- package/{collection → dist/collection}/collection-manifest.json +5 -4
- package/dist/collection/components/chat-button/index.css +122 -0
- package/dist/collection/components/chat-button/index.js +218 -0
- package/dist/collection/components/chat-conversation/index.js +103 -0
- package/dist/collection/components/google-map/assets/map--placeholder.jpeg +0 -0
- package/{collection → dist/collection}/components/google-map/index.css +0 -1
- package/dist/collection/components/google-map/index.js +90 -0
- package/{collection → dist/collection}/components/salon-booking/index.css +11 -20
- package/dist/collection/components/salon-booking/index.js +126 -0
- package/dist/collection/components/salon-booking/salon-booking-modal.js +92 -0
- package/dist/collection/components/salon-gift-card/index.css +30 -0
- package/dist/collection/components/salon-gift-card/index.js +126 -0
- package/dist/collection/components/salon-gift-card/salon-gift-card-modal.js +73 -0
- package/dist/collection/components/salon-info/index.js +77 -0
- package/dist/collection/components/salon-latest-reviews/index.js +163 -0
- package/dist/collection/components/salon-latest-styles/index.css +12 -0
- package/dist/collection/components/salon-latest-styles/index.js +183 -0
- package/{collection/components/salon-contact → dist/collection/components/salon-locations}/index.css +7 -4
- package/dist/collection/components/salon-locations/index.js +143 -0
- package/dist/collection/components/salon-lookbook/index.css +15 -0
- package/dist/collection/components/salon-lookbook/index.js +368 -0
- package/dist/collection/components/salon-ranking/index.js +117 -0
- package/dist/collection/components/salon-reviews/index.css +18 -0
- package/dist/collection/components/salon-reviews/index.js +249 -0
- package/dist/collection/components/salon-schedules/index.css +18 -0
- package/dist/collection/components/salon-schedules/index.js +167 -0
- package/dist/collection/components/salon-services/index.css +1 -0
- package/dist/collection/components/salon-services/index.js +146 -0
- package/dist/collection/components/salon-stylists/index.js +184 -0
- package/dist/collection/components/style-detail/index.css +76 -0
- package/dist/collection/components/style-detail/index.js +386 -0
- package/dist/collection/components/user-avatar/index.js +134 -0
- package/dist/collection/constants/colors.js +65 -0
- package/dist/collection/mocks/users.js +10 -0
- package/dist/collection/services/services.js +295 -0
- package/dist/collection/types/chat.js +23 -0
- package/dist/collection/types/common.js +11 -0
- package/{collection → dist/collection}/types/review.js +9 -5
- package/dist/collection/types/salon.js +58 -0
- package/dist/collection/types/style.js +128 -0
- package/dist/collection/types/stylist.js +30 -0
- package/dist/collection/types/user.js +10 -0
- package/{custom-elements → dist/custom-elements}/index.d.ts +18 -12
- package/dist/custom-elements/index.js +28340 -0
- package/dist/esm/_commonjsHelpers-098d5b27.js +32 -0
- package/dist/esm/chat-button.entry.js +114 -0
- package/dist/esm/colors-ea36347a.js +67 -0
- package/dist/esm/favesalon-embed.js +19 -0
- package/dist/esm/google-map_5.entry.js +302 -0
- package/{esm/index-2160b80b.js → dist/esm/index-3fae868e.js} +586 -200
- package/dist/esm/index-80523fec.js +4393 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/loader.js +19 -0
- package/dist/esm/polyfills/css-shim.js +1 -0
- package/dist/esm/relativeTime-cd452e6d.js +7 -0
- package/dist/esm/salon-booking-modal.entry.js +26 -0
- package/dist/esm/salon-booking.entry.js +47 -0
- package/dist/esm/salon-gift-card-modal.entry.js +25 -0
- package/dist/esm/salon-gift-card.entry.js +47 -0
- package/dist/esm/salon-latest-reviews.entry.js +93 -0
- package/dist/esm/salon-lookbook.entry.js +218 -0
- package/dist/esm/salon-ranking.entry.js +56 -0
- package/dist/esm/salon-reviews.entry.js +189 -0
- package/dist/esm/salon-services.entry.js +77 -0
- package/dist/esm/salon-stylists.entry.js +114 -0
- package/dist/esm/services-40a3e622.js +21485 -0
- package/dist/esm/style-detail.entry.js +308 -0
- package/dist/esm/user-avatar.entry.js +41 -0
- package/dist/esm/utils-e97485e0.js +19 -0
- package/dist/favesalon-embed/assets/map--placeholder.jpeg +0 -0
- package/{favesalon-embed → dist/favesalon-embed}/favesalon-embed.css +1 -1
- package/dist/favesalon-embed/favesalon-embed.esm.js +1 -0
- package/dist/favesalon-embed/p-019c5ccd.entry.js +1 -0
- package/dist/favesalon-embed/p-083a8821.entry.js +1 -0
- package/dist/favesalon-embed/p-0d0ed9ea.entry.js +1 -0
- package/dist/favesalon-embed/p-119db8de.entry.js +1 -0
- package/dist/favesalon-embed/p-1432c51b.entry.js +1 -0
- package/dist/favesalon-embed/p-22093506.entry.js +1 -0
- package/dist/favesalon-embed/p-32b314e9.js +2 -0
- package/dist/favesalon-embed/p-47e646f8.js +1 -0
- package/dist/favesalon-embed/p-4a5eca9a.js +6 -0
- package/dist/favesalon-embed/p-58d2e9be.js +1 -0
- package/dist/favesalon-embed/p-71404b6a.entry.js +1 -0
- package/dist/favesalon-embed/p-857c3a61.entry.js +1 -0
- package/dist/favesalon-embed/p-99ec77f7.entry.js +1 -0
- package/dist/favesalon-embed/p-a33331cc.js +1 -0
- package/dist/favesalon-embed/p-b0c3673a.entry.js +1 -0
- package/dist/favesalon-embed/p-b287b1ea.entry.js +1 -0
- package/dist/favesalon-embed/p-b3af7842.entry.js +1 -0
- package/dist/favesalon-embed/p-b630ae68.js +1580 -0
- package/dist/favesalon-embed/p-ce2c1c9a.entry.js +1 -0
- package/dist/favesalon-embed/p-d6083940.js +1 -0
- package/dist/favesalon-embed/p-d9b7ad58.entry.js +1 -0
- package/dist/favesalon-embed/p-fc9a5551.js +6 -0
- package/dist/types/components/chat-button/index.d.ts +24 -0
- package/dist/types/components/google-map/index.d.ts +5 -0
- package/{types → dist/types}/components/salon-booking/salon-booking-modal.d.ts +1 -0
- package/{types → dist/types}/components/salon-gift-card/index.d.ts +2 -1
- package/{types → dist/types}/components/salon-gift-card/salon-gift-card-modal.d.ts +2 -0
- package/{types → dist/types}/components/salon-info/index.d.ts +0 -1
- package/{types → dist/types}/components/salon-latest-reviews/index.d.ts +2 -0
- package/dist/types/components/salon-latest-styles/index.d.ts +12 -0
- package/{types → dist/types}/components/salon-locations/index.d.ts +2 -0
- package/{types → dist/types}/components/salon-lookbook/index.d.ts +7 -2
- package/dist/types/components/salon-reviews/index.d.ts +24 -0
- package/{types → dist/types}/components/salon-schedules/index.d.ts +2 -0
- package/{types → dist/types}/components/salon-services/index.d.ts +1 -0
- package/{types → dist/types}/components/salon-stylists/index.d.ts +6 -0
- package/dist/types/components/style-detail/index.d.ts +24 -0
- package/{types → dist/types}/components.d.ts +82 -41
- package/dist/types/constants/colors.d.ts +65 -0
- package/dist/types/mocks/users.d.ts +10 -0
- package/dist/types/services/services.d.ts +75 -0
- package/{types → dist/types}/stencil-public-runtime.d.ts +85 -11
- package/dist/types/types/chat.d.ts +17 -0
- package/dist/types/types/common.d.ts +11 -0
- package/{types → dist/types}/types/review.d.ts +4 -0
- package/{types → dist/types}/types/salon.d.ts +3 -1
- package/dist/types/types/style.d.ts +88 -0
- package/{types → dist/types}/types/stylist.d.ts +2 -1
- package/{types → dist/types}/types/user.d.ts +2 -2
- package/loader/cdn.js +3 -0
- package/loader/index.cjs.js +3 -0
- package/loader/index.d.ts +21 -0
- package/loader/index.es2017.js +3 -0
- package/loader/index.js +4 -0
- package/loader/package.json +11 -0
- package/package.json +19 -14
- package/readme.md +25 -2
- package/cjs/favesalon-embed.cjs.js +0 -20
- package/cjs/google-map_15.cjs.entry.js +0 -6632
- package/cjs/loader.cjs.js +0 -22
- package/cjs/salon-booking-modal.cjs.entry.js +0 -23
- package/cjs/salon-gift-card-modal.cjs.entry.js +0 -20
- package/collection/components/google-map/index.js +0 -97
- package/collection/components/salon-booking/index.js +0 -103
- package/collection/components/salon-booking/salon-booking-modal.js +0 -82
- package/collection/components/salon-contact/index.js +0 -88
- package/collection/components/salon-gift-card/index.css +0 -25
- package/collection/components/salon-gift-card/index.js +0 -83
- package/collection/components/salon-gift-card/salon-gift-card-modal.js +0 -43
- package/collection/components/salon-info/index.css +0 -3
- package/collection/components/salon-info/index.js +0 -97
- package/collection/components/salon-latest-reviews/index.js +0 -108
- package/collection/components/salon-locations/index.js +0 -80
- package/collection/components/salon-lookbook/index.css +0 -12
- package/collection/components/salon-lookbook/index.js +0 -303
- package/collection/components/salon-ranking/index.js +0 -114
- package/collection/components/salon-reviews/index.js +0 -291
- package/collection/components/salon-schedules/index.css +0 -14
- package/collection/components/salon-schedules/index.js +0 -103
- package/collection/components/salon-services/index.css +0 -0
- package/collection/components/salon-services/index.js +0 -113
- package/collection/components/salon-styles/index.css +0 -23
- package/collection/components/salon-styles/index.js +0 -100
- package/collection/components/salon-stylists/index.js +0 -96
- package/collection/components/user-avatar/index.css +0 -0
- package/collection/components/user-avatar/index.js +0 -127
- package/collection/constants/colors.js +0 -91
- package/collection/services/services.js +0 -203
- package/collection/types/common.js +0 -2
- package/collection/types/salon.js +0 -52
- package/collection/types/style.js +0 -28
- package/collection/types/stylist.js +0 -13
- package/collection/types/user.js +0 -10
- package/custom-elements/index.js +0 -7410
- package/esm/favesalon-embed.js +0 -18
- package/esm/google-map_15.entry.js +0 -6614
- package/esm/loader.js +0 -18
- package/esm/polyfills/css-shim.js +0 -1
- package/esm/salon-booking-modal.entry.js +0 -19
- package/esm/salon-gift-card-modal.entry.js +0 -16
- package/favesalon-embed/favesalon-embed.esm.js +0 -1
- package/favesalon-embed/p-1432ab16.entry.js +0 -1
- package/favesalon-embed/p-2da2ed75.js +0 -1
- package/favesalon-embed/p-4a5eca9a.js +0 -6
- package/favesalon-embed/p-94a0991e.entry.js +0 -1
- package/favesalon-embed/p-f15bcb43.entry.js +0 -1
- package/types/components/google-map/index.d.ts +0 -10
- package/types/components/salon-contact/index.d.ts +0 -9
- package/types/components/salon-reviews/index.d.ts +0 -23
- package/types/components/salon-styles/index.d.ts +0 -9
- package/types/constants/colors.d.ts +0 -88
- package/types/services/services.d.ts +0 -24
- package/types/types/common.d.ts +0 -2
- package/types/types/style.d.ts +0 -49
- package/{cjs → dist/cjs}/global-9073d10e.js +0 -0
- package/{cjs → dist/cjs}/index.cjs.js +0 -0
- package/{esm/index.js → dist/collection/components/salon-info/index.css} +0 -0
- package/{collection → dist/collection}/components/salon-latest-reviews/index.css +0 -0
- package/{collection → dist/collection}/components/salon-ranking/index.css +0 -0
- package/{collection → dist/collection}/components/salon-stylists/index.css +0 -0
- package/{collection/components/salon-locations → dist/collection/components/user-avatar}/index.css +0 -0
- package/{collection → dist/collection}/global/global.js +0 -0
- package/{collection → dist/collection}/index.js +0 -0
- package/{collection → dist/collection}/types/service.js +0 -0
- package/{collection → dist/collection}/utils/utils.js +0 -0
- package/{esm → dist/esm}/global-e1089ffd.js +0 -0
- package/{esm → dist/esm}/polyfills/core-js.js +0 -0
- package/{esm → dist/esm}/polyfills/dom.js +0 -0
- package/{esm → dist/esm}/polyfills/es5-html-element.js +0 -0
- package/{esm → dist/esm}/polyfills/index.js +0 -0
- package/{esm → dist/esm}/polyfills/system.js +0 -0
- package/{favesalon-embed → dist/favesalon-embed}/index.esm.js +0 -0
- package/{index.cjs.js → dist/index.cjs.js} +0 -0
- package/{index.js → dist/index.js} +0 -0
- package/{collection/components/salon-reviews/index.css → dist/types/components/chat-conversation/index.d.ts} +0 -0
- package/{types → dist/types}/components/salon-booking/index.d.ts +1 -1
- /package/{types → dist/types}/components/salon-ranking/index.d.ts +0 -0
- /package/{types → dist/types}/components/user-avatar/index.d.ts +0 -0
- /package/{types → dist/types}/index.d.ts +0 -0
- /package/{types → dist/types}/types/service.d.ts +0 -0
- /package/{types → dist/types}/utils/utils.d.ts +0 -0
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
const NAMESPACE = 'favesalon-embed';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Virtual DOM patching algorithm based on Snabbdom by
|
|
5
|
+
* Simon Friis Vindum (@paldepind)
|
|
6
|
+
* Licensed under the MIT License
|
|
7
|
+
* https://github.com/snabbdom/snabbdom/blob/master/LICENSE
|
|
8
|
+
*
|
|
9
|
+
* Modified for Stencil's renderer and slot projection
|
|
10
|
+
*/
|
|
3
11
|
let isSvgMode = false;
|
|
4
12
|
let queuePending = false;
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
$flags$: 0,
|
|
9
|
-
$resourcesUrl$: '',
|
|
10
|
-
jmp: (h) => h(),
|
|
11
|
-
raf: (h) => requestAnimationFrame(h),
|
|
12
|
-
ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
|
|
13
|
-
rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
|
|
14
|
-
ce: (eventName, opts) => new CustomEvent(eventName, opts),
|
|
13
|
+
const getAssetPath = (path) => {
|
|
14
|
+
const assetUrl = new URL(path, plt.$resourcesUrl$);
|
|
15
|
+
return assetUrl.origin !== win.location.origin ? assetUrl.href : assetUrl.pathname;
|
|
15
16
|
};
|
|
16
|
-
const promiseResolve = (v) => Promise.resolve(v);
|
|
17
|
-
const supportsConstructibleStylesheets = /*@__PURE__*/ (() => {
|
|
18
|
-
try {
|
|
19
|
-
new CSSStyleSheet();
|
|
20
|
-
return typeof new CSSStyleSheet().replace === 'function';
|
|
21
|
-
}
|
|
22
|
-
catch (e) { }
|
|
23
|
-
return false;
|
|
24
|
-
})()
|
|
25
|
-
;
|
|
26
|
-
const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
|
|
27
17
|
const createTime = (fnName, tagName = '') => {
|
|
28
18
|
{
|
|
29
19
|
return () => {
|
|
@@ -38,59 +28,8 @@ const uniqueTime = (key, measureText) => {
|
|
|
38
28
|
};
|
|
39
29
|
}
|
|
40
30
|
};
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
let style = styles.get(scopeId);
|
|
44
|
-
if (supportsConstructibleStylesheets && allowCS) {
|
|
45
|
-
style = (style || new CSSStyleSheet());
|
|
46
|
-
style.replace(cssText);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
style = cssText;
|
|
50
|
-
}
|
|
51
|
-
styles.set(scopeId, style);
|
|
52
|
-
};
|
|
53
|
-
const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
|
|
54
|
-
let scopeId = getScopeId(cmpMeta);
|
|
55
|
-
let style = styles.get(scopeId);
|
|
56
|
-
// if an element is NOT connected then getRootNode() will return the wrong root node
|
|
57
|
-
// so the fallback is to always use the document for the root node in those cases
|
|
58
|
-
styleContainerNode = styleContainerNode.nodeType === 11 /* DocumentFragment */ ? styleContainerNode : doc;
|
|
59
|
-
if (style) {
|
|
60
|
-
if (typeof style === 'string') {
|
|
61
|
-
styleContainerNode = styleContainerNode.head || styleContainerNode;
|
|
62
|
-
let appliedStyles = rootAppliedStyles.get(styleContainerNode);
|
|
63
|
-
let styleElm;
|
|
64
|
-
if (!appliedStyles) {
|
|
65
|
-
rootAppliedStyles.set(styleContainerNode, (appliedStyles = new Set()));
|
|
66
|
-
}
|
|
67
|
-
if (!appliedStyles.has(scopeId)) {
|
|
68
|
-
{
|
|
69
|
-
{
|
|
70
|
-
styleElm = doc.createElement('style');
|
|
71
|
-
styleElm.innerHTML = style;
|
|
72
|
-
}
|
|
73
|
-
styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
|
|
74
|
-
}
|
|
75
|
-
if (appliedStyles) {
|
|
76
|
-
appliedStyles.add(scopeId);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
else if (!styleContainerNode.adoptedStyleSheets.includes(style)) {
|
|
81
|
-
styleContainerNode.adoptedStyleSheets = [...styleContainerNode.adoptedStyleSheets, style];
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return scopeId;
|
|
85
|
-
};
|
|
86
|
-
const attachStyles = (hostRef) => {
|
|
87
|
-
const cmpMeta = hostRef.$cmpMeta$;
|
|
88
|
-
const elm = hostRef.$hostElement$;
|
|
89
|
-
const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
|
|
90
|
-
addStyle(elm.getRootNode(), cmpMeta);
|
|
91
|
-
endAttachStyles();
|
|
92
|
-
};
|
|
93
|
-
const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
|
|
31
|
+
const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
|
|
32
|
+
const XLINK_NS = 'http://www.w3.org/1999/xlink';
|
|
94
33
|
/**
|
|
95
34
|
* Default style mode id
|
|
96
35
|
*/
|
|
@@ -109,6 +48,18 @@ const isComplexType = (o) => {
|
|
|
109
48
|
o = typeof o;
|
|
110
49
|
return o === 'object' || o === 'function';
|
|
111
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Helper method for querying a `meta` tag that contains a nonce value
|
|
53
|
+
* out of a DOM's head.
|
|
54
|
+
*
|
|
55
|
+
* @param doc The DOM containing the `head` to query against
|
|
56
|
+
* @returns The content of the meta tag representing the nonce value, or `undefined` if no tag
|
|
57
|
+
* exists or the tag has no content.
|
|
58
|
+
*/
|
|
59
|
+
function queryNonceMetaTagContent(doc) {
|
|
60
|
+
var _a, _b, _c;
|
|
61
|
+
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;
|
|
62
|
+
}
|
|
112
63
|
/**
|
|
113
64
|
* Production h() function based on Preact by
|
|
114
65
|
* Jason Miller (@developit)
|
|
@@ -117,14 +68,14 @@ const isComplexType = (o) => {
|
|
|
117
68
|
*
|
|
118
69
|
* Modified for Stencil's compiler and vdom
|
|
119
70
|
*/
|
|
120
|
-
// const stack: any[] = [];
|
|
121
71
|
// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, child?: d.ChildType): d.VNode;
|
|
122
72
|
// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
|
|
123
73
|
const h = (nodeName, vnodeData, ...children) => {
|
|
124
74
|
let child = null;
|
|
75
|
+
let key = null;
|
|
125
76
|
let simple = false;
|
|
126
77
|
let lastSimple = false;
|
|
127
|
-
|
|
78
|
+
const vNodeChildren = [];
|
|
128
79
|
const walk = (c) => {
|
|
129
80
|
for (let i = 0; i < c.length; i++) {
|
|
130
81
|
child = c[i];
|
|
@@ -149,6 +100,10 @@ const h = (nodeName, vnodeData, ...children) => {
|
|
|
149
100
|
};
|
|
150
101
|
walk(children);
|
|
151
102
|
if (vnodeData) {
|
|
103
|
+
// normalize class / classname attributes
|
|
104
|
+
if (vnodeData.key) {
|
|
105
|
+
key = vnodeData.key;
|
|
106
|
+
}
|
|
152
107
|
{
|
|
153
108
|
const classData = vnodeData.className || vnodeData.class;
|
|
154
109
|
if (classData) {
|
|
@@ -166,8 +121,19 @@ const h = (nodeName, vnodeData, ...children) => {
|
|
|
166
121
|
if (vNodeChildren.length > 0) {
|
|
167
122
|
vnode.$children$ = vNodeChildren;
|
|
168
123
|
}
|
|
124
|
+
{
|
|
125
|
+
vnode.$key$ = key;
|
|
126
|
+
}
|
|
169
127
|
return vnode;
|
|
170
128
|
};
|
|
129
|
+
/**
|
|
130
|
+
* A utility function for creating a virtual DOM node from a tag and some
|
|
131
|
+
* possible text content.
|
|
132
|
+
*
|
|
133
|
+
* @param tag the tag for this element
|
|
134
|
+
* @param text possible text content for the node
|
|
135
|
+
* @returns a newly-minted virtual DOM node
|
|
136
|
+
*/
|
|
171
137
|
const newVNode = (tag, text) => {
|
|
172
138
|
const vnode = {
|
|
173
139
|
$flags$: 0,
|
|
@@ -179,10 +145,142 @@ const newVNode = (tag, text) => {
|
|
|
179
145
|
{
|
|
180
146
|
vnode.$attrs$ = null;
|
|
181
147
|
}
|
|
148
|
+
{
|
|
149
|
+
vnode.$key$ = null;
|
|
150
|
+
}
|
|
182
151
|
return vnode;
|
|
183
152
|
};
|
|
184
153
|
const Host = {};
|
|
154
|
+
/**
|
|
155
|
+
* Check whether a given node is a Host node or not
|
|
156
|
+
*
|
|
157
|
+
* @param node the virtual DOM node to check
|
|
158
|
+
* @returns whether it's a Host node or not
|
|
159
|
+
*/
|
|
185
160
|
const isHost = (node) => node && node.$tag$ === Host;
|
|
161
|
+
/**
|
|
162
|
+
* Parse a new property value for a given property type.
|
|
163
|
+
*
|
|
164
|
+
* While the prop value can reasonably be expected to be of `any` type as far as TypeScript's type checker is concerned,
|
|
165
|
+
* it is not safe to assume that the string returned by evaluating `typeof propValue` matches:
|
|
166
|
+
* 1. `any`, the type given to `propValue` in the function signature
|
|
167
|
+
* 2. the type stored from `propType`.
|
|
168
|
+
*
|
|
169
|
+
* This function provides the capability to parse/coerce a property's value to potentially any other JavaScript type.
|
|
170
|
+
*
|
|
171
|
+
* Property values represented in TSX preserve their type information. In the example below, the number 0 is passed to
|
|
172
|
+
* a component. This `propValue` will preserve its type information (`typeof propValue === 'number'`). Note that is
|
|
173
|
+
* based on the type of the value being passed in, not the type declared of the class member decorated with `@Prop`.
|
|
174
|
+
* ```tsx
|
|
175
|
+
* <my-cmp prop-val={0}></my-cmp>
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* HTML prop values on the other hand, will always a string
|
|
179
|
+
*
|
|
180
|
+
* @param propValue the new value to coerce to some type
|
|
181
|
+
* @param propType the type of the prop, expressed as a binary number
|
|
182
|
+
* @returns the parsed/coerced value
|
|
183
|
+
*/
|
|
184
|
+
const parsePropertyValue = (propValue, propType) => {
|
|
185
|
+
// ensure this value is of the correct prop type
|
|
186
|
+
if (propValue != null && !isComplexType(propValue)) {
|
|
187
|
+
if (propType & 4 /* MEMBER_FLAGS.Boolean */) {
|
|
188
|
+
// per the HTML spec, any string value means it is a boolean true value
|
|
189
|
+
// but we'll cheat here and say that the string "false" is the boolean false
|
|
190
|
+
return propValue === 'false' ? false : propValue === '' || !!propValue;
|
|
191
|
+
}
|
|
192
|
+
if (propType & 2 /* MEMBER_FLAGS.Number */) {
|
|
193
|
+
// force it to be a number
|
|
194
|
+
return parseFloat(propValue);
|
|
195
|
+
}
|
|
196
|
+
if (propType & 1 /* MEMBER_FLAGS.String */) {
|
|
197
|
+
// could have been passed as a number or boolean
|
|
198
|
+
// but we still want it as a string
|
|
199
|
+
return String(propValue);
|
|
200
|
+
}
|
|
201
|
+
// redundant return here for better minification
|
|
202
|
+
return propValue;
|
|
203
|
+
}
|
|
204
|
+
// not sure exactly what type we want
|
|
205
|
+
// so no need to change to a different type
|
|
206
|
+
return propValue;
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* Helper function to create & dispatch a custom Event on a provided target
|
|
210
|
+
* @param elm the target of the Event
|
|
211
|
+
* @param name the name to give the custom Event
|
|
212
|
+
* @param opts options for configuring a custom Event
|
|
213
|
+
* @returns the custom Event
|
|
214
|
+
*/
|
|
215
|
+
const emitEvent = (elm, name, opts) => {
|
|
216
|
+
const ev = plt.ce(name, opts);
|
|
217
|
+
elm.dispatchEvent(ev);
|
|
218
|
+
return ev;
|
|
219
|
+
};
|
|
220
|
+
const rootAppliedStyles = /*@__PURE__*/ new WeakMap();
|
|
221
|
+
const registerStyle = (scopeId, cssText, allowCS) => {
|
|
222
|
+
let style = styles.get(scopeId);
|
|
223
|
+
if (supportsConstructableStylesheets && allowCS) {
|
|
224
|
+
style = (style || new CSSStyleSheet());
|
|
225
|
+
if (typeof style === 'string') {
|
|
226
|
+
style = cssText;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
style.replaceSync(cssText);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
style = cssText;
|
|
234
|
+
}
|
|
235
|
+
styles.set(scopeId, style);
|
|
236
|
+
};
|
|
237
|
+
const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
|
|
238
|
+
var _a;
|
|
239
|
+
let scopeId = getScopeId(cmpMeta);
|
|
240
|
+
const style = styles.get(scopeId);
|
|
241
|
+
// if an element is NOT connected then getRootNode() will return the wrong root node
|
|
242
|
+
// so the fallback is to always use the document for the root node in those cases
|
|
243
|
+
styleContainerNode = styleContainerNode.nodeType === 11 /* NODE_TYPE.DocumentFragment */ ? styleContainerNode : doc;
|
|
244
|
+
if (style) {
|
|
245
|
+
if (typeof style === 'string') {
|
|
246
|
+
styleContainerNode = styleContainerNode.head || styleContainerNode;
|
|
247
|
+
let appliedStyles = rootAppliedStyles.get(styleContainerNode);
|
|
248
|
+
let styleElm;
|
|
249
|
+
if (!appliedStyles) {
|
|
250
|
+
rootAppliedStyles.set(styleContainerNode, (appliedStyles = new Set()));
|
|
251
|
+
}
|
|
252
|
+
if (!appliedStyles.has(scopeId)) {
|
|
253
|
+
{
|
|
254
|
+
{
|
|
255
|
+
styleElm = doc.createElement('style');
|
|
256
|
+
styleElm.innerHTML = style;
|
|
257
|
+
}
|
|
258
|
+
// Apply CSP nonce to the style tag if it exists
|
|
259
|
+
const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
|
|
260
|
+
if (nonce != null) {
|
|
261
|
+
styleElm.setAttribute('nonce', nonce);
|
|
262
|
+
}
|
|
263
|
+
styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
|
|
264
|
+
}
|
|
265
|
+
if (appliedStyles) {
|
|
266
|
+
appliedStyles.add(scopeId);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else if (!styleContainerNode.adoptedStyleSheets.includes(style)) {
|
|
271
|
+
styleContainerNode.adoptedStyleSheets = [...styleContainerNode.adoptedStyleSheets, style];
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return scopeId;
|
|
275
|
+
};
|
|
276
|
+
const attachStyles = (hostRef) => {
|
|
277
|
+
const cmpMeta = hostRef.$cmpMeta$;
|
|
278
|
+
const elm = hostRef.$hostElement$;
|
|
279
|
+
const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
|
|
280
|
+
addStyle(elm.getRootNode(), cmpMeta);
|
|
281
|
+
endAttachStyles();
|
|
282
|
+
};
|
|
283
|
+
const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
|
|
186
284
|
/**
|
|
187
285
|
* Production setAccessor() function based on Preact by
|
|
188
286
|
* Jason Miller (@developit)
|
|
@@ -227,6 +325,14 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
227
325
|
}
|
|
228
326
|
}
|
|
229
327
|
}
|
|
328
|
+
else if (memberName === 'key')
|
|
329
|
+
;
|
|
330
|
+
else if (memberName === 'ref') {
|
|
331
|
+
// minifier will clean this up
|
|
332
|
+
if (newValue) {
|
|
333
|
+
newValue(elm);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
230
336
|
else if ((!isProp ) &&
|
|
231
337
|
memberName[0] === 'o' &&
|
|
232
338
|
memberName[1] === 'n') {
|
|
@@ -272,11 +378,10 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
272
378
|
if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
|
|
273
379
|
try {
|
|
274
380
|
if (!elm.tagName.includes('-')) {
|
|
275
|
-
|
|
381
|
+
const n = newValue == null ? '' : newValue;
|
|
276
382
|
// Workaround for Safari, moving the <input> caret when re-assigning the same valued
|
|
277
383
|
if (memberName === 'list') {
|
|
278
384
|
isProp = false;
|
|
279
|
-
// tslint:disable-next-line: triple-equals
|
|
280
385
|
}
|
|
281
386
|
else if (oldValue == null || elm[memberName] != n) {
|
|
282
387
|
elm[memberName] = n;
|
|
@@ -288,16 +393,36 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
|
|
|
288
393
|
}
|
|
289
394
|
catch (e) { }
|
|
290
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* Need to manually update attribute if:
|
|
398
|
+
* - memberName is not an attribute
|
|
399
|
+
* - if we are rendering the host element in order to reflect attribute
|
|
400
|
+
* - if it's a SVG, since properties might not work in <svg>
|
|
401
|
+
* - if the newValue is null/undefined or 'false'.
|
|
402
|
+
*/
|
|
403
|
+
let xlink = false;
|
|
404
|
+
{
|
|
405
|
+
if (ln !== (ln = ln.replace(/^xlink\:?/, ''))) {
|
|
406
|
+
memberName = ln;
|
|
407
|
+
xlink = true;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
291
410
|
if (newValue == null || newValue === false) {
|
|
292
411
|
if (newValue !== false || elm.getAttribute(memberName) === '') {
|
|
293
|
-
{
|
|
412
|
+
if (xlink) {
|
|
413
|
+
elm.removeAttributeNS(XLINK_NS, memberName);
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
294
416
|
elm.removeAttribute(memberName);
|
|
295
417
|
}
|
|
296
418
|
}
|
|
297
419
|
}
|
|
298
|
-
else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex) {
|
|
420
|
+
else if ((!isProp || flags & 4 /* VNODE_FLAGS.isHost */ || isSvg) && !isComplex) {
|
|
299
421
|
newValue = newValue === true ? '' : newValue;
|
|
300
|
-
{
|
|
422
|
+
if (xlink) {
|
|
423
|
+
elm.setAttributeNS(XLINK_NS, memberName, newValue);
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
301
426
|
elm.setAttribute(memberName, newValue);
|
|
302
427
|
}
|
|
303
428
|
}
|
|
@@ -310,7 +435,7 @@ const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
|
|
|
310
435
|
// if the element passed in is a shadow root, which is a document fragment
|
|
311
436
|
// then we want to be adding attrs/props to the shadow root's "host" element
|
|
312
437
|
// if it's not a shadow root, then we add attrs/props to the same element
|
|
313
|
-
const elm = newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host
|
|
438
|
+
const elm = newVnode.$elm$.nodeType === 11 /* NODE_TYPE.DocumentFragment */ && newVnode.$elm$.host
|
|
314
439
|
? newVnode.$elm$.host
|
|
315
440
|
: newVnode.$elm$;
|
|
316
441
|
const oldVnodeAttrs = (oldVnode && oldVnode.$attrs$) || EMPTY_OBJ;
|
|
@@ -328,9 +453,19 @@ const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
|
|
|
328
453
|
setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode, newVnode.$flags$);
|
|
329
454
|
}
|
|
330
455
|
};
|
|
456
|
+
/**
|
|
457
|
+
* Create a DOM Node corresponding to one of the children of a given VNode.
|
|
458
|
+
*
|
|
459
|
+
* @param oldParentVNode the parent VNode from the previous render
|
|
460
|
+
* @param newParentVNode the parent VNode from the current render
|
|
461
|
+
* @param childIndex the index of the VNode, in the _new_ parent node's
|
|
462
|
+
* children, for which we will create a new DOM node
|
|
463
|
+
* @param parentElm the parent DOM node which our new node will be a child of
|
|
464
|
+
* @returns the newly created node
|
|
465
|
+
*/
|
|
331
466
|
const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
|
|
332
467
|
// tslint:disable-next-line: prefer-const
|
|
333
|
-
|
|
468
|
+
const newVNode = newParentVNode.$children$[childIndex];
|
|
334
469
|
let i = 0;
|
|
335
470
|
let elm;
|
|
336
471
|
let childNode;
|
|
@@ -376,6 +511,21 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
|
|
|
376
511
|
}
|
|
377
512
|
return elm;
|
|
378
513
|
};
|
|
514
|
+
/**
|
|
515
|
+
* Create DOM nodes corresponding to a list of {@link d.Vnode} objects and
|
|
516
|
+
* add them to the DOM in the appropriate place.
|
|
517
|
+
*
|
|
518
|
+
* @param parentElm the DOM node which should be used as a parent for the new
|
|
519
|
+
* DOM nodes
|
|
520
|
+
* @param before a child of the `parentElm` which the new children should be
|
|
521
|
+
* inserted before (optional)
|
|
522
|
+
* @param parentVNode the parent virtual DOM node
|
|
523
|
+
* @param vnodes the new child virtual DOM nodes to produce DOM nodes for
|
|
524
|
+
* @param startIdx the index in the child virtual DOM nodes at which to start
|
|
525
|
+
* creating DOM nodes (inclusive)
|
|
526
|
+
* @param endIdx the index in the child virtual DOM nodes at which to stop
|
|
527
|
+
* creating DOM nodes (inclusive)
|
|
528
|
+
*/
|
|
379
529
|
const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
|
|
380
530
|
let containerElm = (parentElm);
|
|
381
531
|
let childNode;
|
|
@@ -389,18 +539,102 @@ const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) =>
|
|
|
389
539
|
}
|
|
390
540
|
}
|
|
391
541
|
};
|
|
542
|
+
/**
|
|
543
|
+
* Remove the DOM elements corresponding to a list of {@link d.VNode} objects.
|
|
544
|
+
* This can be used to, for instance, clean up after a list of children which
|
|
545
|
+
* should no longer be shown.
|
|
546
|
+
*
|
|
547
|
+
* This function also handles some of Stencil's slot relocation logic.
|
|
548
|
+
*
|
|
549
|
+
* @param vnodes a list of virtual DOM nodes to remove
|
|
550
|
+
* @param startIdx the index at which to start removing nodes (inclusive)
|
|
551
|
+
* @param endIdx the index at which to stop removing nodes (inclusive)
|
|
552
|
+
* @param vnode a VNode
|
|
553
|
+
* @param elm an element
|
|
554
|
+
*/
|
|
392
555
|
const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
|
|
393
556
|
for (; startIdx <= endIdx; ++startIdx) {
|
|
394
557
|
if ((vnode = vnodes[startIdx])) {
|
|
395
558
|
elm = vnode.$elm$;
|
|
559
|
+
callNodeRefs(vnode);
|
|
396
560
|
// remove the vnode's element from the dom
|
|
397
561
|
elm.remove();
|
|
398
562
|
}
|
|
399
563
|
}
|
|
400
564
|
};
|
|
565
|
+
/**
|
|
566
|
+
* Reconcile the children of a new VNode with the children of an old VNode by
|
|
567
|
+
* traversing the two collections of children, identifying nodes that are
|
|
568
|
+
* conserved or changed, calling out to `patch` to make any necessary
|
|
569
|
+
* updates to the DOM, and rearranging DOM nodes as needed.
|
|
570
|
+
*
|
|
571
|
+
* The algorithm for reconciling children works by analyzing two 'windows' onto
|
|
572
|
+
* the two arrays of children (`oldCh` and `newCh`). We keep track of the
|
|
573
|
+
* 'windows' by storing start and end indices and references to the
|
|
574
|
+
* corresponding array entries. Initially the two 'windows' are basically equal
|
|
575
|
+
* to the entire array, but we progressively narrow the windows until there are
|
|
576
|
+
* no children left to update by doing the following:
|
|
577
|
+
*
|
|
578
|
+
* 1. Skip any `null` entries at the beginning or end of the two arrays, so
|
|
579
|
+
* that if we have an initial array like the following we'll end up dealing
|
|
580
|
+
* only with a window bounded by the highlighted elements:
|
|
581
|
+
*
|
|
582
|
+
* [null, null, VNode1 , ... , VNode2, null, null]
|
|
583
|
+
* ^^^^^^ ^^^^^^
|
|
584
|
+
*
|
|
585
|
+
* 2. Check to see if the elements at the head and tail positions are equal
|
|
586
|
+
* across the windows. This will basically detect elements which haven't
|
|
587
|
+
* been added, removed, or changed position, i.e. if you had the following
|
|
588
|
+
* VNode elements (represented as HTML):
|
|
589
|
+
*
|
|
590
|
+
* oldVNode: `<div><p><span>HEY</span></p></div>`
|
|
591
|
+
* newVNode: `<div><p><span>THERE</span></p></div>`
|
|
592
|
+
*
|
|
593
|
+
* Then when comparing the children of the `<div>` tag we check the equality
|
|
594
|
+
* of the VNodes corresponding to the `<p>` tags and, since they are the
|
|
595
|
+
* same tag in the same position, we'd be able to avoid completely
|
|
596
|
+
* re-rendering the subtree under them with a new DOM element and would just
|
|
597
|
+
* call out to `patch` to handle reconciling their children and so on.
|
|
598
|
+
*
|
|
599
|
+
* 3. Check, for both windows, to see if the element at the beginning of the
|
|
600
|
+
* window corresponds to the element at the end of the other window. This is
|
|
601
|
+
* a heuristic which will let us identify _some_ situations in which
|
|
602
|
+
* elements have changed position, for instance it _should_ detect that the
|
|
603
|
+
* children nodes themselves have not changed but merely moved in the
|
|
604
|
+
* following example:
|
|
605
|
+
*
|
|
606
|
+
* oldVNode: `<div><element-one /><element-two /></div>`
|
|
607
|
+
* newVNode: `<div><element-two /><element-one /></div>`
|
|
608
|
+
*
|
|
609
|
+
* If we find cases like this then we also need to move the concrete DOM
|
|
610
|
+
* elements corresponding to the moved children to write the re-order to the
|
|
611
|
+
* DOM.
|
|
612
|
+
*
|
|
613
|
+
* 4. Finally, if VNodes have the `key` attribute set on them we check for any
|
|
614
|
+
* nodes in the old children which have the same key as the first element in
|
|
615
|
+
* our window on the new children. If we find such a node we handle calling
|
|
616
|
+
* out to `patch`, moving relevant DOM nodes, and so on, in accordance with
|
|
617
|
+
* what we find.
|
|
618
|
+
*
|
|
619
|
+
* Finally, once we've narrowed our 'windows' to the point that either of them
|
|
620
|
+
* collapse (i.e. they have length 0) we then handle any remaining VNode
|
|
621
|
+
* insertion or deletion that needs to happen to get a DOM state that correctly
|
|
622
|
+
* reflects the new child VNodes. If, for instance, after our window on the old
|
|
623
|
+
* children has collapsed we still have more nodes on the new children that
|
|
624
|
+
* we haven't dealt with yet then we need to add them, or if the new children
|
|
625
|
+
* collapse but we still have unhandled _old_ children then we need to make
|
|
626
|
+
* sure the corresponding DOM nodes are removed.
|
|
627
|
+
*
|
|
628
|
+
* @param parentElm the node into which the parent VNode is rendered
|
|
629
|
+
* @param oldCh the old children of the parent node
|
|
630
|
+
* @param newVNode the new VNode which will replace the parent
|
|
631
|
+
* @param newCh the new children of the parent node
|
|
632
|
+
*/
|
|
401
633
|
const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
402
634
|
let oldStartIdx = 0;
|
|
403
635
|
let newStartIdx = 0;
|
|
636
|
+
let idxInOld = 0;
|
|
637
|
+
let i = 0;
|
|
404
638
|
let oldEndIdx = oldCh.length - 1;
|
|
405
639
|
let oldStartVnode = oldCh[0];
|
|
406
640
|
let oldEndVnode = oldCh[oldEndIdx];
|
|
@@ -408,9 +642,10 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
408
642
|
let newStartVnode = newCh[0];
|
|
409
643
|
let newEndVnode = newCh[newEndIdx];
|
|
410
644
|
let node;
|
|
645
|
+
let elmToMove;
|
|
411
646
|
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
|
|
412
647
|
if (oldStartVnode == null) {
|
|
413
|
-
//
|
|
648
|
+
// VNode might have been moved left
|
|
414
649
|
oldStartVnode = oldCh[++oldStartIdx];
|
|
415
650
|
}
|
|
416
651
|
else if (oldEndVnode == null) {
|
|
@@ -423,34 +658,101 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
423
658
|
newEndVnode = newCh[--newEndIdx];
|
|
424
659
|
}
|
|
425
660
|
else if (isSameVnode(oldStartVnode, newStartVnode)) {
|
|
661
|
+
// if the start nodes are the same then we should patch the new VNode
|
|
662
|
+
// onto the old one, and increment our `newStartIdx` and `oldStartIdx`
|
|
663
|
+
// indices to reflect that. We don't need to move any DOM Nodes around
|
|
664
|
+
// since things are matched up in order.
|
|
426
665
|
patch(oldStartVnode, newStartVnode);
|
|
427
666
|
oldStartVnode = oldCh[++oldStartIdx];
|
|
428
667
|
newStartVnode = newCh[++newStartIdx];
|
|
429
668
|
}
|
|
430
669
|
else if (isSameVnode(oldEndVnode, newEndVnode)) {
|
|
670
|
+
// likewise, if the end nodes are the same we patch new onto old and
|
|
671
|
+
// decrement our end indices, and also likewise in this case we don't
|
|
672
|
+
// need to move any DOM Nodes.
|
|
431
673
|
patch(oldEndVnode, newEndVnode);
|
|
432
674
|
oldEndVnode = oldCh[--oldEndIdx];
|
|
433
675
|
newEndVnode = newCh[--newEndIdx];
|
|
434
676
|
}
|
|
435
677
|
else if (isSameVnode(oldStartVnode, newEndVnode)) {
|
|
436
678
|
patch(oldStartVnode, newEndVnode);
|
|
679
|
+
// We need to move the element for `oldStartVnode` into a position which
|
|
680
|
+
// will be appropriate for `newEndVnode`. For this we can use
|
|
681
|
+
// `.insertBefore` and `oldEndVnode.$elm$.nextSibling`. If there is a
|
|
682
|
+
// sibling for `oldEndVnode.$elm$` then we want to move the DOM node for
|
|
683
|
+
// `oldStartVnode` between `oldEndVnode` and it's sibling, like so:
|
|
684
|
+
//
|
|
685
|
+
// <old-start-node />
|
|
686
|
+
// <some-intervening-node />
|
|
687
|
+
// <old-end-node />
|
|
688
|
+
// <!-- -> <-- `oldStartVnode.$elm$` should be inserted here
|
|
689
|
+
// <next-sibling />
|
|
690
|
+
//
|
|
691
|
+
// If instead `oldEndVnode.$elm$` has no sibling then we just want to put
|
|
692
|
+
// the node for `oldStartVnode` at the end of the children of
|
|
693
|
+
// `parentElm`. Luckily, `Node.nextSibling` will return `null` if there
|
|
694
|
+
// aren't any siblings, and passing `null` to `Node.insertBefore` will
|
|
695
|
+
// append it to the children of the parent element.
|
|
437
696
|
parentElm.insertBefore(oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
|
|
438
697
|
oldStartVnode = oldCh[++oldStartIdx];
|
|
439
698
|
newEndVnode = newCh[--newEndIdx];
|
|
440
699
|
}
|
|
441
700
|
else if (isSameVnode(oldEndVnode, newStartVnode)) {
|
|
442
701
|
patch(oldEndVnode, newStartVnode);
|
|
702
|
+
// We've already checked above if `oldStartVnode` and `newStartVnode` are
|
|
703
|
+
// the same node, so since we're here we know that they are not. Thus we
|
|
704
|
+
// can move the element for `oldEndVnode` _before_ the element for
|
|
705
|
+
// `oldStartVnode`, leaving `oldStartVnode` to be reconciled in the
|
|
706
|
+
// future.
|
|
443
707
|
parentElm.insertBefore(oldEndVnode.$elm$, oldStartVnode.$elm$);
|
|
444
708
|
oldEndVnode = oldCh[--oldEndIdx];
|
|
445
709
|
newStartVnode = newCh[++newStartIdx];
|
|
446
710
|
}
|
|
447
711
|
else {
|
|
712
|
+
// Here we do some checks to match up old and new nodes based on the
|
|
713
|
+
// `$key$` attribute, which is set by putting a `key="my-key"` attribute
|
|
714
|
+
// in the JSX for a DOM element in the implementation of a Stencil
|
|
715
|
+
// component.
|
|
716
|
+
//
|
|
717
|
+
// First we check to see if there are any nodes in the array of old
|
|
718
|
+
// children which have the same key as the first node in the new
|
|
719
|
+
// children.
|
|
720
|
+
idxInOld = -1;
|
|
448
721
|
{
|
|
449
|
-
|
|
722
|
+
for (i = oldStartIdx; i <= oldEndIdx; ++i) {
|
|
723
|
+
if (oldCh[i] && oldCh[i].$key$ !== null && oldCh[i].$key$ === newStartVnode.$key$) {
|
|
724
|
+
idxInOld = i;
|
|
725
|
+
break;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
if (idxInOld >= 0) {
|
|
730
|
+
// We found a node in the old children which matches up with the first
|
|
731
|
+
// node in the new children! So let's deal with that
|
|
732
|
+
elmToMove = oldCh[idxInOld];
|
|
733
|
+
if (elmToMove.$tag$ !== newStartVnode.$tag$) {
|
|
734
|
+
// the tag doesn't match so we'll need a new DOM element
|
|
735
|
+
node = createElm(oldCh && oldCh[newStartIdx], newVNode, idxInOld);
|
|
736
|
+
}
|
|
737
|
+
else {
|
|
738
|
+
patch(elmToMove, newStartVnode);
|
|
739
|
+
// invalidate the matching old node so that we won't try to update it
|
|
740
|
+
// again later on
|
|
741
|
+
oldCh[idxInOld] = undefined;
|
|
742
|
+
node = elmToMove.$elm$;
|
|
743
|
+
}
|
|
744
|
+
newStartVnode = newCh[++newStartIdx];
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
// We either didn't find an element in the old children that matches
|
|
748
|
+
// the key of the first new child OR the build is not using `key`
|
|
749
|
+
// attributes at all. In either case we need to create a new element
|
|
750
|
+
// for the new node.
|
|
450
751
|
node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx);
|
|
451
752
|
newStartVnode = newCh[++newStartIdx];
|
|
452
753
|
}
|
|
453
754
|
if (node) {
|
|
755
|
+
// if we created a new node then handle inserting it to the DOM
|
|
454
756
|
{
|
|
455
757
|
oldStartVnode.$elm$.parentNode.insertBefore(node, oldStartVnode.$elm$);
|
|
456
758
|
}
|
|
@@ -458,20 +760,53 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
|
|
|
458
760
|
}
|
|
459
761
|
}
|
|
460
762
|
if (oldStartIdx > oldEndIdx) {
|
|
763
|
+
// we have some more new nodes to add which don't match up with old nodes
|
|
461
764
|
addVnodes(parentElm, newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$, newVNode, newCh, newStartIdx, newEndIdx);
|
|
462
765
|
}
|
|
463
766
|
else if (newStartIdx > newEndIdx) {
|
|
767
|
+
// there are nodes in the `oldCh` array which no longer correspond to nodes
|
|
768
|
+
// in the new array, so lets remove them (which entails cleaning up the
|
|
769
|
+
// relevant DOM nodes)
|
|
464
770
|
removeVnodes(oldCh, oldStartIdx, oldEndIdx);
|
|
465
771
|
}
|
|
466
772
|
};
|
|
467
|
-
|
|
773
|
+
/**
|
|
774
|
+
* Compare two VNodes to determine if they are the same
|
|
775
|
+
*
|
|
776
|
+
* **NB**: This function is an equality _heuristic_ based on the available
|
|
777
|
+
* information set on the two VNodes and can be misleading under certain
|
|
778
|
+
* circumstances. In particular, if the two nodes do not have `key` attrs
|
|
779
|
+
* (available under `$key$` on VNodes) then the function falls back on merely
|
|
780
|
+
* checking that they have the same tag.
|
|
781
|
+
*
|
|
782
|
+
* So, in other words, if `key` attrs are not set on VNodes which may be
|
|
783
|
+
* changing order within a `children` array or something along those lines then
|
|
784
|
+
* we could obtain a false negative and then have to do needless re-rendering
|
|
785
|
+
* (i.e. we'd say two VNodes aren't equal when in fact they should be).
|
|
786
|
+
*
|
|
787
|
+
* @param leftVNode the first VNode to check
|
|
788
|
+
* @param rightVNode the second VNode to check
|
|
789
|
+
* @returns whether they're equal or not
|
|
790
|
+
*/
|
|
791
|
+
const isSameVnode = (leftVNode, rightVNode) => {
|
|
468
792
|
// compare if two vnode to see if they're "technically" the same
|
|
469
793
|
// need to have the same element tag, and same key to be the same
|
|
470
|
-
if (
|
|
471
|
-
|
|
794
|
+
if (leftVNode.$tag$ === rightVNode.$tag$) {
|
|
795
|
+
// this will be set if components in the build have `key` attrs set on them
|
|
796
|
+
{
|
|
797
|
+
return leftVNode.$key$ === rightVNode.$key$;
|
|
798
|
+
}
|
|
472
799
|
}
|
|
473
800
|
return false;
|
|
474
801
|
};
|
|
802
|
+
/**
|
|
803
|
+
* Handle reconciling an outdated VNode with a new one which corresponds to
|
|
804
|
+
* it. This function handles flushing updates to the DOM and reconciling the
|
|
805
|
+
* children of the two nodes (if any).
|
|
806
|
+
*
|
|
807
|
+
* @param oldVNode an old VNode whose DOM element and children we want to update
|
|
808
|
+
* @param newVNode a new VNode representing an updated version of the old one
|
|
809
|
+
*/
|
|
475
810
|
const patch = (oldVNode, newVNode) => {
|
|
476
811
|
const elm = (newVNode.$elm$ = oldVNode.$elm$);
|
|
477
812
|
const oldChildren = oldVNode.$children$;
|
|
@@ -484,7 +819,6 @@ const patch = (oldVNode, newVNode) => {
|
|
|
484
819
|
// only add this to the when the compiler sees we're using an svg somewhere
|
|
485
820
|
isSvgMode = tag === 'svg' ? true : tag === 'foreignObject' ? false : isSvgMode;
|
|
486
821
|
}
|
|
487
|
-
// element node
|
|
488
822
|
{
|
|
489
823
|
{
|
|
490
824
|
// either this is the first render of an element OR it's an update
|
|
@@ -495,6 +829,7 @@ const patch = (oldVNode, newVNode) => {
|
|
|
495
829
|
}
|
|
496
830
|
if (oldChildren !== null && newChildren !== null) {
|
|
497
831
|
// looks like there's child vnodes for both the old and new vnodes
|
|
832
|
+
// so we need to call `updateChildren` to reconcile them
|
|
498
833
|
updateChildren(elm, oldChildren, newVNode, newChildren);
|
|
499
834
|
}
|
|
500
835
|
else if (newChildren !== null) {
|
|
@@ -520,29 +855,35 @@ const patch = (oldVNode, newVNode) => {
|
|
|
520
855
|
elm.data = text;
|
|
521
856
|
}
|
|
522
857
|
};
|
|
858
|
+
const callNodeRefs = (vNode) => {
|
|
859
|
+
{
|
|
860
|
+
vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(null);
|
|
861
|
+
vNode.$children$ && vNode.$children$.map(callNodeRefs);
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
/**
|
|
865
|
+
* The main entry point for Stencil's virtual DOM-based rendering engine
|
|
866
|
+
*
|
|
867
|
+
* Given a {@link d.HostRef} container and some virtual DOM nodes, this
|
|
868
|
+
* function will handle creating a virtual DOM tree with a single root, patching
|
|
869
|
+
* the current virtual DOM tree onto an old one (if any), dealing with slot
|
|
870
|
+
* relocation, and reflecting attributes.
|
|
871
|
+
*
|
|
872
|
+
* @param hostRef data needed to root and render the virtual DOM tree, such as
|
|
873
|
+
* the DOM node into which it should be rendered.
|
|
874
|
+
* @param renderFnResults the virtual DOM nodes to be rendered
|
|
875
|
+
*/
|
|
523
876
|
const renderVdom = (hostRef, renderFnResults) => {
|
|
524
877
|
const hostElm = hostRef.$hostElement$;
|
|
525
878
|
const oldVNode = hostRef.$vnode$ || newVNode(null, null);
|
|
526
879
|
const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
|
|
527
880
|
rootVnode.$tag$ = null;
|
|
528
|
-
rootVnode.$flags$ |= 4 /* isHost */;
|
|
881
|
+
rootVnode.$flags$ |= 4 /* VNODE_FLAGS.isHost */;
|
|
529
882
|
hostRef.$vnode$ = rootVnode;
|
|
530
883
|
rootVnode.$elm$ = oldVNode.$elm$ = (hostElm);
|
|
531
884
|
// synchronous patch
|
|
532
885
|
patch(oldVNode, rootVnode);
|
|
533
886
|
};
|
|
534
|
-
/**
|
|
535
|
-
* Helper function to create & dispatch a custom Event on a provided target
|
|
536
|
-
* @param elm the target of the Event
|
|
537
|
-
* @param name the name to give the custom Event
|
|
538
|
-
* @param opts options for configuring a custom Event
|
|
539
|
-
* @returns the custom Event
|
|
540
|
-
*/
|
|
541
|
-
const emitEvent = (elm, name, opts) => {
|
|
542
|
-
const ev = plt.ce(name, opts);
|
|
543
|
-
elm.dispatchEvent(ev);
|
|
544
|
-
return ev;
|
|
545
|
-
};
|
|
546
887
|
const attachToAncestor = (hostRef, ancestorComponent) => {
|
|
547
888
|
if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
|
|
548
889
|
ancestorComponent['s-p'].push(new Promise((r) => (hostRef.$onRenderResolve$ = r)));
|
|
@@ -550,10 +891,10 @@ const attachToAncestor = (hostRef, ancestorComponent) => {
|
|
|
550
891
|
};
|
|
551
892
|
const scheduleUpdate = (hostRef, isInitialLoad) => {
|
|
552
893
|
{
|
|
553
|
-
hostRef.$flags$ |= 16 /* isQueuedForUpdate */;
|
|
894
|
+
hostRef.$flags$ |= 16 /* HOST_FLAGS.isQueuedForUpdate */;
|
|
554
895
|
}
|
|
555
|
-
if (hostRef.$flags$ & 4 /* isWaitingForChildren */) {
|
|
556
|
-
hostRef.$flags$ |= 512 /* needsRerender */;
|
|
896
|
+
if (hostRef.$flags$ & 4 /* HOST_FLAGS.isWaitingForChildren */) {
|
|
897
|
+
hostRef.$flags$ |= 512 /* HOST_FLAGS.needsRerender */;
|
|
557
898
|
return;
|
|
558
899
|
}
|
|
559
900
|
attachToAncestor(hostRef, hostRef.$ancestorComponent$);
|
|
@@ -572,6 +913,11 @@ const dispatchHooks = (hostRef, isInitialLoad) => {
|
|
|
572
913
|
promise = safeCall(instance, 'componentWillLoad');
|
|
573
914
|
}
|
|
574
915
|
}
|
|
916
|
+
else {
|
|
917
|
+
{
|
|
918
|
+
promise = safeCall(instance, 'componentWillUpdate');
|
|
919
|
+
}
|
|
920
|
+
}
|
|
575
921
|
endSchedule();
|
|
576
922
|
return then(promise, () => updateComponent(hostRef, instance, isInitialLoad));
|
|
577
923
|
};
|
|
@@ -605,7 +951,7 @@ const updateComponent = async (hostRef, instance, isInitialLoad) => {
|
|
|
605
951
|
}
|
|
606
952
|
else {
|
|
607
953
|
Promise.all(childrenPromises).then(postUpdate);
|
|
608
|
-
hostRef.$flags$ |= 4 /* isWaitingForChildren */;
|
|
954
|
+
hostRef.$flags$ |= 4 /* HOST_FLAGS.isWaitingForChildren */;
|
|
609
955
|
childrenPromises.length = 0;
|
|
610
956
|
}
|
|
611
957
|
}
|
|
@@ -614,10 +960,10 @@ const callRender = (hostRef, instance, elm) => {
|
|
|
614
960
|
try {
|
|
615
961
|
instance = instance.render() ;
|
|
616
962
|
{
|
|
617
|
-
hostRef.$flags$ &= ~16 /* isQueuedForUpdate */;
|
|
963
|
+
hostRef.$flags$ &= ~16 /* HOST_FLAGS.isQueuedForUpdate */;
|
|
618
964
|
}
|
|
619
965
|
{
|
|
620
|
-
hostRef.$flags$ |= 2 /* hasRendered */;
|
|
966
|
+
hostRef.$flags$ |= 2 /* HOST_FLAGS.hasRendered */;
|
|
621
967
|
}
|
|
622
968
|
{
|
|
623
969
|
{
|
|
@@ -644,8 +990,8 @@ const postUpdateComponent = (hostRef) => {
|
|
|
644
990
|
{
|
|
645
991
|
safeCall(instance, 'componentDidRender');
|
|
646
992
|
}
|
|
647
|
-
if (!(hostRef.$flags$ & 64 /* hasLoadedComponent */)) {
|
|
648
|
-
hostRef.$flags$ |= 64 /* hasLoadedComponent */;
|
|
993
|
+
if (!(hostRef.$flags$ & 64 /* HOST_FLAGS.hasLoadedComponent */)) {
|
|
994
|
+
hostRef.$flags$ |= 64 /* HOST_FLAGS.hasLoadedComponent */;
|
|
649
995
|
{
|
|
650
996
|
// DOM WRITE!
|
|
651
997
|
addHydratedFlag(elm);
|
|
@@ -674,10 +1020,10 @@ const postUpdateComponent = (hostRef) => {
|
|
|
674
1020
|
hostRef.$onRenderResolve$();
|
|
675
1021
|
hostRef.$onRenderResolve$ = undefined;
|
|
676
1022
|
}
|
|
677
|
-
if (hostRef.$flags$ & 512 /* needsRerender */) {
|
|
1023
|
+
if (hostRef.$flags$ & 512 /* HOST_FLAGS.needsRerender */) {
|
|
678
1024
|
nextTick(() => scheduleUpdate(hostRef, false));
|
|
679
1025
|
}
|
|
680
|
-
hostRef.$flags$ &= ~(4 /* isWaitingForChildren */ | 512 /* needsRerender */);
|
|
1026
|
+
hostRef.$flags$ &= ~(4 /* HOST_FLAGS.isWaitingForChildren */ | 512 /* HOST_FLAGS.needsRerender */);
|
|
681
1027
|
}
|
|
682
1028
|
// ( •_•)
|
|
683
1029
|
// ( •_•)>⌐■-■
|
|
@@ -707,25 +1053,6 @@ const then = (promise, thenFn) => {
|
|
|
707
1053
|
};
|
|
708
1054
|
const addHydratedFlag = (elm) => elm.classList.add('hydrated')
|
|
709
1055
|
;
|
|
710
|
-
const parsePropertyValue = (propValue, propType) => {
|
|
711
|
-
// ensure this value is of the correct prop type
|
|
712
|
-
if (propValue != null && !isComplexType(propValue)) {
|
|
713
|
-
if (propType & 2 /* Number */) {
|
|
714
|
-
// force it to be a number
|
|
715
|
-
return parseFloat(propValue);
|
|
716
|
-
}
|
|
717
|
-
if (propType & 1 /* String */) {
|
|
718
|
-
// could have been passed as a number or boolean
|
|
719
|
-
// but we still want it as a string
|
|
720
|
-
return String(propValue);
|
|
721
|
-
}
|
|
722
|
-
// redundant return here for better minification
|
|
723
|
-
return propValue;
|
|
724
|
-
}
|
|
725
|
-
// not sure exactly what type we want
|
|
726
|
-
// so no need to change to a different type
|
|
727
|
-
return propValue;
|
|
728
|
-
};
|
|
729
1056
|
const getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
|
|
730
1057
|
const setValue = (ref, propName, newVal, cmpMeta) => {
|
|
731
1058
|
// check our new property value against our internal value
|
|
@@ -734,12 +1061,15 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
|
|
|
734
1061
|
const flags = hostRef.$flags$;
|
|
735
1062
|
const instance = hostRef.$lazyInstance$ ;
|
|
736
1063
|
newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
|
|
737
|
-
|
|
1064
|
+
// explicitly check for NaN on both sides, as `NaN === NaN` is always false
|
|
1065
|
+
const areBothNaN = Number.isNaN(oldVal) && Number.isNaN(newVal);
|
|
1066
|
+
const didValueChange = newVal !== oldVal && !areBothNaN;
|
|
1067
|
+
if ((!(flags & 8 /* HOST_FLAGS.isConstructingInstance */) || oldVal === undefined) && didValueChange) {
|
|
738
1068
|
// gadzooks! the property's value has changed!!
|
|
739
1069
|
// set our new value!
|
|
740
1070
|
hostRef.$instanceValues$.set(propName, newVal);
|
|
741
1071
|
if (instance) {
|
|
742
|
-
if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
|
|
1072
|
+
if ((flags & (2 /* HOST_FLAGS.hasRendered */ | 16 /* HOST_FLAGS.isQueuedForUpdate */)) === 2 /* HOST_FLAGS.hasRendered */) {
|
|
743
1073
|
// looks like this value actually changed, so we've got work to do!
|
|
744
1074
|
// but only if we've already rendered, otherwise just chill out
|
|
745
1075
|
// queue that we need to do an update, but don't worry about queuing
|
|
@@ -749,14 +1079,24 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
|
|
|
749
1079
|
}
|
|
750
1080
|
}
|
|
751
1081
|
};
|
|
1082
|
+
/**
|
|
1083
|
+
* Attach a series of runtime constructs to a compiled Stencil component
|
|
1084
|
+
* constructor, including getters and setters for the `@Prop` and `@State`
|
|
1085
|
+
* decorators, callbacks for when attributes change, and so on.
|
|
1086
|
+
*
|
|
1087
|
+
* @param Cstr the constructor for a component that we need to process
|
|
1088
|
+
* @param cmpMeta metadata collected previously about the component
|
|
1089
|
+
* @param flags a number used to store a series of bit flags
|
|
1090
|
+
* @returns a reference to the same constructor passed in (but now mutated)
|
|
1091
|
+
*/
|
|
752
1092
|
const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
753
1093
|
if (cmpMeta.$members$) {
|
|
754
1094
|
// It's better to have a const than two Object.entries()
|
|
755
1095
|
const members = Object.entries(cmpMeta.$members$);
|
|
756
1096
|
const prototype = Cstr.prototype;
|
|
757
1097
|
members.map(([memberName, [memberFlags]]) => {
|
|
758
|
-
if ((memberFlags & 31 /* Prop */ ||
|
|
759
|
-
((flags & 2 /* proxyState */) && memberFlags & 32 /* State */))) {
|
|
1098
|
+
if ((memberFlags & 31 /* MEMBER_FLAGS.Prop */ ||
|
|
1099
|
+
((flags & 2 /* PROXY_FLAGS.proxyState */) && memberFlags & 32 /* MEMBER_FLAGS.State */))) {
|
|
760
1100
|
// proxyComponent - prop
|
|
761
1101
|
Object.defineProperty(prototype, memberName, {
|
|
762
1102
|
get() {
|
|
@@ -771,8 +1111,8 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
771
1111
|
enumerable: true,
|
|
772
1112
|
});
|
|
773
1113
|
}
|
|
774
|
-
else if (flags & 1 /* isElementConstructor */ &&
|
|
775
|
-
memberFlags & 64 /* Method */) {
|
|
1114
|
+
else if (flags & 1 /* PROXY_FLAGS.isElementConstructor */ &&
|
|
1115
|
+
memberFlags & 64 /* MEMBER_FLAGS.Method */) {
|
|
776
1116
|
// proxyComponent - method
|
|
777
1117
|
Object.defineProperty(prototype, memberName, {
|
|
778
1118
|
value(...args) {
|
|
@@ -782,19 +1122,19 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
782
1122
|
});
|
|
783
1123
|
}
|
|
784
1124
|
});
|
|
785
|
-
if ((flags & 1 /* isElementConstructor */)) {
|
|
1125
|
+
if ((flags & 1 /* PROXY_FLAGS.isElementConstructor */)) {
|
|
786
1126
|
const attrNameToPropName = new Map();
|
|
787
1127
|
prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
|
|
788
1128
|
plt.jmp(() => {
|
|
789
1129
|
const propName = attrNameToPropName.get(attrName);
|
|
790
|
-
// In a
|
|
1130
|
+
// In a web component lifecycle the attributeChangedCallback runs prior to connectedCallback
|
|
791
1131
|
// in the case where an attribute was set inline.
|
|
792
1132
|
// ```html
|
|
793
1133
|
// <my-component some-attribute="some-value"></my-component>
|
|
794
1134
|
// ```
|
|
795
1135
|
//
|
|
796
|
-
// There is an edge case where a developer sets the attribute inline on a custom element and then
|
|
797
|
-
// changes it before it has been upgraded as shown below:
|
|
1136
|
+
// There is an edge case where a developer sets the attribute inline on a custom element and then
|
|
1137
|
+
// programmatically changes it before it has been upgraded as shown below:
|
|
798
1138
|
//
|
|
799
1139
|
// ```html
|
|
800
1140
|
// <!-- this component has _not_ been upgraded yet -->
|
|
@@ -804,13 +1144,13 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
804
1144
|
// el = document.querySelector("#test");
|
|
805
1145
|
// el.someAttribute = "another-value";
|
|
806
1146
|
// // upgrade component
|
|
807
|
-
//
|
|
1147
|
+
// customElements.define('my-component', MyComponent);
|
|
808
1148
|
// </script>
|
|
809
1149
|
// ```
|
|
810
1150
|
// In this case if we do not unshadow here and use the value of the shadowing property, attributeChangedCallback
|
|
811
1151
|
// will be called with `newValue = "some-value"` and will set the shadowed property (this.someAttribute = "another-value")
|
|
812
1152
|
// to the value that was set inline i.e. "some-value" from above example. When
|
|
813
|
-
// the connectedCallback attempts to unshadow it will use "some-value" as the
|
|
1153
|
+
// the connectedCallback attempts to unshadow it will use "some-value" as the initial value rather than "another-value"
|
|
814
1154
|
//
|
|
815
1155
|
// The case where the attribute was NOT set inline but was not set programmatically shall be handled/unshadowed
|
|
816
1156
|
// by connectedCallback as this attributeChangedCallback will not fire.
|
|
@@ -824,13 +1164,21 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
824
1164
|
newValue = this[propName];
|
|
825
1165
|
delete this[propName];
|
|
826
1166
|
}
|
|
1167
|
+
else if (prototype.hasOwnProperty(propName) &&
|
|
1168
|
+
typeof this[propName] === 'number' &&
|
|
1169
|
+
this[propName] == newValue) {
|
|
1170
|
+
// if the propName exists on the prototype of `Cstr`, this update may be a result of Stencil using native
|
|
1171
|
+
// APIs to reflect props as attributes. Calls to `setAttribute(someElement, propName)` will result in
|
|
1172
|
+
// `propName` to be converted to a `DOMString`, which may not be what we want for other primitive props.
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
827
1175
|
this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
|
|
828
1176
|
});
|
|
829
1177
|
};
|
|
830
1178
|
// create an array of attributes to observe
|
|
831
1179
|
// and also create a map of html attribute name to js property name
|
|
832
1180
|
Cstr.observedAttributes = members
|
|
833
|
-
.filter(([_, m]) => m[0] & 15 /* HasAttribute */) // filter to only keep props that should match attributes
|
|
1181
|
+
.filter(([_, m]) => m[0] & 15 /* MEMBER_FLAGS.HasAttribute */) // filter to only keep props that should match attributes
|
|
834
1182
|
.map(([propName, m]) => {
|
|
835
1183
|
const attrName = m[1] || propName;
|
|
836
1184
|
attrNameToPropName.set(attrName, propName);
|
|
@@ -842,10 +1190,10 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
|
842
1190
|
};
|
|
843
1191
|
const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
|
|
844
1192
|
// initializeComponent
|
|
845
|
-
if ((hostRef.$flags$ & 32 /* hasInitializedComponent */) === 0) {
|
|
1193
|
+
if ((hostRef.$flags$ & 32 /* HOST_FLAGS.hasInitializedComponent */) === 0) {
|
|
846
1194
|
{
|
|
847
1195
|
// we haven't initialized this element yet
|
|
848
|
-
hostRef.$flags$ |= 32 /* hasInitializedComponent */;
|
|
1196
|
+
hostRef.$flags$ |= 32 /* HOST_FLAGS.hasInitializedComponent */;
|
|
849
1197
|
// lazy loaded components
|
|
850
1198
|
// request the component's implementation to be
|
|
851
1199
|
// wired up with the host element
|
|
@@ -857,7 +1205,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
857
1205
|
endLoad();
|
|
858
1206
|
}
|
|
859
1207
|
if (!Cstr.isProxied) {
|
|
860
|
-
proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
|
|
1208
|
+
proxyComponent(Cstr, cmpMeta, 2 /* PROXY_FLAGS.proxyState */);
|
|
861
1209
|
Cstr.isProxied = true;
|
|
862
1210
|
}
|
|
863
1211
|
const endNewInstance = createTime('createInstance', cmpMeta.$tagName$);
|
|
@@ -865,7 +1213,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
865
1213
|
// but let's keep track of when we start and stop
|
|
866
1214
|
// so that the getters/setters don't incorrectly step on data
|
|
867
1215
|
{
|
|
868
|
-
hostRef.$flags$ |= 8 /* isConstructingInstance */;
|
|
1216
|
+
hostRef.$flags$ |= 8 /* HOST_FLAGS.isConstructingInstance */;
|
|
869
1217
|
}
|
|
870
1218
|
// construct the lazy-loaded component implementation
|
|
871
1219
|
// passing the hostRef is very important during
|
|
@@ -878,7 +1226,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
878
1226
|
consoleError(e);
|
|
879
1227
|
}
|
|
880
1228
|
{
|
|
881
|
-
hostRef.$flags$ &= ~8 /* isConstructingInstance */;
|
|
1229
|
+
hostRef.$flags$ &= ~8 /* HOST_FLAGS.isConstructingInstance */;
|
|
882
1230
|
}
|
|
883
1231
|
endNewInstance();
|
|
884
1232
|
}
|
|
@@ -888,7 +1236,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
888
1236
|
const scopeId = getScopeId(cmpMeta);
|
|
889
1237
|
if (!styles.has(scopeId)) {
|
|
890
1238
|
const endRegisterStyles = createTime('registerStyles', cmpMeta.$tagName$);
|
|
891
|
-
registerStyle(scopeId, style, !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */));
|
|
1239
|
+
registerStyle(scopeId, style, !!(cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */));
|
|
892
1240
|
endRegisterStyles();
|
|
893
1241
|
}
|
|
894
1242
|
}
|
|
@@ -897,7 +1245,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
897
1245
|
const ancestorComponent = hostRef.$ancestorComponent$;
|
|
898
1246
|
const schedule = () => scheduleUpdate(hostRef, true);
|
|
899
1247
|
if (ancestorComponent && ancestorComponent['s-rc']) {
|
|
900
|
-
// this is the
|
|
1248
|
+
// this is the initial load and this component it has an ancestor component
|
|
901
1249
|
// but the ancestor component has NOT fired its will update lifecycle yet
|
|
902
1250
|
// so let's just cool our jets and wait for the ancestor to continue first
|
|
903
1251
|
// this will get fired off when the ancestor component
|
|
@@ -910,13 +1258,13 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) =>
|
|
|
910
1258
|
}
|
|
911
1259
|
};
|
|
912
1260
|
const connectedCallback = (elm) => {
|
|
913
|
-
if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
|
|
1261
|
+
if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
|
|
914
1262
|
const hostRef = getHostRef(elm);
|
|
915
1263
|
const cmpMeta = hostRef.$cmpMeta$;
|
|
916
1264
|
const endConnected = createTime('connectedCallback', cmpMeta.$tagName$);
|
|
917
|
-
if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
|
|
1265
|
+
if (!(hostRef.$flags$ & 1 /* HOST_FLAGS.hasConnected */)) {
|
|
918
1266
|
// first time this component has connected
|
|
919
|
-
hostRef.$flags$ |= 1 /* hasConnected */;
|
|
1267
|
+
hostRef.$flags$ |= 1 /* HOST_FLAGS.hasConnected */;
|
|
920
1268
|
{
|
|
921
1269
|
// find the first ancestor component (if there is one) and register
|
|
922
1270
|
// this component as one of the actively loading child components for its ancestor
|
|
@@ -936,7 +1284,7 @@ const connectedCallback = (elm) => {
|
|
|
936
1284
|
// https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
|
|
937
1285
|
if (cmpMeta.$members$) {
|
|
938
1286
|
Object.entries(cmpMeta.$members$).map(([memberName, [memberFlags]]) => {
|
|
939
|
-
if (memberFlags & 31 /* Prop */ && elm.hasOwnProperty(memberName)) {
|
|
1287
|
+
if (memberFlags & 31 /* MEMBER_FLAGS.Prop */ && elm.hasOwnProperty(memberName)) {
|
|
940
1288
|
const value = elm[memberName];
|
|
941
1289
|
delete elm[memberName];
|
|
942
1290
|
elm[memberName] = value;
|
|
@@ -951,11 +1299,12 @@ const connectedCallback = (elm) => {
|
|
|
951
1299
|
}
|
|
952
1300
|
};
|
|
953
1301
|
const disconnectedCallback = (elm) => {
|
|
954
|
-
if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
|
|
1302
|
+
if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
|
|
955
1303
|
getHostRef(elm);
|
|
956
1304
|
}
|
|
957
1305
|
};
|
|
958
1306
|
const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
1307
|
+
var _a;
|
|
959
1308
|
const endBootstrap = createTime();
|
|
960
1309
|
const cmpTags = [];
|
|
961
1310
|
const exclude = options.exclude || [];
|
|
@@ -968,54 +1317,61 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
968
1317
|
let isBootstrapping = true;
|
|
969
1318
|
Object.assign(plt, options);
|
|
970
1319
|
plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
|
|
971
|
-
lazyBundles.map((lazyBundle) =>
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
const tagName = cmpMeta.$tagName$;
|
|
982
|
-
const HostElement = class extends HTMLElement {
|
|
983
|
-
// StencilLazyHost
|
|
984
|
-
constructor(self) {
|
|
985
|
-
// @ts-ignore
|
|
986
|
-
super(self);
|
|
987
|
-
self = this;
|
|
988
|
-
registerHost(self, cmpMeta);
|
|
1320
|
+
lazyBundles.map((lazyBundle) => {
|
|
1321
|
+
lazyBundle[1].map((compactMeta) => {
|
|
1322
|
+
const cmpMeta = {
|
|
1323
|
+
$flags$: compactMeta[0],
|
|
1324
|
+
$tagName$: compactMeta[1],
|
|
1325
|
+
$members$: compactMeta[2],
|
|
1326
|
+
$listeners$: compactMeta[3],
|
|
1327
|
+
};
|
|
1328
|
+
{
|
|
1329
|
+
cmpMeta.$members$ = compactMeta[2];
|
|
989
1330
|
}
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
1331
|
+
const tagName = cmpMeta.$tagName$;
|
|
1332
|
+
const HostElement = class extends HTMLElement {
|
|
1333
|
+
// StencilLazyHost
|
|
1334
|
+
constructor(self) {
|
|
1335
|
+
// @ts-ignore
|
|
1336
|
+
super(self);
|
|
1337
|
+
self = this;
|
|
1338
|
+
registerHost(self, cmpMeta);
|
|
994
1339
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1340
|
+
connectedCallback() {
|
|
1341
|
+
if (appLoadFallback) {
|
|
1342
|
+
clearTimeout(appLoadFallback);
|
|
1343
|
+
appLoadFallback = null;
|
|
1344
|
+
}
|
|
1345
|
+
if (isBootstrapping) {
|
|
1346
|
+
// connectedCallback will be processed once all components have been registered
|
|
1347
|
+
deferredConnectedCallbacks.push(this);
|
|
1348
|
+
}
|
|
1349
|
+
else {
|
|
1350
|
+
plt.jmp(() => connectedCallback(this));
|
|
1351
|
+
}
|
|
998
1352
|
}
|
|
999
|
-
|
|
1000
|
-
plt.jmp(() =>
|
|
1353
|
+
disconnectedCallback() {
|
|
1354
|
+
plt.jmp(() => disconnectedCallback(this));
|
|
1001
1355
|
}
|
|
1356
|
+
componentOnReady() {
|
|
1357
|
+
return getHostRef(this).$onReadyPromise$;
|
|
1358
|
+
}
|
|
1359
|
+
};
|
|
1360
|
+
cmpMeta.$lazyBundleId$ = lazyBundle[0];
|
|
1361
|
+
if (!exclude.includes(tagName) && !customElements.get(tagName)) {
|
|
1362
|
+
cmpTags.push(tagName);
|
|
1363
|
+
customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* PROXY_FLAGS.isElementConstructor */));
|
|
1002
1364
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
}
|
|
1006
|
-
componentOnReady() {
|
|
1007
|
-
return getHostRef(this).$onReadyPromise$;
|
|
1008
|
-
}
|
|
1009
|
-
};
|
|
1010
|
-
cmpMeta.$lazyBundleId$ = lazyBundle[0];
|
|
1011
|
-
if (!exclude.includes(tagName) && !customElements.get(tagName)) {
|
|
1012
|
-
cmpTags.push(tagName);
|
|
1013
|
-
customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* isElementConstructor */));
|
|
1014
|
-
}
|
|
1015
|
-
}));
|
|
1365
|
+
});
|
|
1366
|
+
});
|
|
1016
1367
|
{
|
|
1017
1368
|
visibilityStyle.innerHTML = cmpTags + HYDRATED_CSS;
|
|
1018
1369
|
visibilityStyle.setAttribute('data-styles', '');
|
|
1370
|
+
// Apply CSP nonce to the style tag if it exists
|
|
1371
|
+
const nonce = (_a = plt.$nonce$) !== null && _a !== void 0 ? _a : queryNonceMetaTagContent(doc);
|
|
1372
|
+
if (nonce != null) {
|
|
1373
|
+
visibilityStyle.setAttribute('nonce', nonce);
|
|
1374
|
+
}
|
|
1019
1375
|
head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
|
|
1020
1376
|
}
|
|
1021
1377
|
// Process deferred connectedCallbacks now all components have been registered
|
|
@@ -1031,7 +1387,14 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
|
|
|
1031
1387
|
// Fallback appLoad event
|
|
1032
1388
|
endBootstrap();
|
|
1033
1389
|
};
|
|
1034
|
-
|
|
1390
|
+
/**
|
|
1391
|
+
* Assigns the given value to the nonce property on the runtime platform object.
|
|
1392
|
+
* During runtime, this value is used to set the nonce attribute on all dynamically created script and style tags.
|
|
1393
|
+
* @param nonce The value to be assigned to the platform nonce property.
|
|
1394
|
+
* @returns void
|
|
1395
|
+
*/
|
|
1396
|
+
const setNonce = (nonce) => (plt.$nonce$ = nonce);
|
|
1397
|
+
const hostRefs = /*@__PURE__*/ new WeakMap();
|
|
1035
1398
|
const getHostRef = (ref) => hostRefs.get(ref);
|
|
1036
1399
|
const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
|
|
1037
1400
|
const registerHost = (elm, cmpMeta) => {
|
|
@@ -1062,7 +1425,9 @@ const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
|
|
|
1062
1425
|
if (module) {
|
|
1063
1426
|
return module[exportName];
|
|
1064
1427
|
}
|
|
1428
|
+
/*!__STENCIL_STATIC_IMPORT_SWITCH__*/
|
|
1065
1429
|
return import(
|
|
1430
|
+
/* @vite-ignore */
|
|
1066
1431
|
/* webpackInclude: /\.entry\.js$/ */
|
|
1067
1432
|
/* webpackExclude: /\.system\.entry\.js$/ */
|
|
1068
1433
|
/* webpackMode: "lazy" */
|
|
@@ -1073,14 +1438,35 @@ const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
|
|
|
1073
1438
|
return importedModule[exportName];
|
|
1074
1439
|
}, consoleError);
|
|
1075
1440
|
};
|
|
1076
|
-
const styles = new Map();
|
|
1441
|
+
const styles = /*@__PURE__*/ new Map();
|
|
1442
|
+
const win = typeof window !== 'undefined' ? window : {};
|
|
1443
|
+
const doc = win.document || { head: {} };
|
|
1444
|
+
const plt = {
|
|
1445
|
+
$flags$: 0,
|
|
1446
|
+
$resourcesUrl$: '',
|
|
1447
|
+
jmp: (h) => h(),
|
|
1448
|
+
raf: (h) => requestAnimationFrame(h),
|
|
1449
|
+
ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
|
|
1450
|
+
rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
|
|
1451
|
+
ce: (eventName, opts) => new CustomEvent(eventName, opts),
|
|
1452
|
+
};
|
|
1453
|
+
const promiseResolve = (v) => Promise.resolve(v);
|
|
1454
|
+
const supportsConstructableStylesheets = /*@__PURE__*/ (() => {
|
|
1455
|
+
try {
|
|
1456
|
+
new CSSStyleSheet();
|
|
1457
|
+
return typeof new CSSStyleSheet().replaceSync === 'function';
|
|
1458
|
+
}
|
|
1459
|
+
catch (e) { }
|
|
1460
|
+
return false;
|
|
1461
|
+
})()
|
|
1462
|
+
;
|
|
1077
1463
|
const queueDomReads = [];
|
|
1078
1464
|
const queueDomWrites = [];
|
|
1079
1465
|
const queueTask = (queue, write) => (cb) => {
|
|
1080
1466
|
queue.push(cb);
|
|
1081
1467
|
if (!queuePending) {
|
|
1082
1468
|
queuePending = true;
|
|
1083
|
-
if (write && plt.$flags$ & 4 /* queueSync */) {
|
|
1469
|
+
if (write && plt.$flags$ & 4 /* PLATFORM_FLAGS.queueSync */) {
|
|
1084
1470
|
nextTick(flush);
|
|
1085
1471
|
}
|
|
1086
1472
|
else {
|
|
@@ -1117,4 +1503,4 @@ const flush = () => {
|
|
|
1117
1503
|
const nextTick = /*@__PURE__*/ (cb) => promiseResolve().then(cb);
|
|
1118
1504
|
const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
|
|
1119
1505
|
|
|
1120
|
-
export { bootstrapLazy as b, h, promiseResolve as p, registerInstance as r };
|
|
1506
|
+
export { bootstrapLazy as b, getAssetPath as g, h, promiseResolve as p, registerInstance as r, setNonce as s };
|