@saber2pr/react
Version:
react in Typescript.
123 lines (122 loc) • 4.53 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
/*
* @Author: saber2pr
* @Date: 2019-12-06 17:08:56
* @Last Modified by: saber2pr
* @Last Modified time: 2019-12-13 19:03:54
*/
var ReactTypes_1 = require("../shared/ReactTypes");
var ReactChildren_1 = require("../react/ReactChildren");
var ReactIs_1 = require("../react-is/ReactIs");
var testStackSize_1 = require("../shared/testStackSize");
function reconcileChildren(fiber, children) {
if (ReactIs_1.isHookFiber(fiber)) {
reconcileHookRetFiber(fiber);
}
children = ReactChildren_1.Children.toArray(children);
var alternate = fiber.alternate;
var nextOldFiber = alternate ? alternate.child : null;
var newFiber = null;
var index = 0;
while (index < children.length || nextOldFiber) {
testStackSize_1.TestStackSize("reconcileChildren");
var prevChild = newFiber;
var oldFiber = nextOldFiber;
if (oldFiber) {
if (oldFiber.effectType === ReactTypes_1.EffectType.Delete) {
oldFiber = null;
}
}
var element = index < children.length && children[index];
// update
if (oldFiber && element && ReactIs_1.isSameTag(element, oldFiber)) {
newFiber = updateSlot(element, oldFiber, fiber);
}
// place
else if (oldFiber && element && !ReactIs_1.isSameTag(element, oldFiber)) {
newFiber = placeChild(element, oldFiber, fiber);
}
// create
else if (!oldFiber && element) {
newFiber = createChild(element, fiber);
}
// delete
else if (oldFiber && !element) {
deleteChild(fiber, oldFiber);
}
// next alternate
if (nextOldFiber)
nextOldFiber = nextOldFiber.sibling;
if (index === 0 || !fiber.child) {
fiber.child = newFiber; // link: fiber->child
}
else if (prevChild) {
if (element) {
prevChild.sibling = newFiber; // link: fiber.sibling->fiber
}
else {
prevChild.sibling = null; // unlink: fiber.sibling
delete prevChild.sibling;
}
}
index++;
}
return fiber.child;
}
exports.reconcileChildren = reconcileChildren;
function reconcileHookRetFiber(hookFiber) {
var alternate = hookFiber.alternate;
//update hook effect
if (alternate) {
if (ReactIs_1.isSameTag(alternate, hookFiber)) {
// update
hookFiber.effectType = ReactTypes_1.EffectType.Update;
}
else {
// place
hookFiber.effectType = ReactTypes_1.EffectType.Place;
alternate.effectType = ReactTypes_1.EffectType.Delete;
}
}
else {
// create
hookFiber.effectType = ReactTypes_1.EffectType.Create;
}
}
function createChild(element, returnFiber) {
var newFiber = __assign(__assign({}, element), { return: returnFiber, effectType: ReactTypes_1.EffectType.Create });
return newFiber;
}
function updateSlot(element, oldFiber, returnFiber) {
var newFiber = __assign(__assign(__assign({}, oldFiber), element), { return: returnFiber, effectType: ReactTypes_1.EffectType.Update, alternate: oldFiber });
oldFiber.alternate = null;
return newFiber;
}
function placeChild(element, childToPlace, returnFiber) {
var newFiber = __assign(__assign({}, element), { return: returnFiber, effectType: ReactTypes_1.EffectType.Place, alternate: childToPlace });
deleteChild(returnFiber, childToPlace);
return newFiber;
}
function deleteChild(returnFiber, childToDelete) {
childToDelete.effectType = ReactTypes_1.EffectType.Delete;
var effectList = returnFiber.effectList || [];
effectList.push(childToDelete);
returnFiber.effectList = effectList;
// delete child
var child = childToDelete.child;
if (child) {
child.effectType = ReactTypes_1.EffectType.Delete;
}
}