@symbo.ls/element 3.14.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/index.js +1 -0
- package/package.json +21 -0
- package/src/cache.js +124 -0
- package/src/create.js +1705 -0
- package/src/delegate.js +163 -0
- package/src/dispose.js +76 -0
- package/src/extends.js +105 -0
- package/src/index.js +8 -0
- package/src/methods.js +257 -0
- package/src/registry.js +79 -0
- package/src/update.js +124 -0
package/src/update.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { batch, isStore } from '@symbo.ls/signal'
|
|
4
|
+
import { REGISTRY } from './registry.js'
|
|
5
|
+
import { create } from './create.js'
|
|
6
|
+
import { runPluginHook } from '@symbo.ls/utils/function.js'
|
|
7
|
+
|
|
8
|
+
export function update(params = {}, opts = {}) {
|
|
9
|
+
const element = this
|
|
10
|
+
const ref = element.__ref
|
|
11
|
+
if (!ref) return
|
|
12
|
+
|
|
13
|
+
// Normalize string/number shorthand
|
|
14
|
+
if (typeof params === 'string' || typeof params === 'number') {
|
|
15
|
+
params = { text: params }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Fire onBeforeUpdate (v3 syntax — directly on element)
|
|
19
|
+
if (!opts.preventListeners && typeof element.onBeforeUpdate === 'function') {
|
|
20
|
+
const result = element.onBeforeUpdate(element, element.state, element.context, opts)
|
|
21
|
+
if (result === false) return element
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
batch(() => {
|
|
25
|
+
// Update state if provided
|
|
26
|
+
if (params.state && isStore(element.state)) {
|
|
27
|
+
element.state.update(params.state)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Update text
|
|
31
|
+
if (params.text !== undefined) {
|
|
32
|
+
element.text = params.text
|
|
33
|
+
if (!ref.__exec.text && element.node) {
|
|
34
|
+
if (element.tag === 'string') {
|
|
35
|
+
element.node.nodeValue = params.text ?? ''
|
|
36
|
+
} else {
|
|
37
|
+
element.node.textContent = params.text ?? ''
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Update html
|
|
43
|
+
if (params.html !== undefined) {
|
|
44
|
+
element.html = params.html
|
|
45
|
+
if (!ref.__exec.html && element.node) {
|
|
46
|
+
element.node.innerHTML = params.html
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Update style
|
|
51
|
+
if (params.style && element.node?.style) {
|
|
52
|
+
if (!ref.__exec.style) {
|
|
53
|
+
for (const prop in params.style) {
|
|
54
|
+
element.node.style[prop] = params.style[prop]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!element.style) element.style = {}
|
|
58
|
+
Object.assign(element.style, params.style)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (params.attr && element.node?.setAttribute) {
|
|
62
|
+
for (const key in params.attr) {
|
|
63
|
+
const val = params.attr[key]
|
|
64
|
+
if (val == null || val === false) {
|
|
65
|
+
element.node.removeAttribute(key)
|
|
66
|
+
} else if (typeof val !== 'function' && typeof val !== 'object') {
|
|
67
|
+
element.node.setAttribute(key, val === true ? '' : val)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!element.attr) element.attr = {}
|
|
71
|
+
Object.assign(element.attr, params.attr)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (params.data && element.node?.dataset) {
|
|
75
|
+
for (const key in params.data) {
|
|
76
|
+
element.node.dataset[key] = params.data[key]
|
|
77
|
+
}
|
|
78
|
+
if (!element.data) element.data = {}
|
|
79
|
+
Object.assign(element.data, params.data)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Handle child element updates and property changes
|
|
83
|
+
for (const param in params) {
|
|
84
|
+
if (REGISTRY.has(param)) continue
|
|
85
|
+
if (param === 'state') continue
|
|
86
|
+
|
|
87
|
+
const childParams = params[param]
|
|
88
|
+
const child = element[param]
|
|
89
|
+
|
|
90
|
+
if (child && child.__ref && typeof child.update === 'function') {
|
|
91
|
+
// Existing child element — recursive update
|
|
92
|
+
child.update(childParams, opts)
|
|
93
|
+
} else if (typeof childParams === 'object' && childParams !== null) {
|
|
94
|
+
const firstChar = param.charCodeAt(0)
|
|
95
|
+
if (firstChar >= 65 && firstChar <= 90) {
|
|
96
|
+
// Uppercase key with object value — create new child element
|
|
97
|
+
create(childParams, element, param, opts)
|
|
98
|
+
}
|
|
99
|
+
} else if (param !== 'text' && param !== 'html' && param !== 'style' && param !== 'attr' && param !== 'data') {
|
|
100
|
+
// Primitive property update (e.g. name, icon, value)
|
|
101
|
+
// Set the property — if it has a reactive effect, the effect will re-run
|
|
102
|
+
element[param] = childParams
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// Re-evaluate conditionals (.prop / !prop). Signal-driven predicates already
|
|
108
|
+
// re-fired via createEffect; this catches imperative updates to non-signal
|
|
109
|
+
// predicates (e.g. element.update({ isActive: true }) where isActive is a
|
|
110
|
+
// plain element prop, not a state field).
|
|
111
|
+
if (element.node && ref.__conditionalRunners) {
|
|
112
|
+
for (const run of ref.__conditionalRunners) run()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
runPluginHook('update', element)
|
|
116
|
+
|
|
117
|
+
if (!opts.preventListeners && typeof element.onUpdate === 'function') {
|
|
118
|
+
element.onUpdate(element, element.state, element.context, opts)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return element
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default update
|