@substrate-system/tonic 17.1.0 → 17.2.0

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/README.md CHANGED
@@ -34,8 +34,8 @@ with all modern browsers. It's built on top of
34
34
  - [Server-Side Rendering](#server-side-rendering)
35
35
  * [SSR Example](#ssr-example)
36
36
  * [Async Components](#async-components)
37
- - [docs](#docs)
38
- - [types](#types)
37
+ * [Hydration](#hydration)
38
+ - [Docs](#docs)
39
39
  - [API](#api)
40
40
  * [Event listeners](#event-listeners)
41
41
  * [`tag`](#tag)
@@ -360,11 +360,106 @@ const html = await renderToString(component)
360
360
  // Waits for async render to complete
361
361
  ```
362
362
 
363
- ## docs
363
+ ### Hydration
364
+
365
+ Add interactivity to server-rendered HTML without re-rendering.
366
+ The server attaches serialized state to the page,
367
+ and the client initializes components with that state.
368
+
369
+ #### Start a local example
370
+
371
+ ```sh
372
+ npm run start:hydration
373
+ ```
374
+
375
+ #### Build the hydration example
376
+
377
+ ```sh
378
+ npm run build:hydration
379
+ ```
380
+
381
+ #### Server
382
+
383
+ `render` returns the inner HTML of a component. `toHtml`
384
+ wraps that in the custom element tag (e.g.
385
+ `<my-app>...content...</my-app>`), with props encoded as
386
+ attributes. Pass a `state` option to embed complex props
387
+ as JSON.
388
+
389
+ ```js
390
+ import {
391
+ render,
392
+ toHtml
393
+ } from '@substrate-system/tonic/render-to-string'
394
+
395
+ class MyApp extends Tonic {
396
+ render () {
397
+ return this.html`<div>
398
+ <h1>${this.props.title}</h1>
399
+ <ul>
400
+ ${this.props.items.map(item =>
401
+ this.html`<li>${item}</li>`
402
+ )}
403
+ </ul>
404
+ <button>Click me</button>
405
+ </div>`
406
+ }
407
+ }
408
+
409
+ Tonic.add(MyApp)
410
+
411
+ const props = { title: 'Hello', items: ['a', 'b', 'c'] }
412
+ const app = new MyApp()
413
+ app.props = props
414
+ const content = await render(app)
415
+
416
+ // Wrap in component tag + embed state for hydration
417
+ const html = toHtml(app, content, {
418
+ id: 'app',
419
+ state: { app: props }
420
+ })
421
+
422
+ // html =>
423
+ // <my-app id="app" title="Hello">
424
+ // <div><h1>Hello</h1>...</div>
425
+ // </my-app>
426
+ // <script type="application/json" data-tonic-ssr>
427
+ // {"app":{"title":"Hello","items":["a","b","c"]}}
428
+ // </script>
429
+ ```
430
+
431
+ Simple props (strings, numbers, booleans, null) are encoded
432
+ as HTML attributes automatically. Complex props (objects,
433
+ arrays) are transferred via the JSON `<script>` tag, keyed
434
+ by the component's `id`.
435
+
436
+ #### Client
437
+
438
+ Use `hydrate` to register components without re-rendering.
439
+ The existing server-rendered DOM is preserved, event handlers
440
+ are attached, and lifecycle hooks run normally.
441
+
442
+ ```js
443
+ import { Tonic } from '@substrate-system/tonic'
444
+ import { hydrate } from '@substrate-system/tonic/hydrate'
445
+ import { MyApp } from './components.js'
446
+
447
+ // Register components inside the callback --
448
+ // the DOM is preserved, not re-rendered.
449
+ const state = hydrate(() => {
450
+ Tonic.add(MyApp)
451
+ })
452
+
453
+ // state => { app: { title: 'Hello', items: ['a', 'b', 'c'] } }
454
+ // Event handlers (handle_click, etc.) are active.
455
+ // Calling reRender() works normally after hydration.
456
+ ```
457
+
458
+ ## Docs
459
+
364
460
  See [API docs](https://substrate-system.github.io/tonic/).
365
461
 
366
- ## types
367
- See [src/index.ts](./src/index.ts).
462
+ ---
368
463
 
369
464
  ## API
370
465
 
@@ -467,7 +562,7 @@ Return the namespaced event name given a string.
467
562
  ```ts
468
563
  class {
469
564
  static event (type:string):string {
470
- return `${this.tag}:${type}`
565
+ return `${this.TAG}:${type}`
471
566
  }
472
567
  }
473
568
  ```
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var hydrate_exports = {};
21
+ __export(hydrate_exports, {
22
+ hydrate: () => hydrate
23
+ });
24
+ module.exports = __toCommonJS(hydrate_exports);
25
+ var import_index = require("./index.js");
26
+ function hydrate(callback) {
27
+ const script = document.querySelector(
28
+ "script[data-tonic-ssr]"
29
+ );
30
+ const state = script ? JSON.parse(script.textContent || "{}") : null;
31
+ import_index.Tonic._ssrState = state;
32
+ import_index.Tonic._hydrating = true;
33
+ callback();
34
+ import_index.Tonic._hydrating = false;
35
+ import_index.Tonic._ssrState = null;
36
+ return state;
37
+ }
38
+ __name(hydrate, "hydrate");
39
+ //# sourceMappingURL=hydrate.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/hydrate.ts"],
4
+ "sourcesContent": ["import { Tonic } from './index.js'\n\n/**\n * Hydrate server-rendered Tonic components.\n *\n * Call this to wrap component registration so that existing\n * server-rendered DOM is preserved instead of being re-rendered.\n * Event handlers are still attached, props are parsed from\n * attributes, and lifecycle hooks (`willConnect`, `connected`)\n * are called.\n *\n * If a `<script type=\"application/json\" data-tonic-ssr>` tag\n * exists in the document, its JSON content is parsed and used\n * to restore complex props (objects, arrays) for components\n * with matching `id` attributes.\n *\n * @param callback Register your components inside this callback\n * @returns The parsed SSR state, or null if none was embedded\n *\n * @example\n * ```ts\n * import { hydrate } from '@substrate-system/tonic/hydrate'\n * import { Tonic } from '@substrate-system/tonic'\n * import { MyApp } from './components.js'\n *\n * const state = hydrate(() => {\n * Tonic.add(MyApp)\n * })\n * ```\n */\nexport function hydrate (\n callback:() => void\n):Record<string, any>|null {\n const script = document.querySelector(\n 'script[data-tonic-ssr]'\n )\n\n const state:Record<string, any>|null = script ?\n JSON.parse(script.textContent || '{}') :\n null\n\n Tonic._ssrState = state\n Tonic._hydrating = true\n\n callback()\n\n Tonic._hydrating = false\n Tonic._ssrState = null\n\n return state\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAsB;AA8Bf,SAAS,QACZ,UACuB;AACvB,QAAM,SAAS,SAAS;AAAA,IACpB;AAAA,EACJ;AAEA,QAAM,QAAiC,SACnC,KAAK,MAAM,OAAO,eAAe,IAAI,IACrC;AAEJ,qBAAM,YAAY;AAClB,qBAAM,aAAa;AAEnB,WAAS;AAET,qBAAM,aAAa;AACnB,qBAAM,YAAY;AAElB,SAAO;AACX;AApBgB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Hydrate server-rendered Tonic components.
3
+ *
4
+ * Call this to wrap component registration so that existing
5
+ * server-rendered DOM is preserved instead of being re-rendered.
6
+ * Event handlers are still attached, props are parsed from
7
+ * attributes, and lifecycle hooks (`willConnect`, `connected`)
8
+ * are called.
9
+ *
10
+ * If a `<script type="application/json" data-tonic-ssr>` tag
11
+ * exists in the document, its JSON content is parsed and used
12
+ * to restore complex props (objects, arrays) for components
13
+ * with matching `id` attributes.
14
+ *
15
+ * @param callback Register your components inside this callback
16
+ * @returns The parsed SSR state, or null if none was embedded
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { hydrate } from '@substrate-system/tonic/hydrate'
21
+ * import { Tonic } from '@substrate-system/tonic'
22
+ * import { MyApp } from './components.js'
23
+ *
24
+ * const state = hydrate(() => {
25
+ * Tonic.add(MyApp)
26
+ * })
27
+ * ```
28
+ */
29
+ export declare function hydrate(callback: () => void): Record<string, any> | null;
30
+ //# sourceMappingURL=hydrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../src/hydrate.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,OAAO,CACnB,QAAQ,EAAC,MAAM,IAAI,GACrB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAC,IAAI,CAkBzB"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
4
+ import { Tonic } from "./index.js";
5
+ export function hydrate(callback) {
6
+ const script = document.querySelector(
7
+ "script[data-tonic-ssr]"
8
+ );
9
+ const state = script ? JSON.parse(script.textContent || "{}") : null;
10
+ Tonic._ssrState = state;
11
+ Tonic._hydrating = true;
12
+ callback();
13
+ Tonic._hydrating = false;
14
+ Tonic._ssrState = null;
15
+ return state;
16
+ }
17
+ __name(hydrate, "hydrate");
18
+ //# sourceMappingURL=hydrate.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/hydrate.ts"],
4
+ "sourcesContent": ["import { Tonic } from './index.js'\n\n/**\n * Hydrate server-rendered Tonic components.\n *\n * Call this to wrap component registration so that existing\n * server-rendered DOM is preserved instead of being re-rendered.\n * Event handlers are still attached, props are parsed from\n * attributes, and lifecycle hooks (`willConnect`, `connected`)\n * are called.\n *\n * If a `<script type=\"application/json\" data-tonic-ssr>` tag\n * exists in the document, its JSON content is parsed and used\n * to restore complex props (objects, arrays) for components\n * with matching `id` attributes.\n *\n * @param callback Register your components inside this callback\n * @returns The parsed SSR state, or null if none was embedded\n *\n * @example\n * ```ts\n * import { hydrate } from '@substrate-system/tonic/hydrate'\n * import { Tonic } from '@substrate-system/tonic'\n * import { MyApp } from './components.js'\n *\n * const state = hydrate(() => {\n * Tonic.add(MyApp)\n * })\n * ```\n */\nexport function hydrate (\n callback:() => void\n):Record<string, any>|null {\n const script = document.querySelector(\n 'script[data-tonic-ssr]'\n )\n\n const state:Record<string, any>|null = script ?\n JSON.parse(script.textContent || '{}') :\n null\n\n Tonic._ssrState = state\n Tonic._hydrating = true\n\n callback()\n\n Tonic._hydrating = false\n Tonic._ssrState = null\n\n return state\n}\n"],
5
+ "mappings": ";;;AAAA,SAAS,aAAa;AA8Bf,gBAAS,QACZ,UACuB;AACvB,QAAM,SAAS,SAAS;AAAA,IACpB;AAAA,EACJ;AAEA,QAAM,QAAiC,SACnC,KAAK,MAAM,OAAO,eAAe,IAAI,IACrC;AAEJ,QAAM,YAAY;AAClB,QAAM,aAAa;AAEnB,WAAS;AAET,QAAM,aAAa;AACnB,QAAM,YAAY;AAElB,SAAO;AACX;AApBgB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var o=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var c=(r,t)=>o(r,"name",{value:t,configurable:!0});var d=(r,t)=>{for(var n in t)o(r,n,{get:t[n],enumerable:!0})},y=(r,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of l(t))!u.call(r,e)&&e!==n&&o(r,e,{get:()=>t[e],enumerable:!(a=i(t,e))||a.enumerable});return r};var p=r=>y(o({},"__esModule",{value:!0}),r);var S={};d(S,{hydrate:()=>g});module.exports=p(S);var s=require("./index.js");function g(r){const t=document.querySelector("script[data-tonic-ssr]"),n=t?JSON.parse(t.textContent||"{}"):null;return s.Tonic._ssrState=n,s.Tonic._hydrating=!0,r(),s.Tonic._hydrating=!1,s.Tonic._ssrState=null,n}c(g,"hydrate");
2
+ //# sourceMappingURL=hydrate.min.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/hydrate.ts"],
4
+ "sourcesContent": ["import { Tonic } from './index.js'\n\n/**\n * Hydrate server-rendered Tonic components.\n *\n * Call this to wrap component registration so that existing\n * server-rendered DOM is preserved instead of being re-rendered.\n * Event handlers are still attached, props are parsed from\n * attributes, and lifecycle hooks (`willConnect`, `connected`)\n * are called.\n *\n * If a `<script type=\"application/json\" data-tonic-ssr>` tag\n * exists in the document, its JSON content is parsed and used\n * to restore complex props (objects, arrays) for components\n * with matching `id` attributes.\n *\n * @param callback Register your components inside this callback\n * @returns The parsed SSR state, or null if none was embedded\n *\n * @example\n * ```ts\n * import { hydrate } from '@substrate-system/tonic/hydrate'\n * import { Tonic } from '@substrate-system/tonic'\n * import { MyApp } from './components.js'\n *\n * const state = hydrate(() => {\n * Tonic.add(MyApp)\n * })\n * ```\n */\nexport function hydrate (\n callback:() => void\n):Record<string, any>|null {\n const script = document.querySelector(\n 'script[data-tonic-ssr]'\n )\n\n const state:Record<string, any>|null = script ?\n JSON.parse(script.textContent || '{}') :\n null\n\n Tonic._ssrState = state\n Tonic._hydrating = true\n\n callback()\n\n Tonic._hydrating = false\n Tonic._ssrState = null\n\n return state\n}\n"],
5
+ "mappings": "4dAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAsB,sBA8Bf,SAASC,EACZC,EACuB,CACvB,MAAMC,EAAS,SAAS,cACpB,wBACJ,EAEMC,EAAiCD,EACnC,KAAK,MAAMA,EAAO,aAAe,IAAI,EACrC,KAEJ,eAAM,UAAYC,EAClB,QAAM,WAAa,GAEnBF,EAAS,EAET,QAAM,WAAa,GACnB,QAAM,UAAY,KAEXE,CACX,CApBgBC,EAAAJ,EAAA",
6
+ "names": ["hydrate_exports", "__export", "hydrate", "__toCommonJS", "import_index", "hydrate", "callback", "script", "state", "__name"]
7
+ }
@@ -0,0 +1,3 @@
1
+ var le=Object.defineProperty;var p=(n,s)=>le(n,"name",{value:s,configurable:!0});var Y=11;function oe(n,s){var e=s.attributes,t,i,r,o,a;if(!(s.nodeType===Y||n.nodeType===Y)){for(var f=e.length-1;f>=0;f--)t=e[f],i=t.name,r=t.namespaceURI,o=t.value,r?(i=t.localName||i,a=n.getAttributeNS(r,i),a!==o&&(t.prefix==="xmlns"&&(i=t.name),n.setAttributeNS(r,i,o))):(a=n.getAttribute(i),a!==o&&n.setAttribute(i,o));for(var u=n.attributes,v=u.length-1;v>=0;v--)t=u[v],i=t.name,r=t.namespaceURI,r?(i=t.localName||i,s.hasAttributeNS(r,i)||n.removeAttributeNS(r,i)):s.hasAttribute(i)||n.removeAttribute(i)}}p(oe,"morphAttrs");var $,de="http://www.w3.org/1999/xhtml",_=typeof document>"u"?void 0:document,ue=!!_&&"content"in _.createElement("template"),pe=!!_&&_.createRange&&"createContextualFragment"in _.createRange();function he(n){var s=_.createElement("template");return s.innerHTML=n,s.content.childNodes[0]}p(he,"createFragmentFromTemplate");function fe(n){$||($=_.createRange(),$.selectNode(_.body));var s=$.createContextualFragment(n);return s.childNodes[0]}p(fe,"createFragmentFromRange");function ve(n){var s=_.createElement("body");return s.innerHTML=n,s.childNodes[0]}p(ve,"createFragmentFromWrap");function ge(n){return n=n.trim(),ue?he(n):pe?fe(n):ve(n)}p(ge,"toElement");function F(n,s){var e=n.nodeName,t=s.nodeName,i,r;return e===t?!0:(i=e.charCodeAt(0),r=t.charCodeAt(0),i<=90&&r>=97?e===t.toUpperCase():r<=90&&i>=97?t===e.toUpperCase():!1)}p(F,"compareNodeNames");function ye(n,s){return!s||s===de?_.createElement(n):_.createElementNS(s,n)}p(ye,"createElementNS");function me(n,s){for(var e=n.firstChild;e;){var t=e.nextSibling;s.appendChild(e),e=t}return s}p(me,"moveChildren");function X(n,s,e){n[e]!==s[e]&&(n[e]=s[e],n[e]?n.setAttribute(e,""):n.removeAttribute(e))}p(X,"syncBooleanAttrProp");var Q={OPTION:p(function(n,s){var e=n.parentNode;if(e){var t=e.nodeName.toUpperCase();t==="OPTGROUP"&&(e=e.parentNode,t=e&&e.nodeName.toUpperCase()),t==="SELECT"&&!e.hasAttribute("multiple")&&(n.hasAttribute("selected")&&!s.selected&&(n.setAttribute("selected","selected"),n.removeAttribute("selected")),e.selectedIndex=-1)}X(n,s,"selected")},"OPTION"),INPUT:p(function(n,s){X(n,s,"checked"),X(n,s,"disabled"),n.value!==s.value&&(n.value=s.value),s.hasAttribute("value")||n.removeAttribute("value")},"INPUT"),TEXTAREA:p(function(n,s){var e=s.value;n.value!==e&&(n.value=e);var t=n.firstChild;if(t){var i=t.nodeValue;if(i==e||!e&&i==n.placeholder)return;t.nodeValue=e}},"TEXTAREA"),SELECT:p(function(n,s){if(!s.hasAttribute("multiple")){for(var e=-1,t=0,i=n.firstChild,r,o;i;)if(o=i.nodeName&&i.nodeName.toUpperCase(),o==="OPTGROUP")r=i,i=r.firstChild,i||(i=r.nextSibling,r=null);else{if(o==="OPTION"){if(i.hasAttribute("selected")){e=t;break}t++}i=i.nextSibling,!i&&r&&(i=r.nextSibling,r=null)}n.selectedIndex=e}},"SELECT")},L=1,ee=11,te=3,ne=8;function w(){}p(w,"noop");function Te(n){if(n)return n.getAttribute&&n.getAttribute("id")||n.id}p(Te,"defaultGetNodeKey");function _e(n){return p(function(e,t,i){if(i||(i={}),typeof t=="string")if(e.nodeName==="#document"||e.nodeName==="HTML"||e.nodeName==="BODY"){var r=t;t=_.createElement("html"),t.innerHTML=r}else t=ge(t);else t.nodeType===ee&&(t=t.firstElementChild);var o=i.getNodeKey||Te,a=i.onBeforeNodeAdded||w,f=i.onNodeAdded||w,u=i.onBeforeElUpdated||w,v=i.onElUpdated||w,d=i.onBeforeNodeDiscarded||w,y=i.onNodeDiscarded||w,N=i.onBeforeElChildrenUpdated||w,re=i.skipFromChildren||w,K=i.addChild||function(c,l){return c.appendChild(l)},D=i.childrenOnly===!0,M=Object.create(null),O=[];function I(c){O.push(c)}p(I,"addKeyedRemoval");function J(c,l){if(c.nodeType===L)for(var m=c.firstChild;m;){var h=void 0;l&&(h=o(m))?I(h):(y(m),m.firstChild&&J(m,l)),m=m.nextSibling}}p(J,"walkDiscardedChildNodes");function H(c,l,m){d(c)!==!1&&(l&&l.removeChild(c),y(c),J(c,m))}p(H,"removeNode");function V(c){if(c.nodeType===L||c.nodeType===ee)for(var l=c.firstChild;l;){var m=o(l);m&&(M[m]=l),V(l),l=l.nextSibling}}p(V,"indexTree"),V(e);function B(c){f(c);for(var l=c.firstChild;l;){var m=l.nextSibling,h=o(l);if(h){var g=M[h];g&&F(l,g)?(l.parentNode.replaceChild(g,l),j(g,l)):B(l)}else B(l);l=m}}p(B,"handleNodeAdded");function se(c,l,m){for(;l;){var h=l.nextSibling;(m=o(l))?I(m):H(l,c,!0),l=h}}p(se,"cleanupFromEl");function j(c,l,m){var h=o(l);if(h&&delete M[h],!m){var g=u(c,l);if(g===!1||(g instanceof HTMLElement&&(c=g,V(c)),n(c,l),v(c),N(c,l)===!1))return}c.nodeName!=="TEXTAREA"?ae(c,l):Q.TEXTAREA(c,l)}p(j,"morphEl");function ae(c,l){var m=re(c,l),h=l.firstChild,g=c.firstChild,x,b,E,k,A;e:for(;h;){for(k=h.nextSibling,x=o(h);!m&&g;){if(E=g.nextSibling,h.isSameNode&&h.isSameNode(g)){h=k,g=E;continue e}b=o(g);var U=g.nodeType,S=void 0;if(U===h.nodeType&&(U===L?(x?x!==b&&((A=M[x])?E===A?S=!1:(c.insertBefore(A,g),b?I(b):H(g,c,!0),g=A,b=o(g)):S=!1):b&&(S=!1),S=S!==!1&&F(g,h),S&&j(g,h)):(U===te||U==ne)&&(S=!0,g.nodeValue!==h.nodeValue&&(g.nodeValue=h.nodeValue))),S){h=k,g=E;continue e}b?I(b):H(g,c,!0),g=E}if(x&&(A=M[x])&&F(A,h))m||K(c,A),j(A,h);else{var z=a(h);z!==!1&&(z&&(h=z),h.actualize&&(h=h.actualize(c.ownerDocument||_)),K(c,h),B(h))}h=k,g=E}se(c,g,b);var Z=Q[c.nodeName];Z&&Z(c,l)}p(ae,"morphChildren");var T=e,P=T.nodeType,W=t.nodeType;if(!D){if(P===L)W===L?F(e,t)||(y(e),T=me(e,ye(t.nodeName,t.namespaceURI))):T=t;else if(P===te||P===ne){if(W===P)return T.nodeValue!==t.nodeValue&&(T.nodeValue=t.nodeValue),T;T=t}}if(T===t)y(e);else{if(t.isSameNode&&t.isSameNode(T))return;if(j(T,t,D),O)for(var G=0,ce=O.length;G<ce;G++){var q=M[O[G]];q&&H(q,q.parentNode,!1)}}return!D&&T!==e&&e.parentNode&&(T.actualize&&(T=T.actualize(e.ownerDocument||_)),e.parentNode.replaceChild(T,e)),T},"morphdom")}p(_e,"morphdomFactory");var be=_e(oe),ie=be;var C=class{static{p(this,"TonicTemplate")}constructor(s,e,t){this.isTonicTemplate=!0,this.unsafe=!!t,this.rawText=s,this.templateStrings=e}valueOf(){return this.rawText}toString(){return this.rawText}},R=class n extends window.HTMLElement{constructor(){super();this._props=n.getPropertyNames(this);let e=n._states[super.id];delete n._states[super.id],this._state=e||{},this.preventRenderOnReconnect=!1,this.props={},this.elements=[...this.children],this.elements.__children__=!0,this.nodes=[...this.childNodes],this.nodes.__children__=!0,this._events()}static{p(this,"Tonic")}static{this._tags=""}static{this._refIds=[]}static{this._data={}}static{this._states={}}static{this._children={}}static{this._reg={}}static{this._stylesheetRegistry=[]}static{this._index=0}static get version(){return VERSION??null}static get SPREAD(){return/\.\.\.\s?(__\w+__\w+__)/g}static get ESC(){return/["&'<>`/]/g}static get AsyncFunctionGenerator(){return async function*(){}.constructor}static get AsyncFunction(){return async function(){}.constructor}static get MAP(){return{'"':"&quot;","&":"&amp;","'":"&#x27;","<":"&lt;",">":"&gt;","`":"&#x60;","/":"&#x2F;"}}static{this._hydrating=!1}static{this._ssrState=null}defaults(){return{}}get isTonicComponent(){return!0}static event(e){return`${this.TAG}:${e}`}static get TAG(){return n.getTagName(this.name)}static _createId(){return`tonic${n._index++}`}static _normalizeAttrs(e,t={}){return[...e].forEach(i=>t[i.name]=i.value),t}_checkId(){let e=super.id;if(!e){let t=this.outerHTML.replace(this.innerHTML,"...");throw new Error(`Component: ${t} has no id`)}return e}get state(){return this._checkId(),this._state}set state(e){this._state=(this._checkId(),e)}_events(){let e=Object.getOwnPropertyNames(window.HTMLElement.prototype);for(let t of this._props){if(!t.includes("handle_"))continue;let i=t.split("_")[1];e.indexOf("on"+i)!==-1&&this.addEventListener(i,this)}}_prop(e){let t=this._id,i=`__${t}__${n._createId()}__`;return n._data[t]=n._data[t]||{},n._data[t][i]=e,i}_placehold(e){let t=this._id,i=`placehold:${t}:${n._createId()}__`;return n._children[t]=n._children[t]||{},n._children[t][i]=e,i}static match(e,t){return e.matches||(e=e.parentElement),e.matches(t)?e:e.closest(t)}static getTagName(e){return e.match(/[A-Z][a-z0-9]*/g).join("-").toLowerCase()}static getPropertyNames(e){let t=[];for(;e&&e!==n.prototype;)t.push(...Object.getOwnPropertyNames(e)),e=Object.getPrototypeOf(e);return t}static add(e,t){if(!(t||e.name&&e.name.length>1))throw Error("Mangling. https://bit.ly/2TkJ6zP");if(t||(t=n.getTagName(e.name)),!n.ssr&&window.customElements.get(t))throw new Error(`Cannot Tonic.add(${e.name}, '${t}') twice`);if(!e.prototype||!e.prototype.isTonicComponent){let r={[e.name]:class extends n{render(){return new C("",null)}}}[e.name];r.prototype.render=e,e=r}return e.prototype._props=n.getPropertyNames(e.prototype),n._reg[t]=e,n._tags=Object.keys(n._reg).join(),window.customElements.define(t,e),typeof e.stylesheet=="function"&&n.registerStyles(e.stylesheet),e}static registerStyles(e){if(n._stylesheetRegistry.includes(e))return;n._stylesheetRegistry.push(e);let t=document.createElement("style");n.nonce&&t.setAttribute("nonce",n.nonce),t.appendChild(document.createTextNode(e())),document.head&&document.head.appendChild(t)}static escape(e){return e.replace(n.ESC,t=>n.MAP[t])}static unsafeRawString(e,t){return new C(e,t,!0)}dispatch(e,t=null){let i={bubbles:!0,detail:t};this.dispatchEvent(new window.CustomEvent(e,i))}emit(e,t={},i={}){let r=n.getTagName(this.constructor.name),o=new CustomEvent(`${r}:${e}`,{bubbles:i.bubbles===void 0?!0:i.bubbles,cancelable:i.cancelable===void 0?!0:i.cancelable,detail:t});return this.dispatchEvent(o)}html(e,...t){let i=p(a=>{if(a&&a.__children__)return this._placehold(a);if(a&&a.isTonicTemplate)return a.rawText;switch(Object.prototype.toString.call(a)){case"[object HTMLCollection]":case"[object NodeList]":return this._placehold([...a]);case"[object Array]":return a.every(f=>f.isTonicTemplate&&!f.unsafe)?new C(a.join(`
2
+ `),null,!1):this._prop(a);case"[object Object]":case"[object Function]":case"[object AsyncFunction]":case"[object Set]":case"[object Map]":case"[object WeakMap]":case"[object File]":return this._prop(a);case"[object NamedNodeMap]":return this._prop(n._normalizeAttrs(a));case"[object Number]":return`${a}__float`;case"[object String]":return n.escape(a);case"[object Boolean]":return`${a}__boolean`;case"[object Null]":return`${a}__null`;case"[object HTMLElement]":return this._placehold([a])}return typeof a=="object"&&a&&a.nodeType===1&&typeof a.cloneNode=="function"?this._placehold([a]):a},"refs"),r=[];for(let a=0;a<e.length-1;a++)r.push(e[a],i(t[a]));r.push(e[e.length-1]);let o=r.join("").replace(n.SPREAD,(a,f)=>{let u=n._data[f.split("__")[1]][f];return Object.entries(u).map(([v,d])=>{let y=v.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();return d===!0?y:d?`${y}="${n.escape(String(d))}"`:""}).filter(Boolean).join(" ")}).replace(/(\d+(?:\.\d+)?)__float/g,"$1").replace(/(true|false)__boolean/g,"$1").replace(/null__null/g,"null");return new C(o,e,!1)}scheduleReRender(e){return this.pendingReRender?this.pendingReRender:(this.pendingReRender=new Promise(t=>setTimeout(()=>{if(!this.isInDocument(this.shadowRoot||this))return;let i=this._set(this.shadowRoot||this,this.render);if(this.pendingReRender=null,i&&i.then)return i.then(()=>{this.updated&&this.updated(e),t(this)});this.updated&&this.updated(e),t(this)},0)),this.pendingReRender)}reRender(e=this.props){let t={...this.props};return this.props=typeof e=="function"?e(t):e,this.scheduleReRender(t)}handleEvent(e){this["handle_"+e.type]&&this["handle_"+e.type](e)}_drainIterator(e,t){return t.next().then(i=>{if(this._set(e,null,i.value),!i.done)return this._drainIterator(e,t)})}_set(e,t,i=""){this.willRender&&this.willRender();for(let r of e.querySelectorAll(n._tags)){if(!r.isTonicComponent)continue;let o=r.getAttribute("id");!o||!n._refIds.includes(o)||(n._states[o]=r.state)}if(t instanceof n.AsyncFunction)return t.call(this,this.html,this.props).then(r=>this._apply(e,r));if(t instanceof n.AsyncFunctionGenerator)return this._drainIterator(e,t.call(this));t===null?this._apply(e,i):t instanceof Function&&this._apply(e,t.call(this,this.html,this.props)||"")}_apply(e,t){if(t&&t.isTonicTemplate?t=t.rawText:typeof t=="string"&&(t=n.escape(t)),typeof t=="string"){this.stylesheet&&(t=`<style nonce=${n.nonce||""}>${this.stylesheet()}</style>${t}`);let i=e.querySelector&&(e.querySelector("input")||e.querySelector("textarea")||e.querySelector("select"));if(i&&document.activeElement&&(e.contains(document.activeElement)||e===document.activeElement)){let f=document.createElement("div");f.innerHTML=t,ie(e,f,{childrenOnly:!0,onBeforeElUpdated:p((u,v)=>{if(u.isEqualNode&&u.isEqualNode(v))return!1;if(u.tagName==="INPUT"&&v.tagName==="INPUT"){let d=u,y=v;d.value!==""&&(y.value=d.value),document.activeElement===d&&(y.setAttribute("data-preserve-focus","true"),y.setAttribute("data-selection-start",String(d.selectionStart||0)),y.setAttribute("data-selection-end",String(d.selectionEnd||0)))}if(u.tagName==="TEXTAREA"&&v.tagName==="TEXTAREA"){let d=u,y=v;d.value!==""&&(y.value=d.value),document.activeElement===d&&(y.setAttribute("data-preserve-focus","true"),y.setAttribute("data-selection-start",String(d.selectionStart||0)),y.setAttribute("data-selection-end",String(d.selectionEnd||0)))}return!0},"onBeforeElUpdated"),onElUpdated:p(u=>{if(!u.hasAttribute("data-preserve-focus"))return;let v=parseInt(u.getAttribute("data-selection-start")||"0",10),d=parseInt(u.getAttribute("data-selection-end")||"0",10);u.removeAttribute("data-preserve-focus"),u.removeAttribute("data-selection-start"),u.removeAttribute("data-selection-end"),u.focus(),"setSelectionRange"in u&&u.setSelectionRange(v,d)},"onElUpdated")})}else{let f="input, textarea, select",u=[];if(i){let v=e.querySelectorAll(f);for(let d of v){let y=d,N=y.type==="checkbox"||y.type==="radio";u.push({v:d.value,c:y.checked,dirty:N?y.checked!==y.defaultChecked:d.value!==d.defaultValue})}}if(e.innerHTML=t,u.length){let v=e.querySelectorAll(f);for(let d=0;d<Math.min(u.length,v.length);d++){if(!u[d].dirty)continue;let y=v[d],N=y.type;N==="checkbox"||N==="radio"?y.checked=u[d].c:y.value=u[d].v}}}if(this.styles){let f=this.styles();for(let u of e.querySelectorAll("[styles]"))for(let v of u.getAttribute("styles").split(/\s+/))Object.assign(u.style,f[v.trim()])}let o=n._children[this._id]||{},a=p((f,u)=>{if(f.nodeType===3){let d=f.textContent.trim();o[d]&&u(f,o[d],d)}let v=f.childNodes;if(v)for(let d=0;d<v.length;d++)a(v[d],u)},"walk");a(e,(f,u,v)=>{for(let d of u)f.parentNode.insertBefore(d,f);delete n._children[this._id][v],f.parentNode.removeChild(f)})}else e.innerHTML="",e.appendChild(t.cloneNode(!0))}connectedCallback(){this.root=this.shadowRoot||this,super.id&&!n._refIds.includes(super.id)&&n._refIds.push(super.id);let e=p(t=>t.replace(/-(.)/g,(i,r)=>r.toUpperCase()),"cc");for(let{name:t,value:i}of this.attributes){let r=e(t),o=this.props[r]=i;if(/__\w+__\w+__/.test(o)){let{1:a}=o.split("__");this.props[r]=n._data[a][o]}else if(/\d+__float/.test(o))this.props[r]=parseFloat(o);else if(o==="null__null")this.props[r]=null;else if(/\w+__boolean/.test(o))this.props[r]=o.includes("true");else if(/placehold:\w+:\w+__/.test(o)){let{1:a}=o.split(":");this.props[r]=n._children[a][o][0]}}if(this.props=Object.assign(this.defaults(),this.props),this._id=this._id||n._createId(),this.willConnect&&this.willConnect(),!!this.isInDocument(this.root)){if(n._hydrating){super.id&&n._ssrState?.[super.id]&&(this.props=Object.assign(this.props,n._ssrState[super.id])),this._source=this.innerHTML,this.connected&&this.connected();return}if(!this.preventRenderOnReconnect){this._source?this.innerHTML=this._source:this._source=this.innerHTML;let t=this._set(this.root,this.render);if(t&&t.then)return t.then(()=>this.connected&&this.connected())}this.connected&&this.connected()}}isInDocument(e){let t=e.getRootNode();return t===document||t.toString()==="[object ShadowRoot]"}disconnectedCallback(){this.disconnected&&this.disconnected(),delete n._data[this._id],delete n._children[this._id]}};function Ce(n){let s=document.querySelector("script[data-tonic-ssr]"),e=s?JSON.parse(s.textContent||"{}"):null;return R._ssrState=e,R._hydrating=!0,n(),R._hydrating=!1,R._ssrState=null,e}p(Ce,"hydrate");export{Ce as hydrate};
3
+ //# sourceMappingURL=hydrate.min.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../node_modules/@substrate-system/morphdom/dist/morphdom-esm.js", "../src/index.ts", "../src/hydrate.ts"],
4
+ "sourcesContent": ["var DOCUMENT_FRAGMENT_NODE = 11;\n\nfunction morphAttrs(fromNode, toNode) {\n var toNodeAttrs = toNode.attributes;\n var attr;\n var attrName;\n var attrNamespaceURI;\n var attrValue;\n var fromValue;\n\n // document-fragments dont have attributes so lets not do anything\n if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) {\n return;\n }\n\n // update attributes on original DOM element\n for (var i = toNodeAttrs.length - 1; i >= 0; i--) {\n attr = toNodeAttrs[i];\n attrName = attr.name;\n attrNamespaceURI = attr.namespaceURI;\n attrValue = attr.value;\n\n if (attrNamespaceURI) {\n attrName = attr.localName || attrName;\n fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);\n\n if (fromValue !== attrValue) {\n if (attr.prefix === 'xmlns'){\n attrName = attr.name; // It's not allowed to set an attribute with the XMLNS namespace without specifying the `xmlns` prefix\n }\n fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);\n }\n } else {\n fromValue = fromNode.getAttribute(attrName);\n\n if (fromValue !== attrValue) {\n fromNode.setAttribute(attrName, attrValue);\n }\n }\n }\n\n // Remove any extra attributes found on the original DOM element that\n // weren't found on the target element.\n var fromNodeAttrs = fromNode.attributes;\n\n for (var d = fromNodeAttrs.length - 1; d >= 0; d--) {\n attr = fromNodeAttrs[d];\n attrName = attr.name;\n attrNamespaceURI = attr.namespaceURI;\n\n if (attrNamespaceURI) {\n attrName = attr.localName || attrName;\n\n if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) {\n fromNode.removeAttributeNS(attrNamespaceURI, attrName);\n }\n } else {\n if (!toNode.hasAttribute(attrName)) {\n fromNode.removeAttribute(attrName);\n }\n }\n }\n}\n\nvar range; // Create a range object for efficently rendering strings to elements.\nvar NS_XHTML = 'http://www.w3.org/1999/xhtml';\n\nvar doc = typeof document === 'undefined' ? undefined : document;\nvar HAS_TEMPLATE_SUPPORT = !!doc && 'content' in doc.createElement('template');\nvar HAS_RANGE_SUPPORT = !!doc && doc.createRange && 'createContextualFragment' in doc.createRange();\n\nfunction createFragmentFromTemplate(str) {\n var template = doc.createElement('template');\n template.innerHTML = str;\n return template.content.childNodes[0];\n}\n\nfunction createFragmentFromRange(str) {\n if (!range) {\n range = doc.createRange();\n range.selectNode(doc.body);\n }\n\n var fragment = range.createContextualFragment(str);\n return fragment.childNodes[0];\n}\n\nfunction createFragmentFromWrap(str) {\n var fragment = doc.createElement('body');\n fragment.innerHTML = str;\n return fragment.childNodes[0];\n}\n\n/**\n * This is about the same\n * var html = new DOMParser().parseFromString(str, 'text/html');\n * return html.body.firstChild;\n *\n * @method toElement\n * @param {String} str\n */\nfunction toElement(str) {\n str = str.trim();\n if (HAS_TEMPLATE_SUPPORT) {\n // avoid restrictions on content for things like `<tr><th>Hi</th></tr>` which\n // createContextualFragment doesn't support\n // <template> support not available in IE\n return createFragmentFromTemplate(str);\n } else if (HAS_RANGE_SUPPORT) {\n return createFragmentFromRange(str);\n }\n\n return createFragmentFromWrap(str);\n}\n\n/**\n * Returns true if two node's names are the same.\n *\n * NOTE: We don't bother checking `namespaceURI` because you will never find two HTML elements with the same\n * nodeName and different namespace URIs.\n *\n * @param {Element} a\n * @param {Element} b The target element\n * @return {boolean}\n */\nfunction compareNodeNames(fromEl, toEl) {\n var fromNodeName = fromEl.nodeName;\n var toNodeName = toEl.nodeName;\n var fromCodeStart, toCodeStart;\n\n if (fromNodeName === toNodeName) {\n return true;\n }\n\n fromCodeStart = fromNodeName.charCodeAt(0);\n toCodeStart = toNodeName.charCodeAt(0);\n\n // If the target element is a virtual DOM node or SVG node then we may\n // need to normalize the tag name before comparing. Normal HTML elements that are\n // in the \"http://www.w3.org/1999/xhtml\"\n // are converted to upper case\n if (fromCodeStart <= 90 && toCodeStart >= 97) { // from is upper and to is lower\n return fromNodeName === toNodeName.toUpperCase();\n } else if (toCodeStart <= 90 && fromCodeStart >= 97) { // to is upper and from is lower\n return toNodeName === fromNodeName.toUpperCase();\n } else {\n return false;\n }\n}\n\n/**\n * Create an element, optionally with a known namespace URI.\n *\n * @param {string} name the element name, e.g. 'div' or 'svg'\n * @param {string} [namespaceURI] the element's namespace URI, i.e. the value of\n * its `xmlns` attribute or its inferred namespace.\n *\n * @return {Element}\n */\nfunction createElementNS(name, namespaceURI) {\n return !namespaceURI || namespaceURI === NS_XHTML ?\n doc.createElement(name) :\n doc.createElementNS(namespaceURI, name);\n}\n\n/**\n * Copies the children of one DOM element to another DOM element\n */\nfunction moveChildren(fromEl, toEl) {\n var curChild = fromEl.firstChild;\n while (curChild) {\n var nextChild = curChild.nextSibling;\n toEl.appendChild(curChild);\n curChild = nextChild;\n }\n return toEl;\n}\n\nfunction syncBooleanAttrProp(fromEl, toEl, name) {\n if (fromEl[name] !== toEl[name]) {\n fromEl[name] = toEl[name];\n if (fromEl[name]) {\n fromEl.setAttribute(name, '');\n } else {\n fromEl.removeAttribute(name);\n }\n }\n}\n\nvar specialElHandlers = {\n OPTION: function(fromEl, toEl) {\n var parentNode = fromEl.parentNode;\n if (parentNode) {\n var parentName = parentNode.nodeName.toUpperCase();\n if (parentName === 'OPTGROUP') {\n parentNode = parentNode.parentNode;\n parentName = parentNode && parentNode.nodeName.toUpperCase();\n }\n if (parentName === 'SELECT' && !parentNode.hasAttribute('multiple')) {\n if (fromEl.hasAttribute('selected') && !toEl.selected) {\n // Workaround for MS Edge bug where the 'selected' attribute can only be\n // removed if set to a non-empty value:\n // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12087679/\n fromEl.setAttribute('selected', 'selected');\n fromEl.removeAttribute('selected');\n }\n // We have to reset select element's selectedIndex to -1, otherwise setting\n // fromEl.selected using the syncBooleanAttrProp below has no effect.\n // The correct selectedIndex will be set in the SELECT special handler below.\n parentNode.selectedIndex = -1;\n }\n }\n syncBooleanAttrProp(fromEl, toEl, 'selected');\n },\n /**\n * The \"value\" attribute is special for the <input> element since it sets\n * the initial value. Changing the \"value\" attribute without changing the\n * \"value\" property will have no effect since it is only used to the set the\n * initial value. Similar for the \"checked\" attribute, and \"disabled\".\n */\n INPUT: function(fromEl, toEl) {\n syncBooleanAttrProp(fromEl, toEl, 'checked');\n syncBooleanAttrProp(fromEl, toEl, 'disabled');\n\n if (fromEl.value !== toEl.value) {\n fromEl.value = toEl.value;\n }\n\n if (!toEl.hasAttribute('value')) {\n fromEl.removeAttribute('value');\n }\n },\n\n TEXTAREA: function(fromEl, toEl) {\n var newValue = toEl.value;\n if (fromEl.value !== newValue) {\n fromEl.value = newValue;\n }\n\n var firstChild = fromEl.firstChild;\n if (firstChild) {\n // Needed for IE. Apparently IE sets the placeholder as the\n // node value and vise versa. This ignores an empty update.\n var oldValue = firstChild.nodeValue;\n\n if (oldValue == newValue || (!newValue && oldValue == fromEl.placeholder)) {\n return;\n }\n\n firstChild.nodeValue = newValue;\n }\n },\n SELECT: function(fromEl, toEl) {\n if (!toEl.hasAttribute('multiple')) {\n var selectedIndex = -1;\n var i = 0;\n // We have to loop through children of fromEl, not toEl since nodes can be moved\n // from toEl to fromEl directly when morphing.\n // At the time this special handler is invoked, all children have already been morphed\n // and appended to / removed from fromEl, so using fromEl here is safe and correct.\n var curChild = fromEl.firstChild;\n var optgroup;\n var nodeName;\n while(curChild) {\n nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();\n if (nodeName === 'OPTGROUP') {\n optgroup = curChild;\n curChild = optgroup.firstChild;\n // handle empty optgroups\n if (!curChild) {\n curChild = optgroup.nextSibling;\n optgroup = null;\n }\n } else {\n if (nodeName === 'OPTION') {\n if (curChild.hasAttribute('selected')) {\n selectedIndex = i;\n break;\n }\n i++;\n }\n curChild = curChild.nextSibling;\n if (!curChild && optgroup) {\n curChild = optgroup.nextSibling;\n optgroup = null;\n }\n }\n }\n\n fromEl.selectedIndex = selectedIndex;\n }\n }\n};\n\nvar ELEMENT_NODE = 1;\nvar DOCUMENT_FRAGMENT_NODE$1 = 11;\nvar TEXT_NODE = 3;\nvar COMMENT_NODE = 8;\n\nfunction noop() {}\n\nfunction defaultGetNodeKey(node) {\n if (node) {\n return (node.getAttribute && node.getAttribute('id')) || node.id;\n }\n}\n\nfunction morphdomFactory(morphAttrs) {\n\n return function morphdom(fromNode, toNode, options) {\n if (!options) {\n options = {};\n }\n\n if (typeof toNode === 'string') {\n if (fromNode.nodeName === '#document' || fromNode.nodeName === 'HTML' || fromNode.nodeName === 'BODY') {\n var toNodeHtml = toNode;\n toNode = doc.createElement('html');\n toNode.innerHTML = toNodeHtml;\n } else {\n toNode = toElement(toNode);\n }\n } else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) {\n toNode = toNode.firstElementChild;\n }\n\n var getNodeKey = options.getNodeKey || defaultGetNodeKey;\n var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;\n var onNodeAdded = options.onNodeAdded || noop;\n var onBeforeElUpdated = options.onBeforeElUpdated || noop;\n var onElUpdated = options.onElUpdated || noop;\n var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;\n var onNodeDiscarded = options.onNodeDiscarded || noop;\n var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;\n var skipFromChildren = options.skipFromChildren || noop;\n var addChild = options.addChild || function(parent, child){ return parent.appendChild(child); };\n var childrenOnly = options.childrenOnly === true;\n\n // This object is used as a lookup to quickly find all keyed elements in the original DOM tree.\n var fromNodesLookup = Object.create(null);\n var keyedRemovalList = [];\n\n function addKeyedRemoval(key) {\n keyedRemovalList.push(key);\n }\n\n function walkDiscardedChildNodes(node, skipKeyedNodes) {\n if (node.nodeType === ELEMENT_NODE) {\n var curChild = node.firstChild;\n while (curChild) {\n\n var key = undefined;\n\n if (skipKeyedNodes && (key = getNodeKey(curChild))) {\n // If we are skipping keyed nodes then we add the key\n // to a list so that it can be handled at the very end.\n addKeyedRemoval(key);\n } else {\n // Only report the node as discarded if it is not keyed. We do this because\n // at the end we loop through all keyed elements that were unmatched\n // and then discard them in one final pass.\n onNodeDiscarded(curChild);\n if (curChild.firstChild) {\n walkDiscardedChildNodes(curChild, skipKeyedNodes);\n }\n }\n\n curChild = curChild.nextSibling;\n }\n }\n }\n\n /**\n * Removes a DOM node out of the original DOM\n *\n * @param {Node} node The node to remove\n * @param {Node} parentNode The nodes parent\n * @param {Boolean} skipKeyedNodes If true then elements with keys will be skipped and not discarded.\n * @return {undefined}\n */\n function removeNode(node, parentNode, skipKeyedNodes) {\n if (onBeforeNodeDiscarded(node) === false) {\n return;\n }\n\n if (parentNode) {\n parentNode.removeChild(node);\n }\n\n onNodeDiscarded(node);\n walkDiscardedChildNodes(node, skipKeyedNodes);\n }\n\n // // TreeWalker implementation is no faster, but keeping this around in case this changes in the future\n // function indexTree(root) {\n // var treeWalker = document.createTreeWalker(\n // root,\n // NodeFilter.SHOW_ELEMENT);\n //\n // var el;\n // while((el = treeWalker.nextNode())) {\n // var key = getNodeKey(el);\n // if (key) {\n // fromNodesLookup[key] = el;\n // }\n // }\n // }\n\n // // NodeIterator implementation is no faster, but keeping this around in case this changes in the future\n //\n // function indexTree(node) {\n // var nodeIterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT);\n // var el;\n // while((el = nodeIterator.nextNode())) {\n // var key = getNodeKey(el);\n // if (key) {\n // fromNodesLookup[key] = el;\n // }\n // }\n // }\n\n function indexTree(node) {\n if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) {\n var curChild = node.firstChild;\n while (curChild) {\n var key = getNodeKey(curChild);\n if (key) {\n fromNodesLookup[key] = curChild;\n }\n\n // Walk recursively\n indexTree(curChild);\n\n curChild = curChild.nextSibling;\n }\n }\n }\n\n indexTree(fromNode);\n\n function handleNodeAdded(el) {\n onNodeAdded(el);\n\n var curChild = el.firstChild;\n while (curChild) {\n var nextSibling = curChild.nextSibling;\n\n var key = getNodeKey(curChild);\n if (key) {\n var unmatchedFromEl = fromNodesLookup[key];\n // if we find a duplicate #id node in cache, replace `el` with cache value\n // and morph it to the child node.\n if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) {\n curChild.parentNode.replaceChild(unmatchedFromEl, curChild);\n morphEl(unmatchedFromEl, curChild);\n } else {\n handleNodeAdded(curChild);\n }\n } else {\n // recursively call for curChild and it's children to see if we find something in\n // fromNodesLookup\n handleNodeAdded(curChild);\n }\n\n curChild = nextSibling;\n }\n }\n\n function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) {\n // We have processed all of the \"to nodes\". If curFromNodeChild is\n // non-null then we still have some from nodes left over that need\n // to be removed\n while (curFromNodeChild) {\n var fromNextSibling = curFromNodeChild.nextSibling;\n if ((curFromNodeKey = getNodeKey(curFromNodeChild))) {\n // Since the node is keyed it might be matched up later so we defer\n // the actual removal to later\n addKeyedRemoval(curFromNodeKey);\n } else {\n // NOTE: we skip nested keyed nodes from being removed since there is\n // still a chance they will be matched up later\n removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */);\n }\n curFromNodeChild = fromNextSibling;\n }\n }\n\n function morphEl(fromEl, toEl, childrenOnly) {\n var toElKey = getNodeKey(toEl);\n\n if (toElKey) {\n // If an element with an ID is being morphed then it will be in the final\n // DOM so clear it out of the saved elements collection\n delete fromNodesLookup[toElKey];\n }\n\n if (!childrenOnly) {\n // optional\n var beforeUpdateResult = onBeforeElUpdated(fromEl, toEl);\n if (beforeUpdateResult === false) {\n return;\n } else if (beforeUpdateResult instanceof HTMLElement) {\n fromEl = beforeUpdateResult;\n // reindex the new fromEl in case it's not in the same\n // tree as the original fromEl\n // (Phoenix LiveView sometimes returns a cloned tree,\n // but keyed lookups would still point to the original tree)\n indexTree(fromEl);\n }\n\n // update attributes on original DOM element first\n morphAttrs(fromEl, toEl);\n // optional\n onElUpdated(fromEl);\n\n if (onBeforeElChildrenUpdated(fromEl, toEl) === false) {\n return;\n }\n }\n\n if (fromEl.nodeName !== 'TEXTAREA') {\n morphChildren(fromEl, toEl);\n } else {\n specialElHandlers.TEXTAREA(fromEl, toEl);\n }\n }\n\n function morphChildren(fromEl, toEl) {\n var skipFrom = skipFromChildren(fromEl, toEl);\n var curToNodeChild = toEl.firstChild;\n var curFromNodeChild = fromEl.firstChild;\n var curToNodeKey;\n var curFromNodeKey;\n\n var fromNextSibling;\n var toNextSibling;\n var matchingFromEl;\n\n // walk the children\n outer: while (curToNodeChild) {\n toNextSibling = curToNodeChild.nextSibling;\n curToNodeKey = getNodeKey(curToNodeChild);\n\n // walk the fromNode children all the way through\n while (!skipFrom && curFromNodeChild) {\n fromNextSibling = curFromNodeChild.nextSibling;\n\n if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {\n curToNodeChild = toNextSibling;\n curFromNodeChild = fromNextSibling;\n continue outer;\n }\n\n curFromNodeKey = getNodeKey(curFromNodeChild);\n\n var curFromNodeType = curFromNodeChild.nodeType;\n\n // this means if the curFromNodeChild doesnt have a match with the curToNodeChild\n var isCompatible = undefined;\n\n if (curFromNodeType === curToNodeChild.nodeType) {\n if (curFromNodeType === ELEMENT_NODE) {\n // Both nodes being compared are Element nodes\n\n if (curToNodeKey) {\n // The target node has a key so we want to match it up with the correct element\n // in the original DOM tree\n if (curToNodeKey !== curFromNodeKey) {\n // The current element in the original DOM tree does not have a matching key so\n // let's check our lookup to see if there is a matching element in the original\n // DOM tree\n if ((matchingFromEl = fromNodesLookup[curToNodeKey])) {\n if (fromNextSibling === matchingFromEl) {\n // Special case for single element removals. To avoid removing the original\n // DOM node out of the tree (since that can break CSS transitions, etc.),\n // we will instead discard the current node and wait until the next\n // iteration to properly match up the keyed target element with its matching\n // element in the original tree\n isCompatible = false;\n } else {\n // We found a matching keyed element somewhere in the original DOM tree.\n // Let's move the original DOM node into the current position and morph\n // it.\n\n // NOTE: We use insertBefore instead of replaceChild because we want to go through\n // the `removeNode()` function for the node that is being discarded so that\n // all lifecycle hooks are correctly invoked\n fromEl.insertBefore(matchingFromEl, curFromNodeChild);\n\n // fromNextSibling = curFromNodeChild.nextSibling;\n\n if (curFromNodeKey) {\n // Since the node is keyed it might be matched up later so we defer\n // the actual removal to later\n addKeyedRemoval(curFromNodeKey);\n } else {\n // NOTE: we skip nested keyed nodes from being removed since there is\n // still a chance they will be matched up later\n removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */);\n }\n\n curFromNodeChild = matchingFromEl;\n curFromNodeKey = getNodeKey(curFromNodeChild);\n }\n } else {\n // The nodes are not compatible since the \"to\" node has a key and there\n // is no matching keyed node in the source tree\n isCompatible = false;\n }\n }\n } else if (curFromNodeKey) {\n // The original has a key\n isCompatible = false;\n }\n\n isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild);\n if (isCompatible) {\n // We found compatible DOM elements so transform\n // the current \"from\" node to match the current\n // target DOM node.\n // MORPH\n morphEl(curFromNodeChild, curToNodeChild);\n }\n\n } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) {\n // Both nodes being compared are Text or Comment nodes\n isCompatible = true;\n // Simply update nodeValue on the original node to\n // change the text value\n if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) {\n curFromNodeChild.nodeValue = curToNodeChild.nodeValue;\n }\n\n }\n }\n\n if (isCompatible) {\n // Advance both the \"to\" child and the \"from\" child since we found a match\n // Nothing else to do as we already recursively called morphChildren above\n curToNodeChild = toNextSibling;\n curFromNodeChild = fromNextSibling;\n continue outer;\n }\n\n // No compatible match so remove the old node from the DOM and continue trying to find a\n // match in the original DOM. However, we only do this if the from node is not keyed\n // since it is possible that a keyed node might match up with a node somewhere else in the\n // target tree and we don't want to discard it just yet since it still might find a\n // home in the final DOM tree. After everything is done we will remove any keyed nodes\n // that didn't find a home\n if (curFromNodeKey) {\n // Since the node is keyed it might be matched up later so we defer\n // the actual removal to later\n addKeyedRemoval(curFromNodeKey);\n } else {\n // NOTE: we skip nested keyed nodes from being removed since there is\n // still a chance they will be matched up later\n removeNode(curFromNodeChild, fromEl, true /* skip keyed nodes */);\n }\n\n curFromNodeChild = fromNextSibling;\n } // END: while(curFromNodeChild) {}\n\n // If we got this far then we did not find a candidate match for\n // our \"to node\" and we exhausted all of the children \"from\"\n // nodes. Therefore, we will just append the current \"to\" node\n // to the end\n if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {\n // MORPH\n if(!skipFrom){ addChild(fromEl, matchingFromEl); }\n morphEl(matchingFromEl, curToNodeChild);\n } else {\n var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);\n if (onBeforeNodeAddedResult !== false) {\n if (onBeforeNodeAddedResult) {\n curToNodeChild = onBeforeNodeAddedResult;\n }\n\n if (curToNodeChild.actualize) {\n curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);\n }\n addChild(fromEl, curToNodeChild);\n handleNodeAdded(curToNodeChild);\n }\n }\n\n curToNodeChild = toNextSibling;\n curFromNodeChild = fromNextSibling;\n }\n\n cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey);\n\n var specialElHandler = specialElHandlers[fromEl.nodeName];\n if (specialElHandler) {\n specialElHandler(fromEl, toEl);\n }\n } // END: morphChildren(...)\n\n var morphedNode = fromNode;\n var morphedNodeType = morphedNode.nodeType;\n var toNodeType = toNode.nodeType;\n\n if (!childrenOnly) {\n // Handle the case where we are given two DOM nodes that are not\n // compatible (e.g. <div> --> <span> or <div> --> TEXT)\n if (morphedNodeType === ELEMENT_NODE) {\n if (toNodeType === ELEMENT_NODE) {\n if (!compareNodeNames(fromNode, toNode)) {\n onNodeDiscarded(fromNode);\n morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));\n }\n } else {\n // Going from an element node to a text node\n morphedNode = toNode;\n }\n } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) { // Text or comment node\n if (toNodeType === morphedNodeType) {\n if (morphedNode.nodeValue !== toNode.nodeValue) {\n morphedNode.nodeValue = toNode.nodeValue;\n }\n\n return morphedNode;\n } else {\n // Text node to something else\n morphedNode = toNode;\n }\n }\n }\n\n if (morphedNode === toNode) {\n // The \"to node\" was not compatible with the \"from node\" so we had to\n // toss out the \"from node\" and use the \"to node\"\n onNodeDiscarded(fromNode);\n } else {\n if (toNode.isSameNode && toNode.isSameNode(morphedNode)) {\n return;\n }\n\n morphEl(morphedNode, toNode, childrenOnly);\n\n // We now need to loop over any keyed nodes that might need to be\n // removed. We only do the removal if we know that the keyed node\n // never found a match. When a keyed node is matched up we remove\n // it out of fromNodesLookup and we use fromNodesLookup to determine\n // if a keyed node has been matched up or not\n if (keyedRemovalList) {\n for (var i=0, len=keyedRemovalList.length; i<len; i++) {\n var elToRemove = fromNodesLookup[keyedRemovalList[i]];\n if (elToRemove) {\n removeNode(elToRemove, elToRemove.parentNode, false);\n }\n }\n }\n }\n\n if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {\n if (morphedNode.actualize) {\n morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc);\n }\n // If we had to swap out the from node with a new node because the old\n // node was not compatible with the target node then we need to\n // replace the old DOM node in the original DOM tree. This is only\n // possible if the original DOM node was part of a DOM tree which\n // we know is the case if it has a parent node.\n fromNode.parentNode.replaceChild(morphedNode, fromNode);\n }\n\n return morphedNode;\n };\n}\n\nvar morphdom = morphdomFactory(morphAttrs);\n\nexport default morphdom;\n", "import morphdom from '@substrate-system/morphdom'\n\nexport class TonicTemplate {\n rawText:string\n unsafe:boolean\n templateStrings?:string[]|TemplateStringsArray|null\n isTonicTemplate:true\n\n constructor (\n rawText,\n templateStrings?:string[]|TemplateStringsArray|null,\n unsafe?:boolean\n ) {\n this.isTonicTemplate = true\n this.unsafe = !!unsafe\n this.rawText = rawText\n this.templateStrings = templateStrings\n }\n\n valueOf () { return this.rawText }\n toString () { return this.rawText }\n}\n\n/**\n * Class Tonic\n *\n * @template {T extends object = Record<string, any>} T Type of the props\n */\nexport abstract class Tonic<\n T extends { [key:string]:any}=Record<string, any>\n> extends window.HTMLElement {\n private static _tags = ''\n private static _refIds:string[] = []\n private static _data = {}\n private static _states = {}\n private static _children = {}\n private static _reg = {}\n private static _stylesheetRegistry:(()=>string)[] = []\n private static _index = 0\n // @ts-expect-error VERSION is injected during build\n static get version () { return VERSION ?? null }\n static get SPREAD () { return /\\.\\.\\.\\s?(__\\w+__\\w+__)/g }\n static get ESC () { return /[\"&'<>`/]/g }\n static get AsyncFunctionGenerator ():AsyncGeneratorFunctionConstructor {\n return (async function * () {\n }.constructor) as AsyncGeneratorFunctionConstructor\n }\n // eslint-disable-next-line\n static get AsyncFunction ():Function {\n return (async function () {}.constructor)\n }\n\n static get MAP () {\n /* eslint-disable object-property-newline, object-property-newline,\n object-curly-newline */\n return { '\"': '&quot;', '&': '&amp;', '\\'': '&#x27;', '<': '&lt;',\n '>': '&gt;', '`': '&#x60;', '/': '&#x2F;' }\n }\n\n static ssr\n static nonce\n static _hydrating:boolean = false\n static _ssrState:Record<string, any>|null = null\n\n private _state:any\n declare stylesheet?:()=>string\n declare styles?:()=>string\n props:T\n preventRenderOnReconnect:boolean\n private _id?:string\n pendingReRender?:Promise<this>|null\n declare updated?:((props:Record<string, any>)=>any)\n declare willRender?:(()=>any)\n root?:ShadowRoot|this\n declare willConnect?:()=>any\n private _source?:string\n declare connected?:()=>void\n declare disconnected?:()=>void\n\n private elements:Element[] & { __children__? }\n private nodes:ChildNode[] & { __children__? }\n private _props = Tonic.getPropertyNames(this)\n\n constructor () {\n super()\n const state = Tonic._states[super.id]\n delete Tonic._states[super.id]\n this._state = state || {}\n this.preventRenderOnReconnect = false\n this.props = {} as T\n this.elements = [...this.children]\n this.elements.__children__ = true\n this.nodes = [...this.childNodes]\n this.nodes.__children__ = true\n this._events()\n }\n\n abstract render ():TonicTemplate|Promise<TonicTemplate>\n\n defaults ():Record<string, any> {\n return {}\n }\n\n get isTonicComponent ():true {\n return true\n }\n\n /**\n * Get a namespaced event name, given a non-namespaced string.\n *\n * @example\n * MyElement.event('example') // => my-element:example\n *\n * @param {string} type The name of the event\n * @returns {string} The namespaced event name\n */\n static event (type:string):string {\n return `${this.TAG}:${type}`\n }\n\n /**\n * Get the tag name of this component.\n */\n static get TAG ():string {\n return Tonic.getTagName(this.name)\n }\n\n private static _createId () {\n return `tonic${Tonic._index++}`\n }\n\n private static _normalizeAttrs (o, x = {}) {\n [...o].forEach(o => (x[o.name] = o.value))\n return x\n }\n\n private _checkId () {\n const _id = super.id\n if (!_id) {\n const html = this.outerHTML.replace(this.innerHTML, '...')\n throw new Error(`Component: ${html} has no id`)\n }\n return _id\n }\n\n /**\n * Get the component state property.\n */\n get state () {\n return (this._checkId(), this._state)\n }\n\n set state (newState) {\n this._state = (this._checkId(), newState)\n }\n\n private _events () {\n const hp = Object.getOwnPropertyNames(window.HTMLElement.prototype)\n // this is where we map methods like `handle_click` to event handlers.\n // look at the HTMLElement prototype, and if it is has a method like\n // `onclick`, then add an event listener for 'click'\n for (const p of this._props) {\n if (!p.includes('handle_')) continue\n const evName = p.split('_')[1]\n\n if (hp.indexOf('on' + evName) === -1) continue\n this.addEventListener(evName, this)\n }\n }\n\n private _prop (o) {\n const id = this._id!\n const p = `__${id}__${Tonic._createId()}__`\n Tonic._data[id] = Tonic._data[id] || {}\n Tonic._data[id][p] = o\n return p\n }\n\n private _placehold (r) {\n const id = this._id!\n const ref = `placehold:${id}:${Tonic._createId()}__`\n Tonic._children[id] = Tonic._children[id] || {}\n Tonic._children[id][ref] = r\n return ref\n }\n\n static match (el:HTMLElement, s:string) {\n if (!el.matches) el = el.parentElement!\n return el.matches(s) ? el : el.closest(s)\n }\n\n static getTagName (camelName:string) {\n return camelName.match(/[A-Z][a-z0-9]*/g)!.join('-').toLowerCase()\n }\n\n /**\n * Add all methods to this._props\n */\n static getPropertyNames (proto) {\n const props:string[] = []\n while (proto && proto !== Tonic.prototype) {\n props.push(...Object.getOwnPropertyNames(proto))\n proto = Object.getPrototypeOf(proto)\n }\n return props\n }\n\n /**\n * Add a component. Calls `window.customElements.define` with the\n * component's name.\n *\n * @param {Tonic} c Component to add\n * @param {string} [htmlName] Name of the element, default to the class name\n * @returns {Tonic}\n */\n static add (c, htmlName?:string) {\n const hasValidName = htmlName || (c.name && c.name.length > 1)\n if (!hasValidName) {\n throw Error('Mangling. https://bit.ly/2TkJ6zP')\n }\n\n if (!htmlName) htmlName = Tonic.getTagName(c.name)\n if (!Tonic.ssr && window.customElements.get(htmlName)) {\n throw new Error(`Cannot Tonic.add(${c.name}, '${htmlName}') twice`)\n }\n\n if (!c.prototype || !c.prototype.isTonicComponent) {\n const tmp = { [c.name]: class extends Tonic {\n render () {\n return new TonicTemplate('', null)\n }\n } }[c.name]\n tmp.prototype.render = c\n c = tmp\n }\n\n c.prototype._props = Tonic.getPropertyNames(c.prototype)\n\n Tonic._reg[htmlName] = c\n Tonic._tags = Object.keys(Tonic._reg).join()\n window.customElements.define(htmlName, c as unknown as\n CustomElementConstructor)\n\n if (typeof c.stylesheet === 'function') {\n Tonic.registerStyles(c.stylesheet)\n }\n\n return c\n }\n\n static registerStyles (stylesheetFn:()=>string) {\n if (Tonic._stylesheetRegistry.includes(stylesheetFn)) return\n Tonic._stylesheetRegistry.push(stylesheetFn)\n\n const styleNode = document.createElement('style')\n if (Tonic.nonce) styleNode.setAttribute('nonce', Tonic.nonce)\n styleNode.appendChild(document.createTextNode(stylesheetFn()))\n if (document.head) document.head.appendChild(styleNode)\n }\n\n static escape (s:string):string {\n return s.replace(Tonic.ESC, c => Tonic.MAP[c])\n }\n\n static unsafeRawString (\n s:string,\n templateStrings:string[]\n ):InstanceType<typeof TonicTemplate> {\n return new TonicTemplate(s, templateStrings, true)\n }\n\n /**\n * Emit a regular, non-namespaced event.\n *\n * @param {string} eventName Event name as a string.\n * @param {any} detail Any data to go with the event.\n */\n dispatch (eventName:string, detail:any = null):void {\n const opts = { bubbles: true, detail }\n this.dispatchEvent(new window.CustomEvent(eventName, opts))\n }\n\n /**\n * Emit a namespaced event, using a convention for event names.\n *\n * @example\n * myComponent.emit('test') // => `my-compnent:test`\n *\n * @param {string} type The event type, comes after `:` in event name.\n * @param {string|object|any[]} detail detail for Event constructor\n * @param {{ bubbles?:boolean, cancelable?:boolean }} opts `Cancelable` and\n * `bubbles`\n * @returns {boolean}\n */\n emit (type:string, detail:string|object|any[] = {}, opts:Partial<{\n bubbles:boolean;\n cancelable:boolean\n }> = {}):boolean {\n const namespace = Tonic.getTagName(this.constructor.name)\n const event = new CustomEvent(`${namespace}:${type}`, {\n bubbles: (opts.bubbles === undefined) ? true : opts.bubbles,\n cancelable: (opts.cancelable === undefined) ? true : opts.cancelable,\n detail\n })\n\n return this.dispatchEvent(event)\n }\n\n html (\n strings:string[]|TemplateStringsArray,\n ...values\n ):InstanceType<typeof TonicTemplate> {\n const refs = o => {\n if (o && o.__children__) return this._placehold(o)\n if (o && o.isTonicTemplate) return o.rawText\n switch (Object.prototype.toString.call(o)) {\n case '[object HTMLCollection]':\n case '[object NodeList]': return this._placehold([...o])\n case '[object Array]': {\n if (o.every(x => x.isTonicTemplate && !x.unsafe)) {\n return new TonicTemplate(o.join('\\n'), null, false)\n }\n return this._prop(o)\n }\n case '[object Object]':\n case '[object Function]':\n case '[object AsyncFunction]':\n case '[object Set]':\n case '[object Map]':\n case '[object WeakMap]':\n case '[object File]':\n return this._prop(o)\n case '[object NamedNodeMap]':\n return this._prop(Tonic._normalizeAttrs(o))\n case '[object Number]': return `${o}__float`\n case '[object String]': return Tonic.escape(o)\n case '[object Boolean]': return `${o}__boolean`\n case '[object Null]': return `${o}__null`\n case '[object HTMLElement]':\n return this._placehold([o])\n }\n if (\n typeof o === 'object' && o && o.nodeType === 1 &&\n typeof o.cloneNode === 'function'\n ) {\n return this._placehold([o])\n }\n return o\n }\n\n const out:string[] = []\n for (let i = 0; i < strings.length - 1; i++) {\n out.push(strings[i], refs(values[i]))\n }\n out.push(strings[strings.length - 1])\n\n const htmlStr = out.join('').replace(Tonic.SPREAD, (_, p) => {\n const o = Tonic._data[p.split('__')[1]][p]\n return Object.entries(o).map(([key, value]) => {\n const k = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()\n if (value === true) return k\n else if (value) return `${k}=\"${Tonic.escape(String(value))}\"`\n else return ''\n }).filter(Boolean).join(' ')\n })\n // Process type markers in template content\n .replace(/(\\d+(?:\\.\\d+)?)__float/g, '$1')\n .replace(/(true|false)__boolean/g, '$1')\n .replace(/null__null/g, 'null')\n\n return new TonicTemplate(htmlStr, strings, false)\n }\n\n scheduleReRender (oldProps:any):Promise<this> {\n if (this.pendingReRender) return this.pendingReRender\n\n this.pendingReRender = new Promise(resolve => setTimeout(() => {\n if (!this.isInDocument(this.shadowRoot || this)) return\n const p = this._set(this.shadowRoot || this, this.render)\n this.pendingReRender = null\n\n if (p && p.then) {\n return p.then(() => {\n this.updated && this.updated(oldProps)\n resolve(this)\n })\n }\n\n this.updated && this.updated(oldProps)\n resolve(this)\n }, 0))\n\n return this.pendingReRender\n }\n\n /**\n * Update the view\n */\n reRender (o:T|((props:T)=>T) = this.props):Promise<this> {\n const oldProps = { ...this.props }\n this.props = typeof o === 'function' ? (o as (props:T)=>T)(oldProps) : o\n return this.scheduleReRender(oldProps)\n }\n\n /**\n * If there is a method with the same name as the event type,\n * then call the method.\n * @see {@link https://gomakethings.com/the-handleevent-method-is-the-absolute-best-way-to-handle-events-in-web-components/#what-is-the-handleevent-method What is the handleEvent() method?}\n */\n handleEvent (ev:Event):void {\n this['handle_' + ev.type] && this['handle_' + ev.type](ev)\n }\n\n private _drainIterator (target, iterator) {\n return iterator.next().then((result) => {\n this._set(target, null, result.value)\n if (result.done) return\n return this._drainIterator(target, iterator)\n })\n }\n\n /**\n * _set\n * @param {Element|InstanceType<typeof Tonic>|ShadowRoot} target\n * @param {()=>any} render\n * @param {string} content\n * @returns {Promise<void>|void}\n * @private\n */\n private _set (target, render, content = ''):Promise<void>|void {\n this.willRender && this.willRender()\n for (const node of target.querySelectorAll(Tonic._tags)) {\n if (!node.isTonicComponent) continue\n\n const id = node.getAttribute('id')\n if (!id || !Tonic._refIds.includes(id)) continue\n Tonic._states[id] = node.state\n }\n\n if (render instanceof Tonic.AsyncFunction) {\n return ((render as (...args:any)=>any)\n .call(this, this.html, this.props)\n .then(content => this._apply(target, content))\n )\n } else if (render instanceof Tonic.AsyncFunctionGenerator) {\n return this._drainIterator(\n target,\n (render as AsyncGeneratorFunction).call(this))\n } else if (render === null) {\n this._apply(target, content)\n } else if (render instanceof Function) {\n this._apply(target, render.call(this, this.html, this.props) || '')\n }\n }\n\n private _apply (target, content) {\n if (content && content.isTonicTemplate) {\n content = content.rawText\n } else if (typeof content === 'string') {\n content = Tonic.escape(content)\n }\n\n if (typeof content === 'string') {\n if (this.stylesheet) {\n content = `<style nonce=${Tonic.nonce || ''}>${this.stylesheet()}</style>${content}`\n }\n\n // Check if we should use morphdom for DOM state\n // preservation (cursor position, selection, focus)\n const hasFormElements = target.querySelector && (\n target.querySelector('input') ||\n target.querySelector('textarea') ||\n target.querySelector('select')\n )\n\n const shouldUseMorphdom = (\n hasFormElements &&\n document.activeElement &&\n (\n target.contains(document.activeElement) ||\n target === document.activeElement\n )\n )\n\n if (shouldUseMorphdom) {\n // Use morphdom to preserve DOM state\n const tempContainer =\n document.createElement('div')\n tempContainer.innerHTML = content\n\n morphdom(target, tempContainer, {\n childrenOnly: true,\n onBeforeElUpdated: (fromEl, toEl) => {\n if (\n fromEl.isEqualNode &&\n fromEl.isEqualNode(toEl)\n ) {\n return false\n }\n\n // For inputs, preserve value\n // and selection\n if (\n fromEl.tagName === 'INPUT' &&\n toEl.tagName === 'INPUT'\n ) {\n const fromInput =\n fromEl as HTMLInputElement\n const toInput =\n toEl as HTMLInputElement\n\n if (fromInput.value !== '') {\n toInput.value =\n fromInput.value\n }\n\n if (\n document.activeElement ===\n fromInput\n ) {\n toInput.setAttribute(\n 'data-preserve-focus',\n 'true')\n toInput.setAttribute(\n 'data-selection-start',\n String(\n fromInput\n .selectionStart\n || 0\n ))\n toInput.setAttribute(\n 'data-selection-end',\n String(\n fromInput\n .selectionEnd\n || 0\n ))\n }\n }\n\n // For textareas, preserve value\n // and selection\n if (\n fromEl.tagName === 'TEXTAREA' &&\n toEl.tagName === 'TEXTAREA'\n ) {\n const fromTa =\n fromEl as HTMLTextAreaElement\n const toTa =\n toEl as HTMLTextAreaElement\n\n if (fromTa.value !== '') {\n toTa.value = fromTa.value\n }\n\n if (\n document.activeElement ===\n fromTa\n ) {\n toTa.setAttribute(\n 'data-preserve-focus',\n 'true')\n toTa.setAttribute(\n 'data-selection-start',\n String(\n fromTa\n .selectionStart\n || 0\n ))\n toTa.setAttribute(\n 'data-selection-end',\n String(\n fromTa\n .selectionEnd\n || 0\n ))\n }\n }\n\n return true\n },\n\n onElUpdated: (el) => {\n if (\n !el.hasAttribute(\n 'data-preserve-focus'\n )\n ) return\n\n const startPos = parseInt(\n el.getAttribute(\n 'data-selection-start'\n ) || '0',\n 10\n )\n const endPos = parseInt(\n el.getAttribute(\n 'data-selection-end'\n ) || '0',\n 10\n )\n\n el.removeAttribute(\n 'data-preserve-focus')\n el.removeAttribute(\n 'data-selection-start')\n el.removeAttribute(\n 'data-selection-end')\n\n el.focus()\n if ('setSelectionRange' in el) {\n (el as\n HTMLInputElement |\n HTMLTextAreaElement\n ).setSelectionRange(\n startPos,\n endPos\n )\n }\n }\n })\n } else {\n // Save user-modified form values by\n // position so they survive innerHTML\n // replacement. Only save when the user\n // changed the value (value !== default).\n type FormEl = HTMLInputElement |\n HTMLTextAreaElement |\n HTMLSelectElement\n const selector =\n 'input, textarea, select'\n const saved:\n { v:string; c:boolean; dirty:boolean }[]\n = []\n if (hasFormElements) {\n const els = target.querySelectorAll(\n selector\n ) as NodeListOf<FormEl>\n for (const el of els) {\n const inp = el as HTMLInputElement\n const isCheck = (\n inp.type === 'checkbox' ||\n inp.type === 'radio'\n )\n saved.push({\n v: el.value,\n c: inp.checked,\n dirty: isCheck ?\n inp.checked !==\n inp.defaultChecked :\n el.value !==\n (el as HTMLInputElement)\n .defaultValue\n })\n }\n }\n\n target.innerHTML = content\n\n if (saved.length) {\n const els = target.querySelectorAll(\n selector\n ) as NodeListOf<FormEl>\n for (\n let i = 0;\n i < Math.min(\n saved.length,\n els.length\n );\n i++\n ) {\n if (!saved[i].dirty) continue\n const el = els[i]\n const type =\n (el as HTMLInputElement).type\n if (\n type === 'checkbox' ||\n type === 'radio'\n ) {\n (el as HTMLInputElement)\n .checked = saved[i].c\n } else {\n el.value = saved[i].v\n }\n }\n }\n }\n\n if (this.styles) {\n const styles = this.styles()\n for (const node of target.querySelectorAll('[styles]')) {\n for (const s of node.getAttribute('styles').split(/\\s+/)) {\n Object.assign(node.style, styles[s.trim()])\n }\n }\n }\n\n const children = Tonic._children[this._id!] || {}\n\n const walk = (node, fn) => {\n if (node.nodeType === 3) {\n const id = node.textContent.trim()\n if (children[id]) fn(node, children[id], id)\n }\n\n const childNodes = node.childNodes\n if (!childNodes) return\n\n for (let i = 0; i < childNodes.length; i++) {\n walk(childNodes[i], fn)\n }\n }\n\n walk(target, (node, children, id) => {\n for (const child of children) {\n node.parentNode.insertBefore(child, node)\n }\n delete Tonic._children[this._id!][id]\n node.parentNode.removeChild(node)\n })\n } else {\n target.innerHTML = ''\n target.appendChild(content.cloneNode(true))\n }\n }\n\n connectedCallback () {\n this.root = this.shadowRoot || this // here for back compat\n\n if (super.id && !Tonic._refIds.includes(super.id)) {\n Tonic._refIds.push(super.id)\n }\n const cc = s => s.replace(/-(.)/g, (_, m) => m.toUpperCase())\n\n for (const { name: _name, value } of this.attributes) {\n const name = cc(_name)\n const p = (this.props as { [key:string]:any })[name] = value\n\n if (/__\\w+__\\w+__/.test(p)) {\n const { 1: root } = p.split('__');\n (this.props as { [key:string]:any })[name] = Tonic._data[root][p]\n } else if (/\\d+__float/.test(p)) {\n (this.props as { [key:string]:any })[name] = parseFloat(p)\n } else if (p === 'null__null') {\n (this.props as { [key:string]:any })[name] = null\n } else if (/\\w+__boolean/.test(p)) {\n (this.props as { [key:string]:any })[name] = p.includes('true')\n } else if (/placehold:\\w+:\\w+__/.test(p)) {\n const { 1: root } = p.split(':');\n (this.props as { [key:string]:any })[name] =\n Tonic._children[root][p][0]\n }\n }\n\n this.props = Object.assign(\n this.defaults(),\n this.props\n )\n\n this._id = this._id || Tonic._createId()\n\n this.willConnect && this.willConnect()\n\n if (!this.isInDocument(this.root)) return\n\n if (Tonic._hydrating) {\n if (super.id && Tonic._ssrState?.[super.id]) {\n this.props = Object.assign(\n this.props,\n Tonic._ssrState[super.id]\n )\n }\n this._source = this.innerHTML\n this.connected && this.connected()\n return\n }\n\n if (!this.preventRenderOnReconnect) {\n if (!this._source) {\n this._source = this.innerHTML\n } else {\n this.innerHTML = this._source\n }\n const p = this._set(this.root, this.render)\n if (p && p.then) {\n return p.then(() => this.connected && this.connected())\n }\n }\n\n this.connected && this.connected()\n }\n\n isInDocument (target:HTMLElement|ShadowRoot):boolean {\n const root = target.getRootNode()\n return root === document || root.toString() === '[object ShadowRoot]'\n }\n\n disconnectedCallback ():void {\n this.disconnected && this.disconnected()\n delete Tonic._data[this._id!]\n delete Tonic._children[this._id!]\n }\n}\n\nexport default Tonic\n", "import { Tonic } from './index.js'\n\n/**\n * Hydrate server-rendered Tonic components.\n *\n * Call this to wrap component registration so that existing\n * server-rendered DOM is preserved instead of being re-rendered.\n * Event handlers are still attached, props are parsed from\n * attributes, and lifecycle hooks (`willConnect`, `connected`)\n * are called.\n *\n * If a `<script type=\"application/json\" data-tonic-ssr>` tag\n * exists in the document, its JSON content is parsed and used\n * to restore complex props (objects, arrays) for components\n * with matching `id` attributes.\n *\n * @param callback Register your components inside this callback\n * @returns The parsed SSR state, or null if none was embedded\n *\n * @example\n * ```ts\n * import { hydrate } from '@substrate-system/tonic/hydrate'\n * import { Tonic } from '@substrate-system/tonic'\n * import { MyApp } from './components.js'\n *\n * const state = hydrate(() => {\n * Tonic.add(MyApp)\n * })\n * ```\n */\nexport function hydrate (\n callback:() => void\n):Record<string, any>|null {\n const script = document.querySelector(\n 'script[data-tonic-ssr]'\n )\n\n const state:Record<string, any>|null = script ?\n JSON.parse(script.textContent || '{}') :\n null\n\n Tonic._ssrState = state\n Tonic._hydrating = true\n\n callback()\n\n Tonic._hydrating = false\n Tonic._ssrState = null\n\n return state\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["DOCUMENT_FRAGMENT_NODE", "morphAttrs", "fromNode", "toNode", "toNodeAttrs", "attr", "attrName", "attrNamespaceURI", "attrValue", "fromValue", "i", "fromNodeAttrs", "d", "__name", "range", "NS_XHTML", "doc", "HAS_TEMPLATE_SUPPORT", "HAS_RANGE_SUPPORT", "createFragmentFromTemplate", "str", "template", "createFragmentFromRange", "fragment", "createFragmentFromWrap", "toElement", "compareNodeNames", "fromEl", "toEl", "fromNodeName", "toNodeName", "fromCodeStart", "toCodeStart", "createElementNS", "name", "namespaceURI", "moveChildren", "curChild", "nextChild", "syncBooleanAttrProp", "specialElHandlers", "parentNode", "parentName", "newValue", "firstChild", "oldValue", "selectedIndex", "optgroup", "nodeName", "ELEMENT_NODE", "DOCUMENT_FRAGMENT_NODE$1", "TEXT_NODE", "COMMENT_NODE", "noop", "defaultGetNodeKey", "node", "morphdomFactory", "options", "toNodeHtml", "getNodeKey", "onBeforeNodeAdded", "onNodeAdded", "onBeforeElUpdated", "onElUpdated", "onBeforeNodeDiscarded", "onNodeDiscarded", "onBeforeElChildrenUpdated", "skipFromChildren", "addChild", "parent", "child", "childrenOnly", "fromNodesLookup", "keyedRemovalList", "addKeyedRemoval", "key", "walkDiscardedChildNodes", "skipKeyedNodes", "removeNode", "indexTree", "handleNodeAdded", "el", "nextSibling", "unmatchedFromEl", "morphEl", "cleanupFromEl", "curFromNodeChild", "curFromNodeKey", "fromNextSibling", "toElKey", "beforeUpdateResult", "morphChildren", "skipFrom", "curToNodeChild", "curToNodeKey", "toNextSibling", "matchingFromEl", "outer", "curFromNodeType", "isCompatible", "onBeforeNodeAddedResult", "specialElHandler", "morphedNode", "morphedNodeType", "toNodeType", "len", "elToRemove", "morphdom", "morphdom_esm_default", "TonicTemplate", "__name", "rawText", "templateStrings", "unsafe", "Tonic", "_Tonic", "state", "type", "o", "x", "_id", "html", "newState", "hp", "p", "evName", "id", "r", "ref", "el", "s", "camelName", "proto", "props", "c", "htmlName", "tmp", "stylesheetFn", "styleNode", "eventName", "detail", "opts", "namespace", "event", "strings", "values", "refs", "out", "i", "htmlStr", "_", "key", "value", "k", "oldProps", "resolve", "ev", "target", "iterator", "result", "render", "content", "node", "hasFormElements", "tempContainer", "morphdom_esm_default", "fromEl", "toEl", "fromInput", "toInput", "fromTa", "toTa", "startPos", "endPos", "selector", "saved", "els", "inp", "isCheck", "styles", "children", "walk", "fn", "childNodes", "child", "cc", "m", "_name", "name", "root", "hydrate", "callback", "script", "state", "Tonic", "__name"]
7
+ }
@@ -0,0 +1,20 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ import { Tonic } from "./index.js";
4
+ function hydrate(callback) {
5
+ const script = document.querySelector(
6
+ "script[data-tonic-ssr]"
7
+ );
8
+ const state = script ? JSON.parse(script.textContent || "{}") : null;
9
+ Tonic._ssrState = state;
10
+ Tonic._hydrating = true;
11
+ callback();
12
+ Tonic._hydrating = false;
13
+ Tonic._ssrState = null;
14
+ return state;
15
+ }
16
+ __name(hydrate, "hydrate");
17
+ export {
18
+ hydrate
19
+ };
20
+ //# sourceMappingURL=hydrate.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/hydrate.ts"],
4
+ "sourcesContent": ["import { Tonic } from './index.js'\n\n/**\n * Hydrate server-rendered Tonic components.\n *\n * Call this to wrap component registration so that existing\n * server-rendered DOM is preserved instead of being re-rendered.\n * Event handlers are still attached, props are parsed from\n * attributes, and lifecycle hooks (`willConnect`, `connected`)\n * are called.\n *\n * If a `<script type=\"application/json\" data-tonic-ssr>` tag\n * exists in the document, its JSON content is parsed and used\n * to restore complex props (objects, arrays) for components\n * with matching `id` attributes.\n *\n * @param callback Register your components inside this callback\n * @returns The parsed SSR state, or null if none was embedded\n *\n * @example\n * ```ts\n * import { hydrate } from '@substrate-system/tonic/hydrate'\n * import { Tonic } from '@substrate-system/tonic'\n * import { MyApp } from './components.js'\n *\n * const state = hydrate(() => {\n * Tonic.add(MyApp)\n * })\n * ```\n */\nexport function hydrate (\n callback:() => void\n):Record<string, any>|null {\n const script = document.querySelector(\n 'script[data-tonic-ssr]'\n )\n\n const state:Record<string, any>|null = script ?\n JSON.parse(script.textContent || '{}') :\n null\n\n Tonic._ssrState = state\n Tonic._hydrating = true\n\n callback()\n\n Tonic._hydrating = false\n Tonic._ssrState = null\n\n return state\n}\n"],
5
+ "mappings": ";;AAAA,SAAS,aAAa;AA8Bf,SAAS,QACZ,UACuB;AACvB,QAAM,SAAS,SAAS;AAAA,IACpB;AAAA,EACJ;AAEA,QAAM,QAAiC,SACnC,KAAK,MAAM,OAAO,eAAe,IAAI,IACrC;AAEJ,QAAM,YAAY;AAClB,QAAM,aAAa;AAEnB,WAAS;AAET,QAAM,aAAa;AACnB,QAAM,YAAY;AAElB,SAAO;AACX;AApBgB;",
6
+ "names": []
7
+ }