Match-id-6ca59de3cf86b4a09201bae1b847ec3778c100c8
This commit is contained in:
commit
09831eef5c
|
@ -73,6 +73,7 @@ function isInDocument(dom) {
|
||||||
if (dom && dom.ownerDocument) {
|
if (dom && dom.ownerDocument) {
|
||||||
return isNodeContainsByTargetNode(dom.ownerDocument.documentElement, dom);
|
return isNodeContainsByTargetNode(dom.ownerDocument.documentElement, dom);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断一个标签是否有设置选择范围的能力
|
// 判断一个标签是否有设置选择范围的能力
|
||||||
|
|
|
@ -34,12 +34,12 @@ export function watchValueChange(dom) {
|
||||||
// currentVal存储最新值,并重写value的setter、getter
|
// currentVal存储最新值,并重写value的setter、getter
|
||||||
let currentVal = String(dom[keyForValue]);
|
let currentVal = String(dom[keyForValue]);
|
||||||
|
|
||||||
const setFunc = descriptor.set;
|
const setFunc = descriptor?.set;
|
||||||
Object.defineProperty(dom, keyForValue, {
|
Object.defineProperty(dom, keyForValue, {
|
||||||
...descriptor,
|
...descriptor,
|
||||||
set: function (value) {
|
set: function(value) {
|
||||||
currentVal = String(value);
|
currentVal = String(value);
|
||||||
setFunc.apply(this, [value]);
|
setFunc?.apply(this, [value]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -12,45 +12,6 @@ function getItemKey(item: any, index: number): string {
|
||||||
return '.' + index.toString(36);
|
return '.' + index.toString(36);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapChildrenToArray(
|
|
||||||
children: any,
|
|
||||||
arr: Array<any>,
|
|
||||||
prefix: string,
|
|
||||||
callback?: Function,
|
|
||||||
): number | void {
|
|
||||||
const type = typeof children;
|
|
||||||
switch (type) {
|
|
||||||
// 继承原有规格,undefined和boolean类型按照null处理
|
|
||||||
case 'undefined':
|
|
||||||
case 'boolean':
|
|
||||||
callMapFun(null, arr, prefix, callback);
|
|
||||||
return;
|
|
||||||
case 'number':
|
|
||||||
case 'string':
|
|
||||||
callMapFun(children, arr, prefix, callback);
|
|
||||||
return;
|
|
||||||
case 'object':
|
|
||||||
if (children === null) {
|
|
||||||
callMapFun(null, arr, prefix, callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const vtype = children.vtype;
|
|
||||||
if (vtype === TYPE_COMMON_ELEMENT || vtype === TYPE_PORTAL) {
|
|
||||||
callMapFun(children, arr, prefix, callback) ;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Array.isArray(children)) {
|
|
||||||
processArrayChildren(children, arr, prefix, callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new Error(
|
|
||||||
'Object is invalid as a Horizon child. '
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function processArrayChildren(
|
function processArrayChildren(
|
||||||
children: any,
|
children: any,
|
||||||
arr: Array<any>,
|
arr: Array<any>,
|
||||||
|
@ -100,6 +61,44 @@ function callMapFun(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapChildrenToArray(
|
||||||
|
children: any,
|
||||||
|
arr: Array<any>,
|
||||||
|
prefix: string,
|
||||||
|
callback?: Function,
|
||||||
|
): number | void {
|
||||||
|
const type = typeof children;
|
||||||
|
switch (type) {
|
||||||
|
// 继承原有规格,undefined和boolean类型按照null处理
|
||||||
|
case 'undefined':
|
||||||
|
case 'boolean':
|
||||||
|
callMapFun(null, arr, prefix, callback);
|
||||||
|
return;
|
||||||
|
case 'number':
|
||||||
|
case 'string':
|
||||||
|
callMapFun(children, arr, prefix, callback);
|
||||||
|
return;
|
||||||
|
case 'object':
|
||||||
|
if (children === null) {
|
||||||
|
callMapFun(null, arr, prefix, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const vtype = children.vtype;
|
||||||
|
if (vtype === TYPE_COMMON_ELEMENT || vtype === TYPE_PORTAL) {
|
||||||
|
callMapFun(children, arr, prefix, callback) ;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Array.isArray(children)) {
|
||||||
|
processArrayChildren(children, arr, prefix, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
'Object is invalid as a Horizon child. '
|
||||||
|
);
|
||||||
|
// No Default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 在 children 里的每个直接子节点上调用一个函数,并将 this 设置为 thisArg
|
// 在 children 里的每个直接子节点上调用一个函数,并将 this 设置为 thisArg
|
||||||
function mapChildren(
|
function mapChildren(
|
||||||
children: any,
|
children: any,
|
||||||
|
@ -111,9 +110,7 @@ function mapChildren(
|
||||||
}
|
}
|
||||||
let count = 0;
|
let count = 0;
|
||||||
const result = [];
|
const result = [];
|
||||||
mapChildrenToArray(children, result, '', (child) => {
|
mapChildrenToArray(children, result, '', child => func.call(context, child, count++));
|
||||||
return func.call(context, child, count++);
|
|
||||||
});
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,20 @@ export function JSXElement(type, key, ref, vNode, props) {
|
||||||
// 所属的class组件
|
// 所属的class组件
|
||||||
belongClassVNode: vNode,
|
belongClassVNode: vNode,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
function isValidKey(key) {
|
function isValidKey(key) {
|
||||||
return key !== 'key' && key !== 'ref' && key !== '__source';
|
return key !== 'key' && key !== 'ref' && key !== '__source';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mergeDefault(sourceObj, defaultObj) {
|
||||||
|
Object.keys(defaultObj).forEach((key) => {
|
||||||
|
if (sourceObj[key] === undefined) {
|
||||||
|
sourceObj[key] = defaultObj[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function buildElement(isClone, type, setting, ...children) {
|
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);
|
||||||
|
@ -64,14 +72,6 @@ export function createElement(type, setting, ...children) {
|
||||||
return buildElement(false, type, setting, ...children);
|
return buildElement(false, type, setting, ...children);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeDefault(sourceObj, defaultObj) {
|
|
||||||
Object.keys(defaultObj).forEach((key) => {
|
|
||||||
if (sourceObj[key] === undefined) {
|
|
||||||
sourceObj[key] = defaultObj[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cloneElement(element, setting, ...children) {
|
export function cloneElement(element, setting, ...children) {
|
||||||
return buildElement(true, element, setting, ...children);
|
return buildElement(true, element, setting, ...children);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ export function startUpdate(
|
||||||
launchUpdateFromVNode(treeRoot);
|
launchUpdateFromVNode(treeRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFirstCustomDom(treeRoot: VNode): Element | Text | null {
|
export function getFirstCustomDom(treeRoot?: VNode | null): Element | Text | null {
|
||||||
if (treeRoot?.child) {
|
if (treeRoot?.child) {
|
||||||
return treeRoot.child.realNode;
|
return treeRoot.child.realNode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,7 @@ export function tryRenderRoot(treeRoot: VNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发起更新
|
// 发起更新
|
||||||
export function launchUpdateFromVNode(vNode: VNode): null | void {
|
export function launchUpdateFromVNode(vNode: VNode) {
|
||||||
// 检查循环调用
|
// 检查循环调用
|
||||||
checkLoopingUpdateLimit();
|
checkLoopingUpdateLimit();
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ export function launchUpdateFromVNode(vNode: VNode): null | void {
|
||||||
if (treeRoot === null) {
|
if (treeRoot === null) {
|
||||||
// 可能场景是:the componentWillUnmount method 或 useEffect cleanup function 方法中写异步任务,并且修改state。
|
// 可能场景是:the componentWillUnmount method 或 useEffect cleanup function 方法中写异步任务,并且修改state。
|
||||||
// 因为异步回调的时候root都可能被清除了。
|
// 因为异步回调的时候root都可能被清除了。
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存待刷新的节点
|
// 保存待刷新的节点
|
||||||
|
|
|
@ -31,9 +31,9 @@ function useEffect(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stage === HookStage.Init) {
|
if (stage === HookStage.Init) {
|
||||||
return useEffectForInit(effectFunc, deps, effectType);
|
useEffectForInit(effectFunc, deps, effectType);
|
||||||
} else if (stage === HookStage.Update) {
|
} else if (stage === HookStage.Update) {
|
||||||
return useEffectForUpdate(effectFunc, deps, effectType);
|
useEffectForUpdate(effectFunc, deps, effectType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,32 @@ import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||||
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
||||||
import componentRenders from './index';
|
import componentRenders from './index';
|
||||||
|
|
||||||
|
// 复用vNode时,也需对stack进行处理
|
||||||
|
function handlerContext(processing: VNode) {
|
||||||
|
switch (processing.tag) {
|
||||||
|
case TreeRoot:
|
||||||
|
setNamespaceCtx(processing, processing.outerDom);
|
||||||
|
break;
|
||||||
|
case DomComponent:
|
||||||
|
setNamespaceCtx(processing);
|
||||||
|
break;
|
||||||
|
case ClassComponent: {
|
||||||
|
const isOldCxtExist = isOldProvider(processing.type);
|
||||||
|
cacheOldCtx(processing, isOldCxtExist);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DomPortal:
|
||||||
|
setNamespaceCtx(processing, processing.outerDom);
|
||||||
|
break;
|
||||||
|
case ContextProvider: {
|
||||||
|
const newValue = processing.props.value;
|
||||||
|
setContextCtx(processing, newValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// No Default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function captureVNode(processing: VNode): VNode | null {
|
export function captureVNode(processing: VNode): VNode | null {
|
||||||
const component = componentRenders[processing.tag];
|
const component = componentRenders[processing.tag];
|
||||||
|
|
||||||
|
@ -38,31 +64,6 @@ export function captureVNode(processing: VNode): VNode | null {
|
||||||
return component.captureRender(processing, shouldUpdate);
|
return component.captureRender(processing, shouldUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 复用vNode时,也需对stack进行处理
|
|
||||||
function handlerContext(processing: VNode) {
|
|
||||||
switch (processing.tag) {
|
|
||||||
case TreeRoot:
|
|
||||||
setNamespaceCtx(processing, processing.outerDom);
|
|
||||||
break;
|
|
||||||
case DomComponent:
|
|
||||||
setNamespaceCtx(processing);
|
|
||||||
break;
|
|
||||||
case ClassComponent: {
|
|
||||||
const isOldCxtExist = isOldProvider(processing.type);
|
|
||||||
cacheOldCtx(processing, isOldCxtExist);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DomPortal:
|
|
||||||
setNamespaceCtx(processing, processing.outerDom);
|
|
||||||
break;
|
|
||||||
case ContextProvider: {
|
|
||||||
const newValue = processing.props.value;
|
|
||||||
setContextCtx(processing, newValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建孩子节点
|
// 创建孩子节点
|
||||||
export function createVNodeChildren(processing: VNode, nextChildren: any) {
|
export function createVNodeChildren(processing: VNode, nextChildren: any) {
|
||||||
const isComparing = !processing.isCreated;
|
const isComparing = !processing.isCreated;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import {
|
||||||
markComponentDidUpdate,
|
markComponentDidUpdate,
|
||||||
markGetSnapshotBeforeUpdate,
|
markGetSnapshotBeforeUpdate,
|
||||||
} from './class/ClassLifeCycleProcessor';
|
} from './class/ClassLifeCycleProcessor';
|
||||||
import {FlagUtils} from '../vnode/VNodeFlags';
|
import { FlagUtils } from '../vnode/VNodeFlags';
|
||||||
import { createVNodeChildren, markRef } from './BaseComponent';
|
import { createVNodeChildren, markRef } from './BaseComponent';
|
||||||
import {
|
import {
|
||||||
createUpdateArray,
|
createUpdateArray,
|
||||||
|
@ -30,23 +30,78 @@ import { getContextChangeCtx, setContextChangeCtx } from '../ContextSaver';
|
||||||
import { setProcessingClassVNode } from '../GlobalVar';
|
import { setProcessingClassVNode } from '../GlobalVar';
|
||||||
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
|
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
|
||||||
|
|
||||||
export function captureRender(processing: VNode): VNode | null {
|
// 获取当前节点的context
|
||||||
const clazz = processing.type;
|
export function getCurrentContext(clazz, processing: VNode) {
|
||||||
const props = processing.props;
|
const context = clazz.contextType;
|
||||||
const nextProps = processing.isLazyComponent ? mergeDefaultProps(clazz, props) : props;
|
return typeof context === 'object' && context !== null
|
||||||
return captureClassComponent(processing, clazz, nextProps);
|
? getNewContext(processing, context)
|
||||||
|
: getOldContext(processing, clazz, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bubbleRender(processing: VNode) {
|
// 挂载实例
|
||||||
if (isOldProvider(processing.type)) {
|
function mountInstance(clazz, processing: VNode, nextProps: object) {
|
||||||
resetOldCtx(processing);
|
if (!processing.isCreated) {
|
||||||
|
processing.isCreated = true;
|
||||||
|
FlagUtils.markAddition(processing);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造实例
|
||||||
|
callConstructor(processing, clazz, nextProps);
|
||||||
|
|
||||||
|
const inst = processing.realNode;
|
||||||
|
inst.props = nextProps;
|
||||||
|
inst.state = processing.state;
|
||||||
|
inst.context = getCurrentContext(clazz, processing);
|
||||||
|
inst.refs = {};
|
||||||
|
|
||||||
|
createUpdateArray(processing);
|
||||||
|
processUpdates(processing, inst, nextProps);
|
||||||
|
inst.state = processing.state;
|
||||||
|
|
||||||
|
// 在调用类组建的渲染方法之前调用 并且在初始挂载及后续更新时都会被调用
|
||||||
|
callDerivedStateFromProps(processing, clazz.getDerivedStateFromProps, nextProps);
|
||||||
|
callComponentWillMount(processing, inst, nextProps);
|
||||||
|
|
||||||
|
markComponentDidMount(processing);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建子节点
|
||||||
|
function createChildren(clazz: any, processing: VNode) {
|
||||||
|
markRef(processing);
|
||||||
|
|
||||||
|
ProcessingVNode.val = processing;
|
||||||
|
processing.state = processing.realNode.state;
|
||||||
|
|
||||||
|
const inst = processing.realNode;
|
||||||
|
const isCatchError = processing.flags.DidCapture;
|
||||||
|
|
||||||
|
// 按照已有规格,如果捕获了错误却没有定义getDerivedStateFromError函数,返回的child为null
|
||||||
|
const newElements = isCatchError && typeof clazz.getDerivedStateFromError !== 'function'
|
||||||
|
? null
|
||||||
|
: inst.render();
|
||||||
|
|
||||||
|
processing.child = createVNodeChildren(processing, newElements);
|
||||||
|
return processing.child;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据isUpdateComponent,执行不同的生命周期
|
||||||
|
function callUpdateLifeCycle(processing: VNode, nextProps: object, clazz) {
|
||||||
|
const inst = processing.realNode;
|
||||||
|
const newContext = getCurrentContext(clazz, processing);
|
||||||
|
if (processing.isCreated) {
|
||||||
|
callComponentWillMount(processing, inst);
|
||||||
|
} else {
|
||||||
|
callComponentWillUpdate(inst, nextProps, processing.state, newContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于未完成的类组件
|
function markLifeCycle(processing: VNode, nextProps: object, shouldUpdate: Boolean) {
|
||||||
export function getIncompleteClassComponent(clazz, processing: VNode, nextProps: object):VNode | null {
|
if (processing.isCreated) {
|
||||||
mountInstance(clazz, processing, nextProps);
|
markComponentDidMount(processing);
|
||||||
return createChildren(clazz, processing);
|
} else if (processing.state !== processing.oldState || shouldUpdate) {
|
||||||
|
markComponentDidUpdate(processing);
|
||||||
|
markGetSnapshotBeforeUpdate(processing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于类组件
|
// 用于类组件
|
||||||
|
@ -127,77 +182,21 @@ export function captureClassComponent(processing: VNode, clazz: any, nextProps:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 挂载实例
|
export function captureRender(processing: VNode): VNode | null {
|
||||||
function mountInstance(clazz, processing: VNode, nextProps: object) {
|
const clazz = processing.type;
|
||||||
if (!processing.isCreated) {
|
const props = processing.props;
|
||||||
processing.isCreated = true;
|
const nextProps = processing.isLazyComponent ? mergeDefaultProps(clazz, props) : props;
|
||||||
FlagUtils.markAddition(processing);
|
return captureClassComponent(processing, clazz, nextProps);
|
||||||
}
|
|
||||||
|
|
||||||
// 构造实例
|
|
||||||
callConstructor(processing, clazz, nextProps);
|
|
||||||
|
|
||||||
const inst = processing.realNode;
|
|
||||||
inst.props = nextProps;
|
|
||||||
inst.state = processing.state;
|
|
||||||
inst.context = getCurrentContext(clazz, processing);
|
|
||||||
inst.refs = {};
|
|
||||||
|
|
||||||
createUpdateArray(processing);
|
|
||||||
processUpdates(processing, inst, nextProps);
|
|
||||||
inst.state = processing.state;
|
|
||||||
|
|
||||||
// 在调用类组建的渲染方法之前调用 并且在初始挂载及后续更新时都会被调用
|
|
||||||
callDerivedStateFromProps(processing, clazz.getDerivedStateFromProps, nextProps);
|
|
||||||
callComponentWillMount(processing, inst, nextProps);
|
|
||||||
|
|
||||||
markComponentDidMount(processing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建子节点
|
export function bubbleRender(processing: VNode) {
|
||||||
function createChildren(clazz: any, processing: VNode) {
|
if (isOldProvider(processing.type)) {
|
||||||
markRef(processing);
|
resetOldCtx(processing);
|
||||||
|
|
||||||
setProcessingClassVNode(processing);
|
|
||||||
|
|
||||||
processing.state = processing.realNode.state;
|
|
||||||
|
|
||||||
const inst = processing.realNode;
|
|
||||||
const isCatchError = processing.flags.DidCapture;
|
|
||||||
|
|
||||||
// 按照已有规格,如果捕获了错误却没有定义getDerivedStateFromError函数,返回的child为null
|
|
||||||
const newElements = (isCatchError && typeof clazz.getDerivedStateFromError !== 'function')
|
|
||||||
? null
|
|
||||||
: inst.render();
|
|
||||||
|
|
||||||
processing.child = createVNodeChildren(processing, newElements);
|
|
||||||
return processing.child;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前节点的context
|
|
||||||
export function getCurrentContext(clazz, processing: VNode) {
|
|
||||||
const context = clazz.contextType;
|
|
||||||
return typeof context === 'object' && context !== null
|
|
||||||
? getNewContext(processing, context)
|
|
||||||
: getOldContext(processing, clazz, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据isUpdateComponent,执行不同的生命周期
|
|
||||||
function callUpdateLifeCycle(processing: VNode, nextProps: object, clazz) {
|
|
||||||
const inst = processing.realNode;
|
|
||||||
const newContext = getCurrentContext(clazz, processing);
|
|
||||||
if (processing.isCreated) {
|
|
||||||
callComponentWillMount(processing, inst);
|
|
||||||
} else {
|
|
||||||
callComponentWillUpdate(inst, nextProps, processing.state, newContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function markLifeCycle(processing: VNode, nextProps: object, shouldUpdate: Boolean) {
|
// 用于未完成的类组件
|
||||||
if (processing.isCreated) {
|
export function getIncompleteClassComponent(clazz, processing: VNode, nextProps: object): VNode | null {
|
||||||
markComponentDidMount(processing);
|
mountInstance(clazz, processing, nextProps);
|
||||||
} else if (processing.state !== processing.oldState || shouldUpdate) {
|
return createChildren(clazz, processing);
|
||||||
markComponentDidUpdate(processing);
|
|
||||||
markGetSnapshotBeforeUpdate(processing);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,8 @@ import {FlagUtils} from '../vnode/VNodeFlags';
|
||||||
import {exeFunctionHook} from '../hooks/HookMain';
|
import {exeFunctionHook} from '../hooks/HookMain';
|
||||||
import {createVNodeChildren} from './BaseComponent';
|
import {createVNodeChildren} from './BaseComponent';
|
||||||
|
|
||||||
export function captureRender(processing: VNode): VNode | null {
|
|
||||||
return captureIndeterminateComponent(processing);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function bubbleRender() {}
|
|
||||||
|
|
||||||
function captureIndeterminateComponent(
|
function captureIndeterminateComponent(
|
||||||
processing: VNode | null,
|
processing: VNode,
|
||||||
): VNode | null {
|
): VNode | null {
|
||||||
const funcComp = processing.type;
|
const funcComp = processing.type;
|
||||||
|
|
||||||
|
@ -34,3 +28,9 @@ function captureIndeterminateComponent(
|
||||||
processing.child = createVNodeChildren(processing, newElements);
|
processing.child = createVNodeChildren(processing, newElements);
|
||||||
return processing.child;
|
return processing.child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function captureRender(processing: VNode): VNode | null {
|
||||||
|
return captureIndeterminateComponent(processing);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bubbleRender() {}
|
||||||
|
|
|
@ -3,12 +3,6 @@ import type {VNode, ContextType} from '../Types';
|
||||||
import {resetDepContexts, getNewContext} from '../components/context/Context';
|
import {resetDepContexts, getNewContext} from '../components/context/Context';
|
||||||
import {createVNodeChildren} from './BaseComponent';
|
import {createVNodeChildren} from './BaseComponent';
|
||||||
|
|
||||||
export function captureRender(processing: VNode): VNode | null {
|
|
||||||
return captureContextConsumer(processing);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function bubbleRender() {}
|
|
||||||
|
|
||||||
function captureContextConsumer(processing: VNode) {
|
function captureContextConsumer(processing: VNode) {
|
||||||
const context: ContextType<any> = processing.type;
|
const context: ContextType<any> = processing.type;
|
||||||
const props = processing.props;
|
const props = processing.props;
|
||||||
|
@ -21,3 +15,10 @@ function captureContextConsumer(processing: VNode) {
|
||||||
processing.child = createVNodeChildren(processing, newChildren);
|
processing.child = createVNodeChildren(processing, newChildren);
|
||||||
return processing.child;
|
return processing.child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function captureRender(processing: VNode): VNode | null {
|
||||||
|
return captureContextConsumer(processing);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bubbleRender() {}
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,30 @@ import {launchUpdateFromVNode} from '../TreeBuilder';
|
||||||
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
||||||
import {setParentsChildShouldUpdate} from '../vnode/VNodeShouldUpdate';
|
import {setParentsChildShouldUpdate} from '../vnode/VNodeShouldUpdate';
|
||||||
|
|
||||||
export function captureRender(processing: VNode): VNode | null {
|
// 从当前子节点开始向下遍历,找到消费此context的组件,并更新
|
||||||
return captureContextProvider(processing);
|
function handleContextChange(processing: VNode, context: ContextType<any>): void {
|
||||||
}
|
const vNode = processing.child;
|
||||||
|
if (vNode === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
export function bubbleRender(processing: VNode) {
|
let isMatch = false;
|
||||||
resetContextCtx(processing);
|
|
||||||
|
// 从vNode开始遍历
|
||||||
|
travelVNodeTree(vNode, (node) => {
|
||||||
|
const depContexts = node.depContexts;
|
||||||
|
if (depContexts.length) {
|
||||||
|
isMatch = matchDependencies(depContexts, context, node) ?? isMatch;
|
||||||
|
}
|
||||||
|
}, (node) => {
|
||||||
|
// 如果这是匹配的provider,则不要更深入地扫描
|
||||||
|
return node.tag === ContextProvider && node.type === processing.type;
|
||||||
|
}, processing);
|
||||||
|
|
||||||
|
// 找到了依赖context的子节点,触发一次更新
|
||||||
|
if (isMatch) {
|
||||||
|
launchUpdateFromVNode(processing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function captureContextProvider(processing: VNode): VNode | null {
|
function captureContextProvider(processing: VNode): VNode | null {
|
||||||
|
@ -54,6 +72,14 @@ function captureContextProvider(processing: VNode): VNode | null {
|
||||||
return processing.child;
|
return processing.child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function captureRender(processing: VNode): VNode | null {
|
||||||
|
return captureContextProvider(processing);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bubbleRender(processing: VNode) {
|
||||||
|
resetContextCtx(processing);
|
||||||
|
}
|
||||||
|
|
||||||
// 从依赖中找到匹配context的VNode
|
// 从依赖中找到匹配context的VNode
|
||||||
function matchDependencies(depContexts, context, vNode): boolean {
|
function matchDependencies(depContexts, context, vNode): boolean {
|
||||||
for (let i = 0; i < depContexts.length; i++) {
|
for (let i = 0; i < depContexts.length; i++) {
|
||||||
|
@ -77,29 +103,3 @@ function matchDependencies(depContexts, context, vNode): boolean {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从当前子节点开始向下遍历,找到消费此context的组件,并更新
|
|
||||||
function handleContextChange(processing: VNode, context: ContextType<any>): void {
|
|
||||||
const vNode = processing.child;
|
|
||||||
if (vNode === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let isMatch = false;
|
|
||||||
|
|
||||||
// 从vNode开始遍历
|
|
||||||
travelVNodeTree(vNode, (node) => {
|
|
||||||
const depContexts = node.depContexts;
|
|
||||||
if (depContexts.length) {
|
|
||||||
isMatch = matchDependencies(depContexts, context, node) ?? isMatch;
|
|
||||||
}
|
|
||||||
}, (node) => {
|
|
||||||
// 如果这是匹配的provider,则不要更深入地扫描
|
|
||||||
return node.tag === ContextProvider && node.type === processing.type;
|
|
||||||
}, processing);
|
|
||||||
|
|
||||||
// 找到了依赖context的子节点,触发一次更新
|
|
||||||
if (isMatch) {
|
|
||||||
launchUpdateFromVNode(processing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
import type {VNode} from '../Types';
|
import type { VNode } from '../Types';
|
||||||
|
|
||||||
import {FlagUtils} from '../vnode/VNodeFlags';
|
import { FlagUtils } from '../vnode/VNodeFlags';
|
||||||
import {getLazyVNodeTag} from '../vnode/VNodeCreator';
|
import { getLazyVNodeTag } from '../vnode/VNodeCreator';
|
||||||
import {
|
import {
|
||||||
ClassComponent,
|
ClassComponent,
|
||||||
ForwardRef,
|
ForwardRef,
|
||||||
FunctionComponent,
|
FunctionComponent,
|
||||||
MemoComponent,
|
MemoComponent,
|
||||||
} from '../vnode/VNodeTags';
|
} from '../vnode/VNodeTags';
|
||||||
import {throwIfTrue} from '../utils/throwIfTrue';
|
import { throwIfTrue } from '../utils/throwIfTrue';
|
||||||
import {captureFunctionComponent} from './FunctionComponent';
|
import { captureFunctionComponent } from './FunctionComponent';
|
||||||
import {captureClassComponent} from './ClassComponent';
|
import { captureClassComponent } from './ClassComponent';
|
||||||
import {captureMemoComponent} from './MemoComponent';
|
import { captureMemoComponent } from './MemoComponent';
|
||||||
|
|
||||||
export function captureRender(processing: VNode, shouldUpdate: boolean): VNode | null {
|
export function captureRender(processing: VNode, shouldUpdate: boolean): VNode | null {
|
||||||
return captureLazyComponent(processing, processing.type, shouldUpdate);
|
return captureLazyComponent(processing, processing.type, shouldUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bubbleRender() {}
|
export function bubbleRender() { }
|
||||||
|
|
||||||
const LazyRendererMap = {
|
const LazyRendererMap = {
|
||||||
[FunctionComponent]: captureFunctionComponent,
|
[FunctionComponent]: captureFunctionComponent,
|
||||||
|
@ -64,12 +64,13 @@ function captureLazyComponent(
|
||||||
Component,
|
Component,
|
||||||
'',
|
'',
|
||||||
);
|
);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mergeDefaultProps(Component: any, props: object): object {
|
export function mergeDefaultProps(Component: any, props: object): object {
|
||||||
if (Component && Component.defaultProps) {
|
if (Component && Component.defaultProps) {
|
||||||
const clonedProps = {...props};
|
const clonedProps = { ...props };
|
||||||
const defaultProps = Component.defaultProps;
|
const defaultProps = Component.defaultProps;
|
||||||
Object.keys(defaultProps).forEach(key => {
|
Object.keys(defaultProps).forEach(key => {
|
||||||
if (clonedProps[key] === undefined) {
|
if (clonedProps[key] === undefined) {
|
||||||
|
|
|
@ -70,8 +70,9 @@ function callBeforeSubmitLifeCycles(
|
||||||
case TreeRoot: {
|
case TreeRoot: {
|
||||||
const root = vNode.realNode;
|
const root = vNode.realNode;
|
||||||
clearContainer(root.outerDom);
|
clearContainer(root.outerDom);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No Default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +137,9 @@ function callAfterSubmitLifeCycles(
|
||||||
vNode.realNode.focus();
|
vNode.realNode.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No Default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@ export function findDomVNode(vNode: VNode): VNode | null {
|
||||||
if (node.tag === DomComponent || node.tag === DomText) {
|
if (node.tag === DomComponent || node.tag === DomText) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue