@domql/element 3.2.3 → 3.2.8
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/children.js +40 -12
- package/create.js +40 -26
- package/define.js +1 -1
- package/dist/cjs/children.js +39 -11
- package/dist/cjs/create.js +41 -11
- 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 +6 -6
- package/dist/cjs/index.js +9 -6
- package/dist/cjs/iterate.js +13 -13
- 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 +1 -2
- package/dist/cjs/mixins/html.js +1 -2
- package/dist/cjs/mixins/state.js +2 -2
- package/dist/cjs/mixins/style.js +11 -2
- package/dist/cjs/mixins/text.js +5 -1
- package/dist/cjs/node.js +8 -5
- 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 +12 -14
- package/dist/cjs/update.js +80 -40
- package/dist/cjs/utils/applyParam.js +3 -3
- package/dist/cjs/utils/extendUtils.js +5 -5
- package/dist/cjs/utils/index.js +2 -0
- package/dist/cjs/utils/propEvents.js +21 -4
- package/dist/esm/children.js +39 -11
- package/dist/esm/create.js +42 -11
- 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 +7 -7
- package/dist/esm/index.js +8 -6
- package/dist/esm/iterate.js +13 -13
- 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 +1 -2
- package/dist/esm/mixins/html.js +1 -2
- package/dist/esm/mixins/state.js +2 -2
- package/dist/esm/mixins/style.js +12 -3
- package/dist/esm/mixins/text.js +6 -2
- package/dist/esm/node.js +8 -5
- 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 +12 -14
- package/dist/esm/update.js +80 -42
- package/dist/esm/utils/applyParam.js +3 -3
- package/dist/esm/utils/extendUtils.js +5 -5
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/propEvents.js +21 -4
- package/dist/iife/index.js +4718 -0
- package/extend.js +7 -10
- package/index.js +9 -6
- package/iterate.js +20 -13
- package/node.js +10 -8
- package/package.json +42 -18
- package/set.js +6 -5
- package/update.js +90 -52
- package/__tests__/checkIfOnUpdate.test.js +0 -103
- package/__tests__/children.test.js +0 -209
- 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 -312
- 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 -111
- package/__tests__/tree.test.js +0 -15
- package/__tests__/update.test.js +0 -256
- package/dist/cjs/package.json +0 -4
- 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/content.js +0 -65
- 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/extendUtils.js +0 -149
- package/utils/index.js +0 -3
- package/utils/propEvents.js +0 -19
package/extend.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { isFunction, exec
|
|
3
|
+
import { isFunction, exec } from '@domql/utils'
|
|
4
4
|
import {
|
|
5
5
|
getExtendStack,
|
|
6
6
|
jointStacks,
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
fallbackStringExtend
|
|
10
10
|
} from './utils/index.js'
|
|
11
11
|
|
|
12
|
+
// Module-level cache for context.defaultExtends merged result.
|
|
13
|
+
// Set once on first use, never invalidated — assumes defaultExtends is static.
|
|
12
14
|
let mainExtend
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -27,21 +29,16 @@ export const applyExtend = (element, parent, options = {}) => {
|
|
|
27
29
|
|
|
28
30
|
const extendStack = getExtendStack(extend, context)
|
|
29
31
|
|
|
30
|
-
// if (isProduction()) delete element.extend
|
|
31
32
|
delete element.extend
|
|
32
33
|
|
|
33
34
|
let childExtendStack = []
|
|
34
35
|
if (parent) {
|
|
35
36
|
element.parent = parent
|
|
36
37
|
// Assign parent attr to the element
|
|
37
|
-
if (!options.ignoreChildExtend && !
|
|
38
|
+
if (!options.ignoreChildExtend && !props?.ignoreChildExtend) {
|
|
38
39
|
childExtendStack = getExtendStack(parent.childExtend, context)
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
// const ignoreChildExtendRecursive = props && exec(props, element).ignoreChildExtendRecursive
|
|
42
|
-
|
|
43
|
-
const ignoreChildExtendRecursive =
|
|
44
|
-
props && props.ignoreChildExtendRecursive
|
|
41
|
+
const ignoreChildExtendRecursive = props?.ignoreChildExtendRecursive
|
|
45
42
|
if (parent.childExtendRecursive && !ignoreChildExtendRecursive) {
|
|
46
43
|
const canExtendRecursive = element.key !== '__text'
|
|
47
44
|
if (canExtendRecursive) {
|
|
@@ -84,9 +81,9 @@ export const applyExtend = (element, parent, options = {}) => {
|
|
|
84
81
|
if (__ref) __ref.__extend = stack
|
|
85
82
|
let mergedExtend = cloneAndMergeArrayExtend(stack)
|
|
86
83
|
|
|
87
|
-
const COMPONENTS =
|
|
84
|
+
const COMPONENTS = context?.components || options.components
|
|
88
85
|
const component = exec(element.component || mergedExtend.component, element)
|
|
89
|
-
if (component && COMPONENTS
|
|
86
|
+
if (component && COMPONENTS?.[component]) {
|
|
90
87
|
const componentExtend = cloneAndMergeArrayExtend(
|
|
91
88
|
getExtendStack(COMPONENTS[component])
|
|
92
89
|
)
|
package/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { TREE } from './tree'
|
|
4
|
-
import create from './create'
|
|
5
|
-
import createNode from './node'
|
|
6
|
-
import define from './define'
|
|
7
|
-
import update from './update'
|
|
8
|
-
import set from './set'
|
|
3
|
+
import { TREE } from './tree.js'
|
|
4
|
+
import create from './create.js'
|
|
5
|
+
import createNode from './node.js'
|
|
6
|
+
import define from './define.js'
|
|
7
|
+
import update from './update.js'
|
|
8
|
+
import set from './set.js'
|
|
9
9
|
|
|
10
10
|
export {
|
|
11
11
|
TREE,
|
|
@@ -15,3 +15,6 @@ export {
|
|
|
15
15
|
update,
|
|
16
16
|
set
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
export * from './event/index.js'
|
|
20
|
+
export * from './render/index.js'
|
package/iterate.js
CHANGED
|
@@ -49,8 +49,7 @@ export const throughUpdatedExec = (element, options = {}) => {
|
|
|
49
49
|
continue
|
|
50
50
|
}
|
|
51
51
|
const execReturnsString = isString(newExec) || isNumber(newExec)
|
|
52
|
-
|
|
53
|
-
if (prop && prop.node && execReturnsString) {
|
|
52
|
+
if (prop?.node && execReturnsString) {
|
|
54
53
|
overwrite(prop, { text: newExec })
|
|
55
54
|
} else if (newExec !== prop) {
|
|
56
55
|
if (matchesComponentNaming(param)) {
|
|
@@ -74,8 +73,13 @@ export const throughExecProps = element => {
|
|
|
74
73
|
const { __ref: ref } = element
|
|
75
74
|
const { props } = element
|
|
76
75
|
for (const k in props) {
|
|
76
|
+
// Check for 'is', 'has', 'use' prefixes using charCodeAt
|
|
77
|
+
const c0 = k.charCodeAt(0)
|
|
78
|
+
const c1 = k.charCodeAt(1)
|
|
77
79
|
const isDefine =
|
|
78
|
-
|
|
80
|
+
(c0 === 105 && c1 === 115) || // 'is'
|
|
81
|
+
(c0 === 104 && c1 === 97 && k.charCodeAt(2) === 115) || // 'has'
|
|
82
|
+
(c0 === 117 && c1 === 115 && k.charCodeAt(2) === 101) // 'use'
|
|
79
83
|
const cachedExecProp = ref.__execProps[k]
|
|
80
84
|
if (isFunction(cachedExecProp)) {
|
|
81
85
|
const result = exec(cachedExecProp, element)
|
|
@@ -100,15 +104,16 @@ export const throughExecProps = element => {
|
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
106
|
|
|
103
|
-
export const isPropertyInDefines = (key, element) => {}
|
|
104
|
-
|
|
105
107
|
export const throughInitialDefine = element => {
|
|
106
108
|
const { define, context, __ref: ref } = element
|
|
107
109
|
|
|
108
|
-
|
|
110
|
+
const hasLocalDefine = isObject(define)
|
|
109
111
|
const hasGlobalDefine = context && isObject(context.define)
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
+
if (!hasLocalDefine && !hasGlobalDefine) return element
|
|
113
|
+
|
|
114
|
+
const defineObj = hasLocalDefine && hasGlobalDefine
|
|
115
|
+
? { ...define, ...context.define }
|
|
116
|
+
: hasLocalDefine ? define : context.define
|
|
112
117
|
|
|
113
118
|
for (const param in defineObj) {
|
|
114
119
|
let elementProp = element[param]
|
|
@@ -152,11 +157,14 @@ export const throughInitialDefine = element => {
|
|
|
152
157
|
|
|
153
158
|
export const throughUpdatedDefine = element => {
|
|
154
159
|
const { context, define, __ref: ref } = element
|
|
155
|
-
const changes = {}
|
|
156
160
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (
|
|
161
|
+
const hasLocalDefine = isObject(define)
|
|
162
|
+
const hasGlobalDefine = isObject(context?.define)
|
|
163
|
+
if (!hasLocalDefine && !hasGlobalDefine) return
|
|
164
|
+
|
|
165
|
+
const obj = hasLocalDefine && hasGlobalDefine
|
|
166
|
+
? { ...define, ...context.define }
|
|
167
|
+
: hasLocalDefine ? define : context.define
|
|
160
168
|
|
|
161
169
|
for (const param in obj) {
|
|
162
170
|
const execParam = ref.__exec[param]
|
|
@@ -189,5 +197,4 @@ export const throughUpdatedDefine = element => {
|
|
|
189
197
|
element[param] = newExecParam
|
|
190
198
|
}
|
|
191
199
|
}
|
|
192
|
-
return changes
|
|
193
200
|
}
|
package/node.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
import { isFunction, isMethod, isObject, isUndefined } from '@domql/utils'
|
|
4
|
-
import { applyEventsOnNode, triggerEventOn } from '
|
|
5
|
-
import {
|
|
4
|
+
import { applyEventsOnNode, triggerEventOn } from './event/index.js'
|
|
5
|
+
import { propagateEventsFromProps, propagateEventsFromElement } from './utils/propEvents.js'
|
|
6
|
+
import { cacheNode } from './render/index.js'
|
|
6
7
|
import { create } from './create.js'
|
|
7
8
|
|
|
8
9
|
import {
|
|
@@ -14,8 +15,6 @@ import { REGISTRY } from './mixins/index.js'
|
|
|
14
15
|
import { applyParam } from './utils/applyParam.js'
|
|
15
16
|
import setChildren from './children.js'
|
|
16
17
|
import { setContent } from './set.js'
|
|
17
|
-
// import { defineSetter } from './methods'
|
|
18
|
-
|
|
19
18
|
const ENV = process.env.NODE_ENV
|
|
20
19
|
|
|
21
20
|
export const createNode = (element, opts) => {
|
|
@@ -52,16 +51,19 @@ export const createNode = (element, opts) => {
|
|
|
52
51
|
// iterate through exec
|
|
53
52
|
throughInitialExec(element)
|
|
54
53
|
|
|
54
|
+
propagateEventsFromProps(element)
|
|
55
|
+
propagateEventsFromElement(element)
|
|
55
56
|
applyEventsOnNode(element, { isNewNode, ...opts })
|
|
56
57
|
|
|
57
58
|
for (const param in element) {
|
|
58
59
|
const value = element[param]
|
|
59
60
|
|
|
60
61
|
if (
|
|
61
|
-
!Object.hasOwnProperty.call(element, param) ||
|
|
62
|
-
|
|
62
|
+
!Object.prototype.hasOwnProperty.call(element, param) ||
|
|
63
|
+
value === undefined ||
|
|
63
64
|
isMethod(param, element) ||
|
|
64
|
-
isObject(REGISTRY[param])
|
|
65
|
+
isObject(REGISTRY[param]) ||
|
|
66
|
+
(param.length > 2 && param.charCodeAt(0) === 111 && param.charCodeAt(1) === 110 && param.charCodeAt(2) >= 65 && param.charCodeAt(2) <= 90)
|
|
65
67
|
) {
|
|
66
68
|
continue
|
|
67
69
|
}
|
|
@@ -90,7 +92,7 @@ export const createNode = (element, opts) => {
|
|
|
90
92
|
|
|
91
93
|
const content = element.children
|
|
92
94
|
? setChildren(element.children, element, opts)
|
|
93
|
-
: element.
|
|
95
|
+
: element.children || element.content
|
|
94
96
|
|
|
95
97
|
if (content) {
|
|
96
98
|
setContent(content, element, opts)
|
package/package.json
CHANGED
|
@@ -1,39 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domql/element",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"module": "index.js",
|
|
7
|
-
"main": "index.js",
|
|
6
|
+
"module": "./dist/esm/index.js",
|
|
7
|
+
"main": "./dist/cjs/index.js",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"import": "./dist/esm/index.js",
|
|
11
|
+
"require": "./dist/cjs/index.js",
|
|
12
|
+
"browser": "./dist/iife/index.js",
|
|
13
|
+
"default": "./dist/esm/index.js"
|
|
12
14
|
},
|
|
13
|
-
"./
|
|
14
|
-
|
|
15
|
+
"./event": {
|
|
16
|
+
"import": "./dist/esm/event/index.js",
|
|
17
|
+
"require": "./dist/cjs/event/index.js",
|
|
18
|
+
"default": "./dist/esm/event/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./render": {
|
|
21
|
+
"import": "./dist/esm/render/index.js",
|
|
22
|
+
"require": "./dist/cjs/render/index.js",
|
|
23
|
+
"default": "./dist/esm/render/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./*.js": {
|
|
26
|
+
"import": "./dist/esm/*.js",
|
|
27
|
+
"require": "./dist/cjs/*.js",
|
|
28
|
+
"default": "./dist/esm/*.js"
|
|
29
|
+
},
|
|
30
|
+
"./*": {
|
|
31
|
+
"import": "./dist/esm/*.js",
|
|
32
|
+
"require": "./dist/cjs/*.js",
|
|
33
|
+
"default": "./dist/esm/*.js"
|
|
34
|
+
}
|
|
15
35
|
},
|
|
16
36
|
"source": "index.js",
|
|
17
37
|
"files": [
|
|
18
|
-
"
|
|
19
|
-
"*.js"
|
|
20
|
-
"dist"
|
|
38
|
+
"dist",
|
|
39
|
+
"*.js"
|
|
21
40
|
],
|
|
22
41
|
"scripts": {
|
|
23
42
|
"copy:package:cjs": "cp ../../build/package-cjs.json dist/cjs/package.json",
|
|
24
|
-
"build:esm": "
|
|
25
|
-
"build:cjs": "
|
|
26
|
-
"build": "
|
|
27
|
-
"prepublish": "
|
|
43
|
+
"build:esm": "cross-env NODE_ENV=$NODE_ENV esbuild *.js methods/*.js mixins/*.js utils/*.js event/*.js render/*.js --target=es2020 --format=esm --outdir=dist/esm --define:process.env.NODE_ENV=process.env.NODE_ENV",
|
|
44
|
+
"build:cjs": "cross-env NODE_ENV=$NODE_ENV esbuild *.js methods/*.js mixins/*.js utils/*.js event/*.js render/*.js --target=node18 --format=cjs --outdir=dist/cjs --define:process.env.NODE_ENV=process.env.NODE_ENV",
|
|
45
|
+
"build": "node ../../build/build.js",
|
|
46
|
+
"prepublish": "npm run build && npm run copy:package:cjs",
|
|
47
|
+
"build:iife": "cross-env NODE_ENV=$NODE_ENV esbuild index.js --bundle --target=es2020 --format=iife --global-name=DomqlElement --outfile=dist/iife/index.js --define:process.env.NODE_ENV=process.env.NODE_ENV"
|
|
28
48
|
},
|
|
29
49
|
"dependencies": {
|
|
30
|
-
"@domql/
|
|
31
|
-
"@domql/render": "^3.2.3",
|
|
50
|
+
"@domql/report": "^3.2.3",
|
|
32
51
|
"@domql/state": "^3.2.3",
|
|
33
|
-
"@domql/utils": "^3.2.3"
|
|
52
|
+
"@domql/utils": "^3.2.3",
|
|
53
|
+
"attrs-in-props": "^3.2.3"
|
|
34
54
|
},
|
|
35
55
|
"gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
|
|
36
56
|
"devDependencies": {
|
|
37
57
|
"@babel/core": "^7.26.0"
|
|
38
|
-
}
|
|
58
|
+
},
|
|
59
|
+
"browser": "./dist/iife/index.js",
|
|
60
|
+
"unpkg": "./dist/iife/index.js",
|
|
61
|
+
"jsdelivr": "./dist/iife/index.js",
|
|
62
|
+
"sideEffects": false
|
|
39
63
|
}
|
package/set.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { deepContains, exec, isFunction, OPTIONS } from '@domql/utils'
|
|
4
4
|
import { create } from './create.js'
|
|
5
|
-
import { triggerEventOn, triggerEventOnUpdate } from '
|
|
5
|
+
import { triggerEventOn, triggerEventOnUpdate } from './event/index.js'
|
|
6
6
|
|
|
7
7
|
export const setContentKey = (element, opts = {}) => {
|
|
8
8
|
const { __ref: ref } = element
|
|
@@ -13,7 +13,7 @@ export const setContentKey = (element, opts = {}) => {
|
|
|
13
13
|
return ref.contentElementKey
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export
|
|
16
|
+
export function reset (options) {
|
|
17
17
|
const element = this
|
|
18
18
|
create(element, element.parent, undefined, {
|
|
19
19
|
ignoreChildExtends: true,
|
|
@@ -71,15 +71,16 @@ export const removeContent = function (el, opts = {}) {
|
|
|
71
71
|
// Handle fragment removal
|
|
72
72
|
if (content.tag === 'fragment' && content.__ref?.__children) {
|
|
73
73
|
// Remove all child nodes
|
|
74
|
-
content.__ref.__children
|
|
75
|
-
|
|
74
|
+
const __children = content.__ref.__children
|
|
75
|
+
for (let i = 0; i < __children.length; i++) {
|
|
76
|
+
const child = content[__children[i]]
|
|
76
77
|
if (child.node && child.node.parentNode) {
|
|
77
78
|
child.node.parentNode.removeChild(child.node)
|
|
78
79
|
}
|
|
79
80
|
if (isFunction(child.remove)) {
|
|
80
81
|
child.remove()
|
|
81
82
|
}
|
|
82
|
-
}
|
|
83
|
+
}
|
|
83
84
|
} else {
|
|
84
85
|
// Handle regular element removal
|
|
85
86
|
if (content.node && content.node.parentNode) {
|
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'
|
|
@@ -46,14 +44,10 @@ const UPDATE_DEFAULT_OPTIONS = {
|
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
export const update = function (params = {}, opts) {
|
|
49
|
-
|
|
50
|
-
const options =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
: UPDATE_DEFAULT_OPTIONS,
|
|
54
|
-
{ exclude: ['calleeElement'] }
|
|
55
|
-
)
|
|
56
|
-
options.calleeElement = calleeElementCache
|
|
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
|
|
@@ -96,20 +90,23 @@ export const update = function (params = {}, opts) {
|
|
|
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
|
|
@@ -125,10 +122,7 @@ export const update = function (params = {}, opts) {
|
|
|
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 = 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 = 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
|
|
@@ -190,8 +194,11 @@ export const update = function (params = {}, opts) {
|
|
|
190
194
|
options.onEachUpdate(param, element, element.state, element.context)
|
|
191
195
|
}
|
|
192
196
|
|
|
197
|
+
const childParams = params[param]
|
|
198
|
+
if (childParams === undefined && !options.isForced) continue
|
|
199
|
+
|
|
193
200
|
const childUpdateCall = () =>
|
|
194
|
-
update.call(prop,
|
|
201
|
+
update.call(prop, childParams, {
|
|
195
202
|
...options,
|
|
196
203
|
currentSnapshot: snapshotOnCallee,
|
|
197
204
|
calleeElement
|
|
@@ -202,7 +209,7 @@ export const update = function (params = {}, opts) {
|
|
|
202
209
|
// eslint-disable-line
|
|
203
210
|
childUpdateCall()
|
|
204
211
|
// handle lazy load
|
|
205
|
-
if (!options.preventUpdateListener) {
|
|
212
|
+
if (!options.preventUpdateListener && !options.preventListeners) {
|
|
206
213
|
triggerEventOn('lazyLoad', element, options)
|
|
207
214
|
}
|
|
208
215
|
})
|
|
@@ -211,17 +218,60 @@ export const update = function (params = {}, opts) {
|
|
|
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) {
|
|
274
|
+
if (!preventUpdateListener && !options.preventListeners) {
|
|
225
275
|
triggerEventOn('update', element, options)
|
|
226
276
|
}
|
|
227
277
|
}
|
|
@@ -275,8 +325,7 @@ const checkIfOnUpdate = (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,
|
|
@@ -333,7 +382,7 @@ const inheritStateUpdates = (element, options) => {
|
|
|
333
382
|
|
|
334
383
|
// If does not have own state inherit from parent
|
|
335
384
|
if (!stateKey && !ref.__hasRootState) {
|
|
336
|
-
element.state =
|
|
385
|
+
element.state = parent?.state || {}
|
|
337
386
|
return
|
|
338
387
|
}
|
|
339
388
|
|
|
@@ -389,14 +438,3 @@ const createStateUpdate = (element, parent, options) => {
|
|
|
389
438
|
}
|
|
390
439
|
|
|
391
440
|
export default update
|
|
392
|
-
|
|
393
|
-
// save updates history
|
|
394
|
-
// const overwriteChanges = overwriteDeep(element, params, { exclude: METHODS_EXL })
|
|
395
|
-
// // const overwriteChanges = overwriteDeep(element, params)
|
|
396
|
-
// const propsChanges = throughExecProps(element)
|
|
397
|
-
// const execChanges = throughUpdatedExec(element, { ignore: UPDATE_DEFAULT_OPTIONS })
|
|
398
|
-
// const definedChanges = throughUpdatedDefine(element)
|
|
399
|
-
// if (options.stackChanges && ref.__stackChanges) {
|
|
400
|
-
// const stackChanges = merge(definedChanges, merge(execChanges, overwriteChanges))
|
|
401
|
-
// ref.__stackChanges.push(stackChanges)
|
|
402
|
-
// }
|
|
@@ -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', () => {
|
|
48
|
-
delete element.if
|
|
49
|
-
element.props.if = () => false
|
|
50
|
-
update.call(element, {}, options)
|
|
51
|
-
expect(element.node).toEqual(document.createElement('div'))
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('retains state when __hasRootState=true', () => {
|
|
55
|
-
element.__ref.__hasRootState = true
|
|
56
|
-
element.state.critical = true
|
|
57
|
-
element.__ref.__if = false
|
|
58
|
-
|
|
59
|
-
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', () => {
|
|
66
|
-
element.content = {
|
|
67
|
-
parseDeep: () => ({ parsed: true }),
|
|
68
|
-
existing: 'data'
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
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', () => {
|
|
78
|
-
const prevNode = document.createElement('span')
|
|
79
|
-
parent.node.appendChild(prevNode)
|
|
80
|
-
|
|
81
|
-
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', () => {
|
|
89
|
-
// const nextNode = document.createElement('p')
|
|
90
|
-
// parent.node.appendChild(nextNode)
|
|
91
|
-
|
|
92
|
-
// 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', () => {
|
|
100
|
-
// update.call(element, {}, options)
|
|
101
|
-
// expect(parent.node.children).toHaveLength(0)
|
|
102
|
-
// })
|
|
103
|
-
})
|