8000 fix: incorrect nextSibling of prevSibling in appendChild/insertBefore… · joshmossas/nativescript-vue@5156f20 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5156f20

Browse files
authored
fix: incorrect nextSibling of prevSibling in appendChild/insertBefore (nativescript-vue#811)
fixes nativescript-vue#809 * chore: remove unnecessary check from appendChild * fix: remove node before appending if already a child * fix: set nextSibling of prevSibling upon insertion (fixed) * test: add test case for nativescript-vue#809
1 parent ee47fc1 commit 5156f20

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

__tests__/renderer/ViewNode.test.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,27 @@ describe('ViewNode', () => {
120120
expect(refNode.nextSibling).toBeFalsy()
121121
})
122122

123+
test('insertBefore sets siblings of both siblings', () => {
124+
let parentNode = new ViewNode()
125+
let firstNode = new ViewNode()
126+
let lastNode = new ViewNode()
127+
let childNode = new ViewNode()
128+
parentNode.childNodes = [firstNode, lastNode]
129+
firstNode.parentNode = parentNode
130+
lastNode.parentNode = parentNode
131+
132+
parentNode.insertBefore(childNode, lastNode)
133+
134+
expect(parentNode.childNodes.length).toBe(3)
135+
expect(childNode.parentNode).toEqual(parentNode)
136+
expect(firstNode.nextSibling).toEqual(childNode)
137+
expect(lastNode.prevSibling).toEqual(childNode)
138+
expect(childNode.prevSibling).toEqual(firstNode)
139+
expect(childNode.nextSibling).toEqual(lastNode)
140+
expect(firstNode.prevSibling).toBeFalsy()
141+
expect(lastNode.nextSibling).toBeFalsy()
142+
})
143+
123144
test('appendChild throws if no childNode is given', () => {
124145
let node = new ViewNode()
125146

platform/nativescript/renderer/ViewNode.js

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,11 @@ export default class ViewNode {
165165
throw new Error(`Can't insert child.`)
166166
}
167167

168-
// in some rare cases insertBefore is called with a null referenceNode
169-
// this makes sure that it get's appended as the last child
170-
if (!referenceNode) {
171-
return this.appendChild(childNode)
172-
}
173-
174-
if (referenceNode.parentNode && referenceNode.parentNode !== this) {
168+
if (
169+
referenceNode &&
170+
referenceNode.parentNode &&
171+
referenceNode.parentNode !== this
172+
) {
175173
throw new Error(
176174
`Can't insert child, because the reference node has a different parent.`
177175
)
@@ -197,11 +195,18 @@ export default class ViewNode {
197195
// throw new Error(`Can't insert child, because it is already a child.`)
198196
}
199197

198+
// in some rare cases insertBefore is called with a null referenceNode
199+
// this makes sure that it get's appended as the last child
200+
if (!referenceNode) {
201+
return this.appendChild(childNode)
202+
}
203+
200204
let index = this.childNodes.indexOf(referenceNode)
201205

202206
childNode.parentNode = this
203207
childNode.nextSibling = referenceNode
204208
childNode.prevSibling = this.childNodes[index - 1]
209+
if (childNode.prevSibling) childNode.prevSibling.nextSibling = childNode
205210

206211
referenceNode.prevSibling = childNode
207212
this.childNodes.splice(index, 0, childNode)
@@ -220,16 +225,7 @@ export default class ViewNode {
220225
)
221226
}
222227

223-
if (childNode.parentNode === this) {
224-
// we don't need to throw an error here, because it is a valid case
225-
// for example when switching the order of elements in the tree
226-
// fixes #127 - see for more details
227-
// fixes #240
228-
// throw new Error(`Can't append child, because it is already a child.`)
229-
}
230-
231228
childNode.parentNode = this
232-
233229
if (this.lastChild) {
234230
childNode.prevSibling = this.lastChild
235231
this.lastChild.nextSibling = childNode

0 commit comments

Comments
 (0)
0