diff --git a/libs/horizon/src/dom/DOMInternalKeys.ts b/libs/horizon/src/dom/DOMInternalKeys.ts index 3b59dd2d..dec6fed1 100644 --- a/libs/horizon/src/dom/DOMInternalKeys.ts +++ b/libs/horizon/src/dom/DOMInternalKeys.ts @@ -14,14 +14,13 @@ import { TreeRoot, } from '../renderer/vnode/VNodeTags'; -const suffixKey = new Date().getTime().toString(); const prefix = '_horizon'; const internalKeys = { - VNode: `${prefix}VNode@${suffixKey}`, - props: `${prefix}Props@${suffixKey}`, - events: `${prefix}Events@${suffixKey}`, - nonDelegatedEvents: `${prefix}NonDelegatedEvents@${suffixKey}`, + VNode: `${prefix}VNode`, + props: `${prefix}Props`, + events: `${prefix}Events`, + nonDelegatedEvents: `${prefix}NonDelegatedEvents`, }; // 通过 VNode 实例获取 DOM 节点 diff --git a/libs/horizon/src/external/ChildrenUtil.ts b/libs/horizon/src/external/ChildrenUtil.ts index c1b681ad..c5eff12e 100644 --- a/libs/horizon/src/external/ChildrenUtil.ts +++ b/libs/horizon/src/external/ChildrenUtil.ts @@ -1,7 +1,7 @@ import {throwIfTrue} from '../renderer/utils/throwIfTrue'; -import {TYPE_ELEMENT, TYPE_PORTAL} from '../renderer/utils/elementType'; +import {TYPE_COMMON_ELEMENT, TYPE_PORTAL} from './JSXElementType'; -import {isValidElement, HorizonElement} from './HorizonElement'; +import {isValidElement, JSXElement} from './JSXElement'; // 生成key function getItemKey(item: any, index: number): string { @@ -49,11 +49,11 @@ function callMapFun( ? '.$' + mappedChild.key : ''); // 返回一个修改key的children - mappedChild = HorizonElement( + mappedChild = JSXElement( mappedChild.type, newKey, mappedChild.ref, - mappedChild._vNode, + mappedChild.belongClassVNode, mappedChild.props, ); } @@ -84,7 +84,7 @@ function mapChildrenToArray( return; } const vtype = children.vtype; - if (vtype === TYPE_ELEMENT || vtype === TYPE_PORTAL) { + if (vtype === TYPE_COMMON_ELEMENT || vtype === TYPE_PORTAL) { callMapFun(children, arr, prefix, callback) ; return; } diff --git a/libs/horizon/src/external/Horizon.ts b/libs/horizon/src/external/Horizon.ts index 8c933c80..623bfbb4 100644 --- a/libs/horizon/src/external/Horizon.ts +++ b/libs/horizon/src/external/Horizon.ts @@ -3,7 +3,7 @@ import { TYPE_PROFILER, TYPE_STRICT_MODE, TYPE_SUSPENSE, -} from '../renderer/utils/elementType'; +} from './JSXElementType'; import {Component, PureComponent} from '../renderer/components/BaseClassComponent'; import {createRef} from '../renderer/components/CreateRef'; @@ -12,7 +12,7 @@ import { createElement, cloneElement, isValidElement, -} from './HorizonElement'; +} from './JSXElement'; import {createContext} from '../renderer/components/context/CreateContext'; import {lazy} from '../renderer/components/Lazy'; import {forwardRef} from '../renderer/components/ForwardRef'; diff --git a/libs/horizon/src/external/HorizonElement.ts b/libs/horizon/src/external/JSXElement.ts similarity index 70% rename from libs/horizon/src/external/HorizonElement.ts rename to libs/horizon/src/external/JSXElement.ts index c315bd6a..f0218ac9 100644 --- a/libs/horizon/src/external/HorizonElement.ts +++ b/libs/horizon/src/external/JSXElement.ts @@ -1,18 +1,18 @@ -import { TYPE_ELEMENT } from '../renderer/utils/elementType'; -import ProcessingVNode from '../renderer/vnode/ProcessingVNode'; +import { TYPE_COMMON_ELEMENT } from './JSXElementType'; +import { getProcessingClassVNode } from '../renderer/GlobalVar'; /** - * vtype, 节点的类型,这里固定是element - * type,保存dom节点的名称或者组件的函数地址 + * vtype 节点的类型,这里固定是element + * type 保存dom节点的名称或者组件的函数地址 * key key属性 * ref ref属性 * props 其他常规属性 */ -export function HorizonElement(type, key, ref, vNode, props) { +export function JSXElement(type, key, ref, vNode, props) { return { - // Horizon元素标识符 - vtype: TYPE_ELEMENT, + // 元素标识符 + vtype: TYPE_COMMON_ELEMENT, // 属于元素的内置属性 type: type, @@ -20,8 +20,8 @@ export function HorizonElement(type, key, ref, vNode, props) { ref: ref, props: props, - // 记录负责创建此元素的组件。 - _vNode: vNode, + // 所属的class组件 + belongClassVNode: vNode, }; } @@ -42,7 +42,7 @@ function buildElement(isClone, type, setting, ...children) { const key = (setting && setting.key !== undefined) ? String(setting.key) : (isClone ? type.key : null); const ref = (setting && setting.ref !== undefined) ? setting.ref : (isClone ? type.ref : null); const props = isClone ? {...type.props} : {}; - let vNode = isClone ? type._vNode : ProcessingVNode.val; + let vNode = isClone ? type.belongClassVNode : getProcessingClassVNode(); if (setting != null) { Object.keys(setting).forEach(k => { @@ -51,7 +51,7 @@ function buildElement(isClone, type, setting, ...children) { } }); if (setting.ref !== undefined && isClone) { - vNode = ProcessingVNode.val; + vNode = getProcessingClassVNode(); } } @@ -59,15 +59,15 @@ function buildElement(isClone, type, setting, ...children) { props.children = children.length === 1 ? children[0] : children; } const element = isClone ? type.type : type; - //合并默认属性 + // 合并默认属性 if (element && element.defaultProps) { mergeDefault(props, element.defaultProps); } - return HorizonElement(element, key, ref, vNode, props); + return JSXElement(element, key, ref, vNode, props); } -//创建Element结构体,供JSX编译时调用 +// 创建Element结构体,供JSX编译时调用 export function createElement(type, setting, ...children) { return buildElement(false, type, setting, ...children); } @@ -78,5 +78,5 @@ export function cloneElement(element, setting, ...children) { // 检测结构体是否为合法的Element export function isValidElement(element) { - return !!(element && element.vtype === TYPE_ELEMENT); + return !!(element && element.vtype === TYPE_COMMON_ELEMENT); } diff --git a/libs/horizon/src/renderer/utils/elementType.ts b/libs/horizon/src/external/JSXElementType.ts similarity index 89% rename from libs/horizon/src/renderer/utils/elementType.ts rename to libs/horizon/src/external/JSXElementType.ts index b23ad4d6..b692f39a 100644 --- a/libs/horizon/src/renderer/utils/elementType.ts +++ b/libs/horizon/src/external/JSXElementType.ts @@ -1,4 +1,4 @@ -export const TYPE_ELEMENT = 1; +export const TYPE_COMMON_ELEMENT = 1; export const TYPE_PORTAL = 2; export const TYPE_FRAGMENT = 3; export const TYPE_STRICT_MODE = 4; diff --git a/libs/horizon/src/renderer/ExecuteMode.ts b/libs/horizon/src/renderer/ExecuteMode.ts index 880e9374..68c6f2c1 100644 --- a/libs/horizon/src/renderer/ExecuteMode.ts +++ b/libs/horizon/src/renderer/ExecuteMode.ts @@ -5,7 +5,7 @@ export const InRender = 'IN_RENDER'; type RenderMode = typeof ByAsync | typeof BySync | typeof InRender; -// 当前执行阶段标记 +// 当前执行模式标记 let executeMode = { [ByAsync]: false, [BySync]: false, diff --git a/libs/horizon/src/renderer/GlobalVar.ts b/libs/horizon/src/renderer/GlobalVar.ts new file mode 100644 index 00000000..e7ea335c --- /dev/null +++ b/libs/horizon/src/renderer/GlobalVar.ts @@ -0,0 +1,34 @@ +import type {VNode} from './Types'; + +// 当前处理的classVNode,用于inst.refs用法中的 +let processingClassVNode: VNode | null = null; +export function getProcessingClassVNode(): VNode | null { + return processingClassVNode; +} +export function setProcessingClassVNode(vNode: VNode | null) { + processingClassVNode = vNode; +} + +// 计算出来的刷新节点,不一定是根节点 +let startVNode: VNode | null = null; +export function getStartVNode(): VNode | null { + return startVNode; +} +export function setStartVNode(vNode: VNode | null) { + startVNode = vNode; +} + +type BuildVNodeResult = 0 | 1 | 2 | 3; +export const BuildInComplete = 0; +export const BuildFatalErrored = 1; +export const BuildErrored = 2; +export const BuildCompleted = 3; +// 根节点退出build tree时的状态,如: completed, incomplete, errored, fatalErrored. +let buildVNodeResult: BuildVNodeResult = BuildInComplete; +export function setBuildResult(result: BuildVNodeResult) { + buildVNodeResult = result; +} + +export function getBuildResult(): BuildVNodeResult { + return buildVNodeResult; +} diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index 0d3bfa9e..4f89f7a4 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -9,7 +9,15 @@ import { checkLoopingUpdateLimit, submitToRender } from './submit/Submit'; import { runAsyncEffects } from './submit/HookEffectHandler'; import { handleRenderThrowError } from './ErrorHandler'; import componentRenders from './render'; -import ProcessingVNode from './vnode/ProcessingVNode'; +import { + BuildCompleted, BuildErrored, + BuildFatalErrored, + BuildInComplete, getBuildResult, + getStartVNode, + setBuildResult, + setProcessingClassVNode, + setStartVNode +} from './GlobalVar'; import { findDomParent, getSiblingVNode } from './vnode/VNodeUtils'; import { ByAsync, @@ -28,39 +36,16 @@ import { updateShouldUpdateOfTree } from './vnode/VNodeShouldUpdate'; -type BuildVNodeResult = 0 | 1 | 2 | 3; -const BuildInComplete = 0; -const BuildFatalErrored = 1; -const BuildErrored = 2; -const BuildCompleted = 3; - // 当前运行的vNode节点 let processing: VNode | null = null; -// 根节点退出build tree时的状态,如: completed, incomplete, errored, fatalErrored. -let buildVNodeResult: BuildVNodeResult = BuildInComplete; + // 不可恢复错误 let unrecoverableErrorDuringBuild: any = null; -function setBuildResult(result: BuildVNodeResult) { - buildVNodeResult = result; -} - -function getBuildResult(): BuildVNodeResult { - return buildVNodeResult; -} - export function setProcessing(vNode: VNode | null) { processing = vNode; } -let startVNode: VNode | null = null; -export function getStartVNode(): VNode | null { - return startVNode; -} -export function setStartVNode(vNode: VNode | null) { - startVNode = vNode; -} - // 为重新进行深度遍历做准备 function resetProcessingVariables(startUpdateVNode: VNode) { // 创建processing @@ -141,7 +126,6 @@ function buildVNodeTree(treeRoot: VNode) { // 计算出开始节点 const startUpdateVNode = calcStartUpdateVNode(treeRoot); - // 缓存起来 setStartVNode(startUpdateVNode); @@ -163,7 +147,7 @@ function buildVNodeTree(treeRoot: VNode) { recoverParentsContextCtx(startUpdateVNode); } - // 重置环境变量 + // 重置环境变量,为重新进行深度遍历做准备 resetProcessingVariables(startUpdateVNode); do { @@ -178,9 +162,10 @@ function buildVNodeTree(treeRoot: VNode) { } else { processing = next; } - - ProcessingVNode.val = null; } + + setProcessingClassVNode(null); + break; } catch (thrownValue) { handleError(treeRoot, thrownValue); diff --git a/libs/horizon/src/renderer/Types.ts b/libs/horizon/src/renderer/Types.ts index 2f3fad4b..34640d51 100644 --- a/libs/horizon/src/renderer/Types.ts +++ b/libs/horizon/src/renderer/Types.ts @@ -15,14 +15,14 @@ export type UseReducerHookType = { }; export type UseContextHookType = { useContext(context: ContextType,): T }; -export type HorizonElement = { +export type JSXElement = { vtype: any, type: any, key: any, ref: any, props: any, - _vNode: any, + belongClassVNode: any, }; export type ProviderType = { diff --git a/libs/horizon/src/renderer/components/CreatePortal.ts b/libs/horizon/src/renderer/components/CreatePortal.ts index 3bdb4b17..2b018f16 100644 --- a/libs/horizon/src/renderer/components/CreatePortal.ts +++ b/libs/horizon/src/renderer/components/CreatePortal.ts @@ -1,4 +1,4 @@ -import {TYPE_PORTAL} from '../utils/elementType'; +import {TYPE_PORTAL} from '../../external/JSXElementType'; import type {PortalType} from '../Types'; export function createPortal( diff --git a/libs/horizon/src/renderer/components/ForwardRef.ts b/libs/horizon/src/renderer/components/ForwardRef.ts index 5baef940..63b2c791 100644 --- a/libs/horizon/src/renderer/components/ForwardRef.ts +++ b/libs/horizon/src/renderer/components/ForwardRef.ts @@ -1,4 +1,4 @@ -import {TYPE_FORWARD_REF} from '../utils/elementType'; +import {TYPE_FORWARD_REF} from '../../external/JSXElementType'; export function forwardRef(render: Function) { return { diff --git a/libs/horizon/src/renderer/components/Lazy.ts b/libs/horizon/src/renderer/components/Lazy.ts index 4b37091e..8b151da8 100644 --- a/libs/horizon/src/renderer/components/Lazy.ts +++ b/libs/horizon/src/renderer/components/Lazy.ts @@ -1,6 +1,6 @@ import type {PromiseType} from '../Types'; -import {TYPE_LAZY} from '../utils/elementType'; +import {TYPE_LAZY} from '../../external/JSXElementType'; enum LayStatus { UnProcessed = 'UnProcessed', diff --git a/libs/horizon/src/renderer/components/Memo.ts b/libs/horizon/src/renderer/components/Memo.ts index 90d3c140..9d84e8c1 100644 --- a/libs/horizon/src/renderer/components/Memo.ts +++ b/libs/horizon/src/renderer/components/Memo.ts @@ -1,4 +1,4 @@ -import {TYPE_MEMO} from '../utils/elementType'; +import {TYPE_MEMO} from '../../external/JSXElementType'; export function memo(type, compare?: (oldProps: Props, newProps: Props) => boolean) { return { diff --git a/libs/horizon/src/renderer/components/context/CreateContext.ts b/libs/horizon/src/renderer/components/context/CreateContext.ts index 45d97039..cbd6f96f 100644 --- a/libs/horizon/src/renderer/components/context/CreateContext.ts +++ b/libs/horizon/src/renderer/components/context/CreateContext.ts @@ -1,5 +1,5 @@ import type {ContextType} from '../../Types'; -import {TYPE_PROVIDER, TYPE_CONTEXT} from '../../utils/elementType'; +import {TYPE_PROVIDER, TYPE_CONTEXT} from '../../../external/JSXElementType'; export function createContext(val: T): ContextType { const context: ContextType = { diff --git a/libs/horizon/src/renderer/diff/DiffTools.ts b/libs/horizon/src/renderer/diff/DiffTools.ts index c2b44411..0b14f611 100644 --- a/libs/horizon/src/renderer/diff/DiffTools.ts +++ b/libs/horizon/src/renderer/diff/DiffTools.ts @@ -1,27 +1,11 @@ -import type { VNode, HorizonElement } from '../Types'; +import type { VNode, JSXElement } from '../Types'; // 当前vNode和element是同样的类型 // LazyComponent 会修改type的类型,所以特殊处理这种类型 -export const isSameType = (vNode: VNode, ele: HorizonElement) => { +export const isSameType = (vNode: VNode, ele: JSXElement) => { return vNode.type === ele.type || (vNode.isLazyComponent && vNode.lazyType === ele.type); }; -export function createRef(element: HorizonElement): any | void { - const elementRef = element.ref; - // 如果ref是null、function、object,直接返回 - if (elementRef === null || typeof elementRef === 'function' || typeof elementRef === 'object') { - return elementRef; - } else { // 包装成函数 - if (element._vNode) { - let inst = element._vNode.realNode; - - return function(instance) { - inst.refs[String(elementRef)] = instance; - }; - } - } -} - export function isTextType(newChild: any) { return typeof newChild === 'string' || typeof newChild === 'number'; } diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts index 606a97d9..cf2a7993 100644 --- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts +++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts @@ -1,11 +1,10 @@ import type { VNode } from '../Types'; import { FlagUtils } from '../vnode/VNodeFlags'; -import { TYPE_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../utils/elementType'; +import { TYPE_COMMON_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../../external/JSXElementType'; import { DomText, DomPortal, Fragment } from '../vnode/VNodeTags'; import {updateVNode, createVNode, createVNodeFromElement, updateVNodePath} from '../vnode/VNodeCreator'; import { isSameType, - createRef, getIteratorFn, isTextType, isArrayType, @@ -60,7 +59,7 @@ function checkCanReuseNode(oldNode: VNode | null, newChild: any): boolean { if (isArrayType(newChild) || isIteratorType(newChild)) { return oldKey === null; } - if (newChild.vtype === TYPE_ELEMENT || newChild.vtype === TYPE_PORTAL) { + if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) { return oldKey === newChild.key; } } @@ -79,7 +78,7 @@ function getNodeType(newChild: any): string { if (isArrayType(newChild) || isIteratorType(newChild)) { return DiffCategory.ARR_NODE; } - if (newChild.vtype === TYPE_ELEMENT || newChild.vtype === TYPE_PORTAL) { + if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) { return DiffCategory.OBJECT_NODE; } } @@ -129,7 +128,7 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) { break; } case DiffCategory.OBJECT_NODE: { - if (newChild.vtype === TYPE_ELEMENT) { + if (newChild.vtype === TYPE_COMMON_ELEMENT) { if (newChild.type === TYPE_FRAGMENT) { if (oldNode === null || oldNode.tag !== Fragment) { const key = oldNode !== null ? oldNode.key : newChild.key; @@ -142,10 +141,12 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) { if (oldNode === null || !isSameType(oldNode, newChild)) { resultNode = createVNodeFromElement(newChild); - resultNode.ref = createRef(newChild); + resultNode.ref = newChild.ref; + resultNode.belongClassVNode = newChild.belongClassVNode; } else { resultNode = updateVNode(oldNode, newChild.props); - resultNode.ref = createRef(newChild); + resultNode.ref = newChild.ref; + resultNode.belongClassVNode = newChild.belongClassVNode; } break; } else if (newChild.vtype === TYPE_PORTAL) { @@ -200,7 +201,7 @@ function getOldNodeFromMap(nodeMap: Map, newIdx: number, if (isArrayType(newChild) || isIteratorType(newChild)) { return nodeMap.get(newIdx) || null; } - if (newChild.vtype === TYPE_ELEMENT || newChild.vtype === TYPE_PORTAL) { + if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) { return nodeMap.get(newChild.key === null ? newIdx : newChild.key) || null; } } @@ -539,7 +540,7 @@ function diffObjectNodeHandler( let resultNode: VNode | null = null; let startDelVNode = firstChildVNode; - if (newChild.vtype === TYPE_ELEMENT) { + if (newChild.vtype === TYPE_COMMON_ELEMENT) { if (canReuseNode) { // 可以复用 if (canReuseNode.tag === Fragment && newChild.type === TYPE_FRAGMENT) { @@ -548,7 +549,8 @@ function diffObjectNodeHandler( resultNode.next = null; } else if (isSameType(canReuseNode, newChild)) { resultNode = updateVNode(canReuseNode, newChild.props); - resultNode.ref = createRef(newChild); + resultNode.ref = newChild.ref; + resultNode.belongClassVNode = newChild.belongClassVNode; startDelVNode = getSiblingVNode(resultNode); resultNode.next = null; } @@ -560,7 +562,8 @@ function diffObjectNodeHandler( resultNode = createVNode(Fragment, newChild.key, newChild.props.children); } else { resultNode = createVNodeFromElement(newChild); - resultNode.ref = createRef(newChild); + resultNode.ref = newChild.ref; + resultNode.belongClassVNode = newChild.belongClassVNode; } } } else if (newChild.vtype === TYPE_PORTAL) { diff --git a/libs/horizon/src/renderer/render/ClassComponent.ts b/libs/horizon/src/renderer/render/ClassComponent.ts index 2be13d49..b459215c 100644 --- a/libs/horizon/src/renderer/render/ClassComponent.ts +++ b/libs/horizon/src/renderer/render/ClassComponent.ts @@ -27,7 +27,7 @@ import { processUpdates, } from '../UpdateHandler'; import { getContextChangeCtx, setContextChangeCtx } from '../ContextSaver'; -import ProcessingVNode from '../vnode/ProcessingVNode'; +import { setProcessingClassVNode } from '../GlobalVar'; import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator'; // 获取当前节点的context @@ -69,7 +69,7 @@ function mountInstance(clazz, processing: VNode, nextProps: object) { function createChildren(clazz: any, processing: VNode) { markRef(processing); - ProcessingVNode.val = processing; + setProcessingClassVNode(processing); processing.state = processing.realNode.state; const inst = processing.realNode; diff --git a/libs/horizon/src/renderer/render/MemoComponent.ts b/libs/horizon/src/renderer/render/MemoComponent.ts index 2c24c0d7..fd273249 100644 --- a/libs/horizon/src/renderer/render/MemoComponent.ts +++ b/libs/horizon/src/renderer/render/MemoComponent.ts @@ -7,7 +7,7 @@ import { TYPE_FRAGMENT, TYPE_PROFILER, TYPE_STRICT_MODE, -} from '../utils/elementType'; +} from '../../external/JSXElementType'; import {Fragment} from '../vnode/VNodeTags'; export function captureRender(processing: VNode, shouldUpdate: boolean): VNode | null { diff --git a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts index d2eafa4c..46260ac0 100644 --- a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts +++ b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts @@ -159,13 +159,19 @@ function hideOrUnhideAllChildren(vNode, isHidden) { function attachRef(vNode: VNode) { const ref = vNode.ref; + if (ref !== null) { const instance = vNode.realNode; - if (typeof ref === 'function') { + let refType = typeof ref; + if (refType === 'function') { ref(instance); - } else { + } else if (refType === 'object') { (ref).current = instance; + } else { + if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) { + vNode.belongClassVNode.realNode.refs[String(ref)] = instance; + } } } } @@ -174,14 +180,20 @@ function detachRef(vNode: VNode, isOldRef?: boolean) { let ref = (isOldRef ? vNode.oldRef : vNode.ref); if (ref !== null) { - if (typeof ref === 'function') { + let refType = typeof ref; + + if (refType === 'function') { try { ref(null); } catch (error) { handleSubmitError(vNode, error); } - } else { + } else if (refType === 'object') { (ref).current = null; + } else { + if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) { + vNode.belongClassVNode.realNode.refs[String(ref)] = null; + } } } } diff --git a/libs/horizon/src/renderer/submit/Submit.ts b/libs/horizon/src/renderer/submit/Submit.ts index 95ada780..774c7386 100644 --- a/libs/horizon/src/renderer/submit/Submit.ts +++ b/libs/horizon/src/renderer/submit/Submit.ts @@ -11,7 +11,7 @@ import { callBeforeSubmitLifeCycles, submitDeletion, submitAddition, submitResetTextContent, submitUpdate, detachRef, } from './LifeCycleHandler'; -import {tryRenderRoot, setProcessing, getStartVNode} from '../TreeBuilder'; +import {tryRenderRoot, setProcessing} from '../TreeBuilder'; import { BySync, InRender, @@ -24,6 +24,7 @@ import { isSchedulingEffects, setSchedulingEffects, setHookEffectRoot, } from './HookEffectHandler'; +import {getStartVNode} from '../GlobalVar'; let rootThrowError = null; diff --git a/libs/horizon/src/renderer/vnode/ProcessingVNode.ts b/libs/horizon/src/renderer/vnode/ProcessingVNode.ts deleted file mode 100644 index 1110242c..00000000 --- a/libs/horizon/src/renderer/vnode/ProcessingVNode.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type {VNode} from '../Types'; - -// 当前所有者是应拥有当前正在构建的任何组件的组件。 -const ProcessingVNode: { val: VNode | null } = { - val: null, -}; - -export default ProcessingVNode; diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 8c16fad4..810c7fb5 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -76,6 +76,8 @@ export class VNode { path: Array = []; // 保存从根到本节点的路径 toUpdateNodes: Set | null = null; // 保存要更新的节点 + belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode,处理ref的时候使用 + constructor(tag: VNodeTag, props: any, key: null | string, outerDom) { this.tag = tag; // 对应组件的类型,比如ClassComponent等 this.key = key; diff --git a/libs/horizon/src/renderer/vnode/VNodeCreator.ts b/libs/horizon/src/renderer/vnode/VNodeCreator.ts index 71c4a8dc..45648678 100644 --- a/libs/horizon/src/renderer/vnode/VNodeCreator.ts +++ b/libs/horizon/src/renderer/vnode/VNodeCreator.ts @@ -24,9 +24,9 @@ import { TYPE_MEMO, TYPE_PROFILER, TYPE_PROVIDER, TYPE_STRICT_MODE, TYPE_SUSPENSE, -} from '../utils/elementType'; +} from '../../external/JSXElementType'; import { VNode } from './VNode'; -import {HorizonElement} from '../Types'; +import {JSXElement} from '../Types'; const typeLazyMap = { [TYPE_FORWARD_REF]: ForwardRef, @@ -156,7 +156,7 @@ export function updateVNodePath(vNode: VNode) { vNode.path = [...vNode.parent.path, vNode.cIndex]; } -export function createVNodeFromElement(element: HorizonElement): VNode { +export function createVNodeFromElement(element: JSXElement): VNode { const type = element.type; const key = element.key; const props = element.props; diff --git a/libs/horizon/src/renderer/vnode/VNodeUtils.ts b/libs/horizon/src/renderer/vnode/VNodeUtils.ts index 3251cb7d..09ff6f0e 100644 --- a/libs/horizon/src/renderer/vnode/VNodeUtils.ts +++ b/libs/horizon/src/renderer/vnode/VNodeUtils.ts @@ -13,7 +13,7 @@ export function getSiblingVNode(node) { } export function travelChildren(beginVNode: VNode, handleVNode: Function, isFinish?: Function) { - let node = beginVNode; + let node: VNode | null = beginVNode; while (node !== null) { if (isFinish && isFinish(node)) { @@ -77,10 +77,6 @@ export function travelVNodeTree( // 置空vNode export function clearVNode(vNode: VNode) { - clearOneVNode(vNode); -} - -function clearOneVNode(vNode: VNode) { vNode.child = null; vNode.next = null; vNode.depContexts = []; @@ -105,6 +101,8 @@ function clearOneVNode(vNode: VNode) { vNode.path = []; vNode.toUpdateNodes = null; + + vNode.belongClassVNode = null; } // 是dom类型的vNode @@ -225,7 +223,7 @@ function isSameContainer( } // 注释类型的节点 if (isComment(container) && container.parentNode === targetContainer) { - return true + return true; } return false; }