Browse Source

element namespace should be resolved at runtime for render function / jsx usage

Evan You 9 năm trước cách đây
mục cha
commit
06b470369a

+ 1 - 3
src/compiler/codegen.js

@@ -65,11 +65,9 @@ function genElement (el: ASTElement): string {
         ? genChildren(el, !el.ns && !isPlatformReservedTag(el.tag) /* asThunk */)
         : null
       code = `_h('${el.tag}'${
-        data ? `,${data}` : (children || el.ns) ? ',void 0' : '' // data
+        data ? `,${data}` : children ? ',void 0' : '' // data
       }${
         children ? `,${children}` : '' // children
-      }${
-        el.ns ? `,'${el.ns}'` : '' // namespace
       })`
     }
     // module transforms

+ 7 - 1
src/core/config.js

@@ -1,6 +1,6 @@
 /* @flow */
 
-import { no } from 'shared/util'
+import { no, noop } from 'shared/util'
 
 export type Config = {
   // user
@@ -13,6 +13,7 @@ export type Config = {
   // platform
   isReservedTag: (x?: string) => boolean,
   isUnknownElement: (x?: string) => boolean,
+  getTagNamespace: (x?: string) => string | void,
   mustUseProp: (x?: string) => boolean,
   // internal
   _assetTypes: Array<string>,
@@ -64,6 +65,11 @@ const config: Config = {
    */
   isUnknownElement: no,
 
+  /**
+   * Get the namespace of an element
+   */
+  getTagNamespace: noop,
+
   /**
    * Check if an attribute must be bound using property, e.g. value
    * Platform-dependent.

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

@@ -10,8 +10,7 @@ import { warn, resolveAsset } from '../util/index'
 export function createElement (
   tag?: string | Class<Component> | Function | Object,
   data?: VNodeData,
-  children?: VNodeChildren | void,
-  namespace?: string
+  children?: VNodeChildren | void
 ): VNode | Array<VNode> | void {
   // make sure to expose real self instead of proxy
   const context: Component = this._self
@@ -29,10 +28,11 @@ export function createElement (
     return emptyVNode()
   }
   if (typeof tag === 'string') {
+    const namespace = config.getTagNamespace(tag)
     let Ctor
     if (config.isReservedTag(tag)) {
       return new VNode(
-        tag, data, normalizeChildren(children),
+        tag, data, normalizeChildren(children, namespace),
         undefined, undefined,
         namespace, context, host
       )
@@ -53,7 +53,7 @@ export function createElement (
         }
       }
       return new VNode(
-        tag, data, normalizeChildren(children),
+        tag, data, normalizeChildren(children, namespace),
         undefined, undefined,
         namespace, context, host
       )

+ 6 - 1
src/core/vdom/helpers.js

@@ -3,7 +3,10 @@
 import { isPrimitive } from '../util/index'
 import VNode from './vnode'
 
-export function normalizeChildren (children: any): Array<VNode> | void {
+export function normalizeChildren (
+  children: any,
+  ns: string | void
+): Array<VNode> | void {
   // invoke children thunks.
   // components always receive their children as thunks so that they
   // can perform the actual render inside their own dependency collection cycle.
@@ -32,6 +35,8 @@ export function normalizeChildren (children: any): Array<VNode> | void {
         if (c.text && last && last.text) {
           last.text += c.text
         } else {
+          // inherit parent namespace
+          if (ns && c.tag) c.ns = ns
           res.push(c)
         }
       }

+ 1 - 1
src/core/vdom/vnode.js

@@ -21,7 +21,7 @@ export default class VNode {
     children?: Array<VNode> | void,
     text?: string,
     elm?: Node,
-    ns?: string,
+    ns?: string | void,
     context?: Component,
     host?: ?Component,
     componentOptions?: VNodeComponentOptions

+ 8 - 1
src/entries/web-runtime.js

@@ -7,11 +7,18 @@ import { devtools, inBrowser } from 'core/util/index'
 import { patch } from 'web/runtime/patch'
 import platformDirectives from 'web/runtime/directives/index'
 import platformComponents from 'web/runtime/components/index'
-import { query, isUnknownElement, isReservedTag, mustUseProp } from 'web/util/index'
+import {
+  query,
+  isUnknownElement,
+  isReservedTag,
+  getTagNamespace,
+  mustUseProp
+} from 'web/util/index'
 
 // install platform specific utils
 Vue.config.isUnknownElement = isUnknownElement
 Vue.config.isReservedTag = isReservedTag
+Vue.config.getTagNamespace = getTagNamespace
 Vue.config.mustUseProp = mustUseProp
 
 // install platform runtime directives & components

+ 0 - 17
test/unit/modules/compiler/codegen.spec.js

@@ -96,23 +96,6 @@ describe('codegen', () => {
     )
   })
 
-  it('generate svg tag', () => {
-    assertCodegen(
-      '<svg><text>hello world</text></svg>',
-      `with(this){return _h('svg',void 0,[_h('text',void 0,["hello world"],'svg')],'svg')}`
-    )
-  })
-
-  it('generate MathML tag', () => {
-    assertCodegen(
-      `<math>
-        <matrix>
-        </matrix>
-      </math>`,
-      `with(this){return _h('math',void 0,[_h('matrix',void 0,'math')],'math')}`
-    )
-  })
-
   it('generate single slot', () => {
     assertCodegen(
       '<slot></slot>',