@saber2pr/react
Version:
react in Typescript.
253 lines (252 loc) • 8.51 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* @Author: saber2pr
* @Date: 2019-12-06 17:09:07
* @Last Modified by: saber2pr
* @Last Modified time: 2019-12-13 19:12:55
*/
var ReactTypes_1 = require("../shared/ReactTypes");
var ReactFiberHostConfig_1 = require("./ReactFiberHostConfig");
var ReactFiberTraverse_1 = require("./ReactFiberTraverse");
var ReactFiberReflection_1 = require("./ReactFiberReflection");
var ReactIs_1 = require("../react-is/ReactIs");
var testStackSize_1 = require("../shared/testStackSize");
function createStateNode(hostFiber) {
var tag = hostFiber.tag, props = hostFiber.props;
var stateNode = null;
if (ReactIs_1.isTextFiber(hostFiber)) {
stateNode = ReactFiberHostConfig_1.HostConfig.createTextNode(props.nodeValue);
}
if (ReactIs_1.isRootFiber(hostFiber)) {
stateNode = hostFiber.stateNode;
}
if (ReactIs_1.isHostFiber(hostFiber)) {
stateNode = ReactFiberHostConfig_1.HostConfig.createElement(tag);
}
if (ReactIs_1.isFragmentFiber(hostFiber)) {
stateNode = ReactFiberHostConfig_1.HostConfig.createDocumentFragment();
}
if (props.ref) {
var ref = props.ref;
if (typeof ref === "function") {
ref(stateNode);
}
else {
ref.current = stateNode;
}
}
return stateNode;
}
exports.createStateNode = createStateNode;
function commitWork(fiber) {
var effectList = sortEffectList(fiber);
effectList.forEach(commitUnitOfWork);
// set root alternate
if (ReactIs_1.isRootFiber(fiber)) {
ReactFiberReflection_1.Reflection.setContainerFiber(fiber);
}
// set hook alternate
if (ReactIs_1.isHookFiber(fiber)) {
ReactFiberReflection_1.Reflection.setInternalFiber(fiber);
}
testStackSize_1.resetStack();
var callback = fiber.callback;
if (callback)
callback(fiber);
}
exports.commitWork = commitWork;
function sortEffectList(fiber) {
var effectList = fiber.effectList || [];
var nextEffects = [];
var _loop_1 = function (effect) {
if (nextEffects.find(function (nextEffect) { return nextEffect.effect === effect; })) {
return "continue";
}
var nextEffect = {
level: ReactTypes_1.EffectType.getEffectLevel(effect.effectType),
effect: effect
};
nextEffects.push(nextEffect);
};
for (var _i = 0, effectList_1 = effectList; _i < effectList_1.length; _i++) {
var effect = effectList_1[_i];
_loop_1(effect);
}
fiber.effectList = nextEffects
.sort(function (a, b) { return b.level - a.level; })
.map(function (_a) {
var effect = _a.effect;
return effect;
});
return fiber.effectList;
}
function commitUnitOfWork(fiber) {
var effectType = fiber.effectType;
if (ReactIs_1.isHookFiber(fiber)) {
switch (effectType) {
case ReactTypes_1.EffectType.Create:
commitHookMount(fiber);
break;
case ReactTypes_1.EffectType.Update:
commitHookUpdate(fiber);
break;
case ReactTypes_1.EffectType.Place:
commitHookMount(fiber);
commitPlace(fiber);
break;
case ReactTypes_1.EffectType.Delete:
commitHookUnMount(fiber);
commitDelete(fiber);
break;
default:
break;
}
ReactFiberReflection_1.Reflection.setInternalFiber(fiber);
}
else {
switch (effectType) {
case ReactTypes_1.EffectType.Create:
commitCreate(fiber);
break;
case ReactTypes_1.EffectType.Update:
commitUpdate(fiber);
break;
case ReactTypes_1.EffectType.Place:
commitPlace(fiber);
break;
case ReactTypes_1.EffectType.Delete:
commitDelete(fiber);
break;
default:
break;
}
}
}
function commitHookMount(hookFiber) {
var effect = hookFiber.memoizedState;
if (!effect) {
return;
}
var creators = effect.in;
if (creators) {
var nextEffects = [];
while (creators.length) {
testStackSize_1.TestStackSize("commitHookEffectList");
var current = creators.pop();
var nextEffect = current();
if (nextEffect) {
nextEffects.push(nextEffect);
}
}
effect.out = nextEffects;
}
}
function commitHookUnMount(hookFiber) {
var effect = hookFiber.memoizedState;
if (!effect) {
return;
}
var destroys = effect.out;
if (destroys) {
while (destroys.length) {
testStackSize_1.TestStackSize("commitHookEffectList:1");
var current = destroys.pop();
current();
}
}
}
// update = unmount -> mount
function commitHookUpdate(hookFiber) {
commitHookUnMount(hookFiber);
commitHookMount(hookFiber);
}
function commitCreate(hostFiber) {
var HostParent = ReactFiberTraverse_1.getHostParentFiber(hostFiber);
var parent = HostParent.stateNode;
var node = hostFiber.stateNode;
ReactFiberHostConfig_1.HostConfig.appendChild(parent, node);
}
exports.commitCreate = commitCreate;
function commitPlace(finishedWork) {
var parentFiber = ReactFiberTraverse_1.getHostParentFiber(finishedWork);
if (!parentFiber) {
// when parent had been removed, ignore this effect.
return;
}
var parent = parentFiber.stateNode;
var before = ReactFiberTraverse_1.getHostSiblingFiber(finishedWork);
var node = finishedWork;
while (true) {
testStackSize_1.TestStackSize("commitPlace");
var isHost = node.$$typeof === ReactTypes_1.NodeType.Host || node.$$typeof === ReactTypes_1.NodeType.Text;
if (isHost) {
var stateNode = node.stateNode;
if (before) {
ReactFiberHostConfig_1.HostConfig.insertBefore(parent, stateNode, before.stateNode);
}
else {
ReactFiberHostConfig_1.HostConfig.appendChild(parent, stateNode);
}
}
else if (node.child) {
node.child.return = node;
node = node.child;
continue;
}
if (node === finishedWork) {
return;
}
while (!node.sibling) {
testStackSize_1.TestStackSize("commitPlace:1");
if (!node.return || node.return === finishedWork) {
return;
}
node = node.return;
}
node.sibling.return = node.return;
node = node.sibling;
}
}
exports.commitPlace = commitPlace;
function commitUpdate(hostFiber) {
var alternate = hostFiber.alternate;
var newProps = hostFiber.props;
var node = hostFiber.stateNode;
var oldProps = alternate ? alternate.props : {};
var newPropsToUpdate = Object.fromEntries(Object.entries(newProps).filter(function (_a) {
var k = _a[0];
return !["ref", "children"].includes(k);
}));
ReactFiberHostConfig_1.HostConfig.updateProps(node, newPropsToUpdate, oldProps);
}
exports.commitUpdate = commitUpdate;
function commitDelete(finishedWork) {
var current = finishedWork;
if (ReactIs_1.isHookFiber(current)) {
var HostChildFiber = ReactFiberTraverse_1.getHostChildFiber(current);
if (HostChildFiber) {
var stateNode = HostChildFiber.stateNode;
ReactFiberHostConfig_1.HostConfig.removeSelf(stateNode);
datchFiber(HostChildFiber);
}
}
else {
var stateNode = current.stateNode;
ReactFiberHostConfig_1.HostConfig.removeSelf(stateNode);
}
datchFiber(current);
}
exports.commitDelete = commitDelete;
function datchFiber(fiber) {
fiber.return = null;
fiber.child = null;
fiber.sibling = null;
var alternate = fiber.alternate;
if (alternate) {
alternate.return = null;
alternate.child = null;
alternate.sibling = null;
}
fiber.alternate = null;
}