Skip to content

Commit

Permalink
fix(transition): check existence of el.parentNode (#8422)
Browse files Browse the repository at this point in the history
fix #8199

* fix(transition): check existence of `el.parentNode`

If the new parentNode gets a `textContent` or `innerHTML` property during
patching, the `transition` node would have been detached early, which means
`el.parentNode` no longer exists.

* fix(vdom): should not reuse nodes with `textContent` / `innerHTML` props
  • Loading branch information
sodatea authored and yyx990803 committed Oct 24, 2018
1 parent 8f04135 commit 0b16927
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
7 changes: 7 additions & 0 deletions src/core/vdom/patch.js
Expand Up @@ -32,13 +32,20 @@ export const emptyNode = new VNode('', {}, [])

const hooks = ['create', 'activate', 'update', 'remove', 'destroy']

function childrenIgnored (vnode) {
return vnode && vnode.data && vnode.data.domProps && (
vnode.data.domProps.innerHTML || vnode.data.domProps.textContent
)
}

function sameVnode (a, b) {
return (
a.key === b.key && (
(
a.tag === b.tag &&
a.isComment === b.isComment &&
isDef(a.data) === isDef(b.data) &&
!childrenIgnored(a) && !childrenIgnored(b) &&
sameInputType(a, b)
) || (
isTrue(a.isAsyncPlaceholder) &&
Expand Down
2 changes: 1 addition & 1 deletion src/platforms/web/runtime/modules/transition.js
Expand Up @@ -251,7 +251,7 @@ export function leave (vnode: VNodeWithData, rm: Function) {
return
}
// record leaving element
if (!vnode.data.show) {
if (!vnode.data.show && el.parentNode) {
(el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key: any)] = vnode
}
beforeLeave && beforeLeave(el)
Expand Down
22 changes: 22 additions & 0 deletions test/unit/features/transition/transition.spec.js
Expand Up @@ -1167,5 +1167,27 @@ if (!isIE9) {
expect(vm.$el.innerHTML).toBe('<!---->')
}).then(done)
})

// #8199
it('should not throw error when replaced by v-html contents', (done) => {
const vm = new Vue({
template: `
<div>
<div v-if="ok" :class="ok">
<transition>
<span>a</span>
</transition>
</div>
<div v-else v-html="ok"></div>
</div>
`,
data: { ok: true }
}).$mount(el)

vm.ok = false
waitForUpdate(() => {
expect(vm.$el.children[0].innerHTML).toBe('false')
}).then(done)
})
})
}

0 comments on commit 0b16927

Please sign in to comment.