Match-id-a177994d0b3fe27dac34cee64bf01b1ba92b9310

This commit is contained in:
* 2022-08-03 18:14:30 +08:00 committed by *
parent e31ed399de
commit eec4863d61
8 changed files with 62 additions and 99 deletions

View File

@ -1,7 +1,7 @@
import {throwIfTrue} from '../renderer/utils/throwIfTrue'; import { throwIfTrue } from '../renderer/utils/throwIfTrue';
import {TYPE_COMMON_ELEMENT, TYPE_PORTAL} from './JSXElementType'; import { TYPE_COMMON_ELEMENT, TYPE_PORTAL } from './JSXElementType';
import {isValidElement, JSXElement} from './JSXElement'; import { isValidElement, JSXElement } from './JSXElement';
// 生成key // 生成key
function getItemKey(item: any, index: number): string { function getItemKey(item: any, index: number): string {
@ -12,12 +12,7 @@ function getItemKey(item: any, index: number): string {
return '.' + index.toString(36); return '.' + index.toString(36);
} }
function mapChildrenToArray( function mapChildrenToArray(children: any, arr: Array<any>, prefix: string, callback?: Function): number | void {
children: any,
arr: Array<any>,
prefix: string,
callback?: Function,
): number | void {
const type = typeof children; const type = typeof children;
switch (type) { switch (type) {
// 继承原有规格undefined和boolean类型按照null处理 // 继承原有规格undefined和boolean类型按照null处理
@ -36,44 +31,27 @@ function mapChildrenToArray(
} }
const vtype = children.vtype; const vtype = children.vtype;
if (vtype === TYPE_COMMON_ELEMENT || vtype === TYPE_PORTAL) { if (vtype === TYPE_COMMON_ELEMENT || vtype === TYPE_PORTAL) {
callMapFun(children, arr, prefix, callback) ; callMapFun(children, arr, prefix, callback);
return; return;
} }
if (Array.isArray(children)) { if (Array.isArray(children)) {
processArrayChildren(children, arr, prefix, callback); processArrayChildren(children, arr, prefix, callback);
return; return;
} }
throw new Error( throw new Error('Object is invalid as a Horizon child. ');
'Object is invalid as a Horizon child. '
);
// No Default // No Default
} }
} }
function processArrayChildren( function processArrayChildren(children: any, arr: Array<any>, prefix: string, callback: Function) {
children: any,
arr: Array<any>,
prefix: string,
callback: Function,
) {
for (let i = 0; i < children.length; i++) { for (let i = 0; i < children.length; i++) {
const childItem = children[i]; const childItem = children[i];
const nextPrefix = prefix + getItemKey(childItem, i); const nextPrefix = prefix + getItemKey(childItem, i);
mapChildrenToArray( mapChildrenToArray(childItem, arr, nextPrefix, callback);
childItem,
arr,
nextPrefix,
callback,
);
} }
} }
function callMapFun( function callMapFun(children: any, arr: Array<any>, prefix: string, callback: Function) {
children: any,
arr: Array<any>,
prefix: string,
callback: Function,
) {
let mappedChild = callback(children); let mappedChild = callback(children);
if (Array.isArray(mappedChild)) { if (Array.isArray(mappedChild)) {
// 维持原有规格如果callback返回结果是数组处理函数修改为返回数组item // 维持原有规格如果callback返回结果是数组处理函数修改为返回数组item
@ -83,9 +61,8 @@ function callMapFun(
if (isValidElement(mappedChild)) { if (isValidElement(mappedChild)) {
const childKey = prefix === '' ? getItemKey(children, 0) : ''; const childKey = prefix === '' ? getItemKey(children, 0) : '';
const mappedKey = getItemKey(mappedChild, 0); const mappedKey = getItemKey(mappedChild, 0);
const newKey = prefix + childKey + (mappedChild.key && mappedKey !== getItemKey(children, 0) const newKey =
? '.$' + mappedChild.key prefix + childKey + (mappedChild.key && mappedKey !== getItemKey(children, 0) ? '.$' + mappedChild.key : '');
: '');
// 返回一个修改key的children // 返回一个修改key的children
mappedChild = JSXElement( mappedChild = JSXElement(
mappedChild.type, mappedChild.type,
@ -93,6 +70,7 @@ function callMapFun(
mappedChild.ref, mappedChild.ref,
mappedChild.belongClassVNode, mappedChild.belongClassVNode,
mappedChild.props, mappedChild.props,
mappedChild.source
); );
} }
arr.push(mappedChild); arr.push(mappedChild);
@ -100,11 +78,7 @@ function callMapFun(
} }
// 在 children 里的每个直接子节点上调用一个函数,并将 this 设置为 thisArg // 在 children 里的每个直接子节点上调用一个函数,并将 this 设置为 thisArg
function mapChildren( function mapChildren(children: any, func: Function, context?: any): Array<any> {
children: any,
func: Function,
context?: any,
): Array<any> {
if (children === null || children === undefined) { if (children === null || children === undefined) {
return children; return children;
} }
@ -121,27 +95,22 @@ const Children = {
}, },
map: mapChildren, map: mapChildren,
// 并非所有元素都会计数,只计数调用callMapFun函数次数 // 并非所有元素都会计数,只计数调用callMapFun函数次数
count: (children) => { count: children => {
let n = 0; let n = 0;
mapChildren(children, () => { mapChildren(children, () => {
n++; n++;
}); });
return n; return n;
}, },
only: (children) => { only: children => {
throwIfTrue( throwIfTrue(!isValidElement(children), 'Horizon.Children.only function received invalid element.');
!isValidElement(children),
'Horizon.Children.only function received invalid element.'
);
return children; return children;
}, },
toArray: (children) => { toArray: children => {
const result = []; const result = [];
mapChildrenToArray(children, result, '', child => child); mapChildrenToArray(children, result, '', child => child);
return result; return result;
}, },
}
export {
Children
}; };
export { Children };

View File

@ -1,5 +1,5 @@
import { TYPE_COMMON_ELEMENT } from './JSXElementType'; import {TYPE_COMMON_ELEMENT} from './JSXElementType';
import { getProcessingClassVNode } from '../renderer/GlobalVar'; import {getProcessingClassVNode} from '../renderer/GlobalVar';
/** /**
@ -31,7 +31,7 @@ function isValidKey(key) {
'key', 'key',
'ref', 'ref',
'__source', '__source',
'__self' '__self',
]; ];
return !keyArray.includes(key); return !keyArray.includes(key);
} }
@ -48,7 +48,7 @@ function buildElement(isClone, type, setting, children) {
// setting中的值优先级最高clone情况下从 type 中取值,创建情况下直接赋值为 null // setting中的值优先级最高clone情况下从 type 中取值,创建情况下直接赋值为 null
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.belongClassVNode : getProcessingClassVNode(); let vNode = isClone ? type.belongClassVNode : getProcessingClassVNode();
if (setting !== null && setting !== undefined) { if (setting !== null && setting !== undefined) {
@ -74,9 +74,7 @@ function buildElement(isClone, type, setting, children) {
mergeDefault(props, element.defaultProps); mergeDefault(props, element.defaultProps);
} }
const source = setting?.__source === undefined ? null : setting.__source; return JSXElement(element, key, ref, vNode, props, setting?.__source ?? null);
return JSXElement(element, key, ref, vNode, props, source);
} }
// 创建Element结构体供JSX编译时调用 // 创建Element结构体供JSX编译时调用

View File

@ -1,11 +1,11 @@
import { travelVNodeTree } from '../renderer/vnode/VNodeUtils'; import {travelVNodeTree} from '../renderer/vnode/VNodeUtils';
import { Hook, Reducer, Ref, Effect, CallBack, Memo } from '../renderer/hooks/HookType'; import {Hook, Reducer, Ref, Effect, CallBack, Memo} from '../renderer/hooks/HookType';
import { VNode } from '../renderer/vnode/VNode'; import {VNode} from '../renderer/vnode/VNode';
import { launchUpdateFromVNode } from '../renderer/TreeBuilder'; import {launchUpdateFromVNode} from '../renderer/TreeBuilder';
import { DomComponent } from '../renderer/vnode/VNodeTags'; import {DomComponent} from '../renderer/vnode/VNodeTags';
import { getElementTag } from '../renderer/vnode/VNodeCreator'; import {getElementTag} from '../renderer/vnode/VNodeCreator';
import { JSXElement } from '../renderer/Types'; import {JSXElement} from '../renderer/Types';
import { EffectConstant } from '../renderer/hooks/EffectConstant'; import {EffectConstant} from '../renderer/hooks/EffectConstant';
const isEffectHook = (state: any): state is Effect => !!state.effect; const isEffectHook = (state: any): state is Effect => !!state.effect;
const isRefHook = (state: any): state is Ref<any> => Object.prototype.hasOwnProperty.call(state, 'current'); const isRefHook = (state: any): state is Ref<any> => Object.prototype.hasOwnProperty.call(state, 'current');
@ -28,23 +28,23 @@ export const helper = {
}, },
// 获取 hook 名hIndex值和存储的值 // 获取 hook 名hIndex值和存储的值
getHookInfo: (hook: Hook<any, any>) => { getHookInfo: (hook: Hook<any, any>) => {
const { hIndex, state } = hook; const {hIndex, state} = hook;
if ((state as Reducer<any, any>).trigger) { if ((state as Reducer<any, any>).trigger) {
if ((state as Reducer<any, any>).isUseState) { if ((state as Reducer<any, any>).isUseState) {
return { name: HookName.StateHook, hIndex, value: (state as Reducer<any, any>).stateValue }; return {name: HookName.StateHook, hIndex, value: (state as Reducer<any, any>).stateValue};
} else if ((state as Reducer<any, any>).reducer) { } else if ((state as Reducer<any, any>).reducer) {
return { name: HookName.ReducerHook, hIndex, value: (state as Reducer<any, any>).stateValue }; return {name: HookName.ReducerHook, hIndex, value: (state as Reducer<any, any>).stateValue};
} }
} else if (isRefHook(state)) { } else if (isRefHook(state)) {
return { name: HookName.RefHook, hIndex, value: (state as Ref<any>).current }; return {name: HookName.RefHook, hIndex, value: (state as Ref<any>).current};
} else if (isEffectHook(state)) { } else if (isEffectHook(state)) {
const name = const name =
state.effectConstant == EffectConstant.LayoutEffect ? HookName.LayoutEffectHook : HookName.EffectHook; state.effectConstant == EffectConstant.LayoutEffect ? HookName.LayoutEffectHook : HookName.EffectHook;
return { name, hIndex, value: (state as Effect).effect }; return {name, hIndex, value: (state as Effect).effect};
} else if (isCallbackHook(state)) { } else if (isCallbackHook(state)) {
return { name: HookName.CallbackHook, hIndex, value: (state as CallBack<any>).func }; return {name: HookName.CallbackHook, hIndex, value: (state as CallBack<any>).func};
} else if (isMemoHook(state)) { } else if (isMemoHook(state)) {
return { name: HookName.MemoHook, hIndex, value: (state as Memo<any>).result }; return {name: HookName.MemoHook, hIndex, value: (state as Memo<any>).result};
} }
return null; return null;
}, },
@ -70,7 +70,7 @@ export const helper = {
} }
}, },
getComponentInfo: (vNode: VNode) => { getComponentInfo: (vNode: VNode) => {
const { props, state, hooks } = vNode; const {props, state, hooks} = vNode;
const info: any = {}; const info: any = {};
if (props && Object.keys(props).length !== 0) { if (props && Object.keys(props).length !== 0) {
info['Props'] = props; info['Props'] = props;
@ -98,11 +98,7 @@ export const helper = {
return true; return true;
} }
return false; return false;
}, }, null, vNode, null);
null,
vNode,
null
);
return info; return info;
}, },
getElementTag: (element: JSXElement) => { getElementTag: (element: JSXElement) => {

View File

@ -27,8 +27,8 @@ export type ProviderType<T> = {
export type ContextType<T> = { export type ContextType<T> = {
vtype: number; vtype: number;
Consumer: ContextType<T>; Consumer: ContextType<T> | null;
Provider: ProviderType<T>; Provider: ProviderType<T> | null;
value: T; value: T;
}; };

View File

@ -26,7 +26,7 @@ export function captureMemoComponent(
if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) { if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) {
newChild = createFragmentVNode(null, newProps.children); newChild = createFragmentVNode(null, newProps.children);
} else { } else {
newChild = createUndeterminedVNode(type, null, newProps); newChild = createUndeterminedVNode(type, null, newProps,processing.src);
} }
newChild.parent = processing; newChild.parent = processing;
newChild.ref = processing.ref; newChild.ref = processing.ref;

View File

@ -17,10 +17,10 @@ import {
Profiler, Profiler,
MemoComponent, MemoComponent,
} from './VNodeTags'; } from './VNodeTags';
import type { VNodeTag } from './VNodeTags'; import type {VNodeTag} from './VNodeTags';
import type { RefType, ContextType, SuspenseState, Source } from '../Types'; import type {RefType, ContextType, SuspenseState, Source} from '../Types';
import type { Hook } from '../hooks/HookType'; import type {Hook} from '../hooks/HookType';
import { InitFlag } from './VNodeFlags'; import {InitFlag} from './VNodeFlags';
export class VNode { export class VNode {
tag: VNodeTag; tag: VNodeTag;
@ -77,8 +77,8 @@ export class VNode {
// 根节点数据 // 根节点数据
toUpdateNodes: Set<VNode> | null; // 保存要更新的节点 toUpdateNodes: Set<VNode> | null; // 保存要更新的节点
delegatedEvents: Set<string> delegatedEvents: Set<string>;
delegatedNativeEvents: Set<string> delegatedNativeEvents: Set<string>;
belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode处理ref的时候使用 belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode处理ref的时候使用
@ -86,7 +86,7 @@ export class VNode {
isStoreChange: boolean; isStoreChange: boolean;
observers: Set<any> | null = null; // 记录这个函数组件/类组件依赖哪些Observer observers: Set<any> | null = null; // 记录这个函数组件/类组件依赖哪些Observer
classComponentWillUnmount: Function | null; // HorizonX会在classComponentWillUnmount中清除对VNode的引入用 classComponentWillUnmount: Function | null; // HorizonX会在classComponentWillUnmount中清除对VNode的引入用
source: Source | null; // 节点所在代码位置 src: Source | null; // 节点所在代码位置
constructor(tag: VNodeTag, props: any, key: null | string, realNode) { constructor(tag: VNodeTag, props: any, key: null | string, realNode) {
this.tag = tag; // 对应组件的类型比如ClassComponent等 this.tag = tag; // 对应组件的类型比如ClassComponent等
@ -117,7 +117,7 @@ export class VNode {
this.isStoreChange = false; this.isStoreChange = false;
this.observers = null; this.observers = null;
this.classComponentWillUnmount = null; this.classComponentWillUnmount = null;
this.source = null; this.src = null;
break; break;
case ClassComponent: case ClassComponent:
this.realNode = null; this.realNode = null;
@ -132,18 +132,18 @@ export class VNode {
this.isStoreChange = false; this.isStoreChange = false;
this.observers = null; this.observers = null;
this.classComponentWillUnmount = null; this.classComponentWillUnmount = null;
this.source = null; this.src = null;
break; break;
case DomPortal: case DomPortal:
this.realNode = null; this.realNode = null;
this.context = null; this.context = null;
this.source = null; this.src = null;
break; break;
case DomComponent: case DomComponent:
this.realNode = null; this.realNode = null;
this.changeList = null; this.changeList = null;
this.context = null; this.context = null;
this.source = null; this.src = null;
break; break;
case DomText: case DomText:
this.realNode = null; this.realNode = null;
@ -155,17 +155,17 @@ export class VNode {
didCapture: false, didCapture: false,
promiseResolved: false, promiseResolved: false,
oldChildStatus: '', oldChildStatus: '',
childStatus: '' childStatus: '',
}; };
this.source = null; this.src = null;
break; break;
case ContextProvider: case ContextProvider:
this.source = null; this.src = null;
this.context = null; this.context = null;
break; break;
case MemoComponent: case MemoComponent:
this.effectList = null; this.effectList = null;
this.source = null; this.src = null;
break; break;
case LazyComponent: case LazyComponent:
this.realNode = null; this.realNode = null;
@ -173,7 +173,7 @@ export class VNode {
this.isLazyComponent = true; this.isLazyComponent = true;
this.lazyType = null; this.lazyType = null;
this.updates = null; this.updates = null;
this.source = null; this.src = null;
break; break;
case Fragment: case Fragment:
break; break;

View File

@ -132,7 +132,7 @@ export function createUndeterminedVNode(type, key, props, source) {
if (isLazy) { if (isLazy) {
vNode.lazyType = type; vNode.lazyType = type;
} }
vNode.source = source; vNode.src = source;
return vNode; return vNode;
} }

View File

@ -37,7 +37,7 @@
"@babel/plugin-transform-shorthand-properties": "7.16.7", "@babel/plugin-transform-shorthand-properties": "7.16.7",
"@babel/plugin-transform-spread": "7.16.7", "@babel/plugin-transform-spread": "7.16.7",
"@babel/plugin-transform-template-literals": "7.16.7", "@babel/plugin-transform-template-literals": "7.16.7",
"@babel/plugin-transform-react-jsx-source": "^7.18.6", "@babel/plugin-transform-react-jsx-source": "^7.16.7",
"@babel/preset-env": "7.16.7", "@babel/preset-env": "7.16.7",
"@babel/preset-react": "7.16.7", "@babel/preset-react": "7.16.7",
"@babel/preset-typescript": "7.16.7", "@babel/preset-typescript": "7.16.7",