Browse Source

fix: use correct ns inside <foreignObject> as root node

fix #6642
Evan You 8 years ago
parent
commit
cf1ff5b0dc
2 changed files with 31 additions and 4 deletions
  1. 5 4
      src/core/vdom/create-element.js
  2. 26 0
      test/unit/modules/vdom/create-element.spec.js

+ 5 - 4
src/core/vdom/create-element.js

@@ -122,17 +122,18 @@ export function _createElement (
   }
 }
 
-function applyNS (vnode, ns) {
+function applyNS (vnode, ns, force) {
   vnode.ns = ns
   if (vnode.tag === 'foreignObject') {
     // use default namespace inside foreignObject
-    return
+    ns = undefined
+    force = true
   }
   if (isDef(vnode.children)) {
     for (let i = 0, l = vnode.children.length; i < l; i++) {
       const child = vnode.children[i]
-      if (isDef(child.tag) && isUndef(child.ns)) {
-        applyNS(child, ns)
+      if (isDef(child.tag) && (isUndef(child.ns) || force)) {
+        applyNS(child, ns, force)
       }
     }
   }

+ 26 - 0
test/unit/modules/vdom/create-element.spec.js

@@ -141,6 +141,32 @@ describe('create-element', () => {
     expect(vnode.children[0].children[0].ns).toBeUndefined()
   })
 
+  // #6642
+  it('render svg foreignObject component with correct namespace', () => {
+    const vm = new Vue({
+      template: `
+        <svg>
+          <test></test>
+        </svg>
+      `,
+      components: {
+        test: {
+          template: `
+          <foreignObject>
+            <p xmlns="http://www.w3.org/1999/xhtml"></p>
+          </foreignObject>
+          `
+        }
+      }
+    }).$mount()
+    const testComp = vm.$children[0]
+    expect(testComp.$vnode.ns).toBe('svg')
+    expect(testComp._vnode.tag).toBe('foreignObject')
+    expect(testComp._vnode.ns).toBe('svg')
+    expect(testComp._vnode.children[0].tag).toBe('p')
+    expect(testComp._vnode.children[0].ns).toBeUndefined()
+  })
+
   // #6506
   it('render SVGAElement in a component correctly', () => {
     const vm = new Vue({