Skip to content

Commit 5772bb9

Browse files
committed
bump: version 0.4.1
1 parent b844f93 commit 5772bb9

File tree

4 files changed

+165
-146
lines changed

4 files changed

+165
-146
lines changed

lib/cjs/helpers.js

Lines changed: 79 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ exports.FiberVisit = Object.freeze({
5353
Return: 0b000100,
5454
Effect: 0b001000,
5555
Break: 0b010000,
56+
SiblingFirst: 0b100000,
5657
});
5758
exports.FiberTag = Object.freeze({
5859
FunctionComponent: 0,
@@ -126,21 +127,30 @@ const isHostFiber = (fiber) => {
126127
}
127128
return false;
128129
};
129-
const pushVisitStack = (stack, scope, fiber, flags) => {
130-
if (scope !== fiber && flags === exports.FiberVisit.Child) {
130+
const pushVisitStack = (stack, scope, fiber, flags, callback) => {
131+
if (flags === exports.FiberVisit.Return) {
132+
fiber.return && stack.push(fiber.return);
133+
return;
134+
}
135+
if (flags === exports.FiberVisit.Effect) {
136+
fiber.nextEffect && stack.push(fiber.nextEffect);
137+
return;
138+
}
139+
if (scope !== fiber && (flags & ~exports.FiberVisit.SiblingFirst) === exports.FiberVisit.Child) {
131140
flags |= exports.FiberVisit.Sibling;
132141
}
142+
const siblingFirst = flags & exports.FiberVisit.SiblingFirst;
133143
if (flags & exports.FiberVisit.Sibling) {
134-
fiber.sibling && stack.push(fiber.sibling);
144+
siblingFirst || fiber.sibling && stack.push(fiber.sibling);
145+
}
146+
if (isFunction(callback)) {
147+
stack.push(callback);
135148
}
136149
if (flags & exports.FiberVisit.Child) {
137150
fiber.child && stack.push(fiber.child);
138151
}
139-
if (flags === exports.FiberVisit.Return) {
140-
fiber.return && stack.push(fiber.return);
141-
}
142-
if (flags === exports.FiberVisit.Effect) {
143-
fiber.nextEffect && stack.push(fiber.nextEffect);
152+
if (flags & exports.FiberVisit.Sibling) {
153+
siblingFirst && fiber.sibling && stack.push(fiber.sibling);
144154
}
145155
};
146156
const findFiber = (fiber, predicate, flags = exports.FiberVisit.Child) => {
@@ -156,7 +166,7 @@ const findFiber = (fiber, predicate, flags = exports.FiberVisit.Child) => {
156166
if (predicate(current)) {
157167
return current;
158168
}
159-
pushVisitStack(stack, fiber, current, flags);
169+
pushVisitStack(stack, fiber, current, flags, null);
160170
}
161171
return null;
162172
};
@@ -175,7 +185,7 @@ const findFibers = (fiber, predicate, flags = exports.FiberVisit.Child) => {
175185
if (predicate(current)) {
176186
result.push(current);
177187
}
178-
pushVisitStack(stack, fiber, current, flags);
188+
pushVisitStack(stack, fiber, current, flags, null);
179189
}
180190
return result;
181191
};
@@ -206,10 +216,7 @@ const traverseFiber = (fiber, visit, flags = exports.FiberVisit.Child) => {
206216
if (post === exports.FiberVisit.Break) {
207217
continue;
208218
}
209-
if (isFunction(post)) {
210-
stack.push(post);
211-
}
212-
pushVisitStack(stack, fiber, current, flags);
219+
pushVisitStack(stack, fiber, current, flags, post);
213220
}
214221
};
215222
exports.traverseFiber = traverseFiber;
@@ -226,10 +233,10 @@ const findChildHostFibers = (fiber) => {
226233
}
227234
if (isHostFiber(current)) {
228235
result.push(current);
229-
pushVisitStack(stack, fiber, current, exports.FiberVisit.Sibling);
236+
pushVisitStack(stack, fiber, current, exports.FiberVisit.Sibling, null);
230237
}
231238
else {
232-
pushVisitStack(stack, fiber, current, exports.FiberVisit.Child | exports.FiberVisit.Sibling);
239+
pushVisitStack(stack, fiber, current, exports.FiberVisit.Child | exports.FiberVisit.Sibling, null);
233240
}
234241
}
235242
return result;
@@ -438,15 +445,13 @@ const appendFiberEffect = (rootFiber, effectFiber, renderFiber, finishFiber) =>
438445
rootFiber[FiberEffectProp] |= flags;
439446
fiber[FiberEffectProp] |= flags;
440447
fiber.nextEffect = null;
441-
return () => {
442-
if (exports.FiberFlag.NoFlags === (fiber[FiberEffectProp] & exports.FiberFlag.LifecycleEffectMask)) {
443-
return;
444-
}
448+
if (exports.FiberFlag.NoFlags !== (fiber[FiberEffectProp] & exports.FiberFlag.LifecycleEffectMask)) {
445449
const nextEffect = effectFiber.nextEffect;
446450
effectFiber.nextEffect = fiber;
447451
fiber.nextEffect = nextEffect;
448-
};
449-
});
452+
}
453+
return null;
454+
}, exports.FiberVisit.Child | exports.FiberVisit.SiblingFirst);
450455
}
451456
};
452457
exports.appendFiberEffect = appendFiberEffect;
@@ -458,7 +463,7 @@ const defineFiberProp = (fiber, prop, value) => {
458463
value,
459464
});
460465
};
461-
const protectFiberProp = (fiber, prop, restore) => {
466+
const protectFiberProp = (fiber, prop, restore, needDummy) => {
462467
if (null == fiber) {
463468
return;
464469
}
@@ -468,12 +473,11 @@ const protectFiberProp = (fiber, prop, restore) => {
468473
}
469474
const backup = fiber[prop];
470475
let value = backup;
471-
if (!restore.current && prop === 'stateNode' && isHostFiber(fiber)) {
476+
if (needDummy && prop === 'stateNode' && isHostFiber(fiber)) {
472477
value = null;
473478
if (backup === null || backup === void 0 ? void 0 : backup.parentNode) {
474-
const dummy = document.createElement('div');
475-
backup.parentNode.appendChild(dummy);
476-
value = dummy;
479+
value = document.createElement('dummy');
480+
backup.parentNode.appendChild(value);
477481
}
478482
}
479483
Object.defineProperty(fiber, prop, {
@@ -492,13 +496,13 @@ const restoreFiberProp = (fiber, prop) => {
492496
defineFiberProp(fiber, prop, fiber[prop]);
493497
}
494498
};
495-
const protectFiberProps = (fiber, current, restore) => {
499+
const protectFiberProps = (fiber, current, restore, needDummy) => {
496500
const alternate = fiber.alternate;
497501
if (alternate && !current) {
498-
protectFiberProps(alternate, fiber, restore);
502+
protectFiberProps(alternate, fiber, restore, false);
499503
}
500504
for (const prop of ProtectedFiberProps) {
501-
protectFiberProp(fiber, prop, restore);
505+
protectFiberProp(fiber, prop, restore, needDummy);
502506
}
503507
};
504508
const restoreFiberProps = (fiber, current) => {
@@ -513,57 +517,62 @@ const restoreFiberProps = (fiber, current) => {
513517
}
514518
}
515519
};
516-
const protectChildHostNodes = (fiber, restore) => {
517-
const hostFibers = (0, exports.findChildHostFibers)(fiber);
518-
hostFibers.forEach((hostFiber) => {
519-
protectFiberProp(hostFiber, 'stateNode', restore);
520-
const hostNode = getHostNode(hostFiber);
521-
const parentNode = hostNode === null || hostNode === void 0 ? void 0 : hostNode.parentNode;
522-
if (hostNode && parentNode) {
523-
const dummy = document.createElement('div');
524-
parentNode.replaceChild(dummy, hostNode);
525-
hostFiber.stateNode = dummy;
526-
}
527-
});
528-
};
529520
const protectFiber = (fiber) => {
530521
const restore = { current: true };
531-
const portalFibers = (0, exports.findFibers)(fiber, (node) => node.tag === exports.FiberTag.HostPortal);
532-
portalFibers.forEach((portalFiber) => protectChildHostNodes(portalFiber.child, restore));
533-
protectChildHostNodes(fiber, restore);
522+
const stack = [true];
523+
(0, exports.traverseFiber)(fiber, (node) => {
524+
const needDummy = isHostFiber(node) && true === stack[0];
525+
if (needDummy) {
526+
protectFiberProp(node, 'stateNode', restore, false);
527+
const hostNode = getHostNode(node);
528+
const parentNode = hostNode === null || hostNode === void 0 ? void 0 : hostNode.parentNode;
529+
if (hostNode && parentNode) {
530+
const dummy = document.createElement('dummy');
531+
parentNode.replaceChild(dummy, hostNode);
532+
node.stateNode = dummy;
533+
}
534+
}
535+
if (UseDeepDetach || node === fiber) {
536+
protectFiberProps(node, null, restore, true);
537+
}
538+
if (node.tag === exports.FiberTag.HostPortal) {
539+
stack.unshift(true);
540+
return () => stack.shift();
541+
}
542+
if (needDummy) {
543+
stack.unshift(false);
544+
return () => stack.shift();
545+
}
546+
return null;
547+
});
534548
restore.current = false;
535-
if (UseDeepDetach) {
536-
(0, exports.traverseFiber)(fiber, (node) => () => {
537-
protectFiberProps(node, null, restore);
538-
});
539-
}
540-
else {
541-
protectFiberProps(fiber, null, restore);
542-
}
543549
return restore;
544550
};
545551
exports.protectFiber = protectFiber;
546552
const restoreFiber = (fiber, restore) => {
547553
restore.current = true;
548-
if (UseDeepDetach) {
549-
(0, exports.traverseFiber)(fiber, (node) => () => {
554+
const stack = [true];
555+
(0, exports.traverseFiber)(fiber, (node) => {
556+
const needRestore = isHostFiber(node) && true === stack[0];
557+
if (UseDeepDetach || node === fiber) {
550558
restoreFiberProps(node, null);
551-
traverseEffectHooks(node, (effect) => {
552-
effect.destroy = undefined;
553-
});
554-
});
555-
}
556-
else {
557-
restoreFiberProps(fiber, null);
558-
(0, exports.findChildHostFibers)(fiber).forEach((node) => {
559+
}
560+
else if (needRestore) {
559561
restoreFiberProp(node, 'stateNode');
562+
}
563+
traverseEffectHooks(node, (effect) => {
564+
effect.destroy = undefined;
560565
});
561-
(0, exports.traverseFiber)(fiber, (node) => {
562-
traverseEffectHooks(node, (effect) => {
563-
effect.destroy = undefined;
564-
});
565-
});
566-
}
566+
if (node.tag === exports.FiberTag.HostPortal) {
567+
stack.unshift(true);
568+
return () => stack.shift();
569+
}
570+
if (needRestore) {
571+
stack.unshift(false);
572+
return () => stack.shift();
573+
}
574+
return null;
575+
});
567576
restore.current = false;
568577
};
569578
exports.restoreFiber = restoreFiber;

0 commit comments

Comments
 (0)