@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.
Files changed (135) hide show
  1. package/README.md +4 -6
  2. package/children.js +45 -18
  3. package/create.js +58 -46
  4. package/define.js +1 -1
  5. package/dist/cjs/children.js +43 -13
  6. package/dist/cjs/create.js +57 -27
  7. package/dist/cjs/define.js +1 -1
  8. package/dist/cjs/event/animationFrame.js +96 -0
  9. package/dist/cjs/event/can.js +28 -0
  10. package/dist/cjs/event/index.js +20 -0
  11. package/dist/cjs/event/on.js +84 -0
  12. package/dist/cjs/event/store.js +27 -0
  13. package/dist/cjs/extend.js +88 -0
  14. package/dist/cjs/index.js +9 -6
  15. package/dist/cjs/iterate.js +89 -33
  16. package/dist/cjs/methods/set.js +5 -0
  17. package/dist/cjs/methods/v2.js +1 -1
  18. package/dist/cjs/mixins/attr.js +3 -2
  19. package/dist/cjs/mixins/classList.js +11 -1
  20. package/dist/cjs/mixins/content.js +72 -0
  21. package/dist/cjs/mixins/html.js +1 -2
  22. package/dist/cjs/mixins/registry.js +2 -2
  23. package/dist/cjs/mixins/scope.js +1 -1
  24. package/dist/cjs/mixins/state.js +4 -4
  25. package/dist/cjs/mixins/style.js +11 -2
  26. package/dist/cjs/mixins/text.js +9 -5
  27. package/dist/cjs/node.js +22 -19
  28. package/dist/cjs/render/append.js +72 -0
  29. package/dist/cjs/render/cache.js +80 -0
  30. package/dist/cjs/render/create.js +25 -0
  31. package/dist/cjs/render/index.js +20 -0
  32. package/dist/cjs/set.js +33 -40
  33. package/dist/cjs/update.js +100 -69
  34. package/dist/cjs/utils/applyParam.js +7 -7
  35. package/dist/cjs/utils/extendUtils.js +132 -0
  36. package/dist/cjs/utils/index.js +2 -0
  37. package/dist/cjs/utils/propEvents.js +56 -0
  38. package/dist/esm/children.js +44 -14
  39. package/dist/esm/create.js +58 -27
  40. package/dist/esm/define.js +1 -1
  41. package/dist/esm/event/animationFrame.js +76 -0
  42. package/dist/esm/event/can.js +8 -0
  43. package/dist/esm/event/index.js +3 -0
  44. package/dist/esm/event/on.js +64 -0
  45. package/dist/esm/event/store.js +7 -0
  46. package/dist/esm/extend.js +74 -0
  47. package/dist/esm/index.js +8 -6
  48. package/dist/esm/iterate.js +90 -35
  49. package/dist/esm/methods/set.js +10 -0
  50. package/dist/esm/methods/v2.js +1 -1
  51. package/dist/esm/mixins/attr.js +4 -3
  52. package/dist/esm/mixins/classList.js +11 -1
  53. package/dist/esm/mixins/content.js +52 -0
  54. package/dist/esm/mixins/html.js +1 -2
  55. package/dist/esm/mixins/registry.js +1 -1
  56. package/dist/esm/mixins/scope.js +1 -1
  57. package/dist/esm/mixins/state.js +5 -5
  58. package/dist/esm/mixins/style.js +12 -3
  59. package/dist/esm/mixins/text.js +10 -6
  60. package/dist/esm/node.js +22 -19
  61. package/dist/esm/render/append.js +52 -0
  62. package/dist/esm/render/cache.js +60 -0
  63. package/dist/esm/render/create.js +5 -0
  64. package/dist/esm/render/index.js +3 -0
  65. package/dist/esm/set.js +34 -41
  66. package/dist/esm/update.js +100 -71
  67. package/dist/esm/utils/applyParam.js +8 -8
  68. package/dist/esm/utils/extendUtils.js +119 -0
  69. package/dist/esm/utils/index.js +1 -0
  70. package/dist/esm/utils/propEvents.js +36 -0
  71. package/dist/iife/index.js +4718 -0
  72. package/extend.js +95 -0
  73. package/index.js +9 -6
  74. package/iterate.js +100 -38
  75. package/node.js +25 -23
  76. package/package.json +44 -20
  77. package/set.js +28 -32
  78. package/update.js +111 -82
  79. package/__tests__/checkIfOnUpdate.test.js +0 -103
  80. package/__tests__/children.test.js +0 -213
  81. package/__tests__/define.test.js +0 -75
  82. package/__tests__/inheritStateUpdates.test.js +0 -79
  83. package/__tests__/renderElement.test.js +0 -131
  84. package/__tests__/resetElement.test.js +0 -44
  85. package/__tests__/set.test.js +0 -316
  86. package/__tests__/throughExecProps.test.js +0 -86
  87. package/__tests__/throughInitialDefine.test.js +0 -104
  88. package/__tests__/throughInitialExec.test.js +0 -92
  89. package/__tests__/throughUpdatedDefine.test.js +0 -92
  90. package/__tests__/throughUpdatedExec.test.js +0 -110
  91. package/__tests__/tree.test.js +0 -15
  92. package/__tests__/update.test.js +0 -256
  93. package/dist/cjs/__tests__/checkIfOnUpdate.test.js +0 -73
  94. package/dist/cjs/__tests__/children.test.js +0 -177
  95. package/dist/cjs/__tests__/define.test.js +0 -75
  96. package/dist/cjs/__tests__/inheritStateUpdates.test.js +0 -62
  97. package/dist/cjs/__tests__/renderElement.test.js +0 -138
  98. package/dist/cjs/__tests__/resetElement.test.js +0 -35
  99. package/dist/cjs/__tests__/set.test.js +0 -256
  100. package/dist/cjs/__tests__/throughExecProps.test.js +0 -62
  101. package/dist/cjs/__tests__/throughInitialDefine.test.js +0 -79
  102. package/dist/cjs/__tests__/throughInitialExec.test.js +0 -73
  103. package/dist/cjs/__tests__/throughUpdatedDefine.test.js +0 -69
  104. package/dist/cjs/__tests__/throughUpdatedExec.test.js +0 -84
  105. package/dist/cjs/__tests__/tree.test.js +0 -11
  106. package/dist/cjs/__tests__/update.test.js +0 -222
  107. package/dist/cjs/package.json +0 -4
  108. package/dist/esm/__tests__/checkIfOnUpdate.test.js +0 -73
  109. package/dist/esm/__tests__/children.test.js +0 -177
  110. package/dist/esm/__tests__/define.test.js +0 -53
  111. package/dist/esm/__tests__/inheritStateUpdates.test.js +0 -62
  112. package/dist/esm/__tests__/renderElement.test.js +0 -116
  113. package/dist/esm/__tests__/resetElement.test.js +0 -35
  114. package/dist/esm/__tests__/set.test.js +0 -256
  115. package/dist/esm/__tests__/throughExecProps.test.js +0 -62
  116. package/dist/esm/__tests__/throughInitialDefine.test.js +0 -79
  117. package/dist/esm/__tests__/throughInitialExec.test.js +0 -73
  118. package/dist/esm/__tests__/throughUpdatedDefine.test.js +0 -69
  119. package/dist/esm/__tests__/throughUpdatedExec.test.js +0 -84
  120. package/dist/esm/__tests__/tree.test.js +0 -11
  121. package/dist/esm/__tests__/update.test.js +0 -222
  122. package/methods/set.js +0 -63
  123. package/methods/v2.js +0 -83
  124. package/mixins/attr.js +0 -32
  125. package/mixins/classList.js +0 -54
  126. package/mixins/data.js +0 -26
  127. package/mixins/html.js +0 -21
  128. package/mixins/index.js +0 -23
  129. package/mixins/registry.js +0 -46
  130. package/mixins/scope.js +0 -23
  131. package/mixins/state.js +0 -19
  132. package/mixins/style.js +0 -16
  133. package/mixins/text.js +0 -26
  134. package/utils/applyParam.js +0 -34
  135. package/utils/index.js +0 -3
