Match-id-a3b867276dc7741860be264419d6379d8d182100

This commit is contained in:
* 2022-01-27 17:47:31 +08:00 committed by *
parent 59c92e0978
commit 06752cdf27
6 changed files with 70 additions and 60 deletions

View File

@ -1,13 +1,13 @@
import { import {
asyncUpdates, createVNode, getFirstCustomDom, asyncUpdates, getFirstCustomDom,
syncUpdates, startUpdate, syncUpdates, startUpdate,
createTreeRootVNode,
} from '../renderer/Renderer'; } from '../renderer/Renderer';
import {createPortal} from '../renderer/components/CreatePortal'; import {createPortal} from '../renderer/components/CreatePortal';
import type {Container} from './DOMOperator'; import type {Container} from './DOMOperator';
import {isElement} from './utils/Common'; import {isElement} from './utils/Common';
import {listenDelegatedEvents} from '../event/EventBinding'; import {listenDelegatedEvents} from '../event/EventBinding';
import {findDOMByClassInst} from '../renderer/vnode/VNodeUtils'; import {findDOMByClassInst} from '../renderer/vnode/VNodeUtils';
import {TreeRoot} from '../renderer/vnode/VNodeTags';
import {Callback} from '../renderer/UpdateHandler'; import {Callback} from '../renderer/UpdateHandler';
function createRoot(children: any, container: Container, callback?: Callback) { function createRoot(children: any, container: Container, callback?: Callback) {
@ -19,7 +19,7 @@ function createRoot(children: any, container: Container, callback?: Callback) {
} }
// 调度器创建根节点并给容器dom赋vNode结构体 // 调度器创建根节点并给容器dom赋vNode结构体
const treeRoot = createVNode(TreeRoot, container); const treeRoot = createTreeRootVNode(container);
container._treeRoot = treeRoot; container._treeRoot = treeRoot;
// 根节点挂接全量事件 // 根节点挂接全量事件

View File

@ -9,9 +9,9 @@ import {
} from './TreeBuilder'; } from './TreeBuilder';
import { runAsyncEffects } from './submit/HookEffectHandler'; import { runAsyncEffects } from './submit/HookEffectHandler';
import { Callback, newUpdate, pushUpdate } from './UpdateHandler'; import { Callback, newUpdate, pushUpdate } from './UpdateHandler';
import { getFirstChild } from './vnode/VNodeUtils';
export { createVNode } from './vnode/VNodeCreator';
export { createVNode, createTreeRootVNode } from './vnode/VNodeCreator';
export { createPortal } from './components/CreatePortal'; export { createPortal } from './components/CreatePortal';
export { export {
asyncUpdates, asyncUpdates,

View File

@ -2,7 +2,7 @@ import type { VNode } from '../Types';
import { FlagUtils } from '../vnode/VNodeFlags'; import { FlagUtils } from '../vnode/VNodeFlags';
import { TYPE_COMMON_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../../external/JSXElementType'; import { TYPE_COMMON_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../../external/JSXElementType';
import { DomText, DomPortal, Fragment, DomComponent } from '../vnode/VNodeTags'; import { DomText, DomPortal, Fragment, DomComponent } from '../vnode/VNodeTags';
import {updateVNode, createVNode, createVNodeFromElement, updateVNodePath} from '../vnode/VNodeCreator'; import {updateVNode, createVNodeFromElement, updateVNodePath, createFragmentVNode, createPortalVNode, createDomTextVNode} from '../vnode/VNodeCreator';
import { import {
isSameType, isSameType,
getIteratorFn, getIteratorFn,
@ -113,7 +113,7 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) {
switch (newNodeType) { switch (newNodeType) {
case DiffCategory.TEXT_NODE: { case DiffCategory.TEXT_NODE: {
if (oldNode === null || oldNode.tag !== DomText) { if (oldNode === null || oldNode.tag !== DomText) {
resultNode = createVNode(DomText, String(newChild)); resultNode = createDomTextVNode(String(newChild));
} else { } else {
resultNode = updateVNode(oldNode, String(newChild)); resultNode = updateVNode(oldNode, String(newChild));
} }
@ -121,7 +121,7 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) {
} }
case DiffCategory.ARR_NODE: { case DiffCategory.ARR_NODE: {
if (oldNode === null || oldNode.tag !== Fragment) { if (oldNode === null || oldNode.tag !== Fragment) {
resultNode = createVNode(Fragment, null, newChild); resultNode = createFragmentVNode(null, newChild);
} else { } else {
resultNode = updateVNode(oldNode, newChild); resultNode = updateVNode(oldNode, newChild);
} }
@ -132,7 +132,7 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) {
if (newChild.type === TYPE_FRAGMENT) { if (newChild.type === TYPE_FRAGMENT) {
if (oldNode === null || oldNode.tag !== Fragment) { if (oldNode === null || oldNode.tag !== Fragment) {
const key = oldNode !== null ? oldNode.key : newChild.key; const key = oldNode !== null ? oldNode.key : newChild.key;
resultNode = createVNode(Fragment, key, newChild.props.children); resultNode = createFragmentVNode(key, newChild.props.children);
} else { } else {
resultNode = updateVNode(oldNode, newChild); resultNode = updateVNode(oldNode, newChild);
} }
@ -151,7 +151,7 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) {
break; break;
} else if (newChild.vtype === TYPE_PORTAL) { } else if (newChild.vtype === TYPE_PORTAL) {
if (oldNode === null || oldNode.tag !== DomPortal || oldNode.outerDom !== newChild.outerDom) { if (oldNode === null || oldNode.tag !== DomPortal || oldNode.outerDom !== newChild.outerDom) {
resultNode = createVNode(DomPortal, newChild); resultNode = createPortalVNode(newChild);
} else { } else {
resultNode = updateVNode(oldNode, newChild.children || []); resultNode = updateVNode(oldNode, newChild.children || []);
} }
@ -504,7 +504,7 @@ function diffStringNodeHandler(
deleteVNodes(parentNode, firstChildVNode.next); deleteVNodes(parentNode, firstChildVNode.next);
newTextNode.next = null; newTextNode.next = null;
} else { } else {
newTextNode = createVNode(DomText, String(newChild)); newTextNode = createDomTextVNode(String(newChild));
deleteVNodes(parentNode, firstChildVNode); deleteVNodes(parentNode, firstChildVNode);
} }
@ -562,7 +562,7 @@ function diffObjectNodeHandler(
if (resultNode === null) { if (resultNode === null) {
// 新建 // 新建
if (newChild.type === TYPE_FRAGMENT) { if (newChild.type === TYPE_FRAGMENT) {
resultNode = createVNode(Fragment, newChild.key, newChild.props.children); resultNode = createFragmentVNode(newChild.key, newChild.props.children);
} else { } else {
resultNode = createVNodeFromElement(newChild); resultNode = createVNodeFromElement(newChild);
resultNode.ref = newChild.ref; resultNode.ref = newChild.ref;
@ -580,7 +580,7 @@ function diffObjectNodeHandler(
} }
if (resultNode === null) { if (resultNode === null) {
// 新建 // 新建
resultNode = createVNode(DomPortal, newChild); resultNode = createPortalVNode(newChild);
} }
} }

View File

@ -1,14 +1,13 @@
import type {VNode} from '../Types'; import type {VNode} from '../Types';
import {mergeDefaultProps} from './LazyComponent'; import {mergeDefaultProps} from './LazyComponent';
import {updateVNode, createVNode, onlyUpdateChildVNodes, updateVNodePath} from '../vnode/VNodeCreator'; import {updateVNode, onlyUpdateChildVNodes, updateVNodePath, createFragmentVNode, createUndeterminedVNode} from '../vnode/VNodeCreator';
import {shallowCompare} from '../utils/compare'; import {shallowCompare} from '../utils/compare';
import { import {
TYPE_FRAGMENT, TYPE_FRAGMENT,
TYPE_PROFILER, TYPE_PROFILER,
TYPE_STRICT_MODE, TYPE_STRICT_MODE,
} from '../../external/JSXElementType'; } from '../../external/JSXElementType';
import {Fragment} from '../vnode/VNodeTags';
export function bubbleRender() {} export function bubbleRender() {}
@ -24,9 +23,9 @@ export function captureMemoComponent(
let newChild = null; let newChild = null;
const type = Component.type; const type = Component.type;
if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) { if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) {
newChild = createVNode(Fragment, null, newProps.children); newChild = createFragmentVNode(null, newProps.children);
} else { } else {
newChild = createVNode('props', type, null, newProps, processing); newChild = createUndeterminedVNode(type, null, newProps);
} }
newChild.parent = processing; newChild.parent = processing;
newChild.ref = processing.ref; newChild.ref = processing.ref;

View File

@ -1,12 +1,11 @@
import type {VNode, PromiseType} from '../Types'; import type {VNode, PromiseType} from '../Types';
import {FlagUtils, Interrupted} from '../vnode/VNodeFlags'; import {FlagUtils, Interrupted} from '../vnode/VNodeFlags';
import {createVNode, onlyUpdateChildVNodes, updateVNode, updateVNodePath} from '../vnode/VNodeCreator'; import {onlyUpdateChildVNodes, updateVNode, updateVNodePath, createFragmentVNode} from '../vnode/VNodeCreator';
import { import {
ClassComponent, ClassComponent,
IncompleteClassComponent, IncompleteClassComponent,
SuspenseComponent, SuspenseComponent,
Fragment,
} from '../vnode/VNodeTags'; } from '../vnode/VNodeTags';
import {pushForceUpdate} from '../UpdateHandler'; import {pushForceUpdate} from '../UpdateHandler';
import {launchUpdateFromVNode, tryRenderFromRoot} from '../TreeBuilder'; import {launchUpdateFromVNode, tryRenderFromRoot} from '../TreeBuilder';
@ -31,12 +30,12 @@ function createFallback(processing: VNode, fallbackChildren) {
if (oldFallbackFragment !== null) { if (oldFallbackFragment !== null) {
fallbackFragment = updateVNode(oldFallbackFragment, fallbackChildren); fallbackFragment = updateVNode(oldFallbackFragment, fallbackChildren);
} else { } else {
fallbackFragment = createVNode(Fragment, null, fallbackChildren); fallbackFragment = createFragmentVNode(null, fallbackChildren);
FlagUtils.markAddition(fallbackFragment); FlagUtils.markAddition(fallbackFragment);
} }
} else { } else {
// 创建 // 创建
fallbackFragment = createVNode(Fragment, null, fallbackChildren); fallbackFragment = createFragmentVNode(null, fallbackChildren);
} }
processing.child = childFragment; processing.child = childFragment;
@ -72,7 +71,7 @@ function createSuspenseChildren(processing: VNode, newChildren) {
// SuspenseComponent 中使用 // SuspenseComponent 中使用
processing.suspenseChildStatus = SuspenseChildStatus.ShowChild; processing.suspenseChildStatus = SuspenseChildStatus.ShowChild;
} else { } else {
childFragment = createVNode(Fragment, null, newChildren); childFragment = createFragmentVNode(null, newChildren);
} }
childFragment.parent = processing; childFragment.parent = processing;

View File

@ -87,59 +87,71 @@ export function updateVNode(vNode: VNode, vNodeProps?: any): VNode {
function getVNodeTag(type: any) { function getVNodeTag(type: any) {
let vNodeTag = ClsOrFunComponent; let vNodeTag = ClsOrFunComponent;
let isLazy = false; let isLazy = false;
const componentType = typeof type;
if (typeof type === 'function') { if (componentType === 'function') {
if (isClassComponent(type)) { if (isClassComponent(type)) {
vNodeTag = ClassComponent; vNodeTag = ClassComponent;
} }
} else if (typeof type === 'string') { } else if (componentType === 'string') {
vNodeTag = DomComponent; vNodeTag = DomComponent;
} else if (type === TYPE_SUSPENSE) { } else if (type === TYPE_SUSPENSE) {
vNodeTag = SuspenseComponent; vNodeTag = SuspenseComponent;
} else if (typeof type === 'object' && type !== null && typeMap[type.vtype]) { } else if (componentType === 'object' && type !== null && typeMap[type.vtype]) {
vNodeTag = typeMap[type.vtype]; vNodeTag = typeMap[type.vtype];
isLazy = type.vtype === TYPE_LAZY; isLazy = type.vtype === TYPE_LAZY;
} else { } else {
throw Error(`Component type is invalid, got: ${type == null ? type : typeof type}`); throw Error(`Component type is invalid, got: ${type == null ? type : componentType}`);
} }
return { vNodeTag, isLazy }; return { vNodeTag, isLazy };
} }
export function createFragmentVNode(fragmentKey, fragmentProps) {
const vNode = newVirtualNode(Fragment, fragmentKey, fragmentProps);
vNode.shouldUpdate = true;
return vNode;
}
export function createDomTextVNode(content) {
const vNode = newVirtualNode(DomText, null, content);
vNode.shouldUpdate = true;
return vNode;
}
export function createPortalVNode(portal) {
const children = portal.children ?? [];
const vNode = newVirtualNode(DomPortal, portal.key, children);
vNode.shouldUpdate = true;
vNode.outerDom = portal.outerDom;
return vNode;
}
export function createUndeterminedVNode(type, key, props) {
const { vNodeTag, isLazy } = getVNodeTag(type);
const vNode = newVirtualNode(vNodeTag, key, props);
vNode.type = type;
vNode.shouldUpdate = true;
// lazy类型的特殊处理
vNode.isLazyComponent = isLazy;
if (isLazy) {
vNode.lazyType = type;
}
return vNode;
}
export function createTreeRootVNode(container) {
const vNode = newVirtualNode(TreeRoot, null, null, container);
vNode.path.push(0);
createUpdateArray(vNode);
return vNode;
}
// TODO: 暂时保留给测试用例使用,后续修改测试用例
export function createVNode(tag: VNodeTag | string, ...secondArg) { export function createVNode(tag: VNodeTag | string, ...secondArg) {
let vNode = null; let vNode = null;
switch (tag) { switch (tag) {
case Fragment:
const [fragmentKey, fragmentProps] = secondArg;
vNode = newVirtualNode(Fragment, fragmentKey, fragmentProps);
vNode.shouldUpdate = true;
break;
case DomText:
const content = secondArg[0];
vNode = newVirtualNode(DomText, null, content);
vNode.shouldUpdate = true;
break;
case DomPortal:
const portal = secondArg[0];
const children = portal.children ?? [];
vNode = newVirtualNode(DomPortal, portal.key, children);
vNode.shouldUpdate = true;
vNode.outerDom = portal.outerDom;
break;
case 'props':
const [type, key, props] = secondArg;
const { vNodeTag, isLazy } = getVNodeTag(type);
vNode = newVirtualNode(vNodeTag, key, props);
vNode.type = type;
vNode.shouldUpdate = true;
// lazy类型的特殊处理
vNode.isLazyComponent = isLazy;
if (isLazy) {
vNode.lazyType = type;
}
break;
case TreeRoot: case TreeRoot:
// 创建treeRoot // 创建treeRoot
vNode = newVirtualNode(TreeRoot, null, null, secondArg[0]); vNode = newVirtualNode(TreeRoot, null, null, secondArg[0]);
@ -162,9 +174,9 @@ export function createVNodeFromElement(element: JSXElement): VNode {
const props = element.props; const props = element.props;
if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) { if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) {
return createVNode(Fragment, key, props.children); return createFragmentVNode(key, props.children);
} else { } else {
return createVNode('props', type, key, props); return createUndeterminedVNode(type, key, props);
} }
} }