From 3a242e79213bad735dd18b5d39e9c706bc115587 Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 20:20:38 +0800 Subject: [PATCH 1/4] Match-id-f9204abb03ec4372ff212799440e0c744b176e36 --- libs/horizon/src/renderer/TreeBuilder.ts | 23 +++++--- .../src/renderer/submit/LifeCycleHandler.ts | 52 ++++++++++++++++--- libs/horizon/src/renderer/vnode/VNodeUtils.ts | 18 ------- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index 0f13627d..76de8ae4 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -2,7 +2,7 @@ import type { VNode } from './Types'; import { callRenderQueueImmediate, pushRenderCallback } from './taskExecutor/RenderQueue'; 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 { captureVNode } from './render/BaseComponent'; import { checkLoopingUpdateLimit, submitToRender } from './submit/Submit'; @@ -18,7 +18,6 @@ import { setProcessingClassVNode, setStartVNode } from './GlobalVar'; -import { findDomParent } from './vnode/VNodeUtils'; import { ByAsync, BySync, @@ -223,13 +222,21 @@ function buildVNodeTree(treeRoot: VNode) { if (startVNode.tag !== TreeRoot) { // 不是根节点 // 设置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 - if (parentObj !== null) { - const domParent = parentObj.parent; - resetNamespaceCtx(domParent); - setNamespaceCtx(domParent, domParent.outerDom); + if (parent !== null) { + resetNamespaceCtx(parent); + setNamespaceCtx(parent, parent.outerDom); } // 恢复父节点的context diff --git a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts index 55edf2c7..a9d8344d 100644 --- a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts +++ b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts @@ -39,7 +39,7 @@ import { travelVNodeTree, clearVNode, isDomVNode, - findDomParent, getSiblingDom, + getSiblingDom, } from '../vnode/VNodeUtils'; import { shouldAutoFocus } from '../../dom/utils/Common'; @@ -220,7 +220,20 @@ function unmountNestedVNodes(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) { // 在insert之前先reset @@ -270,8 +283,19 @@ function unmountDomComponents(vNode: VNode): void { travelVNodeTree(vNode, (node) => { if (!currentParentIsValid) { - const parentObj = findDomParent(node); - currentParent = parentObj.parentDom; + let parent = node.parent; + 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; } @@ -315,8 +339,20 @@ function submitClear(vNode: VNode): void { } } - const parentObj = findDomParent(vNode); - const currentParent = parentObj.parentDom; + 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; + } let clearChild = vNode.clearChild as VNode; // 上次渲染的child保存在clearChild属性中 // 卸载 clearChild 和 它的兄弟节点 while(clearChild) { @@ -327,9 +363,9 @@ function submitClear(vNode: VNode): void { } // 在所有子项都卸载后,删除dom树中的节点 - removeChildDom(currentParent, vNode.realNode); + removeChildDom(parentDom, vNode.realNode); const realNodeNext = getSiblingDom(vNode); - insertDom(currentParent, cloneDom, realNodeNext); + insertDom(parentDom, cloneDom, realNodeNext); vNode.realNode = cloneDom; attachRef(vNode); FlagUtils.removeFlag(vNode, Clear); diff --git a/libs/horizon/src/renderer/vnode/VNodeUtils.ts b/libs/horizon/src/renderer/vnode/VNodeUtils.ts index c9d4b572..cc56591c 100644 --- a/libs/horizon/src/renderer/vnode/VNodeUtils.ts +++ b/libs/horizon/src/renderer/vnode/VNodeUtils.ts @@ -114,24 +114,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 { return travelVNodeTree(vNode, (node) => { if (node.tag === DomComponent || node.tag === DomText) { From 24d53da4d615be9609732d30e073f4587cea4d53 Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 20:23:48 +0800 Subject: [PATCH 2/4] Match-id-706e1c5d83ec5e03eb89bbbe0d2be5fd18b586e1 --- libs/horizon/src/renderer/vnode/VNode.ts | 1 + libs/horizon/src/renderer/vnode/VNodeCreator.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 5799e34c..371e488d 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -136,6 +136,7 @@ export class VNode { case LazyComponent: this.realNode = null; this.stateCallbacks = null; + this.isLazyComponent = true; break; case Fragment: break; diff --git a/libs/horizon/src/renderer/vnode/VNodeCreator.ts b/libs/horizon/src/renderer/vnode/VNodeCreator.ts index ca585e5f..c8832fa8 100644 --- a/libs/horizon/src/renderer/vnode/VNodeCreator.ts +++ b/libs/horizon/src/renderer/vnode/VNodeCreator.ts @@ -134,7 +134,6 @@ export function createUndeterminedVNode(type, key, props) { vNode.shouldUpdate = true; if (isLazy) { - vNode.isLazyComponent = isLazy; vNode.lazyType = type; } return vNode; From bd7c640db67ef5a1fcbc09764891a2ca33cd52bf Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 20:29:51 +0800 Subject: [PATCH 3/4] Match-id-9ccbe249bd64aa265df986ea76dfa1446be57717 --- libs/horizon/src/renderer/vnode/VNode.ts | 1 + .../src/renderer/vnode/VNodeCreator.ts | 41 ++++++++----------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 371e488d..a48c4ab9 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -137,6 +137,7 @@ export class VNode { this.realNode = null; this.stateCallbacks = null; this.isLazyComponent = true; + this.lazyType = null; break; case Fragment: break; diff --git a/libs/horizon/src/renderer/vnode/VNodeCreator.ts b/libs/horizon/src/renderer/vnode/VNodeCreator.ts index c8832fa8..b37fa3c7 100644 --- a/libs/horizon/src/renderer/vnode/VNodeCreator.ts +++ b/libs/horizon/src/renderer/vnode/VNodeCreator.ts @@ -84,28 +84,6 @@ export function updateVNode(vNode: VNode, vNodeProps?: any): 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) { const vNode = newVirtualNode(Fragment, fragmentKey, fragmentProps); vNode.shouldUpdate = true; @@ -127,7 +105,24 @@ export function createPortalVNode(portal) { } 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); vNode.type = type; From 3f9bcc8c577f9a677256cadf93f8818334c015d7 Mon Sep 17 00:00:00 2001 From: * <8> Date: Fri, 18 Feb 2022 10:23:44 +0800 Subject: [PATCH 4/4] Match-id-85dc02bf87a8af162660f3bac0e8edd29c29323d --- libs/horizon/src/renderer/submit/LifeCycleHandler.ts | 2 +- libs/horizon/src/renderer/vnode/VNodeUtils.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts index a9d8344d..dd68847b 100644 --- a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts +++ b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts @@ -235,7 +235,7 @@ function submitAddition(vNode: VNode): void { parent = parent.parent; } - if ((vNode.flags & ResetText) === ResetText) { + if ((parent.flags & ResetText) === ResetText) { // 在insert之前先reset clearText(parentDom); FlagUtils.removeFlag(parent, ResetText); diff --git a/libs/horizon/src/renderer/vnode/VNodeUtils.ts b/libs/horizon/src/renderer/vnode/VNodeUtils.ts index cc56591c..400ee792 100644 --- a/libs/horizon/src/renderer/vnode/VNodeUtils.ts +++ b/libs/horizon/src/renderer/vnode/VNodeUtils.ts @@ -93,7 +93,6 @@ export function clearVNode(vNode: VNode) { vNode.oldState = null; vNode.oldRef = null; vNode.oldChild = null; - vNode.flags = InitFlag; vNode.toUpdateNodes = null;