@@ -1,75 +0,0 @@
1
- import define from '../define'
2
- import { REGISTRY } from '../mixins'
3
-
4
- describe('default function (registry updater)', () => {
5
- let originalRegistry
6
-
7
- beforeEach(() => {
8
- // Save the original REGISTRY to restore after each test
9
- originalRegistry = { ...REGISTRY }
10
- })
11
-
12
- afterEach(() => {
13
- // Restore the original REGISTRY after each test
14
- Object.keys(REGISTRY).forEach(key => {
15
- REGISTRY[key] = originalRegistry[key]
16
- })
17
- })
18
-
19
- it('should add new params to REGISTRY when overwrite is true', () => {
20
- const params = { newKey: 'newValue', anotherKey: 'anotherValue' }
21
- const options = { overwrite: true }
22
-
23
- define(params, options)
24
-
25
- expect(REGISTRY.newKey).toBe('newValue')
26
- expect(REGISTRY.anotherKey).toBe('anotherValue')
27
- })
28
-
29
- it('should not modify REGISTRY when trying to overwrite existing keys without overwrite option', () => {
30
- const params = { attr: 'newValue', text: 'newText' }
31
-
32
- try {
33
- define(params)
34
- } catch (e) {
35
- // Ignore the error
36
- }
37
-
38
- expect(REGISTRY.attr).toBe(originalRegistry.attr)
39
- expect(REGISTRY.text).toBe(originalRegistry.text)
40
- })
41
-
42
- it('should overwrite existing keys when overwrite is true', () => {
43
- const params = { attr: 'newValue', text: 'newText' }
44
- const options = { overwrite: true }
45
-
46
- define(params, options)
47
-
48
- expect(REGISTRY.attr).toBe('newValue')
49
- expect(REGISTRY.text).toBe('newText')
50
- })
51
-
52
- it('should handle empty params object without errors', () => {
53
- const params = {}
54
- const options = { overwrite: true }
55
-
56
- expect(() => define(params, options)).not.toThrow()
57
- expect(REGISTRY).toEqual(originalRegistry)
58
- })
59
-
60
- it('should handle empty options object without errors', () => {
61
- const params = { newKey: 'newValue' }
62
-
63
- expect(() => define(params, {})).not.toThrow()
64
- expect(REGISTRY.newKey).toBe('newValue')
65
- })
66
-
67
- it('should not add new keys when params is empty', () => {
68
- const params = {}
69
- const options = { overwrite: true }
70
-
71
- define(params, options)
72
-
73
- expect(REGISTRY).toEqual(originalRegistry)
74
- })
75
- })
@@ -1,79 +0,0 @@
1
- import { update } from '../update'
2
-
3
- describe('update() with inheritStateUpdates', () => {
4
- let element, options
5
-
6
- beforeEach(() => {
7
- element = {
8
- __ref: {
9
- __state: null,
10
- __hasRootState: false,
11
- __execProps: {},
12
- __props: []
13
- },
14
- state: {
15
- calculated: 42,
16
- set: () => {
17
- return true
18
- }
19
- },
20
- parent: {
21
- state: { baseState: true },
22
- props: {}
23
- },
24
- props: {},
25
- key: 'testKey'
26
- }
27
- options = {}
28
- })
29
-
30
- // Test 1: Continue update when state inheritance succeeds
31
- it('processes full update flow when state is inherited', async () => {
32
- await update.call(element, { props: { newProp: true } }, options)
33
- expect(element.props.newProp).toBe(true)
34
- expect(element.state.baseState).toBe(true) // Inherited from parent
35
- })
36
-
37
- // Test 2: Preserve existing state when inheritance blocked
38
- it('maintains state when preventInheritedStateUpdate=true', async () => {
39
- options.preventInheritedStateUpdate = true
40
- element.state = { existing: 'state' }
41
-
42
- await update.call(element, {}, options)
43
- expect(element.state).toEqual({ baseState: true })
44
- })
45
-
46
- // Test 3: Execute state functions when forced
47
- it('overwrites state with function result', async () => {
48
- element.__ref.__state = () => ({ calculated: 42 })
49
- options.execStateFunction = true
50
- options.stateFunctionOverwrite = true
51
-
52
- await update.call(element, {}, options)
53
- expect(element.state.calculated).toEqual(42)
54
- })
55
-
56
- // Test 4: Block updates via beforeStateUpdate event
57
- it('preserves state when beforeStateUpdate rejects', async () => {
58
- element.onBeforeStateUpdate = () => false
59
- await update.call(element, { props: { shouldChange: true } }, options)
60
- expect(element.state).toEqual({ baseState: true })
61
- expect(element.props.shouldChange).toBe(true)
62
- })
63
-
64
- // Test 5: Handle parent state changes
65
- it('reflects parent state updates', async () => {
66
- element.parent.state = { updatedParentState: true }
67
- await update.call(element, {}, options)
68
- expect(element.state.updatedParentState).toBe(true)
69
- })
70
-
71
- // Test 6: Maintain local state when root state exists
72
- it('preserves local state when __hasRootState=true', async () => {
73
- element.__ref.__hasRootState = true
74
- element.state = { local: 'data' }
75
-
76
- await update.call(element, {}, options)
77
- expect(element.state.local).toBe('data')
78
- })
79
- })
@@ -1,131 +0,0 @@
1
- import { jest } from '@jest/globals'
2
-
3
- describe('create()', () => {
4
- let props
5
- let parent
6
-
7
- const OLD_ENV = process.env
8
-
9
- beforeEach(() => {
10
- props = {
11
- __ref: { __if: false, path: [], __skipCreate: true },
12
- key: 'testKey',
13
- context: {
14
- defaultExtends: {},
15
- define: ['test']
16
- },
17
- scope: 'props',
18
- define: ['test']
19
- }
20
- parent = {
21
- testKey: 'parentTestKey',
22
- key: 'parentKey'
23
- }
24
- jest.resetModules()
25
- process.env = { ...OLD_ENV }
26
- })
27
-
28
- afterAll(() => {
29
- process.env = OLD_ENV
30
- })
31
-
32
- test('should execute onlyResolveExtends when __skipCreate is true', async () => {
33
- props.__ref.__skipCreate = true
34
- props.scope = undefined
35
- const { create } = await import('../create')
36
- await create(props, parent, 'passedKey', {
37
- onlyResolveExtends: true,
38
- define: ['test']
39
- })
40
- expect(parent.__ref).toBeUndefined()
41
- expect(parent.passedKey).toBe(props.__ref.parent.passedKey)
42
- })
43
-
44
- test('should execute onlyResolveExtends when __ref.__if is true', async () => {
45
- props.__ref.__if = true
46
- props.scope = 'state'
47
- const { create } = await import('../create')
48
- await create(props, parent, 'passedKey', {
49
- onlyResolveExtends: true,
50
- define: ['test']
51
- })
52
- expect(parent.__ref).toBeUndefined()
53
- expect(parent.passedKey).toBe(props.__ref.parent.passedKey)
54
- })
55
-
56
- test('should execute onlyResolveExtends when scope is not state', async () => {
57
- process.env.NODE_ENV = 'prod'
58
- props.__ref = undefined
59
- const { create } = await import('../create')
60
- await create(props, parent, 'passedKey', { onlyResolveExtends: true })
61
- expect(parent.__ref).toBeUndefined()
62
- expect(parent.passedKey).toBe(props.__ref.parent.passedKey)
63
- })
64
-
65
- test('should execute catch statement when __ref is undefined', async () => {
66
- process.env.NODE_ENV = 'prod'
67
- props.__ref = undefined
68
- const { create } = await import('../create')
69
- await create(props, parent, 'passedKey')
70
- expect(parent.__ref).toBeUndefined()
71
- expect(parent.passedKey).toBe(props.__ref.parent.passedKey)
72
- })
73
-
74
- test('should attaches element to parent when ref.__if is false', async () => {
75
- process.env.NODE_ENV = 'prod'
76
- const { create } = await import('../create')
77
- await create(props, parent, 'passedKey')
78
- expect(parent.__ref).toBeUndefined()
79
- expect(parent.passedKey).toBe(props.__ref.parent.passedKey)
80
- })
81
-
82
- test('should attach element to parent when ref.__if is true', async () => {
83
- process.env.NODE_ENV = 'prod'
84
- props.__if = true
85
- const { create } = await import('../create')
86
- await create(props, parent, 'passedKey')
87
- expect(parent.testKey).toBe('parentTestKey')
88
- expect(parent.passedKey).toBe(props.__ref.parent.passedKey)
89
- })
90
-
91
- test('skips createNestedChild when __uniqId exists', async () => {
92
- process.env.NODE_ENV = 'prod'
93
- props.__ref = { __uniqId: 'existing-id', path: [] }
94
- const { create } = await import('../create')
95
- await create(props, {}, 'passedKey')
96
- expect(props.__ref.__uniqId).toBeDefined()
97
- })
98
-
99
- test('skips createNestedChild when infinite loop detected', async () => {
100
- process.env.NODE_ENV = 'prod'
101
- props.__ref = { path: ['loop-path'], __uniqId: undefined }
102
- const { create } = await import('../create')
103
- await create(props, {}, 'passedKey')
104
- expect(props.__ref.__uniqId).toBeDefined()
105
- })
106
-
107
- test('should modifies path containing ComponentsGrid', async () => {
108
- process.env.NODE_ENV = 'prod'
109
- props.__ref = { path: ['ComponentsGrid', 'x', 'y', 'z'] }
110
- const { create } = await import('../create')
111
- await create(props, {}, ['ComponentsGrid', 'x', 'y', 'z'])
112
- expect(props.__ref.path).toEqual(['ComponentsGrid,x,y,z'])
113
- })
114
-
115
- test('should modifies path containing demoComponent', async () => {
116
- process.env.NODE_ENV = 'prod'
117
- props.__ref = { path: ['demoComponent', 'a', 'b', 'c'] }
118
- const { create } = await import('../create')
119
- await create(props, {}, ['demoComponent', 'a', 'b', 'c'])
120
- expect(props.__ref.path).toEqual(['demoComponent,a,b,c'])
121
- })
122
-
123
- test('uses element.key when key property is missing', async () => {
124
- process.env.NODE_ENV = 'prod'
125
- props.__ref = { __if: false, path: [] }
126
- props.key = 'fallbackKey'
127
- const { create } = await import('../create')
128
- await create(props, parent, null)
129
- expect(props.__ref.parent.fallbackKey).toBeDefined()
130
- })
131
- })
@@ -1,44 +0,0 @@
1
- import { resetContent } from '../set'
2
-
3
- describe('resetContent', () => {
4
- let element, ref
5
-
6
- beforeEach(() => {
7
- ref = {
8
- contentElementKey: 'content'
9
- }
10
- element = {
11
- __ref: ref,
12
- content: { node: document.createElement('div') },
13
- node: document.createElement('div'),
14
- context: {}
15
- }
16
- })
17
-
18
- it('should update contentElementKey from options', async () => {
19
- await resetContent({}, element, { contentElementKey: 'mainContent' })
20
-
21
- expect(ref.contentElementKey).toBe('mainContent')
22
- expect(element.mainContent).toBeDefined()
23
- })
24
-
25
- it('should merge options correctly', async () => {
26
- await resetContent({}, element, { customOption: true })
27
-
28
- expect(element.content).toEqual(
29
- expect.objectContaining({
30
- // Verify options merging through observable behavior
31
- // (this assertion pattern would need actual create() implementation details)
32
- })
33
- )
34
- })
35
-
36
- it('should maintain context through reset', async () => {
37
- const originalContext = element.context
38
-
39
- await resetContent({}, element, {})
40
-
41
- expect(element.context).toBe(originalContext)
42
- expect(element.content.context).toBe(originalContext)
43
- })
44
- })
@@ -1,316 +0,0 @@
1
- import { jest } from '@jest/globals'
2
- import { removeContent, set, setContentKey } from '../set'
3
-
4
- describe('set', () => {
5
- let element, ref
6
-
7
- beforeEach(() => {
8
- ref = {
9
- contentElementKey: 'content',
10
- __noChildrenDifference: false
11
- }
12
- element = {
13
- __ref: ref,
14
- props: {},
15
- children: [],
16
- context: { components: {} },
17
- state: {},
18
- node: document.createElement('div'),
19
- childExtends: {},
20
- parent: { node: document.createElement('div') }
21
- }
22
- })
23
-
24
- // 1. Basic Content Updates
25
- it('updates element.props when params.props are provided', async () => {
26
- await set.call(element, { props: { title: 'New Title' } })
27
- expect(element.content.props.title).toBe('New Title')
28
- })
29
-
30
- // 2. Deep Equality Checks
31
- it('skips update when deepContains matches existing content', async () => {
32
- ref.__noChildrenDifference = true
33
- const originalProps = { ...element.props }
34
- await set.call(element, { props: { id: 'same' } })
35
- expect(element.props).toEqual(originalProps)
36
- })
37
-
38
- // 3. ChildExtends Inheritance
39
- it('merges element.childExtends into params when missing', async () => {
40
- element.childExtends = { button: 'PrimaryButton' }
41
- const params = { tag: 'fragment', props: {} }
42
- await set.call(element, params)
43
- expect(params.childExtends).toEqual({ button: 'PrimaryButton' })
44
- expect(params.props.ignoreChildExtends).toBe(true)
45
- })
46
-
47
- // 6. Prevent Content Update
48
- it('preserves content when preventContentUpdate=true and no children', async () => {
49
- const originalContent = element[ref.contentElementKey]
50
- await set.call(
51
- element,
52
- { props: { new: true } },
53
- { preventContentUpdate: true }
54
- )
55
- expect(element[ref.contentElementKey]).toBeDefined()
56
- expect(originalContent).toBeUndefined()
57
- })
58
-
59
- // 7. ChildProps Inheritance
60
- it('copies element.props.childProps into params when missing', async () => {
61
- element.props.childProps = { size: 'large' }
62
- const params = { tag: 'fragment', props: {} }
63
- await set.call(element, params)
64
- expect(params.props.childProps).toEqual({ size: 'large' })
65
- expect(params.props.ignoreChildProps).toBe(true)
66
- })
67
-
68
- // 8. Event Blocking
69
- it('preserves state when beforeUpdate returns false', async () => {
70
- ref.__noChildrenDifference = true
71
- const originalState = { ...element.state }
72
-
73
- // Simulate beforeUpdate rejection by not changing state
74
- await set.call(element, { state: { shouldChange: true } })
75
- expect(element.state).toEqual(originalState)
76
- })
77
-
78
- // 9. DOM Node Handling
79
- it('updates node reference when provided in params', async () => {
80
- const newNode = document.createElement('section')
81
- await set.call(element, { node: newNode })
82
- expect(element.node.tagName).toBe('DIV')
83
- })
84
-
85
- // 11. Context Component Resolution
86
- it('resolves context components in params', async () => {
87
- element.context.components = { Header: {} }
88
- await set.call(element, { Header: {} })
89
- expect(element.Header).toBeUndefined()
90
- })
91
-
92
- // 12. Nested Property Updates
93
- it('updates nested props without mutating original', async () => {
94
- const originalProps = { nested: { value: 1 } }
95
- element.props = originalProps
96
- await set.call(element, { props: { nested: { value: 2 } } })
97
- expect(element.props.nested.value).toBe(1)
98
- expect(originalProps.nested.value).toBe(1) // No mutation
99
- })
100
-
101
- // 13. Empty Param Handling
102
- it('preserves existing props when params=null', async () => {
103
- element.props = { preserveMe: true }
104
- await set.call(element, null)
105
- expect(element.props.preserveMe).toBe(true)
106
- })
107
-
108
- // 14. Content Removal
109
- it('removes content correctly when calling removeContent', async () => {
110
- const content = document.createElement('div')
111
- element.content = {
112
- node: content,
113
- tag: 'div',
114
- remove: jest.fn()
115
- }
116
- element.node.appendChild(content)
117
- await set.call(element, { props: { new: true } })
118
- expect(element.content.__ref).toBeDefined()
119
- expect(element.node.contains(content)).toBeFalsy()
120
- })
121
-
122
- // 15. Lazy Loading
123
- it('handles lazy loading with requestAnimationFrame', async () => {
124
- jest.useFakeTimers()
125
- element.props = { lazyLoad: true }
126
- const params = { props: { test: true } }
127
-
128
- await set.call(element, params)
129
- jest.runAllTimers()
130
-
131
- setTimeout(() => {
132
- expect(element.content).toBeDefined()
133
- }, 35)
134
- jest.useRealTimers()
135
- })
136
-
137
- // 17. Fragment Content
138
- it('handles fragment content removal correctly', async () => {
139
- const remove1 = jest.fn(() => Promise.resolve())
140
- const remove2 = jest.fn(() => Promise.resolve())
141
- const node1 = document.createElement('div')
142
- const node2 = document.createElement('div')
143
-
144
- element.tag = 'fragment'
145
- element.content = {
146
- tag: 'fragment',
147
- node: element.node,
148
- __ref: {
149
- __children: ['child1', 'child2']
150
- },
151
- child1: { node: node1, remove: remove1 },
152
- child2: { node: node2, remove: remove2 }
153
- }
154
-
155
- element.node.appendChild(node1)
156
- element.node.appendChild(node2)
157
-
158
- await set.call(element, { props: { new: true } })
159
-
160
- expect(remove1).toHaveBeenCalled()
161
- expect(remove2).toHaveBeenCalled()
162
- })
163
-
164
- it('handles fragment content removal with children', async () => {
165
- const remove1 = jest.fn()
166
- const remove2 = jest.fn()
167
- const node1 = document.createElement('div')
168
- const node2 = document.createElement('div')
169
-
170
- element.content = {
171
- tag: 'fragment',
172
- node: element.node,
173
- __ref: {
174
- __children: ['child1', 'child2']
175
- },
176
- child1: { node: node1, remove: remove1 },
177
- child2: { node: node2, remove: remove2 }
178
- }
179
-
180
- element.node.appendChild(node1)
181
- element.node.appendChild(node2)
182
-
183
- await set.call(element, { props: { new: true } })
184
-
185
- expect(remove1).toHaveBeenCalled()
186
- expect(remove2).toHaveBeenCalled()
187
- })
188
-
189
- it('merges element.childExtends into params when tag is fragment', async () => {
190
- element.tag = 'fragment'
191
- element.childExtends = { button: 'PrimaryButton' }
192
- const params = { tag: 'fragment', props: {} }
193
- await set.call(element, params)
194
- expect(params.childExtends).toEqual(element.childExtends)
195
- })
196
-
197
- it('copies element.props.childProps into params for fragments', async () => {
198
- element.tag = 'fragment'
199
- element.props.childProps = { size: 'large' }
200
- const params = { tag: 'fragment', props: {} }
201
- await set.call(element, params)
202
- expect(params.props.childProps).toEqual(element.props.childProps)
203
- })
204
- })
205
-
206
- describe('setContentKey', () => {
207
- test('should set default content key', () => {
208
- const element = {
209
- __ref: {}
210
- }
211
- const result = setContentKey(element)
212
- expect(result).toBe('content')
213
- expect(element.__ref.contentElementKey).toBe('content')
214
- })
215
-
216
- test('should set custom content key', () => {
217
- const element = {
218
- __ref: {}
219
- }
220
- const opts = { contentElementKey: 'customContent' }
221
- const result = setContentKey(element, opts)
222
- expect(result).toBe('customContent')
223
- expect(element.__ref.contentElementKey).toBe('customContent')
224
- })
225
-
226
- test('should not override existing content key if same value', () => {
227
- const element = {
228
- __ref: {
229
- contentElementKey: 'content'
230
- }
231
- }
232
- const result = setContentKey(element)
233
- expect(result).toBe('content')
234
- expect(element.__ref.contentElementKey).toBe('content')
235
- })
236
-
237
- test('should override existing content key if different value', () => {
238
- const element = {
239
- __ref: {
240
- contentElementKey: 'oldContent'
241
- }
242
- }
243
- const opts = { contentElementKey: 'newContent' }
244
- const result = setContentKey(element, opts)
245
- expect(result).toBe('newContent')
246
- expect(element.__ref.contentElementKey).toBe('newContent')
247
- })
248
- })
249
-
250
- describe('removeContent', () => {
251
- let element
252
-
253
- beforeEach(() => {
254
- // Setup basic element structure
255
- element = {
256
- node: document.createElement('div'),
257
- __ref: {}
258
- }
259
- })
260
-
261
- test('removes basic content', () => {
262
- const contentNode = document.createElement('span')
263
- element.content = {
264
- node: contentNode,
265
- tag: 'span'
266
- }
267
- element.node.appendChild(contentNode)
268
-
269
- removeContent(element)
270
-
271
- expect(element.content).toBeUndefined()
272
- expect(element.node.children.length).toBe(0)
273
- })
274
-
275
- test('removes fragment content', () => {
276
- const remove1 = jest.fn()
277
- const remove2 = jest.fn()
278
- const node1 = document.createElement('div')
279
- const node2 = document.createElement('div')
280
- const fragmentNode = document.createElement('div')
281
- fragmentNode.setAttribute('fragment', '')
282
-
283
- element.node.appendChild(node1)
284
- element.node.appendChild(node2)
285
- element.content = {
286
- tag: 'fragment',
287
- node: fragmentNode,
288
- __ref: {
289
- __children: ['child1', 'child2']
290
- },
291
- child1: { node: node1, remove: remove1 },
292
- child2: { node: node2, remove: remove2 }
293
- }
294
-
295
- removeContent(element)
296
-
297
- expect(remove1).toHaveBeenCalled()
298
- expect(remove2).toHaveBeenCalled()
299
- expect(element.content).toBeUndefined()
300
- expect(element.node.children.length).toBe(0)
301
- })
302
-
303
- test('handles custom content element key', () => {
304
- const contentNode = document.createElement('span')
305
- element.customContent = {
306
- node: contentNode,
307
- tag: 'span'
308
- }
309
- element.node.appendChild(contentNode)
310
-
311
- removeContent(element, { contentElementKey: 'customContent' })
312
-
313
- expect(element.customContent).toBeUndefined()
314
- expect(element.node.children.length).toBe(0)
315
- })
316
- })