@substrate-system/tonic 16.1.3 → 17.0.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 +239 -37
- package/dist/index.cjs +8 -3
- package/dist/index.cjs.map +2 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +9 -4
- package/dist/index.js.map +2 -2
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +3 -3
- package/dist/index.min.mjs +3 -0
- package/dist/index.min.mjs.map +7 -0
- package/dist/index.mjs +536 -0
- package/dist/index.mjs.map +7 -0
- package/dist/meta.json +6 -6
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
# Tonic
|
|
10
10
|
|
|
11
|
-
Tonic is a low profile component framework for the web.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
Tonic is a low profile component framework for the web.
|
|
12
|
+
It's designed to be used with contemporary Javascript and is compatible
|
|
13
|
+
with all modern browsers. It's built on top of
|
|
14
|
+
[Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components).
|
|
15
15
|
|
|
16
16
|
[See the API docs](https://substrate-system.github.io/tonic/index.html)
|
|
17
17
|
|
|
@@ -24,15 +24,26 @@ with all modern browsers and built on top of Web Components.
|
|
|
24
24
|
- [Use](#use)
|
|
25
25
|
* [Bundler](#bundler)
|
|
26
26
|
* [Pre-bundled](#pre-bundled)
|
|
27
|
-
- [
|
|
28
|
-
|
|
29
|
-
* [
|
|
30
|
-
* [
|
|
31
|
-
* [
|
|
32
|
-
* [
|
|
27
|
+
- [Get Started](#get-started)
|
|
28
|
+
* [Register](#register)
|
|
29
|
+
* [HTML](#html-1)
|
|
30
|
+
* [Render](#render)
|
|
31
|
+
* [Rerender](#rerender)
|
|
32
|
+
* [Events](#events)
|
|
33
|
+
* [State](#state)
|
|
34
|
+
- [API](#api)
|
|
35
|
+
* [Event listeners](#event-listeners)
|
|
36
|
+
- [DOM state](#dom-state)
|
|
37
|
+
- [docs](#docs)
|
|
38
|
+
- [types](#types)
|
|
39
|
+
- [`tag`](#tag)
|
|
33
40
|
* [`emit`](#emit)
|
|
34
41
|
* [`static event`](#static-event)
|
|
35
42
|
* [`dispatch`](#dispatch)
|
|
43
|
+
- [Develop](#develop)
|
|
44
|
+
* [build ESM](#build-esm)
|
|
45
|
+
* [build Common JS](#build-common-js)
|
|
46
|
+
* [build UMD modules](#build-umd-modules)
|
|
36
47
|
- [Useful links](#useful-links)
|
|
37
48
|
|
|
38
49
|
<!-- tocstop -->
|
|
@@ -47,8 +58,11 @@ npm i -S @substrate-system/tonic
|
|
|
47
58
|
|
|
48
59
|
## tl;dr
|
|
49
60
|
|
|
50
|
-
|
|
61
|
+
This is a front-end view library, like React, but using web components.
|
|
51
62
|
|
|
63
|
+
> [!TIP]
|
|
64
|
+
> DOM state, such as element focus and input values, is preserved
|
|
65
|
+
> across multiple calls to `reRender`.
|
|
52
66
|
|
|
53
67
|
## Use
|
|
54
68
|
|
|
@@ -74,64 +88,218 @@ cp ./node_modules/@substrate-system/tonic/dist/index.min.js ./public/tonic.min.j
|
|
|
74
88
|
<script type="module" src="./tonic.min.js"></script>
|
|
75
89
|
```
|
|
76
90
|
|
|
77
|
-
|
|
91
|
+
-----------------------------------
|
|
78
92
|
|
|
79
|
-
|
|
80
|
-
|
|
93
|
+
## Get Started
|
|
94
|
+
|
|
95
|
+
Building a component with Tonic starts by creating a function or a
|
|
96
|
+
[class](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).
|
|
97
|
+
The class should have at least one method named *render* which returns
|
|
98
|
+
a [template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
|
|
99
|
+
of HTML.
|
|
81
100
|
|
|
82
101
|
```js
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
102
|
+
import Tonic from '@substrate-system/tonic'
|
|
103
|
+
|
|
104
|
+
class MyGreeting extends Tonic {
|
|
105
|
+
render () {
|
|
106
|
+
return this.html`<div>Hello, World.</div>`
|
|
107
|
+
}
|
|
86
108
|
}
|
|
87
109
|
```
|
|
88
110
|
|
|
89
|
-
|
|
111
|
+
or
|
|
90
112
|
|
|
91
113
|
```js
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const data = await (await fetch('https://example.com/data')).text()
|
|
97
|
-
return this.html`<div>Hello, ${data}.</div>`
|
|
98
|
-
}
|
|
114
|
+
function MyGreeting () {
|
|
115
|
+
return this.html`
|
|
116
|
+
<div>Hello, World.</div>
|
|
117
|
+
`
|
|
99
118
|
}
|
|
100
119
|
```
|
|
101
120
|
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
The HTML tag for your component will match the class or function name.
|
|
124
|
+
|
|
125
|
+
> [!NOTE]
|
|
126
|
+
> Tonic is a thin wrapper around `web components`. Web
|
|
127
|
+
> components require a name with two or more parts. So your class name should
|
|
128
|
+
> be `CamelCased` (starting with an uppercase letter). For example, `MyGreeting`
|
|
129
|
+
> becomes `<my-greeting></my-greeting>`.
|
|
130
|
+
>
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### Register
|
|
136
|
+
|
|
137
|
+
Next, register your component with `Tonic.add(ClassName)`.
|
|
138
|
+
|
|
102
139
|
```js
|
|
103
|
-
Tonic.add(MyGreeting
|
|
140
|
+
Tonic.add(MyGreeting)
|
|
104
141
|
```
|
|
105
142
|
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### HTML
|
|
146
|
+
|
|
106
147
|
After adding your Javascript to your HTML, you can use your component anywhere.
|
|
107
148
|
|
|
149
|
+
```html
|
|
150
|
+
<html>
|
|
151
|
+
<body>
|
|
152
|
+
<my-greeting></my-greeting>
|
|
153
|
+
|
|
154
|
+
<script src="index.js"></script>
|
|
155
|
+
</body>
|
|
156
|
+
</html>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
>
|
|
160
|
+
> [!NOTE]
|
|
161
|
+
> Custom tags (in all browsers) require a closing tag even if
|
|
162
|
+
> they have no children. Tonic doesn't add any "magic" to change how this works.
|
|
163
|
+
>
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### Render
|
|
168
|
+
|
|
169
|
+
When the component is rendered by the browser, the result of your render
|
|
170
|
+
function will be inserted into the component tag.
|
|
171
|
+
|
|
108
172
|
```html
|
|
109
173
|
<html>
|
|
110
174
|
<head>
|
|
111
|
-
<script src="
|
|
175
|
+
<script src="index.js"></script>
|
|
112
176
|
</head>
|
|
177
|
+
|
|
113
178
|
<body>
|
|
114
|
-
<my-greeting
|
|
179
|
+
<my-greeting>
|
|
180
|
+
<div>Hello, World.</div>
|
|
181
|
+
</my-greeting>
|
|
115
182
|
</body>
|
|
116
183
|
</html>
|
|
117
184
|
```
|
|
118
185
|
|
|
119
|
-
|
|
186
|
+
A component (or its render function) may be an `async` or an `async generator`.
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
class GithubUrls extends Tonic {
|
|
190
|
+
async * render () {
|
|
191
|
+
yield this.html`<p>Loading...</p>`
|
|
192
|
+
|
|
193
|
+
const res = await fetch('https://api.github.com/')
|
|
194
|
+
const urls = await res.json()
|
|
195
|
+
|
|
196
|
+
return this.html`
|
|
197
|
+
<pre>
|
|
198
|
+
${JSON.stringify(urls, 2, 2)}
|
|
199
|
+
</pre>
|
|
200
|
+
`
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Rerender
|
|
206
|
+
|
|
207
|
+
Call `tonicInstance.reRender()` to render your component again with updated
|
|
208
|
+
state. This is totally decoupled from any kind of state machine, so you can
|
|
209
|
+
choose how to batch state updates, and just re-render when necessary.
|
|
120
210
|
|
|
121
|
-
|
|
122
|
-
|
|
211
|
+
> [!TIP]
|
|
212
|
+
> DOM state, such as focus and input values, is preserved
|
|
213
|
+
> across multiple calls to `reRender`.
|
|
123
214
|
|
|
124
|
-
###
|
|
215
|
+
### Events
|
|
216
|
+
|
|
217
|
+
There is a convention for event handler method names. Name a method like
|
|
218
|
+
`handle_example`, and the method will be called with any `example` type
|
|
219
|
+
event.
|
|
220
|
+
|
|
221
|
+
#### Events Example
|
|
222
|
+
|
|
223
|
+
```js
|
|
224
|
+
import { Tonic } from '@substrate-system/tonic'
|
|
225
|
+
|
|
226
|
+
class ButtonExample extends Tonic {
|
|
227
|
+
handle_click (ev) {
|
|
228
|
+
ev.preventDefault()
|
|
229
|
+
if (Tonic.match(ev.target as HTMLButtonElement, 'button')) {
|
|
230
|
+
// button clicks only
|
|
231
|
+
this.increment()
|
|
232
|
+
}
|
|
233
|
+
this.props.onbtnclick('hello')
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
render () {
|
|
237
|
+
return this.html`<div id="test">
|
|
238
|
+
example
|
|
239
|
+
<button id="btn">clicker</button>
|
|
240
|
+
</div>`
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### State
|
|
246
|
+
|
|
247
|
+
`this.state` is a plain-old javascript object. Its value will be persisted if
|
|
248
|
+
the component is re-rendered. Any element that has an id attribute can use
|
|
249
|
+
state, and any component that uses state must have an id property.
|
|
250
|
+
|
|
251
|
+
Setting the state will not cause a component to re-render. This way you can
|
|
252
|
+
make incremental updates. Components can be updated independently. And
|
|
253
|
+
rendering only happens only when necessary.
|
|
254
|
+
|
|
255
|
+
Remember to clean up! States are just a set of key-value pairs on the Tonic
|
|
256
|
+
object. So if you create temporary components that use state,
|
|
257
|
+
clean up their state after you delete them. For example,
|
|
258
|
+
if I have a component with thousands of temporary child elements that
|
|
259
|
+
all use state, I should delete their state after they get destroyed.
|
|
260
|
+
Delete `Tonic._states[someRandomId]`
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
## API
|
|
264
|
+
|
|
265
|
+
### Event listeners
|
|
266
|
+
|
|
267
|
+
Add a method with an event name, and it will be called with any matching events.
|
|
268
|
+
|
|
269
|
+
#### Event Listener Example
|
|
270
|
+
|
|
271
|
+
```js
|
|
272
|
+
import { Tonic } from '@substrate-system/tonic'
|
|
273
|
+
|
|
274
|
+
class MyClicker extends Tonic {
|
|
275
|
+
click (ev:MouseEvent) {
|
|
276
|
+
// automatically called on any click
|
|
277
|
+
ev.preventDefault()
|
|
278
|
+
console.log('click')
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
render () {
|
|
282
|
+
return this.html`<div>
|
|
283
|
+
<button>click the button</button>
|
|
284
|
+
</div>`
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
Tonic.add(MyClicker)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
## DOM state
|
|
125
293
|
|
|
126
294
|
DOM state (like element focus) should be preserved across re-renders.
|
|
127
295
|
|
|
128
|
-
|
|
296
|
+
## docs
|
|
129
297
|
See [API docs](https://substrate-system.github.io/tonic/).
|
|
130
298
|
|
|
131
|
-
|
|
299
|
+
## types
|
|
132
300
|
See [src/index.ts](./src/index.ts).
|
|
133
301
|
|
|
134
|
-
|
|
302
|
+
## `tag`
|
|
135
303
|
Get the HTML tag name given a Tonic class.
|
|
136
304
|
|
|
137
305
|
```ts
|
|
@@ -244,9 +412,43 @@ el.dispatch('more testing', 'some data', {
|
|
|
244
412
|
})
|
|
245
413
|
```
|
|
246
414
|
|
|
415
|
+
## Develop
|
|
416
|
+
|
|
417
|
+
On any version bump, we run `npm run build`, which calls all the other
|
|
418
|
+
build scripts.
|
|
419
|
+
|
|
420
|
+
### build ESM
|
|
421
|
+
|
|
422
|
+
```sh
|
|
423
|
+
npm run build-esm
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
```sh
|
|
427
|
+
npm run build-esm:min
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### build Common JS
|
|
431
|
+
|
|
432
|
+
```sh
|
|
433
|
+
npm run build-cjs
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
```sh
|
|
437
|
+
npm run build-cjs:min
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### build UMD modules
|
|
441
|
+
|
|
442
|
+
```sh
|
|
443
|
+
npm run build:main
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
```sh
|
|
447
|
+
npm run build:minify
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
|
|
247
451
|
## Useful links
|
|
248
|
-
- [Tonic components](https://github.com/socketsupply/components)
|
|
249
|
-
- [Migration from the early versions of Tonic](./MIGRATION.md)
|
|
250
452
|
- [API](./API.md)
|
|
251
453
|
- [Troubleshooting](./HELP.md)
|
|
252
454
|
- [Web Component lifecycle methods](https://gomakethings.com/the-web-component-lifecycle-methods/)
|
package/dist/index.cjs
CHANGED
|
@@ -174,8 +174,10 @@ class Tonic extends window.HTMLElement {
|
|
|
174
174
|
_events() {
|
|
175
175
|
const hp = Object.getOwnPropertyNames(window.HTMLElement.prototype);
|
|
176
176
|
for (const p of this._props) {
|
|
177
|
-
if (
|
|
178
|
-
|
|
177
|
+
if (!p.includes("handle_")) continue;
|
|
178
|
+
const evName = p.split("_")[1];
|
|
179
|
+
if (hp.indexOf("on" + evName) === -1) continue;
|
|
180
|
+
this.addEventListener(evName, this);
|
|
179
181
|
}
|
|
180
182
|
}
|
|
181
183
|
_prop(o) {
|
|
@@ -199,6 +201,9 @@ class Tonic extends window.HTMLElement {
|
|
|
199
201
|
static getTagName(camelName) {
|
|
200
202
|
return camelName.match(/[A-Z][a-z0-9]*/g).join("-").toLowerCase();
|
|
201
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Add all methods to this._props
|
|
206
|
+
*/
|
|
202
207
|
static getPropertyNames(proto) {
|
|
203
208
|
const props = [];
|
|
204
209
|
while (proto && proto !== Tonic.prototype) {
|
|
@@ -371,7 +376,7 @@ class Tonic extends window.HTMLElement {
|
|
|
371
376
|
* @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?}
|
|
372
377
|
*/
|
|
373
378
|
handleEvent(ev) {
|
|
374
|
-
this[ev.type] && this[ev.type](ev);
|
|
379
|
+
this["handle_" + ev.type] && this["handle_" + ev.type](ev);
|
|
375
380
|
}
|
|
376
381
|
_drainIterator(target, iterator) {
|
|
377
382
|
return iterator.next().then((result) => {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["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 { '\"': '"', '&': '&', '\\'': ''', '<': '<',\n '>': '>', '`': '`', '/': '/' }\n }\n\n static ssr\n static nonce\n\n private _state:any\n stylesheet?:()=>string\n styles:()=>string\n props:T\n preventRenderOnReconnect:boolean\n private _id:string\n pendingReRender?:Promise<this>|null\n updated?:((props:Record<string, any>)=>any)\n willRender?:(()=>any)\n root?:ShadowRoot|this\n willConnect?:()=>any\n private _source?:string\n connected?:()=>void\n 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>|undefined {\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 for (const p of this._props) {\n if (hp.indexOf('on' + p) === -1) continue\n this.addEventListener(p, 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 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 { render } }[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 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[ev.type] && this[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 ()=>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(target, (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 preservation\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 during updates\n const tempContainer = document.createElement('div')\n tempContainer.innerHTML = content\n\n morphdom(target, tempContainer, {\n childrenOnly: true,\n onBeforeElUpdated: (fromEl, toEl) => {\n // Skip updating if the elements are the same and preserve form state\n if (fromEl.isEqualNode && fromEl.isEqualNode(toEl)) {\n return false\n }\n\n // For inputs, preserve value and selection\n if (fromEl.tagName === 'INPUT' && toEl.tagName === 'INPUT') {\n const fromInput = fromEl as HTMLInputElement\n const toInput = toEl as HTMLInputElement\n\n // Preserve form values\n if (fromInput.value !== '') {\n toInput.value = fromInput.value\n }\n\n // Preserve selection/cursor position\n if (document.activeElement === fromInput) {\n toInput.setAttribute('data-preserve-focus', 'true')\n toInput.setAttribute('data-selection-start', String(fromInput.selectionStart || 0))\n toInput.setAttribute('data-selection-end', String(fromInput.selectionEnd || 0))\n }\n }\n\n // For textareas, preserve value and selection\n if (fromEl.tagName === 'TEXTAREA' && toEl.tagName === 'TEXTAREA') {\n const fromTextarea = fromEl as HTMLTextAreaElement\n const toTextarea = toEl as HTMLTextAreaElement\n\n // Preserve form values\n if (fromTextarea.value !== '') {\n toTextarea.value = fromTextarea.value\n }\n\n // Preserve selection/cursor position\n if (document.activeElement === fromTextarea) {\n toTextarea.setAttribute('data-preserve-focus', 'true')\n toTextarea.setAttribute('data-selection-start', String(fromTextarea.selectionStart || 0))\n toTextarea.setAttribute('data-selection-end', String(fromTextarea.selectionEnd || 0))\n }\n }\n\n return true\n },\n\n onElUpdated: (el) => {\n // Restore focus and selection after update\n if (el.hasAttribute('data-preserve-focus')) {\n const startPos = parseInt(el.getAttribute('data-selection-start') || '0', 10)\n const endPos = parseInt(el.getAttribute('data-selection-end') || '0', 10)\n\n // Clean up attributes\n el.removeAttribute('data-preserve-focus')\n el.removeAttribute('data-selection-start')\n el.removeAttribute('data-selection-end')\n\n // Focus and restore selection\n el.focus()\n if ('setSelectionRange' in el) {\n (el as HTMLInputElement|HTMLTextAreaElement).setSelectionRange(startPos, endPos)\n }\n }\n }\n })\n } else {\n // Use original innerHTML approach\n target.innerHTML = content\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 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"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["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 { '\"': '"', '&': '&', '\\'': ''', '<': '<',\n '>': '>', '`': '`', '/': '/' }\n }\n\n static ssr\n static nonce\n\n private _state:any\n stylesheet?:()=>string\n styles:()=>string\n props:T\n preventRenderOnReconnect:boolean\n private _id:string\n pendingReRender?:Promise<this>|null\n updated?:((props:Record<string, any>)=>any)\n willRender?:(()=>any)\n root?:ShadowRoot|this\n willConnect?:()=>any\n private _source?:string\n connected?:()=>void\n 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>|undefined {\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 { render } }[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 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 ()=>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(target, (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 preservation\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 during updates\n const tempContainer = document.createElement('div')\n tempContainer.innerHTML = content\n\n morphdom(target, tempContainer, {\n childrenOnly: true,\n onBeforeElUpdated: (fromEl, toEl) => {\n // Skip updating if the elements are the same and preserve form state\n if (fromEl.isEqualNode && fromEl.isEqualNode(toEl)) {\n return false\n }\n\n // For inputs, preserve value and selection\n if (fromEl.tagName === 'INPUT' && toEl.tagName === 'INPUT') {\n const fromInput = fromEl as HTMLInputElement\n const toInput = toEl as HTMLInputElement\n\n // Preserve form values\n if (fromInput.value !== '') {\n toInput.value = fromInput.value\n }\n\n // Preserve selection/cursor position\n if (document.activeElement === fromInput) {\n toInput.setAttribute('data-preserve-focus', 'true')\n toInput.setAttribute('data-selection-start', String(fromInput.selectionStart || 0))\n toInput.setAttribute('data-selection-end', String(fromInput.selectionEnd || 0))\n }\n }\n\n // For textareas, preserve value and selection\n if (fromEl.tagName === 'TEXTAREA' && toEl.tagName === 'TEXTAREA') {\n const fromTextarea = fromEl as HTMLTextAreaElement\n const toTextarea = toEl as HTMLTextAreaElement\n\n // Preserve form values\n if (fromTextarea.value !== '') {\n toTextarea.value = fromTextarea.value\n }\n\n // Preserve selection/cursor position\n if (document.activeElement === fromTextarea) {\n toTextarea.setAttribute('data-preserve-focus', 'true')\n toTextarea.setAttribute('data-selection-start', String(fromTextarea.selectionStart || 0))\n toTextarea.setAttribute('data-selection-end', String(fromTextarea.selectionEnd || 0))\n }\n }\n\n return true\n },\n\n onElUpdated: (el) => {\n // Restore focus and selection after update\n if (el.hasAttribute('data-preserve-focus')) {\n const startPos = parseInt(el.getAttribute('data-selection-start') || '0', 10)\n const endPos = parseInt(el.getAttribute('data-selection-end') || '0', 10)\n\n // Clean up attributes\n el.removeAttribute('data-preserve-focus')\n el.removeAttribute('data-selection-start')\n el.removeAttribute('data-selection-end')\n\n // Focus and restore selection\n el.focus()\n if ('setSelectionRange' in el) {\n (el as HTMLInputElement|HTMLTextAreaElement).setSelectionRange(startPos, endPos)\n }\n }\n }\n })\n } else {\n // Use original innerHTML approach\n target.innerHTML = content\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 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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["o", "content", "morphdom", "children"]
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -87,6 +87,9 @@ export declare abstract class Tonic<T extends {
|
|
|
87
87
|
private _placehold;
|
|
88
88
|
static match(el: HTMLElement, s: string): Element;
|
|
89
89
|
static getTagName(camelName: string): string;
|
|
90
|
+
/**
|
|
91
|
+
* Add all methods to this._props
|
|
92
|
+
*/
|
|
90
93
|
static getPropertyNames(proto: any): string[];
|
|
91
94
|
/**
|
|
92
95
|
* Add a component. Calls `window.customElements.define` with the
|
package/dist/index.js
CHANGED
|
@@ -62,7 +62,7 @@ export class Tonic extends window.HTMLElement {
|
|
|
62
62
|
}
|
|
63
63
|
// @ts-expect-error VERSION is injected during build
|
|
64
64
|
static get version() {
|
|
65
|
-
return "
|
|
65
|
+
return "17.0.0";
|
|
66
66
|
}
|
|
67
67
|
static get SPREAD() {
|
|
68
68
|
return /\.\.\.\s?(__\w+__\w+__)/g;
|
|
@@ -141,8 +141,10 @@ export class Tonic extends window.HTMLElement {
|
|
|
141
141
|
_events() {
|
|
142
142
|
const hp = Object.getOwnPropertyNames(window.HTMLElement.prototype);
|
|
143
143
|
for (const p of this._props) {
|
|
144
|
-
if (
|
|
145
|
-
|
|
144
|
+
if (!p.includes("handle_")) continue;
|
|
145
|
+
const evName = p.split("_")[1];
|
|
146
|
+
if (hp.indexOf("on" + evName) === -1) continue;
|
|
147
|
+
this.addEventListener(evName, this);
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
_prop(o) {
|
|
@@ -166,6 +168,9 @@ export class Tonic extends window.HTMLElement {
|
|
|
166
168
|
static getTagName(camelName) {
|
|
167
169
|
return camelName.match(/[A-Z][a-z0-9]*/g).join("-").toLowerCase();
|
|
168
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Add all methods to this._props
|
|
173
|
+
*/
|
|
169
174
|
static getPropertyNames(proto) {
|
|
170
175
|
const props = [];
|
|
171
176
|
while (proto && proto !== Tonic.prototype) {
|
|
@@ -338,7 +343,7 @@ export class Tonic extends window.HTMLElement {
|
|
|
338
343
|
* @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?}
|
|
339
344
|
*/
|
|
340
345
|
handleEvent(ev) {
|
|
341
|
-
this[ev.type] && this[ev.type](ev);
|
|
346
|
+
this["handle_" + ev.type] && this["handle_" + ev.type](ev);
|
|
342
347
|
}
|
|
343
348
|
_drainIterator(target, iterator) {
|
|
344
349
|
return iterator.next().then((result) => {
|