@knowark/componarkjs 1.14.0 → 1.14.2
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 +57 -45
- package/lib/base/component/README.md +127 -0
- package/lib/base/component/component.js +127 -21
- package/lib/base/component/component.test.js +296 -3
- package/lib/base/component/index.js +3 -0
- package/lib/base/styles/index.js +4 -1
- package/lib/base/utils/define.js +2 -1
- package/lib/base/utils/format.js +12 -6
- package/lib/base/utils/helpers.js +31 -5
- package/lib/base/utils/index.js +1 -0
- package/lib/base/utils/slots.js +3 -2
- package/lib/base/utils/uuid.js +1 -1
- package/lib/components/audio/components/audio.js +17 -2
- package/lib/components/audio/index.js +1 -0
- package/lib/components/audio/styles/index.js +5 -1
- package/lib/components/camera/components/camera.js +10 -0
- package/lib/components/camera/index.js +1 -0
- package/lib/components/camera/styles/index.js +5 -1
- package/lib/components/capture/components/capture.js +18 -2
- package/lib/components/capture/index.js +1 -0
- package/lib/components/droparea/components/droparea-preview.js +58 -13
- package/lib/components/droparea/components/droparea-preview.test.js +82 -0
- package/lib/components/droparea/components/droparea.js +41 -2
- package/lib/components/droparea/index.js +1 -0
- package/lib/components/droparea/styles/index.js +5 -1
- package/lib/components/emit/components/emit.js +11 -1
- package/lib/components/emit/index.js +1 -0
- package/lib/components/index.js +2 -1
- package/lib/components/list/components/item.js +6 -0
- package/lib/components/list/components/list.js +18 -4
- package/lib/components/list/index.js +1 -0
- package/lib/components/paginator/components/paginator.js +34 -8
- package/lib/components/paginator/index.js +1 -0
- package/lib/components/paginator/styles/index.js +5 -1
- package/lib/components/spinner/components/spinner.js +10 -0
- package/lib/components/spinner/index.js +1 -0
- package/lib/components/spinner/styles/index.js +5 -1
- package/lib/components/splitview/components/splitview.detail.js +10 -1
- package/lib/components/splitview/components/splitview.js +18 -3
- package/lib/components/splitview/components/splitview.master.js +10 -0
- package/lib/components/splitview/index.js +1 -0
- package/lib/components/translate/components/translate.js +42 -11
- package/lib/components/translate/components/translate.test.js +169 -1
- package/lib/components/translate/index.js +1 -0
- package/lib/index.js +3 -0
- package/package.json +2 -1
- package/tsconfig.json +1 -1
- package/types/base/component/component.d.ts +43 -8
- package/types/base/component/component.d.ts.map +1 -1
- package/types/base/component/index.d.ts +4 -6
- package/types/base/component/index.d.ts.map +1 -1
- package/types/base/styles/index.d.ts +3 -2
- package/types/base/styles/index.d.ts.map +1 -1
- package/types/base/utils/define.d.ts +3 -2
- package/types/base/utils/define.d.ts.map +1 -1
- package/types/base/utils/format.d.ts +12 -6
- package/types/base/utils/format.d.ts.map +1 -1
- package/types/base/utils/helpers.d.ts +27 -7
- package/types/base/utils/helpers.d.ts.map +1 -1
- package/types/base/utils/slots.d.ts +8 -10
- package/types/base/utils/slots.d.ts.map +1 -1
- package/types/base/utils/uuid.d.ts +1 -1
- package/types/base/utils/uuid.d.ts.map +1 -1
- package/types/components/audio/components/audio.d.ts +23 -9
- package/types/components/audio/components/audio.d.ts.map +1 -1
- package/types/components/audio/styles/index.d.ts +3 -2
- package/types/components/audio/styles/index.d.ts.map +1 -1
- package/types/components/camera/components/camera.d.ts +11 -3
- package/types/components/camera/components/camera.d.ts.map +1 -1
- package/types/components/camera/styles/index.d.ts +3 -2
- package/types/components/camera/styles/index.d.ts.map +1 -1
- package/types/components/capture/components/capture.d.ts +23 -3
- package/types/components/capture/components/capture.d.ts.map +1 -1
- package/types/components/droparea/components/droparea-preview.d.ts +64 -11
- package/types/components/droparea/components/droparea-preview.d.ts.map +1 -1
- package/types/components/droparea/components/droparea.d.ts +58 -13
- package/types/components/droparea/components/droparea.d.ts.map +1 -1
- package/types/components/droparea/styles/index.d.ts +3 -2
- package/types/components/droparea/styles/index.d.ts.map +1 -1
- package/types/components/emit/components/emit.d.ts +15 -3
- package/types/components/emit/components/emit.d.ts.map +1 -1
- package/types/components/list/components/item.d.ts +8 -1
- package/types/components/list/components/item.d.ts.map +1 -1
- package/types/components/list/components/list.d.ts +23 -5
- package/types/components/list/components/list.d.ts.map +1 -1
- package/types/components/paginator/components/paginator.d.ts +32 -8
- package/types/components/paginator/components/paginator.d.ts.map +1 -1
- package/types/components/paginator/styles/index.d.ts +3 -2
- package/types/components/paginator/styles/index.d.ts.map +1 -1
- package/types/components/spinner/components/spinner.d.ts +14 -3
- package/types/components/spinner/components/spinner.d.ts.map +1 -1
- package/types/components/spinner/styles/index.d.ts +3 -2
- package/types/components/spinner/styles/index.d.ts.map +1 -1
- package/types/components/splitview/components/splitview.d.ts +22 -4
- package/types/components/splitview/components/splitview.d.ts.map +1 -1
- package/types/components/splitview/components/splitview.detail.d.ts +12 -2
- package/types/components/splitview/components/splitview.detail.d.ts.map +1 -1
- package/types/components/splitview/components/splitview.master.d.ts +12 -1
- package/types/components/splitview/components/splitview.master.d.ts.map +1 -1
- package/types/components/translate/components/translate.d.ts +44 -10
- package/types/components/translate/components/translate.d.ts.map +1 -1
- package/lib/base/component/README.rst +0 -113
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<a href="https://codecov.io/gh/librark/componark">
|
|
3
|
-
<img src="https://codecov.io/gh/librark/componark/graph/badge.svg?token=IWNapsPUch"/>
|
|
3
|
+
<img src="https://codecov.io/gh/librark/componark/graph/badge.svg?token=IWNapsPUch" alt="codecov" />
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
<p align="center">
|
|
7
7
|
<a href="https://codecov.io/gh/librark/componark">
|
|
8
|
-
<img src="https://codecov.io/gh/librark/componark/graphs/sunburst.svg?token=IWNapsPUch"/>
|
|
8
|
+
<img src="https://codecov.io/gh/librark/componark/graphs/sunburst.svg?token=IWNapsPUch" alt="coverage sunburst" />
|
|
9
9
|
</a>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
@@ -13,46 +13,58 @@
|
|
|
13
13
|
|
|
14
14
|
Pragmatic Web Components Library
|
|
15
15
|
|
|
16
|
-
Introduction
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
16
|
+
## Introduction
|
|
17
|
+
|
|
18
|
+
ComponArk is a lightweight Web Components library with a shared base class for
|
|
19
|
+
consistency and event-driven composition.
|
|
20
|
+
|
|
21
|
+
The library is organized as custom elements that can be used directly in HTML or
|
|
22
|
+
combined with your application code.
|
|
23
|
+
|
|
24
|
+
## Reference
|
|
25
|
+
|
|
26
|
+
- [Base Component](lib/base/component)
|
|
27
|
+
- [Showcase](showcase)
|
|
28
|
+
|
|
29
|
+
## Components library
|
|
30
|
+
|
|
31
|
+
> Components marked in **bold** are available in this repository.
|
|
32
|
+
|
|
33
|
+
- **`ark-audio`** ([docs](lib/components/audio/README.md))
|
|
34
|
+
- **`ark-camera`** ([docs](lib/components/camera/README.md))
|
|
35
|
+
- **`ark-capture`** ([docs](lib/components/capture/README.md))
|
|
36
|
+
- **`ark-droparea`** ([docs](lib/components/droparea/README.md))
|
|
37
|
+
- **`ark-emit`** ([docs](lib/components/emit/README.md))
|
|
38
|
+
- **`ark-list`** ([docs](lib/components/list/README.md))
|
|
39
|
+
- **`ark-paginator`** ([docs](lib/components/paginator/README.md))
|
|
40
|
+
- **`ark-spinner`** ([docs](lib/components/spinner/README.md))
|
|
41
|
+
- **`ark-splitview`** ([docs](lib/components/splitview/README.md))
|
|
42
|
+
- **`ark-translate`** ([docs](lib/components/translate/README.md))
|
|
43
|
+
|
|
44
|
+
## Why this exists
|
|
45
|
+
|
|
46
|
+
- Minimal, reusable base (`Component`) with lifecycle hooks and dependency
|
|
47
|
+
resolution.
|
|
48
|
+
- Template/event binding helper (`listen`) with custom attribute syntax.
|
|
49
|
+
- Lightweight styling support with constructor stylesheet + fallback support.
|
|
50
|
+
- Small test surface included with native Node test runner.
|
|
51
|
+
|
|
52
|
+
## Basic usage
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<ark-translate languages="en,es"></ark-translate>
|
|
56
|
+
|
|
57
|
+
<span data-i18n="hello">Hello</span>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Development
|
|
61
|
+
|
|
62
|
+
- Run tests: `npm test`
|
|
63
|
+
- Build production bundle: `npm run prod`
|
|
64
|
+
- Start local dev server: `npm run dev`
|
|
65
|
+
|
|
66
|
+
## Notes
|
|
67
|
+
|
|
68
|
+
Some older docs in the previous release referenced components that are not in the
|
|
69
|
+
current snapshot of this repository. If you need one of those modules, check
|
|
70
|
+
the release tags or open a request with expected parity.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Component
|
|
2
|
+
|
|
3
|
+
`Component` is the base class for Componark custom elements. It extends `HTMLElement` with:
|
|
4
|
+
|
|
5
|
+
- Declarative event bindings (`listen` + `on-*` attributes)
|
|
6
|
+
- Attribute-to-property reflection
|
|
7
|
+
- Dependency resolution through bubbling `resolve` events
|
|
8
|
+
- Cleanup registration for disconnect lifecycle
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```javascript
|
|
13
|
+
import { Component } from 'base/component'
|
|
14
|
+
|
|
15
|
+
class MyComponent extends Component {
|
|
16
|
+
reflectedProperties () {
|
|
17
|
+
return ['title']
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
init (context = {}) {
|
|
21
|
+
this.local.count = this.local.count ?? 0
|
|
22
|
+
return super.init(context)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
increment () {
|
|
26
|
+
this.local.count += 1
|
|
27
|
+
this.render()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
render () {
|
|
31
|
+
this.content = `
|
|
32
|
+
<button listen on-click="increment">
|
|
33
|
+
${this.title}: ${this.local.count}
|
|
34
|
+
</button>
|
|
35
|
+
`
|
|
36
|
+
return super.render()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async load (_context = {}) {
|
|
40
|
+
// Optional async work after render.
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Component.define('my-component', MyComponent)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Lifecycle
|
|
48
|
+
|
|
49
|
+
1. `constructor()`
|
|
50
|
+
- Initializes internal state (`binding`, `local`, cleanup registry, etc.).
|
|
51
|
+
- Applies reflected properties using `reflectedProperties()`.
|
|
52
|
+
2. `connectedCallback()`
|
|
53
|
+
- Marks the component as connected.
|
|
54
|
+
- Calls `init({})` only when `local` is empty.
|
|
55
|
+
- Calls `render()`.
|
|
56
|
+
- Calls `load({})` (sync or async).
|
|
57
|
+
3. `disconnectedCallback()`
|
|
58
|
+
- Marks the component as disconnected.
|
|
59
|
+
- Runs registered cleanup callbacks.
|
|
60
|
+
|
|
61
|
+
Errors from `init`/`render`, `load`, and cleanup callbacks are emitted as bubbling `error` events. Enhanced errors include:
|
|
62
|
+
|
|
63
|
+
- `phase`: `init-render`, `load`, or `cleanup`
|
|
64
|
+
- `component`: current tag name (for example, `MY-COMPONENT`)
|
|
65
|
+
|
|
66
|
+
## Public API
|
|
67
|
+
|
|
68
|
+
### Static API
|
|
69
|
+
|
|
70
|
+
| Method | Description |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `Component.define(tagName, element, styles?)` | Registers a custom element. If `styles` are provided, they are registered for that tag. |
|
|
73
|
+
|
|
74
|
+
### Instance API
|
|
75
|
+
|
|
76
|
+
| Member | Returns | Description |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| `init(context = {})` | `this` | Component state initialization hook. |
|
|
79
|
+
| `reflectedProperties()` | `string[]` | Attribute names to expose as reflected properties. |
|
|
80
|
+
| `slots` | `Record<string, HTMLElement[]>` | Child elements grouped by `slot` (`general` by default). |
|
|
81
|
+
| `content` | `string` | Proxy for `innerHTML`. Setting it flags listeners for re-binding. |
|
|
82
|
+
| `render()` | `this` | Adds the tag-name class and binds declarative listeners when needed. |
|
|
83
|
+
| `load(context = {})` | `void \| Promise<void>` | Async hook called after `render()`. |
|
|
84
|
+
| `registerCleanup(callback)` | `() => void` | Registers disconnect cleanup and returns an unregister function. |
|
|
85
|
+
| `select(selector)` | `Component` | `querySelector` helper. |
|
|
86
|
+
| `selectAll(selector)` | `NodeListOf<Component>` | `querySelectorAll` helper. |
|
|
87
|
+
| `emit(type, detail)` | `void` | Dispatches a bubbling, cancelable event with `detail`. |
|
|
88
|
+
| `resolve(resource)` | `any` | Requests a dependency through a bubbling `resolve` event. |
|
|
89
|
+
| `styleNames(styleMap)` | `string` | Returns truthy class names from an object map. |
|
|
90
|
+
|
|
91
|
+
## Declarative listeners
|
|
92
|
+
|
|
93
|
+
`render()` triggers listener wiring on descendants marked with `listen`.
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<input listen on-input="{{ local.query = data }}">
|
|
97
|
+
<input listen on-input="{{ local.total = data | number }}">
|
|
98
|
+
<button listen on-click="submit"></button>
|
|
99
|
+
<button listen on-click="submit@#child"></button>
|
|
100
|
+
<div listen on-change="replaceChildren%detail.name@#target"></div>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Rules:
|
|
104
|
+
|
|
105
|
+
- Use `on-<event>` attributes to define handlers.
|
|
106
|
+
- `{{ ... }}` expressions perform state assignment.
|
|
107
|
+
- Pipes support `string`, `number`, `boolean`, and `object`.
|
|
108
|
+
- `handler@<selector>` routes execution to another element/component.
|
|
109
|
+
- Handler failures emit bubbling `error` events.
|
|
110
|
+
|
|
111
|
+
## Dependency resolution
|
|
112
|
+
|
|
113
|
+
`resolve(resource)` dispatches a bubbling `resolve` event with `{ resource }`. Ancestors can provide values by implementing `provide(resource)`.
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
class ParentComponent extends Component {
|
|
117
|
+
provide (resource) {
|
|
118
|
+
if (resource === 'state') return this.local
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Then in a child:
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
const state = this.resolve('state')
|
|
127
|
+
```
|
|
@@ -2,21 +2,31 @@ import { define, listen, reflect, slot, keys } from '../utils/index.js'
|
|
|
2
2
|
import styles from '../styles/index.js'
|
|
3
3
|
|
|
4
4
|
const tag = 'ark-component'
|
|
5
|
+
/**
|
|
6
|
+
* Base composable UI component.
|
|
7
|
+
* @extends {globalThis.HTMLElement}
|
|
8
|
+
*/
|
|
5
9
|
export class Component extends globalThis.HTMLElement {
|
|
6
10
|
constructor () {
|
|
7
11
|
super()
|
|
8
12
|
this.binding = 'listen'
|
|
9
13
|
this.local = {}
|
|
10
14
|
this._isConnected = false
|
|
15
|
+
this._cleanupCallbacks = []
|
|
16
|
+
this._needsBinding = true
|
|
17
|
+
this.global = globalThis
|
|
11
18
|
reflect(this, this.reflectedProperties())
|
|
12
19
|
}
|
|
13
20
|
|
|
14
21
|
/**
|
|
15
|
-
*
|
|
22
|
+
* Register a custom element and optional CSS for the same tag.
|
|
23
|
+
* @param {string} tagName
|
|
16
24
|
* @param {CustomElementConstructor} element
|
|
17
|
-
* @param {string} styles
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
* @param {string} [styles]
|
|
26
|
+
* @returns {void}
|
|
27
|
+
*/
|
|
28
|
+
static define (tagName, element, styles = null) {
|
|
29
|
+
define(tagName, element, styles)
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
/**
|
|
@@ -28,7 +38,7 @@ export class Component extends globalThis.HTMLElement {
|
|
|
28
38
|
|
|
29
39
|
/**
|
|
30
40
|
* @param {object} context
|
|
31
|
-
* @return {
|
|
41
|
+
* @return {this} */
|
|
32
42
|
init (context = {}) {
|
|
33
43
|
return this
|
|
34
44
|
}
|
|
@@ -45,6 +55,7 @@ export class Component extends globalThis.HTMLElement {
|
|
|
45
55
|
/** @param {string} content */
|
|
46
56
|
set content (content) {
|
|
47
57
|
this.innerHTML = content
|
|
58
|
+
this._needsBinding = true
|
|
48
59
|
}
|
|
49
60
|
|
|
50
61
|
/** @return {string} */
|
|
@@ -52,41 +63,62 @@ export class Component extends globalThis.HTMLElement {
|
|
|
52
63
|
return this.innerHTML
|
|
53
64
|
}
|
|
54
65
|
|
|
66
|
+
/** @returns {void} */
|
|
55
67
|
connectedCallback () {
|
|
56
68
|
this._isConnected = true
|
|
57
69
|
try {
|
|
58
70
|
!Boolean(Object.keys(this.local).length) && this.init({})
|
|
59
71
|
this.render()
|
|
60
72
|
} catch (error) {
|
|
61
|
-
this.emit('error', error)
|
|
73
|
+
this.emit('error', this._enhanceError(error, 'init-render'))
|
|
62
74
|
throw error
|
|
63
75
|
}
|
|
64
76
|
try {
|
|
65
77
|
const load = this.load({})
|
|
66
78
|
if (load && typeof load.catch === 'function') {
|
|
67
79
|
load.catch(error => {
|
|
68
|
-
this.emit('error', error)
|
|
80
|
+
this.emit('error', this._enhanceError(error, 'load'))
|
|
69
81
|
})
|
|
70
82
|
}
|
|
71
83
|
} catch (error) {
|
|
72
|
-
this.emit('error', error)
|
|
84
|
+
this.emit('error', this._enhanceError(error, 'load'))
|
|
73
85
|
throw error
|
|
74
86
|
}
|
|
75
87
|
}
|
|
76
88
|
|
|
89
|
+
/** @returns {void} */
|
|
77
90
|
disconnectedCallback () {
|
|
78
91
|
this._isConnected = false
|
|
92
|
+
this._cleanup()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {Function} callback
|
|
97
|
+
* @return {Function} */
|
|
98
|
+
registerCleanup (callback) {
|
|
99
|
+
if (!callback || typeof callback !== 'function') return () => {}
|
|
100
|
+
|
|
101
|
+
this._cleanupCallbacks.push(callback)
|
|
102
|
+
return () => {
|
|
103
|
+
const index = this._cleanupCallbacks.indexOf(callback)
|
|
104
|
+
if (index === -1) return
|
|
105
|
+
this._cleanupCallbacks.splice(index, 1)
|
|
106
|
+
}
|
|
79
107
|
}
|
|
80
108
|
|
|
81
|
-
/** @return {
|
|
109
|
+
/** @return {this} */
|
|
82
110
|
render () {
|
|
83
111
|
this.classList.add(this.tagName.toLowerCase())
|
|
84
|
-
|
|
112
|
+
if (this._needsBinding) {
|
|
113
|
+
listen(this)
|
|
114
|
+
this._needsBinding = false
|
|
115
|
+
}
|
|
85
116
|
return this
|
|
86
117
|
}
|
|
87
118
|
|
|
88
|
-
/** @param {object} context
|
|
89
|
-
|
|
119
|
+
/** @param {object} context
|
|
120
|
+
* @returns {void | Promise<void>} */
|
|
121
|
+
load (context = {}) {}
|
|
90
122
|
|
|
91
123
|
/**
|
|
92
124
|
* @param {string} selectors
|
|
@@ -108,26 +140,100 @@ export class Component extends globalThis.HTMLElement {
|
|
|
108
140
|
* @param {string} type
|
|
109
141
|
* @param {any} detail */
|
|
110
142
|
emit (type, detail) {
|
|
111
|
-
this.dispatchEvent(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
cancelable: true
|
|
116
|
-
})
|
|
117
|
-
)
|
|
143
|
+
this.dispatchEvent(this._createEvent(type, detail, {
|
|
144
|
+
bubbles: true,
|
|
145
|
+
cancelable: true
|
|
146
|
+
}))
|
|
118
147
|
}
|
|
119
148
|
|
|
120
149
|
/**
|
|
121
150
|
* @param {string} resource
|
|
122
151
|
* @return {any} */
|
|
123
152
|
resolve (resource) {
|
|
124
|
-
const event =
|
|
125
|
-
detail: { resource },
|
|
153
|
+
const event = this._createEvent('resolve', { resource }, {
|
|
126
154
|
bubbles: true,
|
|
127
155
|
cancelable: true
|
|
128
156
|
})
|
|
129
157
|
this.dispatchEvent(event)
|
|
130
158
|
return event.detail[resource]
|
|
131
159
|
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @param {any} detail
|
|
163
|
+
* @param {string} phase
|
|
164
|
+
* @return {Error} */
|
|
165
|
+
_enhanceError (detail, phase) {
|
|
166
|
+
if (!detail) return detail
|
|
167
|
+
|
|
168
|
+
const error = detail instanceof Error ? detail : new Error(
|
|
169
|
+
`${detail.message || detail}`
|
|
170
|
+
)
|
|
171
|
+
/** @type {Error & { phase?: string, component?: string }} */
|
|
172
|
+
const enhancedError = error
|
|
173
|
+
enhancedError.phase = phase
|
|
174
|
+
enhancedError.component = this.tagName
|
|
175
|
+
return error
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** @returns {void} */
|
|
179
|
+
_cleanup () {
|
|
180
|
+
const callbacks = [...this._cleanupCallbacks]
|
|
181
|
+
this._cleanupCallbacks = []
|
|
182
|
+
|
|
183
|
+
for (const callback of callbacks) {
|
|
184
|
+
try {
|
|
185
|
+
callback()
|
|
186
|
+
} catch (error) {
|
|
187
|
+
this.emit('error', this._enhanceError(error, 'cleanup'))
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Creates an event object for dispatch.
|
|
194
|
+
* @param {string} type
|
|
195
|
+
* @param {any} detail
|
|
196
|
+
* @param {{ bubbles?: boolean, cancelable?: boolean }} [options]
|
|
197
|
+
* @returns {CustomEvent}
|
|
198
|
+
*/
|
|
199
|
+
_createEvent (type, detail, options = {}) {
|
|
200
|
+
/** @type {{ [key: string]: any }} */
|
|
201
|
+
const contextGlobal = this.global || {}
|
|
202
|
+
const contextWindow = contextGlobal.document?.defaultView || contextGlobal.window || contextGlobal
|
|
203
|
+
const { bubbles = true, cancelable = true } = options
|
|
204
|
+
|
|
205
|
+
if (typeof contextWindow.CustomEvent === 'function') {
|
|
206
|
+
return new contextWindow.CustomEvent(type, { detail, bubbles, cancelable })
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (typeof contextWindow.Event === 'function') {
|
|
210
|
+
const event = new contextWindow.Event(type, { bubbles, cancelable })
|
|
211
|
+
;(/** @type {any} */ (event)).detail = detail
|
|
212
|
+
return /** @type {CustomEvent} */ (event)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (typeof globalThis.CustomEvent === 'function') {
|
|
216
|
+
return new globalThis.CustomEvent(type, { detail, bubbles, cancelable })
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (typeof globalThis.Event === 'function') {
|
|
220
|
+
const event = new globalThis.Event(type, { bubbles, cancelable })
|
|
221
|
+
;(/** @type {any} */ (event)).detail = detail
|
|
222
|
+
return /** @type {CustomEvent} */ (event)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return /** @type {CustomEvent} */ (/** @type {unknown} */ ({
|
|
226
|
+
type,
|
|
227
|
+
detail,
|
|
228
|
+
bubbles,
|
|
229
|
+
cancelable,
|
|
230
|
+
currentTarget: this,
|
|
231
|
+
defaultPrevented: false,
|
|
232
|
+
cancelBubble: false,
|
|
233
|
+
target: this,
|
|
234
|
+
stopPropagation () {},
|
|
235
|
+
preventDefault () {}
|
|
236
|
+
}))
|
|
237
|
+
}
|
|
132
238
|
}
|
|
133
239
|
Component.define(tag, Component, styles)
|