| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- /* @flow */
- import VNode, { createTextVNode } from 'core/vdom/vnode'
- import { isFalse, isDef, isUndef, isPrimitive } from 'shared/util'
- // The template compiler attempts to minimize the need for normalization by
- // statically analyzing the template at compile time.
- //
- // For plain HTML markup, normalization can be completely skipped because the
- // generated render function is guaranteed to return Array<VNode>. There are
- // two cases where extra normalization is needed:
- // 1. When the children contains components - because a functional component
- // may return an Array instead of a single root. In this case, just a simple
- // normalization is needed - if any child is an Array, we flatten the whole
- // thing with Array.prototype.concat. It is guaranteed to be only 1-level deep
- // because functional components already normalize their own children.
- export function simpleNormalizeChildren (children: any) {
- for (let i = 0; i < children.length; i++) {
- if (Array.isArray(children[i])) {
- return Array.prototype.concat.apply([], children)
- }
- }
- return children
- }
- // 2. When the children contains constructs that always generated nested Arrays,
- // e.g. <template>, <slot>, v-for, or when the children is provided by user
- // with hand-written render functions / JSX. In such cases a full normalization
- // is needed to cater to all possible types of children values.
- export function normalizeChildren (children: any): ?Array<VNode> {
- return isPrimitive(children)
- ? [createTextVNode(children)]
- : Array.isArray(children)
- ? normalizeArrayChildren(children)
- : undefined
- }
- function normalizeArrayChildren (children: any, nestedIndex?: string): Array<VNode> {
- const res = []
- let i, c, last
- for (i = 0; i < children.length; i++) {
- c = children[i]
- if (isUndef(c) || typeof c === 'boolean') continue
- last = res[res.length - 1]
- // nested
- if (Array.isArray(c)) {
- res.push.apply(res, normalizeArrayChildren(c, `${nestedIndex || ''}_${i}`))
- } else if (isPrimitive(c)) {
- if (isDef(last) && isDef(last.text)) {
- last.text += String(c)
- } else if (c !== '') {
- // convert primitive to vnode
- res.push(createTextVNode(c))
- }
- } else {
- if (isFalse(c.isComment) && isDef(c.text) && isDef(last) && isFalse(last.isComment) && isDef(last.text)) {
- res[res.length - 1] = createTextVNode(last.text + c.text)
- } else {
- // default key for nested array children (likely generated by v-for)
- if (isDef(c.tag) && isUndef(c.key) && isDef(nestedIndex)) {
- c.key = `__vlist${nestedIndex}_${i}__`
- }
- res.push(c)
- }
- }
- }
- return res
- }
|