How to use isSuspenseBoundaryBeingHidden method in Playwright Internal

Best JavaScript code snippet using playwright-internal

ReactFiberCommitWork.new.js

Source:ReactFiberCommitWork.new.js Github

copy

Full Screen

...335 // Check to see if the focused element was inside of a hidden (Suspense) subtree.336 // TODO: Move this out of the hot path using a dedicated effect tag.337 if (338 finishedWork.tag === SuspenseComponent &&339 isSuspenseBoundaryBeingHidden(current, finishedWork) &&340 doesFiberContain(finishedWork, focusedInstanceHandle)341 ) {342 shouldFireAfterActiveInstanceBlur = true;343 beforeActiveInstanceBlur(finishedWork);344 }345 }346 if ((flags & Snapshot) !== NoFlags) {347 setCurrentDebugFiberInDEV(finishedWork);348 switch (finishedWork.tag) {349 case FunctionComponent:350 case ForwardRef:351 case SimpleMemoComponent: {352 break;353 }354 case ClassComponent: {355 if (current !== null) {356 const prevProps = current.memoizedProps;357 const prevState = current.memoizedState;358 const instance = finishedWork.stateNode;359 // We could update instance props and state here,360 // but instead we rely on them being set during last render.361 // TODO: revisit this when we implement resuming.362 if (__DEV__) {363 if (364 finishedWork.type === finishedWork.elementType &&365 !didWarnAboutReassigningProps366 ) {367 if (instance.props !== finishedWork.memoizedProps) {368 console.error(369 'Expected %s props to match memoized props before ' +370 'getSnapshotBeforeUpdate. ' +371 'This might either be because of a bug in React, or because ' +372 'a component reassigns its own `this.props`. ' +373 'Please file an issue.',374 getComponentName(finishedWork.type) || 'instance',375 );376 }377 if (instance.state !== finishedWork.memoizedState) {378 console.error(379 'Expected %s state to match memoized state before ' +380 'getSnapshotBeforeUpdate. ' +381 'This might either be because of a bug in React, or because ' +382 'a component reassigns its own `this.state`. ' +383 'Please file an issue.',384 getComponentName(finishedWork.type) || 'instance',385 );386 }387 }388 }389 const snapshot = instance.getSnapshotBeforeUpdate(390 finishedWork.elementType === finishedWork.type391 ? prevProps392 : resolveDefaultProps(finishedWork.type, prevProps),393 prevState,394 );395 if (__DEV__) {396 const didWarnSet = ((didWarnAboutUndefinedSnapshotBeforeUpdate: any): Set<mixed>);397 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {398 didWarnSet.add(finishedWork.type);399 console.error(400 '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' +401 'must be returned. You have returned undefined.',402 getComponentName(finishedWork.type),403 );404 }405 }406 instance.__reactInternalSnapshotBeforeUpdate = snapshot;407 }408 break;409 }410 case HostRoot: {411 if (supportsMutation) {412 const root = finishedWork.stateNode;413 clearContainer(root.containerInfo);414 }415 break;416 }417 case HostComponent:418 case HostText:419 case HostPortal:420 case IncompleteClassComponent:421 // Nothing to do for these component types422 break;423 default: {424 invariant(425 false,426 'This unit of work tag should not have side-effects. This error is ' +427 'likely caused by a bug in React. Please file an issue.',428 );429 }430 }431 resetCurrentDebugFiberInDEV();432 }433}434function commitBeforeMutationEffectsDeletion(deletion: Fiber) {435 // TODO (effects) It would be nice to avoid calling doesFiberContain()436 // Maybe we can repurpose one of the subtreeFlags positions for this instead?437 // Use it to store which part of the tree the focused instance is in?438 // This assumes we can safely determine that instance during the "render" phase.439 if (doesFiberContain(deletion, ((focusedInstanceHandle: any): Fiber))) {440 shouldFireAfterActiveInstanceBlur = true;441 beforeActiveInstanceBlur(deletion);442 }443}444function commitHookEffectListUnmount(445 flags: HookFlags,446 finishedWork: Fiber,447 nearestMountedAncestor: Fiber | null,448) {449 const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);450 const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;451 if (lastEffect !== null) {452 const firstEffect = lastEffect.next;453 let effect = firstEffect;454 do {455 if ((effect.tag & flags) === flags) {456 // Unmount457 const destroy = effect.destroy;458 effect.destroy = undefined;459 if (destroy !== undefined) {460 safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);461 }462 }463 effect = effect.next;464 } while (effect !== firstEffect);465 }466}467function commitHookEffectListMount(tag: number, finishedWork: Fiber) {468 const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);469 const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;470 if (lastEffect !== null) {471 const firstEffect = lastEffect.next;472 let effect = firstEffect;473 do {474 if ((effect.tag & tag) === tag) {475 // Mount476 const create = effect.create;477 effect.destroy = create();478 if (__DEV__) {479 const destroy = effect.destroy;480 if (destroy !== undefined && typeof destroy !== 'function') {481 let addendum;482 if (destroy === null) {483 addendum =484 ' You returned null. If your effect does not require clean ' +485 'up, return undefined (or nothing).';486 } else if (typeof destroy.then === 'function') {487 addendum =488 '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' +489 'Instead, write the async function inside your effect ' +490 'and call it immediately:\n\n' +491 'useEffect(() => {\n' +492 ' async function fetchData() {\n' +493 ' // You can await here\n' +494 ' const response = await MyAPI.getData(someId);\n' +495 ' // ...\n' +496 ' }\n' +497 ' fetchData();\n' +498 `}, [someId]); // Or [] if effect doesn't need props or state\n\n` +499 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching';500 } else {501 addendum = ' You returned: ' + destroy;502 }503 console.error(504 'An effect function must not return anything besides a function, ' +505 'which is used for clean-up.%s',506 addendum,507 );508 }509 }510 }511 effect = effect.next;512 } while (effect !== firstEffect);513 }514}515export function commitPassiveEffectDurations(516 finishedRoot: FiberRoot,517 finishedWork: Fiber,518): void {519 if (enableProfilerTimer && enableProfilerCommitHooks) {520 // Only Profilers with work in their subtree will have an Update effect scheduled.521 if ((finishedWork.flags & Update) !== NoFlags) {522 switch (finishedWork.tag) {523 case Profiler: {524 const {passiveEffectDuration} = finishedWork.stateNode;525 const {id, onPostCommit} = finishedWork.memoizedProps;526 // This value will still reflect the previous commit phase.527 // It does not get reset until the start of the next commit phase.528 const commitTime = getCommitTime();529 let phase = finishedWork.alternate === null ? 'mount' : 'update';530 if (enableProfilerNestedUpdatePhase) {531 if (isCurrentUpdateNested()) {532 phase = 'nested-update';533 }534 }535 if (typeof onPostCommit === 'function') {536 if (enableSchedulerTracing) {537 onPostCommit(538 id,539 phase,540 passiveEffectDuration,541 commitTime,542 finishedRoot.memoizedInteractions,543 );544 } else {545 onPostCommit(id, phase, passiveEffectDuration, commitTime);546 }547 }548 // Bubble times to the next nearest ancestor Profiler.549 // After we process that Profiler, we'll bubble further up.550 let parentFiber = finishedWork.return;551 while (parentFiber !== null) {552 if (parentFiber.tag === Profiler) {553 const parentStateNode = parentFiber.stateNode;554 parentStateNode.passiveEffectDuration += passiveEffectDuration;555 break;556 }557 parentFiber = parentFiber.return;558 }559 break;560 }561 default:562 break;563 }564 }565 }566}567function commitLayoutEffectOnFiber(568 finishedRoot: FiberRoot,569 current: Fiber | null,570 finishedWork: Fiber,571 committedLanes: Lanes,572): void {573 if ((finishedWork.flags & (Update | Callback)) !== NoFlags) {574 switch (finishedWork.tag) {575 case FunctionComponent:576 case ForwardRef:577 case SimpleMemoComponent: {578 // At this point layout effects have already been destroyed (during mutation phase).579 // This is done to prevent sibling component effects from interfering with each other,580 // e.g. a destroy function in one component should never override a ref set581 // by a create function in another component during the same commit.582 if (583 enableProfilerTimer &&584 enableProfilerCommitHooks &&585 finishedWork.mode & ProfileMode586 ) {587 try {588 startLayoutEffectTimer();589 commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);590 } finally {591 recordLayoutEffectDuration(finishedWork);592 }593 } else {594 commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);595 }596 break;597 }598 case ClassComponent: {599 const instance = finishedWork.stateNode;600 if (finishedWork.flags & Update) {601 if (current === null) {602 // We could update instance props and state here,603 // but instead we rely on them being set during last render.604 // TODO: revisit this when we implement resuming.605 if (__DEV__) {606 if (607 finishedWork.type === finishedWork.elementType &&608 !didWarnAboutReassigningProps609 ) {610 if (instance.props !== finishedWork.memoizedProps) {611 console.error(612 'Expected %s props to match memoized props before ' +613 'componentDidMount. ' +614 'This might either be because of a bug in React, or because ' +615 'a component reassigns its own `this.props`. ' +616 'Please file an issue.',617 getComponentName(finishedWork.type) || 'instance',618 );619 }620 if (instance.state !== finishedWork.memoizedState) {621 console.error(622 'Expected %s state to match memoized state before ' +623 'componentDidMount. ' +624 'This might either be because of a bug in React, or because ' +625 'a component reassigns its own `this.state`. ' +626 'Please file an issue.',627 getComponentName(finishedWork.type) || 'instance',628 );629 }630 }631 }632 if (633 enableProfilerTimer &&634 enableProfilerCommitHooks &&635 finishedWork.mode & ProfileMode636 ) {637 try {638 startLayoutEffectTimer();639 instance.componentDidMount();640 } finally {641 recordLayoutEffectDuration(finishedWork);642 }643 } else {644 instance.componentDidMount();645 }646 } else {647 const prevProps =648 finishedWork.elementType === finishedWork.type649 ? current.memoizedProps650 : resolveDefaultProps(finishedWork.type, current.memoizedProps);651 const prevState = current.memoizedState;652 // We could update instance props and state here,653 // but instead we rely on them being set during last render.654 // TODO: revisit this when we implement resuming.655 if (__DEV__) {656 if (657 finishedWork.type === finishedWork.elementType &&658 !didWarnAboutReassigningProps659 ) {660 if (instance.props !== finishedWork.memoizedProps) {661 console.error(662 'Expected %s props to match memoized props before ' +663 'componentDidUpdate. ' +664 'This might either be because of a bug in React, or because ' +665 'a component reassigns its own `this.props`. ' +666 'Please file an issue.',667 getComponentName(finishedWork.type) || 'instance',668 );669 }670 if (instance.state !== finishedWork.memoizedState) {671 console.error(672 'Expected %s state to match memoized state before ' +673 'componentDidUpdate. ' +674 'This might either be because of a bug in React, or because ' +675 'a component reassigns its own `this.state`. ' +676 'Please file an issue.',677 getComponentName(finishedWork.type) || 'instance',678 );679 }680 }681 }682 if (683 enableProfilerTimer &&684 enableProfilerCommitHooks &&685 finishedWork.mode & ProfileMode686 ) {687 try {688 startLayoutEffectTimer();689 instance.componentDidUpdate(690 prevProps,691 prevState,692 instance.__reactInternalSnapshotBeforeUpdate,693 );694 } finally {695 recordLayoutEffectDuration(finishedWork);696 }697 } else {698 instance.componentDidUpdate(699 prevProps,700 prevState,701 instance.__reactInternalSnapshotBeforeUpdate,702 );703 }704 }705 }706 // TODO: I think this is now always non-null by the time it reaches the707 // commit phase. Consider removing the type check.708 const updateQueue: UpdateQueue<709 *,710 > | null = (finishedWork.updateQueue: any);711 if (updateQueue !== null) {712 if (__DEV__) {713 if (714 finishedWork.type === finishedWork.elementType &&715 !didWarnAboutReassigningProps716 ) {717 if (instance.props !== finishedWork.memoizedProps) {718 console.error(719 'Expected %s props to match memoized props before ' +720 'processing the update queue. ' +721 'This might either be because of a bug in React, or because ' +722 'a component reassigns its own `this.props`. ' +723 'Please file an issue.',724 getComponentName(finishedWork.type) || 'instance',725 );726 }727 if (instance.state !== finishedWork.memoizedState) {728 console.error(729 'Expected %s state to match memoized state before ' +730 'processing the update queue. ' +731 'This might either be because of a bug in React, or because ' +732 'a component reassigns its own `this.state`. ' +733 'Please file an issue.',734 getComponentName(finishedWork.type) || 'instance',735 );736 }737 }738 }739 // We could update instance props and state here,740 // but instead we rely on them being set during last render.741 // TODO: revisit this when we implement resuming.742 commitUpdateQueue(finishedWork, updateQueue, instance);743 }744 break;745 }746 case HostRoot: {747 // TODO: I think this is now always non-null by the time it reaches the748 // commit phase. Consider removing the type check.749 const updateQueue: UpdateQueue<750 *,751 > | null = (finishedWork.updateQueue: any);752 if (updateQueue !== null) {753 let instance = null;754 if (finishedWork.child !== null) {755 switch (finishedWork.child.tag) {756 case HostComponent:757 instance = getPublicInstance(finishedWork.child.stateNode);758 break;759 case ClassComponent:760 instance = finishedWork.child.stateNode;761 break;762 }763 }764 commitUpdateQueue(finishedWork, updateQueue, instance);765 }766 break;767 }768 case HostComponent: {769 const instance: Instance = finishedWork.stateNode;770 // Renderers may schedule work to be done after host components are mounted771 // (eg DOM renderer may schedule auto-focus for inputs and form controls).772 // These effects should only be committed when components are first mounted,773 // aka when there is no current/alternate.774 if (current === null && finishedWork.flags & Update) {775 const type = finishedWork.type;776 const props = finishedWork.memoizedProps;777 commitMount(instance, type, props, finishedWork);778 }779 break;780 }781 case HostText: {782 // We have no life-cycles associated with text.783 break;784 }785 case HostPortal: {786 // We have no life-cycles associated with portals.787 break;788 }789 case Profiler: {790 if (enableProfilerTimer) {791 const {onCommit, onRender} = finishedWork.memoizedProps;792 const {effectDuration} = finishedWork.stateNode;793 const commitTime = getCommitTime();794 let phase = current === null ? 'mount' : 'update';795 if (enableProfilerNestedUpdatePhase) {796 if (isCurrentUpdateNested()) {797 phase = 'nested-update';798 }799 }800 if (typeof onRender === 'function') {801 if (enableSchedulerTracing) {802 onRender(803 finishedWork.memoizedProps.id,804 phase,805 finishedWork.actualDuration,806 finishedWork.treeBaseDuration,807 finishedWork.actualStartTime,808 commitTime,809 finishedRoot.memoizedInteractions,810 );811 } else {812 onRender(813 finishedWork.memoizedProps.id,814 phase,815 finishedWork.actualDuration,816 finishedWork.treeBaseDuration,817 finishedWork.actualStartTime,818 commitTime,819 );820 }821 }822 if (enableProfilerCommitHooks) {823 if (typeof onCommit === 'function') {824 if (enableSchedulerTracing) {825 onCommit(826 finishedWork.memoizedProps.id,827 phase,828 effectDuration,829 commitTime,830 finishedRoot.memoizedInteractions,831 );832 } else {833 onCommit(834 finishedWork.memoizedProps.id,835 phase,836 effectDuration,837 commitTime,838 );839 }840 }841 // Schedule a passive effect for this Profiler to call onPostCommit hooks.842 // This effect should be scheduled even if there is no onPostCommit callback for this Profiler,843 // because the effect is also where times bubble to parent Profilers.844 enqueuePendingPassiveProfilerEffect(finishedWork);845 // Propagate layout effect durations to the next nearest Profiler ancestor.846 // Do not reset these values until the next render so DevTools has a chance to read them first.847 let parentFiber = finishedWork.return;848 while (parentFiber !== null) {849 if (parentFiber.tag === Profiler) {850 const parentStateNode = parentFiber.stateNode;851 parentStateNode.effectDuration += effectDuration;852 break;853 }854 parentFiber = parentFiber.return;855 }856 }857 }858 break;859 }860 case SuspenseComponent: {861 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);862 break;863 }864 case SuspenseListComponent:865 case IncompleteClassComponent:866 case FundamentalComponent:867 case ScopeComponent:868 case OffscreenComponent:869 case LegacyHiddenComponent:870 break;871 default:872 invariant(873 false,874 'This unit of work tag should not have side-effects. This error is ' +875 'likely caused by a bug in React. Please file an issue.',876 );877 }878 }879 if (enableScopeAPI) {880 // TODO: This is a temporary solution that allowed us to transition away881 // from React Flare on www.882 if (finishedWork.flags & Ref && finishedWork.tag !== ScopeComponent) {883 commitAttachRef(finishedWork);884 }885 } else {886 if (finishedWork.flags & Ref) {887 commitAttachRef(finishedWork);888 }889 }890}891function hideOrUnhideAllChildren(finishedWork, isHidden) {892 if (supportsMutation) {893 // We only have the top Fiber that was inserted but we need to recurse down its894 // children to find all the terminal nodes.895 let node: Fiber = finishedWork;896 while (true) {897 if (node.tag === HostComponent) {898 const instance = node.stateNode;899 if (isHidden) {900 hideInstance(instance);901 } else {902 unhideInstance(node.stateNode, node.memoizedProps);903 }904 } else if (node.tag === HostText) {905 const instance = node.stateNode;906 if (isHidden) {907 hideTextInstance(instance);908 } else {909 unhideTextInstance(instance, node.memoizedProps);910 }911 } else if (912 (node.tag === OffscreenComponent ||913 node.tag === LegacyHiddenComponent) &&914 (node.memoizedState: OffscreenState) !== null &&915 node !== finishedWork916 ) {917 // Found a nested Offscreen component that is hidden. Don't search918 // any deeper. This tree should remain hidden.919 } else if (node.child !== null) {920 node.child.return = node;921 node = node.child;922 continue;923 }924 if (node === finishedWork) {925 return;926 }927 while (node.sibling === null) {928 if (node.return === null || node.return === finishedWork) {929 return;930 }931 node = node.return;932 }933 node.sibling.return = node.return;934 node = node.sibling;935 }936 }937}938function commitAttachRef(finishedWork: Fiber) {939 const ref = finishedWork.ref;940 if (ref !== null) {941 const instance = finishedWork.stateNode;942 let instanceToUse;943 switch (finishedWork.tag) {944 case HostComponent:945 instanceToUse = getPublicInstance(instance);946 break;947 default:948 instanceToUse = instance;949 }950 // Moved outside to ensure DCE works with this flag951 if (enableScopeAPI && finishedWork.tag === ScopeComponent) {952 instanceToUse = instance;953 }954 if (typeof ref === 'function') {955 if (956 enableProfilerTimer &&957 enableProfilerCommitHooks &&958 finishedWork.mode & ProfileMode959 ) {960 try {961 startLayoutEffectTimer();962 ref(instanceToUse);963 } finally {964 recordLayoutEffectDuration(finishedWork);965 }966 } else {967 ref(instanceToUse);968 }969 } else {970 if (__DEV__) {971 if (!ref.hasOwnProperty('current')) {972 console.error(973 'Unexpected ref object provided for %s. ' +974 'Use either a ref-setter function or React.createRef().',975 getComponentName(finishedWork.type),976 );977 }978 }979 ref.current = instanceToUse;980 }981 }982}983function commitDetachRef(current: Fiber) {984 const currentRef = current.ref;985 if (currentRef !== null) {986 if (typeof currentRef === 'function') {987 if (988 enableProfilerTimer &&989 enableProfilerCommitHooks &&990 current.mode & ProfileMode991 ) {992 try {993 startLayoutEffectTimer();994 currentRef(null);995 } finally {996 recordLayoutEffectDuration(current);997 }998 } else {999 currentRef(null);1000 }1001 } else {1002 currentRef.current = null;1003 }1004 }1005}1006// User-originating errors (lifecycles and refs) should not interrupt1007// deletion, so don't let them throw. Host-originating errors should1008// interrupt deletion, so it's okay1009function commitUnmount(1010 finishedRoot: FiberRoot,1011 current: Fiber,1012 nearestMountedAncestor: Fiber,1013 renderPriorityLevel: ReactPriorityLevel,1014): void {1015 onCommitUnmount(current);1016 switch (current.tag) {1017 case FunctionComponent:1018 case ForwardRef:1019 case MemoComponent:1020 case SimpleMemoComponent: {1021 const updateQueue: FunctionComponentUpdateQueue | null = (current.updateQueue: any);1022 if (updateQueue !== null) {1023 const lastEffect = updateQueue.lastEffect;1024 if (lastEffect !== null) {1025 const firstEffect = lastEffect.next;1026 let effect = firstEffect;1027 do {1028 const {destroy, tag} = effect;1029 if (destroy !== undefined) {1030 if ((tag & HookLayout) !== NoHookEffect) {1031 if (1032 enableProfilerTimer &&1033 enableProfilerCommitHooks &&1034 current.mode & ProfileMode1035 ) {1036 startLayoutEffectTimer();1037 safelyCallDestroy(current, nearestMountedAncestor, destroy);1038 recordLayoutEffectDuration(current);1039 } else {1040 safelyCallDestroy(current, nearestMountedAncestor, destroy);1041 }1042 }1043 }1044 effect = effect.next;1045 } while (effect !== firstEffect);1046 }1047 }1048 return;1049 }1050 case ClassComponent: {1051 safelyDetachRef(current, nearestMountedAncestor);1052 const instance = current.stateNode;1053 if (typeof instance.componentWillUnmount === 'function') {1054 safelyCallComponentWillUnmount(1055 current,1056 nearestMountedAncestor,1057 instance,1058 );1059 }1060 return;1061 }1062 case HostComponent: {1063 safelyDetachRef(current, nearestMountedAncestor);1064 return;1065 }1066 case HostPortal: {1067 // TODO: this is recursive.1068 // We are also not using this parent because1069 // the portal will get pushed immediately.1070 if (supportsMutation) {1071 unmountHostComponents(1072 finishedRoot,1073 current,1074 nearestMountedAncestor,1075 renderPriorityLevel,1076 );1077 } else if (supportsPersistence) {1078 emptyPortalContainer(current);1079 }1080 return;1081 }1082 case FundamentalComponent: {1083 if (enableFundamentalAPI) {1084 const fundamentalInstance = current.stateNode;1085 if (fundamentalInstance !== null) {1086 unmountFundamentalComponent(fundamentalInstance);1087 current.stateNode = null;1088 }1089 }1090 return;1091 }1092 case DehydratedFragment: {1093 if (enableSuspenseCallback) {1094 const hydrationCallbacks = finishedRoot.hydrationCallbacks;1095 if (hydrationCallbacks !== null) {1096 const onDeleted = hydrationCallbacks.onDeleted;1097 if (onDeleted) {1098 onDeleted((current.stateNode: SuspenseInstance));1099 }1100 }1101 }1102 return;1103 }1104 case ScopeComponent: {1105 if (enableScopeAPI) {1106 safelyDetachRef(current, nearestMountedAncestor);1107 }1108 return;1109 }1110 }1111}1112function commitNestedUnmounts(1113 finishedRoot: FiberRoot,1114 root: Fiber,1115 nearestMountedAncestor: Fiber,1116 renderPriorityLevel: ReactPriorityLevel,1117): void {1118 // While we're inside a removed host node we don't want to call1119 // removeChild on the inner nodes because they're removed by the top1120 // call anyway. We also want to call componentWillUnmount on all1121 // composites before this host node is removed from the tree. Therefore1122 // we do an inner loop while we're still inside the host node.1123 let node: Fiber = root;1124 while (true) {1125 commitUnmount(1126 finishedRoot,1127 node,1128 nearestMountedAncestor,1129 renderPriorityLevel,1130 );1131 // Visit children because they may contain more composite or host nodes.1132 // Skip portals because commitUnmount() currently visits them recursively.1133 if (1134 node.child !== null &&1135 // If we use mutation we drill down into portals using commitUnmount above.1136 // If we don't use mutation we drill down into portals here instead.1137 (!supportsMutation || node.tag !== HostPortal)1138 ) {1139 node.child.return = node;1140 node = node.child;1141 continue;1142 }1143 if (node === root) {1144 return;1145 }1146 while (node.sibling === null) {1147 if (node.return === null || node.return === root) {1148 return;1149 }1150 node = node.return;1151 }1152 node.sibling.return = node.return;1153 node = node.sibling;1154 }1155}1156function detachFiberMutation(fiber: Fiber) {1157 // Cut off the return pointer to disconnect it from the tree.1158 // This enables us to detect and warn against state updates on an unmounted component.1159 // It also prevents events from bubbling from within disconnected components.1160 //1161 // Ideally, we should also clear the child pointer of the parent alternate to let this1162 // get GC:ed but we don't know which for sure which parent is the current1163 // one so we'll settle for GC:ing the subtree of this child.1164 // This child itself will be GC:ed when the parent updates the next time.1165 //1166 // Note that we can't clear child or sibling pointers yet.1167 // They're needed for passive effects and for findDOMNode.1168 // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).1169 //1170 // Don't reset the alternate yet, either. We need that so we can detach the1171 // alternate's fields in the passive phase. Clearing the return pointer is1172 // sufficient for findDOMNode semantics.1173 fiber.return = null;1174}1175export function detachFiberAfterEffects(fiber: Fiber): void {1176 // Null out fields to improve GC for references that may be lingering (e.g. DevTools).1177 // Note that we already cleared the return pointer in detachFiberMutation().1178 fiber.alternate = null;1179 fiber.child = null;1180 fiber.deletions = null;1181 fiber.dependencies = null;1182 fiber.memoizedProps = null;1183 fiber.memoizedState = null;1184 fiber.pendingProps = null;1185 fiber.sibling = null;1186 fiber.stateNode = null;1187 fiber.updateQueue = null;1188 if (__DEV__) {1189 fiber._debugOwner = null;1190 }1191}1192function emptyPortalContainer(current: Fiber) {1193 if (!supportsPersistence) {1194 return;1195 }1196 const portal: {1197 containerInfo: Container,1198 pendingChildren: ChildSet,1199 ...1200 } = current.stateNode;1201 const {containerInfo} = portal;1202 const emptyChildSet = createContainerChildSet(containerInfo);1203 replaceContainerChildren(containerInfo, emptyChildSet);1204}1205function commitContainer(finishedWork: Fiber) {1206 if (!supportsPersistence) {1207 return;1208 }1209 switch (finishedWork.tag) {1210 case ClassComponent:1211 case HostComponent:1212 case HostText:1213 case FundamentalComponent: {1214 return;1215 }1216 case HostRoot:1217 case HostPortal: {1218 const portalOrRoot: {1219 containerInfo: Container,1220 pendingChildren: ChildSet,1221 ...1222 } = finishedWork.stateNode;1223 const {containerInfo, pendingChildren} = portalOrRoot;1224 replaceContainerChildren(containerInfo, pendingChildren);1225 return;1226 }1227 }1228 invariant(1229 false,1230 'This unit of work tag should not have side-effects. This error is ' +1231 'likely caused by a bug in React. Please file an issue.',1232 );1233}1234function getHostParentFiber(fiber: Fiber): Fiber {1235 let parent = fiber.return;1236 while (parent !== null) {1237 if (isHostParent(parent)) {1238 return parent;1239 }1240 parent = parent.return;1241 }1242 invariant(1243 false,1244 'Expected to find a host parent. This error is likely caused by a bug ' +1245 'in React. Please file an issue.',1246 );1247}1248function isHostParent(fiber: Fiber): boolean {1249 return (1250 fiber.tag === HostComponent ||1251 fiber.tag === HostRoot ||1252 fiber.tag === HostPortal1253 );1254}1255function getHostSibling(fiber: Fiber): ?Instance {1256 // We're going to search forward into the tree until we find a sibling host1257 // node. Unfortunately, if multiple insertions are done in a row we have to1258 // search past them. This leads to exponential search for the next sibling.1259 // TODO: Find a more efficient way to do this.1260 let node: Fiber = fiber;1261 siblings: while (true) {1262 // If we didn't find anything, let's try the next sibling.1263 while (node.sibling === null) {1264 if (node.return === null || isHostParent(node.return)) {1265 // If we pop out of the root or hit the parent the fiber we are the1266 // last sibling.1267 return null;1268 }1269 node = node.return;1270 }1271 node.sibling.return = node.return;1272 node = node.sibling;1273 while (1274 node.tag !== HostComponent &&1275 node.tag !== HostText &&1276 node.tag !== DehydratedFragment1277 ) {1278 // If it is not host node and, we might have a host node inside it.1279 // Try to search down until we find one.1280 if (node.flags & Placement) {1281 // If we don't have a child, try the siblings instead.1282 continue siblings;1283 }1284 // If we don't have a child, try the siblings instead.1285 // We also skip portals because they are not part of this host tree.1286 if (node.child === null || node.tag === HostPortal) {1287 continue siblings;1288 } else {1289 node.child.return = node;1290 node = node.child;1291 }1292 }1293 // Check if this host node is stable or about to be placed.1294 if (!(node.flags & Placement)) {1295 // Found it!1296 return node.stateNode;1297 }1298 }1299}1300function commitPlacement(finishedWork: Fiber): void {1301 if (!supportsMutation) {1302 return;1303 }1304 // Recursively insert all host nodes into the parent.1305 const parentFiber = getHostParentFiber(finishedWork);1306 // Note: these two variables *must* always be updated together.1307 let parent;1308 let isContainer;1309 const parentStateNode = parentFiber.stateNode;1310 switch (parentFiber.tag) {1311 case HostComponent:1312 parent = parentStateNode;1313 isContainer = false;1314 break;1315 case HostRoot:1316 parent = parentStateNode.containerInfo;1317 isContainer = true;1318 break;1319 case HostPortal:1320 parent = parentStateNode.containerInfo;1321 isContainer = true;1322 break;1323 case FundamentalComponent:1324 if (enableFundamentalAPI) {1325 parent = parentStateNode.instance;1326 isContainer = false;1327 }1328 // eslint-disable-next-line-no-fallthrough1329 default:1330 invariant(1331 false,1332 'Invalid host parent fiber. This error is likely caused by a bug ' +1333 'in React. Please file an issue.',1334 );1335 }1336 if (parentFiber.flags & ContentReset) {1337 // Reset the text content of the parent before doing any insertions1338 resetTextContent(parent);1339 // Clear ContentReset from the effect tag1340 parentFiber.flags &= ~ContentReset;1341 }1342 const before = getHostSibling(finishedWork);1343 // We only have the top Fiber that was inserted but we need to recurse down its1344 // children to find all the terminal nodes.1345 if (isContainer) {1346 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);1347 } else {1348 insertOrAppendPlacementNode(finishedWork, before, parent);1349 }1350}1351function insertOrAppendPlacementNodeIntoContainer(1352 node: Fiber,1353 before: ?Instance,1354 parent: Container,1355): void {1356 const {tag} = node;1357 const isHost = tag === HostComponent || tag === HostText;1358 if (isHost || (enableFundamentalAPI && tag === FundamentalComponent)) {1359 const stateNode = isHost ? node.stateNode : node.stateNode.instance;1360 if (before) {1361 insertInContainerBefore(parent, stateNode, before);1362 } else {1363 appendChildToContainer(parent, stateNode);1364 }1365 } else if (tag === HostPortal) {1366 // If the insertion itself is a portal, then we don't want to traverse1367 // down its children. Instead, we'll get insertions from each child in1368 // the portal directly.1369 } else {1370 const child = node.child;1371 if (child !== null) {1372 insertOrAppendPlacementNodeIntoContainer(child, before, parent);1373 let sibling = child.sibling;1374 while (sibling !== null) {1375 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);1376 sibling = sibling.sibling;1377 }1378 }1379 }1380}1381function insertOrAppendPlacementNode(1382 node: Fiber,1383 before: ?Instance,1384 parent: Instance,1385): void {1386 const {tag} = node;1387 const isHost = tag === HostComponent || tag === HostText;1388 if (isHost || (enableFundamentalAPI && tag === FundamentalComponent)) {1389 const stateNode = isHost ? node.stateNode : node.stateNode.instance;1390 if (before) {1391 insertBefore(parent, stateNode, before);1392 } else {1393 appendChild(parent, stateNode);1394 }1395 } else if (tag === HostPortal) {1396 // If the insertion itself is a portal, then we don't want to traverse1397 // down its children. Instead, we'll get insertions from each child in1398 // the portal directly.1399 } else {1400 const child = node.child;1401 if (child !== null) {1402 insertOrAppendPlacementNode(child, before, parent);1403 let sibling = child.sibling;1404 while (sibling !== null) {1405 insertOrAppendPlacementNode(sibling, before, parent);1406 sibling = sibling.sibling;1407 }1408 }1409 }1410}1411function unmountHostComponents(1412 finishedRoot: FiberRoot,1413 current: Fiber,1414 nearestMountedAncestor: Fiber,1415 renderPriorityLevel: ReactPriorityLevel,1416): void {1417 // We only have the top Fiber that was deleted but we need to recurse down its1418 // children to find all the terminal nodes.1419 let node: Fiber = current;1420 // Each iteration, currentParent is populated with node's host parent if not1421 // currentParentIsValid.1422 let currentParentIsValid = false;1423 // Note: these two variables *must* always be updated together.1424 let currentParent;1425 let currentParentIsContainer;1426 while (true) {1427 if (!currentParentIsValid) {1428 let parent = node.return;1429 findParent: while (true) {1430 invariant(1431 parent !== null,1432 'Expected to find a host parent. This error is likely caused by ' +1433 'a bug in React. Please file an issue.',1434 );1435 const parentStateNode = parent.stateNode;1436 switch (parent.tag) {1437 case HostComponent:1438 currentParent = parentStateNode;1439 currentParentIsContainer = false;1440 break findParent;1441 case HostRoot:1442 currentParent = parentStateNode.containerInfo;1443 currentParentIsContainer = true;1444 break findParent;1445 case HostPortal:1446 currentParent = parentStateNode.containerInfo;1447 currentParentIsContainer = true;1448 break findParent;1449 case FundamentalComponent:1450 if (enableFundamentalAPI) {1451 currentParent = parentStateNode.instance;1452 currentParentIsContainer = false;1453 }1454 }1455 parent = parent.return;1456 }1457 currentParentIsValid = true;1458 }1459 if (node.tag === HostComponent || node.tag === HostText) {1460 commitNestedUnmounts(1461 finishedRoot,1462 node,1463 nearestMountedAncestor,1464 renderPriorityLevel,1465 );1466 // After all the children have unmounted, it is now safe to remove the1467 // node from the tree.1468 if (currentParentIsContainer) {1469 removeChildFromContainer(1470 ((currentParent: any): Container),1471 (node.stateNode: Instance | TextInstance),1472 );1473 } else {1474 removeChild(1475 ((currentParent: any): Instance),1476 (node.stateNode: Instance | TextInstance),1477 );1478 }1479 // Don't visit children because we already visited them.1480 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {1481 const fundamentalNode = node.stateNode.instance;1482 commitNestedUnmounts(1483 finishedRoot,1484 node,1485 nearestMountedAncestor,1486 renderPriorityLevel,1487 );1488 // After all the children have unmounted, it is now safe to remove the1489 // node from the tree.1490 if (currentParentIsContainer) {1491 removeChildFromContainer(1492 ((currentParent: any): Container),1493 (fundamentalNode: Instance),1494 );1495 } else {1496 removeChild(1497 ((currentParent: any): Instance),1498 (fundamentalNode: Instance),1499 );1500 }1501 } else if (1502 enableSuspenseServerRenderer &&1503 node.tag === DehydratedFragment1504 ) {1505 if (enableSuspenseCallback) {1506 const hydrationCallbacks = finishedRoot.hydrationCallbacks;1507 if (hydrationCallbacks !== null) {1508 const onDeleted = hydrationCallbacks.onDeleted;1509 if (onDeleted) {1510 onDeleted((node.stateNode: SuspenseInstance));1511 }1512 }1513 }1514 // Delete the dehydrated suspense boundary and all of its content.1515 if (currentParentIsContainer) {1516 clearSuspenseBoundaryFromContainer(1517 ((currentParent: any): Container),1518 (node.stateNode: SuspenseInstance),1519 );1520 } else {1521 clearSuspenseBoundary(1522 ((currentParent: any): Instance),1523 (node.stateNode: SuspenseInstance),1524 );1525 }1526 } else if (node.tag === HostPortal) {1527 if (node.child !== null) {1528 // When we go into a portal, it becomes the parent to remove from.1529 // We will reassign it back when we pop the portal on the way up.1530 currentParent = node.stateNode.containerInfo;1531 currentParentIsContainer = true;1532 // Visit children because portals might contain host components.1533 node.child.return = node;1534 node = node.child;1535 continue;1536 }1537 } else {1538 commitUnmount(1539 finishedRoot,1540 node,1541 nearestMountedAncestor,1542 renderPriorityLevel,1543 );1544 // Visit children because we may find more host components below.1545 if (node.child !== null) {1546 node.child.return = node;1547 node = node.child;1548 continue;1549 }1550 }1551 if (node === current) {1552 return;1553 }1554 while (node.sibling === null) {1555 if (node.return === null || node.return === current) {1556 return;1557 }1558 node = node.return;1559 if (node.tag === HostPortal) {1560 // When we go out of the portal, we need to restore the parent.1561 // Since we don't keep a stack of them, we will search for it.1562 currentParentIsValid = false;1563 }1564 }1565 node.sibling.return = node.return;1566 node = node.sibling;1567 }1568}1569function commitDeletion(1570 finishedRoot: FiberRoot,1571 current: Fiber,1572 nearestMountedAncestor: Fiber,1573 renderPriorityLevel: ReactPriorityLevel,1574): void {1575 if (supportsMutation) {1576 // Recursively delete all host nodes from the parent.1577 // Detach refs and call componentWillUnmount() on the whole subtree.1578 unmountHostComponents(1579 finishedRoot,1580 current,1581 nearestMountedAncestor,1582 renderPriorityLevel,1583 );1584 } else {1585 // Detach refs and call componentWillUnmount() on the whole subtree.1586 commitNestedUnmounts(1587 finishedRoot,1588 current,1589 nearestMountedAncestor,1590 renderPriorityLevel,1591 );1592 }1593 const alternate = current.alternate;1594 detachFiberMutation(current);1595 if (alternate !== null) {1596 detachFiberMutation(alternate);1597 }1598}1599function commitWork(current: Fiber | null, finishedWork: Fiber): void {1600 if (!supportsMutation) {1601 switch (finishedWork.tag) {1602 case FunctionComponent:1603 case ForwardRef:1604 case MemoComponent:1605 case SimpleMemoComponent: {1606 // Layout effects are destroyed during the mutation phase so that all1607 // destroy functions for all fibers are called before any create functions.1608 // This prevents sibling component effects from interfering with each other,1609 // e.g. a destroy function in one component should never override a ref set1610 // by a create function in another component during the same commit.1611 if (1612 enableProfilerTimer &&1613 enableProfilerCommitHooks &&1614 finishedWork.mode & ProfileMode1615 ) {1616 try {1617 startLayoutEffectTimer();1618 commitHookEffectListUnmount(1619 HookLayout | HookHasEffect,1620 finishedWork,1621 finishedWork.return,1622 );1623 } finally {1624 recordLayoutEffectDuration(finishedWork);1625 }1626 } else {1627 commitHookEffectListUnmount(1628 HookLayout | HookHasEffect,1629 finishedWork,1630 finishedWork.return,1631 );1632 }1633 return;1634 }1635 case Profiler: {1636 return;1637 }1638 case SuspenseComponent: {1639 commitSuspenseComponent(finishedWork);1640 attachSuspenseRetryListeners(finishedWork);1641 return;1642 }1643 case SuspenseListComponent: {1644 attachSuspenseRetryListeners(finishedWork);1645 return;1646 }1647 case HostRoot: {1648 if (supportsHydration) {1649 const root: FiberRoot = finishedWork.stateNode;1650 if (root.hydrate) {1651 // We've just hydrated. No need to hydrate again.1652 root.hydrate = false;1653 commitHydratedContainer(root.containerInfo);1654 }1655 }1656 break;1657 }1658 case OffscreenComponent:1659 case LegacyHiddenComponent: {1660 return;1661 }1662 }1663 commitContainer(finishedWork);1664 return;1665 }1666 switch (finishedWork.tag) {1667 case FunctionComponent:1668 case ForwardRef:1669 case MemoComponent:1670 case SimpleMemoComponent: {1671 // Layout effects are destroyed during the mutation phase so that all1672 // destroy functions for all fibers are called before any create functions.1673 // This prevents sibling component effects from interfering with each other,1674 // e.g. a destroy function in one component should never override a ref set1675 // by a create function in another component during the same commit.1676 if (1677 enableProfilerTimer &&1678 enableProfilerCommitHooks &&1679 finishedWork.mode & ProfileMode1680 ) {1681 try {1682 startLayoutEffectTimer();1683 commitHookEffectListUnmount(1684 HookLayout | HookHasEffect,1685 finishedWork,1686 finishedWork.return,1687 );1688 } finally {1689 recordLayoutEffectDuration(finishedWork);1690 }1691 } else {1692 commitHookEffectListUnmount(1693 HookLayout | HookHasEffect,1694 finishedWork,1695 finishedWork.return,1696 );1697 }1698 return;1699 }1700 case ClassComponent: {1701 return;1702 }1703 case HostComponent: {1704 const instance: Instance = finishedWork.stateNode;1705 if (instance != null) {1706 // Commit the work prepared earlier.1707 const newProps = finishedWork.memoizedProps;1708 // For hydration we reuse the update path but we treat the oldProps1709 // as the newProps. The updatePayload will contain the real change in1710 // this case.1711 const oldProps = current !== null ? current.memoizedProps : newProps;1712 const type = finishedWork.type;1713 // TODO: Type the updateQueue to be specific to host components.1714 const updatePayload: null | UpdatePayload = (finishedWork.updateQueue: any);1715 finishedWork.updateQueue = null;1716 if (updatePayload !== null) {1717 commitUpdate(1718 instance,1719 updatePayload,1720 type,1721 oldProps,1722 newProps,1723 finishedWork,1724 );1725 }1726 }1727 return;1728 }1729 case HostText: {1730 invariant(1731 finishedWork.stateNode !== null,1732 'This should have a text node initialized. This error is likely ' +1733 'caused by a bug in React. Please file an issue.',1734 );1735 const textInstance: TextInstance = finishedWork.stateNode;1736 const newText: string = finishedWork.memoizedProps;1737 // For hydration we reuse the update path but we treat the oldProps1738 // as the newProps. The updatePayload will contain the real change in1739 // this case.1740 const oldText: string =1741 current !== null ? current.memoizedProps : newText;1742 commitTextUpdate(textInstance, oldText, newText);1743 return;1744 }1745 case HostRoot: {1746 if (supportsHydration) {1747 const root: FiberRoot = finishedWork.stateNode;1748 if (root.hydrate) {1749 // We've just hydrated. No need to hydrate again.1750 root.hydrate = false;1751 commitHydratedContainer(root.containerInfo);1752 }1753 }1754 return;1755 }1756 case Profiler: {1757 return;1758 }1759 case SuspenseComponent: {1760 commitSuspenseComponent(finishedWork);1761 attachSuspenseRetryListeners(finishedWork);1762 return;1763 }1764 case SuspenseListComponent: {1765 attachSuspenseRetryListeners(finishedWork);1766 return;1767 }1768 case IncompleteClassComponent: {1769 return;1770 }1771 case FundamentalComponent: {1772 if (enableFundamentalAPI) {1773 const fundamentalInstance = finishedWork.stateNode;1774 updateFundamentalComponent(fundamentalInstance);1775 return;1776 }1777 break;1778 }1779 case ScopeComponent: {1780 if (enableScopeAPI) {1781 const scopeInstance = finishedWork.stateNode;1782 prepareScopeUpdate(scopeInstance, finishedWork);1783 return;1784 }1785 break;1786 }1787 case OffscreenComponent:1788 case LegacyHiddenComponent: {1789 const newState: OffscreenState | null = finishedWork.memoizedState;1790 const isHidden = newState !== null;1791 hideOrUnhideAllChildren(finishedWork, isHidden);1792 return;1793 }1794 }1795 invariant(1796 false,1797 'This unit of work tag should not have side-effects. This error is ' +1798 'likely caused by a bug in React. Please file an issue.',1799 );1800}1801function commitSuspenseComponent(finishedWork: Fiber) {1802 const newState: SuspenseState | null = finishedWork.memoizedState;1803 if (newState !== null) {1804 markCommitTimeOfFallback();1805 if (supportsMutation) {1806 // Hide the Offscreen component that contains the primary children. TODO:1807 // Ideally, this effect would have been scheduled on the Offscreen fiber1808 // itself. That's how unhiding works: the Offscreen component schedules an1809 // effect on itself. However, in this case, the component didn't complete,1810 // so the fiber was never added to the effect list in the normal path. We1811 // could have appended it to the effect list in the Suspense component's1812 // second pass, but doing it this way is less complicated. This would be1813 // simpler if we got rid of the effect list and traversed the tree, like1814 // we're planning to do.1815 const primaryChildParent: Fiber = (finishedWork.child: any);1816 hideOrUnhideAllChildren(primaryChildParent, true);1817 }1818 }1819 if (enableSuspenseCallback && newState !== null) {1820 const suspenseCallback = finishedWork.memoizedProps.suspenseCallback;1821 if (typeof suspenseCallback === 'function') {1822 const wakeables: Set<Wakeable> | null = (finishedWork.updateQueue: any);1823 if (wakeables !== null) {1824 suspenseCallback(new Set(wakeables));1825 }1826 } else if (__DEV__) {1827 if (suspenseCallback !== undefined) {1828 console.error('Unexpected type for suspenseCallback.');1829 }1830 }1831 }1832}1833function commitSuspenseHydrationCallbacks(1834 finishedRoot: FiberRoot,1835 finishedWork: Fiber,1836) {1837 if (!supportsHydration) {1838 return;1839 }1840 const newState: SuspenseState | null = finishedWork.memoizedState;1841 if (newState === null) {1842 const current = finishedWork.alternate;1843 if (current !== null) {1844 const prevState: SuspenseState | null = current.memoizedState;1845 if (prevState !== null) {1846 const suspenseInstance = prevState.dehydrated;1847 if (suspenseInstance !== null) {1848 commitHydratedSuspenseInstance(suspenseInstance);1849 if (enableSuspenseCallback) {1850 const hydrationCallbacks = finishedRoot.hydrationCallbacks;1851 if (hydrationCallbacks !== null) {1852 const onHydrated = hydrationCallbacks.onHydrated;1853 if (onHydrated) {1854 onHydrated(suspenseInstance);1855 }1856 }1857 }1858 }1859 }1860 }1861 }1862}1863function attachSuspenseRetryListeners(finishedWork: Fiber) {1864 // If this boundary just timed out, then it will have a set of wakeables.1865 // For each wakeable, attach a listener so that when it resolves, React1866 // attempts to re-render the boundary in the primary (pre-timeout) state.1867 const wakeables: Set<Wakeable> | null = (finishedWork.updateQueue: any);1868 if (wakeables !== null) {1869 finishedWork.updateQueue = null;1870 let retryCache = finishedWork.stateNode;1871 if (retryCache === null) {1872 retryCache = finishedWork.stateNode = new PossiblyWeakSet();1873 }1874 wakeables.forEach(wakeable => {1875 // Memoize using the boundary fiber to prevent redundant listeners.1876 let retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);1877 if (!retryCache.has(wakeable)) {1878 if (enableSchedulerTracing) {1879 if (wakeable.__reactDoNotTraceInteractions !== true) {1880 retry = Schedule_tracing_wrap(retry);1881 }1882 }1883 retryCache.add(wakeable);1884 wakeable.then(retry, retry);1885 }1886 });1887 }1888}1889// This function detects when a Suspense boundary goes from visible to hidden.1890// It returns false if the boundary is already hidden.1891// TODO: Use an effect tag.1892export function isSuspenseBoundaryBeingHidden(1893 current: Fiber | null,1894 finishedWork: Fiber,1895): boolean {1896 if (current !== null) {1897 const oldState: SuspenseState | null = current.memoizedState;1898 if (oldState === null || oldState.dehydrated !== null) {1899 const newState: SuspenseState | null = finishedWork.memoizedState;1900 return newState !== null && newState.dehydrated === null;1901 }1902 }1903 return false;1904}1905function commitResetTextContent(current: Fiber) {1906 if (!supportsMutation) {...

