123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import { Comment, Fragment, Text, createBlock, createCommentVNode, isVNode, openBlock } from 'vue';
- import { camelize, isArray } from '@vue/shared';
- import { hasOwn } from '../objects';
- import { debugWarn } from '../error';
- import type { VNode, VNodeArrayChildren, VNodeChild, VNodeNormalizedChildren } from 'vue';
- const SCOPE = 'utils/vue/vnode';
- export enum PatchFlags {
- TEXT = 1,
- CLASS = 2,
- STYLE = 4,
- PROPS = 8,
- FULL_PROPS = 16,
- HYDRATE_EVENTS = 32,
- STABLE_FRAGMENT = 64,
- KEYED_FRAGMENT = 128,
- UNKEYED_FRAGMENT = 256,
- NEED_PATCH = 512,
- DYNAMIC_SLOTS = 1024,
- HOISTED = -1,
- BAIL = -2,
- }
- export type VNodeChildAtom = Exclude<VNodeChild, Array<any>>;
- export type RawSlots = Exclude<VNodeNormalizedChildren, Array<any> | null | string>;
- export function isFragment(node: VNode): boolean;
- export function isFragment(node: unknown): node is VNode;
- export function isFragment(node: unknown): node is VNode {
- return isVNode(node) && node.type === Fragment;
- }
- export function isText(node: VNode): boolean;
- export function isText(node: unknown): node is VNode;
- export function isText(node: unknown): node is VNode {
- return isVNode(node) && node.type === Text;
- }
- export function isComment(node: VNode): boolean;
- export function isComment(node: unknown): node is VNode;
- export function isComment(node: unknown): node is VNode {
- return isVNode(node) && node.type === Comment;
- }
- const TEMPLATE = 'template';
- export function isTemplate(node: VNode): boolean;
- export function isTemplate(node: unknown): node is VNode;
- export function isTemplate(node: unknown): node is VNode {
- return isVNode(node) && node.type === TEMPLATE;
- }
- /**
- * determine if the element is a valid element type rather than fragments and comment e.g. <template> v-if
- * @param node {VNode} node to be tested
- */
- export function isValidElementNode(node: VNode): boolean;
- export function isValidElementNode(node: unknown): node is VNode;
- export function isValidElementNode(node: unknown): node is VNode {
- return isVNode(node) && !isFragment(node) && !isComment(node);
- }
- /**
- * get a valid child node (not fragment nor comment)
- * @param node {VNode} node to be searched
- * @param depth {number} depth to be searched
- */
- function getChildren(
- node: VNodeNormalizedChildren | VNodeChild,
- depth: number,
- ): VNodeNormalizedChildren | VNodeChild {
- if (isComment(node)) return;
- if (isFragment(node) || isTemplate(node)) {
- return depth > 0 ? getFirstValidNode(node.children, depth - 1) : undefined;
- }
- return node;
- }
- export const getFirstValidNode = (nodes: VNodeNormalizedChildren, maxDepth = 3) => {
- if (Array.isArray(nodes)) {
- return getChildren(nodes[0], maxDepth);
- } else {
- return getChildren(nodes, maxDepth);
- }
- };
- export function renderIf(condition: boolean, ...args: Parameters<typeof createBlock>) {
- return condition ? renderBlock(...args) : createCommentVNode('v-if', true);
- }
- export function renderBlock(...args: Parameters<typeof createBlock>) {
- return openBlock(), createBlock(...args);
- }
- export const getNormalizedProps = (node: VNode) => {
- if (!isVNode(node)) {
- debugWarn(SCOPE, '[getNormalizedProps] must be a VNode');
- return {};
- }
- const raw = node.props || {};
- const type = (isVNode(node.type) ? node.type.props : undefined) || {};
- const props: Record<string, any> = {};
- Object.keys(type).forEach((key) => {
- if (hasOwn(type[key], 'default')) {
- props[key] = type[key].default;
- }
- });
- Object.keys(raw).forEach((key) => {
- props[camelize(key)] = raw[key];
- });
- return props;
- };
- export const ensureOnlyChild = (children: VNodeArrayChildren | undefined) => {
- if (!isArray(children) || children.length > 1) {
- throw new Error('expect to receive a single Vue element child');
- }
- return children[0];
- };
- export type FlattenVNodes = Array<VNodeChildAtom | RawSlots>;
- export const flattedChildren = (
- children: FlattenVNodes | VNode | VNodeNormalizedChildren,
- ): FlattenVNodes => {
- const vNodes = isArray(children) ? children : [children];
- const result: FlattenVNodes = [];
- vNodes.forEach((child) => {
- if (isArray(child)) {
- result.push(...flattedChildren(child));
- } else if (isVNode(child) && isArray(child.children)) {
- result.push(...flattedChildren(child.children));
- } else {
- result.push(child);
- }
- });
- return result;
- };
|