84
supportsMutation,
85
supportsPersistence,
86
cloneInstance,
87
+ cloneHiddenInstance,
88
+ cloneHiddenTextInstance,
89
createContainerChildSet,
90
appendChildToContainerChildSet,
91
finalizeContainerChildren,
130
enableProfilerTimer,
131
enableCache,
132
enableSuspenseLayoutEffectSemantics,
133
+ enablePersistentOffscreenHostContainer,
134
} from 'shared/ReactFeatureFlags';
135
import {
136
renderDidSuspend,
201
if (supportsMutation) {
202
// Mutation mode
203
201
- appendAllChildren = function(parent: Instance, workInProgress: Fiber) {
204
+ appendAllChildren = function(
205
+ parent: Instance,
206
+ workInProgress: Fiber,
207
+ needsVisibilityToggle: boolean,
208
+ isHidden: boolean,
209
+ ) {
210
// We only have the top Fiber that was created but we need recurse down its
211
// children to find all the terminal nodes.
212
let node = workInProgress.child;
294
} else if (supportsPersistence) {
295
// Persistent host tree mode
296
289
- appendAllChildren = function(parent: Instance, workInProgress: Fiber) {
297
+ appendAllChildren = function(
298
+ parent: Instance,
299
+ workInProgress: Fiber,
300
+ needsVisibilityToggle: boolean,
301
+ isHidden: boolean,
302
+ ) {
303
// We only have the top Fiber that was created but we need recurse down its
304
// children to find all the terminal nodes.
305
let node = workInProgress.child;
306
while (node !== null) {
307
// eslint-disable-next-line no-labels
308
branches: if (node.tag === HostComponent) {
296
- const instance = node.stateNode;
309
+ let instance = node.stateNode;
310
+ if (needsVisibilityToggle && isHidden) {
311
+ // This child is inside a timed out tree. Hide it.
312
+ const props = node.memoizedProps;
313
+ const type = node.type;
314
+ instance = cloneHiddenInstance(instance, type, props, node);
315
+ }
316
appendInitialChild(parent, instance);
317
} else if (node.tag === HostText) {
299
- const instance = node.stateNode;
318
+ let instance = node.stateNode;
319
+ if (needsVisibilityToggle && isHidden) {
320
+ // This child is inside a timed out tree. Hide it.
321
+ const text = node.memoizedProps;
322
+ instance = cloneHiddenTextInstance(instance, text, node);
323
+ }
324
appendInitialChild(parent, instance);
325
} else if (node.tag === HostPortal) {
326
// If we have a portal child, then we don't want to traverse
327
// down its children. Instead, we'll get insertions from each child in
328
// the portal directly.
329
+ } else if (
330
+ node.tag === OffscreenComponent &&
331
+ node.memoizedState !== null
332
+ ) {
333
+ // The children in this boundary are hidden. Toggle their visibility
334
+ // before appending.
335
+ const child = node.child;
336
+ if (child !== null) {
337
+ child.return = node;
338
+ }
339
+ if (enablePersistentOffscreenHostContainer) {
340
+ appendAllChildren(parent, node, false, false);
341
+ } else {
342
+ appendAllChildren(parent, node, true, true);
343
+ }
344
} else if (node.child !== null) {
345
node.child.return = node;
346
node = node.child;
366
const appendAllChildrenToContainer = function(
367
containerChildSet: ChildSet,
368
workInProgress: Fiber,
369
+ needsVisibilityToggle: boolean,
370
+ isHidden: boolean,
371
) {
372
// We only have the top Fiber that was created but we need recurse down its
373
// children to find all the terminal nodes.
375
while (node !== null) {
376
// eslint-disable-next-line no-labels
377
branches: if (node.tag === HostComponent) {
337
- const instance = node.stateNode;
378
+ let instance = node.stateNode;
379
+ if (needsVisibilityToggle && isHidden) {
380
+ // This child is inside a timed out tree. Hide it.
381
+ const props = node.memoizedProps;
382
+ const type = node.type;
383
+ instance = cloneHiddenInstance(instance, type, props, node);
384
+ }
385
appendChildToContainerChildSet(containerChildSet, instance);
386
} else if (node.tag === HostText) {
340
- const instance = node.stateNode;
387
+ let instance = node.stateNode;
388
+ if (needsVisibilityToggle && isHidden) {
389
+ // This child is inside a timed out tree. Hide it.
390
+ const text = node.memoizedProps;
391
+ instance = cloneHiddenTextInstance(instance, text, node);
392
+ }
393
appendChildToContainerChildSet(containerChildSet, instance);
394
} else if (node.tag === HostPortal) {
395
// If we have a portal child, then we don't want to traverse
396
// down its children. Instead, we'll get insertions from each child in
397
// the portal directly.
398
+ } else if (
399
+ node.tag === OffscreenComponent &&
400
+ node.memoizedState !== null
401
+ ) {
402
+ // The children in this boundary are hidden. Toggle their visibility
403
+ // before appending.
404
+ const child = node.child;
405
+ if (child !== null) {
406
+ child.return = node;
407
+ }
408
+ if (enablePersistentOffscreenHostContainer) {
409
+ appendAllChildrenToContainer(containerChildSet, node, false, false);
410
+ } else {
411
+ appendAllChildrenToContainer(containerChildSet, node, true, true);
412
+ }
413
} else if (node.child !== null) {
414
node.child.return = node;
415
node = node.child;
443
const container = portalOrRoot.containerInfo;
444
const newChildSet = createContainerChildSet(container);
445
// If children might have changed, we have to add them all to the set.
379
- appendAllChildrenToContainer(newChildSet, workInProgress);
446
+ appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
447
portalOrRoot.pendingChildren = newChildSet;
448
// Schedule an update on the container to swap out the container.
449
markUpdate(workInProgress);
516
markUpdate(workInProgress);
517
} else {
518
// If children might have changed, we have to add them all to the set.
452
- appendAllChildren(newInstance, workInProgress);
519
+ appendAllChildren(newInstance, workInProgress, false, false);
520
}
521
};
522
updateHostText = function(
789
workInProgress,
790
);
791
725
- appendAllChildren(instance, workInProgress);
792
+ appendAllChildren(instance, workInProgress, false, false);
793
794
workInProgress.stateNode = instance;
795
936
workInProgress,
937
);
938
872
- appendAllChildren(instance, workInProgress);
939
+ appendAllChildren(instance, workInProgress, false, false);
940
941
workInProgress.stateNode = instance;
942