84
supportsMutation,
85
supportsPersistence,
86
cloneInstance,
87
- cloneHiddenInstance,
88
- cloneHiddenTextInstance,
87
createContainerChildSet,
88
appendChildToContainerChildSet,
89
finalizeContainerChildren,
198
if (supportsMutation) {
199
// Mutation mode
200
203
- appendAllChildren = function(
204
- parent: Instance,
205
- workInProgress: Fiber,
206
- needsVisibilityToggle: boolean,
207
- isHidden: boolean,
208
- ) {
201
+ appendAllChildren = function(parent: Instance, workInProgress: Fiber) {
202
// We only have the top Fiber that was created but we need recurse down its
203
// children to find all the terminal nodes.
204
let node = workInProgress.child;
286
} else if (supportsPersistence) {
287
// Persistent host tree mode
288
296
- appendAllChildren = function(
297
- parent: Instance,
298
- workInProgress: Fiber,
299
- needsVisibilityToggle: boolean,
300
- isHidden: boolean,
301
- ) {
289
+ appendAllChildren = function(parent: Instance, workInProgress: Fiber) {
290
// We only have the top Fiber that was created but we need recurse down its
291
// children to find all the terminal nodes.
292
let node = workInProgress.child;
293
while (node !== null) {
294
// eslint-disable-next-line no-labels
295
branches: if (node.tag === HostComponent) {
308
- let instance = node.stateNode;
309
- if (needsVisibilityToggle && isHidden) {
310
- // This child is inside a timed out tree. Hide it.
311
- const props = node.memoizedProps;
312
- const type = node.type;
313
- instance = cloneHiddenInstance(instance, type, props, node);
314
- }
296
+ const instance = node.stateNode;
297
appendInitialChild(parent, instance);
298
} else if (node.tag === HostText) {
317
- let instance = node.stateNode;
318
- if (needsVisibilityToggle && isHidden) {
319
- // This child is inside a timed out tree. Hide it.
320
- const text = node.memoizedProps;
321
- instance = cloneHiddenTextInstance(instance, text, node);
322
- }
299
+ const instance = node.stateNode;
300
appendInitialChild(parent, instance);
301
} else if (node.tag === HostPortal) {
302
// If we have a portal child, then we don't want to traverse
303
// down its children. Instead, we'll get insertions from each child in
304
// the portal directly.
328
- } else if (
329
- node.tag === OffscreenComponent &&
330
- node.memoizedState !== null
331
- ) {
332
- // The children in this boundary are hidden. Toggle their visibility
333
- // before appending.
334
- const child = node.child;
335
- if (child !== null) {
336
- child.return = node;
337
- }
338
- appendAllChildren(parent, node, true, true);
305
} else if (node.child !== null) {
306
node.child.return = node;
307
node = node.child;
327
const appendAllChildrenToContainer = function(
328
containerChildSet: ChildSet,
329
workInProgress: Fiber,
364
- needsVisibilityToggle: boolean,
365
- isHidden: boolean,
330
) {
331
// We only have the top Fiber that was created but we need recurse down its
332
// children to find all the terminal nodes.
334
while (node !== null) {
335
// eslint-disable-next-line no-labels
336
branches: if (node.tag === HostComponent) {
373
- let instance = node.stateNode;
374
- if (needsVisibilityToggle && isHidden) {
375
- // This child is inside a timed out tree. Hide it.
376
- const props = node.memoizedProps;
377
- const type = node.type;
378
- instance = cloneHiddenInstance(instance, type, props, node);
379
- }
337
+ const instance = node.stateNode;
338
appendChildToContainerChildSet(containerChildSet, instance);
339
} else if (node.tag === HostText) {
382
- let instance = node.stateNode;
383
- if (needsVisibilityToggle && isHidden) {
384
- // This child is inside a timed out tree. Hide it.
385
- const text = node.memoizedProps;
386
- instance = cloneHiddenTextInstance(instance, text, node);
387
- }
340
+ const instance = node.stateNode;
341
appendChildToContainerChildSet(containerChildSet, instance);
342
} else if (node.tag === HostPortal) {
343
// If we have a portal child, then we don't want to traverse
344
// down its children. Instead, we'll get insertions from each child in
345
// the portal directly.
393
- } else if (
394
- node.tag === OffscreenComponent &&
395
- node.memoizedState !== null
396
- ) {
397
- // The children in this boundary are hidden. Toggle their visibility
398
- // before appending.
399
- const child = node.child;
400
- if (child !== null) {
401
- child.return = node;
402
- }
403
- appendAllChildrenToContainer(containerChildSet, node, true, true);
346
} else if (node.child !== null) {
347
node.child.return = node;
348
node = node.child;
376
const container = portalOrRoot.containerInfo;
377
const newChildSet = createContainerChildSet(container);
378
// If children might have changed, we have to add them all to the set.
437
- appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
379
+ appendAllChildrenToContainer(newChildSet, workInProgress);
380
portalOrRoot.pendingChildren = newChildSet;
381
// Schedule an update on the container to swap out the container.
382
markUpdate(workInProgress);
449
markUpdate(workInProgress);
450
} else {
451
// If children might have changed, we have to add them all to the set.
510
- appendAllChildren(newInstance, workInProgress, false, false);
452
+ appendAllChildren(newInstance, workInProgress);
453
}
454
};
455
updateHostText = function(
690
return didBailout;
691
}
692
693
+export function completeSuspendedOffscreenHostContainer(
694
+ current: Fiber | null,
695
+ workInProgress: Fiber,
696
+) {
697
+ // This is a fork of the complete phase for HostComponent. We use it when
698
+ // a suspense tree is in its fallback state, because in that case the primary
699
+ // tree that includes the offscreen boundary is skipped over without a
700
+ // regular complete phase.
701
+ //
702
+ // We can optimize this path further by inlining the update logic for
703
+ // offscreen instances specifically, i.e. skipping the `prepareUpdate` call.
704
+ const rootContainerInstance = getRootHostContainer();
705
+ const type = workInProgress.type;
706
+ const newProps = workInProgress.memoizedProps;
707
+ if (current !== null) {
708
+ updateHostComponent(
709
+ current,
710
+ workInProgress,
711
+ type,
712
+ newProps,
713
+ rootContainerInstance,
714
+ );
715
+ } else {
716
+ const currentHostContext = getHostContext();
717
+ const instance = createInstance(
718
+ type,
719
+ newProps,
720
+ rootContainerInstance,
721
+ currentHostContext,
722
+ workInProgress,
723
+ );
724
+
725
+ appendAllChildren(instance, workInProgress);
726
+
727
+ workInProgress.stateNode = instance;
728
+
729
+ // Certain renderers require commit-time effects for initial mount.
730
+ // (eg DOM renderer supports auto-focus for certain elements).
731
+ // Make sure such renderers get scheduled for later work.
732
+ if (
733
+ finalizeInitialChildren(
734
+ instance,
735
+ type,
736
+ newProps,
737
+ rootContainerInstance,
738
+ currentHostContext,
739
+ )
740
+ ) {
741
+ markUpdate(workInProgress);
742
+ }
743
+
744
+ if (workInProgress.ref !== null) {
745
+ // If there is a ref on a host node we need to schedule a callback
746
+ markRef(workInProgress);
747
+ }
748
+ }
749
+ bubbleProperties(workInProgress);
750
+}
751
+
752
function completeWork(
753
current: Fiber | null,
754
workInProgress: Fiber,
869
workInProgress,
870
);
871
871
- appendAllChildren(instance, workInProgress, false, false);
872
+ appendAllChildren(instance, workInProgress);
873
874
workInProgress.stateNode = instance;
875