@domql/element 3.1.2 → 3.2.7
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 +4 -6
- package/children.js +45 -18
- package/create.js +58 -46
- package/define.js +1 -1
- package/dist/cjs/children.js +43 -13
- package/dist/cjs/create.js +57 -27
- package/dist/cjs/define.js +1 -1
- package/dist/cjs/event/animationFrame.js +96 -0
- package/dist/cjs/event/can.js +28 -0
- package/dist/cjs/event/index.js +20 -0
- package/dist/cjs/event/on.js +84 -0
- package/dist/cjs/event/store.js +27 -0
- package/dist/cjs/extend.js +88 -0
- package/dist/cjs/index.js +9 -6
- package/dist/cjs/iterate.js +89 -33
- package/dist/cjs/methods/set.js +5 -0
- package/dist/cjs/methods/v2.js +1 -1
- package/dist/cjs/mixins/attr.js +3 -2
- package/dist/cjs/mixins/classList.js +11 -1
- package/dist/cjs/mixins/content.js +72 -0
- package/dist/cjs/mixins/html.js +1 -2
- package/dist/cjs/mixins/registry.js +2 -2
- package/dist/cjs/mixins/scope.js +1 -1
- package/dist/cjs/mixins/state.js +4 -4
- package/dist/cjs/mixins/style.js +11 -2
- package/dist/cjs/mixins/text.js +9 -5
- package/dist/cjs/node.js +22 -19
- package/dist/cjs/render/append.js +72 -0
- package/dist/cjs/render/cache.js +80 -0
- package/dist/cjs/render/create.js +25 -0
- package/dist/cjs/render/index.js +20 -0
- package/dist/cjs/set.js +33 -40
- package/dist/cjs/update.js +100 -69
- package/dist/cjs/utils/applyParam.js +7 -7
- package/dist/cjs/utils/extendUtils.js +132 -0
- package/dist/cjs/utils/index.js +2 -0
- package/dist/cjs/utils/propEvents.js +56 -0
- package/dist/esm/children.js +44 -14
- package/dist/esm/create.js +58 -27
- package/dist/esm/define.js +1 -1
- package/dist/esm/event/animationFrame.js +76 -0
- package/dist/esm/event/can.js +8 -0
- package/dist/esm/event/index.js +3 -0
- package/dist/esm/event/on.js +64 -0
- package/dist/esm/event/store.js +7 -0
- package/dist/esm/extend.js +74 -0
- package/dist/esm/index.js +8 -6
- package/dist/esm/iterate.js +90 -35
- package/dist/esm/methods/set.js +10 -0
- package/dist/esm/methods/v2.js +1 -1
- package/dist/esm/mixins/attr.js +4 -3
- package/dist/esm/mixins/classList.js +11 -1
- package/dist/esm/mixins/content.js +52 -0
- package/dist/esm/mixins/html.js +1 -2
- package/dist/esm/mixins/registry.js +1 -1
- package/dist/esm/mixins/scope.js +1 -1
- package/dist/esm/mixins/state.js +5 -5
- package/dist/esm/mixins/style.js +12 -3
- package/dist/esm/mixins/text.js +10 -6
- package/dist/esm/node.js +22 -19
- package/dist/esm/render/append.js +52 -0
- package/dist/esm/render/cache.js +60 -0
- package/dist/esm/render/create.js +5 -0
- package/dist/esm/render/index.js +3 -0
- package/dist/esm/set.js +34 -41
- package/dist/esm/update.js +100 -71
- package/dist/esm/utils/applyParam.js +8 -8
- package/dist/esm/utils/extendUtils.js +119 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/propEvents.js +36 -0
- package/dist/iife/index.js +4718 -0
- package/extend.js +95 -0
- package/index.js +9 -6
- package/iterate.js +100 -38
- package/node.js +25 -23
- package/package.json +44 -20
- package/set.js +28 -32
- package/update.js +111 -82
- package/__tests__/checkIfOnUpdate.test.js +0 -103
- package/__tests__/children.test.js +0 -213
- package/__tests__/define.test.js +0 -75
- package/__tests__/inheritStateUpdates.test.js +0 -79
- package/__tests__/renderElement.test.js +0 -131
- package/__tests__/resetElement.test.js +0 -44
- package/__tests__/set.test.js +0 -316
- package/__tests__/throughExecProps.test.js +0 -86
- package/__tests__/throughInitialDefine.test.js +0 -104
- package/__tests__/throughInitialExec.test.js +0 -92
- package/__tests__/throughUpdatedDefine.test.js +0 -92
- package/__tests__/throughUpdatedExec.test.js +0 -110
- package/__tests__/tree.test.js +0 -15
- package/__tests__/update.test.js +0 -256
- package/dist/cjs/__tests__/checkIfOnUpdate.test.js +0 -73
- package/dist/cjs/__tests__/children.test.js +0 -177
- package/dist/cjs/__tests__/define.test.js +0 -75
- package/dist/cjs/__tests__/inheritStateUpdates.test.js +0 -62
- package/dist/cjs/__tests__/renderElement.test.js +0 -138
- package/dist/cjs/__tests__/resetElement.test.js +0 -35
- package/dist/cjs/__tests__/set.test.js +0 -256
- package/dist/cjs/__tests__/throughExecProps.test.js +0 -62
- package/dist/cjs/__tests__/throughInitialDefine.test.js +0 -79
- package/dist/cjs/__tests__/throughInitialExec.test.js +0 -73
- package/dist/cjs/__tests__/throughUpdatedDefine.test.js +0 -69
- package/dist/cjs/__tests__/throughUpdatedExec.test.js +0 -84
- package/dist/cjs/__tests__/tree.test.js +0 -11
- package/dist/cjs/__tests__/update.test.js +0 -222
- package/dist/cjs/package.json +0 -4
- package/dist/esm/__tests__/checkIfOnUpdate.test.js +0 -73
- package/dist/esm/__tests__/children.test.js +0 -177
- package/dist/esm/__tests__/define.test.js +0 -53
- package/dist/esm/__tests__/inheritStateUpdates.test.js +0 -62
- package/dist/esm/__tests__/renderElement.test.js +0 -116
- package/dist/esm/__tests__/resetElement.test.js +0 -35
- package/dist/esm/__tests__/set.test.js +0 -256
- package/dist/esm/__tests__/throughExecProps.test.js +0 -62
- package/dist/esm/__tests__/throughInitialDefine.test.js +0 -79
- package/dist/esm/__tests__/throughInitialExec.test.js +0 -73
- package/dist/esm/__tests__/throughUpdatedDefine.test.js +0 -69
- package/dist/esm/__tests__/throughUpdatedExec.test.js +0 -84
- package/dist/esm/__tests__/tree.test.js +0 -11
- package/dist/esm/__tests__/update.test.js +0 -222
- package/methods/set.js +0 -63
- package/methods/v2.js +0 -83
- package/mixins/attr.js +0 -32
- package/mixins/classList.js +0 -54
- package/mixins/data.js +0 -26
- package/mixins/html.js +0 -21
- package/mixins/index.js +0 -23
- package/mixins/registry.js +0 -46
- package/mixins/scope.js +0 -23
- package/mixins/state.js +0 -19
- package/mixins/style.js +0 -16
- package/mixins/text.js +0 -26
- package/utils/applyParam.js +0 -34
- package/utils/index.js +0 -3
package/update.js
CHANGED
|
@@ -11,17 +11,15 @@ import {
|
|
|
11
11
|
isUndefined,
|
|
12
12
|
merge,
|
|
13
13
|
overwriteDeep,
|
|
14
|
-
deepClone,
|
|
15
14
|
isMethod,
|
|
16
15
|
findInheritedState,
|
|
17
|
-
deepMerge,
|
|
18
16
|
OPTIONS,
|
|
19
17
|
updateProps,
|
|
20
18
|
captureSnapshot,
|
|
21
19
|
propertizeUpdate
|
|
22
20
|
} from '@domql/utils'
|
|
23
21
|
|
|
24
|
-
import { applyEvent, triggerEventOn, triggerEventOnUpdate } from '
|
|
22
|
+
import { applyEvent, triggerEventOn, triggerEventOnUpdate } from './event/index.js'
|
|
25
23
|
import { createState } from '@domql/state'
|
|
26
24
|
|
|
27
25
|
import { create } from './create.js'
|
|
@@ -45,15 +43,11 @@ const UPDATE_DEFAULT_OPTIONS = {
|
|
|
45
43
|
exclude: METHODS_EXL
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
export const update =
|
|
49
|
-
|
|
50
|
-
const options =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
: UPDATE_DEFAULT_OPTIONS,
|
|
54
|
-
{ exclude: ['calleeElement'] }
|
|
55
|
-
)
|
|
56
|
-
options.calleeElement = calleeElementCache
|
|
46
|
+
export const update = function (params = {}, opts) {
|
|
47
|
+
// Shallow copy is sufficient - all values are primitives/references that shouldn't be cloned
|
|
48
|
+
const options = isObject(opts)
|
|
49
|
+
? { ...UPDATE_DEFAULT_OPTIONS, ...opts }
|
|
50
|
+
: { ...UPDATE_DEFAULT_OPTIONS }
|
|
57
51
|
const element = this
|
|
58
52
|
|
|
59
53
|
let ref = element.__ref
|
|
@@ -66,7 +60,7 @@ export const update = async function (params = {}, opts) {
|
|
|
66
60
|
if (snapshotHasUpdated) return
|
|
67
61
|
|
|
68
62
|
if (!options.preventListeners) {
|
|
69
|
-
|
|
63
|
+
triggerEventOnUpdate('startUpdate', params, element, options)
|
|
70
64
|
}
|
|
71
65
|
|
|
72
66
|
const { parent, node, key } = element
|
|
@@ -87,29 +81,32 @@ export const update = async function (params = {}, opts) {
|
|
|
87
81
|
// apply new updates
|
|
88
82
|
params = propertizeUpdate.call(element, params)
|
|
89
83
|
|
|
90
|
-
const inheritState =
|
|
84
|
+
const inheritState = inheritStateUpdates(element, options)
|
|
91
85
|
if (inheritState === false) return
|
|
92
86
|
|
|
93
|
-
const ifFails =
|
|
87
|
+
const ifFails = checkIfOnUpdate(element, parent, options)
|
|
94
88
|
if (ifFails) return
|
|
95
89
|
|
|
96
90
|
if (ref.__if && !options.preventPropsUpdate) {
|
|
97
91
|
const hasParentProps =
|
|
98
92
|
parent.props && (parent.props[key] || parent.props.childProps)
|
|
99
|
-
const hasFunctionInProps = ref.__propsStack.
|
|
100
|
-
const props = params.props || hasParentProps || hasFunctionInProps
|
|
93
|
+
const hasFunctionInProps = ref.__propsStack.some(isFunction)
|
|
94
|
+
const props = params.props || hasParentProps || hasFunctionInProps
|
|
101
95
|
if (props) updateProps(props, element, parent)
|
|
102
96
|
}
|
|
103
97
|
|
|
104
98
|
if (!options.preventBeforeUpdateListener && !options.preventListeners) {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
99
|
+
const hasBeforeUpdate = element.on?.beforeUpdate || element.props?.onBeforeUpdate
|
|
100
|
+
if (hasBeforeUpdate) {
|
|
101
|
+
const simulate = { ...params, ...element }
|
|
102
|
+
const beforeUpdateReturns = triggerEventOnUpdate(
|
|
103
|
+
'beforeUpdate',
|
|
104
|
+
params,
|
|
105
|
+
simulate,
|
|
106
|
+
options
|
|
107
|
+
)
|
|
108
|
+
if (beforeUpdateReturns === false) return element
|
|
109
|
+
}
|
|
113
110
|
}
|
|
114
111
|
|
|
115
112
|
// apply new updates
|
|
@@ -121,14 +118,11 @@ export const update = async function (params = {}, opts) {
|
|
|
121
118
|
throughUpdatedDefine(element)
|
|
122
119
|
|
|
123
120
|
if (!options.isForced && !options.preventListeners) {
|
|
124
|
-
|
|
121
|
+
triggerEventOn('beforeClassAssign', element, options)
|
|
125
122
|
}
|
|
126
123
|
|
|
127
124
|
if (!ref.__if) return false
|
|
128
|
-
if (!node)
|
|
129
|
-
// return createNode(element, options)
|
|
130
|
-
return
|
|
131
|
-
}
|
|
125
|
+
if (!node) return
|
|
132
126
|
|
|
133
127
|
const {
|
|
134
128
|
preventUpdate,
|
|
@@ -152,15 +146,24 @@ export const update = async function (params = {}, opts) {
|
|
|
152
146
|
} else options.preventUpdateAfterCount++
|
|
153
147
|
}
|
|
154
148
|
|
|
149
|
+
// Convert arrays to Sets once for O(1) lookups during iteration
|
|
150
|
+
const preventUpdateSet = isArray(preventUpdate) ? new Set(preventUpdate) : null
|
|
151
|
+
const preventDefineUpdateSet = isArray(preventDefineUpdate) ? new Set(preventDefineUpdate) : null
|
|
152
|
+
|
|
155
153
|
for (const param in element) {
|
|
156
154
|
const prop = element[param]
|
|
157
155
|
|
|
158
|
-
if (!Object.hasOwnProperty.call(element, param)) continue
|
|
156
|
+
if (!Object.prototype.hasOwnProperty.call(element, param)) continue
|
|
159
157
|
|
|
160
158
|
const isInPreventUpdate =
|
|
161
|
-
|
|
159
|
+
preventUpdateSet && preventUpdateSet.has(param)
|
|
162
160
|
const isInPreventDefineUpdate =
|
|
163
|
-
|
|
161
|
+
preventDefineUpdateSet && preventDefineUpdateSet.has(param)
|
|
162
|
+
|
|
163
|
+
// Skip onXxx event handler functions (e.g. onClick) that may remain at root level
|
|
164
|
+
const isRootEventHandler = isFunction(prop) && param.length > 2 &&
|
|
165
|
+
param.charCodeAt(0) === 111 && param.charCodeAt(1) === 110 && // 'on'
|
|
166
|
+
param.charCodeAt(2) >= 65 && param.charCodeAt(2) <= 90 // A-Z
|
|
164
167
|
|
|
165
168
|
if (
|
|
166
169
|
isUndefined(prop) ||
|
|
@@ -168,8 +171,9 @@ export const update = async function (params = {}, opts) {
|
|
|
168
171
|
isInPreventDefineUpdate ||
|
|
169
172
|
preventDefineUpdate === true ||
|
|
170
173
|
preventDefineUpdate === param ||
|
|
171
|
-
(preventStateUpdate && param
|
|
174
|
+
(preventStateUpdate && param === 'state') ||
|
|
172
175
|
isMethod(param, element) ||
|
|
176
|
+
isRootEventHandler ||
|
|
173
177
|
isObject(REGISTRY[param])
|
|
174
178
|
) {
|
|
175
179
|
continue
|
|
@@ -177,7 +181,7 @@ export const update = async function (params = {}, opts) {
|
|
|
177
181
|
|
|
178
182
|
if (preventStateUpdate === 'once') options.preventStateUpdate = false
|
|
179
183
|
|
|
180
|
-
const isElement =
|
|
184
|
+
const isElement = applyParam(param, element, options)
|
|
181
185
|
if (isElement) {
|
|
182
186
|
const { hasDefine, hasContextDefine } = isElement
|
|
183
187
|
const canUpdate =
|
|
@@ -190,43 +194,89 @@ export const update = async function (params = {}, opts) {
|
|
|
190
194
|
options.onEachUpdate(param, element, element.state, element.context)
|
|
191
195
|
}
|
|
192
196
|
|
|
193
|
-
const
|
|
194
|
-
|
|
197
|
+
const childParams = params[param]
|
|
198
|
+
if (childParams === undefined && !options.isForced) continue
|
|
199
|
+
|
|
200
|
+
const childUpdateCall = () =>
|
|
201
|
+
update.call(prop, childParams, {
|
|
195
202
|
...options,
|
|
196
203
|
currentSnapshot: snapshotOnCallee,
|
|
197
204
|
calleeElement
|
|
198
205
|
})
|
|
199
206
|
|
|
200
207
|
if (lazyLoad) {
|
|
201
|
-
window.requestAnimationFrame(
|
|
208
|
+
window.requestAnimationFrame(() => {
|
|
202
209
|
// eslint-disable-line
|
|
203
|
-
|
|
210
|
+
childUpdateCall()
|
|
204
211
|
// handle lazy load
|
|
205
|
-
if (!options.preventUpdateListener) {
|
|
206
|
-
|
|
212
|
+
if (!options.preventUpdateListener && !options.preventListeners) {
|
|
213
|
+
triggerEventOn('lazyLoad', element, options)
|
|
207
214
|
}
|
|
208
215
|
})
|
|
209
|
-
} else
|
|
216
|
+
} else childUpdateCall()
|
|
210
217
|
}
|
|
211
218
|
}
|
|
212
219
|
|
|
213
220
|
if (!preventContentUpdate) {
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
221
|
+
// Update existing content element if it's a live DOMQL element
|
|
222
|
+
const contentKey = ref.contentElementKey || 'content'
|
|
223
|
+
const existingContent = element[contentKey]
|
|
224
|
+
|
|
225
|
+
// Re-evaluate children if the element has a children property
|
|
226
|
+
const childrenProp = params.children || element.children
|
|
227
|
+
if (childrenProp) {
|
|
228
|
+
const content = setChildren(childrenProp, element, opts)
|
|
229
|
+
if (content && !ref.__noChildrenDifference) {
|
|
230
|
+
setContent(content, element, options)
|
|
231
|
+
} else if (existingContent?.__ref && isFunction(existingContent.update)) {
|
|
232
|
+
const lazyLoad = element.props?.lazyLoad || options.lazyLoad
|
|
233
|
+
const contentUpdateCall = () =>
|
|
234
|
+
update.call(existingContent, params[contentKey], {
|
|
235
|
+
...options,
|
|
236
|
+
currentSnapshot: snapshotOnCallee,
|
|
237
|
+
calleeElement
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
if (lazyLoad) {
|
|
241
|
+
window.requestAnimationFrame(() => {
|
|
242
|
+
contentUpdateCall()
|
|
243
|
+
if (!options.preventUpdateListener && !options.preventListeners) {
|
|
244
|
+
triggerEventOn('lazyLoad', element, options)
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
} else contentUpdateCall()
|
|
248
|
+
}
|
|
249
|
+
} else if (existingContent?.__ref && isFunction(existingContent.update)) {
|
|
250
|
+
const lazyLoad = element.props?.lazyLoad || options.lazyLoad
|
|
251
|
+
const contentUpdateCall = () =>
|
|
252
|
+
update.call(existingContent, params[contentKey], {
|
|
253
|
+
...options,
|
|
254
|
+
currentSnapshot: snapshotOnCallee,
|
|
255
|
+
calleeElement
|
|
256
|
+
})
|
|
218
257
|
|
|
219
|
-
|
|
220
|
-
|
|
258
|
+
if (lazyLoad) {
|
|
259
|
+
window.requestAnimationFrame(() => {
|
|
260
|
+
contentUpdateCall()
|
|
261
|
+
if (!options.preventUpdateListener && !options.preventListeners) {
|
|
262
|
+
triggerEventOn('lazyLoad', element, options)
|
|
263
|
+
}
|
|
264
|
+
})
|
|
265
|
+
} else contentUpdateCall()
|
|
266
|
+
} else {
|
|
267
|
+
const content = element.children || params.content
|
|
268
|
+
if (content) {
|
|
269
|
+
setContent(content, element, options)
|
|
270
|
+
}
|
|
221
271
|
}
|
|
222
272
|
}
|
|
223
273
|
|
|
224
|
-
if (!preventUpdateListener) {
|
|
225
|
-
|
|
274
|
+
if (!preventUpdateListener && !options.preventListeners) {
|
|
275
|
+
triggerEventOn('update', element, options)
|
|
226
276
|
}
|
|
227
277
|
}
|
|
228
278
|
|
|
229
|
-
const checkIfOnUpdate =
|
|
279
|
+
const checkIfOnUpdate = (element, parent, options) => {
|
|
230
280
|
if ((!isFunction(element.if) && !isFunction(element.props?.if)) || !parent) {
|
|
231
281
|
return
|
|
232
282
|
}
|
|
@@ -275,8 +325,7 @@ const checkIfOnUpdate = async (element, parent, options) => {
|
|
|
275
325
|
|
|
276
326
|
const nextElement = element.nextElement()
|
|
277
327
|
const nextNode = nextElement?.node // document.body.contains(previousElement.node)
|
|
278
|
-
const hasNext = nextNode?.parentNode
|
|
279
|
-
// const hasNext = nextElement && document.body.contains(nextElement.node)
|
|
328
|
+
const hasNext = nextNode?.parentNode
|
|
280
329
|
|
|
281
330
|
const attachOptions = (hasPrevious || hasNext) && {
|
|
282
331
|
position: hasPrevious ? 'after' : hasNext ? 'before' : null,
|
|
@@ -285,7 +334,7 @@ const checkIfOnUpdate = async (element, parent, options) => {
|
|
|
285
334
|
|
|
286
335
|
delete element.__ref
|
|
287
336
|
delete element.parent
|
|
288
|
-
const createdElement =
|
|
337
|
+
const createdElement = create(
|
|
289
338
|
element,
|
|
290
339
|
parent,
|
|
291
340
|
element.key,
|
|
@@ -298,11 +347,7 @@ const checkIfOnUpdate = async (element, parent, options) => {
|
|
|
298
347
|
element.on &&
|
|
299
348
|
isFunction(element.on.update)
|
|
300
349
|
) {
|
|
301
|
-
|
|
302
|
-
element.on.update,
|
|
303
|
-
createdElement,
|
|
304
|
-
createdElement.state
|
|
305
|
-
)
|
|
350
|
+
applyEvent(element.on.update, createdElement, createdElement.state)
|
|
306
351
|
}
|
|
307
352
|
return createdElement
|
|
308
353
|
}
|
|
@@ -326,7 +371,7 @@ const checkIfOnUpdate = async (element, parent, options) => {
|
|
|
326
371
|
* @param {boolean} [options.preventStateUpdateListener] - If true, prevent the 'stateUpdate' event listener.
|
|
327
372
|
* @returns {boolean} - If returns false, it breaks the update function
|
|
328
373
|
*/
|
|
329
|
-
const inheritStateUpdates =
|
|
374
|
+
const inheritStateUpdates = (element, options) => {
|
|
330
375
|
const { __ref: ref } = element
|
|
331
376
|
const stateKey = ref.__state
|
|
332
377
|
const { parent, state } = element
|
|
@@ -337,7 +382,7 @@ const inheritStateUpdates = async (element, options) => {
|
|
|
337
382
|
|
|
338
383
|
// If does not have own state inherit from parent
|
|
339
384
|
if (!stateKey && !ref.__hasRootState) {
|
|
340
|
-
element.state =
|
|
385
|
+
element.state = parent?.state || {}
|
|
341
386
|
return
|
|
342
387
|
}
|
|
343
388
|
|
|
@@ -361,7 +406,7 @@ const inheritStateUpdates = async (element, options) => {
|
|
|
361
406
|
|
|
362
407
|
// Trigger on.beforeStateUpdate event
|
|
363
408
|
if (!options.preventBeforeStateUpdateListener && !options.preventListeners) {
|
|
364
|
-
const initStateReturns =
|
|
409
|
+
const initStateReturns = triggerEventOnUpdate(
|
|
365
410
|
'beforeStateUpdate',
|
|
366
411
|
keyInParentState,
|
|
367
412
|
element,
|
|
@@ -371,22 +416,17 @@ const inheritStateUpdates = async (element, options) => {
|
|
|
371
416
|
}
|
|
372
417
|
|
|
373
418
|
// Recreate the state again
|
|
374
|
-
const newState =
|
|
419
|
+
const newState = createStateUpdate(element, parent, options)
|
|
375
420
|
|
|
376
421
|
// Trigger on.stateUpdate event
|
|
377
422
|
if (!options.preventStateUpdateListener && !options.preventListeners) {
|
|
378
|
-
|
|
379
|
-
'stateUpdate',
|
|
380
|
-
newState.parse(),
|
|
381
|
-
element,
|
|
382
|
-
options
|
|
383
|
-
)
|
|
423
|
+
triggerEventOnUpdate('stateUpdate', newState.parse(), element, options)
|
|
384
424
|
}
|
|
385
425
|
}
|
|
386
426
|
|
|
387
|
-
const createStateUpdate =
|
|
427
|
+
const createStateUpdate = (element, parent, options) => {
|
|
388
428
|
const __stateChildren = element.state.__children
|
|
389
|
-
const newState =
|
|
429
|
+
const newState = createState(element, parent)
|
|
390
430
|
element.state = newState
|
|
391
431
|
for (const child in __stateChildren) {
|
|
392
432
|
// check this for inherited states
|
|
@@ -398,14 +438,3 @@ const createStateUpdate = async (element, parent, options) => {
|
|
|
398
438
|
}
|
|
399
439
|
|
|
400
440
|
export default update
|
|
401
|
-
|
|
402
|
-
// save updates history
|
|
403
|
-
// const overwriteChanges = overwriteDeep(element, params, { exclude: METHODS_EXL })
|
|
404
|
-
// // const overwriteChanges = overwriteDeep(element, params)
|
|
405
|
-
// const propsChanges = throughExecProps(element)
|
|
406
|
-
// const execChanges = throughUpdatedExec(element, { ignore: UPDATE_DEFAULT_OPTIONS })
|
|
407
|
-
// const definedChanges = throughUpdatedDefine(element)
|
|
408
|
-
// if (options.stackChanges && ref.__stackChanges) {
|
|
409
|
-
// const stackChanges = merge(definedChanges, merge(execChanges, overwriteChanges))
|
|
410
|
-
// ref.__stackChanges.push(stackChanges)
|
|
411
|
-
// }
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { update } from '../update'
|
|
2
|
-
|
|
3
|
-
describe('checkIfOnUpdate via update()', () => {
|
|
4
|
-
let element, parent, options
|
|
5
|
-
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
parent = {
|
|
8
|
-
node: document.createElement('div'),
|
|
9
|
-
props: {},
|
|
10
|
-
state: {}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
element = {
|
|
14
|
-
__ref: {
|
|
15
|
-
__if: undefined,
|
|
16
|
-
__state: null,
|
|
17
|
-
__hasRootState: false,
|
|
18
|
-
__execProps: {},
|
|
19
|
-
contentElementKey: 'content'
|
|
20
|
-
},
|
|
21
|
-
parent,
|
|
22
|
-
props: {},
|
|
23
|
-
state: {
|
|
24
|
-
update: (el, st) => {
|
|
25
|
-
return st
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
context: {
|
|
29
|
-
defaultExtends: {}
|
|
30
|
-
},
|
|
31
|
-
node: document.createElement('div'),
|
|
32
|
-
if: () => true,
|
|
33
|
-
previousElement: () => {
|
|
34
|
-
return {}
|
|
35
|
-
},
|
|
36
|
-
nextElement: () => {
|
|
37
|
-
return {}
|
|
38
|
-
},
|
|
39
|
-
removeContent: () => {
|
|
40
|
-
return true
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
options = {}
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('uses props.if when element.if missing', async () => {
|
|
48
|
-
delete element.if
|
|
49
|
-
element.props.if = () => false
|
|
50
|
-
await update.call(element, {}, options)
|
|
51
|
-
expect(element.node).toEqual(document.createElement('div'))
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('retains state when __hasRootState=true', async () => {
|
|
55
|
-
element.__ref.__hasRootState = true
|
|
56
|
-
element.state.critical = true
|
|
57
|
-
element.__ref.__if = false
|
|
58
|
-
|
|
59
|
-
await update.call(element, {}, options)
|
|
60
|
-
|
|
61
|
-
expect(element.state.critical).toBe(true)
|
|
62
|
-
expect(element.state.preserved).toBeUndefined()
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('processes nested content with parseDeep', async () => {
|
|
66
|
-
element.content = {
|
|
67
|
-
parseDeep: () => ({ parsed: true }),
|
|
68
|
-
existing: 'data'
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
await update.call(element, {}, options)
|
|
72
|
-
|
|
73
|
-
expect(element.content.parsed).toBe(true)
|
|
74
|
-
expect(element.content.existing).toBeUndefined()
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('reattaches after previous sibling', async () => {
|
|
78
|
-
const prevNode = document.createElement('span')
|
|
79
|
-
parent.node.appendChild(prevNode)
|
|
80
|
-
|
|
81
|
-
await update.call(element, {}, options)
|
|
82
|
-
|
|
83
|
-
const newElement = parent.node.children[0]
|
|
84
|
-
expect(newElement).toEqual(document.createElement('span'))
|
|
85
|
-
expect(newElement.previousSibling).toBe(null)
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
// it('reattaches before next sibling', async () => {
|
|
89
|
-
// const nextNode = document.createElement('p')
|
|
90
|
-
// parent.node.appendChild(nextNode)
|
|
91
|
-
|
|
92
|
-
// await update.call(element, {}, options)
|
|
93
|
-
|
|
94
|
-
// const newElement = parent.node.children[0]
|
|
95
|
-
// expect(newElement).toEqual(document.createElement('p'))
|
|
96
|
-
// expect(newElement.nextSibling).toBe(null)
|
|
97
|
-
// })
|
|
98
|
-
|
|
99
|
-
// it('appends to parent when no siblings exist', async () => {
|
|
100
|
-
// await update.call(element, {}, options)
|
|
101
|
-
// expect(parent.node.children).toHaveLength(0)
|
|
102
|
-
// })
|
|
103
|
-
})
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { jest } from '@jest/globals'
|
|
2
|
-
import { setChildren } from '../children'
|
|
3
|
-
|
|
4
|
-
describe('children', () => {
|
|
5
|
-
let element, node
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
element = {
|
|
9
|
-
__ref: {},
|
|
10
|
-
state: {},
|
|
11
|
-
props: {},
|
|
12
|
-
call: jest.fn(),
|
|
13
|
-
removeContent: jest.fn(),
|
|
14
|
-
content: null
|
|
15
|
-
}
|
|
16
|
-
node = {}
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('handles null/undefined params', async () => {
|
|
20
|
-
const result = await setChildren(null, element, node)
|
|
21
|
-
expect(result).toBeUndefined()
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('handles direct string children', async () => {
|
|
25
|
-
const result = await setChildren('Hello World', element, node)
|
|
26
|
-
expect(result).toEqual({ tag: 'fragment', 0: { text: 'Hello World' } })
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('handles numeric children', async () => {
|
|
30
|
-
const result = await setChildren(42, element, node)
|
|
31
|
-
expect(result).toEqual({ tag: 'fragment', 0: { text: 42 } })
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('handles array of primitive values with childrenAs prop', async () => {
|
|
35
|
-
const result = await setChildren(['one', 'two'], element, node)
|
|
36
|
-
|
|
37
|
-
expect(result).toEqual({
|
|
38
|
-
tag: 'fragment',
|
|
39
|
-
0: { text: 'one' },
|
|
40
|
-
1: { text: 'two' }
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('handles array of primitive values with childrenAs state', async () => {
|
|
45
|
-
element.props.childrenAs = 'state'
|
|
46
|
-
const result = await setChildren(['one', 'two'], element, node)
|
|
47
|
-
|
|
48
|
-
expect(result).toEqual({
|
|
49
|
-
tag: 'fragment',
|
|
50
|
-
0: { state: { value: 'one' } },
|
|
51
|
-
1: { state: { value: 'two' } }
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('caches children and detects changes', async () => {
|
|
56
|
-
const children1 = [{ id: 1 }, { id: 2 }]
|
|
57
|
-
const children2 = [{ id: 1 }, { id: 2 }]
|
|
58
|
-
const children3 = [{ id: 1 }, { id: 3 }]
|
|
59
|
-
|
|
60
|
-
// First call
|
|
61
|
-
await setChildren(children1, element, node)
|
|
62
|
-
expect(element.__ref.__childrenCache).toEqual(children1)
|
|
63
|
-
expect(element.__ref.__noChildrenDifference).toBeUndefined()
|
|
64
|
-
|
|
65
|
-
// Same content, different reference
|
|
66
|
-
await setChildren(children2, element, node)
|
|
67
|
-
expect(element.__ref.__noChildrenDifference).toBe(true)
|
|
68
|
-
|
|
69
|
-
// Different content
|
|
70
|
-
await setChildren(children3, element, node)
|
|
71
|
-
expect(element.__ref.__noChildrenDifference).toBeUndefined()
|
|
72
|
-
expect(element.__ref.__childrenCache).toEqual(children3)
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('handles mixed React and normal components', async () => {
|
|
76
|
-
const mixedChildren = [
|
|
77
|
-
{ type: 'div', text: 'Normal' },
|
|
78
|
-
{ $$typeof: Symbol('react') },
|
|
79
|
-
{ type: 'span', text: 'Another' }
|
|
80
|
-
]
|
|
81
|
-
|
|
82
|
-
await setChildren(mixedChildren, element, node)
|
|
83
|
-
|
|
84
|
-
expect(element.call).toHaveBeenCalledWith(
|
|
85
|
-
'renderReact',
|
|
86
|
-
[mixedChildren[1]],
|
|
87
|
-
element
|
|
88
|
-
)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('handles state-based children', async () => {
|
|
92
|
-
element.state = {
|
|
93
|
-
items: ['a', 'b'],
|
|
94
|
-
parse: () => ['parsed a', 'parsed b']
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const result = await setChildren('state', element, node)
|
|
98
|
-
expect(result).toEqual({
|
|
99
|
-
tag: 'fragment',
|
|
100
|
-
0: { text: 'parsed a' },
|
|
101
|
-
1: { text: 'parsed b' }
|
|
102
|
-
})
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it('handles async function parameters', async () => {
|
|
106
|
-
const asyncParam = async () => ['async1', 'async2']
|
|
107
|
-
const result = await setChildren(asyncParam, element, node)
|
|
108
|
-
|
|
109
|
-
expect(result).toEqual({
|
|
110
|
-
tag: 'fragment',
|
|
111
|
-
0: { text: 'async1' },
|
|
112
|
-
1: { text: 'async2' }
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it('handles nested object structures', async () => {
|
|
117
|
-
const nestedChildren = {
|
|
118
|
-
header: { text: 'Title' },
|
|
119
|
-
content: {
|
|
120
|
-
nested: { text: 'Content' }
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const result = await setChildren(nestedChildren, element, node)
|
|
125
|
-
expect(result).toEqual({
|
|
126
|
-
tag: 'fragment',
|
|
127
|
-
0: { text: 'Title' },
|
|
128
|
-
1: { nested: { text: 'Content' } }
|
|
129
|
-
})
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
it('handles empty arrays and objects', async () => {
|
|
133
|
-
let result = await setChildren([], element, node)
|
|
134
|
-
expect(result).toEqual({
|
|
135
|
-
tag: 'fragment'
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
result = await setChildren({}, element, node)
|
|
139
|
-
expect(result).toEqual({
|
|
140
|
-
tag: 'fragment'
|
|
141
|
-
})
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
it('handles falsy values in arrays', async () => {
|
|
145
|
-
const result = await setChildren(
|
|
146
|
-
[null, undefined, false, 0, ''],
|
|
147
|
-
element,
|
|
148
|
-
node
|
|
149
|
-
)
|
|
150
|
-
expect(result).toEqual({
|
|
151
|
-
tag: 'fragment',
|
|
152
|
-
3: { text: 0 },
|
|
153
|
-
4: { text: '' }
|
|
154
|
-
})
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it('handles React components with falsy values in array', async () => {
|
|
158
|
-
const mixedChildren = [
|
|
159
|
-
null,
|
|
160
|
-
{ $$typeof: Symbol('react') },
|
|
161
|
-
undefined,
|
|
162
|
-
{ $$typeof: Symbol('react') },
|
|
163
|
-
false
|
|
164
|
-
]
|
|
165
|
-
|
|
166
|
-
await setChildren(mixedChildren, element, node)
|
|
167
|
-
|
|
168
|
-
expect(element.call).toHaveBeenCalledWith(
|
|
169
|
-
'renderReact',
|
|
170
|
-
[mixedChildren[1], mixedChildren[3]],
|
|
171
|
-
element
|
|
172
|
-
)
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
it('handles nested state parsing', async () => {
|
|
176
|
-
element.state = {
|
|
177
|
-
nested: {
|
|
178
|
-
items: ['c', 'd']
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
element.state.nested.__proto__.parse = () => ['parsed c', 'parsed d']
|
|
182
|
-
|
|
183
|
-
const result = await setChildren('nested', element, node)
|
|
184
|
-
expect(result).toEqual({
|
|
185
|
-
tag: 'fragment',
|
|
186
|
-
0: { state: ['c', 'd'] }
|
|
187
|
-
})
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
it('handles mixed state and regular objects', async () => {
|
|
191
|
-
element.state = {
|
|
192
|
-
header: { parse: () => 'Header' },
|
|
193
|
-
footer: { parse: () => 'Footer' }
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const result = await setChildren(
|
|
197
|
-
{
|
|
198
|
-
header: 'header',
|
|
199
|
-
content: { text: 'Content' },
|
|
200
|
-
footer: 'footer'
|
|
201
|
-
},
|
|
202
|
-
element,
|
|
203
|
-
node
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
expect(result).toEqual({
|
|
207
|
-
tag: 'fragment',
|
|
208
|
-
0: { text: 'header' },
|
|
209
|
-
1: { text: 'Content' },
|
|
210
|
-
2: { text: 'footer' }
|
|
211
|
-
})
|
|
212
|
-
})
|
|
213
|
-
})
|