diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js
index 859f4454..2c7aa7b3 100644
--- a/src/compiler/parser/index.js
+++ b/src/compiler/parser/index.js
@@ -3,7 +3,7 @@
import { decodeHTML } from 'entities'
import { parseHTML } from './html-parser'
import { parseText } from './text-parser'
-import { hyphenate, cached, no } from 'shared/util'
+import { cached, no } from 'shared/util'
import {
pluckModuleFunction,
getAndRemoveAttr,
@@ -59,9 +59,6 @@ export function parse (
expectHTML: options.expectHTML,
isUnaryTag: options.isUnaryTag,
start (tag, attrs, unary) {
- // normalize tag name
- tag = hyphenate(tag)
-
// check namespace.
// inherit parent ns if there is one
const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag)
diff --git a/src/core/vdom/create-element.js b/src/core/vdom/create-element.js
index 778c5135..8ce307dc 100644
--- a/src/core/vdom/create-element.js
+++ b/src/core/vdom/create-element.js
@@ -41,38 +41,16 @@ function _createElement (
// in case of component :is set to falsy value
return emptyVNode()
}
- if (typeof tag === 'string') {
- const namespace = config.getTagNamespace(tag)
- let Ctor
- if (config.isReservedTag(tag)) {
- return new VNode(
- tag, data, normalizeChildren(children, namespace),
- undefined, undefined,
- namespace, context, host
- )
- } else if ((Ctor = resolveAsset(context.$options, 'components', tag))) {
- return createComponent(Ctor, data, parent, context, host, children, tag)
- } else {
- if (process.env.NODE_ENV !== 'production') {
- if (
- !namespace &&
- !(config.ignoredElements && config.ignoredElements.indexOf(tag) > -1) &&
- config.isUnknownElement(tag)
- ) {
- warn(
- 'Unknown custom element: <' + tag + '> - did you ' +
- 'register the component correctly? For recursive components, ' +
- 'make sure to provide the "name" option.'
- )
- }
- }
- return new VNode(
- tag, data, normalizeChildren(children, namespace),
- undefined, undefined,
- namespace, context, host
- )
- }
- } else {
- return createComponent(tag, data, parent, context, host, children)
+ const Ctor = typeof tag === 'string'
+ ? resolveAsset(context.$options, 'components', tag)
+ : tag
+ if (Ctor) {
+ return createComponent(Ctor, data, parent, context, host, children)
+ } else if (typeof tag === 'string') {
+ const ns = config.getTagNamespace(tag)
+ return new VNode(
+ tag, data, normalizeChildren(children, ns),
+ undefined, undefined, ns, context, host
+ )
}
}
diff --git a/src/core/vdom/helpers.js b/src/core/vdom/helpers.js
index c0c22b89..795e577a 100644
--- a/src/core/vdom/helpers.js
+++ b/src/core/vdom/helpers.js
@@ -36,7 +36,9 @@ export function normalizeChildren (
last.text += c.text
} else {
// inherit parent namespace
- if (ns && c.tag) c.ns = ns
+ if (ns) {
+ applyNS(c, ns)
+ }
res.push(c)
}
}
@@ -49,6 +51,17 @@ function createTextVNode (val) {
return new VNode(undefined, undefined, undefined, String(val))
}
+function applyNS (vnode, ns) {
+ if (vnode.tag && !vnode.ns) {
+ vnode.ns = ns
+ if (vnode.children) {
+ for (let i = 0, l = vnode.children.length; i < l; i++) {
+ applyNS(vnode.children[i], ns)
+ }
+ }
+ }
+}
+
export function updateListeners (
on: Object,
oldOn: Object,
diff --git a/src/core/vdom/patch.js b/src/core/vdom/patch.js
index 775ea4df..3a8d5400 100644
--- a/src/core/vdom/patch.js
+++ b/src/core/vdom/patch.js
@@ -7,6 +7,7 @@
* of making flow understand it is not worth it.
*/
+import config from '../config'
import VNode from './vnode'
import { isPrimitive, _toString, warn } from '../util/index'
@@ -90,6 +91,20 @@ export function createPatchFunction (backend) {
const children = vnode.children
const tag = vnode.tag
if (isDef(tag)) {
+ if (process.env.NODE_ENV !== 'production') {
+ if (
+ !vnode.ns &&
+ !(config.ignoredElements && config.ignoredElements.indexOf(tag) > -1) &&
+ config.isUnknownElement(tag)
+ ) {
+ warn(
+ 'Unknown custom element: <' + tag + '> - did you ' +
+ 'register the component correctly? For recursive components, ' +
+ 'make sure to provide the "name" option.',
+ vnode.context
+ )
+ }
+ }
elm = vnode.elm = vnode.ns
? nodeOps.createElementNS(vnode.ns, tag)
: nodeOps.createElement(tag)
diff --git a/test/unit/features/options/el.spec.js b/test/unit/features/options/el.spec.js
index 6da792b5..9f7b5f6c 100644
--- a/test/unit/features/options/el.spec.js
+++ b/test/unit/features/options/el.spec.js
@@ -42,7 +42,11 @@ describe('Options el', () => {
it('svg element', () => {
const parent = document.createElement('div')
- parent.innerHTML = ''
+ parent.innerHTML =
+ ''
const vm = new Vue({
el: parent.childNodes[0],
data: {
@@ -57,6 +61,9 @@ describe('Options el', () => {
expect(vm.$el.childNodes[0].getAttribute('y')).toBe(vm.y.toString())
expect(vm.$el.childNodes[0].getAttribute('fill')).toBe(vm.color)
expect(vm.$el.childNodes[0].textContent).toBe(vm.text)
+ // nested, non-explicitly listed SVG elements
+ expect(vm.$el.childNodes[1].childNodes[0].namespaceURI).toContain('svg')
+ expect(vm.$el.childNodes[1].childNodes[0].childNodes[0].namespaceURI).toContain('svg')
})
it('warn cannot find element', () => {
diff --git a/test/unit/modules/compiler/parser.spec.js b/test/unit/modules/compiler/parser.spec.js
index 8f260eca..9281f31e 100644
--- a/test/unit/modules/compiler/parser.spec.js
+++ b/test/unit/modules/compiler/parser.spec.js
@@ -46,7 +46,7 @@ describe('parser', () => {
it('camelCase element', () => {
const ast = parse('hello world
', baseOptions)
- expect(ast.tag).toBe('my-component')
+ expect(ast.tag).toBe('MyComponent')
expect(ast.plain).toBe(true)
expect(ast.children[0].tag).toBe('p')
expect(ast.children[0].plain).toBe(true)
diff --git a/test/unit/modules/vdom/create-element.spec.js b/test/unit/modules/vdom/create-element.spec.js
index 96695f3b..c39350b2 100644
--- a/test/unit/modules/vdom/create-element.spec.js
+++ b/test/unit/modules/vdom/create-element.spec.js
@@ -62,7 +62,6 @@ describe('create-element', () => {
expect(vnode.ns).toBeUndefined()
expect(vnode.context).toEqual(vm)
expect(vnode.componentOptions).toBeUndefined()
- expect(`Unknown custom element: <${tag}> - did you`).toHaveBeenWarned()
})
it('render empty vnode with falsy tag using createElement', () => {
diff --git a/test/unit/modules/vdom/patch/element.spec.js b/test/unit/modules/vdom/patch/element.spec.js
index 14b429f2..5872bdf8 100644
--- a/test/unit/modules/vdom/patch/element.spec.js
+++ b/test/unit/modules/vdom/patch/element.spec.js
@@ -16,6 +16,12 @@ describe('element', () => {
expect(elm.namespaceURI).toBe('http://www.w3.org/2000/svg')
})
+ it('should warn unknown element', () => {
+ const vnode = new VNode('unknown')
+ patch(null, vnode)
+ expect(`Unknown custom element: `).toHaveBeenWarned()
+ })
+
it('should create an elements which having text content', () => {
const vnode = new VNode('div', {}, [createTextVNode('hello world')])
const elm = patch(null, vnode)