How to use resetContextDependencies method in Playwright Internal

Best JavaScript code snippet using playwright-internal

ReactFiberScheduler.js

Source:ReactFiberScheduler.js Github

copy

Full Screen

...699 const currentTime = requestCurrentTime();700 if (currentTime < expirationTime) {701 // Restart at the current time.702 workPhase = prevWorkPhase;703 resetContextDependencies();704 ReactCurrentDispatcher.current = prevDispatcher;705 if (enableSchedulerTracing) {706 __interactionsRef.current = ((prevInteractions: any): Set<707 Interaction,708 >);709 }710 return renderRoot.bind(null, root, currentTime);711 }712 }713 } else {714 // Since we know we're in a React event, we can clear the current715 // event time. The next update will compute a new event time.716 currentEventTime = NoWork;717 }718 do {719 try {720 if (isSync) {721 workLoopSync();722 } else {723 workLoop();724 }725 break;726 } catch (thrownValue) {727 // Reset module-level state that was set during the render phase.728 resetContextDependencies();729 resetHooks();730 const sourceFiber = workInProgress;731 if (sourceFiber === null || sourceFiber.return === null) {732 // Expected to be working on a non-root fiber. This is a fatal error733 // because there's no ancestor that can handle it; the root is734 // supposed to capture all errors that weren't caught by an error735 // boundary.736 prepareFreshStack(root, expirationTime);737 workPhase = prevWorkPhase;738 throw thrownValue;739 }740 if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {741 // Record the time spent rendering before an error was thrown. This742 // avoids inaccurate Profiler durations in the case of a743 // suspended render.744 stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);745 }746 const returnFiber = sourceFiber.return;747 throwException(748 root,749 returnFiber,750 sourceFiber,751 thrownValue,752 renderExpirationTime,753 );754 workInProgress = completeUnitOfWork(sourceFiber);755 }756 } while (true);757 workPhase = prevWorkPhase;758 resetContextDependencies();759 ReactCurrentDispatcher.current = prevDispatcher;760 if (enableSchedulerTracing) {761 __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);762 }763 if (workInProgress !== null) {764 // There's still work left over. Return a continuation.765 stopInterruptedWorkLoopTimer();766 if (expirationTime !== Sync) {767 startRequestCallbackTimer();768 }769 return renderRoot.bind(null, root, expirationTime);770 }771 }772 // We now have a consistent tree. The next step is either to commit it, or, if773 // something suspended, wait to commit it after a timeout.774 stopFinishedWorkLoopTimer();775 const isLocked = resolveLocksOnRoot(root, expirationTime);776 if (isLocked) {777 // This root has a lock that prevents it from committing. Exit. If we begin778 // work on the root again, without any intervening updates, it will finish779 // without doing additional work.780 return null;781 }782 // Set this to null to indicate there's no in-progress render.783 workInProgressRoot = null;784 switch (workInProgressRootExitStatus) {785 case RootIncomplete: {786 invariant(false, 'Should have a work-in-progress.');787 }788 // Flow knows about invariant, so it compains if I add a break statement,789 // but eslint doesn't know about invariant, so it complains if I do.790 // eslint-disable-next-line no-fallthrough791 case RootErrored: {792 // An error was thrown. First check if there is lower priority work793 // scheduled on this root.794 const lastPendingTime = root.lastPendingTime;795 if (root.lastPendingTime < expirationTime) {796 // There's lower priority work. Before raising the error, try rendering797 // at the lower priority to see if it fixes it. Use a continuation to798 // maintain the existing priority and position in the queue.799 return renderRoot.bind(null, root, lastPendingTime);800 }801 if (!isSync) {802 // If we're rendering asynchronously, it's possible the error was803 // caused by tearing due to a mutation during an event. Try rendering804 // one more time without yiedling to events.805 prepareFreshStack(root, expirationTime);806 scheduleCallback(807 ImmediatePriority,808 renderRoot.bind(null, root, expirationTime),809 );810 return null;811 }812 // If we're already rendering synchronously, commit the root in its813 // errored state.814 return commitRoot.bind(null, root, expirationTime);815 }816 case RootSuspended: {817 if (!isSync) {818 const lastPendingTime = root.lastPendingTime;819 if (root.lastPendingTime < expirationTime) {820 // There's lower priority work. It might be unsuspended. Try rendering821 // at that level.822 return renderRoot.bind(null, root, lastPendingTime);823 }824 // If workInProgressRootMostRecentEventTime is Sync, that means we didn't825 // track any event times. That can happen if we retried but nothing switched826 // from fallback to content. There's no reason to delay doing no work.827 if (workInProgressRootMostRecentEventTime !== Sync) {828 let msUntilTimeout = computeMsUntilTimeout(829 workInProgressRootMostRecentEventTime,830 expirationTime,831 );832 // Don't bother with a very short suspense time.833 if (msUntilTimeout > 10) {834 // The render is suspended, it hasn't timed out, and there's no lower835 // priority work to do. Instead of committing the fallback836 // immediately, wait for more data to arrive.837 root.timeoutHandle = scheduleTimeout(838 commitRoot.bind(null, root, expirationTime),839 msUntilTimeout,840 );841 return null;842 }843 }844 }845 // The work expired. Commit immediately.846 return commitRoot.bind(null, root, expirationTime);847 }848 case RootCompleted: {849 // The work completed. Ready to commit.850 return commitRoot.bind(null, root, expirationTime);851 }852 default: {853 invariant(false, 'Unknown root exit status.');854 }855 }856}857export function markRenderEventTime(expirationTime: ExpirationTime): void {858 if (expirationTime < workInProgressRootMostRecentEventTime) {859 workInProgressRootMostRecentEventTime = expirationTime;860 }861}862export function renderDidSuspend(): void {863 if (workInProgressRootExitStatus === RootIncomplete) {864 workInProgressRootExitStatus = RootSuspended;865 }866}867export function renderDidError() {868 if (869 workInProgressRootExitStatus === RootIncomplete ||870 workInProgressRootExitStatus === RootSuspended871 ) {872 workInProgressRootExitStatus = RootErrored;873 }874}875function inferTimeFromExpirationTime(expirationTime: ExpirationTime): number {876 // We don't know exactly when the update was scheduled, but we can infer an877 // approximate start time from the expiration time.878 const earliestExpirationTimeMs = expirationTimeToMs(expirationTime);879 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;880}881function workLoopSync() {882 // Already timed out, so perform work without checking if we need to yield.883 while (workInProgress !== null) {884 workInProgress = performUnitOfWork(workInProgress);885 }886}887function workLoop() {888 // Perform work until Scheduler asks us to yield889 while (workInProgress !== null && !shouldYield()) {890 workInProgress = performUnitOfWork(workInProgress);891 }892}893function performUnitOfWork(unitOfWork: Fiber): Fiber | null {894 // The current, flushed, state of this fiber is the alternate. Ideally895 // nothing should rely on this, but relying on it here means that we don't896 // need an additional field on the work in progress.897 const current = unitOfWork.alternate;898 startWorkTimer(unitOfWork);899 setCurrentDebugFiberInDEV(unitOfWork);900 let next;901 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoContext) {902 startProfilerTimer(unitOfWork);903 next = beginWork(current, unitOfWork, renderExpirationTime);904 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);905 } else {906 next = beginWork(current, unitOfWork, renderExpirationTime);907 }908 resetCurrentDebugFiberInDEV();909 unitOfWork.memoizedProps = unitOfWork.pendingProps;910 if (next === null) {911 // If this doesn't spawn new work, complete the current work.912 next = completeUnitOfWork(unitOfWork);913 }914 ReactCurrentOwner.current = null;915 return next;916}917function completeUnitOfWork(unitOfWork: Fiber): Fiber | null {918 // Attempt to complete the current unit of work, then move to the next919 // sibling. If there are no more siblings, return to the parent fiber.920 workInProgress = unitOfWork;921 do {922 // The current, flushed, state of this fiber is the alternate. Ideally923 // nothing should rely on this, but relying on it here means that we don't924 // need an additional field on the work in progress.925 const current = workInProgress.alternate;926 const returnFiber = workInProgress.return;927 // Check if the work completed or if something threw.928 if ((workInProgress.effectTag & Incomplete) === NoEffect) {929 setCurrentDebugFiberInDEV(workInProgress);930 let next;931 if (932 !enableProfilerTimer ||933 (workInProgress.mode & ProfileMode) === NoContext934 ) {935 next = completeWork(current, workInProgress, renderExpirationTime);936 } else {937 startProfilerTimer(workInProgress);938 next = completeWork(current, workInProgress, renderExpirationTime);939 // Update render duration assuming we didn't error.940 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);941 }942 stopWorkTimer(workInProgress);943 resetCurrentDebugFiberInDEV();944 resetChildExpirationTime(workInProgress);945 if (next !== null) {946 // Completing this fiber spawned new work. Work on that next.947 return next;948 }949 if (950 returnFiber !== null &&951 // Do not append effects to parents if a sibling failed to complete952 (returnFiber.effectTag & Incomplete) === NoEffect953 ) {954 // Append all the effects of the subtree and this fiber onto the effect955 // list of the parent. The completion order of the children affects the956 // side-effect order.957 if (returnFiber.firstEffect === null) {958 returnFiber.firstEffect = workInProgress.firstEffect;959 }960 if (workInProgress.lastEffect !== null) {961 if (returnFiber.lastEffect !== null) {962 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;963 }964 returnFiber.lastEffect = workInProgress.lastEffect;965 }966 // If this fiber had side-effects, we append it AFTER the children's967 // side-effects. We can perform certain side-effects earlier if needed,968 // by doing multiple passes over the effect list. We don't want to969 // schedule our own side-effect on our own list because if end up970 // reusing children we'll schedule this effect onto itself since we're971 // at the end.972 const effectTag = workInProgress.effectTag;973 // Skip both NoWork and PerformedWork tags when creating the effect974 // list. PerformedWork effect is read by React DevTools but shouldn't be975 // committed.976 if (effectTag > PerformedWork) {977 if (returnFiber.lastEffect !== null) {978 returnFiber.lastEffect.nextEffect = workInProgress;979 } else {980 returnFiber.firstEffect = workInProgress;981 }982 returnFiber.lastEffect = workInProgress;983 }984 }985 } else {986 // This fiber did not complete because something threw. Pop values off987 // the stack without entering the complete phase. If this is a boundary,988 // capture values if possible.989 const next = unwindWork(workInProgress, renderExpirationTime);990 // Because this fiber did not complete, don't reset its expiration time.991 if (992 enableProfilerTimer &&993 (workInProgress.mode & ProfileMode) !== NoContext994 ) {995 // Record the render duration for the fiber that errored.996 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);997 // Include the time spent working on failed children before continuing.998 let actualDuration = workInProgress.actualDuration;999 let child = workInProgress.child;1000 while (child !== null) {1001 actualDuration += child.actualDuration;1002 child = child.sibling;1003 }1004 workInProgress.actualDuration = actualDuration;1005 }1006 if (next !== null) {1007 // If completing this work spawned new work, do that next. We'll come1008 // back here again.1009 // Since we're restarting, remove anything that is not a host effect1010 // from the effect tag.1011 // TODO: The name stopFailedWorkTimer is misleading because Suspense1012 // also captures and restarts.1013 stopFailedWorkTimer(workInProgress);1014 next.effectTag &= HostEffectMask;1015 return next;1016 }1017 stopWorkTimer(workInProgress);1018 if (returnFiber !== null) {1019 // Mark the parent fiber as incomplete and clear its effect list.1020 returnFiber.firstEffect = returnFiber.lastEffect = null;1021 returnFiber.effectTag |= Incomplete;1022 }1023 }1024 const siblingFiber = workInProgress.sibling;1025 if (siblingFiber !== null) {1026 // If there is more work to do in this returnFiber, do that next.1027 return siblingFiber;1028 }1029 // Otherwise, return to the parent1030 workInProgress = returnFiber;1031 } while (workInProgress !== null);1032 // We've reached the root.1033 if (workInProgressRootExitStatus === RootIncomplete) {1034 workInProgressRootExitStatus = RootCompleted;1035 }1036 return null;1037}1038function resetChildExpirationTime(completedWork: Fiber) {1039 if (1040 renderExpirationTime !== Never &&1041 completedWork.childExpirationTime === Never1042 ) {1043 // The children of this component are hidden. Don't bubble their1044 // expiration times.1045 return;1046 }1047 let newChildExpirationTime = NoWork;1048 // Bubble up the earliest expiration time.1049 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoContext) {1050 // In profiling mode, resetChildExpirationTime is also used to reset1051 // profiler durations.1052 let actualDuration = completedWork.actualDuration;1053 let treeBaseDuration = completedWork.selfBaseDuration;1054 // When a fiber is cloned, its actualDuration is reset to 0. This value will1055 // only be updated if work is done on the fiber (i.e. it doesn't bailout).1056 // When work is done, it should bubble to the parent's actualDuration. If1057 // the fiber has not been cloned though, (meaning no work was done), then1058 // this value will reflect the amount of time spent working on a previous1059 // render. In that case it should not bubble. We determine whether it was1060 // cloned by comparing the child pointer.1061 const shouldBubbleActualDurations =1062 completedWork.alternate === null ||1063 completedWork.child !== completedWork.alternate.child;1064 let child = completedWork.child;1065 while (child !== null) {1066 const childUpdateExpirationTime = child.expirationTime;1067 const childChildExpirationTime = child.childExpirationTime;1068 if (childUpdateExpirationTime > newChildExpirationTime) {1069 newChildExpirationTime = childUpdateExpirationTime;1070 }1071 if (childChildExpirationTime > newChildExpirationTime) {1072 newChildExpirationTime = childChildExpirationTime;1073 }1074 if (shouldBubbleActualDurations) {1075 actualDuration += child.actualDuration;1076 }1077 treeBaseDuration += child.treeBaseDuration;1078 child = child.sibling;1079 }1080 completedWork.actualDuration = actualDuration;1081 completedWork.treeBaseDuration = treeBaseDuration;1082 } else {1083 let child = completedWork.child;1084 while (child !== null) {1085 const childUpdateExpirationTime = child.expirationTime;1086 const childChildExpirationTime = child.childExpirationTime;1087 if (childUpdateExpirationTime > newChildExpirationTime) {1088 newChildExpirationTime = childUpdateExpirationTime;1089 }1090 if (childChildExpirationTime > newChildExpirationTime) {1091 newChildExpirationTime = childChildExpirationTime;1092 }1093 child = child.sibling;1094 }1095 }1096 completedWork.childExpirationTime = newChildExpirationTime;1097}1098function commitRoot(root, expirationTime) {1099 runWithPriority(1100 ImmediatePriority,1101 commitRootImpl.bind(null, root, expirationTime),1102 );1103 // If there are passive effects, schedule a callback to flush them. This goes1104 // outside commitRootImpl so that it inherits the priority of the render.1105 if (rootWithPendingPassiveEffects !== null) {1106 const priorityLevel = getCurrentPriorityLevel();1107 scheduleCallback(priorityLevel, () => {1108 flushPassiveEffects();1109 return null;1110 });1111 }1112 return null;1113}1114function commitRootImpl(root, expirationTime) {1115 flushPassiveEffects();1116 flushRenderPhaseStrictModeWarningsInDEV();1117 invariant(1118 workPhase !== RenderPhase && workPhase !== CommitPhase,1119 'Should not already be working.',1120 );1121 const finishedWork = root.current.alternate;1122 invariant(finishedWork !== null, 'Should have a work-in-progress root.');1123 // commitRoot never returns a continuation; it always finishes synchronously.1124 // So we can clear these now to allow a new callback to be scheduled.1125 root.callbackNode = null;1126 root.callbackExpirationTime = NoWork;1127 startCommitTimer();1128 // Update the first and last pending times on this root. The new first1129 // pending time is whatever is left on the root fiber.1130 const updateExpirationTimeBeforeCommit = finishedWork.expirationTime;1131 const childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;1132 const firstPendingTimeBeforeCommit =1133 childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit1134 ? childExpirationTimeBeforeCommit1135 : updateExpirationTimeBeforeCommit;1136 root.firstPendingTime = firstPendingTimeBeforeCommit;1137 if (firstPendingTimeBeforeCommit < root.lastPendingTime) {1138 // This usually means we've finished all the work, but it can also happen1139 // when something gets downprioritized during render, like a hidden tree.1140 root.lastPendingTime = firstPendingTimeBeforeCommit;1141 }1142 if (root === workInProgressRoot) {1143 // We can reset these now that they are finished.1144 workInProgressRoot = null;1145 workInProgress = null;1146 renderExpirationTime = NoWork;1147 } else {1148 // This indicates that the last root we worked on is not the same one that1149 // we're committing now. This most commonly happens when a suspended root1150 // times out.1151 }1152 // Get the list of effects.1153 let firstEffect;1154 if (finishedWork.effectTag > PerformedWork) {1155 // A fiber's effect list consists only of its children, not itself. So if1156 // the root has an effect, we need to add it to the end of the list. The1157 // resulting list is the set that would belong to the root's parent, if it1158 // had one; that is, all the effects in the tree including the root.1159 if (finishedWork.lastEffect !== null) {1160 finishedWork.lastEffect.nextEffect = finishedWork;1161 firstEffect = finishedWork.firstEffect;1162 } else {1163 firstEffect = finishedWork;1164 }1165 } else {1166 // There is no effect on the root.1167 firstEffect = finishedWork.firstEffect;1168 }1169 if (firstEffect !== null) {1170 const prevWorkPhase = workPhase;1171 workPhase = CommitPhase;1172 let prevInteractions: Set<Interaction> | null = null;1173 if (enableSchedulerTracing) {1174 prevInteractions = __interactionsRef.current;1175 __interactionsRef.current = root.memoizedInteractions;1176 }1177 // Reset this to null before calling lifecycles1178 ReactCurrentOwner.current = null;1179 // The commit phase is broken into several sub-phases. We do a separate pass1180 // of the effect list for each phase: all mutation effects come before all1181 // layout effects, and so on.1182 // The first phase a "before mutation" phase. We use this phase to read the1183 // state of the host tree right before we mutate it. This is where1184 // getSnapshotBeforeUpdate is called.1185 startCommitSnapshotEffectsTimer();1186 prepareForCommit(root.containerInfo);1187 nextEffect = firstEffect;1188 do {1189 if (__DEV__) {1190 invokeGuardedCallback(null, commitBeforeMutationEffects, null);1191 if (hasCaughtError()) {1192 invariant(nextEffect !== null, 'Should be working on an effect.');1193 const error = clearCaughtError();1194 captureCommitPhaseError(nextEffect, error);1195 nextEffect = nextEffect.nextEffect;1196 }1197 } else {1198 try {1199 commitBeforeMutationEffects();1200 } catch (error) {1201 invariant(nextEffect !== null, 'Should be working on an effect.');1202 captureCommitPhaseError(nextEffect, error);1203 nextEffect = nextEffect.nextEffect;1204 }1205 }1206 } while (nextEffect !== null);1207 stopCommitSnapshotEffectsTimer();1208 if (enableProfilerTimer) {1209 // Mark the current commit time to be shared by all Profilers in this1210 // batch. This enables them to be grouped later.1211 recordCommitTime();1212 }1213 // The next phase is the mutation phase, where we mutate the host tree.1214 startCommitHostEffectsTimer();1215 nextEffect = firstEffect;1216 do {1217 if (__DEV__) {1218 invokeGuardedCallback(null, commitMutationEffects, null);1219 if (hasCaughtError()) {1220 invariant(nextEffect !== null, 'Should be working on an effect.');1221 const error = clearCaughtError();1222 captureCommitPhaseError(nextEffect, error);1223 nextEffect = nextEffect.nextEffect;1224 }1225 } else {1226 try {1227 commitMutationEffects();1228 } catch (error) {1229 invariant(nextEffect !== null, 'Should be working on an effect.');1230 captureCommitPhaseError(nextEffect, error);1231 nextEffect = nextEffect.nextEffect;1232 }1233 }1234 } while (nextEffect !== null);1235 stopCommitHostEffectsTimer();1236 resetAfterCommit(root.containerInfo);1237 // The work-in-progress tree is now the current tree. This must come after1238 // the mutation phase, so that the previous tree is still current during1239 // componentWillUnmount, but before the layout phase, so that the finished1240 // work is current during componentDidMount/Update.1241 root.current = finishedWork;1242 // The next phase is the layout phase, where we call effects that read1243 // the host tree after it's been mutated. The idiomatic use case for this is1244 // layout, but class component lifecycles also fire here for legacy reasons.1245 startCommitLifeCyclesTimer();1246 nextEffect = firstEffect;1247 do {1248 if (__DEV__) {1249 invokeGuardedCallback(1250 null,1251 commitLayoutEffects,1252 null,1253 root,1254 expirationTime,1255 );1256 if (hasCaughtError()) {1257 invariant(nextEffect !== null, 'Should be working on an effect.');1258 const error = clearCaughtError();1259 captureCommitPhaseError(nextEffect, error);1260 nextEffect = nextEffect.nextEffect;1261 }1262 } else {1263 try {1264 commitLayoutEffects(root, expirationTime);1265 } catch (error) {1266 invariant(nextEffect !== null, 'Should be working on an effect.');1267 captureCommitPhaseError(nextEffect, error);1268 nextEffect = nextEffect.nextEffect;1269 }1270 }1271 } while (nextEffect !== null);1272 stopCommitLifeCyclesTimer();1273 nextEffect = null;1274 if (enableSchedulerTracing) {1275 __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);1276 }1277 workPhase = prevWorkPhase;1278 } else {1279 // No effects.1280 root.current = finishedWork;1281 // Measure these anyway so the flamegraph explicitly shows that there were1282 // no effects.1283 // TODO: Maybe there's a better way to report this.1284 startCommitSnapshotEffectsTimer();1285 stopCommitSnapshotEffectsTimer();1286 if (enableProfilerTimer) {1287 recordCommitTime();1288 }1289 startCommitHostEffectsTimer();1290 stopCommitHostEffectsTimer();1291 startCommitLifeCyclesTimer();1292 stopCommitLifeCyclesTimer();1293 }1294 stopCommitTimer();1295 if (rootDoesHavePassiveEffects) {1296 // This commit has passive effects. Stash a reference to them. But don't1297 // schedule a callback until after flushing layout work.1298 rootDoesHavePassiveEffects = false;1299 rootWithPendingPassiveEffects = root;1300 pendingPassiveEffectsExpirationTime = expirationTime;1301 } else {1302 if (enableSchedulerTracing) {1303 // If there are no passive effects, then we can complete the pending1304 // interactions. Otherwise, we'll wait until after the passive effects1305 // are flushed.1306 finishPendingInteractions(root, expirationTime);1307 }1308 }1309 // Check if there's remaining work on this root1310 const remainingExpirationTime = root.firstPendingTime;1311 if (remainingExpirationTime !== NoWork) {1312 const currentTime = requestCurrentTime();1313 const priorityLevel = inferPriorityFromExpirationTime(1314 currentTime,1315 remainingExpirationTime,1316 );1317 scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);1318 } else {1319 // If there's no remaining work, we can clear the set of already failed1320 // error boundaries.1321 legacyErrorBoundariesThatAlreadyFailed = null;1322 }1323 onCommitRoot(finishedWork.stateNode);1324 if (remainingExpirationTime === Sync) {1325 // Count the number of times the root synchronously re-renders without1326 // finishing. If there are too many, it indicates an infinite update loop.1327 if (root === rootWithNestedUpdates) {1328 nestedUpdateCount++;1329 } else {1330 nestedUpdateCount = 0;1331 rootWithNestedUpdates = root;1332 }1333 } else {1334 nestedUpdateCount = 0;1335 }1336 if (hasUncaughtError) {1337 hasUncaughtError = false;1338 const error = firstUncaughtError;1339 firstUncaughtError = null;1340 throw error;1341 }1342 if (workPhase === LegacyUnbatchedPhase) {1343 // This is a legacy edge case. We just committed the initial mount of1344 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired1345 // synchronously, but layout updates should be deferred until the end1346 // of the batch.1347 return null;1348 }1349 // If layout work was scheduled, flush it now.1350 flushImmediateQueue();1351 return null;1352}1353function commitBeforeMutationEffects() {1354 while (nextEffect !== null) {1355 if ((nextEffect.effectTag & Snapshot) !== NoEffect) {1356 setCurrentDebugFiberInDEV(nextEffect);1357 recordEffect();1358 const current = nextEffect.alternate;1359 commitBeforeMutationEffectOnFiber(current, nextEffect);1360 resetCurrentDebugFiberInDEV();1361 }1362 nextEffect = nextEffect.nextEffect;1363 }1364}1365function commitMutationEffects() {1366 // TODO: Should probably move the bulk of this function to commitWork.1367 while (nextEffect !== null) {1368 setCurrentDebugFiberInDEV(nextEffect);1369 const effectTag = nextEffect.effectTag;1370 if (effectTag & ContentReset) {1371 commitResetTextContent(nextEffect);1372 }1373 if (effectTag & Ref) {1374 const current = nextEffect.alternate;1375 if (current !== null) {1376 commitDetachRef(current);1377 }1378 }1379 // The following switch statement is only concerned about placement,1380 // updates, and deletions. To avoid needing to add a case for every possible1381 // bitmap value, we remove the secondary effects from the effect tag and1382 // switch on that value.1383 let primaryEffectTag = effectTag & (Placement | Update | Deletion);1384 switch (primaryEffectTag) {1385 case Placement: {1386 commitPlacement(nextEffect);1387 // Clear the "placement" from effect tag so that we know that this is1388 // inserted, before any life-cycles like componentDidMount gets called.1389 // TODO: findDOMNode doesn't rely on this any more but isMounted does1390 // and isMounted is deprecated anyway so we should be able to kill this.1391 nextEffect.effectTag &= ~Placement;1392 break;1393 }1394 case PlacementAndUpdate: {1395 // Placement1396 commitPlacement(nextEffect);1397 // Clear the "placement" from effect tag so that we know that this is1398 // inserted, before any life-cycles like componentDidMount gets called.1399 nextEffect.effectTag &= ~Placement;1400 // Update1401 const current = nextEffect.alternate;1402 commitWork(current, nextEffect);1403 break;1404 }1405 case Update: {1406 const current = nextEffect.alternate;1407 commitWork(current, nextEffect);1408 break;1409 }1410 case Deletion: {1411 commitDeletion(nextEffect);1412 break;1413 }1414 }1415 // TODO: Only record a mutation effect if primaryEffectTag is non-zero.1416 recordEffect();1417 resetCurrentDebugFiberInDEV();1418 nextEffect = nextEffect.nextEffect;1419 }1420}1421function commitLayoutEffects(1422 root: FiberRoot,1423 committedExpirationTime: ExpirationTime,1424) {1425 // TODO: Should probably move the bulk of this function to commitWork.1426 while (nextEffect !== null) {1427 setCurrentDebugFiberInDEV(nextEffect);1428 const effectTag = nextEffect.effectTag;1429 if (effectTag & (Update | Callback)) {1430 recordEffect();1431 const current = nextEffect.alternate;1432 commitLayoutEffectOnFiber(1433 root,1434 current,1435 nextEffect,1436 committedExpirationTime,1437 );1438 }1439 if (effectTag & Ref) {1440 recordEffect();1441 commitAttachRef(nextEffect);1442 }1443 if (effectTag & Passive) {1444 rootDoesHavePassiveEffects = true;1445 }1446 resetCurrentDebugFiberInDEV();1447 nextEffect = nextEffect.nextEffect;1448 }1449}1450export function flushPassiveEffects() {1451 if (rootWithPendingPassiveEffects === null) {1452 return false;1453 }1454 const root = rootWithPendingPassiveEffects;1455 const expirationTime = pendingPassiveEffectsExpirationTime;1456 rootWithPendingPassiveEffects = null;1457 pendingPassiveEffectsExpirationTime = NoWork;1458 let prevInteractions: Set<Interaction> | null = null;1459 if (enableSchedulerTracing) {1460 prevInteractions = __interactionsRef.current;1461 __interactionsRef.current = root.memoizedInteractions;1462 }1463 invariant(1464 workPhase !== RenderPhase && workPhase !== CommitPhase,1465 'Cannot flush passive effects while already rendering.',1466 );1467 const prevWorkPhase = workPhase;1468 workPhase = CommitPhase;1469 // Note: This currently assumes there are no passive effects on the root1470 // fiber, because the root is not part of its own effect list. This could1471 // change in the future.1472 let effect = root.current.firstEffect;1473 while (effect !== null) {1474 if (__DEV__) {1475 setCurrentDebugFiberInDEV(effect);1476 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);1477 if (hasCaughtError()) {1478 invariant(effect !== null, 'Should be working on an effect.');1479 const error = clearCaughtError();1480 captureCommitPhaseError(effect, error);1481 }1482 resetCurrentDebugFiberInDEV();1483 } else {1484 try {1485 commitPassiveHookEffects(effect);1486 } catch (error) {1487 invariant(effect !== null, 'Should be working on an effect.');1488 captureCommitPhaseError(effect, error);1489 }1490 }1491 effect = effect.nextEffect;1492 }1493 if (enableSchedulerTracing) {1494 __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);1495 finishPendingInteractions(root, expirationTime);1496 }1497 workPhase = prevWorkPhase;1498 flushImmediateQueue();1499 // If additional passive effects were scheduled, increment a counter. If this1500 // exceeds the limit, we'll fire a warning.1501 nestedPassiveUpdateCount =1502 rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;1503 return true;1504}1505export function isAlreadyFailedLegacyErrorBoundary(instance: mixed): boolean {1506 return (1507 legacyErrorBoundariesThatAlreadyFailed !== null &&1508 legacyErrorBoundariesThatAlreadyFailed.has(instance)1509 );1510}1511export function markLegacyErrorBoundaryAsFailed(instance: mixed) {1512 if (legacyErrorBoundariesThatAlreadyFailed === null) {1513 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);1514 } else {1515 legacyErrorBoundariesThatAlreadyFailed.add(instance);1516 }1517}1518function prepareToThrowUncaughtError(error: mixed) {1519 if (!hasUncaughtError) {1520 hasUncaughtError = true;1521 firstUncaughtError = error;1522 }1523}1524export const onUncaughtError = prepareToThrowUncaughtError;1525function captureCommitPhaseErrorOnRoot(1526 rootFiber: Fiber,1527 sourceFiber: Fiber,1528 error: mixed,1529) {1530 const errorInfo = createCapturedValue(error, sourceFiber);1531 const update = createRootErrorUpdate(rootFiber, errorInfo, Sync);1532 enqueueUpdate(rootFiber, update);1533 const root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);1534 if (root !== null) {1535 scheduleCallbackForRoot(root, ImmediatePriority, Sync);1536 }1537}1538export function captureCommitPhaseError(sourceFiber: Fiber, error: mixed) {1539 if (sourceFiber.tag === HostRoot) {1540 // Error was thrown at the root. There is no parent, so the root1541 // itself should capture it.1542 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);1543 return;1544 }1545 let fiber = sourceFiber.return;1546 while (fiber !== null) {1547 if (fiber.tag === HostRoot) {1548 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);1549 return;1550 } else if (fiber.tag === ClassComponent) {1551 const ctor = fiber.type;1552 const instance = fiber.stateNode;1553 if (1554 typeof ctor.getDerivedStateFromError === 'function' ||1555 (typeof instance.componentDidCatch === 'function' &&1556 !isAlreadyFailedLegacyErrorBoundary(instance))1557 ) {1558 const errorInfo = createCapturedValue(error, sourceFiber);1559 const update = createClassErrorUpdate(1560 fiber,1561 errorInfo,1562 // TODO: This is always sync1563 Sync,1564 );1565 enqueueUpdate(fiber, update);1566 const root = markUpdateTimeFromFiberToRoot(fiber, Sync);1567 if (root !== null) {1568 scheduleCallbackForRoot(root, ImmediatePriority, Sync);1569 }1570 return;1571 }1572 }1573 fiber = fiber.return;1574 }1575}1576export function pingSuspendedRoot(1577 root: FiberRoot,1578 thenable: Thenable,1579 suspendedTime: ExpirationTime,1580) {1581 const pingCache = root.pingCache;1582 if (pingCache !== null) {1583 // The thenable resolved, so we no longer need to memoize, because it will1584 // never be thrown again.1585 pingCache.delete(thenable);1586 }1587 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {1588 // Received a ping at the same priority level at which we're currently1589 // rendering. Restart from the root. Don't need to schedule a ping because1590 // we're already working on this tree.1591 prepareFreshStack(root, renderExpirationTime);1592 return;1593 }1594 const lastPendingTime = root.lastPendingTime;1595 if (lastPendingTime < suspendedTime) {1596 // The root is no longer suspended at this time.1597 return;1598 }1599 const pingTime = root.pingTime;1600 if (pingTime !== NoWork && pingTime < suspendedTime) {1601 // There's already a lower priority ping scheduled.1602 return;1603 }1604 // Mark the time at which this ping was scheduled.1605 root.pingTime = suspendedTime;1606 const currentTime = requestCurrentTime();1607 const priorityLevel = inferPriorityFromExpirationTime(1608 currentTime,1609 suspendedTime,1610 );1611 scheduleCallbackForRoot(root, priorityLevel, suspendedTime);1612}1613export function retryTimedOutBoundary(boundaryFiber: Fiber) {1614 // The boundary fiber (a Suspense component) previously timed out and was1615 // rendered in its fallback state. One of the promises that suspended it has1616 // resolved, which means at least part of the tree was likely unblocked. Try1617 // rendering again, at a new expiration time.1618 const currentTime = requestCurrentTime();1619 const retryTime = computeExpirationForFiber(currentTime, boundaryFiber);1620 // TODO: Special case idle priority?1621 const priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);1622 const root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);1623 if (root !== null) {1624 scheduleCallbackForRoot(root, priorityLevel, retryTime);1625 }1626}1627export function resolveRetryThenable(boundaryFiber: Fiber, thenable: Thenable) {1628 let retryCache: WeakSet<Thenable> | Set<Thenable> | null;1629 if (enableSuspenseServerRenderer) {1630 switch (boundaryFiber.tag) {1631 case SuspenseComponent:1632 retryCache = boundaryFiber.stateNode;1633 break;1634 case DehydratedSuspenseComponent:1635 retryCache = boundaryFiber.memoizedState;1636 break;1637 default:1638 invariant(1639 false,1640 'Pinged unknown suspense boundary type. ' +1641 'This is probably a bug in React.',1642 );1643 }1644 } else {1645 retryCache = boundaryFiber.stateNode;1646 }1647 if (retryCache !== null) {1648 // The thenable resolved, so we no longer need to memoize, because it will1649 // never be thrown again.1650 retryCache.delete(thenable);1651 }1652 retryTimedOutBoundary(boundaryFiber);1653}1654// Computes the next Just Noticeable Difference (JND) boundary.1655// The theory is that a person can't tell the difference between small differences in time.1656// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable1657// difference in the experience. However, waiting for longer might mean that we can avoid1658// showing an intermediate loading state. The longer we have already waited, the harder it1659// is to tell small differences in time. Therefore, the longer we've already waited,1660// the longer we can wait additionally. At some point we have to give up though.1661// We pick a train model where the next boundary commits at a consistent schedule.1662// These particular numbers are vague estimates. We expect to adjust them based on research.1663function jnd(timeElapsed: number) {1664 return timeElapsed < 1201665 ? 1201666 : timeElapsed < 4801667 ? 4801668 : timeElapsed < 10801669 ? 10801670 : timeElapsed < 19201671 ? 19201672 : timeElapsed < 30001673 ? 30001674 : timeElapsed < 43201675 ? 43201676 : ceil(timeElapsed / 1960) * 1960;1677}1678function computeMsUntilTimeout(1679 mostRecentEventTime: ExpirationTime,1680 committedExpirationTime: ExpirationTime,1681) {1682 if (disableYielding) {1683 // Timeout immediately when yielding is disabled.1684 return 0;1685 }1686 const eventTimeMs: number = inferTimeFromExpirationTime(mostRecentEventTime);1687 const currentTimeMs: number = now();1688 const timeElapsed = currentTimeMs - eventTimeMs;1689 let msUntilTimeout = jnd(timeElapsed) - timeElapsed;1690 // Compute the time until this render pass would expire.1691 const timeUntilExpirationMs =1692 expirationTimeToMs(committedExpirationTime) - currentTimeMs;1693 // Clamp the timeout to the expiration time.1694 // TODO: Once the event time is exact instead of inferred from expiration time1695 // we don't need this.1696 if (timeUntilExpirationMs < msUntilTimeout) {1697 msUntilTimeout = timeUntilExpirationMs;1698 }1699 // This is the value that is passed to `setTimeout`.1700 return msUntilTimeout;1701}1702function checkForNestedUpdates() {1703 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {1704 nestedUpdateCount = 0;1705 rootWithNestedUpdates = null;1706 invariant(1707 false,1708 'Maximum update depth exceeded. This can happen when a component ' +1709 'repeatedly calls setState inside componentWillUpdate or ' +1710 'componentDidUpdate. React limits the number of nested updates to ' +1711 'prevent infinite loops.',1712 );1713 }1714 if (__DEV__) {1715 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {1716 nestedPassiveUpdateCount = 0;1717 warning(1718 false,1719 'Maximum update depth exceeded. This can happen when a component ' +1720 "calls setState inside useEffect, but useEffect either doesn't " +1721 'have a dependency array, or one of the dependencies changes on ' +1722 'every render.',1723 );1724 }1725 }1726}1727function flushRenderPhaseStrictModeWarningsInDEV() {1728 if (__DEV__) {1729 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();1730 ReactStrictModeWarnings.flushLegacyContextWarning();1731 if (warnAboutDeprecatedLifecycles) {1732 ReactStrictModeWarnings.flushPendingDeprecationWarnings();1733 }1734 }1735}1736function stopFinishedWorkLoopTimer() {1737 const didCompleteRoot = true;1738 stopWorkLoopTimer(interruptedBy, didCompleteRoot);1739 interruptedBy = null;1740}1741function stopInterruptedWorkLoopTimer() {1742 // TODO: Track which fiber caused the interruption.1743 const didCompleteRoot = false;1744 stopWorkLoopTimer(interruptedBy, didCompleteRoot);1745 interruptedBy = null;1746}1747function checkForInterruption(1748 fiberThatReceivedUpdate: Fiber,1749 updateExpirationTime: ExpirationTime,1750) {1751 if (1752 enableUserTimingAPI &&1753 workInProgressRoot !== null &&1754 updateExpirationTime > renderExpirationTime1755 ) {1756 interruptedBy = fiberThatReceivedUpdate;1757 }1758}1759let didWarnStateUpdateForUnmountedComponent: Set<string> | null = null;1760function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {1761 if (__DEV__) {1762 const tag = fiber.tag;1763 if (1764 tag !== HostRoot &&1765 tag !== ClassComponent &&1766 tag !== FunctionComponent &&1767 tag !== ForwardRef &&1768 tag !== MemoComponent &&1769 tag !== SimpleMemoComponent1770 ) {1771 // Only warn for user-defined components, not internal ones like Suspense.1772 return;1773 }1774 // We show the whole stack but dedupe on the top component's name because1775 // the problematic code almost always lies inside that component.1776 const componentName = getComponentName(fiber.type) || 'ReactComponent';1777 if (didWarnStateUpdateForUnmountedComponent !== null) {1778 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {1779 return;1780 }1781 didWarnStateUpdateForUnmountedComponent.add(componentName);1782 } else {1783 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);1784 }1785 warningWithoutStack(1786 false,1787 "Can't perform a React state update on an unmounted component. This " +1788 'is a no-op, but it indicates a memory leak in your application. To ' +1789 'fix, cancel all subscriptions and asynchronous tasks in %s.%s',1790 tag === ClassComponent1791 ? 'the componentWillUnmount method'1792 : 'a useEffect cleanup function',1793 getStackByFiberInDevAndProd(fiber),1794 );1795 }1796}1797let beginWork;1798if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) {1799 let dummyFiber = null;1800 beginWork = (current, unitOfWork, expirationTime) => {1801 // If a component throws an error, we replay it again in a synchronously1802 // dispatched event, so that the debugger will treat it as an uncaught1803 // error See ReactErrorUtils for more information.1804 // Before entering the begin phase, copy the work-in-progress onto a dummy1805 // fiber. If beginWork throws, we'll use this to reset the state.1806 const originalWorkInProgressCopy = assignFiberPropertiesInDEV(1807 dummyFiber,1808 unitOfWork,1809 );1810 try {1811 return originalBeginWork(current, unitOfWork, expirationTime);1812 } catch (originalError) {1813 if (1814 originalError !== null &&1815 typeof originalError === 'object' &&1816 typeof originalError.then === 'function'1817 ) {1818 // Don't replay promises. Treat everything else like an error.1819 throw originalError;1820 }1821 // Keep this code in sync with renderRoot; any changes here must have1822 // corresponding changes there.1823 resetContextDependencies();1824 resetHooks();1825 // Unwind the failed stack frame1826 unwindInterruptedWork(unitOfWork);1827 // Restore the original properties of the fiber.1828 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);1829 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {1830 // Reset the profiler timer.1831 startProfilerTimer(unitOfWork);1832 }1833 // Run beginWork again.1834 invokeGuardedCallback(1835 null,1836 originalBeginWork,1837 null,...

Full Screen

Full Screen

ReactFiberScheduler.new.js

Source:ReactFiberScheduler.new.js Github

copy

Full Screen

...689 const currentTime = requestCurrentTime();690 if (currentTime < expirationTime) {691 // Restart at the current time.692 workPhase = prevWorkPhase;693 resetContextDependencies();694 ReactCurrentDispatcher.current = prevDispatcher;695 if (enableSchedulerTracing) {696 __interactionsRef.current = ((prevInteractions: any): Set<697 Interaction,698 >);699 }700 return renderRoot.bind(null, root, currentTime);701 }702 }703 } else {704 // Since we know we're in a React event, we can clear the current705 // event time. The next update will compute a new event time.706 currentEventTime = NoWork;707 }708 do {709 try {710 if (isSync) {711 workLoopSync();712 } else {713 workLoop();714 }715 break;716 } catch (thrownValue) {717 // Reset module-level state that was set during the render phase.718 resetContextDependencies();719 resetHooks();720 const sourceFiber = workInProgress;721 if (sourceFiber === null || sourceFiber.return === null) {722 // Expected to be working on a non-root fiber. This is a fatal error723 // because there's no ancestor that can handle it; the root is724 // supposed to capture all errors that weren't caught by an error725 // boundary.726 prepareFreshStack(root, expirationTime);727 workPhase = prevWorkPhase;728 throw thrownValue;729 }730 if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {731 // Record the time spent rendering before an error was thrown. This732 // avoids inaccurate Profiler durations in the case of a733 // suspended render.734 stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);735 }736 const returnFiber = sourceFiber.return;737 throwException(738 root,739 returnFiber,740 sourceFiber,741 thrownValue,742 renderExpirationTime,743 );744 workInProgress = completeUnitOfWork(sourceFiber);745 }746 } while (true);747 workPhase = prevWorkPhase;748 resetContextDependencies();749 ReactCurrentDispatcher.current = prevDispatcher;750 if (enableSchedulerTracing) {751 __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);752 }753 if (workInProgress !== null) {754 // There's still work left over. Return a continuation.755 stopInterruptedWorkLoopTimer();756 if (expirationTime !== Sync) {757 startRequestCallbackTimer();758 }759 return renderRoot.bind(null, root, expirationTime);760 }761 }762 // We now have a consistent tree. The next step is either to commit it, or, if763 // something suspended, wait to commit it after a timeout.764 stopFinishedWorkLoopTimer();765 const isLocked = resolveLocksOnRoot(root, expirationTime);766 if (isLocked) {767 // This root has a lock that prevents it from committing. Exit. If we begin768 // work on the root again, without any intervening updates, it will finish769 // without doing additional work.770 return null;771 }772 // Set this to null to indicate there's no in-progress render.773 workInProgressRoot = null;774 switch (workInProgressRootExitStatus) {775 case RootIncomplete: {776 invariant(false, 'Should have a work-in-progress.');777 }778 // Flow knows about invariant, so it compains if I add a break statement,779 // but eslint doesn't know about invariant, so it complains if I do.780 // eslint-disable-next-line no-fallthrough781 case RootErrored: {782 // An error was thrown. First check if there is lower priority work783 // scheduled on this root.784 const lastPendingTime = root.lastPendingTime;785 if (root.lastPendingTime < expirationTime) {786 // There's lower priority work. Before raising the error, try rendering787 // at the lower priority to see if it fixes it. Use a continuation to788 // maintain the existing priority and position in the queue.789 return renderRoot.bind(null, root, lastPendingTime);790 }791 if (!isSync) {792 // If we're rendering asynchronously, it's possible the error was793 // caused by tearing due to a mutation during an event. Try rendering794 // one more time without yiedling to events.795 prepareFreshStack(root, expirationTime);796 scheduleCallback(797 ImmediatePriority,798 renderRoot.bind(null, root, expirationTime),799 );800 return null;801 }802 // If we're already rendering synchronously, commit the root in its803 // errored state.804 return commitRoot.bind(null, root, expirationTime);805 }806 case RootSuspended: {807 const lastPendingTime = root.lastPendingTime;808 if (root.lastPendingTime < expirationTime) {809 // There's lower priority work. It might be unsuspended. Try rendering810 // at that level.811 return renderRoot.bind(null, root, lastPendingTime);812 }813 if (!isSync) {814 const msUntilTimeout = computeMsUntilTimeout(815 root,816 workInProgressRootAbsoluteTimeoutMs,817 );818 if (msUntilTimeout > 0) {819 // The render is suspended, it hasn't timed out, and there's no lower820 // priority work to do. Instead of committing the fallback821 // immediately, wait for more data to arrive.822 root.timeoutHandle = scheduleTimeout(823 commitRoot.bind(null, root, expirationTime),824 msUntilTimeout,825 );826 return null;827 }828 }829 // The work expired. Commit immediately.830 return commitRoot.bind(null, root, expirationTime);831 }832 case RootCompleted: {833 // The work completed. Ready to commit.834 return commitRoot.bind(null, root, expirationTime);835 }836 default: {837 invariant(false, 'Unknown root exit status.');838 }839 }840}841export function renderDidSuspend(842 root: FiberRoot,843 absoluteTimeoutMs: number,844 // TODO: Don't need this argument anymore845 suspendedTime: ExpirationTime,846) {847 if (848 absoluteTimeoutMs >= 0 &&849 workInProgressRootAbsoluteTimeoutMs < absoluteTimeoutMs850 ) {851 workInProgressRootAbsoluteTimeoutMs = absoluteTimeoutMs;852 if (workInProgressRootExitStatus === RootIncomplete) {853 workInProgressRootExitStatus = RootSuspended;854 }855 }856}857export function renderDidError() {858 if (859 workInProgressRootExitStatus === RootIncomplete ||860 workInProgressRootExitStatus === RootSuspended861 ) {862 workInProgressRootExitStatus = RootErrored;863 }864}865function workLoopSync() {866 // Already timed out, so perform work without checking if we need to yield.867 while (workInProgress !== null) {868 workInProgress = performUnitOfWork(workInProgress);869 }870}871function workLoop() {872 // Perform work until Scheduler asks us to yield873 while (workInProgress !== null && !shouldYield()) {874 workInProgress = performUnitOfWork(workInProgress);875 }876}877function performUnitOfWork(unitOfWork: Fiber): Fiber | null {878 // The current, flushed, state of this fiber is the alternate. Ideally879 // nothing should rely on this, but relying on it here means that we don't880 // need an additional field on the work in progress.881 const current = unitOfWork.alternate;882 startWorkTimer(unitOfWork);883 setCurrentDebugFiberInDEV(unitOfWork);884 let next;885 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoContext) {886 startProfilerTimer(unitOfWork);887 next = beginWork(current, unitOfWork, renderExpirationTime);888 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);889 } else {890 next = beginWork(current, unitOfWork, renderExpirationTime);891 }892 resetCurrentDebugFiberInDEV();893 unitOfWork.memoizedProps = unitOfWork.pendingProps;894 if (next === null) {895 // If this doesn't spawn new work, complete the current work.896 next = completeUnitOfWork(unitOfWork);897 }898 ReactCurrentOwner.current = null;899 return next;900}901function completeUnitOfWork(unitOfWork: Fiber): Fiber | null {902 // Attempt to complete the current unit of work, then move to the next903 // sibling. If there are no more siblings, return to the parent fiber.904 workInProgress = unitOfWork;905 do {906 // The current, flushed, state of this fiber is the alternate. Ideally907 // nothing should rely on this, but relying on it here means that we don't908 // need an additional field on the work in progress.909 const current = workInProgress.alternate;910 const returnFiber = workInProgress.return;911 // Check if the work completed or if something threw.912 if ((workInProgress.effectTag & Incomplete) === NoEffect) {913 setCurrentDebugFiberInDEV(workInProgress);914 let next;915 if (916 !enableProfilerTimer ||917 (workInProgress.mode & ProfileMode) === NoContext918 ) {919 next = completeWork(current, workInProgress, renderExpirationTime);920 } else {921 startProfilerTimer(workInProgress);922 next = completeWork(current, workInProgress, renderExpirationTime);923 // Update render duration assuming we didn't error.924 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);925 }926 stopWorkTimer(workInProgress);927 resetCurrentDebugFiberInDEV();928 resetChildExpirationTime(workInProgress);929 if (next !== null) {930 // Completing this fiber spawned new work. Work on that next.931 return next;932 }933 if (934 returnFiber !== null &&935 // Do not append effects to parents if a sibling failed to complete936 (returnFiber.effectTag & Incomplete) === NoEffect937 ) {938 // Append all the effects of the subtree and this fiber onto the effect939 // list of the parent. The completion order of the children affects the940 // side-effect order.941 if (returnFiber.firstEffect === null) {942 returnFiber.firstEffect = workInProgress.firstEffect;943 }944 if (workInProgress.lastEffect !== null) {945 if (returnFiber.lastEffect !== null) {946 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;947 }948 returnFiber.lastEffect = workInProgress.lastEffect;949 }950 // If this fiber had side-effects, we append it AFTER the children's951 // side-effects. We can perform certain side-effects earlier if needed,952 // by doing multiple passes over the effect list. We don't want to953 // schedule our own side-effect on our own list because if end up954 // reusing children we'll schedule this effect onto itself since we're955 // at the end.956 const effectTag = workInProgress.effectTag;957 // Skip both NoWork and PerformedWork tags when creating the effect958 // list. PerformedWork effect is read by React DevTools but shouldn't be959 // committed.960 if (effectTag > PerformedWork) {961 if (returnFiber.lastEffect !== null) {962 returnFiber.lastEffect.nextEffect = workInProgress;963 } else {964 returnFiber.firstEffect = workInProgress;965 }966 returnFiber.lastEffect = workInProgress;967 }968 }969 } else {970 // This fiber did not complete because something threw. Pop values off971 // the stack without entering the complete phase. If this is a boundary,972 // capture values if possible.973 const next = unwindWork(workInProgress, renderExpirationTime);974 // Because this fiber did not complete, don't reset its expiration time.975 if (976 enableProfilerTimer &&977 (workInProgress.mode & ProfileMode) !== NoContext978 ) {979 // Record the render duration for the fiber that errored.980 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);981 // Include the time spent working on failed children before continuing.982 let actualDuration = workInProgress.actualDuration;983 let child = workInProgress.child;984 while (child !== null) {985 actualDuration += child.actualDuration;986 child = child.sibling;987 }988 workInProgress.actualDuration = actualDuration;989 }990 if (next !== null) {991 // If completing this work spawned new work, do that next. We'll come992 // back here again.993 // Since we're restarting, remove anything that is not a host effect994 // from the effect tag.995 // TODO: The name stopFailedWorkTimer is misleading because Suspense996 // also captures and restarts.997 stopFailedWorkTimer(workInProgress);998 next.effectTag &= HostEffectMask;999 return next;1000 }1001 stopWorkTimer(workInProgress);1002 if (returnFiber !== null) {1003 // Mark the parent fiber as incomplete and clear its effect list.1004 returnFiber.firstEffect = returnFiber.lastEffect = null;1005 returnFiber.effectTag |= Incomplete;1006 }1007 }1008 const siblingFiber = workInProgress.sibling;1009 if (siblingFiber !== null) {1010 // If there is more work to do in this returnFiber, do that next.1011 return siblingFiber;1012 }1013 // Otherwise, return to the parent1014 workInProgress = returnFiber;1015 } while (workInProgress !== null);1016 // We've reached the root.1017 if (workInProgressRootExitStatus === RootIncomplete) {1018 workInProgressRootExitStatus = RootCompleted;1019 }1020 return null;1021}1022function resetChildExpirationTime(completedWork: Fiber) {1023 if (1024 renderExpirationTime !== Never &&1025 completedWork.childExpirationTime === Never1026 ) {1027 // The children of this component are hidden. Don't bubble their1028 // expiration times.1029 return;1030 }1031 let newChildExpirationTime = NoWork;1032 // Bubble up the earliest expiration time.1033 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoContext) {1034 // In profiling mode, resetChildExpirationTime is also used to reset1035 // profiler durations.1036 let actualDuration = completedWork.actualDuration;1037 let treeBaseDuration = completedWork.selfBaseDuration;1038 // When a fiber is cloned, its actualDuration is reset to 0. This value will1039 // only be updated if work is done on the fiber (i.e. it doesn't bailout).1040 // When work is done, it should bubble to the parent's actualDuration. If1041 // the fiber has not been cloned though, (meaning no work was done), then1042 // this value will reflect the amount of time spent working on a previous1043 // render. In that case it should not bubble. We determine whether it was1044 // cloned by comparing the child pointer.1045 const shouldBubbleActualDurations =1046 completedWork.alternate === null ||1047 completedWork.child !== completedWork.alternate.child;1048 let child = completedWork.child;1049 while (child !== null) {1050 const childUpdateExpirationTime = child.expirationTime;1051 const childChildExpirationTime = child.childExpirationTime;1052 if (childUpdateExpirationTime > newChildExpirationTime) {1053 newChildExpirationTime = childUpdateExpirationTime;1054 }1055 if (childChildExpirationTime > newChildExpirationTime) {1056 newChildExpirationTime = childChildExpirationTime;1057 }1058 if (shouldBubbleActualDurations) {1059 actualDuration += child.actualDuration;1060 }1061 treeBaseDuration += child.treeBaseDuration;1062 child = child.sibling;1063 }1064 completedWork.actualDuration = actualDuration;1065 completedWork.treeBaseDuration = treeBaseDuration;1066 } else {1067 let child = completedWork.child;1068 while (child !== null) {1069 const childUpdateExpirationTime = child.expirationTime;1070 const childChildExpirationTime = child.childExpirationTime;1071 if (childUpdateExpirationTime > newChildExpirationTime) {1072 newChildExpirationTime = childUpdateExpirationTime;1073 }1074 if (childChildExpirationTime > newChildExpirationTime) {1075 newChildExpirationTime = childChildExpirationTime;1076 }1077 child = child.sibling;1078 }1079 }1080 completedWork.childExpirationTime = newChildExpirationTime;1081}1082function commitRoot(root, expirationTime) {1083 runWithPriority(1084 ImmediatePriority,1085 commitRootImpl.bind(null, root, expirationTime),1086 );1087 // If there are passive effects, schedule a callback to flush them. This goes1088 // outside commitRootImpl so that it inherits the priority of the render.1089 if (rootWithPendingPassiveEffects !== null) {1090 const priorityLevel = getCurrentPriorityLevel();1091 scheduleCallback(priorityLevel, () => {1092 flushPassiveEffects();1093 return null;1094 });1095 }1096 return null;1097}1098function commitRootImpl(root, expirationTime) {1099 flushPassiveEffects();1100 flushRenderPhaseStrictModeWarningsInDEV();1101 invariant(1102 workPhase !== RenderPhase && workPhase !== CommitPhase,1103 'Should not already be working.',1104 );1105 const finishedWork = root.current.alternate;1106 invariant(finishedWork !== null, 'Should have a work-in-progress root.');1107 // commitRoot never returns a continuation; it always finishes synchronously.1108 // So we can clear these now to allow a new callback to be scheduled.1109 root.callbackNode = null;1110 root.callbackExpirationTime = NoWork;1111 startCommitTimer();1112 // Update the first and last pending times on this root. The new first1113 // pending time is whatever is left on the root fiber.1114 const updateExpirationTimeBeforeCommit = finishedWork.expirationTime;1115 const childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;1116 const firstPendingTimeBeforeCommit =1117 childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit1118 ? childExpirationTimeBeforeCommit1119 : updateExpirationTimeBeforeCommit;1120 root.firstPendingTime = firstPendingTimeBeforeCommit;1121 if (firstPendingTimeBeforeCommit < root.lastPendingTime) {1122 // This usually means we've finished all the work, but it can also happen1123 // when something gets downprioritized during render, like a hidden tree.1124 root.lastPendingTime = firstPendingTimeBeforeCommit;1125 }1126 if (root === workInProgressRoot) {1127 // We can reset these now that they are finished.1128 workInProgressRoot = null;1129 workInProgress = null;1130 renderExpirationTime = NoWork;1131 } else {1132 // This indicates that the last root we worked on is not the same one that1133 // we're committing now. This most commonly happens when a suspended root1134 // times out.1135 }1136 // Get the list of effects.1137 let firstEffect;1138 if (finishedWork.effectTag > PerformedWork) {1139 // A fiber's effect list consists only of its children, not itself. So if1140 // the root has an effect, we need to add it to the end of the list. The1141 // resulting list is the set that would belong to the root's parent, if it1142 // had one; that is, all the effects in the tree including the root.1143 if (finishedWork.lastEffect !== null) {1144 finishedWork.lastEffect.nextEffect = finishedWork;1145 firstEffect = finishedWork.firstEffect;1146 } else {1147 firstEffect = finishedWork;1148 }1149 } else {1150 // There is no effect on the root.1151 firstEffect = finishedWork.firstEffect;1152 }1153 if (firstEffect !== null) {1154 const prevWorkPhase = workPhase;1155 workPhase = CommitPhase;1156 let prevInteractions: Set<Interaction> | null = null;1157 if (enableSchedulerTracing) {1158 prevInteractions = __interactionsRef.current;1159 __interactionsRef.current = root.memoizedInteractions;1160 }1161 // Reset this to null before calling lifecycles1162 ReactCurrentOwner.current = null;1163 // The commit phase is broken into several sub-phases. We do a separate pass1164 // of the effect list for each phase: all mutation effects come before all1165 // layout effects, and so on.1166 // The first phase a "before mutation" phase. We use this phase to read the1167 // state of the host tree right before we mutate it. This is where1168 // getSnapshotBeforeUpdate is called.1169 startCommitSnapshotEffectsTimer();1170 prepareForCommit(root.containerInfo);1171 nextEffect = firstEffect;1172 do {1173 if (__DEV__) {1174 invokeGuardedCallback(null, commitBeforeMutationEffects, null);1175 if (hasCaughtError()) {1176 invariant(nextEffect !== null, 'Should be working on an effect.');1177 const error = clearCaughtError();1178 captureCommitPhaseError(nextEffect, error);1179 nextEffect = nextEffect.nextEffect;1180 }1181 } else {1182 try {1183 commitBeforeMutationEffects();1184 } catch (error) {1185 invariant(nextEffect !== null, 'Should be working on an effect.');1186 captureCommitPhaseError(nextEffect, error);1187 nextEffect = nextEffect.nextEffect;1188 }1189 }1190 } while (nextEffect !== null);1191 stopCommitSnapshotEffectsTimer();1192 if (enableProfilerTimer) {1193 // Mark the current commit time to be shared by all Profilers in this1194 // batch. This enables them to be grouped later.1195 recordCommitTime();1196 }1197 // The next phase is the mutation phase, where we mutate the host tree.1198 startCommitHostEffectsTimer();1199 nextEffect = firstEffect;1200 do {1201 if (__DEV__) {1202 invokeGuardedCallback(null, commitMutationEffects, null);1203 if (hasCaughtError()) {1204 invariant(nextEffect !== null, 'Should be working on an effect.');1205 const error = clearCaughtError();1206 captureCommitPhaseError(nextEffect, error);1207 nextEffect = nextEffect.nextEffect;1208 }1209 } else {1210 try {1211 commitMutationEffects();1212 } catch (error) {1213 invariant(nextEffect !== null, 'Should be working on an effect.');1214 captureCommitPhaseError(nextEffect, error);1215 nextEffect = nextEffect.nextEffect;1216 }1217 }1218 } while (nextEffect !== null);1219 stopCommitHostEffectsTimer();1220 resetAfterCommit(root.containerInfo);1221 // The work-in-progress tree is now the current tree. This must come after1222 // the mutation phase, so that the previous tree is still current during1223 // componentWillUnmount, but before the layout phase, so that the finished1224 // work is current during componentDidMount/Update.1225 root.current = finishedWork;1226 // The next phase is the layout phase, where we call effects that read1227 // the host tree after it's been mutated. The idiomatic use case for this is1228 // layout, but class component lifecycles also fire here for legacy reasons.1229 startCommitLifeCyclesTimer();1230 nextEffect = firstEffect;1231 do {1232 if (__DEV__) {1233 invokeGuardedCallback(1234 null,1235 commitLayoutEffects,1236 null,1237 root,1238 expirationTime,1239 );1240 if (hasCaughtError()) {1241 invariant(nextEffect !== null, 'Should be working on an effect.');1242 const error = clearCaughtError();1243 captureCommitPhaseError(nextEffect, error);1244 nextEffect = nextEffect.nextEffect;1245 }1246 } else {1247 try {1248 commitLayoutEffects(root, expirationTime);1249 } catch (error) {1250 invariant(nextEffect !== null, 'Should be working on an effect.');1251 captureCommitPhaseError(nextEffect, error);1252 nextEffect = nextEffect.nextEffect;1253 }1254 }1255 } while (nextEffect !== null);1256 stopCommitLifeCyclesTimer();1257 nextEffect = null;1258 if (enableSchedulerTracing) {1259 __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);1260 }1261 workPhase = prevWorkPhase;1262 } else {1263 // No effects.1264 root.current = finishedWork;1265 // Measure these anyway so the flamegraph explicitly shows that there were1266 // no effects.1267 // TODO: Maybe there's a better way to report this.1268 startCommitSnapshotEffectsTimer();1269 stopCommitSnapshotEffectsTimer();1270 if (enableProfilerTimer) {1271 recordCommitTime();1272 }1273 startCommitHostEffectsTimer();1274 stopCommitHostEffectsTimer();1275 startCommitLifeCyclesTimer();1276 stopCommitLifeCyclesTimer();1277 }1278 stopCommitTimer();1279 if (rootDoesHavePassiveEffects) {1280 // This commit has passive effects. Stash a reference to them. But don't1281 // schedule a callback until after flushing layout work.1282 rootDoesHavePassiveEffects = false;1283 rootWithPendingPassiveEffects = root;1284 pendingPassiveEffectsExpirationTime = expirationTime;1285 } else {1286 if (enableSchedulerTracing) {1287 // If there are no passive effects, then we can complete the pending1288 // interactions. Otherwise, we'll wait until after the passive effects1289 // are flushed.1290 finishPendingInteractions(root, expirationTime);1291 }1292 }1293 // Check if there's remaining work on this root1294 const remainingExpirationTime = root.firstPendingTime;1295 if (remainingExpirationTime !== NoWork) {1296 const currentTime = requestCurrentTime();1297 const priorityLevel = inferPriorityFromExpirationTime(1298 currentTime,1299 remainingExpirationTime,1300 );1301 scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);1302 } else {1303 // If there's no remaining work, we can clear the set of already failed1304 // error boundaries.1305 legacyErrorBoundariesThatAlreadyFailed = null;1306 }1307 onCommitRoot(finishedWork.stateNode);1308 if (remainingExpirationTime === Sync) {1309 // Count the number of times the root synchronously re-renders without1310 // finishing. If there are too many, it indicates an infinite update loop.1311 if (root === rootWithNestedUpdates) {1312 nestedUpdateCount++;1313 } else {1314 nestedUpdateCount = 0;1315 rootWithNestedUpdates = root;1316 }1317 } else {1318 nestedUpdateCount = 0;1319 }1320 if (hasUncaughtError) {1321 hasUncaughtError = false;1322 const error = firstUncaughtError;1323 firstUncaughtError = null;1324 throw error;1325 }1326 if (workPhase === LegacyUnbatchedPhase) {1327 // This is a legacy edge case. We just committed the initial mount of1328 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired1329 // synchronously, but layout updates should be deferred until the end1330 // of the batch.1331 return null;1332 }1333 // If layout work was scheduled, flush it now.1334 flushImmediateQueue();1335 return null;1336}1337function commitBeforeMutationEffects() {1338 while (nextEffect !== null) {1339 if ((nextEffect.effectTag & Snapshot) !== NoEffect) {1340 setCurrentDebugFiberInDEV(nextEffect);1341 recordEffect();1342 const current = nextEffect.alternate;1343 commitBeforeMutationEffectOnFiber(current, nextEffect);1344 resetCurrentDebugFiberInDEV();1345 }1346 nextEffect = nextEffect.nextEffect;1347 }1348}1349function commitMutationEffects() {1350 // TODO: Should probably move the bulk of this function to commitWork.1351 while (nextEffect !== null) {1352 setCurrentDebugFiberInDEV(nextEffect);1353 const effectTag = nextEffect.effectTag;1354 if (effectTag & ContentReset) {1355 commitResetTextContent(nextEffect);1356 }1357 if (effectTag & Ref) {1358 const current = nextEffect.alternate;1359 if (current !== null) {1360 commitDetachRef(current);1361 }1362 }1363 // The following switch statement is only concerned about placement,1364 // updates, and deletions. To avoid needing to add a case for every possible1365 // bitmap value, we remove the secondary effects from the effect tag and1366 // switch on that value.1367 let primaryEffectTag = effectTag & (Placement | Update | Deletion);1368 switch (primaryEffectTag) {1369 case Placement: {1370 commitPlacement(nextEffect);1371 // Clear the "placement" from effect tag so that we know that this is1372 // inserted, before any life-cycles like componentDidMount gets called.1373 // TODO: findDOMNode doesn't rely on this any more but isMounted does1374 // and isMounted is deprecated anyway so we should be able to kill this.1375 nextEffect.effectTag &= ~Placement;1376 break;1377 }1378 case PlacementAndUpdate: {1379 // Placement1380 commitPlacement(nextEffect);1381 // Clear the "placement" from effect tag so that we know that this is1382 // inserted, before any life-cycles like componentDidMount gets called.1383 nextEffect.effectTag &= ~Placement;1384 // Update1385 const current = nextEffect.alternate;1386 commitWork(current, nextEffect);1387 break;1388 }1389 case Update: {1390 const current = nextEffect.alternate;1391 commitWork(current, nextEffect);1392 break;1393 }1394 case Deletion: {1395 commitDeletion(nextEffect);1396 break;1397 }1398 }1399 // TODO: Only record a mutation effect if primaryEffectTag is non-zero.1400 recordEffect();1401 resetCurrentDebugFiberInDEV();1402 nextEffect = nextEffect.nextEffect;1403 }1404}1405function commitLayoutEffects(1406 root: FiberRoot,1407 committedExpirationTime: ExpirationTime,1408) {1409 // TODO: Should probably move the bulk of this function to commitWork.1410 while (nextEffect !== null) {1411 setCurrentDebugFiberInDEV(nextEffect);1412 const effectTag = nextEffect.effectTag;1413 if (effectTag & (Update | Callback)) {1414 recordEffect();1415 const current = nextEffect.alternate;1416 commitLayoutEffectOnFiber(1417 root,1418 current,1419 nextEffect,1420 committedExpirationTime,1421 );1422 }1423 if (effectTag & Ref) {1424 recordEffect();1425 commitAttachRef(nextEffect);1426 }1427 if (effectTag & Passive) {1428 rootDoesHavePassiveEffects = true;1429 }1430 resetCurrentDebugFiberInDEV();1431 nextEffect = nextEffect.nextEffect;1432 }1433}1434export function flushPassiveEffects() {1435 if (rootWithPendingPassiveEffects === null) {1436 return false;1437 }1438 const root = rootWithPendingPassiveEffects;1439 const expirationTime = pendingPassiveEffectsExpirationTime;1440 rootWithPendingPassiveEffects = null;1441 pendingPassiveEffectsExpirationTime = NoWork;1442 let prevInteractions: Set<Interaction> | null = null;1443 if (enableSchedulerTracing) {1444 prevInteractions = __interactionsRef.current;1445 __interactionsRef.current = root.memoizedInteractions;1446 }1447 invariant(1448 workPhase !== RenderPhase && workPhase !== CommitPhase,1449 'Cannot flush passive effects while already rendering.',1450 );1451 const prevWorkPhase = workPhase;1452 workPhase = CommitPhase;1453 // Note: This currently assumes there are no passive effects on the root1454 // fiber, because the root is not part of its own effect list. This could1455 // change in the future.1456 let effect = root.current.firstEffect;1457 while (effect !== null) {1458 if (__DEV__) {1459 setCurrentDebugFiberInDEV(effect);1460 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);1461 if (hasCaughtError()) {1462 invariant(effect !== null, 'Should be working on an effect.');1463 const error = clearCaughtError();1464 captureCommitPhaseError(effect, error);1465 }1466 resetCurrentDebugFiberInDEV();1467 } else {1468 try {1469 commitPassiveHookEffects(effect);1470 } catch (error) {1471 invariant(effect !== null, 'Should be working on an effect.');1472 captureCommitPhaseError(effect, error);1473 }1474 }1475 effect = effect.nextEffect;1476 }1477 if (enableSchedulerTracing) {1478 __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);1479 finishPendingInteractions(root, expirationTime);1480 }1481 workPhase = prevWorkPhase;1482 flushImmediateQueue();1483 // If additional passive effects were scheduled, increment a counter. If this1484 // exceeds the limit, we'll fire a warning.1485 nestedPassiveUpdateCount =1486 rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;1487 return true;1488}1489export function isAlreadyFailedLegacyErrorBoundary(instance: mixed): boolean {1490 return (1491 legacyErrorBoundariesThatAlreadyFailed !== null &&1492 legacyErrorBoundariesThatAlreadyFailed.has(instance)1493 );1494}1495export function markLegacyErrorBoundaryAsFailed(instance: mixed) {1496 if (legacyErrorBoundariesThatAlreadyFailed === null) {1497 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);1498 } else {1499 legacyErrorBoundariesThatAlreadyFailed.add(instance);1500 }1501}1502function prepareToThrowUncaughtError(error: mixed) {1503 if (!hasUncaughtError) {1504 hasUncaughtError = true;1505 firstUncaughtError = error;1506 }1507}1508export const onUncaughtError = prepareToThrowUncaughtError;1509function captureCommitPhaseErrorOnRoot(1510 rootFiber: Fiber,1511 sourceFiber: Fiber,1512 error: mixed,1513) {1514 const errorInfo = createCapturedValue(error, sourceFiber);1515 const update = createRootErrorUpdate(rootFiber, errorInfo, Sync);1516 enqueueUpdate(rootFiber, update);1517 const root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);1518 if (root !== null) {1519 scheduleCallbackForRoot(root, ImmediatePriority, Sync);1520 }1521}1522export function captureCommitPhaseError(sourceFiber: Fiber, error: mixed) {1523 if (sourceFiber.tag === HostRoot) {1524 // Error was thrown at the root. There is no parent, so the root1525 // itself should capture it.1526 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);1527 return;1528 }1529 let fiber = sourceFiber.return;1530 while (fiber !== null) {1531 if (fiber.tag === HostRoot) {1532 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);1533 return;1534 } else if (fiber.tag === ClassComponent) {1535 const ctor = fiber.type;1536 const instance = fiber.stateNode;1537 if (1538 typeof ctor.getDerivedStateFromError === 'function' ||1539 (typeof instance.componentDidCatch === 'function' &&1540 !isAlreadyFailedLegacyErrorBoundary(instance))1541 ) {1542 const errorInfo = createCapturedValue(error, sourceFiber);1543 const update = createClassErrorUpdate(1544 fiber,1545 errorInfo,1546 // TODO: This is always sync1547 Sync,1548 );1549 enqueueUpdate(fiber, update);1550 const root = markUpdateTimeFromFiberToRoot(fiber, Sync);1551 if (root !== null) {1552 scheduleCallbackForRoot(root, ImmediatePriority, Sync);1553 }1554 return;1555 }1556 }1557 fiber = fiber.return;1558 }1559}1560export function pingSuspendedRoot(1561 root: FiberRoot,1562 thenable: Thenable,1563 suspendedTime: ExpirationTime,1564) {1565 const pingCache = root.pingCache;1566 if (pingCache !== null) {1567 // The thenable resolved, so we no longer need to memoize, because it will1568 // never be thrown again.1569 pingCache.delete(thenable);1570 }1571 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {1572 // Received a ping at the same priority level at which we're currently1573 // rendering. Restart from the root. Don't need to schedule a ping because1574 // we're already working on this tree.1575 prepareFreshStack(root, renderExpirationTime);1576 return;1577 }1578 const lastPendingTime = root.lastPendingTime;1579 if (lastPendingTime < suspendedTime) {1580 // The root is no longer suspended at this time.1581 return;1582 }1583 const pingTime = root.pingTime;1584 if (pingTime !== NoWork && pingTime < suspendedTime) {1585 // There's already a lower priority ping scheduled.1586 return;1587 }1588 // Mark the time at which this ping was scheduled.1589 root.pingTime = suspendedTime;1590 const currentTime = requestCurrentTime();1591 const priorityLevel = inferPriorityFromExpirationTime(1592 currentTime,1593 suspendedTime,1594 );1595 scheduleCallbackForRoot(root, priorityLevel, suspendedTime);1596}1597export function retryTimedOutBoundary(boundaryFiber: Fiber) {1598 // The boundary fiber (a Suspense component) previously timed out and was1599 // rendered in its fallback state. One of the promises that suspended it has1600 // resolved, which means at least part of the tree was likely unblocked. Try1601 // rendering again, at a new expiration time.1602 const currentTime = requestCurrentTime();1603 const retryTime = computeExpirationForFiber(currentTime, boundaryFiber);1604 // TODO: Special case idle priority?1605 const priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);1606 const root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);1607 if (root !== null) {1608 scheduleCallbackForRoot(root, priorityLevel, retryTime);1609 }1610}1611export function resolveRetryThenable(boundaryFiber: Fiber, thenable: Thenable) {1612 let retryCache: WeakSet<Thenable> | Set<Thenable> | null;1613 if (enableSuspenseServerRenderer) {1614 switch (boundaryFiber.tag) {1615 case SuspenseComponent:1616 retryCache = boundaryFiber.stateNode;1617 break;1618 case DehydratedSuspenseComponent:1619 retryCache = boundaryFiber.memoizedState;1620 break;1621 default:1622 invariant(1623 false,1624 'Pinged unknown suspense boundary type. ' +1625 'This is probably a bug in React.',1626 );1627 }1628 } else {1629 retryCache = boundaryFiber.stateNode;1630 }1631 if (retryCache !== null) {1632 // The thenable resolved, so we no longer need to memoize, because it will1633 // never be thrown again.1634 retryCache.delete(thenable);1635 }1636 retryTimedOutBoundary(boundaryFiber);1637}1638export function inferStartTimeFromExpirationTime(1639 root: FiberRoot,1640 expirationTime: ExpirationTime,1641) {1642 // We don't know exactly when the update was scheduled, but we can infer an1643 // approximate start time from the expiration time.1644 const earliestExpirationTimeMs = expirationTimeToMs(root.firstPendingTime);1645 // TODO: Track this on the root instead. It's more accurate, doesn't rely on1646 // assumptions about priority, and isn't coupled to Scheduler details.1647 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;1648}1649function computeMsUntilTimeout(root, absoluteTimeoutMs) {1650 if (disableYielding) {1651 // Timeout immediately when yielding is disabled.1652 return 0;1653 }1654 // Find the earliest uncommitted expiration time in the tree, including1655 // work that is suspended. The timeout threshold cannot be longer than1656 // the overall expiration.1657 const earliestExpirationTimeMs = expirationTimeToMs(root.firstPendingTime);1658 if (earliestExpirationTimeMs < absoluteTimeoutMs) {1659 absoluteTimeoutMs = earliestExpirationTimeMs;1660 }1661 // Subtract the current time from the absolute timeout to get the number1662 // of milliseconds until the timeout. In other words, convert an absolute1663 // timestamp to a relative time. This is the value that is passed1664 // to `setTimeout`.1665 let msUntilTimeout = absoluteTimeoutMs - now();1666 return msUntilTimeout < 0 ? 0 : msUntilTimeout;1667}1668function checkForNestedUpdates() {1669 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {1670 nestedUpdateCount = 0;1671 rootWithNestedUpdates = null;1672 invariant(1673 false,1674 'Maximum update depth exceeded. This can happen when a component ' +1675 'repeatedly calls setState inside componentWillUpdate or ' +1676 'componentDidUpdate. React limits the number of nested updates to ' +1677 'prevent infinite loops.',1678 );1679 }1680 if (__DEV__) {1681 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {1682 nestedPassiveUpdateCount = 0;1683 warning(1684 false,1685 'Maximum update depth exceeded. This can happen when a component ' +1686 "calls setState inside useEffect, but useEffect either doesn't " +1687 'have a dependency array, or one of the dependencies changes on ' +1688 'every render.',1689 );1690 }1691 }1692}1693function flushRenderPhaseStrictModeWarningsInDEV() {1694 if (__DEV__) {1695 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();1696 ReactStrictModeWarnings.flushLegacyContextWarning();1697 if (warnAboutDeprecatedLifecycles) {1698 ReactStrictModeWarnings.flushPendingDeprecationWarnings();1699 }1700 }1701}1702function stopFinishedWorkLoopTimer() {1703 const didCompleteRoot = true;1704 stopWorkLoopTimer(interruptedBy, didCompleteRoot);1705 interruptedBy = null;1706}1707function stopInterruptedWorkLoopTimer() {1708 // TODO: Track which fiber caused the interruption.1709 const didCompleteRoot = false;1710 stopWorkLoopTimer(interruptedBy, didCompleteRoot);1711 interruptedBy = null;1712}1713function checkForInterruption(1714 fiberThatReceivedUpdate: Fiber,1715 updateExpirationTime: ExpirationTime,1716) {1717 if (1718 enableUserTimingAPI &&1719 workInProgressRoot !== null &&1720 updateExpirationTime > renderExpirationTime1721 ) {1722 interruptedBy = fiberThatReceivedUpdate;1723 }1724}1725let didWarnStateUpdateForUnmountedComponent: Set<string> | null = null;1726function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {1727 if (__DEV__) {1728 const tag = fiber.tag;1729 if (1730 tag !== HostRoot &&1731 tag !== ClassComponent &&1732 tag !== FunctionComponent &&1733 tag !== ForwardRef &&1734 tag !== MemoComponent &&1735 tag !== SimpleMemoComponent1736 ) {1737 // Only warn for user-defined components, not internal ones like Suspense.1738 return;1739 }1740 // We show the whole stack but dedupe on the top component's name because1741 // the problematic code almost always lies inside that component.1742 const componentName = getComponentName(fiber.type) || 'ReactComponent';1743 if (didWarnStateUpdateForUnmountedComponent !== null) {1744 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {1745 return;1746 }1747 didWarnStateUpdateForUnmountedComponent.add(componentName);1748 } else {1749 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);1750 }1751 warningWithoutStack(1752 false,1753 "Can't perform a React state update on an unmounted component. This " +1754 'is a no-op, but it indicates a memory leak in your application. To ' +1755 'fix, cancel all subscriptions and asynchronous tasks in %s.%s',1756 tag === ClassComponent1757 ? 'the componentWillUnmount method'1758 : 'a useEffect cleanup function',1759 getStackByFiberInDevAndProd(fiber),1760 );1761 }1762}1763let beginWork;1764if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) {1765 let dummyFiber = null;1766 beginWork = (current, unitOfWork, expirationTime) => {1767 // If a component throws an error, we replay it again in a synchronously1768 // dispatched event, so that the debugger will treat it as an uncaught1769 // error See ReactErrorUtils for more information.1770 // Before entering the begin phase, copy the work-in-progress onto a dummy1771 // fiber. If beginWork throws, we'll use this to reset the state.1772 const originalWorkInProgressCopy = assignFiberPropertiesInDEV(1773 dummyFiber,1774 unitOfWork,1775 );1776 try {1777 return originalBeginWork(current, unitOfWork, expirationTime);1778 } catch (originalError) {1779 if (1780 originalError !== null &&1781 typeof originalError === 'object' &&1782 typeof originalError.then === 'function'1783 ) {1784 // Don't replay promises. Treat everything else like an error.1785 throw originalError;1786 }1787 // Keep this code in sync with renderRoot; any changes here must have1788 // corresponding changes there.1789 resetContextDependencies();1790 resetHooks();1791 // Unwind the failed stack frame1792 unwindInterruptedWork(unitOfWork);1793 // Restore the original properties of the fiber.1794 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);1795 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {1796 // Reset the profiler timer.1797 startProfilerTimer(unitOfWork);1798 }1799 // Run beginWork again.1800 invokeGuardedCallback(1801 null,1802 originalBeginWork,1803 null,...

Full Screen

Full Screen

ReactFiberWorkLoop.js

Source:ReactFiberWorkLoop.js Github

copy

Full Screen

...619 } catch (thrownValue) {620 // handleError(root, thrownValue);621 }622 } while (true);623 resetContextDependencies();624 executionContext = prevExecutionContext;625 popDispatcher(prevDispatcher);626 if (workInProgress !== null) {627 invariant(628 false,629 'Cannot commit an incomplete root. This error is likely caused by a ' +630 'bug in React. Please file an issue.'631 );632 }633 workInProgressRoot = null;634 workInProgressRootRenderLanes = NoLanes;635 return workInProgressRootExitStatus;636};637const ensureRootIsScheduled = (root, currentTime) => {...

Full Screen

Full Screen

ReactFiberNewContext.new.js

Source:ReactFiberNewContext.new.js Github

copy

Full Screen

...40let currentlyRenderingFiber: Fiber | null = null;41let lastContextDependency: ContextDependency<mixed> | null = null;42let lastContextWithAllBitsObserved: ReactContext<any> | null = null;43let isDisallowedContextReadInDEV: boolean = false;44export function resetContextDependencies(): void {45 // This is called right before React yields execution, to ensure `readContext`46 // cannot be called outside the render phase.47 currentlyRenderingFiber = null;48 lastContextDependency = null;49 lastContextWithAllBitsObserved = null;50 if (__DEV__) {51 isDisallowedContextReadInDEV = false;52 }53}54export function enterDisallowedContextReadInDEV(): void {55 if (__DEV__) {56 isDisallowedContextReadInDEV = true;57 }58}...

Full Screen

Full Screen

ReactFiberNewContext.old.js

Source:ReactFiberNewContext.old.js Github

copy

Full Screen

...7 var currentlyRenderingFiber = null;8 var lastContextDependency = null;9 var lastContextWithAllBitsObserved = null;10 var isDisallowedContextReadInDEV = false;11 function resetContextDependencies() {12 // This is called right before React yields execution, to ensure `readContext`13 // cannot be called outside the render phase.14 currentlyRenderingFiber = null;15 lastContextDependency = null;16 lastContextWithAllBitsObserved = null;17 {18 isDisallowedContextReadInDEV = false;19 }20 }21 function enterDisallowedContextReadInDEV() {22 {23 isDisallowedContextReadInDEV = true;24 }25 }...

Full Screen

Full Screen

ReactFiberNewContext.js

Source:ReactFiberNewContext.js Github

copy

Full Screen

1import { includesSomeLane, NoLanes } from './ReactFiberLane';2import { markWorkInProgressReceivedUpdate } from './ReactFiberBeginWork';3const invariant = require('invariant');4const MAX_SIGNED_31_BIT_INT = 1073741823;5let currentlyRenderingFiber = null;6let lastContextDependency = null;7let lastContextWithAllBitsObserved = null;8const resetContextDependencies = () => {9 currentlyRenderingFiber = null;10 lastContextDependency = null;11 lastContextWithAllBitsObserved = null;12};13const prepareToReadContext = (workInProgress, renderLanes) => {14 currentlyRenderingFiber = workInProgress;15 lastContextDependency = null;16 lastContextWithAllBitsObserved = null;17 const dependencies = workInProgress.dependencies;18 if (dependencies !== null) {19 const firstContext = dependencies.firstContext;20 if (firstContext !== null) {21 if (includesSomeLane(dependencies.lanes, renderLanes)) {22 markWorkInProgressReceivedUpdate();23 }24 dependencies.firstContext = null;25 }26 }27};28const readContext = (context, observedBits) => {29 if (lastContextWithAllBitsObserved === context) {30 // Nothing to do. We already observe everything in this context.31 } else if (observedBits === false || observedBits === 0) {32 // Do not observe any updates.33 } else {34 let resolvedObservedBits;35 if (36 typeof observedBits !== 'number' ||37 observedBits === MAX_SIGNED_31_BIT_INT38 ) {39 lastContextWithAllBitsObserved = context;40 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;41 } else {42 resolvedObservedBits = observedBits;43 }44 const contextItem = {45 context: context,46 observedBits: resolvedObservedBits,47 next: null,48 };49 if (lastContextDependency === null) {50 invariant(51 currentlyRenderingFiber !== null,52 'Context can only be read while React is rendering. ' +53 'In classes, you can read it in the render method or getDerivedStateFromProps. ' +54 'In function components, you can read it directly in the function body, but not ' +55 'inside Hooks like useReducer() or useMemo().'56 );57 lastContextDependency = contextItem;58 currentlyRenderingFiber.dependencies = {59 lanes: NoLanes,60 firstContext: contextItem,61 responders: null,62 };63 } else {64 lastContextDependency = lastContextDependency.next = contextItem;65 }66 }67 return context._currentValue;68};...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { resetContextDependencies } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 await resetContextDependencies(context);7 await context.close();8 await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext();14 await context.close();15 await browser.close();16})();17 at Object.throwProtocolError (/Users/kritikaparmar/Desktop/playwright-test/node_modules/playwright/lib/server/cjs/transport.js:285:15)18 at CDPSession.dispatch (/Users/kritikaparmar/Desktop/playwright-test/node_modules/playwright/lib/server/cjs/transport.js:181:23)19 at CDPSession._onMessage (/Users/kritikaparmar/Desktop/playwright-test/node_modules/playwright/lib/server/cjs/transport.js:132:16)20 at WebSocketTransport._ws.addEventListener (/Users/kritikaparmar/Desktop/playwright-test/node_modules/playwright/lib/server/cjs/transport.js:42:24)21 at WebSocket.onMessage (/Users/kritikaparmar/Desktop/playwright-test/node_modules/ws/lib/event-target.js:132:16)22 at WebSocket.emit (events.js:315:20)23 at Receiver.receiverOnMessage (/Users/kritikaparmar/Desktop/playwright-test/node_modules/ws/lib/websocket.js:800:20)24 at Receiver.emit (events.js:315:20)25 at Receiver.dataMessage (/Users/kritikaparmar/Desktop/playwright-test/node_modules/ws/lib/receiver.js:437:14)26 at Receiver.getData (/Users/kritikaparmar/Desktop/playwright-test/node_modules/ws/lib/receiver.js:367:17)

Full Screen

Using AI Code Generation

copy

Full Screen

1const { resetContextDependencies } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 await resetContextDependencies(context);7 await context.close();8 await browser.close();9})();10const { chromium } = require('playwright');11const { resetContextDependencies } = require('playwright/lib/server/browserContext');12describe('My test', () => {13 let browser;14 let context;15 beforeEach(async () => {16 browser = await chromium.launch();17 context = await browser.newContext();18 });19 afterEach(async () => {20 await resetContextDependencies(context);21 await context.close();22 await browser.close();23 });24 it('should work', async () => {25 const page = await context.newPage();26 await page.screenshot({ path: 'playwright.png' });27 });28});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { resetContextDependencies } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const context = await browser.newContext();6 await resetContextDependencies(context);7 await browser.close();8})();9const { resetContextDependencies } = require('playwright/lib/server/browserContext');10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch({ headless: false });13 const context = await browser.newContext();14 await resetContextDependencies(context);15 await browser.close();16})();17const { resetContextDependencies } = require('playwright/lib/server/browserContext');18const { chromium } = require('playwright');19(async () => {20 const browser = await chromium.launch({ headless: false });21 const context = await browser.newContext();22 await resetContextDependencies(context);23 await browser.close();24})();25const { resetContextDependencies } = require('playwright/lib/server/browserContext');26const { chromium } = require('playwright');27(async () => {28 const browser = await chromium.launch({ headless: false });29 const context = await browser.newContext();30 await resetContextDependencies(context);31 await browser.close();32})();33const { resetContextDependencies } = require('playwright/lib/server/browserContext');34const { chromium } = require('playwright');35(async () => {36 const browser = await chromium.launch({ headless: false });37 const context = await browser.newContext();38 await resetContextDependencies(context);39 await browser.close();40})();41const { resetContextDependencies } = require('playwright/lib/server/browserContext');42const { chromium } = require('playwright');43(async () => {44 const browser = await chromium.launch({ headless: false });45 const context = await browser.newContext();46 await resetContextDependencies(context);47 await browser.close();48})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { resetContextDependencies } = require('playwright-core/lib/server/browserContext');2resetContextDependencies();3const { resetBrowserDependencies } = require('playwright-core/lib/server/browser');4resetBrowserDependencies();5const { resetBrowserTypeDependencies } = require('playwright-core/lib/server/browserType');6resetBrowserTypeDependencies();7const { resetServerDependencies } = require('playwright-core/lib/server/server');8resetServerDependencies();9const { resetTestState } = require('playwright-core/lib/test/test');10resetTestState();11const { resetTestTypeDependencies } = require('playwright-core/lib/test/testType');12resetTestTypeDependencies();13const { resetTraceModel } = require('playwright-core/lib/trace/traceModel');14resetTraceModel();15const { resetTracePlayer } = require('playwright-core/lib/trace/tracePlayer');16resetTracePlayer();17const { resetTraceRecorder } = require('playwright-core/lib/trace/traceRecorder');18resetTraceRecorder();19const { resetTransport } = require('playwright-core/lib/transport/transport');20resetTransport();21const { resetWebSocketTransport } = require('playwright-core/lib/transport/webSocketTransport');22resetWebSocketTransport();23const { resetBrowserServer } = require('playwright-core/lib/server/browserServer');24resetBrowserServer();25const { resetBrowserContext } = require('playwright-core/lib/server/browserContext');26resetBrowserContext();27const { resetBrowserType } = require('playwright-core/lib/server/browserType');28resetBrowserType();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");2resetContextDependencies();3const { resetContextDependencies } = require("playwright/lib/server/firefox/ffBrowser");4resetContextDependencies();5const { resetContextDependencies } = require("playwright/lib/server/webkit/wkBrowser");6resetContextDependencies();7const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");8resetContextDependencies();9const { resetContextDependencies } = require("playwright/lib/server/firefox/ffBrowser");10resetContextDependencies();11const { resetContextDependencies } = require("playwright/lib/server/webkit/wkBrowser");12resetContextDependencies();13const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");14resetContextDependencies();15const { resetContextDependencies } = require("playwright/lib/server/firefox/ffBrowser");16resetContextDependencies();17const { resetContextDependencies } = require("playwright/lib/server/webkit/wkBrowser");18resetContextDependencies();19const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");20resetContextDependencies();21const { resetContextDependencies } = require("playwright/lib/server/firefox/ffBrowser");22resetContextDependencies();23const { resetContextDependencies } = require("playwright/lib/server/webkit/wkBrowser");24resetContextDependencies();25const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");26resetContextDependencies();27const { resetContextDependencies } = require("playwright/lib/server/firefox/

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2(async () => {3 const browser = await playwright.chromium.launch();4 await browser._defaultContext.resetContextDependencies();5 await browser.close();6})();7const playwright = require('playwright');8(async () => {9 const browser = await playwright.chromium.launch();10 await browser._defaultContext.resetContextDependencies();11 await browser.close();12})();13const playwright = require('playwright');14(async () => {15 const browser = await playwright.chromium.launch();16 await browser._defaultContext.resetContextDependencies();17 await browser.close();18})();19const playwright = require('playwright');20(async () => {21 const browser = await playwright.chromium.launch();22 await browser._defaultContext.resetContextDependencies();23 await browser.close();24})();25const playwright = require('playwright');26(async () => {27 const browser = await playwright.chromium.launch();28 await browser._defaultContext.resetContextDependencies();29 await browser.close();30})();31const playwright = require('playwright');32(async () => {33 const browser = await playwright.chromium.launch();34 await browser._defaultContext.resetContextDependencies();35 await browser.close();36})();37const playwright = require('playwright');38(async () => {39 const browser = await playwright.chromium.launch();40 await browser._defaultContext.resetContextDependencies();41 await browser.close();42})();43const playwright = require('playwright');44(async () => {45 const browser = await playwright.chromium.launch();46 await browser._defaultContext.resetContextDependencies();47 await browser.close();48})();49const playwright = require('playwright');50(async () => {51 const browser = await playwright.chromium.launch();52 await browser._defaultContext.resetContextDependencies();53 await browser.close();54})();55const playwright = require('

Full Screen

Using AI Code Generation

copy

Full Screen

1const { resetContextDependencies } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3const context = await chromium.launchPersistentContext('./data');4await resetContextDependencies(context);5await context.close();6await context.clearCookies();7await context.clearPermissions();8await context.clearStorageData();9await context.tracing.start({ screenshots: true, snapshots: true });10await context.tracing.stop({ path: 'trace.zip' });11await context.tracing.startChunk();12await context.tracing.stopChunk({ path: 'trace.zip' });13await context.addCookies([{14}]);15const cookies = await context.cookies();16console.log(cookies);17await context.grantPermissions(['geolocation']);18const permissions = await context.permissions();19console.log(permissions);20await context.setGeolocation({ latitude: 59.95, longitude: 30.31667 });21await context.setExtraHTTPHeaders({ foo: 'bar' });22await context.setOffline(true);23await context.setHTTPCredentials({ username: 'user', password: 'pass' });24await context.addInitScript({ path: 'inject.js' });25await context.addInitScript({ content: 'window.injected = 123;' });26await context.exposeBinding('compute', (source, ...args) => {27 return args.reduce((a, b) => a * b, 1);28});29await context.exposeFunction('compute', (...args) => {30 return args.reduce((a, b) => a * b, 1);31});32await context.route('**/*', route => route.continue());33await context.unroute('**/*');34await context.waitForEvent('page');35const page = await context.newPage();36await context.close();37await context.clearCookies();38await context.clearPermissions();39await context.clearStorageData();40await context.tracing.start({ screenshots: true, snapshots: true });41await context.tracing.stop({ path: 'trace.zip' });42await context.tracing.startChunk();43await context.tracing.stopChunk({ path: 'trace.zip' });44await context.addCookies([{

Full Screen

Using AI Code Generation

copy

Full Screen

1const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");2resetContextDependencies();3const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");4resetContextDependencies();5const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");6resetContextDependencies();7const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");8resetContextDependencies();9const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");10resetContextDependencies();11const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");12resetContextDependencies();13const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");14resetContextDependencies();15const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");16resetContextDependencies();17const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");18resetContextDependencies();19const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");20resetContextDependencies();21const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");22resetContextDependencies();23const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");24resetContextDependencies();

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