]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-dom): should patch svg innerHtml (#956)
authorlikui <2218301630@qq.com>
Mon, 13 Apr 2020 16:13:37 +0000 (00:13 +0800)
committerGitHub <noreply@github.com>
Mon, 13 Apr 2020 16:13:37 +0000 (12:13 -0400)
packages/runtime-dom/__tests__/patchProps.spec.ts
packages/runtime-dom/src/patchProp.ts

index 96f3037cf13254ef245bbcdba78e74de15873fc5..ce30f91162f02958f4c9c51838e11a465a582332 100644 (file)
@@ -45,6 +45,22 @@ describe('runtime-dom: props patching', () => {
     expect(fn).toHaveBeenCalled()
   })
 
+  // #954
+  test('(svg) innerHTML unmount prev children', () => {
+    const fn = jest.fn()
+    const comp = {
+      render: () => 'foo',
+      unmounted: fn
+    }
+    const root = document.createElement('div')
+    render(h('div', null, [h(comp)]), root)
+    expect(root.innerHTML).toBe(`<div>foo</div>`)
+
+    render(h('svg', { innerHTML: '<g></g>' }), root)
+    expect(root.innerHTML).toBe(`<svg><g></g></svg>`)
+    expect(fn).toHaveBeenCalled()
+  })
+
   test('textContent unmount prev children', () => {
     const fn = jest.fn()
     const comp = {
index 71d6415551735d07b639958c89f6ef9fa799a26e..4543bd1a54d8aa555246cc54c3d27a5c34a35b46 100644 (file)
@@ -3,7 +3,7 @@ import { patchStyle } from './modules/style'
 import { patchAttr } from './modules/attrs'
 import { patchDOMProp } from './modules/props'
 import { patchEvent } from './modules/events'
-import { isOn, isString } from '@vue/shared'
+import { isOn, isString, isFunction } from '@vue/shared'
 import { RendererOptions } from '@vue/runtime-core'
 
 const nativeOnRE = /^on[a-z]/
@@ -34,10 +34,16 @@ export const patchProp: RendererOptions<Node, Element>['patchProp'] = (
           patchEvent(el, key, prevValue, nextValue, parentComponent)
         }
       } else if (
-        !isSVG &&
-        key in el &&
-        // onclick="foo" needs to be set as an attribute to work
-        !(nativeOnRE.test(key) && isString(nextValue))
+        isSVG
+          ? // most keys must be set as attribute on svg elements to work
+            // ...except innerHTML
+            key === 'innerHTML' ||
+            // or native onclick with function values
+            (key in el && nativeOnRE.test(key) && isFunction(nextValue))
+          : // for normal html elements, set as a property if it exists
+            key in el &&
+            // except native onclick with string values
+            !(nativeOnRE.test(key) && isString(nextValue))
       ) {
         patchDOMProp(
           el,