index-a0010f96.js 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.97
  5. */
  6. 'use strict';
  7. function _interopNamespace(e) {
  8. if (e && e.__esModule) return e;
  9. var n = Object.create(null);
  10. if (e) {
  11. Object.keys(e).forEach(function (k) {
  12. if (k !== 'default') {
  13. var d = Object.getOwnPropertyDescriptor(e, k);
  14. Object.defineProperty(n, k, d.get ? d : {
  15. enumerable: true,
  16. get: function () {
  17. return e[k];
  18. }
  19. });
  20. }
  21. });
  22. }
  23. n['default'] = e;
  24. return Object.freeze(n);
  25. }
  26. const NAMESPACE = 'calcite';
  27. /**
  28. * Virtual DOM patching algorithm based on Snabbdom by
  29. * Simon Friis Vindum (@paldepind)
  30. * Licensed under the MIT License
  31. * https://github.com/snabbdom/snabbdom/blob/master/LICENSE
  32. *
  33. * Modified for Stencil's renderer and slot projection
  34. */
  35. let scopeId;
  36. let hostTagName;
  37. let isSvgMode = false;
  38. let queuePending = false;
  39. const getAssetPath = (path) => {
  40. const assetUrl = new URL(path, plt.$resourcesUrl$);
  41. return assetUrl.origin !== win.location.origin ? assetUrl.href : assetUrl.pathname;
  42. };
  43. const createTime = (fnName, tagName = '') => {
  44. {
  45. return () => {
  46. return;
  47. };
  48. }
  49. };
  50. const uniqueTime = (key, measureText) => {
  51. {
  52. return () => {
  53. return;
  54. };
  55. }
  56. };
  57. const CONTENT_REF_ID = 'r';
  58. const ORG_LOCATION_ID = 'o';
  59. const SLOT_NODE_ID = 's';
  60. const TEXT_NODE_ID = 't';
  61. const HYDRATE_ID = 's-id';
  62. const HYDRATED_STYLE_ID = 'sty-id';
  63. const HYDRATE_CHILD_ID = 'c-id';
  64. const HYDRATED_CSS = '{visibility:hidden}[calcite-hydrated]{visibility:inherit}';
  65. const XLINK_NS = 'http://www.w3.org/1999/xlink';
  66. /**
  67. * Default style mode id
  68. */
  69. /**
  70. * Reusable empty obj/array
  71. * Don't add values to these!!
  72. */
  73. const EMPTY_OBJ = {};
  74. /**
  75. * Namespaces
  76. */
  77. const SVG_NS = 'http://www.w3.org/2000/svg';
  78. const HTML_NS = 'http://www.w3.org/1999/xhtml';
  79. const isDef = (v) => v != null;
  80. const isComplexType = (o) => {
  81. // https://jsperf.com/typeof-fn-object/5
  82. o = typeof o;
  83. return o === 'object' || o === 'function';
  84. };
  85. /**
  86. * Production h() function based on Preact by
  87. * Jason Miller (@developit)
  88. * Licensed under the MIT License
  89. * https://github.com/developit/preact/blob/master/LICENSE
  90. *
  91. * Modified for Stencil's compiler and vdom
  92. */
  93. // const stack: any[] = [];
  94. // export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, child?: d.ChildType): d.VNode;
  95. // export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
  96. const h = (nodeName, vnodeData, ...children) => {
  97. let child = null;
  98. let key = null;
  99. let simple = false;
  100. let lastSimple = false;
  101. const vNodeChildren = [];
  102. const walk = (c) => {
  103. for (let i = 0; i < c.length; i++) {
  104. child = c[i];
  105. if (Array.isArray(child)) {
  106. walk(child);
  107. }
  108. else if (child != null && typeof child !== 'boolean') {
  109. if ((simple = typeof nodeName !== 'function' && !isComplexType(child))) {
  110. child = String(child);
  111. }
  112. if (simple && lastSimple) {
  113. // If the previous child was simple (string), we merge both
  114. vNodeChildren[vNodeChildren.length - 1].$text$ += child;
  115. }
  116. else {
  117. // Append a new vNode, if it's text, we create a text vNode
  118. vNodeChildren.push(simple ? newVNode(null, child) : child);
  119. }
  120. lastSimple = simple;
  121. }
  122. }
  123. };
  124. walk(children);
  125. if (vnodeData) {
  126. // normalize class / classname attributes
  127. if (vnodeData.key) {
  128. key = vnodeData.key;
  129. }
  130. {
  131. const classData = vnodeData.className || vnodeData.class;
  132. if (classData) {
  133. vnodeData.class =
  134. typeof classData !== 'object'
  135. ? classData
  136. : Object.keys(classData)
  137. .filter((k) => classData[k])
  138. .join(' ');
  139. }
  140. }
  141. }
  142. if (typeof nodeName === 'function') {
  143. // nodeName is a functional component
  144. return nodeName(vnodeData === null ? {} : vnodeData, vNodeChildren, vdomFnUtils);
  145. }
  146. const vnode = newVNode(nodeName, null);
  147. vnode.$attrs$ = vnodeData;
  148. if (vNodeChildren.length > 0) {
  149. vnode.$children$ = vNodeChildren;
  150. }
  151. {
  152. vnode.$key$ = key;
  153. }
  154. return vnode;
  155. };
  156. const newVNode = (tag, text) => {
  157. const vnode = {
  158. $flags$: 0,
  159. $tag$: tag,
  160. $text$: text,
  161. $elm$: null,
  162. $children$: null,
  163. };
  164. {
  165. vnode.$attrs$ = null;
  166. }
  167. {
  168. vnode.$key$ = null;
  169. }
  170. return vnode;
  171. };
  172. const Host = {};
  173. const isHost = (node) => node && node.$tag$ === Host;
  174. const vdomFnUtils = {
  175. forEach: (children, cb) => children.map(convertToPublic).forEach(cb),
  176. map: (children, cb) => children.map(convertToPublic).map(cb).map(convertToPrivate),
  177. };
  178. const convertToPublic = (node) => ({
  179. vattrs: node.$attrs$,
  180. vchildren: node.$children$,
  181. vkey: node.$key$,
  182. vname: node.$name$,
  183. vtag: node.$tag$,
  184. vtext: node.$text$,
  185. });
  186. const convertToPrivate = (node) => {
  187. if (typeof node.vtag === 'function') {
  188. const vnodeData = Object.assign({}, node.vattrs);
  189. if (node.vkey) {
  190. vnodeData.key = node.vkey;
  191. }
  192. if (node.vname) {
  193. vnodeData.name = node.vname;
  194. }
  195. return h(node.vtag, vnodeData, ...(node.vchildren || []));
  196. }
  197. const vnode = newVNode(node.vtag, node.vtext);
  198. vnode.$attrs$ = node.vattrs;
  199. vnode.$children$ = node.vchildren;
  200. vnode.$key$ = node.vkey;
  201. vnode.$name$ = node.vname;
  202. return vnode;
  203. };
  204. const initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
  205. const endHydrate = createTime('hydrateClient', tagName);
  206. const shadowRoot = hostElm.shadowRoot;
  207. const childRenderNodes = [];
  208. const slotNodes = [];
  209. const shadowRootNodes = shadowRoot ? [] : null;
  210. const vnode = (hostRef.$vnode$ = newVNode(tagName, null));
  211. if (!plt.$orgLocNodes$) {
  212. initializeDocumentHydrate(doc.body, (plt.$orgLocNodes$ = new Map()));
  213. }
  214. hostElm[HYDRATE_ID] = hostId;
  215. hostElm.removeAttribute(HYDRATE_ID);
  216. clientHydrate(vnode, childRenderNodes, slotNodes, shadowRootNodes, hostElm, hostElm, hostId);
  217. childRenderNodes.map((c) => {
  218. const orgLocationId = c.$hostId$ + '.' + c.$nodeId$;
  219. const orgLocationNode = plt.$orgLocNodes$.get(orgLocationId);
  220. const node = c.$elm$;
  221. if (orgLocationNode && supportsShadow && orgLocationNode['s-en'] === '') {
  222. orgLocationNode.parentNode.insertBefore(node, orgLocationNode.nextSibling);
  223. }
  224. if (!shadowRoot) {
  225. node['s-hn'] = tagName;
  226. if (orgLocationNode) {
  227. node['s-ol'] = orgLocationNode;
  228. node['s-ol']['s-nr'] = node;
  229. }
  230. }
  231. plt.$orgLocNodes$.delete(orgLocationId);
  232. });
  233. if (shadowRoot) {
  234. shadowRootNodes.map((shadowRootNode) => {
  235. if (shadowRootNode) {
  236. shadowRoot.appendChild(shadowRootNode);
  237. }
  238. });
  239. }
  240. endHydrate();
  241. };
  242. const clientHydrate = (parentVNode, childRenderNodes, slotNodes, shadowRootNodes, hostElm, node, hostId) => {
  243. let childNodeType;
  244. let childIdSplt;
  245. let childVNode;
  246. let i;
  247. if (node.nodeType === 1 /* NODE_TYPE.ElementNode */) {
  248. childNodeType = node.getAttribute(HYDRATE_CHILD_ID);
  249. if (childNodeType) {
  250. // got the node data from the element's attribute
  251. // `${hostId}.${nodeId}.${depth}.${index}`
  252. childIdSplt = childNodeType.split('.');
  253. if (childIdSplt[0] === hostId || childIdSplt[0] === '0') {
  254. childVNode = {
  255. $flags$: 0,
  256. $hostId$: childIdSplt[0],
  257. $nodeId$: childIdSplt[1],
  258. $depth$: childIdSplt[2],
  259. $index$: childIdSplt[3],
  260. $tag$: node.tagName.toLowerCase(),
  261. $elm$: node,
  262. $attrs$: null,
  263. $children$: null,
  264. $key$: null,
  265. $name$: null,
  266. $text$: null,
  267. };
  268. childRenderNodes.push(childVNode);
  269. node.removeAttribute(HYDRATE_CHILD_ID);
  270. // this is a new child vnode
  271. // so ensure its parent vnode has the vchildren array
  272. if (!parentVNode.$children$) {
  273. parentVNode.$children$ = [];
  274. }
  275. // add our child vnode to a specific index of the vnode's children
  276. parentVNode.$children$[childVNode.$index$] = childVNode;
  277. // this is now the new parent vnode for all the next child checks
  278. parentVNode = childVNode;
  279. if (shadowRootNodes && childVNode.$depth$ === '0') {
  280. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  281. }
  282. }
  283. }
  284. // recursively drill down, end to start so we can remove nodes
  285. for (i = node.childNodes.length - 1; i >= 0; i--) {
  286. clientHydrate(parentVNode, childRenderNodes, slotNodes, shadowRootNodes, hostElm, node.childNodes[i], hostId);
  287. }
  288. if (node.shadowRoot) {
  289. // keep drilling down through the shadow root nodes
  290. for (i = node.shadowRoot.childNodes.length - 1; i >= 0; i--) {
  291. clientHydrate(parentVNode, childRenderNodes, slotNodes, shadowRootNodes, hostElm, node.shadowRoot.childNodes[i], hostId);
  292. }
  293. }
  294. }
  295. else if (node.nodeType === 8 /* NODE_TYPE.CommentNode */) {
  296. // `${COMMENT_TYPE}.${hostId}.${nodeId}.${depth}.${index}`
  297. childIdSplt = node.nodeValue.split('.');
  298. if (childIdSplt[1] === hostId || childIdSplt[1] === '0') {
  299. // comment node for either the host id or a 0 host id
  300. childNodeType = childIdSplt[0];
  301. childVNode = {
  302. $flags$: 0,
  303. $hostId$: childIdSplt[1],
  304. $nodeId$: childIdSplt[2],
  305. $depth$: childIdSplt[3],
  306. $index$: childIdSplt[4],
  307. $elm$: node,
  308. $attrs$: null,
  309. $children$: null,
  310. $key$: null,
  311. $name$: null,
  312. $tag$: null,
  313. $text$: null,
  314. };
  315. if (childNodeType === TEXT_NODE_ID) {
  316. childVNode.$elm$ = node.nextSibling;
  317. if (childVNode.$elm$ && childVNode.$elm$.nodeType === 3 /* NODE_TYPE.TextNode */) {
  318. childVNode.$text$ = childVNode.$elm$.textContent;
  319. childRenderNodes.push(childVNode);
  320. // remove the text comment since it's no longer needed
  321. node.remove();
  322. if (!parentVNode.$children$) {
  323. parentVNode.$children$ = [];
  324. }
  325. parentVNode.$children$[childVNode.$index$] = childVNode;
  326. if (shadowRootNodes && childVNode.$depth$ === '0') {
  327. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  328. }
  329. }
  330. }
  331. else if (childVNode.$hostId$ === hostId) {
  332. // this comment node is specifcally for this host id
  333. if (childNodeType === SLOT_NODE_ID) {
  334. // `${SLOT_NODE_ID}.${hostId}.${nodeId}.${depth}.${index}.${slotName}`;
  335. childVNode.$tag$ = 'slot';
  336. if (childIdSplt[5]) {
  337. node['s-sn'] = childVNode.$name$ = childIdSplt[5];
  338. }
  339. else {
  340. node['s-sn'] = '';
  341. }
  342. node['s-sr'] = true;
  343. if (shadowRootNodes) {
  344. // browser support shadowRoot and this is a shadow dom component
  345. // create an actual slot element
  346. childVNode.$elm$ = doc.createElement(childVNode.$tag$);
  347. if (childVNode.$name$) {
  348. // add the slot name attribute
  349. childVNode.$elm$.setAttribute('name', childVNode.$name$);
  350. }
  351. // insert the new slot element before the slot comment
  352. node.parentNode.insertBefore(childVNode.$elm$, node);
  353. // remove the slot comment since it's not needed for shadow
  354. node.remove();
  355. if (childVNode.$depth$ === '0') {
  356. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  357. }
  358. }
  359. slotNodes.push(childVNode);
  360. if (!parentVNode.$children$) {
  361. parentVNode.$children$ = [];
  362. }
  363. parentVNode.$children$[childVNode.$index$] = childVNode;
  364. }
  365. else if (childNodeType === CONTENT_REF_ID) {
  366. // `${CONTENT_REF_ID}.${hostId}`;
  367. if (shadowRootNodes) {
  368. // remove the content ref comment since it's not needed for shadow
  369. node.remove();
  370. }
  371. }
  372. }
  373. }
  374. }
  375. else if (parentVNode && parentVNode.$tag$ === 'style') {
  376. const vnode = newVNode(null, node.textContent);
  377. vnode.$elm$ = node;
  378. vnode.$index$ = '0';
  379. parentVNode.$children$ = [vnode];
  380. }
  381. };
  382. const initializeDocumentHydrate = (node, orgLocNodes) => {
  383. if (node.nodeType === 1 /* NODE_TYPE.ElementNode */) {
  384. let i = 0;
  385. for (; i < node.childNodes.length; i++) {
  386. initializeDocumentHydrate(node.childNodes[i], orgLocNodes);
  387. }
  388. if (node.shadowRoot) {
  389. for (i = 0; i < node.shadowRoot.childNodes.length; i++) {
  390. initializeDocumentHydrate(node.shadowRoot.childNodes[i], orgLocNodes);
  391. }
  392. }
  393. }
  394. else if (node.nodeType === 8 /* NODE_TYPE.CommentNode */) {
  395. const childIdSplt = node.nodeValue.split('.');
  396. if (childIdSplt[0] === ORG_LOCATION_ID) {
  397. orgLocNodes.set(childIdSplt[1] + '.' + childIdSplt[2], node);
  398. node.nodeValue = '';
  399. // useful to know if the original location is
  400. // the root light-dom of a shadow dom component
  401. node['s-en'] = childIdSplt[3];
  402. }
  403. }
  404. };
  405. /**
  406. * Parse a new property value for a given property type.
  407. *
  408. * While the prop value can reasonably be expected to be of `any` type as far as TypeScript's type checker is concerned,
  409. * it is not safe to assume that the string returned by evaluating `typeof propValue` matches:
  410. * 1. `any`, the type given to `propValue` in the function signature
  411. * 2. the type stored from `propType`.
  412. *
  413. * This function provides the capability to parse/coerce a property's value to potentially any other JavaScript type.
  414. *
  415. * Property values represented in TSX preserve their type information. In the example below, the number 0 is passed to
  416. * a component. This `propValue` will preserve its type information (`typeof propValue === 'number'`). Note that is
  417. * based on the type of the value being passed in, not the type declared of the class member decorated with `@Prop`.
  418. * ```tsx
  419. * <my-cmp prop-val={0}></my-cmp>
  420. * ```
  421. *
  422. * HTML prop values on the other hand, will always a string
  423. *
  424. * @param propValue the new value to coerce to some type
  425. * @param propType the type of the prop, expressed as a binary number
  426. * @returns the parsed/coerced value
  427. */
  428. const parsePropertyValue = (propValue, propType) => {
  429. // ensure this value is of the correct prop type
  430. if (propValue != null && !isComplexType(propValue)) {
  431. if (propType & 4 /* MEMBER_FLAGS.Boolean */) {
  432. // per the HTML spec, any string value means it is a boolean true value
  433. // but we'll cheat here and say that the string "false" is the boolean false
  434. return propValue === 'false' ? false : propValue === '' || !!propValue;
  435. }
  436. if (propType & 2 /* MEMBER_FLAGS.Number */) {
  437. // force it to be a number
  438. return parseFloat(propValue);
  439. }
  440. if (propType & 1 /* MEMBER_FLAGS.String */) {
  441. // could have been passed as a number or boolean
  442. // but we still want it as a string
  443. return String(propValue);
  444. }
  445. // redundant return here for better minification
  446. return propValue;
  447. }
  448. // not sure exactly what type we want
  449. // so no need to change to a different type
  450. return propValue;
  451. };
  452. const getElement = (ref) => (getHostRef(ref).$hostElement$ );
  453. const createEvent = (ref, name, flags) => {
  454. const elm = getElement(ref);
  455. return {
  456. emit: (detail) => {
  457. return emitEvent(elm, name, {
  458. bubbles: !!(flags & 4 /* EVENT_FLAGS.Bubbles */),
  459. composed: !!(flags & 2 /* EVENT_FLAGS.Composed */),
  460. cancelable: !!(flags & 1 /* EVENT_FLAGS.Cancellable */),
  461. detail,
  462. });
  463. },
  464. };
  465. };
  466. /**
  467. * Helper function to create & dispatch a custom Event on a provided target
  468. * @param elm the target of the Event
  469. * @param name the name to give the custom Event
  470. * @param opts options for configuring a custom Event
  471. * @returns the custom Event
  472. */
  473. const emitEvent = (elm, name, opts) => {
  474. const ev = plt.ce(name, opts);
  475. elm.dispatchEvent(ev);
  476. return ev;
  477. };
  478. const rootAppliedStyles = /*@__PURE__*/ new WeakMap();
  479. const registerStyle = (scopeId, cssText, allowCS) => {
  480. let style = styles.get(scopeId);
  481. if (supportsConstructableStylesheets && allowCS) {
  482. style = (style || new CSSStyleSheet());
  483. if (typeof style === 'string') {
  484. style = cssText;
  485. }
  486. else {
  487. style.replaceSync(cssText);
  488. }
  489. }
  490. else {
  491. style = cssText;
  492. }
  493. styles.set(scopeId, style);
  494. };
  495. const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
  496. let scopeId = getScopeId(cmpMeta);
  497. const style = styles.get(scopeId);
  498. // if an element is NOT connected then getRootNode() will return the wrong root node
  499. // so the fallback is to always use the document for the root node in those cases
  500. styleContainerNode = styleContainerNode.nodeType === 11 /* NODE_TYPE.DocumentFragment */ ? styleContainerNode : doc;
  501. if (style) {
  502. if (typeof style === 'string') {
  503. styleContainerNode = styleContainerNode.head || styleContainerNode;
  504. let appliedStyles = rootAppliedStyles.get(styleContainerNode);
  505. let styleElm;
  506. if (!appliedStyles) {
  507. rootAppliedStyles.set(styleContainerNode, (appliedStyles = new Set()));
  508. }
  509. if (!appliedStyles.has(scopeId)) {
  510. if (styleContainerNode.host &&
  511. (styleElm = styleContainerNode.querySelector(`[${HYDRATED_STYLE_ID}="${scopeId}"]`))) {
  512. // This is only happening on native shadow-dom, do not needs CSS var shim
  513. styleElm.innerHTML = style;
  514. }
  515. else {
  516. {
  517. styleElm = doc.createElement('style');
  518. styleElm.innerHTML = style;
  519. }
  520. styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector('link'));
  521. }
  522. if (appliedStyles) {
  523. appliedStyles.add(scopeId);
  524. }
  525. }
  526. }
  527. else if (!styleContainerNode.adoptedStyleSheets.includes(style)) {
  528. styleContainerNode.adoptedStyleSheets = [...styleContainerNode.adoptedStyleSheets, style];
  529. }
  530. }
  531. return scopeId;
  532. };
  533. const attachStyles = (hostRef) => {
  534. const cmpMeta = hostRef.$cmpMeta$;
  535. const elm = hostRef.$hostElement$;
  536. const flags = cmpMeta.$flags$;
  537. const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
  538. const scopeId = addStyle(elm.shadowRoot ? elm.shadowRoot : elm.getRootNode(), cmpMeta);
  539. if (flags & 10 /* CMP_FLAGS.needsScopedEncapsulation */) {
  540. // only required when we're NOT using native shadow dom (slot)
  541. // or this browser doesn't support native shadow dom
  542. // and this host element was NOT created with SSR
  543. // let's pick out the inner content for slot projection
  544. // create a node to represent where the original
  545. // content was first placed, which is useful later on
  546. // DOM WRITE!!
  547. elm['s-sc'] = scopeId;
  548. elm.classList.add(scopeId + '-h');
  549. }
  550. endAttachStyles();
  551. };
  552. const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
  553. const convertScopedToShadow = (css) => css.replace(/\/\*!@([^\/]+)\*\/[^\{]+\{/g, '$1{');
  554. /**
  555. * Production setAccessor() function based on Preact by
  556. * Jason Miller (@developit)
  557. * Licensed under the MIT License
  558. * https://github.com/developit/preact/blob/master/LICENSE
  559. *
  560. * Modified for Stencil's compiler and vdom
  561. */
  562. const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
  563. if (oldValue !== newValue) {
  564. let isProp = isMemberInElement(elm, memberName);
  565. let ln = memberName.toLowerCase();
  566. if (memberName === 'class') {
  567. const classList = elm.classList;
  568. const oldClasses = parseClassList(oldValue);
  569. const newClasses = parseClassList(newValue);
  570. classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
  571. classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
  572. }
  573. else if (memberName === 'style') {
  574. // update style attribute, css properties and values
  575. {
  576. for (const prop in oldValue) {
  577. if (!newValue || newValue[prop] == null) {
  578. if (prop.includes('-')) {
  579. elm.style.removeProperty(prop);
  580. }
  581. else {
  582. elm.style[prop] = '';
  583. }
  584. }
  585. }
  586. }
  587. for (const prop in newValue) {
  588. if (!oldValue || newValue[prop] !== oldValue[prop]) {
  589. if (prop.includes('-')) {
  590. elm.style.setProperty(prop, newValue[prop]);
  591. }
  592. else {
  593. elm.style[prop] = newValue[prop];
  594. }
  595. }
  596. }
  597. }
  598. else if (memberName === 'key')
  599. ;
  600. else if (memberName === 'ref') {
  601. // minifier will clean this up
  602. if (newValue) {
  603. newValue(elm);
  604. }
  605. }
  606. else if ((!isProp ) &&
  607. memberName[0] === 'o' &&
  608. memberName[1] === 'n') {
  609. // Event Handlers
  610. // so if the member name starts with "on" and the 3rd characters is
  611. // a capital letter, and it's not already a member on the element,
  612. // then we're assuming it's an event listener
  613. if (memberName[2] === '-') {
  614. // on- prefixed events
  615. // allows to be explicit about the dom event to listen without any magic
  616. // under the hood:
  617. // <my-cmp on-click> // listens for "click"
  618. // <my-cmp on-Click> // listens for "Click"
  619. // <my-cmp on-ionChange> // listens for "ionChange"
  620. // <my-cmp on-EVENTS> // listens for "EVENTS"
  621. memberName = memberName.slice(3);
  622. }
  623. else if (isMemberInElement(win, ln)) {
  624. // standard event
  625. // the JSX attribute could have been "onMouseOver" and the
  626. // member name "onmouseover" is on the window's prototype
  627. // so let's add the listener "mouseover", which is all lowercased
  628. memberName = ln.slice(2);
  629. }
  630. else {
  631. // custom event
  632. // the JSX attribute could have been "onMyCustomEvent"
  633. // so let's trim off the "on" prefix and lowercase the first character
  634. // and add the listener "myCustomEvent"
  635. // except for the first character, we keep the event name case
  636. memberName = ln[2] + memberName.slice(3);
  637. }
  638. if (oldValue) {
  639. plt.rel(elm, memberName, oldValue, false);
  640. }
  641. if (newValue) {
  642. plt.ael(elm, memberName, newValue, false);
  643. }
  644. }
  645. else {
  646. // Set property if it exists and it's not a SVG
  647. const isComplex = isComplexType(newValue);
  648. if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
  649. try {
  650. if (!elm.tagName.includes('-')) {
  651. const n = newValue == null ? '' : newValue;
  652. // Workaround for Safari, moving the <input> caret when re-assigning the same valued
  653. if (memberName === 'list') {
  654. isProp = false;
  655. }
  656. else if (oldValue == null || elm[memberName] != n) {
  657. elm[memberName] = n;
  658. }
  659. }
  660. else {
  661. elm[memberName] = newValue;
  662. }
  663. }
  664. catch (e) { }
  665. }
  666. /**
  667. * Need to manually update attribute if:
  668. * - memberName is not an attribute
  669. * - if we are rendering the host element in order to reflect attribute
  670. * - if it's a SVG, since properties might not work in <svg>
  671. * - if the newValue is null/undefined or 'false'.
  672. */
  673. let xlink = false;
  674. {
  675. if (ln !== (ln = ln.replace(/^xlink\:?/, ''))) {
  676. memberName = ln;
  677. xlink = true;
  678. }
  679. }
  680. if (newValue == null || newValue === false) {
  681. if (newValue !== false || elm.getAttribute(memberName) === '') {
  682. if (xlink) {
  683. elm.removeAttributeNS(XLINK_NS, memberName);
  684. }
  685. else {
  686. elm.removeAttribute(memberName);
  687. }
  688. }
  689. }
  690. else if ((!isProp || flags & 4 /* VNODE_FLAGS.isHost */ || isSvg) && !isComplex) {
  691. newValue = newValue === true ? '' : newValue;
  692. if (xlink) {
  693. elm.setAttributeNS(XLINK_NS, memberName, newValue);
  694. }
  695. else {
  696. elm.setAttribute(memberName, newValue);
  697. }
  698. }
  699. }
  700. }
  701. };
  702. const parseClassListRegex = /\s/;
  703. const parseClassList = (value) => (!value ? [] : value.split(parseClassListRegex));
  704. const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
  705. // if the element passed in is a shadow root, which is a document fragment
  706. // then we want to be adding attrs/props to the shadow root's "host" element
  707. // if it's not a shadow root, then we add attrs/props to the same element
  708. const elm = newVnode.$elm$.nodeType === 11 /* NODE_TYPE.DocumentFragment */ && newVnode.$elm$.host
  709. ? newVnode.$elm$.host
  710. : newVnode.$elm$;
  711. const oldVnodeAttrs = (oldVnode && oldVnode.$attrs$) || EMPTY_OBJ;
  712. const newVnodeAttrs = newVnode.$attrs$ || EMPTY_OBJ;
  713. {
  714. // remove attributes no longer present on the vnode by setting them to undefined
  715. for (memberName in oldVnodeAttrs) {
  716. if (!(memberName in newVnodeAttrs)) {
  717. setAccessor(elm, memberName, oldVnodeAttrs[memberName], undefined, isSvgMode, newVnode.$flags$);
  718. }
  719. }
  720. }
  721. // add new & update changed attributes
  722. for (memberName in newVnodeAttrs) {
  723. setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode, newVnode.$flags$);
  724. }
  725. };
  726. /**
  727. * Create a DOM Node corresponding to one of the children of a given VNode.
  728. *
  729. * @param oldParentVNode the parent VNode from the previous render
  730. * @param newParentVNode the parent VNode from the current render
  731. * @param childIndex the index of the VNode, in the _new_ parent node's
  732. * children, for which we will create a new DOM node
  733. * @param parentElm the parent DOM node which our new node will be a child of
  734. * @returns the newly created node
  735. */
  736. const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
  737. // tslint:disable-next-line: prefer-const
  738. const newVNode = newParentVNode.$children$[childIndex];
  739. let i = 0;
  740. let elm;
  741. let childNode;
  742. if (newVNode.$text$ !== null) {
  743. // create text node
  744. elm = newVNode.$elm$ = doc.createTextNode(newVNode.$text$);
  745. }
  746. else {
  747. if (!isSvgMode) {
  748. isSvgMode = newVNode.$tag$ === 'svg';
  749. }
  750. // create element
  751. elm = newVNode.$elm$ = (doc.createElementNS(isSvgMode ? SVG_NS : HTML_NS, newVNode.$tag$)
  752. );
  753. if (isSvgMode && newVNode.$tag$ === 'foreignObject') {
  754. isSvgMode = false;
  755. }
  756. // add css classes, attrs, props, listeners, etc.
  757. {
  758. updateElement(null, newVNode, isSvgMode);
  759. }
  760. if (isDef(scopeId) && elm['s-si'] !== scopeId) {
  761. // if there is a scopeId and this is the initial render
  762. // then let's add the scopeId as a css class
  763. elm.classList.add((elm['s-si'] = scopeId));
  764. }
  765. if (newVNode.$children$) {
  766. for (i = 0; i < newVNode.$children$.length; ++i) {
  767. // create the node
  768. childNode = createElm(oldParentVNode, newVNode, i);
  769. // return node could have been null
  770. if (childNode) {
  771. // append our new node
  772. elm.appendChild(childNode);
  773. }
  774. }
  775. }
  776. {
  777. if (newVNode.$tag$ === 'svg') {
  778. // Only reset the SVG context when we're exiting <svg> element
  779. isSvgMode = false;
  780. }
  781. else if (elm.tagName === 'foreignObject') {
  782. // Reenter SVG context when we're exiting <foreignObject> element
  783. isSvgMode = true;
  784. }
  785. }
  786. }
  787. return elm;
  788. };
  789. const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
  790. let containerElm = (parentElm);
  791. let childNode;
  792. if (containerElm.shadowRoot && containerElm.tagName === hostTagName) {
  793. containerElm = containerElm.shadowRoot;
  794. }
  795. for (; startIdx <= endIdx; ++startIdx) {
  796. if (vnodes[startIdx]) {
  797. childNode = createElm(null, parentVNode, startIdx);
  798. if (childNode) {
  799. vnodes[startIdx].$elm$ = childNode;
  800. containerElm.insertBefore(childNode, before);
  801. }
  802. }
  803. }
  804. };
  805. const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
  806. for (; startIdx <= endIdx; ++startIdx) {
  807. if ((vnode = vnodes[startIdx])) {
  808. elm = vnode.$elm$;
  809. callNodeRefs(vnode);
  810. // remove the vnode's element from the dom
  811. elm.remove();
  812. }
  813. }
  814. };
  815. /**
  816. * Reconcile the children of a new VNode with the children of an old VNode by
  817. * traversing the two collections of children, identifying nodes that are
  818. * conserved or changed, calling out to `patch` to make any necessary
  819. * updates to the DOM, and rearranging DOM nodes as needed.
  820. *
  821. * The algorithm for reconciling children works by analyzing two 'windows' onto
  822. * the two arrays of children (`oldCh` and `newCh`). We keep track of the
  823. * 'windows' by storing start and end indices and references to the
  824. * corresponding array entries. Initially the two 'windows' are basically equal
  825. * to the entire array, but we progressively narrow the windows until there are
  826. * no children left to update by doing the following:
  827. *
  828. * 1. Skip any `null` entries at the beginning or end of the two arrays, so
  829. * that if we have an initial array like the following we'll end up dealing
  830. * only with a window bounded by the highlighted elements:
  831. *
  832. * [null, null, VNode1 , ... , VNode2, null, null]
  833. * ^^^^^^ ^^^^^^
  834. *
  835. * 2. Check to see if the elements at the head and tail positions are equal
  836. * across the windows. This will basically detect elements which haven't
  837. * been added, removed, or changed position, i.e. if you had the following
  838. * VNode elements (represented as HTML):
  839. *
  840. * oldVNode: `<div><p><span>HEY</span></p></div>`
  841. * newVNode: `<div><p><span>THERE</span></p></div>`
  842. *
  843. * Then when comparing the children of the `<div>` tag we check the equality
  844. * of the VNodes corresponding to the `<p>` tags and, since they are the
  845. * same tag in the same position, we'd be able to avoid completely
  846. * re-rendering the subtree under them with a new DOM element and would just
  847. * call out to `patch` to handle reconciling their children and so on.
  848. *
  849. * 3. Check, for both windows, to see if the element at the beginning of the
  850. * window corresponds to the element at the end of the other window. This is
  851. * a heuristic which will let us identify _some_ situations in which
  852. * elements have changed position, for instance it _should_ detect that the
  853. * children nodes themselves have not changed but merely moved in the
  854. * following example:
  855. *
  856. * oldVNode: `<div><element-one /><element-two /></div>`
  857. * newVNode: `<div><element-two /><element-one /></div>`
  858. *
  859. * If we find cases like this then we also need to move the concrete DOM
  860. * elements corresponding to the moved children to write the re-order to the
  861. * DOM.
  862. *
  863. * 4. Finally, if VNodes have the `key` attribute set on them we check for any
  864. * nodes in the old children which have the same key as the first element in
  865. * our window on the new children. If we find such a node we handle calling
  866. * out to `patch`, moving relevant DOM nodes, and so on, in accordance with
  867. * what we find.
  868. *
  869. * Finally, once we've narrowed our 'windows' to the point that either of them
  870. * collapse (i.e. they have length 0) we then handle any remaining VNode
  871. * insertion or deletion that needs to happen to get a DOM state that correctly
  872. * reflects the new child VNodes. If, for instance, after our window on the old
  873. * children has collapsed we still have more nodes on the new children that
  874. * we haven't dealt with yet then we need to add them, or if the new children
  875. * collapse but we still have unhandled _old_ children then we need to make
  876. * sure the corresponding DOM nodes are removed.
  877. *
  878. * @param parentElm the node into which the parent VNode is rendered
  879. * @param oldCh the old children of the parent node
  880. * @param newVNode the new VNode which will replace the parent
  881. * @param newCh the new children of the parent node
  882. */
  883. const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
  884. let oldStartIdx = 0;
  885. let newStartIdx = 0;
  886. let idxInOld = 0;
  887. let i = 0;
  888. let oldEndIdx = oldCh.length - 1;
  889. let oldStartVnode = oldCh[0];
  890. let oldEndVnode = oldCh[oldEndIdx];
  891. let newEndIdx = newCh.length - 1;
  892. let newStartVnode = newCh[0];
  893. let newEndVnode = newCh[newEndIdx];
  894. let node;
  895. let elmToMove;
  896. while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
  897. if (oldStartVnode == null) {
  898. // VNode might have been moved left
  899. oldStartVnode = oldCh[++oldStartIdx];
  900. }
  901. else if (oldEndVnode == null) {
  902. oldEndVnode = oldCh[--oldEndIdx];
  903. }
  904. else if (newStartVnode == null) {
  905. newStartVnode = newCh[++newStartIdx];
  906. }
  907. else if (newEndVnode == null) {
  908. newEndVnode = newCh[--newEndIdx];
  909. }
  910. else if (isSameVnode(oldStartVnode, newStartVnode)) {
  911. // if the start nodes are the same then we should patch the new VNode
  912. // onto the old one, and increment our `newStartIdx` and `oldStartIdx`
  913. // indices to reflect that. We don't need to move any DOM Nodes around
  914. // since things are matched up in order.
  915. patch(oldStartVnode, newStartVnode);
  916. oldStartVnode = oldCh[++oldStartIdx];
  917. newStartVnode = newCh[++newStartIdx];
  918. }
  919. else if (isSameVnode(oldEndVnode, newEndVnode)) {
  920. // likewise, if the end nodes are the same we patch new onto old and
  921. // decrement our end indices, and also likewise in this case we don't
  922. // need to move any DOM Nodes.
  923. patch(oldEndVnode, newEndVnode);
  924. oldEndVnode = oldCh[--oldEndIdx];
  925. newEndVnode = newCh[--newEndIdx];
  926. }
  927. else if (isSameVnode(oldStartVnode, newEndVnode)) {
  928. patch(oldStartVnode, newEndVnode);
  929. // We need to move the element for `oldStartVnode` into a position which
  930. // will be appropriate for `newEndVnode`. For this we can use
  931. // `.insertBefore` and `oldEndVnode.$elm$.nextSibling`. If there is a
  932. // sibling for `oldEndVnode.$elm$` then we want to move the DOM node for
  933. // `oldStartVnode` between `oldEndVnode` and it's sibling, like so:
  934. //
  935. // <old-start-node />
  936. // <some-intervening-node />
  937. // <old-end-node />
  938. // <!-- -> <-- `oldStartVnode.$elm$` should be inserted here
  939. // <next-sibling />
  940. //
  941. // If instead `oldEndVnode.$elm$` has no sibling then we just want to put
  942. // the node for `oldStartVnode` at the end of the children of
  943. // `parentElm`. Luckily, `Node.nextSibling` will return `null` if there
  944. // aren't any siblings, and passing `null` to `Node.insertBefore` will
  945. // append it to the children of the parent element.
  946. parentElm.insertBefore(oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
  947. oldStartVnode = oldCh[++oldStartIdx];
  948. newEndVnode = newCh[--newEndIdx];
  949. }
  950. else if (isSameVnode(oldEndVnode, newStartVnode)) {
  951. patch(oldEndVnode, newStartVnode);
  952. // We've already checked above if `oldStartVnode` and `newStartVnode` are
  953. // the same node, so since we're here we know that they are not. Thus we
  954. // can move the element for `oldEndVnode` _before_ the element for
  955. // `oldStartVnode`, leaving `oldStartVnode` to be reconciled in the
  956. // future.
  957. parentElm.insertBefore(oldEndVnode.$elm$, oldStartVnode.$elm$);
  958. oldEndVnode = oldCh[--oldEndIdx];
  959. newStartVnode = newCh[++newStartIdx];
  960. }
  961. else {
  962. // Here we do some checks to match up old and new nodes based on the
  963. // `$key$` attribute, which is set by putting a `key="my-key"` attribute
  964. // in the JSX for a DOM element in the implementation of a Stencil
  965. // component.
  966. //
  967. // First we check to see if there are any nodes in the array of old
  968. // children which have the same key as the first node in the new
  969. // children.
  970. idxInOld = -1;
  971. {
  972. for (i = oldStartIdx; i <= oldEndIdx; ++i) {
  973. if (oldCh[i] && oldCh[i].$key$ !== null && oldCh[i].$key$ === newStartVnode.$key$) {
  974. idxInOld = i;
  975. break;
  976. }
  977. }
  978. }
  979. if (idxInOld >= 0) {
  980. // We found a node in the old children which matches up with the first
  981. // node in the new children! So let's deal with that
  982. elmToMove = oldCh[idxInOld];
  983. if (elmToMove.$tag$ !== newStartVnode.$tag$) {
  984. // the tag doesn't match so we'll need a new DOM element
  985. node = createElm(oldCh && oldCh[newStartIdx], newVNode, idxInOld);
  986. }
  987. else {
  988. patch(elmToMove, newStartVnode);
  989. // invalidate the matching old node so that we won't try to update it
  990. // again later on
  991. oldCh[idxInOld] = undefined;
  992. node = elmToMove.$elm$;
  993. }
  994. newStartVnode = newCh[++newStartIdx];
  995. }
  996. else {
  997. // We either didn't find an element in the old children that matches
  998. // the key of the first new child OR the build is not using `key`
  999. // attributes at all. In either case we need to create a new element
  1000. // for the new node.
  1001. node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx);
  1002. newStartVnode = newCh[++newStartIdx];
  1003. }
  1004. if (node) {
  1005. // if we created a new node then handle inserting it to the DOM
  1006. {
  1007. oldStartVnode.$elm$.parentNode.insertBefore(node, oldStartVnode.$elm$);
  1008. }
  1009. }
  1010. }
  1011. }
  1012. if (oldStartIdx > oldEndIdx) {
  1013. // we have some more new nodes to add which don't match up with old nodes
  1014. addVnodes(parentElm, newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$, newVNode, newCh, newStartIdx, newEndIdx);
  1015. }
  1016. else if (newStartIdx > newEndIdx) {
  1017. // there are nodes in the `oldCh` array which no longer correspond to nodes
  1018. // in the new array, so lets remove them (which entails cleaning up the
  1019. // relevant DOM nodes)
  1020. removeVnodes(oldCh, oldStartIdx, oldEndIdx);
  1021. }
  1022. };
  1023. /**
  1024. * Compare two VNodes to determine if they are the same
  1025. *
  1026. * **NB**: This function is an equality _heuristic_ based on the available
  1027. * information set on the two VNodes and can be misleading under certain
  1028. * circumstances. In particular, if the two nodes do not have `key` attrs
  1029. * (available under `$key$` on VNodes) then the function falls back on merely
  1030. * checking that they have the same tag.
  1031. *
  1032. * So, in other words, if `key` attrs are not set on VNodes which may be
  1033. * changing order within a `children` array or something along those lines then
  1034. * we could obtain a false positive and then have to do needless re-rendering.
  1035. *
  1036. * @param leftVNode the first VNode to check
  1037. * @param rightVNode the second VNode to check
  1038. * @returns whether they're equal or not
  1039. */
  1040. const isSameVnode = (leftVNode, rightVNode) => {
  1041. // compare if two vnode to see if they're "technically" the same
  1042. // need to have the same element tag, and same key to be the same
  1043. if (leftVNode.$tag$ === rightVNode.$tag$) {
  1044. // this will be set if components in the build have `key` attrs set on them
  1045. {
  1046. return leftVNode.$key$ === rightVNode.$key$;
  1047. }
  1048. }
  1049. return false;
  1050. };
  1051. /**
  1052. * Handle reconciling an outdated VNode with a new one which corresponds to
  1053. * it. This function handles flushing updates to the DOM and reconciling the
  1054. * children of the two nodes (if any).
  1055. *
  1056. * @param oldVNode an old VNode whose DOM element and children we want to update
  1057. * @param newVNode a new VNode representing an updated version of the old one
  1058. */
  1059. const patch = (oldVNode, newVNode) => {
  1060. const elm = (newVNode.$elm$ = oldVNode.$elm$);
  1061. const oldChildren = oldVNode.$children$;
  1062. const newChildren = newVNode.$children$;
  1063. const tag = newVNode.$tag$;
  1064. const text = newVNode.$text$;
  1065. if (text === null) {
  1066. {
  1067. // test if we're rendering an svg element, or still rendering nodes inside of one
  1068. // only add this to the when the compiler sees we're using an svg somewhere
  1069. isSvgMode = tag === 'svg' ? true : tag === 'foreignObject' ? false : isSvgMode;
  1070. }
  1071. {
  1072. if (tag === 'slot')
  1073. ;
  1074. else {
  1075. // either this is the first render of an element OR it's an update
  1076. // AND we already know it's possible it could have changed
  1077. // this updates the element's css classes, attrs, props, listeners, etc.
  1078. updateElement(oldVNode, newVNode, isSvgMode);
  1079. }
  1080. }
  1081. if (oldChildren !== null && newChildren !== null) {
  1082. // looks like there's child vnodes for both the old and new vnodes
  1083. // so we need to call `updateChildren` to reconcile them
  1084. updateChildren(elm, oldChildren, newVNode, newChildren);
  1085. }
  1086. else if (newChildren !== null) {
  1087. // no old child vnodes, but there are new child vnodes to add
  1088. if (oldVNode.$text$ !== null) {
  1089. // the old vnode was text, so be sure to clear it out
  1090. elm.textContent = '';
  1091. }
  1092. // add the new vnode children
  1093. addVnodes(elm, null, newVNode, newChildren, 0, newChildren.length - 1);
  1094. }
  1095. else if (oldChildren !== null) {
  1096. // no new child vnodes, but there are old child vnodes to remove
  1097. removeVnodes(oldChildren, 0, oldChildren.length - 1);
  1098. }
  1099. if (isSvgMode && tag === 'svg') {
  1100. isSvgMode = false;
  1101. }
  1102. }
  1103. else if (oldVNode.$text$ !== text) {
  1104. // update the text content for the text only vnode
  1105. // and also only if the text is different than before
  1106. elm.data = text;
  1107. }
  1108. };
  1109. const callNodeRefs = (vNode) => {
  1110. {
  1111. vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(null);
  1112. vNode.$children$ && vNode.$children$.map(callNodeRefs);
  1113. }
  1114. };
  1115. const renderVdom = (hostRef, renderFnResults) => {
  1116. const hostElm = hostRef.$hostElement$;
  1117. const cmpMeta = hostRef.$cmpMeta$;
  1118. const oldVNode = hostRef.$vnode$ || newVNode(null, null);
  1119. const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
  1120. hostTagName = hostElm.tagName;
  1121. if (cmpMeta.$attrsToReflect$) {
  1122. rootVnode.$attrs$ = rootVnode.$attrs$ || {};
  1123. cmpMeta.$attrsToReflect$.map(([propName, attribute]) => (rootVnode.$attrs$[attribute] = hostElm[propName]));
  1124. }
  1125. rootVnode.$tag$ = null;
  1126. rootVnode.$flags$ |= 4 /* VNODE_FLAGS.isHost */;
  1127. hostRef.$vnode$ = rootVnode;
  1128. rootVnode.$elm$ = oldVNode.$elm$ = (hostElm.shadowRoot || hostElm );
  1129. {
  1130. scopeId = hostElm['s-sc'];
  1131. }
  1132. // synchronous patch
  1133. patch(oldVNode, rootVnode);
  1134. };
  1135. const attachToAncestor = (hostRef, ancestorComponent) => {
  1136. if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
  1137. ancestorComponent['s-p'].push(new Promise((r) => (hostRef.$onRenderResolve$ = r)));
  1138. }
  1139. };
  1140. const scheduleUpdate = (hostRef, isInitialLoad) => {
  1141. {
  1142. hostRef.$flags$ |= 16 /* HOST_FLAGS.isQueuedForUpdate */;
  1143. }
  1144. if (hostRef.$flags$ & 4 /* HOST_FLAGS.isWaitingForChildren */) {
  1145. hostRef.$flags$ |= 512 /* HOST_FLAGS.needsRerender */;
  1146. return;
  1147. }
  1148. attachToAncestor(hostRef, hostRef.$ancestorComponent$);
  1149. // there is no ancestor component or the ancestor component
  1150. // has already fired off its lifecycle update then
  1151. // fire off the initial update
  1152. const dispatch = () => dispatchHooks(hostRef, isInitialLoad);
  1153. return writeTask(dispatch) ;
  1154. };
  1155. const dispatchHooks = (hostRef, isInitialLoad) => {
  1156. const endSchedule = createTime('scheduleUpdate', hostRef.$cmpMeta$.$tagName$);
  1157. const instance = hostRef.$lazyInstance$ ;
  1158. let promise;
  1159. if (isInitialLoad) {
  1160. {
  1161. hostRef.$flags$ |= 256 /* HOST_FLAGS.isListenReady */;
  1162. if (hostRef.$queuedListeners$) {
  1163. hostRef.$queuedListeners$.map(([methodName, event]) => safeCall(instance, methodName, event));
  1164. hostRef.$queuedListeners$ = null;
  1165. }
  1166. }
  1167. {
  1168. promise = safeCall(instance, 'componentWillLoad');
  1169. }
  1170. }
  1171. {
  1172. promise = then(promise, () => safeCall(instance, 'componentWillRender'));
  1173. }
  1174. endSchedule();
  1175. return then(promise, () => updateComponent(hostRef, instance, isInitialLoad));
  1176. };
  1177. const updateComponent = async (hostRef, instance, isInitialLoad) => {
  1178. // updateComponent
  1179. const elm = hostRef.$hostElement$;
  1180. const endUpdate = createTime('update', hostRef.$cmpMeta$.$tagName$);
  1181. const rc = elm['s-rc'];
  1182. if (isInitialLoad) {
  1183. // DOM WRITE!
  1184. attachStyles(hostRef);
  1185. }
  1186. const endRender = createTime('render', hostRef.$cmpMeta$.$tagName$);
  1187. {
  1188. callRender(hostRef, instance);
  1189. }
  1190. if (rc) {
  1191. // ok, so turns out there are some child host elements
  1192. // waiting on this parent element to load
  1193. // let's fire off all update callbacks waiting
  1194. rc.map((cb) => cb());
  1195. elm['s-rc'] = undefined;
  1196. }
  1197. endRender();
  1198. endUpdate();
  1199. {
  1200. const childrenPromises = elm['s-p'];
  1201. const postUpdate = () => postUpdateComponent(hostRef);
  1202. if (childrenPromises.length === 0) {
  1203. postUpdate();
  1204. }
  1205. else {
  1206. Promise.all(childrenPromises).then(postUpdate);
  1207. hostRef.$flags$ |= 4 /* HOST_FLAGS.isWaitingForChildren */;
  1208. childrenPromises.length = 0;
  1209. }
  1210. }
  1211. };
  1212. const callRender = (hostRef, instance, elm) => {
  1213. try {
  1214. instance = instance.render() ;
  1215. {
  1216. hostRef.$flags$ &= ~16 /* HOST_FLAGS.isQueuedForUpdate */;
  1217. }
  1218. {
  1219. hostRef.$flags$ |= 2 /* HOST_FLAGS.hasRendered */;
  1220. }
  1221. {
  1222. {
  1223. // looks like we've got child nodes to render into this host element
  1224. // or we need to update the css class/attrs on the host element
  1225. // DOM WRITE!
  1226. {
  1227. renderVdom(hostRef, instance);
  1228. }
  1229. }
  1230. }
  1231. }
  1232. catch (e) {
  1233. consoleError(e, hostRef.$hostElement$);
  1234. }
  1235. return null;
  1236. };
  1237. const postUpdateComponent = (hostRef) => {
  1238. const tagName = hostRef.$cmpMeta$.$tagName$;
  1239. const elm = hostRef.$hostElement$;
  1240. const endPostUpdate = createTime('postUpdate', tagName);
  1241. const instance = hostRef.$lazyInstance$ ;
  1242. const ancestorComponent = hostRef.$ancestorComponent$;
  1243. {
  1244. safeCall(instance, 'componentDidRender');
  1245. }
  1246. if (!(hostRef.$flags$ & 64 /* HOST_FLAGS.hasLoadedComponent */)) {
  1247. hostRef.$flags$ |= 64 /* HOST_FLAGS.hasLoadedComponent */;
  1248. {
  1249. // DOM WRITE!
  1250. addHydratedFlag(elm);
  1251. }
  1252. {
  1253. safeCall(instance, 'componentDidLoad');
  1254. }
  1255. endPostUpdate();
  1256. {
  1257. hostRef.$onReadyResolve$(elm);
  1258. if (!ancestorComponent) {
  1259. appDidLoad();
  1260. }
  1261. }
  1262. }
  1263. else {
  1264. endPostUpdate();
  1265. }
  1266. {
  1267. hostRef.$onInstanceResolve$(elm);
  1268. }
  1269. // load events fire from bottom to top
  1270. // the deepest elements load first then bubbles up
  1271. {
  1272. if (hostRef.$onRenderResolve$) {
  1273. hostRef.$onRenderResolve$();
  1274. hostRef.$onRenderResolve$ = undefined;
  1275. }
  1276. if (hostRef.$flags$ & 512 /* HOST_FLAGS.needsRerender */) {
  1277. nextTick(() => scheduleUpdate(hostRef, false));
  1278. }
  1279. hostRef.$flags$ &= ~(4 /* HOST_FLAGS.isWaitingForChildren */ | 512 /* HOST_FLAGS.needsRerender */);
  1280. }
  1281. // ( •_•)
  1282. // ( •_•)>⌐■-■
  1283. // (⌐■_■)
  1284. };
  1285. const forceUpdate = (ref) => {
  1286. {
  1287. const hostRef = getHostRef(ref);
  1288. const isConnected = hostRef.$hostElement$.isConnected;
  1289. if (isConnected &&
  1290. (hostRef.$flags$ & (2 /* HOST_FLAGS.hasRendered */ | 16 /* HOST_FLAGS.isQueuedForUpdate */)) === 2 /* HOST_FLAGS.hasRendered */) {
  1291. scheduleUpdate(hostRef, false);
  1292. }
  1293. // Returns "true" when the forced update was successfully scheduled
  1294. return isConnected;
  1295. }
  1296. };
  1297. const appDidLoad = (who) => {
  1298. // on appload
  1299. // we have finish the first big initial render
  1300. {
  1301. addHydratedFlag(doc.documentElement);
  1302. }
  1303. nextTick(() => emitEvent(win, 'appload', { detail: { namespace: NAMESPACE } }));
  1304. };
  1305. const safeCall = (instance, method, arg) => {
  1306. if (instance && instance[method]) {
  1307. try {
  1308. return instance[method](arg);
  1309. }
  1310. catch (e) {
  1311. consoleError(e);
  1312. }
  1313. }
  1314. return undefined;
  1315. };
  1316. const then = (promise, thenFn) => {
  1317. return promise && promise.then ? promise.then(thenFn) : thenFn();
  1318. };
  1319. const addHydratedFlag = (elm) => elm.setAttribute('calcite-hydrated', '')
  1320. ;
  1321. const getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
  1322. const setValue = (ref, propName, newVal, cmpMeta) => {
  1323. // check our new property value against our internal value
  1324. const hostRef = getHostRef(ref);
  1325. const elm = hostRef.$hostElement$ ;
  1326. const oldVal = hostRef.$instanceValues$.get(propName);
  1327. const flags = hostRef.$flags$;
  1328. const instance = hostRef.$lazyInstance$ ;
  1329. newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
  1330. // explicitly check for NaN on both sides, as `NaN === NaN` is always false
  1331. const areBothNaN = Number.isNaN(oldVal) && Number.isNaN(newVal);
  1332. const didValueChange = newVal !== oldVal && !areBothNaN;
  1333. if ((!(flags & 8 /* HOST_FLAGS.isConstructingInstance */) || oldVal === undefined) && didValueChange) {
  1334. // gadzooks! the property's value has changed!!
  1335. // set our new value!
  1336. hostRef.$instanceValues$.set(propName, newVal);
  1337. if (instance) {
  1338. // get an array of method names of watch functions to call
  1339. if (cmpMeta.$watchers$ && flags & 128 /* HOST_FLAGS.isWatchReady */) {
  1340. const watchMethods = cmpMeta.$watchers$[propName];
  1341. if (watchMethods) {
  1342. // this instance is watching for when this property changed
  1343. watchMethods.map((watchMethodName) => {
  1344. try {
  1345. // fire off each of the watch methods that are watching this property
  1346. instance[watchMethodName](newVal, oldVal, propName);
  1347. }
  1348. catch (e) {
  1349. consoleError(e, elm);
  1350. }
  1351. });
  1352. }
  1353. }
  1354. if ((flags & (2 /* HOST_FLAGS.hasRendered */ | 16 /* HOST_FLAGS.isQueuedForUpdate */)) === 2 /* HOST_FLAGS.hasRendered */) {
  1355. if (instance.componentShouldUpdate) {
  1356. if (instance.componentShouldUpdate(newVal, oldVal, propName) === false) {
  1357. return;
  1358. }
  1359. }
  1360. // looks like this value actually changed, so we've got work to do!
  1361. // but only if we've already rendered, otherwise just chill out
  1362. // queue that we need to do an update, but don't worry about queuing
  1363. // up millions cuz this function ensures it only runs once
  1364. scheduleUpdate(hostRef, false);
  1365. }
  1366. }
  1367. }
  1368. };
  1369. /**
  1370. * Attach a series of runtime constructs to a compiled Stencil component
  1371. * constructor, including getters and setters for the `@Prop` and `@State`
  1372. * decorators, callbacks for when attributes change, and so on.
  1373. *
  1374. * @param Cstr the constructor for a component that we need to process
  1375. * @param cmpMeta metadata collected previously about the component
  1376. * @param flags a number used to store a series of bit flags
  1377. * @returns a reference to the same constructor passed in (but now mutated)
  1378. */
  1379. const proxyComponent = (Cstr, cmpMeta, flags) => {
  1380. if (cmpMeta.$members$) {
  1381. if (Cstr.watchers) {
  1382. cmpMeta.$watchers$ = Cstr.watchers;
  1383. }
  1384. // It's better to have a const than two Object.entries()
  1385. const members = Object.entries(cmpMeta.$members$);
  1386. const prototype = Cstr.prototype;
  1387. members.map(([memberName, [memberFlags]]) => {
  1388. if ((memberFlags & 31 /* MEMBER_FLAGS.Prop */ ||
  1389. ((flags & 2 /* PROXY_FLAGS.proxyState */) && memberFlags & 32 /* MEMBER_FLAGS.State */))) {
  1390. // proxyComponent - prop
  1391. Object.defineProperty(prototype, memberName, {
  1392. get() {
  1393. // proxyComponent, get value
  1394. return getValue(this, memberName);
  1395. },
  1396. set(newValue) {
  1397. // proxyComponent, set value
  1398. setValue(this, memberName, newValue, cmpMeta);
  1399. },
  1400. configurable: true,
  1401. enumerable: true,
  1402. });
  1403. }
  1404. else if (flags & 1 /* PROXY_FLAGS.isElementConstructor */ &&
  1405. memberFlags & 64 /* MEMBER_FLAGS.Method */) {
  1406. // proxyComponent - method
  1407. Object.defineProperty(prototype, memberName, {
  1408. value(...args) {
  1409. const ref = getHostRef(this);
  1410. return ref.$onInstancePromise$.then(() => ref.$lazyInstance$[memberName](...args));
  1411. },
  1412. });
  1413. }
  1414. });
  1415. if ((flags & 1 /* PROXY_FLAGS.isElementConstructor */)) {
  1416. const attrNameToPropName = new Map();
  1417. prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
  1418. plt.jmp(() => {
  1419. const propName = attrNameToPropName.get(attrName);
  1420. // In a web component lifecycle the attributeChangedCallback runs prior to connectedCallback
  1421. // in the case where an attribute was set inline.
  1422. // ```html
  1423. // <my-component some-attribute="some-value"></my-component>
  1424. // ```
  1425. //
  1426. // There is an edge case where a developer sets the attribute inline on a custom element and then
  1427. // programmatically changes it before it has been upgraded as shown below:
  1428. //
  1429. // ```html
  1430. // <!-- this component has _not_ been upgraded yet -->
  1431. // <my-component id="test" some-attribute="some-value"></my-component>
  1432. // <script>
  1433. // // grab non-upgraded component
  1434. // el = document.querySelector("#test");
  1435. // el.someAttribute = "another-value";
  1436. // // upgrade component
  1437. // customElements.define('my-component', MyComponent);
  1438. // </script>
  1439. // ```
  1440. // In this case if we do not unshadow here and use the value of the shadowing property, attributeChangedCallback
  1441. // will be called with `newValue = "some-value"` and will set the shadowed property (this.someAttribute = "another-value")
  1442. // to the value that was set inline i.e. "some-value" from above example. When
  1443. // the connectedCallback attempts to unshadow it will use "some-value" as the initial value rather than "another-value"
  1444. //
  1445. // The case where the attribute was NOT set inline but was not set programmatically shall be handled/unshadowed
  1446. // by connectedCallback as this attributeChangedCallback will not fire.
  1447. //
  1448. // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
  1449. //
  1450. // TODO(STENCIL-16) we should think about whether or not we actually want to be reflecting the attributes to
  1451. // properties here given that this goes against best practices outlined here
  1452. // https://developers.google.com/web/fundamentals/web-components/best-practices#avoid-reentrancy
  1453. if (this.hasOwnProperty(propName)) {
  1454. newValue = this[propName];
  1455. delete this[propName];
  1456. }
  1457. else if (prototype.hasOwnProperty(propName) &&
  1458. typeof this[propName] === 'number' &&
  1459. this[propName] == newValue) {
  1460. // if the propName exists on the prototype of `Cstr`, this update may be a result of Stencil using native
  1461. // APIs to reflect props as attributes. Calls to `setAttribute(someElement, propName)` will result in
  1462. // `propName` to be converted to a `DOMString`, which may not be what we want for other primitive props.
  1463. return;
  1464. }
  1465. this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
  1466. });
  1467. };
  1468. // create an array of attributes to observe
  1469. // and also create a map of html attribute name to js property name
  1470. Cstr.observedAttributes = members
  1471. .filter(([_, m]) => m[0] & 15 /* MEMBER_FLAGS.HasAttribute */) // filter to only keep props that should match attributes
  1472. .map(([propName, m]) => {
  1473. const attrName = m[1] || propName;
  1474. attrNameToPropName.set(attrName, propName);
  1475. if (m[0] & 512 /* MEMBER_FLAGS.ReflectAttr */) {
  1476. cmpMeta.$attrsToReflect$.push([propName, attrName]);
  1477. }
  1478. return attrName;
  1479. });
  1480. }
  1481. }
  1482. return Cstr;
  1483. };
  1484. const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
  1485. // initializeComponent
  1486. if ((hostRef.$flags$ & 32 /* HOST_FLAGS.hasInitializedComponent */) === 0) {
  1487. {
  1488. // we haven't initialized this element yet
  1489. hostRef.$flags$ |= 32 /* HOST_FLAGS.hasInitializedComponent */;
  1490. // lazy loaded components
  1491. // request the component's implementation to be
  1492. // wired up with the host element
  1493. Cstr = loadModule(cmpMeta);
  1494. if (Cstr.then) {
  1495. // Await creates a micro-task avoid if possible
  1496. const endLoad = uniqueTime();
  1497. Cstr = await Cstr;
  1498. endLoad();
  1499. }
  1500. if (!Cstr.isProxied) {
  1501. // we've never proxied this Constructor before
  1502. // let's add the getters/setters to its prototype before
  1503. // the first time we create an instance of the implementation
  1504. {
  1505. cmpMeta.$watchers$ = Cstr.watchers;
  1506. }
  1507. proxyComponent(Cstr, cmpMeta, 2 /* PROXY_FLAGS.proxyState */);
  1508. Cstr.isProxied = true;
  1509. }
  1510. const endNewInstance = createTime('createInstance', cmpMeta.$tagName$);
  1511. // ok, time to construct the instance
  1512. // but let's keep track of when we start and stop
  1513. // so that the getters/setters don't incorrectly step on data
  1514. {
  1515. hostRef.$flags$ |= 8 /* HOST_FLAGS.isConstructingInstance */;
  1516. }
  1517. // construct the lazy-loaded component implementation
  1518. // passing the hostRef is very important during
  1519. // construction in order to directly wire together the
  1520. // host element and the lazy-loaded instance
  1521. try {
  1522. new Cstr(hostRef);
  1523. }
  1524. catch (e) {
  1525. consoleError(e);
  1526. }
  1527. {
  1528. hostRef.$flags$ &= ~8 /* HOST_FLAGS.isConstructingInstance */;
  1529. }
  1530. {
  1531. hostRef.$flags$ |= 128 /* HOST_FLAGS.isWatchReady */;
  1532. }
  1533. endNewInstance();
  1534. fireConnectedCallback(hostRef.$lazyInstance$);
  1535. }
  1536. if (Cstr.style) {
  1537. // this component has styles but we haven't registered them yet
  1538. let style = Cstr.style;
  1539. const scopeId = getScopeId(cmpMeta);
  1540. if (!styles.has(scopeId)) {
  1541. const endRegisterStyles = createTime('registerStyles', cmpMeta.$tagName$);
  1542. registerStyle(scopeId, style, !!(cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */));
  1543. endRegisterStyles();
  1544. }
  1545. }
  1546. }
  1547. // we've successfully created a lazy instance
  1548. const ancestorComponent = hostRef.$ancestorComponent$;
  1549. const schedule = () => scheduleUpdate(hostRef, true);
  1550. if (ancestorComponent && ancestorComponent['s-rc']) {
  1551. // this is the initial load and this component it has an ancestor component
  1552. // but the ancestor component has NOT fired its will update lifecycle yet
  1553. // so let's just cool our jets and wait for the ancestor to continue first
  1554. // this will get fired off when the ancestor component
  1555. // finally gets around to rendering its lazy self
  1556. // fire off the initial update
  1557. ancestorComponent['s-rc'].push(schedule);
  1558. }
  1559. else {
  1560. schedule();
  1561. }
  1562. };
  1563. const fireConnectedCallback = (instance) => {
  1564. {
  1565. safeCall(instance, 'connectedCallback');
  1566. }
  1567. };
  1568. const connectedCallback = (elm) => {
  1569. if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
  1570. const hostRef = getHostRef(elm);
  1571. const cmpMeta = hostRef.$cmpMeta$;
  1572. const endConnected = createTime('connectedCallback', cmpMeta.$tagName$);
  1573. if (!(hostRef.$flags$ & 1 /* HOST_FLAGS.hasConnected */)) {
  1574. // first time this component has connected
  1575. hostRef.$flags$ |= 1 /* HOST_FLAGS.hasConnected */;
  1576. let hostId;
  1577. {
  1578. hostId = elm.getAttribute(HYDRATE_ID);
  1579. if (hostId) {
  1580. if (cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */) {
  1581. const scopeId = addStyle(elm.shadowRoot, cmpMeta);
  1582. elm.classList.remove(scopeId + '-h', scopeId + '-s');
  1583. }
  1584. initializeClientHydrate(elm, cmpMeta.$tagName$, hostId, hostRef);
  1585. }
  1586. }
  1587. {
  1588. // find the first ancestor component (if there is one) and register
  1589. // this component as one of the actively loading child components for its ancestor
  1590. let ancestorComponent = elm;
  1591. while ((ancestorComponent = ancestorComponent.parentNode || ancestorComponent.host)) {
  1592. // climb up the ancestors looking for the first
  1593. // component that hasn't finished its lifecycle update yet
  1594. if ((ancestorComponent.nodeType === 1 /* NODE_TYPE.ElementNode */ &&
  1595. ancestorComponent.hasAttribute('s-id') &&
  1596. ancestorComponent['s-p']) ||
  1597. ancestorComponent['s-p']) {
  1598. // we found this components first ancestor component
  1599. // keep a reference to this component's ancestor component
  1600. attachToAncestor(hostRef, (hostRef.$ancestorComponent$ = ancestorComponent));
  1601. break;
  1602. }
  1603. }
  1604. }
  1605. // Lazy properties
  1606. // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
  1607. if (cmpMeta.$members$) {
  1608. Object.entries(cmpMeta.$members$).map(([memberName, [memberFlags]]) => {
  1609. if (memberFlags & 31 /* MEMBER_FLAGS.Prop */ && elm.hasOwnProperty(memberName)) {
  1610. const value = elm[memberName];
  1611. delete elm[memberName];
  1612. elm[memberName] = value;
  1613. }
  1614. });
  1615. }
  1616. {
  1617. initializeComponent(elm, hostRef, cmpMeta);
  1618. }
  1619. }
  1620. else {
  1621. // not the first time this has connected
  1622. // reattach any event listeners to the host
  1623. // since they would have been removed when disconnected
  1624. addHostEventListeners(elm, hostRef, cmpMeta.$listeners$);
  1625. // fire off connectedCallback() on component instance
  1626. fireConnectedCallback(hostRef.$lazyInstance$);
  1627. }
  1628. endConnected();
  1629. }
  1630. };
  1631. const disconnectedCallback = (elm) => {
  1632. if ((plt.$flags$ & 1 /* PLATFORM_FLAGS.isTmpDisconnected */) === 0) {
  1633. const hostRef = getHostRef(elm);
  1634. const instance = hostRef.$lazyInstance$ ;
  1635. {
  1636. if (hostRef.$rmListeners$) {
  1637. hostRef.$rmListeners$.map((rmListener) => rmListener());
  1638. hostRef.$rmListeners$ = undefined;
  1639. }
  1640. }
  1641. {
  1642. safeCall(instance, 'disconnectedCallback');
  1643. }
  1644. }
  1645. };
  1646. const bootstrapLazy = (lazyBundles, options = {}) => {
  1647. const endBootstrap = createTime();
  1648. const cmpTags = [];
  1649. const exclude = options.exclude || [];
  1650. const customElements = win.customElements;
  1651. const head = doc.head;
  1652. const metaCharset = /*@__PURE__*/ head.querySelector('meta[charset]');
  1653. const visibilityStyle = /*@__PURE__*/ doc.createElement('style');
  1654. const deferredConnectedCallbacks = [];
  1655. const styles = /*@__PURE__*/ doc.querySelectorAll(`[${HYDRATED_STYLE_ID}]`);
  1656. let appLoadFallback;
  1657. let isBootstrapping = true;
  1658. let i = 0;
  1659. Object.assign(plt, options);
  1660. plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
  1661. {
  1662. // If the app is already hydrated there is not point to disable the
  1663. // async queue. This will improve the first input delay
  1664. plt.$flags$ |= 2 /* PLATFORM_FLAGS.appLoaded */;
  1665. }
  1666. {
  1667. for (; i < styles.length; i++) {
  1668. registerStyle(styles[i].getAttribute(HYDRATED_STYLE_ID), convertScopedToShadow(styles[i].innerHTML), true);
  1669. }
  1670. }
  1671. lazyBundles.map((lazyBundle) => {
  1672. lazyBundle[1].map((compactMeta) => {
  1673. const cmpMeta = {
  1674. $flags$: compactMeta[0],
  1675. $tagName$: compactMeta[1],
  1676. $members$: compactMeta[2],
  1677. $listeners$: compactMeta[3],
  1678. };
  1679. {
  1680. cmpMeta.$members$ = compactMeta[2];
  1681. }
  1682. {
  1683. cmpMeta.$listeners$ = compactMeta[3];
  1684. }
  1685. {
  1686. cmpMeta.$attrsToReflect$ = [];
  1687. }
  1688. {
  1689. cmpMeta.$watchers$ = {};
  1690. }
  1691. const tagName = cmpMeta.$tagName$;
  1692. const HostElement = class extends HTMLElement {
  1693. // StencilLazyHost
  1694. constructor(self) {
  1695. // @ts-ignore
  1696. super(self);
  1697. self = this;
  1698. registerHost(self, cmpMeta);
  1699. if (cmpMeta.$flags$ & 1 /* CMP_FLAGS.shadowDomEncapsulation */) {
  1700. // this component is using shadow dom
  1701. // and this browser supports shadow dom
  1702. // add the read-only property "shadowRoot" to the host element
  1703. // adding the shadow root build conditionals to minimize runtime
  1704. {
  1705. {
  1706. self.attachShadow({ mode: 'open' });
  1707. }
  1708. }
  1709. }
  1710. }
  1711. connectedCallback() {
  1712. if (appLoadFallback) {
  1713. clearTimeout(appLoadFallback);
  1714. appLoadFallback = null;
  1715. }
  1716. if (isBootstrapping) {
  1717. // connectedCallback will be processed once all components have been registered
  1718. deferredConnectedCallbacks.push(this);
  1719. }
  1720. else {
  1721. plt.jmp(() => connectedCallback(this));
  1722. }
  1723. }
  1724. disconnectedCallback() {
  1725. plt.jmp(() => disconnectedCallback(this));
  1726. }
  1727. componentOnReady() {
  1728. return getHostRef(this).$onReadyPromise$;
  1729. }
  1730. };
  1731. cmpMeta.$lazyBundleId$ = lazyBundle[0];
  1732. if (!exclude.includes(tagName) && !customElements.get(tagName)) {
  1733. cmpTags.push(tagName);
  1734. customElements.define(tagName, proxyComponent(HostElement, cmpMeta, 1 /* PROXY_FLAGS.isElementConstructor */));
  1735. }
  1736. });
  1737. });
  1738. {
  1739. visibilityStyle.innerHTML = cmpTags + HYDRATED_CSS;
  1740. visibilityStyle.setAttribute('data-styles', '');
  1741. head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
  1742. }
  1743. // Process deferred connectedCallbacks now all components have been registered
  1744. isBootstrapping = false;
  1745. if (deferredConnectedCallbacks.length) {
  1746. deferredConnectedCallbacks.map((host) => host.connectedCallback());
  1747. }
  1748. else {
  1749. {
  1750. plt.jmp(() => (appLoadFallback = setTimeout(appDidLoad, 30)));
  1751. }
  1752. }
  1753. // Fallback appLoad event
  1754. endBootstrap();
  1755. };
  1756. const Fragment = (_, children) => children;
  1757. const addHostEventListeners = (elm, hostRef, listeners, attachParentListeners) => {
  1758. if (listeners) {
  1759. listeners.map(([flags, name, method]) => {
  1760. const target = getHostListenerTarget(elm, flags) ;
  1761. const handler = hostListenerProxy(hostRef, method);
  1762. const opts = hostListenerOpts(flags);
  1763. plt.ael(target, name, handler, opts);
  1764. (hostRef.$rmListeners$ = hostRef.$rmListeners$ || []).push(() => plt.rel(target, name, handler, opts));
  1765. });
  1766. }
  1767. };
  1768. const hostListenerProxy = (hostRef, methodName) => (ev) => {
  1769. try {
  1770. {
  1771. if (hostRef.$flags$ & 256 /* HOST_FLAGS.isListenReady */) {
  1772. // instance is ready, let's call it's member method for this event
  1773. hostRef.$lazyInstance$[methodName](ev);
  1774. }
  1775. else {
  1776. (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
  1777. }
  1778. }
  1779. }
  1780. catch (e) {
  1781. consoleError(e);
  1782. }
  1783. };
  1784. const getHostListenerTarget = (elm, flags) => {
  1785. if (flags & 4 /* LISTENER_FLAGS.TargetDocument */)
  1786. return doc;
  1787. if (flags & 8 /* LISTENER_FLAGS.TargetWindow */)
  1788. return win;
  1789. if (flags & 16 /* LISTENER_FLAGS.TargetBody */)
  1790. return doc.body;
  1791. return elm;
  1792. };
  1793. // prettier-ignore
  1794. const hostListenerOpts = (flags) => (flags & 2 /* LISTENER_FLAGS.Capture */) !== 0;
  1795. const hostRefs = /*@__PURE__*/ new WeakMap();
  1796. const getHostRef = (ref) => hostRefs.get(ref);
  1797. const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
  1798. const registerHost = (elm, cmpMeta) => {
  1799. const hostRef = {
  1800. $flags$: 0,
  1801. $hostElement$: elm,
  1802. $cmpMeta$: cmpMeta,
  1803. $instanceValues$: new Map(),
  1804. };
  1805. {
  1806. hostRef.$onInstancePromise$ = new Promise((r) => (hostRef.$onInstanceResolve$ = r));
  1807. }
  1808. {
  1809. hostRef.$onReadyPromise$ = new Promise((r) => (hostRef.$onReadyResolve$ = r));
  1810. elm['s-p'] = [];
  1811. elm['s-rc'] = [];
  1812. }
  1813. addHostEventListeners(elm, hostRef, cmpMeta.$listeners$);
  1814. return hostRefs.set(elm, hostRef);
  1815. };
  1816. const isMemberInElement = (elm, memberName) => memberName in elm;
  1817. const consoleError = (e, el) => (0, console.error)(e, el);
  1818. const cmpModules = /*@__PURE__*/ new Map();
  1819. const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
  1820. // loadModuleImport
  1821. const exportName = cmpMeta.$tagName$.replace(/-/g, '_');
  1822. const bundleId = cmpMeta.$lazyBundleId$;
  1823. const module = cmpModules.get(bundleId) ;
  1824. if (module) {
  1825. return module[exportName];
  1826. }
  1827. /*!__STENCIL_STATIC_IMPORT_SWITCH__*/
  1828. return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(
  1829. /* @vite-ignore */
  1830. /* webpackInclude: /\.entry\.js$/ */
  1831. /* webpackExclude: /\.system\.entry\.js$/ */
  1832. /* webpackMode: "lazy" */
  1833. `./${bundleId}.entry.js${''}`)); }).then((importedModule) => {
  1834. {
  1835. cmpModules.set(bundleId, importedModule);
  1836. }
  1837. return importedModule[exportName];
  1838. }, consoleError);
  1839. };
  1840. const styles = /*@__PURE__*/ new Map();
  1841. const win = typeof window !== 'undefined' ? window : {};
  1842. const doc = win.document || { head: {} };
  1843. const plt = {
  1844. $flags$: 0,
  1845. $resourcesUrl$: '',
  1846. jmp: (h) => h(),
  1847. raf: (h) => requestAnimationFrame(h),
  1848. ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
  1849. rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
  1850. ce: (eventName, opts) => new CustomEvent(eventName, opts),
  1851. };
  1852. const supportsShadow = true;
  1853. const promiseResolve = (v) => Promise.resolve(v);
  1854. const supportsConstructableStylesheets = /*@__PURE__*/ (() => {
  1855. try {
  1856. new CSSStyleSheet();
  1857. return typeof new CSSStyleSheet().replaceSync === 'function';
  1858. }
  1859. catch (e) { }
  1860. return false;
  1861. })()
  1862. ;
  1863. const queueDomReads = [];
  1864. const queueDomWrites = [];
  1865. const queueTask = (queue, write) => (cb) => {
  1866. queue.push(cb);
  1867. if (!queuePending) {
  1868. queuePending = true;
  1869. if (write && plt.$flags$ & 4 /* PLATFORM_FLAGS.queueSync */) {
  1870. nextTick(flush);
  1871. }
  1872. else {
  1873. plt.raf(flush);
  1874. }
  1875. }
  1876. };
  1877. const consume = (queue) => {
  1878. for (let i = 0; i < queue.length; i++) {
  1879. try {
  1880. queue[i](performance.now());
  1881. }
  1882. catch (e) {
  1883. consoleError(e);
  1884. }
  1885. }
  1886. queue.length = 0;
  1887. };
  1888. const flush = () => {
  1889. // always force a bunch of medium callbacks to run, but still have
  1890. // a throttle on how many can run in a certain time
  1891. // DOM READS!!!
  1892. consume(queueDomReads);
  1893. // DOM WRITES!!!
  1894. {
  1895. consume(queueDomWrites);
  1896. if ((queuePending = queueDomReads.length > 0)) {
  1897. // still more to do yet, but we've run out of time
  1898. // let's let this thing cool off and try again in the next tick
  1899. plt.raf(flush);
  1900. }
  1901. }
  1902. };
  1903. const nextTick = /*@__PURE__*/ (cb) => promiseResolve().then(cb);
  1904. const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
  1905. exports.Fragment = Fragment;
  1906. exports.Host = Host;
  1907. exports.NAMESPACE = NAMESPACE;
  1908. exports.bootstrapLazy = bootstrapLazy;
  1909. exports.createEvent = createEvent;
  1910. exports.doc = doc;
  1911. exports.forceUpdate = forceUpdate;
  1912. exports.getAssetPath = getAssetPath;
  1913. exports.getElement = getElement;
  1914. exports.h = h;
  1915. exports.promiseResolve = promiseResolve;
  1916. exports.registerInstance = registerInstance;