UNPKG

vue

Version:

Reactive, component-oriented view layer for modern web interfaces.

70 lines (64 loc) 2.57 kB
/* @flow */ import { isPrimitive } from 'core/util/index' import VNode, { createTextVNode } from 'core/vdom/vnode' // 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 // nomralization 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 constrcuts 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 (c == null || 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 (last && last.text) { last.text += String(c) } else if (c !== '') { // convert primitive to vnode res.push(createTextVNode(c)) } } else { if (c.text && last && last.text) { res[res.length - 1] = createTextVNode(last.text + c.text) } else { // default key for nested array children (likely generated by v-for) if (c.tag && c.key == null && nestedIndex != null) { c.key = `__vlist${nestedIndex}_${i}__` } res.push(c) } } } return res }