Match-id-ddc72092565c7daebcfd35b019c5f5422e0293d6
This commit is contained in:
commit
391977a312
|
@ -2,7 +2,7 @@ import type { VNode } from './Types';
|
||||||
|
|
||||||
import { callRenderQueueImmediate, pushRenderCallback } from './taskExecutor/RenderQueue';
|
import { callRenderQueueImmediate, pushRenderCallback } from './taskExecutor/RenderQueue';
|
||||||
import { updateVNode } from './vnode/VNodeCreator';
|
import { updateVNode } from './vnode/VNodeCreator';
|
||||||
import { TreeRoot } from './vnode/VNodeTags';
|
import { TreeRoot, DomComponent, DomPortal } from './vnode/VNodeTags';
|
||||||
import { FlagUtils, InitFlag, Interrupted } from './vnode/VNodeFlags';
|
import { FlagUtils, InitFlag, Interrupted } from './vnode/VNodeFlags';
|
||||||
import { captureVNode } from './render/BaseComponent';
|
import { captureVNode } from './render/BaseComponent';
|
||||||
import { checkLoopingUpdateLimit, submitToRender } from './submit/Submit';
|
import { checkLoopingUpdateLimit, submitToRender } from './submit/Submit';
|
||||||
|
@ -18,7 +18,6 @@ import {
|
||||||
setProcessingClassVNode,
|
setProcessingClassVNode,
|
||||||
setStartVNode
|
setStartVNode
|
||||||
} from './GlobalVar';
|
} from './GlobalVar';
|
||||||
import { findDomParent } from './vnode/VNodeUtils';
|
|
||||||
import {
|
import {
|
||||||
ByAsync,
|
ByAsync,
|
||||||
BySync,
|
BySync,
|
||||||
|
@ -223,13 +222,21 @@ function buildVNodeTree(treeRoot: VNode) {
|
||||||
|
|
||||||
if (startVNode.tag !== TreeRoot) { // 不是根节点
|
if (startVNode.tag !== TreeRoot) { // 不是根节点
|
||||||
// 设置namespace,用于createElement
|
// 设置namespace,用于createElement
|
||||||
const parentObj = findDomParent(startVNode);
|
let parent = startVNode.parent;
|
||||||
|
while (parent !== null) {
|
||||||
|
const tag = parent.tag;
|
||||||
|
if (tag === DomComponent) {
|
||||||
|
break;
|
||||||
|
} else if (tag === TreeRoot || tag === DomPortal) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
|
|
||||||
// 当在componentWillUnmount中调用setState,parent可能是null,因为startVNode会被clear
|
// 当在componentWillUnmount中调用setState,parent可能是null,因为startVNode会被clear
|
||||||
if (parentObj !== null) {
|
if (parent !== null) {
|
||||||
const domParent = parentObj.parent;
|
resetNamespaceCtx(parent);
|
||||||
resetNamespaceCtx(domParent);
|
setNamespaceCtx(parent, parent.outerDom);
|
||||||
setNamespaceCtx(domParent, domParent.outerDom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 恢复父节点的context
|
// 恢复父节点的context
|
||||||
|
|
|
@ -39,7 +39,7 @@ import {
|
||||||
travelVNodeTree,
|
travelVNodeTree,
|
||||||
clearVNode,
|
clearVNode,
|
||||||
isDomVNode,
|
isDomVNode,
|
||||||
findDomParent, getSiblingDom,
|
getSiblingDom,
|
||||||
} from '../vnode/VNodeUtils';
|
} from '../vnode/VNodeUtils';
|
||||||
import { shouldAutoFocus } from '../../dom/utils/Common';
|
import { shouldAutoFocus } from '../../dom/utils/Common';
|
||||||
|
|
||||||
|
@ -220,9 +220,22 @@ function unmountNestedVNodes(vNode: VNode): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitAddition(vNode: VNode): void {
|
function submitAddition(vNode: VNode): void {
|
||||||
const { parent, parentDom } = findDomParent(vNode);
|
let parent = vNode.parent;
|
||||||
|
let parentDom;
|
||||||
|
let tag;
|
||||||
|
while (parent !== null) {
|
||||||
|
tag = parent.tag;
|
||||||
|
if (tag === DomComponent) {
|
||||||
|
parentDom = parent.realNode;
|
||||||
|
break;
|
||||||
|
} else if (tag === TreeRoot || tag === DomPortal) {
|
||||||
|
parentDom = parent.outerDom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
|
|
||||||
if ((vNode.flags & ResetText) === ResetText) {
|
if ((parent.flags & ResetText) === ResetText) {
|
||||||
// 在insert之前先reset
|
// 在insert之前先reset
|
||||||
clearText(parentDom);
|
clearText(parentDom);
|
||||||
FlagUtils.removeFlag(parent, ResetText);
|
FlagUtils.removeFlag(parent, ResetText);
|
||||||
|
@ -270,8 +283,19 @@ function unmountDomComponents(vNode: VNode): void {
|
||||||
|
|
||||||
travelVNodeTree(vNode, (node) => {
|
travelVNodeTree(vNode, (node) => {
|
||||||
if (!currentParentIsValid) {
|
if (!currentParentIsValid) {
|
||||||
const parentObj = findDomParent(node);
|
let parent = node.parent;
|
||||||
currentParent = parentObj.parentDom;
|
let tag;
|
||||||
|
while (parent !== null) {
|
||||||
|
tag = parent.tag;
|
||||||
|
if (tag === DomComponent) {
|
||||||
|
currentParent = parent.realNode;
|
||||||
|
break;
|
||||||
|
} else if (tag === TreeRoot || tag === DomPortal) {
|
||||||
|
currentParent = parent.outerDom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
currentParentIsValid = true;
|
currentParentIsValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,8 +339,20 @@ function submitClear(vNode: VNode): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parentObj = findDomParent(vNode);
|
let parent = vNode.parent;
|
||||||
const currentParent = parentObj.parentDom;
|
let parentDom;
|
||||||
|
let tag;
|
||||||
|
while (parent !== null) {
|
||||||
|
tag = parent.tag;
|
||||||
|
if (tag === DomComponent) {
|
||||||
|
parentDom = parent.realNode;
|
||||||
|
break;
|
||||||
|
} else if (tag === TreeRoot || tag === DomPortal) {
|
||||||
|
parentDom = parent.outerDom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
let clearChild = vNode.clearChild as VNode; // 上次渲染的child保存在clearChild属性中
|
let clearChild = vNode.clearChild as VNode; // 上次渲染的child保存在clearChild属性中
|
||||||
// 卸载 clearChild 和 它的兄弟节点
|
// 卸载 clearChild 和 它的兄弟节点
|
||||||
while(clearChild) {
|
while(clearChild) {
|
||||||
|
@ -327,9 +363,9 @@ function submitClear(vNode: VNode): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在所有子项都卸载后,删除dom树中的节点
|
// 在所有子项都卸载后,删除dom树中的节点
|
||||||
removeChildDom(currentParent, vNode.realNode);
|
removeChildDom(parentDom, vNode.realNode);
|
||||||
const realNodeNext = getSiblingDom(vNode);
|
const realNodeNext = getSiblingDom(vNode);
|
||||||
insertDom(currentParent, cloneDom, realNodeNext);
|
insertDom(parentDom, cloneDom, realNodeNext);
|
||||||
vNode.realNode = cloneDom;
|
vNode.realNode = cloneDom;
|
||||||
attachRef(vNode);
|
attachRef(vNode);
|
||||||
FlagUtils.removeFlag(vNode, Clear);
|
FlagUtils.removeFlag(vNode, Clear);
|
||||||
|
|
|
@ -136,6 +136,8 @@ export class VNode {
|
||||||
case LazyComponent:
|
case LazyComponent:
|
||||||
this.realNode = null;
|
this.realNode = null;
|
||||||
this.stateCallbacks = null;
|
this.stateCallbacks = null;
|
||||||
|
this.isLazyComponent = true;
|
||||||
|
this.lazyType = null;
|
||||||
break;
|
break;
|
||||||
case Fragment:
|
case Fragment:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -84,28 +84,6 @@ export function updateVNode(vNode: VNode, vNodeProps?: any): VNode {
|
||||||
return vNode;
|
return vNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVNodeTag(type: any) {
|
|
||||||
let vNodeTag = ClsOrFunComponent;
|
|
||||||
let isLazy = false;
|
|
||||||
const componentType = typeof type;
|
|
||||||
|
|
||||||
if (componentType === 'function') {
|
|
||||||
if (isClassComponent(type)) {
|
|
||||||
vNodeTag = ClassComponent;
|
|
||||||
}
|
|
||||||
} else if (componentType === 'string') {
|
|
||||||
vNodeTag = DomComponent;
|
|
||||||
} else if (type === TYPE_SUSPENSE) {
|
|
||||||
vNodeTag = SuspenseComponent;
|
|
||||||
} else if (componentType === 'object' && type !== null && typeMap[type.vtype]) {
|
|
||||||
vNodeTag = typeMap[type.vtype];
|
|
||||||
isLazy = type.vtype === TYPE_LAZY;
|
|
||||||
} else {
|
|
||||||
throw Error(`Component type is invalid, got: ${type == null ? type : componentType}`);
|
|
||||||
}
|
|
||||||
return { vNodeTag, isLazy };
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createFragmentVNode(fragmentKey, fragmentProps) {
|
export function createFragmentVNode(fragmentKey, fragmentProps) {
|
||||||
const vNode = newVirtualNode(Fragment, fragmentKey, fragmentProps);
|
const vNode = newVirtualNode(Fragment, fragmentKey, fragmentProps);
|
||||||
vNode.shouldUpdate = true;
|
vNode.shouldUpdate = true;
|
||||||
|
@ -127,14 +105,30 @@ export function createPortalVNode(portal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createUndeterminedVNode(type, key, props) {
|
export function createUndeterminedVNode(type, key, props) {
|
||||||
const { vNodeTag, isLazy } = getVNodeTag(type);
|
let vNodeTag = ClsOrFunComponent;
|
||||||
|
let isLazy = false;
|
||||||
|
const componentType = typeof type;
|
||||||
|
|
||||||
|
if (componentType === 'function') {
|
||||||
|
if (isClassComponent(type)) {
|
||||||
|
vNodeTag = ClassComponent;
|
||||||
|
}
|
||||||
|
} else if (componentType === 'string') {
|
||||||
|
vNodeTag = DomComponent;
|
||||||
|
} else if (type === TYPE_SUSPENSE) {
|
||||||
|
vNodeTag = SuspenseComponent;
|
||||||
|
} else if (componentType === 'object' && type !== null && typeMap[type.vtype]) {
|
||||||
|
vNodeTag = typeMap[type.vtype];
|
||||||
|
isLazy = type.vtype === TYPE_LAZY;
|
||||||
|
} else {
|
||||||
|
throw Error(`Component type is invalid, got: ${type == null ? type : componentType}`);
|
||||||
|
}
|
||||||
|
|
||||||
const vNode = newVirtualNode(vNodeTag, key, props);
|
const vNode = newVirtualNode(vNodeTag, key, props);
|
||||||
vNode.type = type;
|
vNode.type = type;
|
||||||
vNode.shouldUpdate = true;
|
vNode.shouldUpdate = true;
|
||||||
|
|
||||||
if (isLazy) {
|
if (isLazy) {
|
||||||
vNode.isLazyComponent = isLazy;
|
|
||||||
vNode.lazyType = type;
|
vNode.lazyType = type;
|
||||||
}
|
}
|
||||||
return vNode;
|
return vNode;
|
||||||
|
|
|
@ -93,7 +93,6 @@ export function clearVNode(vNode: VNode) {
|
||||||
vNode.oldState = null;
|
vNode.oldState = null;
|
||||||
vNode.oldRef = null;
|
vNode.oldRef = null;
|
||||||
vNode.oldChild = null;
|
vNode.oldChild = null;
|
||||||
vNode.flags = InitFlag;
|
|
||||||
|
|
||||||
vNode.toUpdateNodes = null;
|
vNode.toUpdateNodes = null;
|
||||||
|
|
||||||
|
@ -114,24 +113,6 @@ function isDomContainer(vNode: VNode): boolean {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 找到DOM类型的父
|
|
||||||
export function findDomParent(vNode: VNode) {
|
|
||||||
let parent = vNode.parent;
|
|
||||||
|
|
||||||
while (parent !== null) {
|
|
||||||
switch (parent.tag) {
|
|
||||||
case DomComponent:
|
|
||||||
return {parent, parentDom: parent.realNode};
|
|
||||||
case TreeRoot:
|
|
||||||
case DomPortal:
|
|
||||||
return {parent, parentDom: parent.outerDom};
|
|
||||||
}
|
|
||||||
parent = parent.parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function findDomVNode(vNode: VNode): VNode | null {
|
export function findDomVNode(vNode: VNode): VNode | null {
|
||||||
return travelVNodeTree(vNode, (node) => {
|
return travelVNodeTree(vNode, (node) => {
|
||||||
if (node.tag === DomComponent || node.tag === DomText) {
|
if (node.tag === DomComponent || node.tag === DomText) {
|
||||||
|
|
Loading…
Reference in New Issue