Skip to content

Commit 27b5c71

Browse files
authored
fix(runtime-dom): should patch svg innerHtml (#956)
1 parent 33ccfc0 commit 27b5c71

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

packages/runtime-dom/__tests__/patchProps.spec.ts

+16
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ describe('runtime-dom: props patching', () => {
4545
expect(fn).toHaveBeenCalled()
4646
})
4747

48+
// #954
49+
test('(svg) innerHTML unmount prev children', () => {
50+
const fn = jest.fn()
51+
const comp = {
52+
render: () => 'foo',
53+
unmounted: fn
54+
}
55+
const root = document.createElement('div')
56+
render(h('div', null, [h(comp)]), root)
57+
expect(root.innerHTML).toBe(`<div>foo</div>`)
58+
59+
render(h('svg', { innerHTML: '<g></g>' }), root)
60+
expect(root.innerHTML).toBe(`<svg><g></g></svg>`)
61+
expect(fn).toHaveBeenCalled()
62+
})
63+
4864
test('textContent unmount prev children', () => {
4965
const fn = jest.fn()
5066
const comp = {

packages/runtime-dom/src/patchProp.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { patchStyle } from './modules/style'
33
import { patchAttr } from './modules/attrs'
44
import { patchDOMProp } from './modules/props'
55
import { patchEvent } from './modules/events'
6-
import { isOn, isString } from '@vue/shared'
6+
import { isOn, isString, isFunction } from '@vue/shared'
77
import { RendererOptions } from '@vue/runtime-core'
88

99
const nativeOnRE = /^on[a-z]/
@@ -34,10 +34,16 @@ export const patchProp: RendererOptions<Node, Element>['patchProp'] = (
3434
patchEvent(el, key, prevValue, nextValue, parentComponent)
3535
}
3636
} else if (
37-
!isSVG &&
38-
key in el &&
39-
// onclick="foo" needs to be set as an attribute to work
40-
!(nativeOnRE.test(key) && isString(nextValue))
37+
isSVG
38+
? // most keys must be set as attribute on svg elements to work
39+
// ...except innerHTML
40+
key === 'innerHTML' ||
41+
// or native onclick with function values
42+
(key in el && nativeOnRE.test(key) && isFunction(nextValue))
43+
: // for normal html elements, set as a property if it exists
44+
key in el &&
45+
// except native onclick with string values
46+
!(nativeOnRE.test(key) && isString(nextValue))
4147
) {
4248
patchDOMProp(
4349
el,

0 commit comments

Comments
 (0)