Full Screen

Full Screen

ReactFiberCommitWork.old.js

Source:ReactFiberCommitWork.old.js Github

copy

Full Screen

...944 }945 } // This function detects when a Suspense boundary goes from visible to hidden.946 // It returns false if the boundary is already hidden.947 // TODO: Use an effect tag.948 function isSuspenseBoundaryBeingHidden(current, finishedWork) {949 if (current !== null) {950 var oldState = current.memoizedState;951 if (oldState === null || oldState.dehydrated !== null) {952 var newState = finishedWork.memoizedState;953 return newState !== null && newState.dehydrated === null;954 }955 }956 return false;957 }958 function commitResetTextContent(current) {959 resetTextContent(current.stateNode);...

Full Screen

Full Screen

ReactFiberCommitWork.js

Source:ReactFiberCommitWork.js Github

copy

Full Screen

1import {2 FunctionComponent,3 ForwardRef,4 ClassComponent,5 HostRoot,6 HostComponent,7 HostText,8 HostPortal,9 IncompleteClassComponent,10 SimpleMemoComponent,11 Block,12 FundamentalComponent,13 DehydratedFragment,14 MemoComponent,15 SuspenseComponent,16 OffscreenComponent,17 LegacyHiddenComponent,18} from './ReactWorkTags';19import { Snapshot, ContentReset, Placement } from './ReactFiberFlags';20import { resolveDefaultProps } from './ReactFiberLazyComponent';21import {22 clearContainer,23 resetTextContent,24 insertInContainerBefore,25 appendChildToContainer,26 commitUpdate,27 commitTextUpdate,28} from './ReactFiberHostConfig';29import {30 NoFlags as NoHookEffect,31 HasEffect as HookHasEffect,32 Layout as HookLayout,33 Passive as HookPassive,34} from './ReactHookEffectTags';35const invariant = require('invariant');36const isSuspenseBoundaryBeingHidden = (current, finishedWork) => {37 if (current !== null) {38 const oldState = current.memoizedState;39 if (oldState === null || oldState.dehydrated !== null) {40 const newState = finishedWork.memoizedState;41 return newState !== null && newState.dehydrated === null;42 }43 }44 return false;45};46const commitBeforeMutationLifeCycles = (current, finishedWork) => {47 switch (finishedWork.tag) {48 case FunctionComponent:49 case ForwardRef:50 case SimpleMemoComponent:51 case Block: {52 return;53 }54 case ClassComponent: {55 if (finishedWork.flags & Snapshot) {56 if (current !== null) {57 const prevProps = current.memoizedProps;58 const prevState = current.memoizedState;59 const instance = finishedWork.stateNode;60 const snapshot = instance.getSnapshotBeforeUpdate(61 finishedWork.elementType === finishedWork.type62 ? prevProps63 : resolveDefaultProps(finishedWork.type, prevProps),64 prevState65 );66 instance.__reactInternalSnapshotBeforeUpdate = snapshot;67 }68 }69 return;70 }71 case HostRoot: {72 if (finishedWork.flags & Snapshot) {73 const root = finishedWork.stateNode;74 clearContainer(root.containerInfo);75 }76 return;77 }78 case HostComponent:79 case HostText:80 case HostPortal:81 case IncompleteClassComponent:82 return;83 }84 invariant(85 false,86 'This unit of work tag should not have side-effects. This error is ' +87 'likely caused by a bug in React. Please file an issue.'88 );89};90const commitResetTextContent = (current) => {91 resetTextContent(current.stateNode);92};93const commitDetachRef = (current) => {94 const currentRef = current.ref;95 if (currentRef !== null) {96 if (typeof currentRef === 'function') {97 currentRef(null);98 } else {99 currentRef.current = null;100 }101 }102};103const isHostParent = (fiber) => {104 return (105 fiber.tag === HostComponent ||106 fiber.tag === HostRoot ||107 fiber.tag === HostPortal108 );109};110const getHostParentFiber = (fiber) => {111 let parent = fiber.return;112 while (parent !== null) {113 if (isHostParent(parent)) {114 return parent;115 }116 parent = parent.return;117 }118 invariant(119 false,120 'Expected to find a host parent. This error is likely caused by a bug ' +121 'in React. Please file an issue.'122 );123};124const getHostSibling = (fiber) => {125 let node = fiber;126 while (true) {127 while (node.sibling === null) {128 if (node.return === null || isHostParent(node.return)) return null;129 node = node.return;130 }131 node.sibling.return = node.return;132 node = node.sibling;133 let shouldRun = true;134 while (135 node.tag !== HostComponent &&136 node.tag !== HostText &&137 node.tag !== DehydratedFragment &&138 shouldRun139 ) {140 if (node.flags & Placement) {141 shouldRun = false;142 }143 if (node.child === null || node.tag === HostPortal) {144 shouldRun = false;145 } else {146 node.child.return = node;147 node = node.child;148 }149 }150 if (!(node.flags & Placement)) {151 return node.stateNode;152 }153 }154};155const insertOrAppendPlacementNodeIntoContainer = (node, before, parent) => {156 const { tag } = node;157 const isHost = tag === HostComponent || tag === HostText;158 if (isHost) {159 const stateNode = isHost ? node.stateNode : node.stateNode.instance;160 if (before) {161 insertInContainerBefore(parent, stateNode, before);162 } else {163 appendChildToContainer(parent, stateNode);164 }165 } else if (tag === HostPortal) {166 //167 } else {168 const child = node.child;169 if (child !== null) {170 insertOrAppendPlacementNodeIntoContainer(child, before, parent);171 let sibling = child.sibling;172 while (sibling !== null) {173 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);174 sibling = sibling.sibling;175 }176 }177 }178};179const insertOrAppendPlacementNode = (node, before, parent) => {180 const { tag } = node;181 const isHost = tag === HostComponent || tag === HostText;182 if (isHost) {183 const stateNode = isHost ? node.stateNode : node.stateNode.instance;184 if (before) {185 parent.insertBefore(stateNode, before);186 } else {187 parent.appendChild(stateNode);188 }189 } else if (tag === HostPortal) {190 // If the insertion itself is a portal, then we don't want to traverse191 // down its children. Instead, we'll get insertions from each child in192 // the portal directly.193 } else {194 const child = node.child;195 if (child !== null) {196 insertOrAppendPlacementNode(child, before, parent);197 let sibling = child.sibling;198 while (sibling !== null) {199 insertOrAppendPlacementNode(sibling, before, parent);200 sibling = sibling.sibling;201 }202 }203 }204};205const commitPlacement = (finishedWork) => {206 const parentFiber = getHostParentFiber(finishedWork);207 let parent;208 let isContainer;209 const parentStateNode = parentFiber.stateNode;210 switch (parentFiber.tag) {211 case HostComponent:212 parent = parentStateNode;213 isContainer = false;214 break;215 case HostRoot:216 parent = parentStateNode.containerInfo;217 isContainer = true;218 break;219 case HostPortal:220 parent = parentStateNode.containerInfo;221 isContainer = true;222 break;223 case FundamentalComponent:224 default:225 invariant(226 false,227 'Invalid host parent fiber. This error is likely caused by a bug ' +228 'in React. Please file an issue.'229 );230 }231 if (parentFiber.flags & ContentReset) {232 resetTextContent(parent);233 parentFiber.flags &= ~ContentReset;234 }235 const before = getHostSibling(finishedWork);236 if (isContainer) {237 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);238 } else {239 insertOrAppendPlacementNode(finishedWork, before, parent);240 }241};242const commitHookEffectListUnmount = (tag, finishedWork) => {243 const updateQueue = finishedWork.updateQueue;244 const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;245 if (lastEffect !== null) {246 const firstEffect = lastEffect.next;247 let effect = firstEffect;248 do {249 if ((effect.tag & tag) === tag) {250 const destroy = effect.destroy;251 effect.destroy = undefined;252 if (destroy !== undefined) {253 destroy();254 }255 }256 effect = effect.next;257 } while (effect !== firstEffect);258 }259};260const commitWork = (current, finishedWork) => {261 switch (finishedWork.tag) {262 case FunctionComponent:263 case ForwardRef:264 case MemoComponent:265 case SimpleMemoComponent:266 case Block: {267 commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);268 return;269 }270 case ClassComponent: {271 return;272 }273 case HostComponent: {274 const instance = finishedWork.stateNode;275 if (instance != null) {276 const newProps = finishedWork.memoizedProps;277 const oldProps = current !== null ? current.memoizedProps : newProps;278 const type = finishedWork.type;279 const updatePayload = finishedWork.updateQueue;280 finishedWork.updateQueue = null;281 if (updatePayload !== null) {282 commitUpdate(283 instance,284 updatePayload,285 type,286 oldProps,287 newProps,288 finishedWork289 );290 }291 }292 return;293 }294 case HostText: {295 invariant(296 finishedWork.stateNode !== null,297 'This should have a text node initialized. This error is likely ' +298 'caused by a bug in React. Please file an issue.'299 );300 const textInstance = finishedWork.stateNode;301 const newText = finishedWork.memoizedProps;302 const oldText = current !== null ? current.memoizedProps : newText;303 commitTextUpdate(textInstance, oldText, newText);304 return;305 }306 case HostRoot: {307 const root = finishedWork.stateNode;308 if (root.hydrate) {309 root.hydrate = false;310 commitHydratedContainer(root.containerInfo);311 }312 return;313 }314 // case SuspenseComponent: {315 // commitSuspenseComponent(finishedWork);316 // attachSuspenseRetryListeners(finishedWork);317 // return;318 // }319 // case IncompleteClassComponent: {320 // return;321 // }322 // case FundamentalComponent: {323 // break;324 // }325 // case OffscreenComponent:326 // case LegacyHiddenComponent: {327 // const newState = finishedWork.memoizedState;328 // const isHidden = newState !== null;329 // hideOrUnhideAllChildren(finishedWork, isHidden);330 // return;331 // }332 }333 invariant(334 false,335 'This unit of work tag should not have side-effects. This error is ' +336 'likely caused by a bug in React. Please file an issue.'337 );338};339const unmountHostComponents = (340 finishedRoot,341 current,342 renderPriorityLevel343) => {};344const detachFiberMutation = (fiber) => {345 fiber.alternate = null;346 fiber.child = null;347 fiber.dependencies = null;348 fiber.firstEffect = null;349 fiber.lastEffect = null;350 fiber.memoizedProps = null;351 fiber.memoizedState = null;352 fiber.pendingProps = null;353 fiber.return = null;354 fiber.updateQueue = null;355};356const commitDeletion = (finishedRoot, current, renderPriorityLevel) => {357 unmountHostComponents(finishedRoot, current, renderPriorityLevel);358 const alternate = current.alternate;359 detachFiberMutation(current);360 if (alternate !== null) {361 detachFiberMutation(alternate);362 }363};364export {365 isSuspenseBoundaryBeingHidden,366 commitBeforeMutationLifeCycles,367 commitResetTextContent,368 commitDetachRef,369 commitPlacement,370 commitWork,371 commitDeletion,...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const isHidden = await page.evaluate(() => window._playwrightInternals.isSuspenseBoundaryBeingHidden(document.getElementById('hplogo')));7 console.log(isHidden);8 await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext();14 const page = await context.newPage();15 const isHidden = await page.evaluate(() => window._playwrightInternals.isSuspenseBoundaryBeingHidden(document.getElementById('hplogo')));16 console.log(isHidden);17 await browser.close();18})();19const { chromium } = require('playwright');20(async () => {21 const browser = await chromium.launch();22 const context = await browser.newContext();23 const page = await context.newPage();24 const isHidden = await page.evaluate(() => window._playwrightInternals.isSuspenseBoundaryBeingHidden(document.getElementById('hplogo')));25 console.log(isHidden);26 await browser.close();27})();28const { chromium } = require('playwright');29(async () => {30 const browser = await chromium.launch();31 const context = await browser.newContext();32 const page = await context.newPage();33 const isHidden = await page.evaluate(() => window._playwrightInternals.isSuspenseBoundaryBeingHidden(document.getElementById('hplogo')));34 console.log(isHidden);35 await browser.close();36})();37const { chromium } = require('playwright');38(async () => {39 const browser = await chromium.launch();40 const context = await browser.newContext();41 const page = await context.newPage();42 await page.goto('

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.waitForLoadState('load');7 await page.screenshot({ path: 'example.png' });8 await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext();14 const page = await context.newPage();15 await page.waitForLoadState('load');16 const isHidden = await page.isSuspenseBoundaryBeingHidden();17 console.log(isHidden);18 await browser.close();19})();20const { chromium } = require('playwright');21(async () => {22 const browser = await chromium.launch();23 const context = await browser.newContext();24 const page = await context.newPage();25 await page.waitForLoadState('load');26 const isHidden = await page.isSuspenseBoundaryBeingHidden();27 console.log(isHidden);

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2const { isSuspenseBoundaryBeingHidden } = require('playwright/lib/internal/api');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.waitForSelector('text=Loading...');8 const isHidden = await isSuspenseBoundaryBeingHidden(page, 'text=Loading...');9 console.log('isHidden', isHidden);10 await browser.close();11})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isSuspenseBoundaryBeingHidden } = require('@playwright/test/lib/internal/inspectorHelper');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 await page.waitForTimeout(2000);7 console.log(await isSuspenseBoundaryBeingHidden(page, 'main'));8 await browser.close();9})();10The test() method is used to write tests. The test() method takes two arguments:11const { test, expect } = require('@playwright/test');12test('text is displayed', async ({ page }) => {13 const text = await page.textContent('h1');14 expect(text).toBe('Hello, world!');15});16The describe() method is used to group tests. The describe() method takes two arguments:

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isSuspenseBoundaryBeingHidden } = require('playwright/lib/client/supplements/har/harTracer');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.click('text=Sign in');8 await page.waitForLoadState('networkidle');9 await page.screenshot({ path: `example.png` });10 console.log(isSuspenseBoundaryBeingHidden(page));11 await browser.close();12})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isSuspenseBoundaryBeingHidden } = require('@playwright/test/lib/server/supplements/recorderSupplement');2const { test } = require('@playwright/test');3test('test', async ({ page }) => {4 await page.click('text=Get started');5 await page.click('text=Docs');6 await page.click('text=API');7 await page.click('text=Page');8 await page.click('text=page.goto');9 console.log(await isSuspenseBoundaryBeingHidden(page, 'docs-ui'));10});11const { isSuspenseBoundaryBeingHidden } = require('@playwright/test/lib/server/supplements/recorderSupplement');12const { test } = require('@playwright/test');13test('test', async ({ page }) => {14 await page.click('text=Get started');15 await page.click('text=Docs');16 await page.click('text=API');17 await page.click('text=Page');18 await page.click('text=page.goto');19 console.log(await isSuspenseBoundaryBeingHidden(page, 'docs-ui'));20});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isSuspenseBoundaryBeingHidden } = require("@playwright/test/lib/server/frames");2const { test } = require('@playwright/test');3test('should test isSuspenseBoundaryBeingHidden method', async ({ page }) => {4 const isHidden = await isSuspenseBoundaryBeingHidden(page.mainFrame(), 'text=Get started');5 console.log(isHidden);6});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isSuspenseBoundaryBeingHidden } = require('playwright-core/lib/server/supplements/recorderSupplement/recorderSupplement.js');2const { page } = require('playwright-core/lib/server/supplements/recorderSupplement/recorderSupplement.js');3(async () => {4 await page.fill('input[type="text"]', 'Hello World');5 await page.click('input[type="submit"]');6 const isHidden = await isSuspenseBoundaryBeingHidden();7 console.log(isHidden);8})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 await page.screenshot({ path: 'google.png' });6 await browser.close();7})();

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful