| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- /* @flow */
- import config from '../config'
- import VNode, { createEmptyVNode } from './vnode'
- import { createComponent } from './create-component'
- import {
- warn,
- isDef,
- isUndef,
- isTrue,
- isPrimitive,
- resolveAsset
- } from '../util/index'
- import {
- normalizeChildren,
- simpleNormalizeChildren
- } from './helpers/index'
- const SIMPLE_NORMALIZE = 1
- const ALWAYS_NORMALIZE = 2
- // wrapper function for providing a more flexible interface
- // without getting yelled at by flow
- export function createElement (
- context: Component,
- tag: any,
- data: any,
- children: any,
- normalizationType: any,
- alwaysNormalize: boolean
- ): VNode {
- if (Array.isArray(data) || isPrimitive(data)) {
- normalizationType = children
- children = data
- data = undefined
- }
- if (isTrue(alwaysNormalize)) {
- normalizationType = ALWAYS_NORMALIZE
- }
- return _createElement(context, tag, data, children, normalizationType)
- }
- export function _createElement (
- context: Component,
- tag?: string | Class<Component> | Function | Object,
- data?: VNodeData,
- children?: any,
- normalizationType?: number
- ): VNode {
- if (isDef(data) && isDef((data: any).__ob__)) {
- process.env.NODE_ENV !== 'production' && warn(
- `Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +
- 'Always create fresh vnode data objects in each render!',
- context
- )
- return createEmptyVNode()
- }
- if (!tag) {
- // in case of component :is set to falsy value
- return createEmptyVNode()
- }
- // support single function children as default scoped slot
- if (Array.isArray(children) &&
- typeof children[0] === 'function') {
- data = data || {}
- data.scopedSlots = { default: children[0] }
- children.length = 0
- }
- if (normalizationType === ALWAYS_NORMALIZE) {
- children = normalizeChildren(children)
- } else if (normalizationType === SIMPLE_NORMALIZE) {
- children = simpleNormalizeChildren(children)
- }
- let vnode, ns
- if (typeof tag === 'string') {
- let Ctor
- ns = config.getTagNamespace(tag)
- if (config.isReservedTag(tag)) {
- // platform built-in elements
- vnode = new VNode(
- config.parsePlatformTagName(tag), data, children,
- undefined, undefined, context
- )
- } else if (isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
- // component
- vnode = createComponent(Ctor, data, context, children, tag)
- } else {
- // unknown or unlisted namespaced elements
- // check at runtime because it may get assigned a namespace when its
- // parent normalizes children
- vnode = new VNode(
- tag, data, children,
- undefined, undefined, context
- )
- }
- } else {
- // direct component options / constructor
- vnode = createComponent(tag, data, context, children)
- }
- if (isDef(vnode)) {
- if (ns) applyNS(vnode, ns)
- return vnode
- } else {
- return createEmptyVNode()
- }
- }
- function applyNS (vnode, ns) {
- vnode.ns = ns
- if (vnode.tag === 'foreignObject') {
- // use default namespace inside foreignObject
- return
- }
- 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)
- }
- }
- }
- }
|