Match-id-ee1618a953547a36c93091149d8747063b69e256
This commit is contained in:
commit
2dbd2903b7
|
@ -110,7 +110,7 @@ export function getPropChangeList(
|
|||
type: string,
|
||||
lastRawProps: Props,
|
||||
nextRawProps: Props,
|
||||
): Array<any> {
|
||||
): Map<string, any> {
|
||||
// 校验两个对象的不同
|
||||
validateProps(type, nextRawProps);
|
||||
|
||||
|
@ -123,11 +123,11 @@ export function getPropChangeList(
|
|||
}
|
||||
|
||||
export function isTextChild(type: string, props: Props): boolean {
|
||||
const typeArray = ['textarea', 'option', 'noscript'];
|
||||
const typeOfPropsChild = ['string', 'number'];
|
||||
if (typeArray.indexOf(type) >= 0) {
|
||||
if (type === 'textarea' || type === 'option' || type === 'noscript') {
|
||||
return true;
|
||||
} else if (typeOfPropsChild.indexOf(typeof props.children) >= 0) {
|
||||
}
|
||||
const childType = typeof props.children;
|
||||
if (childType === 'string' || childType === 'number') {
|
||||
return true;
|
||||
} else {
|
||||
return (
|
||||
|
|
|
@ -52,15 +52,10 @@ export function setDomProps(
|
|||
// 更新 DOM 属性
|
||||
export function updateDomProps(
|
||||
dom: Element,
|
||||
changeList: Array<any>,
|
||||
changeList: Map<string, any>,
|
||||
isNativeTag: boolean,
|
||||
): void {
|
||||
const listLength = changeList.length;
|
||||
let propName;
|
||||
let propVal;
|
||||
for (let i = 0; i < listLength; i++) {
|
||||
propName = changeList[i].propName;
|
||||
propVal = changeList[i].propVal;
|
||||
for(const [propName, propVal] of changeList) {
|
||||
updateOneProp(dom, propName, isNativeTag, propVal);
|
||||
}
|
||||
}
|
||||
|
@ -69,10 +64,9 @@ export function updateDomProps(
|
|||
export function compareProps(
|
||||
oldProps: Object,
|
||||
newProps: Object,
|
||||
): Array<any> {
|
||||
): Map<string, any> {
|
||||
let updatesForStyle = {};
|
||||
const toBeDeletedProps: Array<any> = [];
|
||||
const toBeUpdatedProps: Array<any> = [];
|
||||
const toUpdateProps = new Map();
|
||||
const keysOfOldProps = Object.keys(oldProps);
|
||||
const keysOfNewProps = Object.keys(newProps);
|
||||
|
||||
|
@ -104,17 +98,11 @@ export function compareProps(
|
|||
continue;
|
||||
} else if (isEventProp(propName)) {
|
||||
if (!allDelegatedHorizonEvents.has(propName)) {
|
||||
toBeDeletedProps.push({
|
||||
propName,
|
||||
propVal: null,
|
||||
});
|
||||
toUpdateProps.set(propName, null);
|
||||
}
|
||||
} else {
|
||||
// 其它属性都要加入到删除队列里面,等待删除
|
||||
toBeDeletedProps.push({
|
||||
propName,
|
||||
propVal: null,
|
||||
});
|
||||
toUpdateProps.set(propName, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,10 +144,7 @@ export function compareProps(
|
|||
}
|
||||
} else { // 之前未设置 style 属性或者设置了空值
|
||||
if (Object.keys(updatesForStyle).length === 0) {
|
||||
toBeUpdatedProps.push({
|
||||
propName,
|
||||
propVal: null,
|
||||
});
|
||||
toUpdateProps.set(propName, null);
|
||||
}
|
||||
updatesForStyle = newPropValue;
|
||||
}
|
||||
|
@ -168,41 +153,26 @@ export function compareProps(
|
|||
oldHTML = oldPropValue ? oldPropValue.__html : undefined;
|
||||
if (newHTML != null) {
|
||||
if (oldHTML !== newHTML) {
|
||||
toBeUpdatedProps.push({
|
||||
propName,
|
||||
propVal: newPropValue,
|
||||
});
|
||||
toUpdateProps.set(propName, newPropValue);
|
||||
}
|
||||
}
|
||||
} else if (propName === 'children') {
|
||||
if (typeof newPropValue === 'string' || typeof newPropValue === 'number') {
|
||||
toBeUpdatedProps.push({
|
||||
propName,
|
||||
propVal: String(newPropValue),
|
||||
});
|
||||
toUpdateProps.set(propName, String(newPropValue));
|
||||
}
|
||||
} else if (isEventProp(propName)) {
|
||||
if (!allDelegatedHorizonEvents.has(propName)) {
|
||||
toBeUpdatedProps.push({
|
||||
propName,
|
||||
propVal: newPropValue,
|
||||
});
|
||||
toUpdateProps.set(propName, newPropValue);
|
||||
}
|
||||
} else {
|
||||
toBeUpdatedProps.push({
|
||||
propName,
|
||||
propVal: newPropValue,
|
||||
});
|
||||
toUpdateProps.set(propName, newPropValue);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理style
|
||||
if (Object.keys(updatesForStyle).length > 0) {
|
||||
toBeUpdatedProps.push({
|
||||
propName: 'style',
|
||||
propVal: updatesForStyle,
|
||||
});
|
||||
toUpdateProps.set('style', updatesForStyle);
|
||||
}
|
||||
|
||||
return [...toBeDeletedProps, ...toBeUpdatedProps];
|
||||
return toUpdateProps;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
class Component<P,S,C> {
|
||||
props: P;
|
||||
context: C;
|
||||
state: S;
|
||||
state: S | null;
|
||||
refs: any;
|
||||
setState: any;
|
||||
forceUpdate: any;
|
||||
|
||||
constructor(props: P, context: C) {
|
||||
this.props = props;
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { VNode } from '../Types';
|
|||
import { FlagUtils } from '../vnode/VNodeFlags';
|
||||
import { TYPE_COMMON_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../../external/JSXElementType';
|
||||
import { DomText, DomPortal, Fragment, DomComponent } from '../vnode/VNodeTags';
|
||||
import {updateVNode, createVNodeFromElement, updateVNodePath, createFragmentVNode, createPortalVNode, createDomTextVNode} from '../vnode/VNodeCreator';
|
||||
import {updateVNode, createVNodeFromElement, createFragmentVNode, createPortalVNode, createDomTextVNode} from '../vnode/VNodeCreator';
|
||||
import {
|
||||
isSameType,
|
||||
getIteratorFn,
|
||||
|
@ -209,11 +209,6 @@ function getOldNodeFromMap(nodeMap: Map<string | number, VNode>, newIdx: number,
|
|||
return null;
|
||||
}
|
||||
|
||||
function setCIndex(vNode: VNode, idx: number) {
|
||||
vNode.cIndex = idx;
|
||||
updateVNodePath(vNode);
|
||||
}
|
||||
|
||||
// diff数组类型的节点,核心算法
|
||||
function diffArrayNodesHandler(
|
||||
parentNode: VNode,
|
||||
|
@ -274,7 +269,8 @@ function diffArrayNodesHandler(
|
|||
|
||||
theLastPosition = setVNodeAdditionFlag(newNode, theLastPosition, isComparing);
|
||||
newNode.eIndex = leftIdx;
|
||||
setCIndex(newNode, leftIdx);
|
||||
newNode.cIndex = leftIdx;
|
||||
newNode.path = newNode.parent.path + newNode.cIndex;
|
||||
appendNode(newNode);
|
||||
oldNode = nextOldNode;
|
||||
}
|
||||
|
@ -347,11 +343,23 @@ function diffArrayNodesHandler(
|
|||
|
||||
// 4. 新节点还有一部分,但是老节点已经没有了
|
||||
if (oldNode === null) {
|
||||
|
||||
let isDirectAdd = false;
|
||||
// TODO: 是否可以扩大至非dom类型节点
|
||||
// 如果dom节点在上次添加前没有节点,说明本次添加时,可以直接添加到最后,不需要通过 getSiblingDom 函数找到 before 节点
|
||||
if (parentNode.tag === DomComponent && parentNode.oldProps?.children?.length === 0 && rightIdx - leftIdx === newChildren.length) {
|
||||
isDirectAdd = true;
|
||||
}
|
||||
for (; leftIdx < rightIdx; leftIdx++) {
|
||||
newNode = getNewNode(parentNode, newChildren[leftIdx], null);
|
||||
|
||||
if (newNode !== null) {
|
||||
theLastPosition = setVNodeAdditionFlag(newNode, theLastPosition, isComparing);
|
||||
if (isComparing) {
|
||||
FlagUtils.setAddition(newNode);
|
||||
}
|
||||
if (isDirectAdd) {
|
||||
FlagUtils.markDirectAddition(newNode);
|
||||
}
|
||||
newNode.eIndex = leftIdx;
|
||||
appendNode(newNode);
|
||||
}
|
||||
|
@ -460,7 +468,7 @@ function setVNodesCIndex(startChild: VNode, startIdx: number) {
|
|||
|
||||
while (node !== null) {
|
||||
node.cIndex = idx;
|
||||
updateVNodePath(node);
|
||||
node.path = node.parent.path + node.cIndex;
|
||||
node = node.next;
|
||||
idx++;
|
||||
}
|
||||
|
@ -471,7 +479,7 @@ function diffIteratorNodesHandler(
|
|||
parentNode: VNode,
|
||||
firstChild: VNode | null,
|
||||
newChildrenIterable: Iterable<any>,
|
||||
isComparing: boolean = true
|
||||
isComparing: boolean
|
||||
): VNode | null {
|
||||
const iteratorFn = getIteratorFn(newChildrenIterable);
|
||||
const iteratorObj = iteratorFn.call(newChildrenIterable);
|
||||
|
@ -511,7 +519,7 @@ function diffStringNodeHandler(
|
|||
}
|
||||
newTextNode.parent = parentNode;
|
||||
newTextNode.cIndex = 0;
|
||||
updateVNodePath(newTextNode);
|
||||
newTextNode.path = newTextNode.parent.path + newTextNode.cIndex;
|
||||
|
||||
return newTextNode;
|
||||
}
|
||||
|
@ -589,7 +597,7 @@ function diffObjectNodeHandler(
|
|||
|
||||
resultNode.parent = parentNode;
|
||||
resultNode.cIndex = 0;
|
||||
updateVNodePath(resultNode);
|
||||
resultNode.path = resultNode.parent.path + resultNode.cIndex;
|
||||
if (startDelVNode) {
|
||||
deleteVNodes(parentNode, startDelVNode);
|
||||
}
|
||||
|
@ -604,7 +612,7 @@ export function createChildrenByDiff(
|
|||
parentNode: VNode,
|
||||
firstChild: VNode | null,
|
||||
newChild: any,
|
||||
isComparing: boolean = true
|
||||
isComparing: boolean
|
||||
): VNode | null {
|
||||
const isFragment = isNoKeyFragment(newChild);
|
||||
newChild = isFragment ? newChild.props.children : newChild;
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
} from '../vnode/VNodeTags';
|
||||
import { getContextChangeCtx, setContextCtx, setNamespaceCtx } from '../ContextSaver';
|
||||
import { FlagUtils } from '../vnode/VNodeFlags';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
||||
import componentRenders from './index';
|
||||
|
||||
|
@ -64,11 +63,6 @@ export function captureVNode(processing: VNode): VNode | null {
|
|||
return component.captureRender(processing, shouldUpdate);
|
||||
}
|
||||
|
||||
// 创建孩子节点
|
||||
export function createVNodeChildren(processing: VNode, nextChildren: any) {
|
||||
return createChildrenByDiff(processing, processing.child, nextChildren, !processing.isCreated);
|
||||
}
|
||||
|
||||
export function markRef(processing: VNode) {
|
||||
const ref = processing.ref;
|
||||
if ((processing.isCreated && ref !== null) || (!processing.isCreated && processing.oldRef !== ref)) {
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
markGetSnapshotBeforeUpdate,
|
||||
} from './class/ClassLifeCycleProcessor';
|
||||
import { FlagUtils, DidCapture } from '../vnode/VNodeFlags';
|
||||
import { createVNodeChildren, markRef } from './BaseComponent';
|
||||
import { markRef } from './BaseComponent';
|
||||
import {
|
||||
createUpdateArray,
|
||||
processUpdates,
|
||||
|
@ -29,6 +29,7 @@ import {
|
|||
import { getContextChangeCtx, setContextChangeCtx } from '../ContextSaver';
|
||||
import { setProcessingClassVNode } from '../GlobalVar';
|
||||
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
|
||||
// 获取当前节点的context
|
||||
export function getCurrentContext(clazz, processing: VNode) {
|
||||
|
@ -80,7 +81,7 @@ function createChildren(clazz: any, processing: VNode) {
|
|||
? null
|
||||
: inst.render();
|
||||
|
||||
processing.child = createVNodeChildren(processing, newElements);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, newElements, !processing.isCreated);
|
||||
return processing.child;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import {resetDepContexts} from '../components/context/Context';
|
|||
import {getOldContext} from '../components/context/CompatibleContext';
|
||||
import {FlagUtils} from '../vnode/VNodeFlags';
|
||||
import {exeFunctionHook} from '../hooks/HookMain';
|
||||
import {createVNodeChildren} from './BaseComponent';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
|
||||
function captureIndeterminateComponent(
|
||||
processing: VNode,
|
||||
|
@ -25,7 +25,7 @@ function captureIndeterminateComponent(
|
|||
const newElements = exeFunctionHook(funcComp, props, context, processing);
|
||||
|
||||
processing.tag = FunctionComponent;
|
||||
processing.child = createVNodeChildren(processing, newElements);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, newElements, !processing.isCreated);
|
||||
return processing.child;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type {VNode, ContextType} from '../Types';
|
||||
|
||||
import {resetDepContexts, getNewContext} from '../components/context/Context';
|
||||
import {createVNodeChildren} from './BaseComponent';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
|
||||
function captureContextConsumer(processing: VNode) {
|
||||
const context: ContextType<any> = processing.type;
|
||||
|
@ -12,7 +12,7 @@ function captureContextConsumer(processing: VNode) {
|
|||
const contextVal = getNewContext(processing, context);
|
||||
const newChildren = renderFunc(contextVal);
|
||||
|
||||
processing.child = createVNodeChildren(processing, newChildren);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, newChildren, !processing.isCreated);
|
||||
return processing.child;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import type {VNode, ContextType, ProviderType} from '../Types';
|
||||
import type { VNode, ContextType, ProviderType } from '../Types';
|
||||
|
||||
import {createVNodeChildren} from './BaseComponent';
|
||||
import {isSame} from '../utils/compare';
|
||||
import {ClassComponent, ContextProvider} from '../vnode/VNodeTags';
|
||||
import {pushForceUpdate} from '../UpdateHandler';
|
||||
import { isSame } from '../utils/compare';
|
||||
import { ClassComponent, ContextProvider } from '../vnode/VNodeTags';
|
||||
import { pushForceUpdate } from '../UpdateHandler';
|
||||
import {
|
||||
getContextChangeCtx,
|
||||
resetContextCtx,
|
||||
setContextCtx,
|
||||
} from '../ContextSaver';
|
||||
import {getFirstChild, travelVNodeTree} from '../vnode/VNodeUtils';
|
||||
import {launchUpdateFromVNode} from '../TreeBuilder';
|
||||
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
||||
import {setParentsChildShouldUpdate} from '../vnode/VNodeShouldUpdate';
|
||||
import { travelVNodeTree } from '../vnode/VNodeUtils';
|
||||
import { launchUpdateFromVNode } from '../TreeBuilder';
|
||||
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
|
||||
import { setParentsChildShouldUpdate } from '../vnode/VNodeShouldUpdate';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
|
||||
// 从依赖中找到匹配context的VNode
|
||||
function matchDependencies(depContexts, context, vNode): boolean {
|
||||
|
@ -56,7 +56,7 @@ function handleContextChange(processing: VNode, context: ContextType<any>): void
|
|||
}, node =>
|
||||
// 如果这是匹配的provider,则不要更深入地扫描
|
||||
node.tag === ContextProvider && node.type === processing.type
|
||||
, processing);
|
||||
, processing, null);
|
||||
|
||||
// 找到了依赖context的子节点,触发一次更新
|
||||
if (isMatch) {
|
||||
|
@ -92,7 +92,7 @@ function captureContextProvider(processing: VNode): VNode | null {
|
|||
}
|
||||
|
||||
const newElements = newProps.children;
|
||||
processing.child = createVNodeChildren(processing, newElements);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, newElements, !processing.isCreated);
|
||||
return processing.child;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,10 @@ import {
|
|||
isTextChild,
|
||||
} from '../../dom/DOMOperator';
|
||||
import { FlagUtils } from '../vnode/VNodeFlags';
|
||||
import { createVNodeChildren, markRef } from './BaseComponent';
|
||||
import { markRef } from './BaseComponent';
|
||||
import { DomComponent, DomPortal, DomText } from '../vnode/VNodeTags';
|
||||
import { travelVNodeTree } from '../vnode/VNodeUtils';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
|
||||
function updateDom(
|
||||
processing: VNode,
|
||||
|
@ -44,7 +45,7 @@ function updateDom(
|
|||
FlagUtils.markUpdate(processing);
|
||||
} else {
|
||||
// 其它的类型,数据有变化才标记更新
|
||||
if (changeList.length) {
|
||||
if (changeList.size) {
|
||||
FlagUtils.markUpdate(processing);
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +89,7 @@ export function bubbleRender(processing: VNode) {
|
|||
}, node =>
|
||||
// 已经append到父节点,或者是DomPortal都不需要处理child了
|
||||
node.tag === DomComponent || node.tag === DomText || node.tag === DomPortal
|
||||
, processing);
|
||||
, processing, null);
|
||||
}
|
||||
|
||||
processing.realNode = dom;
|
||||
|
@ -123,7 +124,7 @@ function captureDomComponent(processing: VNode): VNode | null {
|
|||
}
|
||||
|
||||
markRef(processing);
|
||||
processing.child = createVNodeChildren(processing, nextChildren);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, nextChildren, !processing.isCreated);
|
||||
return processing.child;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import type { VNode } from '../Types';
|
||||
import { resetNamespaceCtx, setNamespaceCtx } from '../ContextSaver';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
import { createVNodeChildren } from './BaseComponent';
|
||||
import { prePortal } from '../../dom/DOMOperator';
|
||||
|
||||
export function bubbleRender(processing: VNode) {
|
||||
|
@ -17,9 +16,9 @@ function capturePortalComponent(processing: VNode) {
|
|||
|
||||
const newElements = processing.props;
|
||||
if (processing.isCreated) {
|
||||
processing.child = createChildrenByDiff(processing, null, newElements);
|
||||
processing.child = createChildrenByDiff(processing, null, newElements, true);
|
||||
} else {
|
||||
processing.child = createVNodeChildren(processing, newElements);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, newElements, !processing.isCreated);
|
||||
}
|
||||
return processing.child;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type {VNode} from '../Types';
|
||||
import {createVNodeChildren} from './BaseComponent';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
|
||||
export function bubbleRender() {}
|
||||
|
||||
function captureFragment(processing: VNode) {
|
||||
const newElement = processing.props;
|
||||
processing.child = createVNodeChildren(processing, newElement);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, newElement, !processing.isCreated);
|
||||
return processing.child;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ import {mergeDefaultProps} from './LazyComponent';
|
|||
import {getOldContext} from '../components/context/CompatibleContext';
|
||||
import {resetDepContexts} from '../components/context/Context';
|
||||
import {exeFunctionHook} from '../hooks/HookMain';
|
||||
import {createVNodeChildren} from './BaseComponent';
|
||||
import {ForwardRef} from '../vnode/VNodeTags';
|
||||
import {FlagUtils, Update} from '../vnode/VNodeFlags';
|
||||
import {getContextChangeCtx} from '../ContextSaver';
|
||||
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
|
||||
// 在useState, useReducer的时候,会触发state变化
|
||||
let stateChange = false;
|
||||
|
@ -79,7 +79,7 @@ export function captureFunctionComponent(
|
|||
return onlyUpdateChildVNodes(processing);
|
||||
}
|
||||
|
||||
processing.child = createVNodeChildren(processing, newElements);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, newElements, !processing.isCreated);
|
||||
return processing.child;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type {VNode} from '../Types';
|
||||
|
||||
import {mergeDefaultProps} from './LazyComponent';
|
||||
import {updateVNode, onlyUpdateChildVNodes, updateVNodePath, createFragmentVNode, createUndeterminedVNode} from '../vnode/VNodeCreator';
|
||||
import {updateVNode, onlyUpdateChildVNodes, createFragmentVNode, createUndeterminedVNode} from '../vnode/VNodeCreator';
|
||||
import {shallowCompare} from '../utils/compare';
|
||||
import {
|
||||
TYPE_FRAGMENT,
|
||||
|
@ -29,7 +29,7 @@ export function captureMemoComponent(
|
|||
}
|
||||
newChild.parent = processing;
|
||||
newChild.ref = processing.ref;
|
||||
updateVNodePath(newChild);
|
||||
newChild.path = newChild.parent.path + newChild.cIndex;
|
||||
processing.child = newChild;
|
||||
|
||||
return newChild;
|
||||
|
@ -48,7 +48,7 @@ export function captureMemoComponent(
|
|||
const newChild = updateVNode(firstChild, newProps);
|
||||
newChild.parent = processing;
|
||||
newChild.cIndex = 0;
|
||||
updateVNodePath(newChild);
|
||||
newChild.path = newChild.parent.path + newChild.cIndex;
|
||||
newChild.ref = processing.ref;
|
||||
processing.child = newChild;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type {VNode, PromiseType} from '../Types';
|
||||
|
||||
import {FlagUtils, Interrupted} from '../vnode/VNodeFlags';
|
||||
import {onlyUpdateChildVNodes, updateVNode, updateVNodePath, createFragmentVNode} from '../vnode/VNodeCreator';
|
||||
import {onlyUpdateChildVNodes, updateVNode, createFragmentVNode} from '../vnode/VNodeCreator';
|
||||
import {
|
||||
ClassComponent,
|
||||
IncompleteClassComponent,
|
||||
|
@ -44,7 +44,7 @@ function createFallback(processing: VNode, fallbackChildren) {
|
|||
fallbackFragment.parent = processing;
|
||||
fallbackFragment.eIndex = 1;
|
||||
fallbackFragment.cIndex = 1;
|
||||
updateVNodePath(fallbackFragment);
|
||||
fallbackFragment.path = fallbackFragment.parent.path + fallbackFragment.cIndex;
|
||||
processing.suspenseChildStatus = SuspenseChildStatus.ShowFallback;
|
||||
|
||||
return fallbackFragment;
|
||||
|
@ -76,7 +76,7 @@ function createSuspenseChildren(processing: VNode, newChildren) {
|
|||
|
||||
childFragment.parent = processing;
|
||||
childFragment.cIndex = 0;
|
||||
updateVNodePath(childFragment);
|
||||
childFragment.path = childFragment.parent.path + childFragment.cIndex;
|
||||
processing.child = childFragment;
|
||||
processing.promiseResolve = false;
|
||||
return processing.child;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import type {VNode} from '../Types';
|
||||
import {throwIfTrue} from '../utils/throwIfTrue';
|
||||
import {processUpdates} from '../UpdateHandler';
|
||||
import {createVNodeChildren} from './BaseComponent';
|
||||
import {resetNamespaceCtx, setNamespaceCtx} from '../ContextSaver';
|
||||
import {resetOldCtx} from '../components/context/CompatibleContext';
|
||||
import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator';
|
||||
import { createChildrenByDiff } from '../diff/nodeDiffComparator';
|
||||
|
||||
export function bubbleRender(processing: VNode) {
|
||||
resetNamespaceCtx(processing);
|
||||
|
@ -33,7 +33,7 @@ function updateTreeRoot(processing) {
|
|||
if (newElement === oldElement) {
|
||||
return onlyUpdateChildVNodes(processing);
|
||||
}
|
||||
processing.child = createVNodeChildren(processing, newElement);
|
||||
processing.child = createChildrenByDiff(processing, processing.child, newElement, !processing.isCreated);
|
||||
return processing.child;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ export function callDerivedStateFromProps(
|
|||
getDerivedStateFromProps: (props: object, state: object) => object,
|
||||
nextProps: object,
|
||||
) {
|
||||
if (typeof getDerivedStateFromProps === 'function') {
|
||||
if (getDerivedStateFromProps) {
|
||||
const oldState = processing.state;
|
||||
|
||||
// 调用class组件的getDerivedStateFromProps函数
|
||||
|
@ -57,7 +57,7 @@ export function callShouldComponentUpdate(
|
|||
) {
|
||||
const inst = processing.realNode;
|
||||
|
||||
if (typeof inst.shouldComponentUpdate === 'function') {
|
||||
if (inst.shouldComponentUpdate) {
|
||||
return inst.shouldComponentUpdate(newProps, newState, newContext);
|
||||
}
|
||||
|
||||
|
@ -91,10 +91,10 @@ export function callConstructor(processing: VNode, ctor: any, props: any): any {
|
|||
export function callComponentWillMount(processing, inst, newProps?) {
|
||||
const oldState = inst.state;
|
||||
|
||||
if (typeof inst.componentWillMount === 'function') {
|
||||
if (inst.componentWillMount) {
|
||||
inst.componentWillMount();
|
||||
}
|
||||
if (typeof inst.UNSAFE_componentWillMount === 'function') {
|
||||
if (inst.UNSAFE_componentWillMount) {
|
||||
inst.UNSAFE_componentWillMount();
|
||||
}
|
||||
|
||||
|
@ -108,21 +108,21 @@ export function callComponentWillMount(processing, inst, newProps?) {
|
|||
}
|
||||
|
||||
export function callComponentWillUpdate(inst, newProps, newState, nextContext) {
|
||||
if (typeof inst.componentWillUpdate === 'function') {
|
||||
if (inst.componentWillUpdate) {
|
||||
inst.componentWillUpdate(newProps, newState, nextContext);
|
||||
}
|
||||
|
||||
if (typeof inst.UNSAFE_componentWillUpdate === 'function') {
|
||||
if (inst.UNSAFE_componentWillUpdate) {
|
||||
inst.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
|
||||
}
|
||||
}
|
||||
|
||||
export function callComponentWillReceiveProps(inst, newProps: object, newContext: object) {
|
||||
const oldState = inst.state;
|
||||
if (typeof inst.componentWillReceiveProps === 'function') {
|
||||
if (inst.componentWillReceiveProps) {
|
||||
inst.componentWillReceiveProps(newProps, newContext);
|
||||
}
|
||||
if (typeof inst.UNSAFE_componentWillReceiveProps === 'function') {
|
||||
if (inst.UNSAFE_componentWillReceiveProps) {
|
||||
inst.UNSAFE_componentWillReceiveProps(newProps, newContext);
|
||||
}
|
||||
if (inst.state !== oldState) {
|
||||
|
@ -132,21 +132,21 @@ export function callComponentWillReceiveProps(inst, newProps: object, newContext
|
|||
|
||||
export function markComponentDidMount(processing: VNode) {
|
||||
const inst = processing.realNode;
|
||||
if (typeof inst.componentDidMount === 'function') {
|
||||
if (inst.componentDidMount) {
|
||||
FlagUtils.markUpdate(processing);
|
||||
}
|
||||
}
|
||||
|
||||
export function markGetSnapshotBeforeUpdate(processing: VNode) {
|
||||
const inst = processing.realNode;
|
||||
if (typeof inst.getSnapshotBeforeUpdate === 'function') {
|
||||
if (inst.getSnapshotBeforeUpdate) {
|
||||
FlagUtils.markSnapshot(processing);
|
||||
}
|
||||
}
|
||||
|
||||
export function markComponentDidUpdate(processing: VNode) {
|
||||
const inst = processing.realNode;
|
||||
if (typeof inst.componentDidUpdate === 'function') {
|
||||
if (inst.componentDidUpdate) {
|
||||
FlagUtils.markUpdate(processing);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
SuspenseComponent,
|
||||
MemoComponent,
|
||||
} from '../vnode/VNodeTags';
|
||||
import { FlagUtils, ResetText, Clear, Update } from '../vnode/VNodeFlags';
|
||||
import { FlagUtils, ResetText, Clear, Update, DirectAddition } from '../vnode/VNodeFlags';
|
||||
import { mergeDefaultProps } from '../render/LazyComponent';
|
||||
import {
|
||||
submitDomUpdate,
|
||||
|
@ -147,7 +147,7 @@ function hideOrUnhideAllChildren(vNode, isHidden) {
|
|||
unHideDom(node.tag, instance, node.props);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, null, vNode, null);
|
||||
}
|
||||
|
||||
function attachRef(vNode: VNode) {
|
||||
|
@ -216,7 +216,7 @@ function unmountNestedVNodes(vNode: VNode): void {
|
|||
}, node =>
|
||||
// 如果是DomPortal,不需要遍历child
|
||||
node.tag === DomPortal
|
||||
);
|
||||
, vNode, null);
|
||||
}
|
||||
|
||||
function submitAddition(vNode: VNode): void {
|
||||
|
@ -241,6 +241,11 @@ function submitAddition(vNode: VNode): void {
|
|||
FlagUtils.removeFlag(parent, ResetText);
|
||||
}
|
||||
|
||||
if ((vNode.flags & DirectAddition) === DirectAddition) {
|
||||
insertOrAppendPlacementNode(vNode, null, parentDom);
|
||||
FlagUtils.removeFlag(vNode, DirectAddition);
|
||||
return;
|
||||
}
|
||||
const before = getSiblingDom(vNode);
|
||||
insertOrAppendPlacementNode(vNode, before, parentDom);
|
||||
}
|
||||
|
@ -314,7 +319,7 @@ function unmountDomComponents(vNode: VNode): void {
|
|||
}
|
||||
}, node =>
|
||||
// 如果是dom不用再遍历child
|
||||
node.tag === DomComponent || node.tag === DomText, null, (node) => {
|
||||
node.tag === DomComponent || node.tag === DomText, vNode, (node) => {
|
||||
if (node.tag === DomPortal) {
|
||||
// 当离开portal,需要重新设置parent
|
||||
currentParentIsValid = false;
|
||||
|
|
|
@ -87,7 +87,10 @@ export function submitToRender(treeRoot) {
|
|||
}
|
||||
|
||||
function beforeSubmit(dirtyNodes: Array<VNode>) {
|
||||
dirtyNodes.forEach(node => {
|
||||
let node;
|
||||
const nodesLength = dirtyNodes.length;
|
||||
for(let i = 0; i < nodesLength; i++) {
|
||||
node = dirtyNodes[i];
|
||||
try {
|
||||
if ((node.flags & Snapshot) === Snapshot) {
|
||||
callBeforeSubmitLifeCycles(node);
|
||||
|
@ -95,11 +98,18 @@ function beforeSubmit(dirtyNodes: Array<VNode>) {
|
|||
} catch (error) {
|
||||
handleSubmitError(node, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function submit(dirtyNodes: Array<VNode>) {
|
||||
dirtyNodes.forEach(node => {
|
||||
let node;
|
||||
const nodesLength = dirtyNodes.length;
|
||||
let isAdd;
|
||||
let isUpdate;
|
||||
let isDeletion;
|
||||
let isClear;
|
||||
for(let i = 0; i < nodesLength; i++) {
|
||||
node = dirtyNodes[i];
|
||||
try {
|
||||
if ((node.flags & ResetText) === ResetText) {
|
||||
submitResetTextContent(node);
|
||||
|
@ -112,8 +122,8 @@ function submit(dirtyNodes: Array<VNode>) {
|
|||
}
|
||||
}
|
||||
|
||||
const isAdd = (node.flags & Addition) === Addition;
|
||||
const isUpdate = (node.flags & Update) === Update;
|
||||
isAdd = (node.flags & Addition) === Addition;
|
||||
isUpdate = (node.flags & Update) === Update;
|
||||
if (isAdd && isUpdate) {
|
||||
// Addition
|
||||
submitAddition(node);
|
||||
|
@ -122,8 +132,8 @@ function submit(dirtyNodes: Array<VNode>) {
|
|||
// Update
|
||||
submitUpdate(node);
|
||||
} else {
|
||||
const isDeletion = (node.flags & Deletion) === Deletion;
|
||||
const isClear = (node.flags & Clear) === Clear;
|
||||
isDeletion = (node.flags & Deletion) === Deletion;
|
||||
isClear = (node.flags & Clear) === Clear;
|
||||
if (isAdd) {
|
||||
submitAddition(node);
|
||||
FlagUtils.removeFlag(node, Addition);
|
||||
|
@ -139,11 +149,14 @@ function submit(dirtyNodes: Array<VNode>) {
|
|||
} catch (error) {
|
||||
handleSubmitError(node, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function afterSubmit(dirtyNodes: Array<VNode>) {
|
||||
dirtyNodes.forEach(node => {
|
||||
let node;
|
||||
const nodesLength = dirtyNodes.length;
|
||||
for(let i = 0; i < nodesLength; i++) {
|
||||
node = dirtyNodes[i];
|
||||
try {
|
||||
if ((node.flags & Update) === Update || (node.flags & Callback) === Callback) {
|
||||
callAfterSubmitLifeCycles(node);
|
||||
|
@ -155,7 +168,7 @@ function afterSubmit(dirtyNodes: Array<VNode>) {
|
|||
} catch (error) {
|
||||
handleSubmitError(node, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function setRootThrowError(error: any) {
|
||||
|
|
|
@ -157,10 +157,6 @@ export function createVNode(tag: VNodeTag | string, ...secondArg) {
|
|||
return vNode;
|
||||
}
|
||||
|
||||
export function updateVNodePath(vNode: VNode) {
|
||||
vNode.path = vNode.parent.path + vNode.cIndex;
|
||||
}
|
||||
|
||||
export function createVNodeFromElement(element: JSXElement): VNode {
|
||||
const type = element.type;
|
||||
const key = element.key;
|
||||
|
@ -183,7 +179,7 @@ export function onlyUpdateChildVNodes(processing: VNode): VNode | null {
|
|||
let child: VNode | null = processing.child;
|
||||
while (child !== null) {
|
||||
updateVNode(child, child.props);
|
||||
updateVNodePath(child);
|
||||
child.path = child.parent.path + child.cIndex;
|
||||
child = child.next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,20 +5,21 @@
|
|||
import type { VNode } from '../Types';
|
||||
|
||||
|
||||
export const InitFlag = /** */ 0b000000000000;
|
||||
export const InitFlag = /** */ 0;
|
||||
// vNode节点的flags
|
||||
export const Addition = /** */ 0b100000000000;
|
||||
export const Update = /** */ 0b010000000000;
|
||||
export const Deletion = /** */ 0b001000000000;
|
||||
export const ResetText =/** */ 0b000100000000;
|
||||
export const Callback = /** */ 0b000010000000;
|
||||
export const DidCapture =/** */ 0b000001000000;
|
||||
export const Ref = /** */ 0b000000100000;
|
||||
export const Snapshot = /** */ 0b000000010000;
|
||||
export const Interrupted = /** */ 0b000000001000; // 被中断了,抛出错误的vNode以及它的父vNode
|
||||
export const ShouldCapture =/** */ 0b000000000100;
|
||||
export const ForceUpdate = /** */ 0b000000000010; // For suspense
|
||||
export const Clear = /** */ 0b000000000001;
|
||||
export const DirectAddition = /** */ 1 << 0; // 在本次更新前入股父dom没有子节点,说明本次可以直接添加至父节点,不需要通过 getSiblingDom 找到 before 节点
|
||||
export const Addition = /** */ 1 << 1;
|
||||
export const Update = /** */ 1 << 2;
|
||||
export const Deletion = /** */ 1 << 3;
|
||||
export const ResetText =/** */ 1 << 4;
|
||||
export const Callback = /** */ 1 << 5;
|
||||
export const DidCapture =/** */ 1 << 6;
|
||||
export const Ref = /** */ 1 << 7;
|
||||
export const Snapshot = /** */ 1 << 8;
|
||||
export const Interrupted = /** */ 1 << 9; // 被中断了,抛出错误的vNode以及它的父vNode
|
||||
export const ShouldCapture =/** */ 1 << 11;
|
||||
export const ForceUpdate = /** */ 1 << 12; // For suspense
|
||||
export const Clear = /** */ 1 << 13;
|
||||
const LifecycleEffectArr = Update | Callback | Ref | Snapshot;
|
||||
|
||||
export class FlagUtils {
|
||||
|
@ -44,6 +45,10 @@ export class FlagUtils {
|
|||
static setAddition(node: VNode) {
|
||||
node.flags = Addition;
|
||||
}
|
||||
|
||||
static markDirectAddition(node: VNode) {
|
||||
node.flags |= DirectAddition;
|
||||
}
|
||||
static markUpdate(node: VNode) {
|
||||
node.flags |= Update;
|
||||
}
|
||||
|
|
|
@ -27,11 +27,11 @@ export function travelChildren(beginVNode: VNode, handleVNode: Function, isFinis
|
|||
export function travelVNodeTree(
|
||||
beginVNode: VNode,
|
||||
handleVNode: Function,
|
||||
childFilter: Function = () => false, // 返回true不处理child
|
||||
finishVNode?: VNode, // 结束遍历节点,有时候和beginVNode不相同
|
||||
handleWhenToParent?: Function
|
||||
childFilter: ((node: VNode) => boolean) | null, // 返回true不处理child
|
||||
finishVNode: VNode, // 结束遍历节点,有时候和beginVNode不相同
|
||||
handleWhenToParent: Function | null
|
||||
): VNode | null {
|
||||
const overVNode = finishVNode || beginVNode;
|
||||
const filter = childFilter === null;
|
||||
let node = beginVNode;
|
||||
|
||||
while (true) {
|
||||
|
@ -43,20 +43,20 @@ export function travelVNodeTree(
|
|||
|
||||
// 找子节点
|
||||
const childVNode = node.child;
|
||||
if (childVNode !== null && !childFilter(node)) {
|
||||
if (childVNode !== null && (filter || !childFilter(node))) {
|
||||
childVNode.parent = node;
|
||||
node = childVNode;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 回到开始节点
|
||||
if (node === overVNode) {
|
||||
if (node === finishVNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 找兄弟,没有就往上再找兄弟
|
||||
while (node.next === null) {
|
||||
if (node.parent === null || node.parent === overVNode) {
|
||||
if (node.parent === null || node.parent === finishVNode) {
|
||||
return null;
|
||||
}
|
||||
node = node.parent;
|
||||
|
@ -119,7 +119,7 @@ export function findDomVNode(vNode: VNode): VNode | null {
|
|||
return node;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}, null, vNode, null);
|
||||
}
|
||||
|
||||
export function findDOMByClassInst(inst) {
|
||||
|
@ -169,7 +169,7 @@ export function getSiblingDom(vNode: VNode): Element | null {
|
|||
// 如果不是dom节点,往下找
|
||||
while (!isDomVNode(node)) {
|
||||
// 如果节点也是Addition
|
||||
if ((node.flags & Addition) ===Addition) {
|
||||
if ((node.flags & Addition) === Addition) {
|
||||
continue findSibling;
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ export function getSiblingDom(vNode: VNode): Element | null {
|
|||
}
|
||||
}
|
||||
|
||||
if ((node.flags & Addition) ===InitFlag) {
|
||||
if ((node.flags & Addition) === InitFlag) {
|
||||
// 找到
|
||||
return node.realNode;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue