Match-id-49b2f36cda8b4bb3c0bd2f10fba05d43d5cf72ea
This commit is contained in:
commit
e43fb0fd5e
|
@ -14,14 +14,13 @@ import {
|
||||||
TreeRoot,
|
TreeRoot,
|
||||||
} from '../renderer/vnode/VNodeTags';
|
} from '../renderer/vnode/VNodeTags';
|
||||||
|
|
||||||
const suffixKey = new Date().getTime().toString();
|
|
||||||
const prefix = '_horizon';
|
const prefix = '_horizon';
|
||||||
|
|
||||||
const internalKeys = {
|
const internalKeys = {
|
||||||
VNode: `${prefix}VNode@${suffixKey}`,
|
VNode: `${prefix}VNode`,
|
||||||
props: `${prefix}Props@${suffixKey}`,
|
props: `${prefix}Props`,
|
||||||
events: `${prefix}Events@${suffixKey}`,
|
events: `${prefix}Events`,
|
||||||
nonDelegatedEvents: `${prefix}NonDelegatedEvents@${suffixKey}`,
|
nonDelegatedEvents: `${prefix}NonDelegatedEvents`,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 通过 VNode 实例获取 DOM 节点
|
// 通过 VNode 实例获取 DOM 节点
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {throwIfTrue} from '../renderer/utils/throwIfTrue';
|
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
|
// 生成key
|
||||||
function getItemKey(item: any, index: number): string {
|
function getItemKey(item: any, index: number): string {
|
||||||
|
@ -49,11 +49,11 @@ function callMapFun(
|
||||||
? '.$' + mappedChild.key
|
? '.$' + mappedChild.key
|
||||||
: '');
|
: '');
|
||||||
// 返回一个修改key的children
|
// 返回一个修改key的children
|
||||||
mappedChild = HorizonElement(
|
mappedChild = JSXElement(
|
||||||
mappedChild.type,
|
mappedChild.type,
|
||||||
newKey,
|
newKey,
|
||||||
mappedChild.ref,
|
mappedChild.ref,
|
||||||
mappedChild._vNode,
|
mappedChild.belongClassVNode,
|
||||||
mappedChild.props,
|
mappedChild.props,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ function mapChildrenToArray(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const vtype = children.vtype;
|
const vtype = children.vtype;
|
||||||
if (vtype === TYPE_ELEMENT || vtype === TYPE_PORTAL) {
|
if (vtype === TYPE_COMMON_ELEMENT || vtype === TYPE_PORTAL) {
|
||||||
callMapFun(children, arr, prefix, callback) ;
|
callMapFun(children, arr, prefix, callback) ;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
TYPE_PROFILER,
|
TYPE_PROFILER,
|
||||||
TYPE_STRICT_MODE,
|
TYPE_STRICT_MODE,
|
||||||
TYPE_SUSPENSE,
|
TYPE_SUSPENSE,
|
||||||
} from '../renderer/utils/elementType';
|
} from './JSXElementType';
|
||||||
|
|
||||||
import {Component, PureComponent} from '../renderer/components/BaseClassComponent';
|
import {Component, PureComponent} from '../renderer/components/BaseClassComponent';
|
||||||
import {createRef} from '../renderer/components/CreateRef';
|
import {createRef} from '../renderer/components/CreateRef';
|
||||||
|
@ -12,7 +12,7 @@ import {
|
||||||
createElement,
|
createElement,
|
||||||
cloneElement,
|
cloneElement,
|
||||||
isValidElement,
|
isValidElement,
|
||||||
} from './HorizonElement';
|
} from './JSXElement';
|
||||||
import {createContext} from '../renderer/components/context/CreateContext';
|
import {createContext} from '../renderer/components/context/CreateContext';
|
||||||
import {lazy} from '../renderer/components/Lazy';
|
import {lazy} from '../renderer/components/Lazy';
|
||||||
import {forwardRef} from '../renderer/components/ForwardRef';
|
import {forwardRef} from '../renderer/components/ForwardRef';
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import { TYPE_ELEMENT } from '../renderer/utils/elementType';
|
import { TYPE_COMMON_ELEMENT } from './JSXElementType';
|
||||||
import ProcessingVNode from '../renderer/vnode/ProcessingVNode';
|
import { getProcessingClassVNode } from '../renderer/GlobalVar';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vtype, 节点的类型,这里固定是element
|
* vtype 节点的类型,这里固定是element
|
||||||
* type,保存dom节点的名称或者组件的函数地址
|
* type 保存dom节点的名称或者组件的函数地址
|
||||||
* key key属性
|
* key key属性
|
||||||
* ref ref属性
|
* ref ref属性
|
||||||
* props 其他常规属性
|
* props 其他常规属性
|
||||||
*/
|
*/
|
||||||
export function HorizonElement(type, key, ref, vNode, props) {
|
export function JSXElement(type, key, ref, vNode, props) {
|
||||||
return {
|
return {
|
||||||
// Horizon元素标识符
|
// 元素标识符
|
||||||
vtype: TYPE_ELEMENT,
|
vtype: TYPE_COMMON_ELEMENT,
|
||||||
|
|
||||||
// 属于元素的内置属性
|
// 属于元素的内置属性
|
||||||
type: type,
|
type: type,
|
||||||
|
@ -20,8 +20,8 @@ export function HorizonElement(type, key, ref, vNode, props) {
|
||||||
ref: ref,
|
ref: ref,
|
||||||
props: props,
|
props: props,
|
||||||
|
|
||||||
// 记录负责创建此元素的组件。
|
// 所属的class组件
|
||||||
_vNode: vNode,
|
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 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 ref = (setting && setting.ref !== undefined) ? setting.ref : (isClone ? type.ref : null);
|
||||||
const props = isClone ? {...type.props} : {};
|
const props = isClone ? {...type.props} : {};
|
||||||
let vNode = isClone ? type._vNode : ProcessingVNode.val;
|
let vNode = isClone ? type.belongClassVNode : getProcessingClassVNode();
|
||||||
|
|
||||||
if (setting != null) {
|
if (setting != null) {
|
||||||
Object.keys(setting).forEach(k => {
|
Object.keys(setting).forEach(k => {
|
||||||
|
@ -51,7 +51,7 @@ function buildElement(isClone, type, setting, ...children) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (setting.ref !== undefined && isClone) {
|
if (setting.ref !== undefined && isClone) {
|
||||||
vNode = ProcessingVNode.val;
|
vNode = getProcessingClassVNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ function buildElement(isClone, type, setting, ...children) {
|
||||||
mergeDefault(props, element.defaultProps);
|
mergeDefault(props, element.defaultProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
return HorizonElement(element, key, ref, vNode, props);
|
return JSXElement(element, key, ref, vNode, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建Element结构体,供JSX编译时调用
|
// 创建Element结构体,供JSX编译时调用
|
||||||
|
@ -78,5 +78,5 @@ export function cloneElement(element, setting, ...children) {
|
||||||
|
|
||||||
// 检测结构体是否为合法的Element
|
// 检测结构体是否为合法的Element
|
||||||
export function isValidElement(element) {
|
export function isValidElement(element) {
|
||||||
return !!(element && element.vtype === TYPE_ELEMENT);
|
return !!(element && element.vtype === TYPE_COMMON_ELEMENT);
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
export const TYPE_ELEMENT = 1;
|
export const TYPE_COMMON_ELEMENT = 1;
|
||||||
export const TYPE_PORTAL = 2;
|
export const TYPE_PORTAL = 2;
|
||||||
export const TYPE_FRAGMENT = 3;
|
export const TYPE_FRAGMENT = 3;
|
||||||
export const TYPE_STRICT_MODE = 4;
|
export const TYPE_STRICT_MODE = 4;
|
|
@ -5,7 +5,7 @@ export const InRender = 'IN_RENDER';
|
||||||
|
|
||||||
type RenderMode = typeof ByAsync | typeof BySync | typeof InRender;
|
type RenderMode = typeof ByAsync | typeof BySync | typeof InRender;
|
||||||
|
|
||||||
// 当前执行阶段标记
|
// 当前执行模式标记
|
||||||
let executeMode = {
|
let executeMode = {
|
||||||
[ByAsync]: false,
|
[ByAsync]: false,
|
||||||
[BySync]: false,
|
[BySync]: false,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -9,7 +9,15 @@ import { checkLoopingUpdateLimit, submitToRender } from './submit/Submit';
|
||||||
import { runAsyncEffects } from './submit/HookEffectHandler';
|
import { runAsyncEffects } from './submit/HookEffectHandler';
|
||||||
import { handleRenderThrowError } from './ErrorHandler';
|
import { handleRenderThrowError } from './ErrorHandler';
|
||||||
import componentRenders from './render';
|
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 { findDomParent, getSiblingVNode } from './vnode/VNodeUtils';
|
||||||
import {
|
import {
|
||||||
ByAsync,
|
ByAsync,
|
||||||
|
@ -28,39 +36,16 @@ import {
|
||||||
updateShouldUpdateOfTree
|
updateShouldUpdateOfTree
|
||||||
} from './vnode/VNodeShouldUpdate';
|
} from './vnode/VNodeShouldUpdate';
|
||||||
|
|
||||||
type BuildVNodeResult = 0 | 1 | 2 | 3;
|
|
||||||
const BuildInComplete = 0;
|
|
||||||
const BuildFatalErrored = 1;
|
|
||||||
const BuildErrored = 2;
|
|
||||||
const BuildCompleted = 3;
|
|
||||||
|
|
||||||
// 当前运行的vNode节点
|
// 当前运行的vNode节点
|
||||||
let processing: VNode | null = null;
|
let processing: VNode | null = null;
|
||||||
// 根节点退出build tree时的状态,如: completed, incomplete, errored, fatalErrored.
|
|
||||||
let buildVNodeResult: BuildVNodeResult = BuildInComplete;
|
|
||||||
// 不可恢复错误
|
// 不可恢复错误
|
||||||
let unrecoverableErrorDuringBuild: any = null;
|
let unrecoverableErrorDuringBuild: any = null;
|
||||||
|
|
||||||
function setBuildResult(result: BuildVNodeResult) {
|
|
||||||
buildVNodeResult = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBuildResult(): BuildVNodeResult {
|
|
||||||
return buildVNodeResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setProcessing(vNode: VNode | null) {
|
export function setProcessing(vNode: VNode | null) {
|
||||||
processing = vNode;
|
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) {
|
function resetProcessingVariables(startUpdateVNode: VNode) {
|
||||||
// 创建processing
|
// 创建processing
|
||||||
|
@ -141,7 +126,6 @@ function buildVNodeTree(treeRoot: VNode) {
|
||||||
|
|
||||||
// 计算出开始节点
|
// 计算出开始节点
|
||||||
const startUpdateVNode = calcStartUpdateVNode(treeRoot);
|
const startUpdateVNode = calcStartUpdateVNode(treeRoot);
|
||||||
|
|
||||||
// 缓存起来
|
// 缓存起来
|
||||||
setStartVNode(startUpdateVNode);
|
setStartVNode(startUpdateVNode);
|
||||||
|
|
||||||
|
@ -163,7 +147,7 @@ function buildVNodeTree(treeRoot: VNode) {
|
||||||
recoverParentsContextCtx(startUpdateVNode);
|
recoverParentsContextCtx(startUpdateVNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置环境变量
|
// 重置环境变量,为重新进行深度遍历做准备
|
||||||
resetProcessingVariables(startUpdateVNode);
|
resetProcessingVariables(startUpdateVNode);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -178,9 +162,10 @@ function buildVNodeTree(treeRoot: VNode) {
|
||||||
} else {
|
} else {
|
||||||
processing = next;
|
processing = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessingVNode.val = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setProcessingClassVNode(null);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} catch (thrownValue) {
|
} catch (thrownValue) {
|
||||||
handleError(treeRoot, thrownValue);
|
handleError(treeRoot, thrownValue);
|
||||||
|
|
|
@ -15,14 +15,14 @@ export type UseReducerHookType = {
|
||||||
};
|
};
|
||||||
export type UseContextHookType = { useContext<T>(context: ContextType<T>,): T };
|
export type UseContextHookType = { useContext<T>(context: ContextType<T>,): T };
|
||||||
|
|
||||||
export type HorizonElement = {
|
export type JSXElement = {
|
||||||
vtype: any,
|
vtype: any,
|
||||||
type: any,
|
type: any,
|
||||||
key: any,
|
key: any,
|
||||||
ref: any,
|
ref: any,
|
||||||
props: any,
|
props: any,
|
||||||
|
|
||||||
_vNode: any,
|
belongClassVNode: any,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProviderType<T> = {
|
export type ProviderType<T> = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {TYPE_PORTAL} from '../utils/elementType';
|
import {TYPE_PORTAL} from '../../external/JSXElementType';
|
||||||
import type {PortalType} from '../Types';
|
import type {PortalType} from '../Types';
|
||||||
|
|
||||||
export function createPortal(
|
export function createPortal(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {TYPE_FORWARD_REF} from '../utils/elementType';
|
import {TYPE_FORWARD_REF} from '../../external/JSXElementType';
|
||||||
|
|
||||||
export function forwardRef(render: Function) {
|
export function forwardRef(render: Function) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type {PromiseType} from '../Types';
|
import type {PromiseType} from '../Types';
|
||||||
|
|
||||||
import {TYPE_LAZY} from '../utils/elementType';
|
import {TYPE_LAZY} from '../../external/JSXElementType';
|
||||||
|
|
||||||
enum LayStatus {
|
enum LayStatus {
|
||||||
UnProcessed = 'UnProcessed',
|
UnProcessed = 'UnProcessed',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {TYPE_MEMO} from '../utils/elementType';
|
import {TYPE_MEMO} from '../../external/JSXElementType';
|
||||||
|
|
||||||
export function memo<Props>(type, compare?: (oldProps: Props, newProps: Props) => boolean) {
|
export function memo<Props>(type, compare?: (oldProps: Props, newProps: Props) => boolean) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type {ContextType} from '../../Types';
|
import type {ContextType} from '../../Types';
|
||||||
import {TYPE_PROVIDER, TYPE_CONTEXT} from '../../utils/elementType';
|
import {TYPE_PROVIDER, TYPE_CONTEXT} from '../../../external/JSXElementType';
|
||||||
|
|
||||||
export function createContext<T>(val: T): ContextType<T> {
|
export function createContext<T>(val: T): ContextType<T> {
|
||||||
const context: ContextType<T> = {
|
const context: ContextType<T> = {
|
||||||
|
|
|
@ -1,27 +1,11 @@
|
||||||
import type { VNode, HorizonElement } from '../Types';
|
import type { VNode, JSXElement } from '../Types';
|
||||||
|
|
||||||
// 当前vNode和element是同样的类型
|
// 当前vNode和element是同样的类型
|
||||||
// LazyComponent 会修改type的类型,所以特殊处理这种类型
|
// 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);
|
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) {
|
export function isTextType(newChild: any) {
|
||||||
return typeof newChild === 'string' || typeof newChild === 'number';
|
return typeof newChild === 'string' || typeof newChild === 'number';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import type { VNode } from '../Types';
|
import type { VNode } from '../Types';
|
||||||
import { FlagUtils } from '../vnode/VNodeFlags';
|
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 { DomText, DomPortal, Fragment } from '../vnode/VNodeTags';
|
||||||
import {updateVNode, createVNode, createVNodeFromElement, updateVNodePath} from '../vnode/VNodeCreator';
|
import {updateVNode, createVNode, createVNodeFromElement, updateVNodePath} from '../vnode/VNodeCreator';
|
||||||
import {
|
import {
|
||||||
isSameType,
|
isSameType,
|
||||||
createRef,
|
|
||||||
getIteratorFn,
|
getIteratorFn,
|
||||||
isTextType,
|
isTextType,
|
||||||
isArrayType,
|
isArrayType,
|
||||||
|
@ -60,7 +59,7 @@ function checkCanReuseNode(oldNode: VNode | null, newChild: any): boolean {
|
||||||
if (isArrayType(newChild) || isIteratorType(newChild)) {
|
if (isArrayType(newChild) || isIteratorType(newChild)) {
|
||||||
return oldKey === null;
|
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;
|
return oldKey === newChild.key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +78,7 @@ function getNodeType(newChild: any): string {
|
||||||
if (isArrayType(newChild) || isIteratorType(newChild)) {
|
if (isArrayType(newChild) || isIteratorType(newChild)) {
|
||||||
return DiffCategory.ARR_NODE;
|
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;
|
return DiffCategory.OBJECT_NODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +128,7 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DiffCategory.OBJECT_NODE: {
|
case DiffCategory.OBJECT_NODE: {
|
||||||
if (newChild.vtype === TYPE_ELEMENT) {
|
if (newChild.vtype === TYPE_COMMON_ELEMENT) {
|
||||||
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;
|
||||||
|
@ -142,10 +141,12 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) {
|
||||||
|
|
||||||
if (oldNode === null || !isSameType(oldNode, newChild)) {
|
if (oldNode === null || !isSameType(oldNode, newChild)) {
|
||||||
resultNode = createVNodeFromElement(newChild);
|
resultNode = createVNodeFromElement(newChild);
|
||||||
resultNode.ref = createRef(newChild);
|
resultNode.ref = newChild.ref;
|
||||||
|
resultNode.belongClassVNode = newChild.belongClassVNode;
|
||||||
} else {
|
} else {
|
||||||
resultNode = updateVNode(oldNode, newChild.props);
|
resultNode = updateVNode(oldNode, newChild.props);
|
||||||
resultNode.ref = createRef(newChild);
|
resultNode.ref = newChild.ref;
|
||||||
|
resultNode.belongClassVNode = newChild.belongClassVNode;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (newChild.vtype === TYPE_PORTAL) {
|
} else if (newChild.vtype === TYPE_PORTAL) {
|
||||||
|
@ -200,7 +201,7 @@ function getOldNodeFromMap(nodeMap: Map<string | number, VNode>, newIdx: number,
|
||||||
if (isArrayType(newChild) || isIteratorType(newChild)) {
|
if (isArrayType(newChild) || isIteratorType(newChild)) {
|
||||||
return nodeMap.get(newIdx) || null;
|
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;
|
return nodeMap.get(newChild.key === null ? newIdx : newChild.key) || null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,7 +540,7 @@ function diffObjectNodeHandler(
|
||||||
|
|
||||||
let resultNode: VNode | null = null;
|
let resultNode: VNode | null = null;
|
||||||
let startDelVNode = firstChildVNode;
|
let startDelVNode = firstChildVNode;
|
||||||
if (newChild.vtype === TYPE_ELEMENT) {
|
if (newChild.vtype === TYPE_COMMON_ELEMENT) {
|
||||||
if (canReuseNode) {
|
if (canReuseNode) {
|
||||||
// 可以复用
|
// 可以复用
|
||||||
if (canReuseNode.tag === Fragment && newChild.type === TYPE_FRAGMENT) {
|
if (canReuseNode.tag === Fragment && newChild.type === TYPE_FRAGMENT) {
|
||||||
|
@ -548,7 +549,8 @@ function diffObjectNodeHandler(
|
||||||
resultNode.next = null;
|
resultNode.next = null;
|
||||||
} else if (isSameType(canReuseNode, newChild)) {
|
} else if (isSameType(canReuseNode, newChild)) {
|
||||||
resultNode = updateVNode(canReuseNode, newChild.props);
|
resultNode = updateVNode(canReuseNode, newChild.props);
|
||||||
resultNode.ref = createRef(newChild);
|
resultNode.ref = newChild.ref;
|
||||||
|
resultNode.belongClassVNode = newChild.belongClassVNode;
|
||||||
startDelVNode = getSiblingVNode(resultNode);
|
startDelVNode = getSiblingVNode(resultNode);
|
||||||
resultNode.next = null;
|
resultNode.next = null;
|
||||||
}
|
}
|
||||||
|
@ -560,7 +562,8 @@ function diffObjectNodeHandler(
|
||||||
resultNode = createVNode(Fragment, newChild.key, newChild.props.children);
|
resultNode = createVNode(Fragment, newChild.key, newChild.props.children);
|
||||||
} else {
|
} else {
|
||||||
resultNode = createVNodeFromElement(newChild);
|
resultNode = createVNodeFromElement(newChild);
|
||||||
resultNode.ref = createRef(newChild);
|
resultNode.ref = newChild.ref;
|
||||||
|
resultNode.belongClassVNode = newChild.belongClassVNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (newChild.vtype === TYPE_PORTAL) {
|
} else if (newChild.vtype === TYPE_PORTAL) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ import {
|
||||||
processUpdates,
|
processUpdates,
|
||||||
} from '../UpdateHandler';
|
} from '../UpdateHandler';
|
||||||
import { getContextChangeCtx, setContextChangeCtx } from '../ContextSaver';
|
import { getContextChangeCtx, setContextChangeCtx } from '../ContextSaver';
|
||||||
import ProcessingVNode from '../vnode/ProcessingVNode';
|
import { setProcessingClassVNode } from '../GlobalVar';
|
||||||
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
|
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
|
||||||
|
|
||||||
// 获取当前节点的context
|
// 获取当前节点的context
|
||||||
|
@ -69,7 +69,7 @@ function mountInstance(clazz, processing: VNode, nextProps: object) {
|
||||||
function createChildren(clazz: any, processing: VNode) {
|
function createChildren(clazz: any, processing: VNode) {
|
||||||
markRef(processing);
|
markRef(processing);
|
||||||
|
|
||||||
ProcessingVNode.val = processing;
|
setProcessingClassVNode(processing);
|
||||||
processing.state = processing.realNode.state;
|
processing.state = processing.realNode.state;
|
||||||
|
|
||||||
const inst = processing.realNode;
|
const inst = processing.realNode;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
TYPE_FRAGMENT,
|
TYPE_FRAGMENT,
|
||||||
TYPE_PROFILER,
|
TYPE_PROFILER,
|
||||||
TYPE_STRICT_MODE,
|
TYPE_STRICT_MODE,
|
||||||
} from '../utils/elementType';
|
} from '../../external/JSXElementType';
|
||||||
import {Fragment} from '../vnode/VNodeTags';
|
import {Fragment} from '../vnode/VNodeTags';
|
||||||
|
|
||||||
export function captureRender(processing: VNode, shouldUpdate: boolean): VNode | null {
|
export function captureRender(processing: VNode, shouldUpdate: boolean): VNode | null {
|
||||||
|
|
|
@ -159,13 +159,19 @@ function hideOrUnhideAllChildren(vNode, isHidden) {
|
||||||
|
|
||||||
function attachRef(vNode: VNode) {
|
function attachRef(vNode: VNode) {
|
||||||
const ref = vNode.ref;
|
const ref = vNode.ref;
|
||||||
|
|
||||||
if (ref !== null) {
|
if (ref !== null) {
|
||||||
const instance = vNode.realNode;
|
const instance = vNode.realNode;
|
||||||
|
|
||||||
if (typeof ref === 'function') {
|
let refType = typeof ref;
|
||||||
|
if (refType === 'function') {
|
||||||
ref(instance);
|
ref(instance);
|
||||||
} else {
|
} else if (refType === 'object') {
|
||||||
(<RefType>ref).current = instance;
|
(<RefType>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);
|
let ref = (isOldRef ? vNode.oldRef : vNode.ref);
|
||||||
|
|
||||||
if (ref !== null) {
|
if (ref !== null) {
|
||||||
if (typeof ref === 'function') {
|
let refType = typeof ref;
|
||||||
|
|
||||||
|
if (refType === 'function') {
|
||||||
try {
|
try {
|
||||||
ref(null);
|
ref(null);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleSubmitError(vNode, error);
|
handleSubmitError(vNode, error);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (refType === 'object') {
|
||||||
(<RefType>ref).current = null;
|
(<RefType>ref).current = null;
|
||||||
|
} else {
|
||||||
|
if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) {
|
||||||
|
vNode.belongClassVNode.realNode.refs[String(ref)] = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
callBeforeSubmitLifeCycles, submitDeletion, submitAddition,
|
callBeforeSubmitLifeCycles, submitDeletion, submitAddition,
|
||||||
submitResetTextContent, submitUpdate, detachRef,
|
submitResetTextContent, submitUpdate, detachRef,
|
||||||
} from './LifeCycleHandler';
|
} from './LifeCycleHandler';
|
||||||
import {tryRenderRoot, setProcessing, getStartVNode} from '../TreeBuilder';
|
import {tryRenderRoot, setProcessing} from '../TreeBuilder';
|
||||||
import {
|
import {
|
||||||
BySync,
|
BySync,
|
||||||
InRender,
|
InRender,
|
||||||
|
@ -24,6 +24,7 @@ import {
|
||||||
isSchedulingEffects,
|
isSchedulingEffects,
|
||||||
setSchedulingEffects, setHookEffectRoot,
|
setSchedulingEffects, setHookEffectRoot,
|
||||||
} from './HookEffectHandler';
|
} from './HookEffectHandler';
|
||||||
|
import {getStartVNode} from '../GlobalVar';
|
||||||
|
|
||||||
let rootThrowError = null;
|
let rootThrowError = null;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import type {VNode} from '../Types';
|
|
||||||
|
|
||||||
// 当前所有者是应拥有当前正在构建的任何组件的组件。
|
|
||||||
const ProcessingVNode: { val: VNode | null } = {
|
|
||||||
val: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProcessingVNode;
|
|
|
@ -76,6 +76,8 @@ export class VNode {
|
||||||
path: Array<number> = []; // 保存从根到本节点的路径
|
path: Array<number> = []; // 保存从根到本节点的路径
|
||||||
toUpdateNodes: Set<VNode> | null = null; // 保存要更新的节点
|
toUpdateNodes: Set<VNode> | null = null; // 保存要更新的节点
|
||||||
|
|
||||||
|
belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode,处理ref的时候使用
|
||||||
|
|
||||||
constructor(tag: VNodeTag, props: any, key: null | string, outerDom) {
|
constructor(tag: VNodeTag, props: any, key: null | string, outerDom) {
|
||||||
this.tag = tag; // 对应组件的类型,比如ClassComponent等
|
this.tag = tag; // 对应组件的类型,比如ClassComponent等
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
|
|
@ -24,9 +24,9 @@ import {
|
||||||
TYPE_MEMO, TYPE_PROFILER,
|
TYPE_MEMO, TYPE_PROFILER,
|
||||||
TYPE_PROVIDER, TYPE_STRICT_MODE,
|
TYPE_PROVIDER, TYPE_STRICT_MODE,
|
||||||
TYPE_SUSPENSE,
|
TYPE_SUSPENSE,
|
||||||
} from '../utils/elementType';
|
} from '../../external/JSXElementType';
|
||||||
import { VNode } from './VNode';
|
import { VNode } from './VNode';
|
||||||
import {HorizonElement} from '../Types';
|
import {JSXElement} from '../Types';
|
||||||
|
|
||||||
const typeLazyMap = {
|
const typeLazyMap = {
|
||||||
[TYPE_FORWARD_REF]: ForwardRef,
|
[TYPE_FORWARD_REF]: ForwardRef,
|
||||||
|
@ -156,7 +156,7 @@ export function updateVNodePath(vNode: VNode) {
|
||||||
vNode.path = [...vNode.parent.path, vNode.cIndex];
|
vNode.path = [...vNode.parent.path, vNode.cIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createVNodeFromElement(element: HorizonElement): VNode {
|
export function createVNodeFromElement(element: JSXElement): VNode {
|
||||||
const type = element.type;
|
const type = element.type;
|
||||||
const key = element.key;
|
const key = element.key;
|
||||||
const props = element.props;
|
const props = element.props;
|
||||||
|
|
|
@ -13,7 +13,7 @@ export function getSiblingVNode(node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function travelChildren(beginVNode: VNode, handleVNode: Function, isFinish?: Function) {
|
export function travelChildren(beginVNode: VNode, handleVNode: Function, isFinish?: Function) {
|
||||||
let node = beginVNode;
|
let node: VNode | null = beginVNode;
|
||||||
|
|
||||||
while (node !== null) {
|
while (node !== null) {
|
||||||
if (isFinish && isFinish(node)) {
|
if (isFinish && isFinish(node)) {
|
||||||
|
@ -77,10 +77,6 @@ export function travelVNodeTree(
|
||||||
|
|
||||||
// 置空vNode
|
// 置空vNode
|
||||||
export function clearVNode(vNode: VNode) {
|
export function clearVNode(vNode: VNode) {
|
||||||
clearOneVNode(vNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearOneVNode(vNode: VNode) {
|
|
||||||
vNode.child = null;
|
vNode.child = null;
|
||||||
vNode.next = null;
|
vNode.next = null;
|
||||||
vNode.depContexts = [];
|
vNode.depContexts = [];
|
||||||
|
@ -105,6 +101,8 @@ function clearOneVNode(vNode: VNode) {
|
||||||
|
|
||||||
vNode.path = [];
|
vNode.path = [];
|
||||||
vNode.toUpdateNodes = null;
|
vNode.toUpdateNodes = null;
|
||||||
|
|
||||||
|
vNode.belongClassVNode = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 是dom类型的vNode
|
// 是dom类型的vNode
|
||||||
|
@ -225,7 +223,7 @@ function isSameContainer(
|
||||||
}
|
}
|
||||||
// 注释类型的节点
|
// 注释类型的节点
|
||||||
if (isComment(container) && container.parentNode === targetContainer) {
|
if (isComment(container) && container.parentNode === targetContainer) {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue