diff --git a/src/core/vdom/create-element.js b/src/core/vdom/create-element.js index c9f30d2287e..039b0a9b6e6 100644 --- a/src/core/vdom/create-element.js +++ b/src/core/vdom/create-element.js @@ -126,13 +126,34 @@ function applyNS (vnode, ns) { vnode.ns = ns if (vnode.tag === 'foreignObject') { // use default namespace inside foreignObject + // #6642 + removeNS(vnode) return } + walkChildren( + vnode, + child => isDef(child.tag) && isUndef(child.ns), + child => applyNS(child, ns) + ) +} + +function removeNS (vnode: VNode): void { + walkChildren( + vnode, + child => isDef(child.tag) && isDef(child.ns), + child => { + child.ns = undefined + removeNS(child) + } + ) +} + +function walkChildren (vnode: VNode, tester: Function, cb: Function): void { 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 (tester(child)) { + cb(child) } } } diff --git a/src/platforms/web/util/element.js b/src/platforms/web/util/element.js index 65f1aafbbf2..d6a03f49aa5 100644 --- a/src/platforms/web/util/element.js +++ b/src/platforms/web/util/element.js @@ -26,7 +26,7 @@ export const isHTMLTag = makeMap( // contain child elements. export const isSVG = makeMap( 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' + - 'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + + 'foreignobject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view', true ) diff --git a/test/unit/modules/vdom/create-element.spec.js b/test/unit/modules/vdom/create-element.spec.js index c060343df19..3bec065f312 100644 --- a/test/unit/modules/vdom/create-element.spec.js +++ b/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: ` + + + + `, + components: { + test: { + template: ` + +

+
+ ` + } + } + }).$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({