@domql/element 3.4.4 → 3.4.6
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/event/__tests__/applyAnimationFrame.test.js +114 -0
- package/event/__tests__/applyEvent.test.js +159 -0
- package/event/__tests__/applyEventUpdate.test.js +198 -0
- package/event/__tests__/applyEventsOnNode.test.js +216 -0
- package/event/__tests__/canRenderTag.test.js +50 -0
- package/event/__tests__/index.test.js +39 -0
- package/event/__tests__/initAnimationFrame.test.js +156 -0
- package/event/__tests__/registerFrameListener.test.js +97 -0
- package/event/__tests__/store.test.js +93 -0
- package/event/__tests__/triggerEventOn.test.js +195 -0
- package/event/__tests__/triggerEventOnUpdate.test.js +207 -0
- package/event/animationFrame.js +92 -0
- package/event/can.js +8 -0
- package/event/index.js +5 -0
- package/event/on.js +71 -0
- package/event/store.js +6 -0
- package/methods/set.js +73 -0
- package/methods/v2.js +83 -0
- package/mixins/attr.js +32 -0
- package/mixins/classList.js +62 -0
- package/mixins/content.js +65 -0
- package/mixins/data.js +26 -0
- package/mixins/html.js +19 -0
- package/mixins/index.js +23 -0
- package/mixins/registry.js +46 -0
- package/mixins/scope.js +23 -0
- package/mixins/state.js +18 -0
- package/mixins/style.js +25 -0
- package/mixins/text.js +31 -0
- package/package.json +13 -8
- package/render/__tests__/appendNode.test.js +53 -0
- package/render/__tests__/assignNode.test.js +151 -0
- package/render/__tests__/cacheNode.test.js +168 -0
- package/render/__tests__/createHTMLNode.test.js +118 -0
- package/render/__tests__/createNode.test.js +9 -0
- package/render/__tests__/detectTag.test.js +99 -0
- package/render/__tests__/index.test.js +56 -0
- package/render/__tests__/insertNodeAfter.test.js +111 -0
- package/render/__tests__/insertNodeBefore.test.js +65 -0
- package/render/append.js +61 -0
- package/render/cache.js +68 -0
- package/render/create.js +3 -0
- package/render/index.js +5 -0
- package/utils/applyParam.js +33 -0
- package/utils/extendUtils.js +135 -0
- package/utils/index.js +4 -0
- package/utils/propEvents.js +36 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { isFunction, setContentKey } from '@domql/utils'
|
|
4
|
+
import { set } from '../set.js'
|
|
5
|
+
|
|
6
|
+
export const updateContent = function (params, options) {
|
|
7
|
+
const element = this
|
|
8
|
+
const ref = element.__ref
|
|
9
|
+
|
|
10
|
+
const contentKey = ref.contentElementKey
|
|
11
|
+
|
|
12
|
+
if (!element[contentKey]) return
|
|
13
|
+
if (element[contentKey].update) element[contentKey].update(params, options)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const removeContent = function (el, opts = {}) {
|
|
17
|
+
const element = el || this
|
|
18
|
+
const { __ref: ref } = element
|
|
19
|
+
const contentElementKey = setContentKey(element, opts)
|
|
20
|
+
|
|
21
|
+
if (opts.contentElementKey !== 'content') opts.contentElementKey = 'content'
|
|
22
|
+
if (element[contentElementKey]) {
|
|
23
|
+
if (element[contentElementKey].node && element.node) {
|
|
24
|
+
if (element[contentElementKey].tag === 'fragment')
|
|
25
|
+
element.node.innerHTML = ''
|
|
26
|
+
else {
|
|
27
|
+
const contentNode = element[contentElementKey].node
|
|
28
|
+
if (contentNode.parentNode === element.node)
|
|
29
|
+
element.node.removeChild(element[contentElementKey].node)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const { __cached } = ref
|
|
34
|
+
if (__cached && __cached[contentElementKey]) {
|
|
35
|
+
if (__cached[contentElementKey].tag === 'fragment')
|
|
36
|
+
__cached[contentElementKey].parent.node.innerHTML = ''
|
|
37
|
+
else if (
|
|
38
|
+
__cached[contentElementKey] &&
|
|
39
|
+
isFunction(__cached[contentElementKey].remove)
|
|
40
|
+
)
|
|
41
|
+
__cached[contentElementKey].remove()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
ref.__children.splice(ref.__children.indexOf(element[contentElementKey]), 1)
|
|
45
|
+
|
|
46
|
+
delete element[contentElementKey]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Appends anything as content
|
|
52
|
+
* an original one as a child
|
|
53
|
+
*/
|
|
54
|
+
export function setContent (param, element, node, opts) {
|
|
55
|
+
const contentElementKey = setContentKey(element, opts)
|
|
56
|
+
if (param && element) {
|
|
57
|
+
if (element[contentElementKey]?.update) {
|
|
58
|
+
element[contentElementKey].update({}, opts)
|
|
59
|
+
} else {
|
|
60
|
+
set.call(element, param, opts)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default setContent
|
package/mixins/data.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { isObject, deepMerge, exec } from '@domql/utils'
|
|
4
|
+
import { report } from '@domql/report'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Apply data parameters on the DOM nodes
|
|
8
|
+
* this should only work if `showOnNode: true` is passed
|
|
9
|
+
*/
|
|
10
|
+
export function data (params, element, node) {
|
|
11
|
+
if (params) {
|
|
12
|
+
if (element.props.data) deepMerge(params, element.props.data)
|
|
13
|
+
if (params.showOnNode) {
|
|
14
|
+
if (!isObject(params)) report('HTMLInvalidData', params)
|
|
15
|
+
|
|
16
|
+
// Apply data params on node
|
|
17
|
+
for (const dataset in params) {
|
|
18
|
+
if (dataset !== 'showOnNode') {
|
|
19
|
+
node.dataset[dataset] = exec(params[dataset], element)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default data
|
package/mixins/html.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { exec } from '@domql/utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Appends raw HTML as content
|
|
7
|
+
* an original one as a child
|
|
8
|
+
*/
|
|
9
|
+
export function html (param, element, node) {
|
|
10
|
+
const prop = exec(element?.props?.html || param, element)
|
|
11
|
+
const { __ref } = element
|
|
12
|
+
if (prop !== __ref.__html) {
|
|
13
|
+
if (node.nodeName === 'SVG') node.textContent = prop
|
|
14
|
+
else node.innerHTML = prop
|
|
15
|
+
__ref.__html = prop
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default html
|
package/mixins/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { attr } from './attr.js'
|
|
4
|
+
import { applyClasslist } from './classList.js'
|
|
5
|
+
import { data } from './data.js'
|
|
6
|
+
import { html } from './html.js'
|
|
7
|
+
import { style } from './style.js'
|
|
8
|
+
import { text } from './text.js'
|
|
9
|
+
import { state } from './state.js'
|
|
10
|
+
import { scope } from './scope.js'
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
applyClasslist as classList,
|
|
14
|
+
attr,
|
|
15
|
+
data,
|
|
16
|
+
style,
|
|
17
|
+
text,
|
|
18
|
+
html,
|
|
19
|
+
state,
|
|
20
|
+
scope
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export * from './registry.js'
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { attr } from './attr.js'
|
|
4
|
+
import { classList } from './classList.js'
|
|
5
|
+
import data from './data.js'
|
|
6
|
+
import html from './html.js'
|
|
7
|
+
import scope from './scope.js'
|
|
8
|
+
import state from './state.js'
|
|
9
|
+
import style from './style.js'
|
|
10
|
+
import text from './text.js'
|
|
11
|
+
|
|
12
|
+
export const REGISTRY = {
|
|
13
|
+
attr,
|
|
14
|
+
style,
|
|
15
|
+
text,
|
|
16
|
+
html,
|
|
17
|
+
data,
|
|
18
|
+
classlist: classList,
|
|
19
|
+
state,
|
|
20
|
+
scope,
|
|
21
|
+
deps: (param, el) => param || el.parent.deps,
|
|
22
|
+
|
|
23
|
+
extends: {},
|
|
24
|
+
children: {},
|
|
25
|
+
content: {},
|
|
26
|
+
childExtends: {},
|
|
27
|
+
childExtendsRecursive: {},
|
|
28
|
+
props: {},
|
|
29
|
+
if: {},
|
|
30
|
+
define: {},
|
|
31
|
+
__name: {},
|
|
32
|
+
__ref: {},
|
|
33
|
+
__hash: {},
|
|
34
|
+
__text: {},
|
|
35
|
+
key: {},
|
|
36
|
+
tag: {},
|
|
37
|
+
query: {},
|
|
38
|
+
parent: {},
|
|
39
|
+
node: {},
|
|
40
|
+
variables: {},
|
|
41
|
+
on: {},
|
|
42
|
+
component: {},
|
|
43
|
+
context: {}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default REGISTRY
|
package/mixins/scope.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { isFunction, isObject } from '@domql/utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Apply data parameters on the DOM nodes
|
|
7
|
+
* this should only work if `showOnNode: true` is passed
|
|
8
|
+
*/
|
|
9
|
+
export function scope (params, element, node) {
|
|
10
|
+
if (!isObject(params)) return
|
|
11
|
+
|
|
12
|
+
// Apply data params on node
|
|
13
|
+
for (const scopeItem in params) {
|
|
14
|
+
const value = params[scopeItem]
|
|
15
|
+
if (isFunction(value)) {
|
|
16
|
+
element.scope[scopeItem] = value.bind(element)
|
|
17
|
+
} else {
|
|
18
|
+
element.scope[scopeItem] = value
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default scope
|
package/mixins/state.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { exec, isObject, STATE_METHODS } from '@domql/utils'
|
|
4
|
+
|
|
5
|
+
export function state (params, element, node) {
|
|
6
|
+
const state = exec(params, element)
|
|
7
|
+
|
|
8
|
+
if (isObject(state)) {
|
|
9
|
+
for (const param in state) {
|
|
10
|
+
if (STATE_METHODS.has(param)) continue
|
|
11
|
+
if (!Object.prototype.hasOwnProperty.call(state, param)) continue
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return element
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default state
|
package/mixins/style.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { exec, isObject } from '@domql/utils'
|
|
4
|
+
import { report } from '@domql/report'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Recursively add styles to a DOM node
|
|
8
|
+
*/
|
|
9
|
+
export function style (params, element, node) {
|
|
10
|
+
if (params) {
|
|
11
|
+
if (isObject(params)) {
|
|
12
|
+
const { __ref } = element
|
|
13
|
+
if (!__ref.__style) __ref.__style = {}
|
|
14
|
+
const cache = __ref.__style
|
|
15
|
+
for (const prop in params) {
|
|
16
|
+
const val = exec(params[prop], element)
|
|
17
|
+
if (val === cache[prop]) continue
|
|
18
|
+
cache[prop] = val
|
|
19
|
+
node.style[prop] = val
|
|
20
|
+
}
|
|
21
|
+
} else report('HTMLInvalidStyles', params)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default style
|
package/mixins/text.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { create } from '../create.js'
|
|
4
|
+
import { exec, isString, SVG_TAGS } from '@domql/utils'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a text node and appends into
|
|
8
|
+
* an original one as a child
|
|
9
|
+
*/
|
|
10
|
+
export function text (param, element, node) {
|
|
11
|
+
let prop = exec(element.props.text || param, element)
|
|
12
|
+
if (isString(prop) && prop.includes('{{')) {
|
|
13
|
+
prop = element.call('replaceLiteralsWithObjectFields', prop, element.state)
|
|
14
|
+
}
|
|
15
|
+
if (element.tag === 'string') {
|
|
16
|
+
node.nodeValue = prop
|
|
17
|
+
} else if (param !== undefined && param !== null) {
|
|
18
|
+
// SVG elements don't support appending text nodes as children
|
|
19
|
+
if (SVG_TAGS.has(element.tag)) {
|
|
20
|
+
if (node) node.textContent = prop
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
if (element.__text) {
|
|
24
|
+
if (element.__text.text === prop) return
|
|
25
|
+
element.__text.text = prop
|
|
26
|
+
if (element.__text.node) element.__text.node.nodeValue = prop
|
|
27
|
+
} else create({ tag: 'string', text: prop }, element, '__text')
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default text
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domql/element",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"import": "./dist/esm/index.js",
|
|
11
11
|
"require": "./dist/cjs/index.js",
|
|
12
|
-
"browser": "./dist/
|
|
12
|
+
"browser": "./dist/esm/index.js",
|
|
13
13
|
"default": "./dist/esm/index.js"
|
|
14
14
|
},
|
|
15
15
|
"./event": {
|
|
@@ -36,7 +36,12 @@
|
|
|
36
36
|
"source": "index.js",
|
|
37
37
|
"files": [
|
|
38
38
|
"dist",
|
|
39
|
-
"*.js"
|
|
39
|
+
"*.js",
|
|
40
|
+
"event",
|
|
41
|
+
"methods",
|
|
42
|
+
"mixins",
|
|
43
|
+
"utils",
|
|
44
|
+
"render"
|
|
40
45
|
],
|
|
41
46
|
"scripts": {
|
|
42
47
|
"copy:package:cjs": "cp ../../build/package-cjs.json dist/cjs/package.json",
|
|
@@ -47,16 +52,16 @@
|
|
|
47
52
|
"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"
|
|
48
53
|
},
|
|
49
54
|
"dependencies": {
|
|
50
|
-
"@domql/report": "^3.4.
|
|
51
|
-
"@domql/state": "^3.4.
|
|
52
|
-
"@domql/utils": "^3.4.
|
|
53
|
-
"attrs-in-props": "^3.4.
|
|
55
|
+
"@domql/report": "^3.4.6",
|
|
56
|
+
"@domql/state": "^3.4.6",
|
|
57
|
+
"@domql/utils": "^3.4.6",
|
|
58
|
+
"attrs-in-props": "^3.4.6"
|
|
54
59
|
},
|
|
55
60
|
"gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
|
|
56
61
|
"devDependencies": {
|
|
57
62
|
"@babel/core": "^7.26.0"
|
|
58
63
|
},
|
|
59
|
-
"browser": "./dist/
|
|
64
|
+
"browser": "./dist/esm/index.js",
|
|
60
65
|
"unpkg": "./dist/iife/index.js",
|
|
61
66
|
"jsdelivr": "./dist/iife/index.js",
|
|
62
67
|
"sideEffects": false
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jest } from '@jest/globals'
|
|
2
|
+
import { appendNode } from '../append'
|
|
3
|
+
|
|
4
|
+
describe('appendNode', () => {
|
|
5
|
+
let parentNode
|
|
6
|
+
let childNode
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
// Setup fresh DOM elements before each test
|
|
10
|
+
parentNode = document.createElement('div')
|
|
11
|
+
childNode = document.createElement('span')
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test('should append child to parent node successfully', () => {
|
|
15
|
+
const result = appendNode(childNode, parentNode)
|
|
16
|
+
|
|
17
|
+
expect(parentNode.children).toHaveLength(1)
|
|
18
|
+
expect(parentNode.firstChild).toBe(childNode)
|
|
19
|
+
expect(result).toBe(childNode)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('should handle invalid parent node', () => {
|
|
23
|
+
const consoleSpy = jest.spyOn(console, 'error')
|
|
24
|
+
const invalidParent = null
|
|
25
|
+
|
|
26
|
+
const result = appendNode(childNode, invalidParent)
|
|
27
|
+
|
|
28
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
29
|
+
'Does not support to append',
|
|
30
|
+
invalidParent,
|
|
31
|
+
childNode
|
|
32
|
+
)
|
|
33
|
+
expect(result).toBeUndefined()
|
|
34
|
+
|
|
35
|
+
consoleSpy.mockRestore()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('should handle invalid child node', () => {
|
|
39
|
+
const consoleSpy = jest.spyOn(console, 'error')
|
|
40
|
+
const invalidChild = null
|
|
41
|
+
|
|
42
|
+
const result = appendNode(invalidChild, parentNode)
|
|
43
|
+
|
|
44
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
45
|
+
'Does not support to append',
|
|
46
|
+
parentNode,
|
|
47
|
+
invalidChild
|
|
48
|
+
)
|
|
49
|
+
expect(result).toBeUndefined()
|
|
50
|
+
|
|
51
|
+
consoleSpy.mockRestore()
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { assignNode } from '../append'
|
|
2
|
+
|
|
3
|
+
describe('assignNode', () => {
|
|
4
|
+
let element
|
|
5
|
+
let parent
|
|
6
|
+
let mockNode
|
|
7
|
+
let mockParentNode
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
// Setup mock DOM nodes
|
|
11
|
+
mockNode = document.createElement('div')
|
|
12
|
+
mockParentNode = document.createElement('div')
|
|
13
|
+
|
|
14
|
+
// Setup mock element and parent objects
|
|
15
|
+
element = {
|
|
16
|
+
key: 'testKey',
|
|
17
|
+
node: mockNode,
|
|
18
|
+
tag: 'div'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
parent = {
|
|
22
|
+
node: mockParentNode
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('should throw error when element is null', () => {
|
|
27
|
+
expect(() => {
|
|
28
|
+
assignNode(null, parent)
|
|
29
|
+
}).toThrow('Element is required')
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('should throw error when parent is null', () => {
|
|
33
|
+
expect(() => {
|
|
34
|
+
assignNode(element, null)
|
|
35
|
+
}).toThrow('Parent is required')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('should assign element to parent using element key', () => {
|
|
39
|
+
const result = assignNode(element, parent)
|
|
40
|
+
|
|
41
|
+
// Check key assignment
|
|
42
|
+
expect(parent[element.key]).toBe(element)
|
|
43
|
+
|
|
44
|
+
// Check DOM structure
|
|
45
|
+
expect(parent.node.children).toHaveLength(1)
|
|
46
|
+
expect(parent.node.firstChild).toBe(element.node)
|
|
47
|
+
expect(element.node.parentNode).toBe(parent.node)
|
|
48
|
+
|
|
49
|
+
// Check return value
|
|
50
|
+
expect(result).toBe(element)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('should assign element to parent using custom key', () => {
|
|
54
|
+
const customKey = 'customKey'
|
|
55
|
+
const result = assignNode(element, parent, customKey)
|
|
56
|
+
|
|
57
|
+
// Check custom key assignment
|
|
58
|
+
expect(parent[customKey]).toBe(element)
|
|
59
|
+
expect(parent[element.key]).toBeUndefined()
|
|
60
|
+
|
|
61
|
+
// Check DOM structure
|
|
62
|
+
expect(parent.node.children).toHaveLength(1)
|
|
63
|
+
expect(parent.node.firstChild).toBe(element.node)
|
|
64
|
+
expect(element.node.parentNode).toBe(parent.node)
|
|
65
|
+
|
|
66
|
+
// Check return value
|
|
67
|
+
expect(result).toBe(element)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('should not modify DOM when element tag is shadow', () => {
|
|
71
|
+
element.tag = 'shadow'
|
|
72
|
+
const result = assignNode(element, parent)
|
|
73
|
+
|
|
74
|
+
// Check key assignment still happens
|
|
75
|
+
expect(parent[element.key]).toBe(element)
|
|
76
|
+
|
|
77
|
+
// Check DOM remains unchanged
|
|
78
|
+
expect(parent.node.children).toHaveLength(0)
|
|
79
|
+
expect(element.node.parentNode).toBeNull()
|
|
80
|
+
|
|
81
|
+
// Check return value
|
|
82
|
+
expect(result).toBe(element)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('should insert node before reference node', () => {
|
|
86
|
+
const referenceNode = document.createElement('div')
|
|
87
|
+
parent.node.appendChild(referenceNode)
|
|
88
|
+
|
|
89
|
+
const attachOptions = {
|
|
90
|
+
position: 'before',
|
|
91
|
+
node: referenceNode
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const result = assignNode(element, parent, null, attachOptions)
|
|
95
|
+
|
|
96
|
+
// Check key assignment
|
|
97
|
+
expect(parent[element.key]).toBe(element)
|
|
98
|
+
|
|
99
|
+
// Check DOM structure
|
|
100
|
+
expect(parent.node.children).toHaveLength(2)
|
|
101
|
+
expect(parent.node.firstChild).toBe(element.node)
|
|
102
|
+
expect(element.node.nextSibling).toBe(referenceNode)
|
|
103
|
+
expect(referenceNode.previousSibling).toBe(element.node)
|
|
104
|
+
|
|
105
|
+
// Check return value
|
|
106
|
+
expect(result).toBe(element)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
test('should insert node after reference node', () => {
|
|
110
|
+
const referenceNode = document.createElement('div')
|
|
111
|
+
parent.node.appendChild(referenceNode)
|
|
112
|
+
|
|
113
|
+
const attachOptions = {
|
|
114
|
+
position: 'after',
|
|
115
|
+
node: referenceNode
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const result = assignNode(element, parent, null, attachOptions)
|
|
119
|
+
|
|
120
|
+
// Check key assignment
|
|
121
|
+
expect(parent[element.key]).toBe(element)
|
|
122
|
+
|
|
123
|
+
// Check DOM structure
|
|
124
|
+
expect(parent.node.children).toHaveLength(2)
|
|
125
|
+
expect(parent.node.lastChild).toBe(element.node)
|
|
126
|
+
expect(element.node.previousSibling).toBe(referenceNode)
|
|
127
|
+
expect(referenceNode.nextSibling).toBe(element.node)
|
|
128
|
+
|
|
129
|
+
// Check return value
|
|
130
|
+
expect(result).toBe(element)
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
test('should use parent node when attachOptions node is not provided', () => {
|
|
134
|
+
const attachOptions = {
|
|
135
|
+
position: 'before'
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const result = assignNode(element, parent, null, attachOptions)
|
|
139
|
+
|
|
140
|
+
// Check key assignment
|
|
141
|
+
expect(parent[element.key]).toBe(element)
|
|
142
|
+
|
|
143
|
+
// Check DOM structure
|
|
144
|
+
expect(parent.node.children).toHaveLength(0)
|
|
145
|
+
expect(parent.node.firstChild).toBe(null)
|
|
146
|
+
expect(element.node.parentNode).toBe(null)
|
|
147
|
+
|
|
148
|
+
// Check return value
|
|
149
|
+
expect(result).toBe(element)
|
|
150
|
+
})
|
|
151
|
+
})
|