11
12
import type {ReactElement} from 'shared/ReactElementType';
13
import type {Fiber, FiberRoot} from './ReactInternalTypes';
14
-import type {Instance} from './ReactFiberConfig';
14
import type {ReactNodeList} from 'shared/ReactTypes';
15
16
import {
26
ClassComponent,
27
FunctionComponent,
28
ForwardRef,
30
- HostComponent,
31
- HostHoistable,
32
- HostSingleton,
33
- HostPortal,
34
- HostRoot,
29
MemoComponent,
30
SimpleMemoComponent,
31
} from './ReactWorkTags';
34
REACT_MEMO_TYPE,
35
REACT_LAZY_TYPE,
36
} from 'shared/ReactSymbols';
43
-import {supportsSingletons} from './ReactFiberConfig';
37
38
export type Family = {
39
current: any,
51
export type SetRefreshHandler = (handler: RefreshHandler | null) => void;
52
export type ScheduleRefresh = (root: FiberRoot, update: RefreshUpdate) => void;
53
export type ScheduleRoot = (root: FiberRoot, element: ReactNodeList) => void;
61
-export type FindHostInstancesForRefresh = (
62
- root: FiberRoot,
63
- families: Array<Family>,
64
-) => Set<Instance>;
54
55
let resolveFamily: RefreshHandler | null = null;
56
let failedBoundaries: WeakSet<Fiber> | null = null;
332
}
333
}
334
}
346
-
347
-export const findHostInstancesForRefresh: FindHostInstancesForRefresh = (
348
- root: FiberRoot,
349
- families: Array<Family>,
350
-): Set<Instance> => {
351
- if (__DEV__) {
352
- const hostInstances = new Set<Instance>();
353
- const types = new Set(families.map(family => family.current));
354
- findHostInstancesForMatchingFibersRecursively(
355
- root.current,
356
- types,
357
- hostInstances,
358
- );
359
- return hostInstances;
360
- } else {
361
- throw new Error(
362
- 'Did not expect findHostInstancesForRefresh to be called in production.',
363
- );
364
- }
365
-};
366
-
367
-function findHostInstancesForMatchingFibersRecursively(
368
- fiber: Fiber,
369
- types: Set<any>,
370
- hostInstances: Set<Instance>,
371
-) {
372
- if (__DEV__) {
373
- const {child, sibling, tag, type} = fiber;
374
-
375
- let candidateType = null;
376
- switch (tag) {
377
- case FunctionComponent:
378
- case SimpleMemoComponent:
379
- case ClassComponent:
380
- candidateType = type;
381
- break;
382
- case ForwardRef:
383
- candidateType = type.render;
384
- break;
385
- default:
386
- break;
387
- }
388
-
389
- let didMatch = false;
390
- if (candidateType !== null) {
391
- if (types.has(candidateType)) {
392
- didMatch = true;
393
- }
394
- }
395
-
396
- if (didMatch) {
397
- // We have a match. This only drills down to the closest host components.
398
- // There's no need to search deeper because for the purpose of giving
399
- // visual feedback, "flashing" outermost parent rectangles is sufficient.
400
- findHostInstancesForFiberShallowly(fiber, hostInstances);
401
- } else {
402
- // If there's no match, maybe there will be one further down in the child tree.
403
- if (child !== null) {
404
- findHostInstancesForMatchingFibersRecursively(
405
- child,
406
- types,
407
- hostInstances,
408
- );
409
- }
410
- }
411
-
412
- if (sibling !== null) {
413
- findHostInstancesForMatchingFibersRecursively(
414
- sibling,
415
- types,
416
- hostInstances,
417
- );
418
- }
419
- }
420
-}
421
-
422
-function findHostInstancesForFiberShallowly(
423
- fiber: Fiber,
424
- hostInstances: Set<Instance>,
425
-): void {
426
- if (__DEV__) {
427
- const foundHostInstances = findChildHostInstancesForFiberShallowly(
428
- fiber,
429
- hostInstances,
430
- );
431
- if (foundHostInstances) {
432
- return;
433
- }
434
- // If we didn't find any host children, fallback to closest host parent.
435
- let node = fiber;
436
- while (true) {
437
- switch (node.tag) {
438
- case HostSingleton:
439
- case HostComponent:
440
- hostInstances.add(node.stateNode);
441
- return;
442
- case HostPortal:
443
- hostInstances.add(node.stateNode.containerInfo);
444
- return;
445
- case HostRoot:
446
- hostInstances.add(node.stateNode.containerInfo);
447
- return;
448
- }
449
- if (node.return === null) {
450
- throw new Error('Expected to reach root first.');
451
- }
452
- node = node.return;
453
- }
454
- }
455
-}
456
-
457
-function findChildHostInstancesForFiberShallowly(
458
- fiber: Fiber,
459
- hostInstances: Set<Instance>,
460
-): boolean {
461
- if (__DEV__) {
462
- let node: Fiber = fiber;
463
- let foundHostInstances = false;
464
- while (true) {
465
- if (
466
- node.tag === HostComponent ||
467
- node.tag === HostHoistable ||
468
- (supportsSingletons ? node.tag === HostSingleton : false)
469
- ) {
470
- // We got a match.
471
- foundHostInstances = true;
472
- hostInstances.add(node.stateNode);
473
- // There may still be more, so keep searching.
474
- } else if (node.child !== null) {
475
- node.child.return = node;
476
- node = node.child;
477
- continue;
478
- }
479
- if (node === fiber) {
480
- return foundHostInstances;
481
- }
482
- while (node.sibling === null) {
483
- if (node.return === null || node.return === fiber) {
484
- return foundHostInstances;
485
- }
486
- node = node.return;
487
- }
488
- node.sibling.return = node.return;
489
- node = node.sibling;
490
- }
491
- }
492
- return false;
493
-}