UNPKG

756 kBJavaScriptView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @noflow
8 * @providesModule ReactFabric-dev
9 * @preventMunge
10 * @generated
11 */
12
13'use strict';
14
15if (__DEV__) {
16 (function() {
17"use strict";
18
19require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore");
20var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface");
21var React = require("react");
22var Scheduler = require("scheduler");
23var checkPropTypes = require("prop-types/checkPropTypes");
24var tracing = require("scheduler/tracing");
25
26// Do not require this module directly! Use normal `invariant` calls with
27// template literal strings. The messages will be converted to ReactError during
28// build, and in production they will be minified.
29
30function ReactError(error) {
31 error.name = "Invariant Violation";
32 return error;
33}
34
35/**
36 * Use invariant() to assert state which your program assumes to be true.
37 *
38 * Provide sprintf-style format (only %s is supported) and arguments
39 * to provide information about what broke and what you were
40 * expecting.
41 *
42 * The invariant message will be stripped in production, but the invariant
43 * will remain to ensure logic does not differ in production.
44 */
45
46/**
47 * Injectable ordering of event plugins.
48 */
49var eventPluginOrder = null;
50
51/**
52 * Injectable mapping from names to event plugin modules.
53 */
54var namesToPlugins = {};
55
56/**
57 * Recomputes the plugin list using the injected plugins and plugin ordering.
58 *
59 * @private
60 */
61function recomputePluginOrdering() {
62 if (!eventPluginOrder) {
63 // Wait until an `eventPluginOrder` is injected.
64 return;
65 }
66 for (var pluginName in namesToPlugins) {
67 var pluginModule = namesToPlugins[pluginName];
68 var pluginIndex = eventPluginOrder.indexOf(pluginName);
69 (function() {
70 if (!(pluginIndex > -1)) {
71 throw ReactError(
72 Error(
73 "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" +
74 pluginName +
75 "`."
76 )
77 );
78 }
79 })();
80 if (plugins[pluginIndex]) {
81 continue;
82 }
83 (function() {
84 if (!pluginModule.extractEvents) {
85 throw ReactError(
86 Error(
87 "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" +
88 pluginName +
89 "` does not."
90 )
91 );
92 }
93 })();
94 plugins[pluginIndex] = pluginModule;
95 var publishedEvents = pluginModule.eventTypes;
96 for (var eventName in publishedEvents) {
97 (function() {
98 if (
99 !publishEventForPlugin(
100 publishedEvents[eventName],
101 pluginModule,
102 eventName
103 )
104 ) {
105 throw ReactError(
106 Error(
107 "EventPluginRegistry: Failed to publish event `" +
108 eventName +
109 "` for plugin `" +
110 pluginName +
111 "`."
112 )
113 );
114 }
115 })();
116 }
117 }
118}
119
120/**
121 * Publishes an event so that it can be dispatched by the supplied plugin.
122 *
123 * @param {object} dispatchConfig Dispatch configuration for the event.
124 * @param {object} PluginModule Plugin publishing the event.
125 * @return {boolean} True if the event was successfully published.
126 * @private
127 */
128function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
129 (function() {
130 if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) {
131 throw ReactError(
132 Error(
133 "EventPluginHub: More than one plugin attempted to publish the same event name, `" +
134 eventName +
135 "`."
136 )
137 );
138 }
139 })();
140 eventNameDispatchConfigs[eventName] = dispatchConfig;
141
142 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
143 if (phasedRegistrationNames) {
144 for (var phaseName in phasedRegistrationNames) {
145 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
146 var phasedRegistrationName = phasedRegistrationNames[phaseName];
147 publishRegistrationName(
148 phasedRegistrationName,
149 pluginModule,
150 eventName
151 );
152 }
153 }
154 return true;
155 } else if (dispatchConfig.registrationName) {
156 publishRegistrationName(
157 dispatchConfig.registrationName,
158 pluginModule,
159 eventName
160 );
161 return true;
162 }
163 return false;
164}
165
166/**
167 * Publishes a registration name that is used to identify dispatched events.
168 *
169 * @param {string} registrationName Registration name to add.
170 * @param {object} PluginModule Plugin publishing the event.
171 * @private
172 */
173function publishRegistrationName(registrationName, pluginModule, eventName) {
174 (function() {
175 if (!!registrationNameModules[registrationName]) {
176 throw ReactError(
177 Error(
178 "EventPluginHub: More than one plugin attempted to publish the same registration name, `" +
179 registrationName +
180 "`."
181 )
182 );
183 }
184 })();
185 registrationNameModules[registrationName] = pluginModule;
186 registrationNameDependencies[registrationName] =
187 pluginModule.eventTypes[eventName].dependencies;
188
189 {
190 var lowerCasedName = registrationName.toLowerCase();
191 }
192}
193
194/**
195 * Registers plugins so that they can extract and dispatch events.
196 *
197 * @see {EventPluginHub}
198 */
199
200/**
201 * Ordered list of injected plugins.
202 */
203var plugins = [];
204
205/**
206 * Mapping from event name to dispatch config
207 */
208var eventNameDispatchConfigs = {};
209
210/**
211 * Mapping from registration name to plugin module
212 */
213var registrationNameModules = {};
214
215/**
216 * Mapping from registration name to event name
217 */
218var registrationNameDependencies = {};
219
220/**
221 * Mapping from lowercase registration names to the properly cased version,
222 * used to warn in the case of missing event handlers. Available
223 * only in true.
224 * @type {Object}
225 */
226
227// Trust the developer to only use possibleRegistrationNames in true
228
229/**
230 * Injects an ordering of plugins (by plugin name). This allows the ordering
231 * to be decoupled from injection of the actual plugins so that ordering is
232 * always deterministic regardless of packaging, on-the-fly injection, etc.
233 *
234 * @param {array} InjectedEventPluginOrder
235 * @internal
236 * @see {EventPluginHub.injection.injectEventPluginOrder}
237 */
238function injectEventPluginOrder(injectedEventPluginOrder) {
239 (function() {
240 if (!!eventPluginOrder) {
241 throw ReactError(
242 Error(
243 "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React."
244 )
245 );
246 }
247 })();
248 // Clone the ordering so it cannot be dynamically mutated.
249 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
250 recomputePluginOrdering();
251}
252
253/**
254 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
255 * in the ordering injected by `injectEventPluginOrder`.
256 *
257 * Plugins can be injected as part of page initialization or on-the-fly.
258 *
259 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
260 * @internal
261 * @see {EventPluginHub.injection.injectEventPluginsByName}
262 */
263function injectEventPluginsByName(injectedNamesToPlugins) {
264 var isOrderingDirty = false;
265 for (var pluginName in injectedNamesToPlugins) {
266 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
267 continue;
268 }
269 var pluginModule = injectedNamesToPlugins[pluginName];
270 if (
271 !namesToPlugins.hasOwnProperty(pluginName) ||
272 namesToPlugins[pluginName] !== pluginModule
273 ) {
274 (function() {
275 if (!!namesToPlugins[pluginName]) {
276 throw ReactError(
277 Error(
278 "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" +
279 pluginName +
280 "`."
281 )
282 );
283 }
284 })();
285 namesToPlugins[pluginName] = pluginModule;
286 isOrderingDirty = true;
287 }
288 }
289 if (isOrderingDirty) {
290 recomputePluginOrdering();
291 }
292}
293
294var invokeGuardedCallbackImpl = function(
295 name,
296 func,
297 context,
298 a,
299 b,
300 c,
301 d,
302 e,
303 f
304) {
305 var funcArgs = Array.prototype.slice.call(arguments, 3);
306 try {
307 func.apply(context, funcArgs);
308 } catch (error) {
309 this.onError(error);
310 }
311};
312
313{
314 // In DEV mode, we swap out invokeGuardedCallback for a special version
315 // that plays more nicely with the browser's DevTools. The idea is to preserve
316 // "Pause on exceptions" behavior. Because React wraps all user-provided
317 // functions in invokeGuardedCallback, and the production version of
318 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
319 // like caught exceptions, and the DevTools won't pause unless the developer
320 // takes the extra step of enabling pause on caught exceptions. This is
321 // unintuitive, though, because even though React has caught the error, from
322 // the developer's perspective, the error is uncaught.
323 //
324 // To preserve the expected "Pause on exceptions" behavior, we don't use a
325 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
326 // DOM node, and call the user-provided callback from inside an event handler
327 // for that fake event. If the callback throws, the error is "captured" using
328 // a global event handler. But because the error happens in a different
329 // event loop context, it does not interrupt the normal program flow.
330 // Effectively, this gives us try-catch behavior without actually using
331 // try-catch. Neat!
332
333 // Check that the browser supports the APIs we need to implement our special
334 // DEV version of invokeGuardedCallback
335 if (
336 typeof window !== "undefined" &&
337 typeof window.dispatchEvent === "function" &&
338 typeof document !== "undefined" &&
339 typeof document.createEvent === "function"
340 ) {
341 var fakeNode = document.createElement("react");
342
343 var invokeGuardedCallbackDev = function(
344 name,
345 func,
346 context,
347 a,
348 b,
349 c,
350 d,
351 e,
352 f
353 ) {
354 // If document doesn't exist we know for sure we will crash in this method
355 // when we call document.createEvent(). However this can cause confusing
356 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
357 // So we preemptively throw with a better message instead.
358 (function() {
359 if (!(typeof document !== "undefined")) {
360 throw ReactError(
361 Error(
362 "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous."
363 )
364 );
365 }
366 })();
367 var evt = document.createEvent("Event");
368
369 // Keeps track of whether the user-provided callback threw an error. We
370 // set this to true at the beginning, then set it to false right after
371 // calling the function. If the function errors, `didError` will never be
372 // set to false. This strategy works even if the browser is flaky and
373 // fails to call our global error handler, because it doesn't rely on
374 // the error event at all.
375 var didError = true;
376
377 // Keeps track of the value of window.event so that we can reset it
378 // during the callback to let user code access window.event in the
379 // browsers that support it.
380 var windowEvent = window.event;
381
382 // Keeps track of the descriptor of window.event to restore it after event
383 // dispatching: https://github.com/facebook/react/issues/13688
384 var windowEventDescriptor = Object.getOwnPropertyDescriptor(
385 window,
386 "event"
387 );
388
389 // Create an event handler for our fake event. We will synchronously
390 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
391 // call the user-provided callback.
392 var funcArgs = Array.prototype.slice.call(arguments, 3);
393 function callCallback() {
394 // We immediately remove the callback from event listeners so that
395 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
396 // nested call would trigger the fake event handlers of any call higher
397 // in the stack.
398 fakeNode.removeEventListener(evtType, callCallback, false);
399
400 // We check for window.hasOwnProperty('event') to prevent the
401 // window.event assignment in both IE <= 10 as they throw an error
402 // "Member not found" in strict mode, and in Firefox which does not
403 // support window.event.
404 if (
405 typeof window.event !== "undefined" &&
406 window.hasOwnProperty("event")
407 ) {
408 window.event = windowEvent;
409 }
410
411 func.apply(context, funcArgs);
412 didError = false;
413 }
414
415 // Create a global error event handler. We use this to capture the value
416 // that was thrown. It's possible that this error handler will fire more
417 // than once; for example, if non-React code also calls `dispatchEvent`
418 // and a handler for that event throws. We should be resilient to most of
419 // those cases. Even if our error event handler fires more than once, the
420 // last error event is always used. If the callback actually does error,
421 // we know that the last error event is the correct one, because it's not
422 // possible for anything else to have happened in between our callback
423 // erroring and the code that follows the `dispatchEvent` call below. If
424 // the callback doesn't error, but the error event was fired, we know to
425 // ignore it because `didError` will be false, as described above.
426 var error = void 0;
427 // Use this to track whether the error event is ever called.
428 var didSetError = false;
429 var isCrossOriginError = false;
430
431 function handleWindowError(event) {
432 error = event.error;
433 didSetError = true;
434 if (error === null && event.colno === 0 && event.lineno === 0) {
435 isCrossOriginError = true;
436 }
437 if (event.defaultPrevented) {
438 // Some other error handler has prevented default.
439 // Browsers silence the error report if this happens.
440 // We'll remember this to later decide whether to log it or not.
441 if (error != null && typeof error === "object") {
442 try {
443 error._suppressLogging = true;
444 } catch (inner) {
445 // Ignore.
446 }
447 }
448 }
449 }
450
451 // Create a fake event type.
452 var evtType = "react-" + (name ? name : "invokeguardedcallback");
453
454 // Attach our event handlers
455 window.addEventListener("error", handleWindowError);
456 fakeNode.addEventListener(evtType, callCallback, false);
457
458 // Synchronously dispatch our fake event. If the user-provided function
459 // errors, it will trigger our global error handler.
460 evt.initEvent(evtType, false, false);
461 fakeNode.dispatchEvent(evt);
462
463 if (windowEventDescriptor) {
464 Object.defineProperty(window, "event", windowEventDescriptor);
465 }
466
467 if (didError) {
468 if (!didSetError) {
469 // The callback errored, but the error event never fired.
470 error = new Error(
471 "An error was thrown inside one of your components, but React " +
472 "doesn't know what it was. This is likely due to browser " +
473 'flakiness. React does its best to preserve the "Pause on ' +
474 'exceptions" behavior of the DevTools, which requires some ' +
475 "DEV-mode only tricks. It's possible that these don't work in " +
476 "your browser. Try triggering the error in production mode, " +
477 "or switching to a modern browser. If you suspect that this is " +
478 "actually an issue with React, please file an issue."
479 );
480 } else if (isCrossOriginError) {
481 error = new Error(
482 "A cross-origin error was thrown. React doesn't have access to " +
483 "the actual error object in development. " +
484 "See https://fb.me/react-crossorigin-error for more information."
485 );
486 }
487 this.onError(error);
488 }
489
490 // Remove our event listeners
491 window.removeEventListener("error", handleWindowError);
492 };
493
494 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
495 }
496}
497
498var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
499
500// Used by Fiber to simulate a try-catch.
501var hasError = false;
502var caughtError = null;
503
504// Used by event system to capture/rethrow the first error.
505var hasRethrowError = false;
506var rethrowError = null;
507
508var reporter = {
509 onError: function(error) {
510 hasError = true;
511 caughtError = error;
512 }
513};
514
515/**
516 * Call a function while guarding against errors that happens within it.
517 * Returns an error if it throws, otherwise null.
518 *
519 * In production, this is implemented using a try-catch. The reason we don't
520 * use a try-catch directly is so that we can swap out a different
521 * implementation in DEV mode.
522 *
523 * @param {String} name of the guard to use for logging or debugging
524 * @param {Function} func The function to invoke
525 * @param {*} context The context to use when calling the function
526 * @param {...*} args Arguments for function
527 */
528function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
529 hasError = false;
530 caughtError = null;
531 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
532}
533
534/**
535 * Same as invokeGuardedCallback, but instead of returning an error, it stores
536 * it in a global so it can be rethrown by `rethrowCaughtError` later.
537 * TODO: See if caughtError and rethrowError can be unified.
538 *
539 * @param {String} name of the guard to use for logging or debugging
540 * @param {Function} func The function to invoke
541 * @param {*} context The context to use when calling the function
542 * @param {...*} args Arguments for function
543 */
544function invokeGuardedCallbackAndCatchFirstError(
545 name,
546 func,
547 context,
548 a,
549 b,
550 c,
551 d,
552 e,
553 f
554) {
555 invokeGuardedCallback.apply(this, arguments);
556 if (hasError) {
557 var error = clearCaughtError();
558 if (!hasRethrowError) {
559 hasRethrowError = true;
560 rethrowError = error;
561 }
562 }
563}
564
565/**
566 * During execution of guarded functions we will capture the first error which
567 * we will rethrow to be handled by the top level error handler.
568 */
569function rethrowCaughtError() {
570 if (hasRethrowError) {
571 var error = rethrowError;
572 hasRethrowError = false;
573 rethrowError = null;
574 throw error;
575 }
576}
577
578function hasCaughtError() {
579 return hasError;
580}
581
582function clearCaughtError() {
583 if (hasError) {
584 var error = caughtError;
585 hasError = false;
586 caughtError = null;
587 return error;
588 } else {
589 (function() {
590 {
591 throw ReactError(
592 Error(
593 "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue."
594 )
595 );
596 }
597 })();
598 }
599}
600
601/**
602 * Similar to invariant but only logs a warning if the condition is not met.
603 * This can be used to log issues in development environments in critical
604 * paths. Removing the logging code for production environments will keep the
605 * same logic and follow the same code paths.
606 */
607
608var warningWithoutStack = function() {};
609
610{
611 warningWithoutStack = function(condition, format) {
612 for (
613 var _len = arguments.length,
614 args = Array(_len > 2 ? _len - 2 : 0),
615 _key = 2;
616 _key < _len;
617 _key++
618 ) {
619 args[_key - 2] = arguments[_key];
620 }
621
622 if (format === undefined) {
623 throw new Error(
624 "`warningWithoutStack(condition, format, ...args)` requires a warning " +
625 "message argument"
626 );
627 }
628 if (args.length > 8) {
629 // Check before the condition to catch violations early.
630 throw new Error(
631 "warningWithoutStack() currently supports at most 8 arguments."
632 );
633 }
634 if (condition) {
635 return;
636 }
637 if (typeof console !== "undefined") {
638 var argsWithFormat = args.map(function(item) {
639 return "" + item;
640 });
641 argsWithFormat.unshift("Warning: " + format);
642
643 // We intentionally don't use spread (or .apply) directly because it
644 // breaks IE9: https://github.com/facebook/react/issues/13610
645 Function.prototype.apply.call(console.error, console, argsWithFormat);
646 }
647 try {
648 // --- Welcome to debugging React ---
649 // This error was thrown as a convenience so that you can use this stack
650 // to find the callsite that caused this warning to fire.
651 var argIndex = 0;
652 var message =
653 "Warning: " +
654 format.replace(/%s/g, function() {
655 return args[argIndex++];
656 });
657 throw new Error(message);
658 } catch (x) {}
659 };
660}
661
662var warningWithoutStack$1 = warningWithoutStack;
663
664var getFiberCurrentPropsFromNode = null;
665var getInstanceFromNode = null;
666var getNodeFromInstance = null;
667
668function setComponentTree(
669 getFiberCurrentPropsFromNodeImpl,
670 getInstanceFromNodeImpl,
671 getNodeFromInstanceImpl
672) {
673 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
674 getInstanceFromNode = getInstanceFromNodeImpl;
675 getNodeFromInstance = getNodeFromInstanceImpl;
676 {
677 !(getNodeFromInstance && getInstanceFromNode)
678 ? warningWithoutStack$1(
679 false,
680 "EventPluginUtils.setComponentTree(...): Injected " +
681 "module is missing getNodeFromInstance or getInstanceFromNode."
682 )
683 : void 0;
684 }
685}
686
687var validateEventDispatches = void 0;
688{
689 validateEventDispatches = function(event) {
690 var dispatchListeners = event._dispatchListeners;
691 var dispatchInstances = event._dispatchInstances;
692
693 var listenersIsArr = Array.isArray(dispatchListeners);
694 var listenersLen = listenersIsArr
695 ? dispatchListeners.length
696 : dispatchListeners
697 ? 1
698 : 0;
699
700 var instancesIsArr = Array.isArray(dispatchInstances);
701 var instancesLen = instancesIsArr
702 ? dispatchInstances.length
703 : dispatchInstances
704 ? 1
705 : 0;
706
707 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen)
708 ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.")
709 : void 0;
710 };
711}
712
713/**
714 * Dispatch the event to the listener.
715 * @param {SyntheticEvent} event SyntheticEvent to handle
716 * @param {function} listener Application-level callback
717 * @param {*} inst Internal component instance
718 */
719function executeDispatch(event, listener, inst) {
720 var type = event.type || "unknown-event";
721 event.currentTarget = getNodeFromInstance(inst);
722 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
723 event.currentTarget = null;
724}
725
726/**
727 * Standard/simple iteration through an event's collected dispatches.
728 */
729function executeDispatchesInOrder(event) {
730 var dispatchListeners = event._dispatchListeners;
731 var dispatchInstances = event._dispatchInstances;
732 {
733 validateEventDispatches(event);
734 }
735 if (Array.isArray(dispatchListeners)) {
736 for (var i = 0; i < dispatchListeners.length; i++) {
737 if (event.isPropagationStopped()) {
738 break;
739 }
740 // Listeners and Instances are two parallel arrays that are always in sync.
741 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
742 }
743 } else if (dispatchListeners) {
744 executeDispatch(event, dispatchListeners, dispatchInstances);
745 }
746 event._dispatchListeners = null;
747 event._dispatchInstances = null;
748}
749
750/**
751 * Standard/simple iteration through an event's collected dispatches, but stops
752 * at the first dispatch execution returning true, and returns that id.
753 *
754 * @return {?string} id of the first dispatch execution who's listener returns
755 * true, or null if no listener returned true.
756 */
757function executeDispatchesInOrderStopAtTrueImpl(event) {
758 var dispatchListeners = event._dispatchListeners;
759 var dispatchInstances = event._dispatchInstances;
760 {
761 validateEventDispatches(event);
762 }
763 if (Array.isArray(dispatchListeners)) {
764 for (var i = 0; i < dispatchListeners.length; i++) {
765 if (event.isPropagationStopped()) {
766 break;
767 }
768 // Listeners and Instances are two parallel arrays that are always in sync.
769 if (dispatchListeners[i](event, dispatchInstances[i])) {
770 return dispatchInstances[i];
771 }
772 }
773 } else if (dispatchListeners) {
774 if (dispatchListeners(event, dispatchInstances)) {
775 return dispatchInstances;
776 }
777 }
778 return null;
779}
780
781/**
782 * @see executeDispatchesInOrderStopAtTrueImpl
783 */
784function executeDispatchesInOrderStopAtTrue(event) {
785 var ret = executeDispatchesInOrderStopAtTrueImpl(event);
786 event._dispatchInstances = null;
787 event._dispatchListeners = null;
788 return ret;
789}
790
791/**
792 * Execution of a "direct" dispatch - there must be at most one dispatch
793 * accumulated on the event or it is considered an error. It doesn't really make
794 * sense for an event with multiple dispatches (bubbled) to keep track of the
795 * return values at each dispatch execution, but it does tend to make sense when
796 * dealing with "direct" dispatches.
797 *
798 * @return {*} The return value of executing the single dispatch.
799 */
800function executeDirectDispatch(event) {
801 {
802 validateEventDispatches(event);
803 }
804 var dispatchListener = event._dispatchListeners;
805 var dispatchInstance = event._dispatchInstances;
806 (function() {
807 if (!!Array.isArray(dispatchListener)) {
808 throw ReactError(Error("executeDirectDispatch(...): Invalid `event`."));
809 }
810 })();
811 event.currentTarget = dispatchListener
812 ? getNodeFromInstance(dispatchInstance)
813 : null;
814 var res = dispatchListener ? dispatchListener(event) : null;
815 event.currentTarget = null;
816 event._dispatchListeners = null;
817 event._dispatchInstances = null;
818 return res;
819}
820
821/**
822 * @param {SyntheticEvent} event
823 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
824 */
825function hasDispatches(event) {
826 return !!event._dispatchListeners;
827}
828
829/**
830 * Accumulates items that must not be null or undefined into the first one. This
831 * is used to conserve memory by avoiding array allocations, and thus sacrifices
832 * API cleanness. Since `current` can be null before being passed in and not
833 * null after this function, make sure to assign it back to `current`:
834 *
835 * `a = accumulateInto(a, b);`
836 *
837 * This API should be sparingly used. Try `accumulate` for something cleaner.
838 *
839 * @return {*|array<*>} An accumulation of items.
840 */
841
842function accumulateInto(current, next) {
843 (function() {
844 if (!(next != null)) {
845 throw ReactError(
846 Error(
847 "accumulateInto(...): Accumulated items must not be null or undefined."
848 )
849 );
850 }
851 })();
852
853 if (current == null) {
854 return next;
855 }
856
857 // Both are not empty. Warning: Never call x.concat(y) when you are not
858 // certain that x is an Array (x could be a string with concat method).
859 if (Array.isArray(current)) {
860 if (Array.isArray(next)) {
861 current.push.apply(current, next);
862 return current;
863 }
864 current.push(next);
865 return current;
866 }
867
868 if (Array.isArray(next)) {
869 // A bit too dangerous to mutate `next`.
870 return [current].concat(next);
871 }
872
873 return [current, next];
874}
875
876/**
877 * @param {array} arr an "accumulation" of items which is either an Array or
878 * a single item. Useful when paired with the `accumulate` module. This is a
879 * simple utility that allows us to reason about a collection of items, but
880 * handling the case when there is exactly one item (and we do not need to
881 * allocate an array).
882 * @param {function} cb Callback invoked with each element or a collection.
883 * @param {?} [scope] Scope used as `this` in a callback.
884 */
885function forEachAccumulated(arr, cb, scope) {
886 if (Array.isArray(arr)) {
887 arr.forEach(cb, scope);
888 } else if (arr) {
889 cb.call(scope, arr);
890 }
891}
892
893/**
894 * Internal queue of events that have accumulated their dispatches and are
895 * waiting to have their dispatches executed.
896 */
897var eventQueue = null;
898
899/**
900 * Dispatches an event and releases it back into the pool, unless persistent.
901 *
902 * @param {?object} event Synthetic event to be dispatched.
903 * @private
904 */
905var executeDispatchesAndRelease = function(event) {
906 if (event) {
907 executeDispatchesInOrder(event);
908
909 if (!event.isPersistent()) {
910 event.constructor.release(event);
911 }
912 }
913};
914var executeDispatchesAndReleaseTopLevel = function(e) {
915 return executeDispatchesAndRelease(e);
916};
917
918function runEventsInBatch(events) {
919 if (events !== null) {
920 eventQueue = accumulateInto(eventQueue, events);
921 }
922
923 // Set `eventQueue` to null before processing it so that we can tell if more
924 // events get enqueued while processing.
925 var processingEventQueue = eventQueue;
926 eventQueue = null;
927
928 if (!processingEventQueue) {
929 return;
930 }
931
932 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
933 (function() {
934 if (!!eventQueue) {
935 throw ReactError(
936 Error(
937 "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented."
938 )
939 );
940 }
941 })();
942 // This would be a good time to rethrow if any of the event handlers threw.
943 rethrowCaughtError();
944}
945
946function isInteractive(tag) {
947 return (
948 tag === "button" ||
949 tag === "input" ||
950 tag === "select" ||
951 tag === "textarea"
952 );
953}
954
955function shouldPreventMouseEvent(name, type, props) {
956 switch (name) {
957 case "onClick":
958 case "onClickCapture":
959 case "onDoubleClick":
960 case "onDoubleClickCapture":
961 case "onMouseDown":
962 case "onMouseDownCapture":
963 case "onMouseMove":
964 case "onMouseMoveCapture":
965 case "onMouseUp":
966 case "onMouseUpCapture":
967 return !!(props.disabled && isInteractive(type));
968 default:
969 return false;
970 }
971}
972
973/**
974 * This is a unified interface for event plugins to be installed and configured.
975 *
976 * Event plugins can implement the following properties:
977 *
978 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
979 * Required. When a top-level event is fired, this method is expected to
980 * extract synthetic events that will in turn be queued and dispatched.
981 *
982 * `eventTypes` {object}
983 * Optional, plugins that fire events must publish a mapping of registration
984 * names that are used to register listeners. Values of this mapping must
985 * be objects that contain `registrationName` or `phasedRegistrationNames`.
986 *
987 * `executeDispatch` {function(object, function, string)}
988 * Optional, allows plugins to override how an event gets dispatched. By
989 * default, the listener is simply invoked.
990 *
991 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
992 *
993 * @public
994 */
995
996/**
997 * Methods for injecting dependencies.
998 */
999var injection = {
1000 /**
1001 * @param {array} InjectedEventPluginOrder
1002 * @public
1003 */
1004 injectEventPluginOrder: injectEventPluginOrder,
1005
1006 /**
1007 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
1008 */
1009 injectEventPluginsByName: injectEventPluginsByName
1010};
1011
1012/**
1013 * @param {object} inst The instance, which is the source of events.
1014 * @param {string} registrationName Name of listener (e.g. `onClick`).
1015 * @return {?function} The stored callback.
1016 */
1017function getListener(inst, registrationName) {
1018 var listener = void 0;
1019
1020 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
1021 // live here; needs to be moved to a better place soon
1022 var stateNode = inst.stateNode;
1023 if (!stateNode) {
1024 // Work in progress (ex: onload events in incremental mode).
1025 return null;
1026 }
1027 var props = getFiberCurrentPropsFromNode(stateNode);
1028 if (!props) {
1029 // Work in progress.
1030 return null;
1031 }
1032 listener = props[registrationName];
1033 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
1034 return null;
1035 }
1036 (function() {
1037 if (!(!listener || typeof listener === "function")) {
1038 throw ReactError(
1039 Error(
1040 "Expected `" +
1041 registrationName +
1042 "` listener to be a function, instead got a value of `" +
1043 typeof listener +
1044 "` type."
1045 )
1046 );
1047 }
1048 })();
1049 return listener;
1050}
1051
1052/**
1053 * Allows registered plugins an opportunity to extract events from top-level
1054 * native browser events.
1055 *
1056 * @return {*} An accumulation of synthetic events.
1057 * @internal
1058 */
1059function extractPluginEvents(
1060 topLevelType,
1061 targetInst,
1062 nativeEvent,
1063 nativeEventTarget
1064) {
1065 var events = null;
1066 for (var i = 0; i < plugins.length; i++) {
1067 // Not every plugin in the ordering may be loaded at runtime.
1068 var possiblePlugin = plugins[i];
1069 if (possiblePlugin) {
1070 var extractedEvents = possiblePlugin.extractEvents(
1071 topLevelType,
1072 targetInst,
1073 nativeEvent,
1074 nativeEventTarget
1075 );
1076 if (extractedEvents) {
1077 events = accumulateInto(events, extractedEvents);
1078 }
1079 }
1080 }
1081 return events;
1082}
1083
1084function runExtractedPluginEventsInBatch(
1085 topLevelType,
1086 targetInst,
1087 nativeEvent,
1088 nativeEventTarget
1089) {
1090 var events = extractPluginEvents(
1091 topLevelType,
1092 targetInst,
1093 nativeEvent,
1094 nativeEventTarget
1095 );
1096 runEventsInBatch(events);
1097}
1098
1099var FunctionComponent = 0;
1100var ClassComponent = 1;
1101var IndeterminateComponent = 2; // Before we know whether it is function or class
1102var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
1103var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
1104var HostComponent = 5;
1105var HostText = 6;
1106var Fragment = 7;
1107var Mode = 8;
1108var ContextConsumer = 9;
1109var ContextProvider = 10;
1110var ForwardRef = 11;
1111var Profiler = 12;
1112var SuspenseComponent = 13;
1113var MemoComponent = 14;
1114var SimpleMemoComponent = 15;
1115var LazyComponent = 16;
1116var IncompleteClassComponent = 17;
1117var DehydratedSuspenseComponent = 18;
1118var SuspenseListComponent = 19;
1119var FundamentalComponent = 20;
1120
1121function getParent(inst) {
1122 do {
1123 inst = inst.return;
1124 // TODO: If this is a HostRoot we might want to bail out.
1125 // That is depending on if we want nested subtrees (layers) to bubble
1126 // events to their parent. We could also go through parentNode on the
1127 // host node but that wouldn't work for React Native and doesn't let us
1128 // do the portal feature.
1129 } while (inst && inst.tag !== HostComponent);
1130 if (inst) {
1131 return inst;
1132 }
1133 return null;
1134}
1135
1136/**
1137 * Return the lowest common ancestor of A and B, or null if they are in
1138 * different trees.
1139 */
1140function getLowestCommonAncestor(instA, instB) {
1141 var depthA = 0;
1142 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
1143 depthA++;
1144 }
1145 var depthB = 0;
1146 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
1147 depthB++;
1148 }
1149
1150 // If A is deeper, crawl up.
1151 while (depthA - depthB > 0) {
1152 instA = getParent(instA);
1153 depthA--;
1154 }
1155
1156 // If B is deeper, crawl up.
1157 while (depthB - depthA > 0) {
1158 instB = getParent(instB);
1159 depthB--;
1160 }
1161
1162 // Walk in lockstep until we find a match.
1163 var depth = depthA;
1164 while (depth--) {
1165 if (instA === instB || instA === instB.alternate) {
1166 return instA;
1167 }
1168 instA = getParent(instA);
1169 instB = getParent(instB);
1170 }
1171 return null;
1172}
1173
1174/**
1175 * Return if A is an ancestor of B.
1176 */
1177function isAncestor(instA, instB) {
1178 while (instB) {
1179 if (instA === instB || instA === instB.alternate) {
1180 return true;
1181 }
1182 instB = getParent(instB);
1183 }
1184 return false;
1185}
1186
1187/**
1188 * Return the parent instance of the passed-in instance.
1189 */
1190function getParentInstance(inst) {
1191 return getParent(inst);
1192}
1193
1194/**
1195 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
1196 */
1197function traverseTwoPhase(inst, fn, arg) {
1198 var path = [];
1199 while (inst) {
1200 path.push(inst);
1201 inst = getParent(inst);
1202 }
1203 var i = void 0;
1204 for (i = path.length; i-- > 0; ) {
1205 fn(path[i], "captured", arg);
1206 }
1207 for (i = 0; i < path.length; i++) {
1208 fn(path[i], "bubbled", arg);
1209 }
1210}
1211
1212/**
1213 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
1214 * should would receive a `mouseEnter` or `mouseLeave` event.
1215 *
1216 * Does not invoke the callback on the nearest common ancestor because nothing
1217 * "entered" or "left" that element.
1218 */
1219
1220/**
1221 * Some event types have a notion of different registration names for different
1222 * "phases" of propagation. This finds listeners by a given phase.
1223 */
1224function listenerAtPhase(inst, event, propagationPhase) {
1225 var registrationName =
1226 event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1227 return getListener(inst, registrationName);
1228}
1229
1230/**
1231 * A small set of propagation patterns, each of which will accept a small amount
1232 * of information, and generate a set of "dispatch ready event objects" - which
1233 * are sets of events that have already been annotated with a set of dispatched
1234 * listener functions/ids. The API is designed this way to discourage these
1235 * propagation strategies from actually executing the dispatches, since we
1236 * always want to collect the entire set of dispatches before executing even a
1237 * single one.
1238 */
1239
1240/**
1241 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1242 * here, allows us to not have to bind or create functions for each event.
1243 * Mutating the event's members allows us to not have to create a wrapping
1244 * "dispatch" object that pairs the event with the listener.
1245 */
1246function accumulateDirectionalDispatches(inst, phase, event) {
1247 {
1248 !inst
1249 ? warningWithoutStack$1(false, "Dispatching inst must not be null")
1250 : void 0;
1251 }
1252 var listener = listenerAtPhase(inst, event, phase);
1253 if (listener) {
1254 event._dispatchListeners = accumulateInto(
1255 event._dispatchListeners,
1256 listener
1257 );
1258 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1259 }
1260}
1261
1262/**
1263 * Collect dispatches (must be entirely collected before dispatching - see unit
1264 * tests). Lazily allocate the array to conserve memory. We must loop through
1265 * each event and perform the traversal for each one. We cannot perform a
1266 * single traversal for the entire collection of events because each event may
1267 * have a different target.
1268 */
1269function accumulateTwoPhaseDispatchesSingle(event) {
1270 if (event && event.dispatchConfig.phasedRegistrationNames) {
1271 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1272 }
1273}
1274
1275/**
1276 * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
1277 */
1278function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
1279 if (event && event.dispatchConfig.phasedRegistrationNames) {
1280 var targetInst = event._targetInst;
1281 var parentInst = targetInst ? getParentInstance(targetInst) : null;
1282 traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
1283 }
1284}
1285
1286/**
1287 * Accumulates without regard to direction, does not look for phased
1288 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1289 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1290 */
1291function accumulateDispatches(inst, ignoredDirection, event) {
1292 if (inst && event && event.dispatchConfig.registrationName) {
1293 var registrationName = event.dispatchConfig.registrationName;
1294 var listener = getListener(inst, registrationName);
1295 if (listener) {
1296 event._dispatchListeners = accumulateInto(
1297 event._dispatchListeners,
1298 listener
1299 );
1300 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1301 }
1302 }
1303}
1304
1305/**
1306 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1307 * `dispatchMarker`.
1308 * @param {SyntheticEvent} event
1309 */
1310function accumulateDirectDispatchesSingle(event) {
1311 if (event && event.dispatchConfig.registrationName) {
1312 accumulateDispatches(event._targetInst, null, event);
1313 }
1314}
1315
1316function accumulateTwoPhaseDispatches(events) {
1317 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1318}
1319
1320function accumulateTwoPhaseDispatchesSkipTarget(events) {
1321 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
1322}
1323
1324function accumulateDirectDispatches(events) {
1325 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1326}
1327
1328/* eslint valid-typeof: 0 */
1329
1330var EVENT_POOL_SIZE = 10;
1331
1332/**
1333 * @interface Event
1334 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1335 */
1336var EventInterface = {
1337 type: null,
1338 target: null,
1339 // currentTarget is set when dispatching; no use in copying it here
1340 currentTarget: function() {
1341 return null;
1342 },
1343 eventPhase: null,
1344 bubbles: null,
1345 cancelable: null,
1346 timeStamp: function(event) {
1347 return event.timeStamp || Date.now();
1348 },
1349 defaultPrevented: null,
1350 isTrusted: null
1351};
1352
1353function functionThatReturnsTrue() {
1354 return true;
1355}
1356
1357function functionThatReturnsFalse() {
1358 return false;
1359}
1360
1361/**
1362 * Synthetic events are dispatched by event plugins, typically in response to a
1363 * top-level event delegation handler.
1364 *
1365 * These systems should generally use pooling to reduce the frequency of garbage
1366 * collection. The system should check `isPersistent` to determine whether the
1367 * event should be released into the pool after being dispatched. Users that
1368 * need a persisted event should invoke `persist`.
1369 *
1370 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1371 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1372 * DOM interface; custom application-specific events can also subclass this.
1373 *
1374 * @param {object} dispatchConfig Configuration used to dispatch this event.
1375 * @param {*} targetInst Marker identifying the event target.
1376 * @param {object} nativeEvent Native browser event.
1377 * @param {DOMEventTarget} nativeEventTarget Target node.
1378 */
1379function SyntheticEvent(
1380 dispatchConfig,
1381 targetInst,
1382 nativeEvent,
1383 nativeEventTarget
1384) {
1385 {
1386 // these have a getter/setter for warnings
1387 delete this.nativeEvent;
1388 delete this.preventDefault;
1389 delete this.stopPropagation;
1390 delete this.isDefaultPrevented;
1391 delete this.isPropagationStopped;
1392 }
1393
1394 this.dispatchConfig = dispatchConfig;
1395 this._targetInst = targetInst;
1396 this.nativeEvent = nativeEvent;
1397
1398 var Interface = this.constructor.Interface;
1399 for (var propName in Interface) {
1400 if (!Interface.hasOwnProperty(propName)) {
1401 continue;
1402 }
1403 {
1404 delete this[propName]; // this has a getter/setter for warnings
1405 }
1406 var normalize = Interface[propName];
1407 if (normalize) {
1408 this[propName] = normalize(nativeEvent);
1409 } else {
1410 if (propName === "target") {
1411 this.target = nativeEventTarget;
1412 } else {
1413 this[propName] = nativeEvent[propName];
1414 }
1415 }
1416 }
1417
1418 var defaultPrevented =
1419 nativeEvent.defaultPrevented != null
1420 ? nativeEvent.defaultPrevented
1421 : nativeEvent.returnValue === false;
1422 if (defaultPrevented) {
1423 this.isDefaultPrevented = functionThatReturnsTrue;
1424 } else {
1425 this.isDefaultPrevented = functionThatReturnsFalse;
1426 }
1427 this.isPropagationStopped = functionThatReturnsFalse;
1428 return this;
1429}
1430
1431Object.assign(SyntheticEvent.prototype, {
1432 preventDefault: function() {
1433 this.defaultPrevented = true;
1434 var event = this.nativeEvent;
1435 if (!event) {
1436 return;
1437 }
1438
1439 if (event.preventDefault) {
1440 event.preventDefault();
1441 } else if (typeof event.returnValue !== "unknown") {
1442 event.returnValue = false;
1443 }
1444 this.isDefaultPrevented = functionThatReturnsTrue;
1445 },
1446
1447 stopPropagation: function() {
1448 var event = this.nativeEvent;
1449 if (!event) {
1450 return;
1451 }
1452
1453 if (event.stopPropagation) {
1454 event.stopPropagation();
1455 } else if (typeof event.cancelBubble !== "unknown") {
1456 // The ChangeEventPlugin registers a "propertychange" event for
1457 // IE. This event does not support bubbling or cancelling, and
1458 // any references to cancelBubble throw "Member not found". A
1459 // typeof check of "unknown" circumvents this issue (and is also
1460 // IE specific).
1461 event.cancelBubble = true;
1462 }
1463
1464 this.isPropagationStopped = functionThatReturnsTrue;
1465 },
1466
1467 /**
1468 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1469 * them back into the pool. This allows a way to hold onto a reference that
1470 * won't be added back into the pool.
1471 */
1472 persist: function() {
1473 this.isPersistent = functionThatReturnsTrue;
1474 },
1475
1476 /**
1477 * Checks if this event should be released back into the pool.
1478 *
1479 * @return {boolean} True if this should not be released, false otherwise.
1480 */
1481 isPersistent: functionThatReturnsFalse,
1482
1483 /**
1484 * `PooledClass` looks for `destructor` on each instance it releases.
1485 */
1486 destructor: function() {
1487 var Interface = this.constructor.Interface;
1488 for (var propName in Interface) {
1489 {
1490 Object.defineProperty(
1491 this,
1492 propName,
1493 getPooledWarningPropertyDefinition(propName, Interface[propName])
1494 );
1495 }
1496 }
1497 this.dispatchConfig = null;
1498 this._targetInst = null;
1499 this.nativeEvent = null;
1500 this.isDefaultPrevented = functionThatReturnsFalse;
1501 this.isPropagationStopped = functionThatReturnsFalse;
1502 this._dispatchListeners = null;
1503 this._dispatchInstances = null;
1504 {
1505 Object.defineProperty(
1506 this,
1507 "nativeEvent",
1508 getPooledWarningPropertyDefinition("nativeEvent", null)
1509 );
1510 Object.defineProperty(
1511 this,
1512 "isDefaultPrevented",
1513 getPooledWarningPropertyDefinition(
1514 "isDefaultPrevented",
1515 functionThatReturnsFalse
1516 )
1517 );
1518 Object.defineProperty(
1519 this,
1520 "isPropagationStopped",
1521 getPooledWarningPropertyDefinition(
1522 "isPropagationStopped",
1523 functionThatReturnsFalse
1524 )
1525 );
1526 Object.defineProperty(
1527 this,
1528 "preventDefault",
1529 getPooledWarningPropertyDefinition("preventDefault", function() {})
1530 );
1531 Object.defineProperty(
1532 this,
1533 "stopPropagation",
1534 getPooledWarningPropertyDefinition("stopPropagation", function() {})
1535 );
1536 }
1537 }
1538});
1539
1540SyntheticEvent.Interface = EventInterface;
1541
1542/**
1543 * Helper to reduce boilerplate when creating subclasses.
1544 */
1545SyntheticEvent.extend = function(Interface) {
1546 var Super = this;
1547
1548 var E = function() {};
1549 E.prototype = Super.prototype;
1550 var prototype = new E();
1551
1552 function Class() {
1553 return Super.apply(this, arguments);
1554 }
1555 Object.assign(prototype, Class.prototype);
1556 Class.prototype = prototype;
1557 Class.prototype.constructor = Class;
1558
1559 Class.Interface = Object.assign({}, Super.Interface, Interface);
1560 Class.extend = Super.extend;
1561 addEventPoolingTo(Class);
1562
1563 return Class;
1564};
1565
1566addEventPoolingTo(SyntheticEvent);
1567
1568/**
1569 * Helper to nullify syntheticEvent instance properties when destructing
1570 *
1571 * @param {String} propName
1572 * @param {?object} getVal
1573 * @return {object} defineProperty object
1574 */
1575function getPooledWarningPropertyDefinition(propName, getVal) {
1576 var isFunction = typeof getVal === "function";
1577 return {
1578 configurable: true,
1579 set: set,
1580 get: get
1581 };
1582
1583 function set(val) {
1584 var action = isFunction ? "setting the method" : "setting the property";
1585 warn(action, "This is effectively a no-op");
1586 return val;
1587 }
1588
1589 function get() {
1590 var action = isFunction ? "accessing the method" : "accessing the property";
1591 var result = isFunction
1592 ? "This is a no-op function"
1593 : "This is set to null";
1594 warn(action, result);
1595 return getVal;
1596 }
1597
1598 function warn(action, result) {
1599 var warningCondition = false;
1600 !warningCondition
1601 ? warningWithoutStack$1(
1602 false,
1603 "This synthetic event is reused for performance reasons. If you're seeing this, " +
1604 "you're %s `%s` on a released/nullified synthetic event. %s. " +
1605 "If you must keep the original synthetic event around, use event.persist(). " +
1606 "See https://fb.me/react-event-pooling for more information.",
1607 action,
1608 propName,
1609 result
1610 )
1611 : void 0;
1612 }
1613}
1614
1615function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1616 var EventConstructor = this;
1617 if (EventConstructor.eventPool.length) {
1618 var instance = EventConstructor.eventPool.pop();
1619 EventConstructor.call(
1620 instance,
1621 dispatchConfig,
1622 targetInst,
1623 nativeEvent,
1624 nativeInst
1625 );
1626 return instance;
1627 }
1628 return new EventConstructor(
1629 dispatchConfig,
1630 targetInst,
1631 nativeEvent,
1632 nativeInst
1633 );
1634}
1635
1636function releasePooledEvent(event) {
1637 var EventConstructor = this;
1638 (function() {
1639 if (!(event instanceof EventConstructor)) {
1640 throw ReactError(
1641 Error(
1642 "Trying to release an event instance into a pool of a different type."
1643 )
1644 );
1645 }
1646 })();
1647 event.destructor();
1648 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1649 EventConstructor.eventPool.push(event);
1650 }
1651}
1652
1653function addEventPoolingTo(EventConstructor) {
1654 EventConstructor.eventPool = [];
1655 EventConstructor.getPooled = getPooledEvent;
1656 EventConstructor.release = releasePooledEvent;
1657}
1658
1659/**
1660 * `touchHistory` isn't actually on the native event, but putting it in the
1661 * interface will ensure that it is cleaned up when pooled/destroyed. The
1662 * `ResponderEventPlugin` will populate it appropriately.
1663 */
1664var ResponderSyntheticEvent = SyntheticEvent.extend({
1665 touchHistory: function(nativeEvent) {
1666 return null; // Actually doesn't even look at the native event.
1667 }
1668});
1669
1670var TOP_TOUCH_START = "topTouchStart";
1671var TOP_TOUCH_MOVE = "topTouchMove";
1672var TOP_TOUCH_END = "topTouchEnd";
1673var TOP_TOUCH_CANCEL = "topTouchCancel";
1674var TOP_SCROLL = "topScroll";
1675var TOP_SELECTION_CHANGE = "topSelectionChange";
1676
1677function isStartish(topLevelType) {
1678 return topLevelType === TOP_TOUCH_START;
1679}
1680
1681function isMoveish(topLevelType) {
1682 return topLevelType === TOP_TOUCH_MOVE;
1683}
1684
1685function isEndish(topLevelType) {
1686 return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL;
1687}
1688
1689var startDependencies = [TOP_TOUCH_START];
1690var moveDependencies = [TOP_TOUCH_MOVE];
1691var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END];
1692
1693/**
1694 * Tracks the position and time of each active touch by `touch.identifier`. We
1695 * should typically only see IDs in the range of 1-20 because IDs get recycled
1696 * when touches end and start again.
1697 */
1698
1699var MAX_TOUCH_BANK = 20;
1700var touchBank = [];
1701var touchHistory = {
1702 touchBank: touchBank,
1703 numberActiveTouches: 0,
1704 // If there is only one active touch, we remember its location. This prevents
1705 // us having to loop through all of the touches all the time in the most
1706 // common case.
1707 indexOfSingleActiveTouch: -1,
1708 mostRecentTimeStamp: 0
1709};
1710
1711function timestampForTouch(touch) {
1712 // The legacy internal implementation provides "timeStamp", which has been
1713 // renamed to "timestamp". Let both work for now while we iron it out
1714 // TODO (evv): rename timeStamp to timestamp in internal code
1715 return touch.timeStamp || touch.timestamp;
1716}
1717
1718/**
1719 * TODO: Instead of making gestures recompute filtered velocity, we could
1720 * include a built in velocity computation that can be reused globally.
1721 */
1722function createTouchRecord(touch) {
1723 return {
1724 touchActive: true,
1725 startPageX: touch.pageX,
1726 startPageY: touch.pageY,
1727 startTimeStamp: timestampForTouch(touch),
1728 currentPageX: touch.pageX,
1729 currentPageY: touch.pageY,
1730 currentTimeStamp: timestampForTouch(touch),
1731 previousPageX: touch.pageX,
1732 previousPageY: touch.pageY,
1733 previousTimeStamp: timestampForTouch(touch)
1734 };
1735}
1736
1737function resetTouchRecord(touchRecord, touch) {
1738 touchRecord.touchActive = true;
1739 touchRecord.startPageX = touch.pageX;
1740 touchRecord.startPageY = touch.pageY;
1741 touchRecord.startTimeStamp = timestampForTouch(touch);
1742 touchRecord.currentPageX = touch.pageX;
1743 touchRecord.currentPageY = touch.pageY;
1744 touchRecord.currentTimeStamp = timestampForTouch(touch);
1745 touchRecord.previousPageX = touch.pageX;
1746 touchRecord.previousPageY = touch.pageY;
1747 touchRecord.previousTimeStamp = timestampForTouch(touch);
1748}
1749
1750function getTouchIdentifier(_ref) {
1751 var identifier = _ref.identifier;
1752
1753 (function() {
1754 if (!(identifier != null)) {
1755 throw ReactError(Error("Touch object is missing identifier."));
1756 }
1757 })();
1758 {
1759 !(identifier <= MAX_TOUCH_BANK)
1760 ? warningWithoutStack$1(
1761 false,
1762 "Touch identifier %s is greater than maximum supported %s which causes " +
1763 "performance issues backfilling array locations for all of the indices.",
1764 identifier,
1765 MAX_TOUCH_BANK
1766 )
1767 : void 0;
1768 }
1769 return identifier;
1770}
1771
1772function recordTouchStart(touch) {
1773 var identifier = getTouchIdentifier(touch);
1774 var touchRecord = touchBank[identifier];
1775 if (touchRecord) {
1776 resetTouchRecord(touchRecord, touch);
1777 } else {
1778 touchBank[identifier] = createTouchRecord(touch);
1779 }
1780 touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
1781}
1782
1783function recordTouchMove(touch) {
1784 var touchRecord = touchBank[getTouchIdentifier(touch)];
1785 if (touchRecord) {
1786 touchRecord.touchActive = true;
1787 touchRecord.previousPageX = touchRecord.currentPageX;
1788 touchRecord.previousPageY = touchRecord.currentPageY;
1789 touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
1790 touchRecord.currentPageX = touch.pageX;
1791 touchRecord.currentPageY = touch.pageY;
1792 touchRecord.currentTimeStamp = timestampForTouch(touch);
1793 touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
1794 } else {
1795 console.warn(
1796 "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n",
1797 "Touch Bank: %s",
1798 printTouch(touch),
1799 printTouchBank()
1800 );
1801 }
1802}
1803
1804function recordTouchEnd(touch) {
1805 var touchRecord = touchBank[getTouchIdentifier(touch)];
1806 if (touchRecord) {
1807 touchRecord.touchActive = false;
1808 touchRecord.previousPageX = touchRecord.currentPageX;
1809 touchRecord.previousPageY = touchRecord.currentPageY;
1810 touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
1811 touchRecord.currentPageX = touch.pageX;
1812 touchRecord.currentPageY = touch.pageY;
1813 touchRecord.currentTimeStamp = timestampForTouch(touch);
1814 touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
1815 } else {
1816 console.warn(
1817 "Cannot record touch end without a touch start.\n" + "Touch End: %s\n",
1818 "Touch Bank: %s",
1819 printTouch(touch),
1820 printTouchBank()
1821 );
1822 }
1823}
1824
1825function printTouch(touch) {
1826 return JSON.stringify({
1827 identifier: touch.identifier,
1828 pageX: touch.pageX,
1829 pageY: touch.pageY,
1830 timestamp: timestampForTouch(touch)
1831 });
1832}
1833
1834function printTouchBank() {
1835 var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK));
1836 if (touchBank.length > MAX_TOUCH_BANK) {
1837 printed += " (original size: " + touchBank.length + ")";
1838 }
1839 return printed;
1840}
1841
1842var ResponderTouchHistoryStore = {
1843 recordTouchTrack: function(topLevelType, nativeEvent) {
1844 if (isMoveish(topLevelType)) {
1845 nativeEvent.changedTouches.forEach(recordTouchMove);
1846 } else if (isStartish(topLevelType)) {
1847 nativeEvent.changedTouches.forEach(recordTouchStart);
1848 touchHistory.numberActiveTouches = nativeEvent.touches.length;
1849 if (touchHistory.numberActiveTouches === 1) {
1850 touchHistory.indexOfSingleActiveTouch =
1851 nativeEvent.touches[0].identifier;
1852 }
1853 } else if (isEndish(topLevelType)) {
1854 nativeEvent.changedTouches.forEach(recordTouchEnd);
1855 touchHistory.numberActiveTouches = nativeEvent.touches.length;
1856 if (touchHistory.numberActiveTouches === 1) {
1857 for (var i = 0; i < touchBank.length; i++) {
1858 var touchTrackToCheck = touchBank[i];
1859 if (touchTrackToCheck != null && touchTrackToCheck.touchActive) {
1860 touchHistory.indexOfSingleActiveTouch = i;
1861 break;
1862 }
1863 }
1864 {
1865 var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch];
1866 !(activeRecord != null && activeRecord.touchActive)
1867 ? warningWithoutStack$1(false, "Cannot find single active touch.")
1868 : void 0;
1869 }
1870 }
1871 }
1872 },
1873
1874 touchHistory: touchHistory
1875};
1876
1877/**
1878 * Accumulates items that must not be null or undefined.
1879 *
1880 * This is used to conserve memory by avoiding array allocations.
1881 *
1882 * @return {*|array<*>} An accumulation of items.
1883 */
1884function accumulate(current, next) {
1885 (function() {
1886 if (!(next != null)) {
1887 throw ReactError(
1888 Error(
1889 "accumulate(...): Accumulated items must not be null or undefined."
1890 )
1891 );
1892 }
1893 })();
1894
1895 if (current == null) {
1896 return next;
1897 }
1898
1899 // Both are not empty. Warning: Never call x.concat(y) when you are not
1900 // certain that x is an Array (x could be a string with concat method).
1901 if (Array.isArray(current)) {
1902 return current.concat(next);
1903 }
1904
1905 if (Array.isArray(next)) {
1906 return [current].concat(next);
1907 }
1908
1909 return [current, next];
1910}
1911
1912/**
1913 * Instance of element that should respond to touch/move types of interactions,
1914 * as indicated explicitly by relevant callbacks.
1915 */
1916var responderInst = null;
1917
1918/**
1919 * Count of current touches. A textInput should become responder iff the
1920 * selection changes while there is a touch on the screen.
1921 */
1922var trackedTouchCount = 0;
1923
1924var changeResponder = function(nextResponderInst, blockHostResponder) {
1925 var oldResponderInst = responderInst;
1926 responderInst = nextResponderInst;
1927 if (ResponderEventPlugin.GlobalResponderHandler !== null) {
1928 ResponderEventPlugin.GlobalResponderHandler.onChange(
1929 oldResponderInst,
1930 nextResponderInst,
1931 blockHostResponder
1932 );
1933 }
1934};
1935
1936var eventTypes = {
1937 /**
1938 * On a `touchStart`/`mouseDown`, is it desired that this element become the
1939 * responder?
1940 */
1941 startShouldSetResponder: {
1942 phasedRegistrationNames: {
1943 bubbled: "onStartShouldSetResponder",
1944 captured: "onStartShouldSetResponderCapture"
1945 },
1946 dependencies: startDependencies
1947 },
1948
1949 /**
1950 * On a `scroll`, is it desired that this element become the responder? This
1951 * is usually not needed, but should be used to retroactively infer that a
1952 * `touchStart` had occurred during momentum scroll. During a momentum scroll,
1953 * a touch start will be immediately followed by a scroll event if the view is
1954 * currently scrolling.
1955 *
1956 * TODO: This shouldn't bubble.
1957 */
1958 scrollShouldSetResponder: {
1959 phasedRegistrationNames: {
1960 bubbled: "onScrollShouldSetResponder",
1961 captured: "onScrollShouldSetResponderCapture"
1962 },
1963 dependencies: [TOP_SCROLL]
1964 },
1965
1966 /**
1967 * On text selection change, should this element become the responder? This
1968 * is needed for text inputs or other views with native selection, so the
1969 * JS view can claim the responder.
1970 *
1971 * TODO: This shouldn't bubble.
1972 */
1973 selectionChangeShouldSetResponder: {
1974 phasedRegistrationNames: {
1975 bubbled: "onSelectionChangeShouldSetResponder",
1976 captured: "onSelectionChangeShouldSetResponderCapture"
1977 },
1978 dependencies: [TOP_SELECTION_CHANGE]
1979 },
1980
1981 /**
1982 * On a `touchMove`/`mouseMove`, is it desired that this element become the
1983 * responder?
1984 */
1985 moveShouldSetResponder: {
1986 phasedRegistrationNames: {
1987 bubbled: "onMoveShouldSetResponder",
1988 captured: "onMoveShouldSetResponderCapture"
1989 },
1990 dependencies: moveDependencies
1991 },
1992
1993 /**
1994 * Direct responder events dispatched directly to responder. Do not bubble.
1995 */
1996 responderStart: {
1997 registrationName: "onResponderStart",
1998 dependencies: startDependencies
1999 },
2000 responderMove: {
2001 registrationName: "onResponderMove",
2002 dependencies: moveDependencies
2003 },
2004 responderEnd: {
2005 registrationName: "onResponderEnd",
2006 dependencies: endDependencies
2007 },
2008 responderRelease: {
2009 registrationName: "onResponderRelease",
2010 dependencies: endDependencies
2011 },
2012 responderTerminationRequest: {
2013 registrationName: "onResponderTerminationRequest",
2014 dependencies: []
2015 },
2016 responderGrant: {
2017 registrationName: "onResponderGrant",
2018 dependencies: []
2019 },
2020 responderReject: {
2021 registrationName: "onResponderReject",
2022 dependencies: []
2023 },
2024 responderTerminate: {
2025 registrationName: "onResponderTerminate",
2026 dependencies: []
2027 }
2028};
2029
2030/**
2031 *
2032 * Responder System:
2033 * ----------------
2034 *
2035 * - A global, solitary "interaction lock" on a view.
2036 * - If a node becomes the responder, it should convey visual feedback
2037 * immediately to indicate so, either by highlighting or moving accordingly.
2038 * - To be the responder means, that touches are exclusively important to that
2039 * responder view, and no other view.
2040 * - While touches are still occurring, the responder lock can be transferred to
2041 * a new view, but only to increasingly "higher" views (meaning ancestors of
2042 * the current responder).
2043 *
2044 * Responder being granted:
2045 * ------------------------
2046 *
2047 * - Touch starts, moves, and scrolls can cause an ID to become the responder.
2048 * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to
2049 * the "appropriate place".
2050 * - If nothing is currently the responder, the "appropriate place" is the
2051 * initiating event's `targetID`.
2052 * - If something *is* already the responder, the "appropriate place" is the
2053 * first common ancestor of the event target and the current `responderInst`.
2054 * - Some negotiation happens: See the timing diagram below.
2055 * - Scrolled views automatically become responder. The reasoning is that a
2056 * platform scroll view that isn't built on top of the responder system has
2057 * began scrolling, and the active responder must now be notified that the
2058 * interaction is no longer locked to it - the system has taken over.
2059 *
2060 * - Responder being released:
2061 * As soon as no more touches that *started* inside of descendants of the
2062 * *current* responderInst, an `onResponderRelease` event is dispatched to the
2063 * current responder, and the responder lock is released.
2064 *
2065 * TODO:
2066 * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that
2067 * determines if the responder lock should remain.
2068 * - If a view shouldn't "remain" the responder, any active touches should by
2069 * default be considered "dead" and do not influence future negotiations or
2070 * bubble paths. It should be as if those touches do not exist.
2071 * -- For multitouch: Usually a translate-z will choose to "remain" responder
2072 * after one out of many touches ended. For translate-y, usually the view
2073 * doesn't wish to "remain" responder after one of many touches end.
2074 * - Consider building this on top of a `stopPropagation` model similar to
2075 * `W3C` events.
2076 * - Ensure that `onResponderTerminate` is called on touch cancels, whether or
2077 * not `onResponderTerminationRequest` returns `true` or `false`.
2078 *
2079 */
2080
2081/* Negotiation Performed
2082 +-----------------------+
2083 / \
2084Process low level events to + Current Responder + wantsResponderID
2085determine who to perform negot-| (if any exists at all) |
2086iation/transition | Otherwise just pass through|
2087-------------------------------+----------------------------+------------------+
2088Bubble to find first ID | |
2089to return true:wantsResponderID| |
2090 | |
2091 +-------------+ | |
2092 | onTouchStart| | |
2093 +------+------+ none | |
2094 | return| |
2095+-----------v-------------+true| +------------------------+ |
2096|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+
2097+-----------+-------------+ | +------------------------+ | |
2098 | | | +--------+-------+
2099 | returned true for| false:REJECT +-------->|onResponderReject
2100 | wantsResponderID | | | +----------------+
2101 | (now attempt | +------------------+-----+ |
2102 | handoff) | | onResponder | |
2103 +------------------->| TerminationRequest| |
2104 | +------------------+-----+ |
2105 | | | +----------------+
2106 | true:GRANT +-------->|onResponderGrant|
2107 | | +--------+-------+
2108 | +------------------------+ | |
2109 | | onResponderTerminate |<-----------+
2110 | +------------------+-----+ |
2111 | | | +----------------+
2112 | +-------->|onResponderStart|
2113 | | +----------------+
2114Bubble to find first ID | |
2115to return true:wantsResponderID| |
2116 | |
2117 +-------------+ | |
2118 | onTouchMove | | |
2119 +------+------+ none | |
2120 | return| |
2121+-----------v-------------+true| +------------------------+ |
2122|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+
2123+-----------+-------------+ | +------------------------+ | |
2124 | | | +--------+-------+
2125 | returned true for| false:REJECT +-------->|onResponderRejec|
2126 | wantsResponderID | | | +----------------+
2127 | (now attempt | +------------------+-----+ |
2128 | handoff) | | onResponder | |
2129 +------------------->| TerminationRequest| |
2130 | +------------------+-----+ |
2131 | | | +----------------+
2132 | true:GRANT +-------->|onResponderGrant|
2133 | | +--------+-------+
2134 | +------------------------+ | |
2135 | | onResponderTerminate |<-----------+
2136 | +------------------+-----+ |
2137 | | | +----------------+
2138 | +-------->|onResponderMove |
2139 | | +----------------+
2140 | |
2141 | |
2142 Some active touch started| |
2143 inside current responder | +------------------------+ |
2144 +------------------------->| onResponderEnd | |
2145 | | +------------------------+ |
2146 +---+---------+ | |
2147 | onTouchEnd | | |
2148 +---+---------+ | |
2149 | | +------------------------+ |
2150 +------------------------->| onResponderEnd | |
2151 No active touches started| +-----------+------------+ |
2152 inside current responder | | |
2153 | v |
2154 | +------------------------+ |
2155 | | onResponderRelease | |
2156 | +------------------------+ |
2157 | |
2158 + + */
2159
2160/**
2161 * A note about event ordering in the `EventPluginHub`.
2162 *
2163 * Suppose plugins are injected in the following order:
2164 *
2165 * `[R, S, C]`
2166 *
2167 * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for
2168 * `onClick` etc) and `R` is `ResponderEventPlugin`.
2169 *
2170 * "Deferred-Dispatched Events":
2171 *
2172 * - The current event plugin system will traverse the list of injected plugins,
2173 * in order, and extract events by collecting the plugin's return value of
2174 * `extractEvents()`.
2175 * - These events that are returned from `extractEvents` are "deferred
2176 * dispatched events".
2177 * - When returned from `extractEvents`, deferred-dispatched events contain an
2178 * "accumulation" of deferred dispatches.
2179 * - These deferred dispatches are accumulated/collected before they are
2180 * returned, but processed at a later time by the `EventPluginHub` (hence the
2181 * name deferred).
2182 *
2183 * In the process of returning their deferred-dispatched events, event plugins
2184 * themselves can dispatch events on-demand without returning them from
2185 * `extractEvents`. Plugins might want to do this, so that they can use event
2186 * dispatching as a tool that helps them decide which events should be extracted
2187 * in the first place.
2188 *
2189 * "On-Demand-Dispatched Events":
2190 *
2191 * - On-demand-dispatched events are not returned from `extractEvents`.
2192 * - On-demand-dispatched events are dispatched during the process of returning
2193 * the deferred-dispatched events.
2194 * - They should not have side effects.
2195 * - They should be avoided, and/or eventually be replaced with another
2196 * abstraction that allows event plugins to perform multiple "rounds" of event
2197 * extraction.
2198 *
2199 * Therefore, the sequence of event dispatches becomes:
2200 *
2201 * - `R`s on-demand events (if any) (dispatched by `R` on-demand)
2202 * - `S`s on-demand events (if any) (dispatched by `S` on-demand)
2203 * - `C`s on-demand events (if any) (dispatched by `C` on-demand)
2204 * - `R`s extracted events (if any) (dispatched by `EventPluginHub`)
2205 * - `S`s extracted events (if any) (dispatched by `EventPluginHub`)
2206 * - `C`s extracted events (if any) (dispatched by `EventPluginHub`)
2207 *
2208 * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder`
2209 * on-demand dispatch returns `true` (and some other details are satisfied) the
2210 * `onResponderGrant` deferred dispatched event is returned from
2211 * `extractEvents`. The sequence of dispatch executions in this case
2212 * will appear as follows:
2213 *
2214 * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand)
2215 * - `touchStartCapture` (`EventPluginHub` dispatches as usual)
2216 * - `touchStart` (`EventPluginHub` dispatches as usual)
2217 * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual)
2218 */
2219
2220function setResponderAndExtractTransfer(
2221 topLevelType,
2222 targetInst,
2223 nativeEvent,
2224 nativeEventTarget
2225) {
2226 var shouldSetEventType = isStartish(topLevelType)
2227 ? eventTypes.startShouldSetResponder
2228 : isMoveish(topLevelType)
2229 ? eventTypes.moveShouldSetResponder
2230 : topLevelType === TOP_SELECTION_CHANGE
2231 ? eventTypes.selectionChangeShouldSetResponder
2232 : eventTypes.scrollShouldSetResponder;
2233
2234 // TODO: stop one short of the current responder.
2235 var bubbleShouldSetFrom = !responderInst
2236 ? targetInst
2237 : getLowestCommonAncestor(responderInst, targetInst);
2238
2239 // When capturing/bubbling the "shouldSet" event, we want to skip the target
2240 // (deepest ID) if it happens to be the current responder. The reasoning:
2241 // It's strange to get an `onMoveShouldSetResponder` when you're *already*
2242 // the responder.
2243 var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst;
2244 var shouldSetEvent = ResponderSyntheticEvent.getPooled(
2245 shouldSetEventType,
2246 bubbleShouldSetFrom,
2247 nativeEvent,
2248 nativeEventTarget
2249 );
2250 shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
2251 if (skipOverBubbleShouldSetFrom) {
2252 accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent);
2253 } else {
2254 accumulateTwoPhaseDispatches(shouldSetEvent);
2255 }
2256 var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent);
2257 if (!shouldSetEvent.isPersistent()) {
2258 shouldSetEvent.constructor.release(shouldSetEvent);
2259 }
2260
2261 if (!wantsResponderInst || wantsResponderInst === responderInst) {
2262 return null;
2263 }
2264 var extracted = void 0;
2265 var grantEvent = ResponderSyntheticEvent.getPooled(
2266 eventTypes.responderGrant,
2267 wantsResponderInst,
2268 nativeEvent,
2269 nativeEventTarget
2270 );
2271 grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
2272
2273 accumulateDirectDispatches(grantEvent);
2274 var blockHostResponder = executeDirectDispatch(grantEvent) === true;
2275 if (responderInst) {
2276 var terminationRequestEvent = ResponderSyntheticEvent.getPooled(
2277 eventTypes.responderTerminationRequest,
2278 responderInst,
2279 nativeEvent,
2280 nativeEventTarget
2281 );
2282 terminationRequestEvent.touchHistory =
2283 ResponderTouchHistoryStore.touchHistory;
2284 accumulateDirectDispatches(terminationRequestEvent);
2285 var shouldSwitch =
2286 !hasDispatches(terminationRequestEvent) ||
2287 executeDirectDispatch(terminationRequestEvent);
2288 if (!terminationRequestEvent.isPersistent()) {
2289 terminationRequestEvent.constructor.release(terminationRequestEvent);
2290 }
2291
2292 if (shouldSwitch) {
2293 var terminateEvent = ResponderSyntheticEvent.getPooled(
2294 eventTypes.responderTerminate,
2295 responderInst,
2296 nativeEvent,
2297 nativeEventTarget
2298 );
2299 terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
2300 accumulateDirectDispatches(terminateEvent);
2301 extracted = accumulate(extracted, [grantEvent, terminateEvent]);
2302 changeResponder(wantsResponderInst, blockHostResponder);
2303 } else {
2304 var rejectEvent = ResponderSyntheticEvent.getPooled(
2305 eventTypes.responderReject,
2306 wantsResponderInst,
2307 nativeEvent,
2308 nativeEventTarget
2309 );
2310 rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
2311 accumulateDirectDispatches(rejectEvent);
2312 extracted = accumulate(extracted, rejectEvent);
2313 }
2314 } else {
2315 extracted = accumulate(extracted, grantEvent);
2316 changeResponder(wantsResponderInst, blockHostResponder);
2317 }
2318 return extracted;
2319}
2320
2321/**
2322 * A transfer is a negotiation between a currently set responder and the next
2323 * element to claim responder status. Any start event could trigger a transfer
2324 * of responderInst. Any move event could trigger a transfer.
2325 *
2326 * @param {string} topLevelType Record from `BrowserEventConstants`.
2327 * @return {boolean} True if a transfer of responder could possibly occur.
2328 */
2329function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) {
2330 return (
2331 topLevelInst &&
2332 // responderIgnoreScroll: We are trying to migrate away from specifically
2333 // tracking native scroll events here and responderIgnoreScroll indicates we
2334 // will send topTouchCancel to handle canceling touch events instead
2335 ((topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll) ||
2336 (trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE) ||
2337 isStartish(topLevelType) ||
2338 isMoveish(topLevelType))
2339 );
2340}
2341
2342/**
2343 * Returns whether or not this touch end event makes it such that there are no
2344 * longer any touches that started inside of the current `responderInst`.
2345 *
2346 * @param {NativeEvent} nativeEvent Native touch end event.
2347 * @return {boolean} Whether or not this touch end event ends the responder.
2348 */
2349function noResponderTouches(nativeEvent) {
2350 var touches = nativeEvent.touches;
2351 if (!touches || touches.length === 0) {
2352 return true;
2353 }
2354 for (var i = 0; i < touches.length; i++) {
2355 var activeTouch = touches[i];
2356 var target = activeTouch.target;
2357 if (target !== null && target !== undefined && target !== 0) {
2358 // Is the original touch location inside of the current responder?
2359 var targetInst = getInstanceFromNode(target);
2360 if (isAncestor(responderInst, targetInst)) {
2361 return false;
2362 }
2363 }
2364 }
2365 return true;
2366}
2367
2368var ResponderEventPlugin = {
2369 /* For unit testing only */
2370 _getResponder: function() {
2371 return responderInst;
2372 },
2373
2374 eventTypes: eventTypes,
2375
2376 /**
2377 * We must be resilient to `targetInst` being `null` on `touchMove` or
2378 * `touchEnd`. On certain platforms, this means that a native scroll has
2379 * assumed control and the original touch targets are destroyed.
2380 */
2381 extractEvents: function(
2382 topLevelType,
2383 targetInst,
2384 nativeEvent,
2385 nativeEventTarget
2386 ) {
2387 if (isStartish(topLevelType)) {
2388 trackedTouchCount += 1;
2389 } else if (isEndish(topLevelType)) {
2390 if (trackedTouchCount >= 0) {
2391 trackedTouchCount -= 1;
2392 } else {
2393 console.error(
2394 "Ended a touch event which was not counted in `trackedTouchCount`."
2395 );
2396 return null;
2397 }
2398 }
2399
2400 ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent);
2401
2402 var extracted = canTriggerTransfer(topLevelType, targetInst, nativeEvent)
2403 ? setResponderAndExtractTransfer(
2404 topLevelType,
2405 targetInst,
2406 nativeEvent,
2407 nativeEventTarget
2408 )
2409 : null;
2410 // Responder may or may not have transferred on a new touch start/move.
2411 // Regardless, whoever is the responder after any potential transfer, we
2412 // direct all touch start/move/ends to them in the form of
2413 // `onResponderMove/Start/End`. These will be called for *every* additional
2414 // finger that move/start/end, dispatched directly to whoever is the
2415 // current responder at that moment, until the responder is "released".
2416 //
2417 // These multiple individual change touch events are are always bookended
2418 // by `onResponderGrant`, and one of
2419 // (`onResponderRelease/onResponderTerminate`).
2420 var isResponderTouchStart = responderInst && isStartish(topLevelType);
2421 var isResponderTouchMove = responderInst && isMoveish(topLevelType);
2422 var isResponderTouchEnd = responderInst && isEndish(topLevelType);
2423 var incrementalTouch = isResponderTouchStart
2424 ? eventTypes.responderStart
2425 : isResponderTouchMove
2426 ? eventTypes.responderMove
2427 : isResponderTouchEnd
2428 ? eventTypes.responderEnd
2429 : null;
2430
2431 if (incrementalTouch) {
2432 var gesture = ResponderSyntheticEvent.getPooled(
2433 incrementalTouch,
2434 responderInst,
2435 nativeEvent,
2436 nativeEventTarget
2437 );
2438 gesture.touchHistory = ResponderTouchHistoryStore.touchHistory;
2439 accumulateDirectDispatches(gesture);
2440 extracted = accumulate(extracted, gesture);
2441 }
2442
2443 var isResponderTerminate =
2444 responderInst && topLevelType === TOP_TOUCH_CANCEL;
2445 var isResponderRelease =
2446 responderInst &&
2447 !isResponderTerminate &&
2448 isEndish(topLevelType) &&
2449 noResponderTouches(nativeEvent);
2450 var finalTouch = isResponderTerminate
2451 ? eventTypes.responderTerminate
2452 : isResponderRelease
2453 ? eventTypes.responderRelease
2454 : null;
2455 if (finalTouch) {
2456 var finalEvent = ResponderSyntheticEvent.getPooled(
2457 finalTouch,
2458 responderInst,
2459 nativeEvent,
2460 nativeEventTarget
2461 );
2462 finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
2463 accumulateDirectDispatches(finalEvent);
2464 extracted = accumulate(extracted, finalEvent);
2465 changeResponder(null);
2466 }
2467
2468 return extracted;
2469 },
2470
2471 GlobalResponderHandler: null,
2472
2473 injection: {
2474 /**
2475 * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler
2476 * Object that handles any change in responder. Use this to inject
2477 * integration with an existing touch handling system etc.
2478 */
2479 injectGlobalResponderHandler: function(GlobalResponderHandler) {
2480 ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler;
2481 }
2482 }
2483};
2484
2485// Module provided by RN:
2486var customBubblingEventTypes =
2487 ReactNativePrivateInterface.ReactNativeViewConfigRegistry
2488 .customBubblingEventTypes;
2489var customDirectEventTypes =
2490 ReactNativePrivateInterface.ReactNativeViewConfigRegistry
2491 .customDirectEventTypes;
2492
2493var ReactNativeBridgeEventPlugin = {
2494 eventTypes: {},
2495
2496 /**
2497 * @see {EventPluginHub.extractEvents}
2498 */
2499 extractEvents: function(
2500 topLevelType,
2501 targetInst,
2502 nativeEvent,
2503 nativeEventTarget
2504 ) {
2505 if (targetInst == null) {
2506 // Probably a node belonging to another renderer's tree.
2507 return null;
2508 }
2509 var bubbleDispatchConfig = customBubblingEventTypes[topLevelType];
2510 var directDispatchConfig = customDirectEventTypes[topLevelType];
2511 (function() {
2512 if (!(bubbleDispatchConfig || directDispatchConfig)) {
2513 throw ReactError(
2514 Error(
2515 'Unsupported top level event type "' + topLevelType + '" dispatched'
2516 )
2517 );
2518 }
2519 })();
2520 var event = SyntheticEvent.getPooled(
2521 bubbleDispatchConfig || directDispatchConfig,
2522 targetInst,
2523 nativeEvent,
2524 nativeEventTarget
2525 );
2526 if (bubbleDispatchConfig) {
2527 accumulateTwoPhaseDispatches(event);
2528 } else if (directDispatchConfig) {
2529 accumulateDirectDispatches(event);
2530 } else {
2531 return null;
2532 }
2533 return event;
2534 }
2535};
2536
2537var ReactNativeEventPluginOrder = [
2538 "ResponderEventPlugin",
2539 "ReactNativeBridgeEventPlugin"
2540];
2541
2542/**
2543 * Make sure essential globals are available and are patched correctly. Please don't remove this
2544 * line. Bundles created by react-packager `require` it before executing any application code. This
2545 * ensures it exists in the dependency graph and can be `require`d.
2546 * TODO: require this in packager, not in React #10932517
2547 */
2548// Module provided by RN:
2549/**
2550 * Inject module for resolving DOM hierarchy and plugin ordering.
2551 */
2552injection.injectEventPluginOrder(ReactNativeEventPluginOrder);
2553
2554/**
2555 * Some important event plugins included by default (without having to require
2556 * them).
2557 */
2558injection.injectEventPluginsByName({
2559 ResponderEventPlugin: ResponderEventPlugin,
2560 ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin
2561});
2562
2563function getInstanceFromInstance(instanceHandle) {
2564 return instanceHandle;
2565}
2566
2567function getTagFromInstance(inst) {
2568 var tag = inst.stateNode.canonical._nativeTag;
2569 (function() {
2570 if (!tag) {
2571 throw ReactError(Error("All native instances should have a tag."));
2572 }
2573 })();
2574 return tag;
2575}
2576
2577function getFiberCurrentPropsFromNode$1(inst) {
2578 return inst.canonical.currentProps;
2579}
2580
2581// Module provided by RN:
2582var ReactFabricGlobalResponderHandler = {
2583 onChange: function(from, to, blockNativeResponder) {
2584 if (to !== null) {
2585 var tag = to.stateNode.canonical._nativeTag;
2586 ReactNativePrivateInterface.UIManager.setJSResponder(
2587 tag,
2588 blockNativeResponder
2589 );
2590 } else {
2591 ReactNativePrivateInterface.UIManager.clearJSResponder();
2592 }
2593 }
2594};
2595
2596setComponentTree(
2597 getFiberCurrentPropsFromNode$1,
2598 getInstanceFromInstance,
2599 getTagFromInstance
2600);
2601
2602ResponderEventPlugin.injection.injectGlobalResponderHandler(
2603 ReactFabricGlobalResponderHandler
2604);
2605
2606/**
2607 * `ReactInstanceMap` maintains a mapping from a public facing stateful
2608 * instance (key) and the internal representation (value). This allows public
2609 * methods to accept the user facing instance as an argument and map them back
2610 * to internal methods.
2611 *
2612 * Note that this module is currently shared and assumed to be stateless.
2613 * If this becomes an actual Map, that will break.
2614 */
2615
2616/**
2617 * This API should be called `delete` but we'd have to make sure to always
2618 * transform these to strings for IE support. When this transform is fully
2619 * supported we can rename it.
2620 */
2621
2622function get(key) {
2623 return key._reactInternalFiber;
2624}
2625
2626function set(key, value) {
2627 key._reactInternalFiber = value;
2628}
2629
2630var ReactSharedInternals =
2631 React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2632
2633// Prevent newer renderers from RTE when used with older react package versions.
2634// Current owner and dispatcher used to share the same ref,
2635// but PR #14548 split them out to better support the react-debug-tools package.
2636if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) {
2637 ReactSharedInternals.ReactCurrentDispatcher = {
2638 current: null
2639 };
2640}
2641if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) {
2642 ReactSharedInternals.ReactCurrentBatchConfig = {
2643 suspense: null
2644 };
2645}
2646
2647// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2648// nor polyfill, then a plain number is used for performance.
2649var hasSymbol = typeof Symbol === "function" && Symbol.for;
2650
2651var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 0xeac7;
2652var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 0xeaca;
2653var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 0xeacb;
2654var REACT_STRICT_MODE_TYPE = hasSymbol
2655 ? Symbol.for("react.strict_mode")
2656 : 0xeacc;
2657var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2;
2658var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd;
2659var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace;
2660// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
2661// (unstable) APIs that have been removed. Can we remove the symbols?
2662
2663var REACT_CONCURRENT_MODE_TYPE = hasSymbol
2664 ? Symbol.for("react.concurrent_mode")
2665 : 0xeacf;
2666var REACT_FORWARD_REF_TYPE = hasSymbol
2667 ? Symbol.for("react.forward_ref")
2668 : 0xead0;
2669var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1;
2670var REACT_SUSPENSE_LIST_TYPE = hasSymbol
2671 ? Symbol.for("react.suspense_list")
2672 : 0xead8;
2673var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3;
2674var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4;
2675var REACT_FUNDAMENTAL_TYPE = hasSymbol
2676 ? Symbol.for("react.fundamental")
2677 : 0xead5;
2678var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6;
2679
2680var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator;
2681var FAUX_ITERATOR_SYMBOL = "@@iterator";
2682
2683function getIteratorFn(maybeIterable) {
2684 if (maybeIterable === null || typeof maybeIterable !== "object") {
2685 return null;
2686 }
2687 var maybeIterator =
2688 (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||
2689 maybeIterable[FAUX_ITERATOR_SYMBOL];
2690 if (typeof maybeIterator === "function") {
2691 return maybeIterator;
2692 }
2693 return null;
2694}
2695
2696var Pending = 0;
2697var Resolved = 1;
2698var Rejected = 2;
2699
2700function refineResolvedLazyComponent(lazyComponent) {
2701 return lazyComponent._status === Resolved ? lazyComponent._result : null;
2702}
2703
2704function getWrappedName(outerType, innerType, wrapperName) {
2705 var functionName = innerType.displayName || innerType.name || "";
2706 return (
2707 outerType.displayName ||
2708 (functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName)
2709 );
2710}
2711
2712function getComponentName(type) {
2713 if (type == null) {
2714 // Host root, text node or just invalid type.
2715 return null;
2716 }
2717 {
2718 if (typeof type.tag === "number") {
2719 warningWithoutStack$1(
2720 false,
2721 "Received an unexpected object in getComponentName(). " +
2722 "This is likely a bug in React. Please file an issue."
2723 );
2724 }
2725 }
2726 if (typeof type === "function") {
2727 return type.displayName || type.name || null;
2728 }
2729 if (typeof type === "string") {
2730 return type;
2731 }
2732 switch (type) {
2733 case REACT_FRAGMENT_TYPE:
2734 return "Fragment";
2735 case REACT_PORTAL_TYPE:
2736 return "Portal";
2737 case REACT_PROFILER_TYPE:
2738 return "Profiler";
2739 case REACT_STRICT_MODE_TYPE:
2740 return "StrictMode";
2741 case REACT_SUSPENSE_TYPE:
2742 return "Suspense";
2743 case REACT_SUSPENSE_LIST_TYPE:
2744 return "SuspenseList";
2745 }
2746 if (typeof type === "object") {
2747 switch (type.$$typeof) {
2748 case REACT_CONTEXT_TYPE:
2749 return "Context.Consumer";
2750 case REACT_PROVIDER_TYPE:
2751 return "Context.Provider";
2752 case REACT_FORWARD_REF_TYPE:
2753 return getWrappedName(type, type.render, "ForwardRef");
2754 case REACT_MEMO_TYPE:
2755 return getComponentName(type.type);
2756 case REACT_LAZY_TYPE: {
2757 var thenable = type;
2758 var resolvedThenable = refineResolvedLazyComponent(thenable);
2759 if (resolvedThenable) {
2760 return getComponentName(resolvedThenable);
2761 }
2762 break;
2763 }
2764 }
2765 }
2766 return null;
2767}
2768
2769// Don't change these two values. They're used by React Dev Tools.
2770var NoEffect = /* */ 0;
2771var PerformedWork = /* */ 1;
2772
2773// You can change the rest (and add more).
2774var Placement = /* */ 2;
2775var Update = /* */ 4;
2776var PlacementAndUpdate = /* */ 6;
2777var Deletion = /* */ 8;
2778var ContentReset = /* */ 16;
2779var Callback = /* */ 32;
2780var DidCapture = /* */ 64;
2781var Ref = /* */ 128;
2782var Snapshot = /* */ 256;
2783var Passive = /* */ 512;
2784
2785// Passive & Update & Callback & Ref & Snapshot
2786var LifecycleEffectMask = /* */ 932;
2787
2788// Union of all host effects
2789var HostEffectMask = /* */ 1023;
2790
2791var Incomplete = /* */ 1024;
2792var ShouldCapture = /* */ 2048;
2793
2794var debugRenderPhaseSideEffects = false;
2795var debugRenderPhaseSideEffectsForStrictMode = false;
2796var enableUserTimingAPI = true;
2797var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
2798var warnAboutDeprecatedLifecycles = true;
2799var enableProfilerTimer = true;
2800var enableSchedulerTracing = true;
2801var enableSuspenseServerRenderer = false;
2802
2803var warnAboutDeprecatedSetNativeProps = false;
2804var enableFlareAPI = false;
2805var enableFundamentalAPI = false;
2806
2807var warnAboutUnmockedScheduler = false;
2808var revertPassiveEffectsChange = false;
2809var flushSuspenseFallbacksInTests = true;
2810var enableUserBlockingEvents = false;
2811var enableSuspenseCallback = false;
2812var warnAboutDefaultPropsOnFunctionComponents = false;
2813var warnAboutStringRefs = false;
2814var disableLegacyContext = false;
2815var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
2816
2817// Only used in www builds.
2818
2819var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
2820
2821var MOUNTING = 1;
2822var MOUNTED = 2;
2823var UNMOUNTED = 3;
2824
2825function isFiberMountedImpl(fiber) {
2826 var node = fiber;
2827 if (!fiber.alternate) {
2828 // If there is no alternate, this might be a new tree that isn't inserted
2829 // yet. If it is, then it will have a pending insertion effect on it.
2830 if ((node.effectTag & Placement) !== NoEffect) {
2831 return MOUNTING;
2832 }
2833 while (node.return) {
2834 node = node.return;
2835 if ((node.effectTag & Placement) !== NoEffect) {
2836 return MOUNTING;
2837 }
2838 }
2839 } else {
2840 while (node.return) {
2841 node = node.return;
2842 }
2843 }
2844 if (node.tag === HostRoot) {
2845 // TODO: Check if this was a nested HostRoot when used with
2846 // renderContainerIntoSubtree.
2847 return MOUNTED;
2848 }
2849 // If we didn't hit the root, that means that we're in an disconnected tree
2850 // that has been unmounted.
2851 return UNMOUNTED;
2852}
2853
2854function isFiberMounted(fiber) {
2855 return isFiberMountedImpl(fiber) === MOUNTED;
2856}
2857
2858function isMounted(component) {
2859 {
2860 var owner = ReactCurrentOwner$1.current;
2861 if (owner !== null && owner.tag === ClassComponent) {
2862 var ownerFiber = owner;
2863 var instance = ownerFiber.stateNode;
2864 !instance._warnedAboutRefsInRender
2865 ? warningWithoutStack$1(
2866 false,
2867 "%s is accessing isMounted inside its render() function. " +
2868 "render() should be a pure function of props and state. It should " +
2869 "never access something that requires stale data from the previous " +
2870 "render, such as refs. Move this logic to componentDidMount and " +
2871 "componentDidUpdate instead.",
2872 getComponentName(ownerFiber.type) || "A component"
2873 )
2874 : void 0;
2875 instance._warnedAboutRefsInRender = true;
2876 }
2877 }
2878
2879 var fiber = get(component);
2880 if (!fiber) {
2881 return false;
2882 }
2883 return isFiberMountedImpl(fiber) === MOUNTED;
2884}
2885
2886function assertIsMounted(fiber) {
2887 (function() {
2888 if (!(isFiberMountedImpl(fiber) === MOUNTED)) {
2889 throw ReactError(Error("Unable to find node on an unmounted component."));
2890 }
2891 })();
2892}
2893
2894function findCurrentFiberUsingSlowPath(fiber) {
2895 var alternate = fiber.alternate;
2896 if (!alternate) {
2897 // If there is no alternate, then we only need to check if it is mounted.
2898 var state = isFiberMountedImpl(fiber);
2899 (function() {
2900 if (!(state !== UNMOUNTED)) {
2901 throw ReactError(
2902 Error("Unable to find node on an unmounted component.")
2903 );
2904 }
2905 })();
2906 if (state === MOUNTING) {
2907 return null;
2908 }
2909 return fiber;
2910 }
2911 // If we have two possible branches, we'll walk backwards up to the root
2912 // to see what path the root points to. On the way we may hit one of the
2913 // special cases and we'll deal with them.
2914 var a = fiber;
2915 var b = alternate;
2916 while (true) {
2917 var parentA = a.return;
2918 if (parentA === null) {
2919 // We're at the root.
2920 break;
2921 }
2922 var parentB = parentA.alternate;
2923 if (parentB === null) {
2924 // There is no alternate. This is an unusual case. Currently, it only
2925 // happens when a Suspense component is hidden. An extra fragment fiber
2926 // is inserted in between the Suspense fiber and its children. Skip
2927 // over this extra fragment fiber and proceed to the next parent.
2928 var nextParent = parentA.return;
2929 if (nextParent !== null) {
2930 a = b = nextParent;
2931 continue;
2932 }
2933 // If there's no parent, we're at the root.
2934 break;
2935 }
2936
2937 // If both copies of the parent fiber point to the same child, we can
2938 // assume that the child is current. This happens when we bailout on low
2939 // priority: the bailed out fiber's child reuses the current child.
2940 if (parentA.child === parentB.child) {
2941 var child = parentA.child;
2942 while (child) {
2943 if (child === a) {
2944 // We've determined that A is the current branch.
2945 assertIsMounted(parentA);
2946 return fiber;
2947 }
2948 if (child === b) {
2949 // We've determined that B is the current branch.
2950 assertIsMounted(parentA);
2951 return alternate;
2952 }
2953 child = child.sibling;
2954 }
2955 // We should never have an alternate for any mounting node. So the only
2956 // way this could possibly happen is if this was unmounted, if at all.
2957 (function() {
2958 {
2959 throw ReactError(
2960 Error("Unable to find node on an unmounted component.")
2961 );
2962 }
2963 })();
2964 }
2965
2966 if (a.return !== b.return) {
2967 // The return pointer of A and the return pointer of B point to different
2968 // fibers. We assume that return pointers never criss-cross, so A must
2969 // belong to the child set of A.return, and B must belong to the child
2970 // set of B.return.
2971 a = parentA;
2972 b = parentB;
2973 } else {
2974 // The return pointers point to the same fiber. We'll have to use the
2975 // default, slow path: scan the child sets of each parent alternate to see
2976 // which child belongs to which set.
2977 //
2978 // Search parent A's child set
2979 var didFindChild = false;
2980 var _child = parentA.child;
2981 while (_child) {
2982 if (_child === a) {
2983 didFindChild = true;
2984 a = parentA;
2985 b = parentB;
2986 break;
2987 }
2988 if (_child === b) {
2989 didFindChild = true;
2990 b = parentA;
2991 a = parentB;
2992 break;
2993 }
2994 _child = _child.sibling;
2995 }
2996 if (!didFindChild) {
2997 // Search parent B's child set
2998 _child = parentB.child;
2999 while (_child) {
3000 if (_child === a) {
3001 didFindChild = true;
3002 a = parentB;
3003 b = parentA;
3004 break;
3005 }
3006 if (_child === b) {
3007 didFindChild = true;
3008 b = parentB;
3009 a = parentA;
3010 break;
3011 }
3012 _child = _child.sibling;
3013 }
3014 (function() {
3015 if (!didFindChild) {
3016 throw ReactError(
3017 Error(
3018 "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue."
3019 )
3020 );
3021 }
3022 })();
3023 }
3024 }
3025
3026 (function() {
3027 if (!(a.alternate === b)) {
3028 throw ReactError(
3029 Error(
3030 "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue."
3031 )
3032 );
3033 }
3034 })();
3035 }
3036 // If the root is not a host container, we're in a disconnected tree. I.e.
3037 // unmounted.
3038 (function() {
3039 if (!(a.tag === HostRoot)) {
3040 throw ReactError(Error("Unable to find node on an unmounted component."));
3041 }
3042 })();
3043 if (a.stateNode.current === a) {
3044 // We've determined that A is the current branch.
3045 return fiber;
3046 }
3047 // Otherwise B has to be current branch.
3048 return alternate;
3049}
3050
3051function findCurrentHostFiber(parent) {
3052 var currentParent = findCurrentFiberUsingSlowPath(parent);
3053 if (!currentParent) {
3054 return null;
3055 }
3056
3057 // Next we'll drill down this component to find the first HostComponent/Text.
3058 var node = currentParent;
3059 while (true) {
3060 if (node.tag === HostComponent || node.tag === HostText) {
3061 return node;
3062 } else if (node.child) {
3063 node.child.return = node;
3064 node = node.child;
3065 continue;
3066 }
3067 if (node === currentParent) {
3068 return null;
3069 }
3070 while (!node.sibling) {
3071 if (!node.return || node.return === currentParent) {
3072 return null;
3073 }
3074 node = node.return;
3075 }
3076 node.sibling.return = node.return;
3077 node = node.sibling;
3078 }
3079 // Flow needs the return null here, but ESLint complains about it.
3080 // eslint-disable-next-line no-unreachable
3081 return null;
3082}
3083
3084/**
3085 * In the future, we should cleanup callbacks by cancelling them instead of
3086 * using this.
3087 */
3088function mountSafeCallback_NOT_REALLY_SAFE(context, callback) {
3089 return function() {
3090 if (!callback) {
3091 return undefined;
3092 }
3093 // This protects against createClass() components.
3094 // We don't know if there is code depending on it.
3095 // We intentionally don't use isMounted() because even accessing
3096 // isMounted property on a React ES6 class will trigger a warning.
3097 if (typeof context.__isMounted === "boolean") {
3098 if (!context.__isMounted) {
3099 return undefined;
3100 }
3101 }
3102
3103 // FIXME: there used to be other branches that protected
3104 // against unmounted host components. But RN host components don't
3105 // define isMounted() anymore, so those checks didn't do anything.
3106
3107 // They caused false positive warning noise so we removed them:
3108 // https://github.com/facebook/react-native/issues/18868#issuecomment-413579095
3109
3110 // However, this means that the callback is NOT guaranteed to be safe
3111 // for host components. The solution we should implement is to make
3112 // UIManager.measure() and similar calls truly cancelable. Then we
3113 // can change our own code calling them to cancel when something unmounts.
3114
3115 return callback.apply(context, arguments);
3116 };
3117}
3118
3119function throwOnStylesProp(component, props) {
3120 if (props.styles !== undefined) {
3121 var owner = component._owner || null;
3122 var name = component.constructor.displayName;
3123 var msg =
3124 "`styles` is not a supported property of `" +
3125 name +
3126 "`, did " +
3127 "you mean `style` (singular)?";
3128 if (owner && owner.constructor && owner.constructor.displayName) {
3129 msg +=
3130 "\n\nCheck the `" +
3131 owner.constructor.displayName +
3132 "` parent " +
3133 " component.";
3134 }
3135 throw new Error(msg);
3136 }
3137}
3138
3139function warnForStyleProps(props, validAttributes) {
3140 for (var key in validAttributes.style) {
3141 if (!(validAttributes[key] || props[key] === undefined)) {
3142 console.error(
3143 "You are setting the style `{ " +
3144 key +
3145 ": ... }` as a prop. You " +
3146 "should nest it in a style object. " +
3147 "E.g. `{ style: { " +
3148 key +
3149 ": ... } }`"
3150 );
3151 }
3152 }
3153}
3154
3155// Modules provided by RN:
3156var emptyObject = {};
3157
3158/**
3159 * Create a payload that contains all the updates between two sets of props.
3160 *
3161 * These helpers are all encapsulated into a single module, because they use
3162 * mutation as a performance optimization which leads to subtle shared
3163 * dependencies between the code paths. To avoid this mutable state leaking
3164 * across modules, I've kept them isolated to this module.
3165 */
3166
3167// Tracks removed keys
3168var removedKeys = null;
3169var removedKeyCount = 0;
3170
3171function defaultDiffer(prevProp, nextProp) {
3172 if (typeof nextProp !== "object" || nextProp === null) {
3173 // Scalars have already been checked for equality
3174 return true;
3175 } else {
3176 // For objects and arrays, the default diffing algorithm is a deep compare
3177 return ReactNativePrivateInterface.deepDiffer(prevProp, nextProp);
3178 }
3179}
3180
3181function restoreDeletedValuesInNestedArray(
3182 updatePayload,
3183 node,
3184 validAttributes
3185) {
3186 if (Array.isArray(node)) {
3187 var i = node.length;
3188 while (i-- && removedKeyCount > 0) {
3189 restoreDeletedValuesInNestedArray(
3190 updatePayload,
3191 node[i],
3192 validAttributes
3193 );
3194 }
3195 } else if (node && removedKeyCount > 0) {
3196 var obj = node;
3197 for (var propKey in removedKeys) {
3198 if (!removedKeys[propKey]) {
3199 continue;
3200 }
3201 var nextProp = obj[propKey];
3202 if (nextProp === undefined) {
3203 continue;
3204 }
3205
3206 var attributeConfig = validAttributes[propKey];
3207 if (!attributeConfig) {
3208 continue; // not a valid native prop
3209 }
3210
3211 if (typeof nextProp === "function") {
3212 nextProp = true;
3213 }
3214 if (typeof nextProp === "undefined") {
3215 nextProp = null;
3216 }
3217
3218 if (typeof attributeConfig !== "object") {
3219 // case: !Object is the default case
3220 updatePayload[propKey] = nextProp;
3221 } else if (
3222 typeof attributeConfig.diff === "function" ||
3223 typeof attributeConfig.process === "function"
3224 ) {
3225 // case: CustomAttributeConfiguration
3226 var nextValue =
3227 typeof attributeConfig.process === "function"
3228 ? attributeConfig.process(nextProp)
3229 : nextProp;
3230 updatePayload[propKey] = nextValue;
3231 }
3232 removedKeys[propKey] = false;
3233 removedKeyCount--;
3234 }
3235 }
3236}
3237
3238function diffNestedArrayProperty(
3239 updatePayload,
3240 prevArray,
3241 nextArray,
3242 validAttributes
3243) {
3244 var minLength =
3245 prevArray.length < nextArray.length ? prevArray.length : nextArray.length;
3246 var i = void 0;
3247 for (i = 0; i < minLength; i++) {
3248 // Diff any items in the array in the forward direction. Repeated keys
3249 // will be overwritten by later values.
3250 updatePayload = diffNestedProperty(
3251 updatePayload,
3252 prevArray[i],
3253 nextArray[i],
3254 validAttributes
3255 );
3256 }
3257 for (; i < prevArray.length; i++) {
3258 // Clear out all remaining properties.
3259 updatePayload = clearNestedProperty(
3260 updatePayload,
3261 prevArray[i],
3262 validAttributes
3263 );
3264 }
3265 for (; i < nextArray.length; i++) {
3266 // Add all remaining properties.
3267 updatePayload = addNestedProperty(
3268 updatePayload,
3269 nextArray[i],
3270 validAttributes
3271 );
3272 }
3273 return updatePayload;
3274}
3275
3276function diffNestedProperty(
3277 updatePayload,
3278 prevProp,
3279 nextProp,
3280 validAttributes
3281) {
3282 if (!updatePayload && prevProp === nextProp) {
3283 // If no properties have been added, then we can bail out quickly on object
3284 // equality.
3285 return updatePayload;
3286 }
3287
3288 if (!prevProp || !nextProp) {
3289 if (nextProp) {
3290 return addNestedProperty(updatePayload, nextProp, validAttributes);
3291 }
3292 if (prevProp) {
3293 return clearNestedProperty(updatePayload, prevProp, validAttributes);
3294 }
3295 return updatePayload;
3296 }
3297
3298 if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) {
3299 // Both are leaves, we can diff the leaves.
3300 return diffProperties(updatePayload, prevProp, nextProp, validAttributes);
3301 }
3302
3303 if (Array.isArray(prevProp) && Array.isArray(nextProp)) {
3304 // Both are arrays, we can diff the arrays.
3305 return diffNestedArrayProperty(
3306 updatePayload,
3307 prevProp,
3308 nextProp,
3309 validAttributes
3310 );
3311 }
3312
3313 if (Array.isArray(prevProp)) {
3314 return diffProperties(
3315 updatePayload,
3316 // $FlowFixMe - We know that this is always an object when the input is.
3317 ReactNativePrivateInterface.flattenStyle(prevProp),
3318 // $FlowFixMe - We know that this isn't an array because of above flow.
3319 nextProp,
3320 validAttributes
3321 );
3322 }
3323
3324 return diffProperties(
3325 updatePayload,
3326 prevProp,
3327 // $FlowFixMe - We know that this is always an object when the input is.
3328 ReactNativePrivateInterface.flattenStyle(nextProp),
3329 validAttributes
3330 );
3331}
3332
3333/**
3334 * addNestedProperty takes a single set of props and valid attribute
3335 * attribute configurations. It processes each prop and adds it to the
3336 * updatePayload.
3337 */
3338function addNestedProperty(updatePayload, nextProp, validAttributes) {
3339 if (!nextProp) {
3340 return updatePayload;
3341 }
3342
3343 if (!Array.isArray(nextProp)) {
3344 // Add each property of the leaf.
3345 return addProperties(updatePayload, nextProp, validAttributes);
3346 }
3347
3348 for (var i = 0; i < nextProp.length; i++) {
3349 // Add all the properties of the array.
3350 updatePayload = addNestedProperty(
3351 updatePayload,
3352 nextProp[i],
3353 validAttributes
3354 );
3355 }
3356
3357 return updatePayload;
3358}
3359
3360/**
3361 * clearNestedProperty takes a single set of props and valid attributes. It
3362 * adds a null sentinel to the updatePayload, for each prop key.
3363 */
3364function clearNestedProperty(updatePayload, prevProp, validAttributes) {
3365 if (!prevProp) {
3366 return updatePayload;
3367 }
3368
3369 if (!Array.isArray(prevProp)) {
3370 // Add each property of the leaf.
3371 return clearProperties(updatePayload, prevProp, validAttributes);
3372 }
3373
3374 for (var i = 0; i < prevProp.length; i++) {
3375 // Add all the properties of the array.
3376 updatePayload = clearNestedProperty(
3377 updatePayload,
3378 prevProp[i],
3379 validAttributes
3380 );
3381 }
3382 return updatePayload;
3383}
3384
3385/**
3386 * diffProperties takes two sets of props and a set of valid attributes
3387 * and write to updatePayload the values that changed or were deleted.
3388 * If no updatePayload is provided, a new one is created and returned if
3389 * anything changed.
3390 */
3391function diffProperties(updatePayload, prevProps, nextProps, validAttributes) {
3392 var attributeConfig = void 0;
3393 var nextProp = void 0;
3394 var prevProp = void 0;
3395
3396 for (var propKey in nextProps) {
3397 attributeConfig = validAttributes[propKey];
3398 if (!attributeConfig) {
3399 continue; // not a valid native prop
3400 }
3401
3402 prevProp = prevProps[propKey];
3403 nextProp = nextProps[propKey];
3404
3405 // functions are converted to booleans as markers that the associated
3406 // events should be sent from native.
3407 if (typeof nextProp === "function") {
3408 nextProp = true;
3409 // If nextProp is not a function, then don't bother changing prevProp
3410 // since nextProp will win and go into the updatePayload regardless.
3411 if (typeof prevProp === "function") {
3412 prevProp = true;
3413 }
3414 }
3415
3416 // An explicit value of undefined is treated as a null because it overrides
3417 // any other preceding value.
3418 if (typeof nextProp === "undefined") {
3419 nextProp = null;
3420 if (typeof prevProp === "undefined") {
3421 prevProp = null;
3422 }
3423 }
3424
3425 if (removedKeys) {
3426 removedKeys[propKey] = false;
3427 }
3428
3429 if (updatePayload && updatePayload[propKey] !== undefined) {
3430 // Something else already triggered an update to this key because another
3431 // value diffed. Since we're now later in the nested arrays our value is
3432 // more important so we need to calculate it and override the existing
3433 // value. It doesn't matter if nothing changed, we'll set it anyway.
3434
3435 // Pattern match on: attributeConfig
3436 if (typeof attributeConfig !== "object") {
3437 // case: !Object is the default case
3438 updatePayload[propKey] = nextProp;
3439 } else if (
3440 typeof attributeConfig.diff === "function" ||
3441 typeof attributeConfig.process === "function"
3442 ) {
3443 // case: CustomAttributeConfiguration
3444 var nextValue =
3445 typeof attributeConfig.process === "function"
3446 ? attributeConfig.process(nextProp)
3447 : nextProp;
3448 updatePayload[propKey] = nextValue;
3449 }
3450 continue;
3451 }
3452
3453 if (prevProp === nextProp) {
3454 continue; // nothing changed
3455 }
3456
3457 // Pattern match on: attributeConfig
3458 if (typeof attributeConfig !== "object") {
3459 // case: !Object is the default case
3460 if (defaultDiffer(prevProp, nextProp)) {
3461 // a normal leaf has changed
3462 (updatePayload || (updatePayload = {}))[propKey] = nextProp;
3463 }
3464 } else if (
3465 typeof attributeConfig.diff === "function" ||
3466 typeof attributeConfig.process === "function"
3467 ) {
3468 // case: CustomAttributeConfiguration
3469 var shouldUpdate =
3470 prevProp === undefined ||
3471 (typeof attributeConfig.diff === "function"
3472 ? attributeConfig.diff(prevProp, nextProp)
3473 : defaultDiffer(prevProp, nextProp));
3474 if (shouldUpdate) {
3475 var _nextValue =
3476 typeof attributeConfig.process === "function"
3477 ? attributeConfig.process(nextProp)
3478 : nextProp;
3479 (updatePayload || (updatePayload = {}))[propKey] = _nextValue;
3480 }
3481 } else {
3482 // default: fallthrough case when nested properties are defined
3483 removedKeys = null;
3484 removedKeyCount = 0;
3485 // We think that attributeConfig is not CustomAttributeConfiguration at
3486 // this point so we assume it must be AttributeConfiguration.
3487 updatePayload = diffNestedProperty(
3488 updatePayload,
3489 prevProp,
3490 nextProp,
3491 attributeConfig
3492 );
3493 if (removedKeyCount > 0 && updatePayload) {
3494 restoreDeletedValuesInNestedArray(
3495 updatePayload,
3496 nextProp,
3497 attributeConfig
3498 );
3499 removedKeys = null;
3500 }
3501 }
3502 }
3503
3504 // Also iterate through all the previous props to catch any that have been
3505 // removed and make sure native gets the signal so it can reset them to the
3506 // default.
3507 for (var _propKey in prevProps) {
3508 if (nextProps[_propKey] !== undefined) {
3509 continue; // we've already covered this key in the previous pass
3510 }
3511 attributeConfig = validAttributes[_propKey];
3512 if (!attributeConfig) {
3513 continue; // not a valid native prop
3514 }
3515
3516 if (updatePayload && updatePayload[_propKey] !== undefined) {
3517 // This was already updated to a diff result earlier.
3518 continue;
3519 }
3520
3521 prevProp = prevProps[_propKey];
3522 if (prevProp === undefined) {
3523 continue; // was already empty anyway
3524 }
3525 // Pattern match on: attributeConfig
3526 if (
3527 typeof attributeConfig !== "object" ||
3528 typeof attributeConfig.diff === "function" ||
3529 typeof attributeConfig.process === "function"
3530 ) {
3531 // case: CustomAttributeConfiguration | !Object
3532 // Flag the leaf property for removal by sending a sentinel.
3533 (updatePayload || (updatePayload = {}))[_propKey] = null;
3534 if (!removedKeys) {
3535 removedKeys = {};
3536 }
3537 if (!removedKeys[_propKey]) {
3538 removedKeys[_propKey] = true;
3539 removedKeyCount++;
3540 }
3541 } else {
3542 // default:
3543 // This is a nested attribute configuration where all the properties
3544 // were removed so we need to go through and clear out all of them.
3545 updatePayload = clearNestedProperty(
3546 updatePayload,
3547 prevProp,
3548 attributeConfig
3549 );
3550 }
3551 }
3552 return updatePayload;
3553}
3554
3555/**
3556 * addProperties adds all the valid props to the payload after being processed.
3557 */
3558function addProperties(updatePayload, props, validAttributes) {
3559 // TODO: Fast path
3560 return diffProperties(updatePayload, emptyObject, props, validAttributes);
3561}
3562
3563/**
3564 * clearProperties clears all the previous props by adding a null sentinel
3565 * to the payload for each valid key.
3566 */
3567function clearProperties(updatePayload, prevProps, validAttributes) {
3568 // TODO: Fast path
3569 return diffProperties(updatePayload, prevProps, emptyObject, validAttributes);
3570}
3571
3572function create(props, validAttributes) {
3573 return addProperties(
3574 null, // updatePayload
3575 props,
3576 validAttributes
3577 );
3578}
3579
3580function diff(prevProps, nextProps, validAttributes) {
3581 return diffProperties(
3582 null, // updatePayload
3583 prevProps,
3584 nextProps,
3585 validAttributes
3586 );
3587}
3588
3589// Use to restore controlled state after a change event has fired.
3590
3591var restoreImpl = null;
3592var restoreTarget = null;
3593var restoreQueue = null;
3594
3595function restoreStateOfTarget(target) {
3596 // We perform this translation at the end of the event loop so that we
3597 // always receive the correct fiber here
3598 var internalInstance = getInstanceFromNode(target);
3599 if (!internalInstance) {
3600 // Unmounted
3601 return;
3602 }
3603 (function() {
3604 if (!(typeof restoreImpl === "function")) {
3605 throw ReactError(
3606 Error(
3607 "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue."
3608 )
3609 );
3610 }
3611 })();
3612 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
3613 restoreImpl(internalInstance.stateNode, internalInstance.type, props);
3614}
3615
3616function needsStateRestore() {
3617 return restoreTarget !== null || restoreQueue !== null;
3618}
3619
3620function restoreStateIfNeeded() {
3621 if (!restoreTarget) {
3622 return;
3623 }
3624 var target = restoreTarget;
3625 var queuedTargets = restoreQueue;
3626 restoreTarget = null;
3627 restoreQueue = null;
3628
3629 restoreStateOfTarget(target);
3630 if (queuedTargets) {
3631 for (var i = 0; i < queuedTargets.length; i++) {
3632 restoreStateOfTarget(queuedTargets[i]);
3633 }
3634 }
3635}
3636
3637// Used as a way to call batchedUpdates when we don't have a reference to
3638// the renderer. Such as when we're dispatching events or if third party
3639// libraries need to call batchedUpdates. Eventually, this API will go away when
3640// everything is batched by default. We'll then have a similar API to opt-out of
3641// scheduled work and instead do synchronous work.
3642
3643// Defaults
3644var batchedUpdatesImpl = function(fn, bookkeeping) {
3645 return fn(bookkeeping);
3646};
3647var discreteUpdatesImpl = function(fn, a, b, c) {
3648 return fn(a, b, c);
3649};
3650var flushDiscreteUpdatesImpl = function() {};
3651var batchedEventUpdatesImpl = batchedUpdatesImpl;
3652
3653var isInsideEventHandler = false;
3654
3655function finishEventHandler() {
3656 // Here we wait until all updates have propagated, which is important
3657 // when using controlled components within layers:
3658 // https://github.com/facebook/react/issues/1698
3659 // Then we restore state of any controlled component.
3660 var controlledComponentsHavePendingUpdates = needsStateRestore();
3661 if (controlledComponentsHavePendingUpdates) {
3662 // If a controlled event was fired, we may need to restore the state of
3663 // the DOM node back to the controlled value. This is necessary when React
3664 // bails out of the update without touching the DOM.
3665 flushDiscreteUpdatesImpl();
3666 restoreStateIfNeeded();
3667 }
3668}
3669
3670function batchedUpdates(fn, bookkeeping) {
3671 if (isInsideEventHandler) {
3672 // If we are currently inside another batch, we need to wait until it
3673 // fully completes before restoring state.
3674 return fn(bookkeeping);
3675 }
3676 isInsideEventHandler = true;
3677 try {
3678 return batchedUpdatesImpl(fn, bookkeeping);
3679 } finally {
3680 isInsideEventHandler = false;
3681 finishEventHandler();
3682 }
3683}
3684
3685function batchedEventUpdates(fn, a, b) {
3686 if (isInsideEventHandler) {
3687 // If we are currently inside another batch, we need to wait until it
3688 // fully completes before restoring state.
3689 return fn(a, b);
3690 }
3691 isInsideEventHandler = true;
3692 try {
3693 return batchedEventUpdatesImpl(fn, a, b);
3694 } finally {
3695 isInsideEventHandler = false;
3696 finishEventHandler();
3697 }
3698}
3699
3700function discreteUpdates(fn, a, b, c) {
3701 var prevIsInsideEventHandler = isInsideEventHandler;
3702 isInsideEventHandler = true;
3703 try {
3704 return discreteUpdatesImpl(fn, a, b, c);
3705 } finally {
3706 isInsideEventHandler = prevIsInsideEventHandler;
3707 if (!isInsideEventHandler) {
3708 finishEventHandler();
3709 }
3710 }
3711}
3712
3713var lastFlushedEventTimeStamp = 0;
3714function flushDiscreteUpdatesIfNeeded(timeStamp) {
3715 // event.timeStamp isn't overly reliable due to inconsistencies in
3716 // how different browsers have historically provided the time stamp.
3717 // Some browsers provide high-resolution time stamps for all events,
3718 // some provide low-resolution time stamps for all events. FF < 52
3719 // even mixes both time stamps together. Some browsers even report
3720 // negative time stamps or time stamps that are 0 (iOS9) in some cases.
3721 // Given we are only comparing two time stamps with equality (!==),
3722 // we are safe from the resolution differences. If the time stamp is 0
3723 // we bail-out of preventing the flush, which can affect semantics,
3724 // such as if an earlier flush removes or adds event listeners that
3725 // are fired in the subsequent flush. However, this is the same
3726 // behaviour as we had before this change, so the risks are low.
3727 if (
3728 !isInsideEventHandler &&
3729 (!enableFlareAPI ||
3730 timeStamp === 0 ||
3731 lastFlushedEventTimeStamp !== timeStamp)
3732 ) {
3733 lastFlushedEventTimeStamp = timeStamp;
3734 flushDiscreteUpdatesImpl();
3735 }
3736}
3737
3738function setBatchingImplementation(
3739 _batchedUpdatesImpl,
3740 _discreteUpdatesImpl,
3741 _flushDiscreteUpdatesImpl,
3742 _batchedEventUpdatesImpl
3743) {
3744 batchedUpdatesImpl = _batchedUpdatesImpl;
3745 discreteUpdatesImpl = _discreteUpdatesImpl;
3746 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
3747 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
3748}
3749
3750function _classCallCheck$1(instance, Constructor) {
3751 if (!(instance instanceof Constructor)) {
3752 throw new TypeError("Cannot call a class as a function");
3753 }
3754}
3755
3756function _possibleConstructorReturn(self, call) {
3757 if (!self) {
3758 throw new ReferenceError(
3759 "this hasn't been initialised - super() hasn't been called"
3760 );
3761 }
3762 return call && (typeof call === "object" || typeof call === "function")
3763 ? call
3764 : self;
3765}
3766
3767function _inherits(subClass, superClass) {
3768 if (typeof superClass !== "function" && superClass !== null) {
3769 throw new TypeError(
3770 "Super expression must either be null or a function, not " +
3771 typeof superClass
3772 );
3773 }
3774 subClass.prototype = Object.create(superClass && superClass.prototype, {
3775 constructor: {
3776 value: subClass,
3777 enumerable: false,
3778 writable: true,
3779 configurable: true
3780 }
3781 });
3782 if (superClass)
3783 Object.setPrototypeOf
3784 ? Object.setPrototypeOf(subClass, superClass)
3785 : (subClass.__proto__ = superClass);
3786}
3787
3788/**
3789 * Class only exists for its Flow type.
3790 */
3791var ReactNativeComponent = (function(_React$Component) {
3792 _inherits(ReactNativeComponent, _React$Component);
3793
3794 function ReactNativeComponent() {
3795 _classCallCheck$1(this, ReactNativeComponent);
3796
3797 return _possibleConstructorReturn(
3798 this,
3799 _React$Component.apply(this, arguments)
3800 );
3801 }
3802
3803 ReactNativeComponent.prototype.blur = function blur() {};
3804
3805 ReactNativeComponent.prototype.focus = function focus() {};
3806
3807 ReactNativeComponent.prototype.measure = function measure(callback) {};
3808
3809 ReactNativeComponent.prototype.measureInWindow = function measureInWindow(
3810 callback
3811 ) {};
3812
3813 ReactNativeComponent.prototype.measureLayout = function measureLayout(
3814 relativeToNativeNode,
3815 onSuccess,
3816 onFail
3817 ) {};
3818
3819 ReactNativeComponent.prototype.setNativeProps = function setNativeProps(
3820 nativeProps
3821 ) {};
3822
3823 return ReactNativeComponent;
3824})(React.Component);
3825
3826/**
3827 * This type keeps ReactNativeFiberHostComponent and NativeMethodsMixin in sync.
3828 * It can also provide types for ReactNative applications that use NMM or refs.
3829 */
3830
3831/**
3832 * Flat ReactNative renderer bundles are too big for Flow to parse efficiently.
3833 * Provide minimal Flow typing for the high-level RN API and call it a day.
3834 */
3835
3836var DiscreteEvent = 0;
3837var UserBlockingEvent = 1;
3838var ContinuousEvent = 2;
3839
3840/**
3841 * Similar to invariant but only logs a warning if the condition is not met.
3842 * This can be used to log issues in development environments in critical
3843 * paths. Removing the logging code for production environments will keep the
3844 * same logic and follow the same code paths.
3845 */
3846
3847var warning = warningWithoutStack$1;
3848
3849{
3850 warning = function(condition, format) {
3851 if (condition) {
3852 return;
3853 }
3854 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
3855 var stack = ReactDebugCurrentFrame.getStackAddendum();
3856 // eslint-disable-next-line react-internal/warning-and-invariant-args
3857
3858 for (
3859 var _len = arguments.length,
3860 args = Array(_len > 2 ? _len - 2 : 0),
3861 _key = 2;
3862 _key < _len;
3863 _key++
3864 ) {
3865 args[_key - 2] = arguments[_key];
3866 }
3867
3868 warningWithoutStack$1.apply(
3869 undefined,
3870 [false, format + "%s"].concat(args, [stack])
3871 );
3872 };
3873}
3874
3875var warning$1 = warning;
3876
3877// Intentionally not named imports because Rollup would use dynamic dispatch for
3878// CommonJS interop named imports.
3879var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
3880var runWithPriority = Scheduler.unstable_runWithPriority;
3881var _nativeFabricUIManage$2 = nativeFabricUIManager;
3882var measureInWindow = _nativeFabricUIManage$2.measureInWindow;
3883
3884var activeTimeouts = new Map();
3885var rootEventTypesToEventResponderInstances = new Map();
3886var ownershipChangeListeners = new Set();
3887
3888var globalOwner = null;
3889
3890var currentTimeStamp = 0;
3891var currentTimers = new Map();
3892var currentInstance = null;
3893var currentEventQueue = null;
3894var currentEventQueuePriority = ContinuousEvent;
3895var currentTimerIDCounter = 0;
3896
3897var eventResponderContext = {
3898 dispatchEvent: function(eventValue, eventListener, eventPriority) {
3899 validateResponderContext();
3900 validateEventValue(eventValue);
3901 if (eventPriority < currentEventQueuePriority) {
3902 currentEventQueuePriority = eventPriority;
3903 }
3904 currentEventQueue.push(createEventQueueItem(eventValue, eventListener));
3905 },
3906 isTargetWithinNode: function(childTarget, parentTarget) {
3907 validateResponderContext();
3908 var childFiber = getFiberFromTarget(childTarget);
3909 var parentFiber = getFiberFromTarget(parentTarget);
3910
3911 var node = childFiber;
3912 while (node !== null) {
3913 if (node === parentFiber) {
3914 return true;
3915 }
3916 node = node.return;
3917 }
3918 return false;
3919 },
3920 getTargetBoundingRect: function(target, callback) {
3921 measureInWindow(target.node, function(x, y, width, height) {
3922 callback({
3923 left: x,
3924 right: x + width,
3925 top: y,
3926 bottom: y + height
3927 });
3928 });
3929 },
3930 addRootEventTypes: function(rootEventTypes) {
3931 validateResponderContext();
3932 for (var i = 0; i < rootEventTypes.length; i++) {
3933 var rootEventType = rootEventTypes[i];
3934 var eventResponderInstance = currentInstance;
3935 registerRootEventType(rootEventType, eventResponderInstance);
3936 }
3937 },
3938 removeRootEventTypes: function(rootEventTypes) {
3939 validateResponderContext();
3940 for (var i = 0; i < rootEventTypes.length; i++) {
3941 var rootEventType = rootEventTypes[i];
3942
3943 var rootEventResponders = rootEventTypesToEventResponderInstances.get(
3944 rootEventType
3945 );
3946 var rootEventTypesSet = currentInstance.rootEventTypes;
3947 if (rootEventTypesSet !== null) {
3948 rootEventTypesSet.delete(rootEventType);
3949 }
3950 if (rootEventResponders !== undefined) {
3951 rootEventResponders.delete(currentInstance);
3952 }
3953 }
3954 },
3955 setTimeout: function(func, delay) {
3956 validateResponderContext();
3957 if (currentTimers === null) {
3958 currentTimers = new Map();
3959 }
3960 var timeout = currentTimers.get(delay);
3961
3962 var timerId = currentTimerIDCounter++;
3963 if (timeout === undefined) {
3964 var _timers = new Map();
3965 var _id = setTimeout(function() {
3966 processTimers(_timers, delay);
3967 }, delay);
3968 timeout = {
3969 id: _id,
3970 timers: _timers
3971 };
3972 currentTimers.set(delay, timeout);
3973 }
3974 timeout.timers.set(timerId, {
3975 instance: currentInstance,
3976 func: func,
3977 id: timerId,
3978 timeStamp: currentTimeStamp
3979 });
3980 activeTimeouts.set(timerId, timeout);
3981 return timerId;
3982 },
3983 clearTimeout: function(timerId) {
3984 validateResponderContext();
3985 var timeout = activeTimeouts.get(timerId);
3986
3987 if (timeout !== undefined) {
3988 var _timers2 = timeout.timers;
3989 _timers2.delete(timerId);
3990 if (_timers2.size === 0) {
3991 clearTimeout(timeout.id);
3992 }
3993 }
3994 },
3995 getTimeStamp: function() {
3996 validateResponderContext();
3997 return currentTimeStamp;
3998 }
3999};
4000
4001function createEventQueueItem(value, listener) {
4002 return {
4003 value: value,
4004 listener: listener
4005 };
4006}
4007
4008function validateEventValue(eventValue) {
4009 if (typeof eventValue === "object" && eventValue !== null) {
4010 var target = eventValue.target,
4011 type = eventValue.type,
4012 _timeStamp = eventValue.timeStamp;
4013
4014 if (target == null || type == null || _timeStamp == null) {
4015 throw new Error(
4016 'context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.'
4017 );
4018 }
4019 var showWarning = function(name) {
4020 {
4021 warning$1(
4022 false,
4023 "%s is not available on event objects created from event responder modules (React Flare). " +
4024 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`',
4025 name,
4026 name
4027 );
4028 }
4029 };
4030 eventValue.preventDefault = function() {
4031 {
4032 showWarning("preventDefault()");
4033 }
4034 };
4035 eventValue.stopPropagation = function() {
4036 {
4037 showWarning("stopPropagation()");
4038 }
4039 };
4040 eventValue.isDefaultPrevented = function() {
4041 {
4042 showWarning("isDefaultPrevented()");
4043 }
4044 };
4045 eventValue.isPropagationStopped = function() {
4046 {
4047 showWarning("isPropagationStopped()");
4048 }
4049 };
4050 // $FlowFixMe: we don't need value, Flow thinks we do
4051 Object.defineProperty(eventValue, "nativeEvent", {
4052 get: function() {
4053 {
4054 showWarning("nativeEvent");
4055 }
4056 }
4057 });
4058 }
4059}
4060
4061function getFiberFromTarget(target) {
4062 if (target === null) {
4063 return null;
4064 }
4065 return target.canonical._internalInstanceHandle || null;
4066}
4067
4068function processTimers(timers, delay) {
4069 var timersArr = Array.from(timers.values());
4070 currentEventQueuePriority = ContinuousEvent;
4071 try {
4072 for (var i = 0; i < timersArr.length; i++) {
4073 var _timersArr$i = timersArr[i],
4074 _instance = _timersArr$i.instance,
4075 _func = _timersArr$i.func,
4076 _id2 = _timersArr$i.id,
4077 _timeStamp2 = _timersArr$i.timeStamp;
4078
4079 currentInstance = _instance;
4080 currentEventQueue = [];
4081 currentTimeStamp = _timeStamp2 + delay;
4082 try {
4083 _func();
4084 } finally {
4085 activeTimeouts.delete(_id2);
4086 }
4087 }
4088 processEventQueue();
4089 } finally {
4090 currentTimers = null;
4091 currentInstance = null;
4092 currentEventQueue = null;
4093 currentTimeStamp = 0;
4094 }
4095}
4096
4097function createFabricResponderEvent(topLevelType, nativeEvent, target) {
4098 return {
4099 nativeEvent: nativeEvent,
4100 responderTarget: target,
4101 target: target,
4102 type: topLevelType
4103 };
4104}
4105
4106function validateResponderContext() {
4107 (function() {
4108 if (!(currentEventQueue && currentInstance)) {
4109 throw ReactError(
4110 Error(
4111 "An event responder context was used outside of an event cycle. Use context.setTimeout() to use asynchronous responder context outside of event cycle ."
4112 )
4113 );
4114 }
4115 })();
4116}
4117
4118// TODO this function is almost an exact copy of the DOM version, we should
4119// somehow share the logic
4120function processEventQueue() {
4121 var eventQueue = currentEventQueue;
4122 if (eventQueue.length === 0) {
4123 return;
4124 }
4125 switch (currentEventQueuePriority) {
4126 case DiscreteEvent: {
4127 flushDiscreteUpdatesIfNeeded(currentTimeStamp);
4128 discreteUpdates(function() {
4129 batchedEventUpdates(processEvents, eventQueue);
4130 });
4131 break;
4132 }
4133 case UserBlockingEvent: {
4134 if (enableUserBlockingEvents) {
4135 runWithPriority(
4136 UserBlockingPriority,
4137 batchedEventUpdates.bind(null, processEvents, eventQueue)
4138 );
4139 } else {
4140 batchedEventUpdates(processEvents, eventQueue);
4141 }
4142 break;
4143 }
4144 case ContinuousEvent: {
4145 batchedEventUpdates(processEvents, eventQueue);
4146 break;
4147 }
4148 }
4149}
4150
4151// TODO this function is almost an exact copy of the DOM version, we should
4152// somehow share the logic
4153function releaseOwnershipForEventResponderInstance(eventResponderInstance) {
4154 if (globalOwner === eventResponderInstance) {
4155 globalOwner = null;
4156 triggerOwnershipListeners();
4157 return true;
4158 }
4159 return false;
4160}
4161
4162// TODO this function is almost an exact copy of the DOM version, we should
4163// somehow share the logic
4164function processEvents(eventQueue) {
4165 for (var i = 0, length = eventQueue.length; i < length; i++) {
4166 var _eventQueue$i = eventQueue[i],
4167 _value = _eventQueue$i.value,
4168 _listener = _eventQueue$i.listener;
4169
4170 var type = typeof _value === "object" && _value !== null ? _value.type : "";
4171 invokeGuardedCallbackAndCatchFirstError(type, _listener, undefined, _value);
4172 }
4173}
4174
4175// TODO this function is almost an exact copy of the DOM version, we should
4176// somehow share the logic
4177function responderEventTypesContainType(eventTypes, type) {
4178 for (var i = 0, len = eventTypes.length; i < len; i++) {
4179 if (eventTypes[i] === type) {
4180 return true;
4181 }
4182 }
4183 return false;
4184}
4185
4186function validateResponderTargetEventTypes(eventType, responder) {
4187 var targetEventTypes = responder.targetEventTypes;
4188 // Validate the target event type exists on the responder
4189
4190 if (targetEventTypes !== null) {
4191 return responderEventTypesContainType(targetEventTypes, eventType);
4192 }
4193 return false;
4194}
4195
4196function validateOwnership(responderInstance) {
4197 return globalOwner === null || globalOwner === responderInstance;
4198}
4199
4200// TODO this function is almost an exact copy of the DOM version, we should
4201// somehow share the logic
4202function traverseAndHandleEventResponderInstances(
4203 eventType,
4204 targetFiber,
4205 nativeEvent
4206) {
4207 // Trigger event responders in this order:
4208 // - Bubble target responder phase
4209 // - Root responder phase
4210
4211 var responderEvent = createFabricResponderEvent(
4212 eventType,
4213 nativeEvent,
4214 targetFiber !== null ? targetFiber.stateNode : null
4215 );
4216 var visitedResponders = new Set();
4217 var node = targetFiber;
4218 while (node !== null) {
4219 var _node = node,
4220 dependencies = _node.dependencies,
4221 tag = _node.tag;
4222
4223 if (tag === HostComponent && dependencies !== null) {
4224 var respondersMap = dependencies.responders;
4225 if (respondersMap !== null) {
4226 var responderInstances = Array.from(respondersMap.values());
4227 for (var i = 0, length = responderInstances.length; i < length; i++) {
4228 var responderInstance = responderInstances[i];
4229
4230 if (validateOwnership(responderInstance)) {
4231 var props = responderInstance.props,
4232 responder = responderInstance.responder,
4233 state = responderInstance.state,
4234 target = responderInstance.target;
4235
4236 if (
4237 !visitedResponders.has(responder) &&
4238 validateResponderTargetEventTypes(eventType, responder)
4239 ) {
4240 var onEvent = responder.onEvent;
4241 visitedResponders.add(responder);
4242 if (onEvent !== null) {
4243 currentInstance = responderInstance;
4244 responderEvent.responderTarget = target;
4245 onEvent(responderEvent, eventResponderContext, props, state);
4246 }
4247 }
4248 }
4249 }
4250 }
4251 }
4252 node = node.return;
4253 }
4254 // Root phase
4255 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(
4256 eventType
4257 );
4258 if (rootEventResponderInstances !== undefined) {
4259 var _responderInstances = Array.from(rootEventResponderInstances);
4260
4261 for (var _i = 0; _i < _responderInstances.length; _i++) {
4262 var _responderInstance = _responderInstances[_i];
4263 if (!validateOwnership(_responderInstance)) {
4264 continue;
4265 }
4266 var _props = _responderInstance.props,
4267 _responder = _responderInstance.responder,
4268 _state = _responderInstance.state,
4269 _target = _responderInstance.target;
4270
4271 var onRootEvent = _responder.onRootEvent;
4272 if (onRootEvent !== null) {
4273 currentInstance = _responderInstance;
4274 responderEvent.responderTarget = _target;
4275 onRootEvent(responderEvent, eventResponderContext, _props, _state);
4276 }
4277 }
4278 }
4279}
4280
4281// TODO this function is almost an exact copy of the DOM version, we should
4282// somehow share the logic
4283function dispatchEventForResponderEventSystem(
4284 topLevelType,
4285 targetFiber,
4286 nativeEvent
4287) {
4288 var previousEventQueue = currentEventQueue;
4289 var previousInstance = currentInstance;
4290 var previousTimers = currentTimers;
4291 var previousTimeStamp = currentTimeStamp;
4292 var previousEventQueuePriority = currentEventQueuePriority;
4293 currentTimers = null;
4294 currentEventQueue = [];
4295 currentEventQueuePriority = ContinuousEvent;
4296 // We might want to control timeStamp another way here
4297 currentTimeStamp = Date.now();
4298 try {
4299 traverseAndHandleEventResponderInstances(
4300 topLevelType,
4301 targetFiber,
4302 nativeEvent
4303 );
4304 processEventQueue();
4305 } finally {
4306 currentTimers = previousTimers;
4307 currentInstance = previousInstance;
4308 currentEventQueue = previousEventQueue;
4309 currentTimeStamp = previousTimeStamp;
4310 currentEventQueuePriority = previousEventQueuePriority;
4311 }
4312}
4313
4314// TODO this function is almost an exact copy of the DOM version, we should
4315// somehow share the logic
4316function triggerOwnershipListeners() {
4317 var listeningInstances = Array.from(ownershipChangeListeners);
4318 var previousInstance = currentInstance;
4319 var previousEventQueuePriority = currentEventQueuePriority;
4320 var previousEventQueue = currentEventQueue;
4321 try {
4322 for (var i = 0; i < listeningInstances.length; i++) {
4323 var _instance2 = listeningInstances[i];
4324 var props = _instance2.props,
4325 responder = _instance2.responder,
4326 state = _instance2.state;
4327
4328 currentInstance = _instance2;
4329 currentEventQueuePriority = ContinuousEvent;
4330 currentEventQueue = [];
4331 var onOwnershipChange = responder.onOwnershipChange;
4332 if (onOwnershipChange !== null) {
4333 onOwnershipChange(eventResponderContext, props, state);
4334 }
4335 }
4336 processEventQueue();
4337 } finally {
4338 currentInstance = previousInstance;
4339 currentEventQueue = previousEventQueue;
4340 currentEventQueuePriority = previousEventQueuePriority;
4341 }
4342}
4343
4344// TODO this function is almost an exact copy of the DOM version, we should
4345// somehow share the logic
4346function mountEventResponder(responder, responderInstance, props, state) {
4347 if (responder.onOwnershipChange !== null) {
4348 ownershipChangeListeners.add(responderInstance);
4349 }
4350 var onMount = responder.onMount;
4351 if (onMount !== null) {
4352 currentEventQueuePriority = ContinuousEvent;
4353 currentInstance = responderInstance;
4354 currentEventQueue = [];
4355 try {
4356 onMount(eventResponderContext, props, state);
4357 processEventQueue();
4358 } finally {
4359 currentEventQueue = null;
4360 currentInstance = null;
4361 currentTimers = null;
4362 }
4363 }
4364}
4365
4366// TODO this function is almost an exact copy of the DOM version, we should
4367// somehow share the logic
4368function unmountEventResponder(responderInstance) {
4369 var responder = responderInstance.responder;
4370 var onUnmount = responder.onUnmount;
4371 if (onUnmount !== null) {
4372 var props = responderInstance.props,
4373 state = responderInstance.state;
4374
4375 currentEventQueue = [];
4376 currentEventQueuePriority = ContinuousEvent;
4377 currentInstance = responderInstance;
4378 try {
4379 onUnmount(eventResponderContext, props, state);
4380 processEventQueue();
4381 } finally {
4382 currentEventQueue = null;
4383 currentInstance = null;
4384 currentTimers = null;
4385 }
4386 }
4387 releaseOwnershipForEventResponderInstance(responderInstance);
4388 if (responder.onOwnershipChange !== null) {
4389 ownershipChangeListeners.delete(responderInstance);
4390 }
4391 var rootEventTypesSet = responderInstance.rootEventTypes;
4392 if (rootEventTypesSet !== null) {
4393 var rootEventTypes = Array.from(rootEventTypesSet);
4394
4395 for (var i = 0; i < rootEventTypes.length; i++) {
4396 var topLevelEventType = rootEventTypes[i];
4397 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(
4398 topLevelEventType
4399 );
4400 if (rootEventResponderInstances !== undefined) {
4401 rootEventResponderInstances.delete(responderInstance);
4402 }
4403 }
4404 }
4405}
4406
4407function registerRootEventType(rootEventType, responderInstance) {
4408 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(
4409 rootEventType
4410 );
4411 if (rootEventResponderInstances === undefined) {
4412 rootEventResponderInstances = new Set();
4413 rootEventTypesToEventResponderInstances.set(
4414 rootEventType,
4415 rootEventResponderInstances
4416 );
4417 }
4418 var rootEventTypesSet = responderInstance.rootEventTypes;
4419 if (rootEventTypesSet === null) {
4420 rootEventTypesSet = responderInstance.rootEventTypes = new Set();
4421 }
4422 (function() {
4423 if (!!rootEventTypesSet.has(rootEventType)) {
4424 throw ReactError(
4425 Error(
4426 'addRootEventTypes() found a duplicate root event type of "' +
4427 rootEventType +
4428 '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.'
4429 )
4430 );
4431 }
4432 })();
4433 rootEventTypesSet.add(rootEventType);
4434 rootEventResponderInstances.add(responderInstance);
4435}
4436
4437function addRootEventTypesForResponderInstance(
4438 responderInstance,
4439 rootEventTypes
4440) {
4441 for (var i = 0; i < rootEventTypes.length; i++) {
4442 var rootEventType = rootEventTypes[i];
4443 registerRootEventType(rootEventType, responderInstance);
4444 }
4445}
4446
4447function dispatchEvent(target, topLevelType, nativeEvent) {
4448 var targetFiber = target;
4449 if (enableFlareAPI) {
4450 // React Flare event system
4451 dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent);
4452 }
4453 batchedUpdates(function() {
4454 // Heritage plugin event system
4455 runExtractedPluginEventsInBatch(
4456 topLevelType,
4457 targetFiber,
4458 nativeEvent,
4459 nativeEvent.target
4460 );
4461 });
4462 // React Native doesn't use ReactControlledComponent but if it did, here's
4463 // where it would do it.
4464}
4465
4466// Renderers that don't support mutation
4467// can re-export everything from this module.
4468
4469function shim() {
4470 (function() {
4471 {
4472 throw ReactError(
4473 Error(
4474 "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue."
4475 )
4476 );
4477 }
4478 })();
4479}
4480
4481// Mutation (when unsupported)
4482var supportsMutation = false;
4483var appendChild = shim;
4484var appendChildToContainer = shim;
4485var commitTextUpdate = shim;
4486var commitMount = shim;
4487var commitUpdate = shim;
4488var insertBefore = shim;
4489var insertInContainerBefore = shim;
4490var removeChild = shim;
4491var removeChildFromContainer = shim;
4492var resetTextContent = shim;
4493var hideInstance = shim;
4494var hideTextInstance = shim;
4495var unhideInstance = shim;
4496var unhideTextInstance = shim;
4497
4498// Renderers that don't support hydration
4499// can re-export everything from this module.
4500
4501function shim$1() {
4502 (function() {
4503 {
4504 throw ReactError(
4505 Error(
4506 "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue."
4507 )
4508 );
4509 }
4510 })();
4511}
4512
4513// Hydration (when unsupported)
4514
4515var supportsHydration = false;
4516var canHydrateInstance = shim$1;
4517var canHydrateTextInstance = shim$1;
4518var canHydrateSuspenseInstance = shim$1;
4519var isSuspenseInstancePending = shim$1;
4520var isSuspenseInstanceFallback = shim$1;
4521var registerSuspenseInstanceRetry = shim$1;
4522var getNextHydratableSibling = shim$1;
4523var getFirstHydratableChild = shim$1;
4524var hydrateInstance = shim$1;
4525var hydrateTextInstance = shim$1;
4526var getNextHydratableInstanceAfterSuspenseInstance = shim$1;
4527var clearSuspenseBoundary = shim$1;
4528var clearSuspenseBoundaryFromContainer = shim$1;
4529var didNotMatchHydratedContainerTextInstance = shim$1;
4530var didNotMatchHydratedTextInstance = shim$1;
4531var didNotHydrateContainerInstance = shim$1;
4532var didNotHydrateInstance = shim$1;
4533var didNotFindHydratableContainerInstance = shim$1;
4534var didNotFindHydratableContainerTextInstance = shim$1;
4535var didNotFindHydratableContainerSuspenseInstance = shim$1;
4536var didNotFindHydratableInstance = shim$1;
4537var didNotFindHydratableTextInstance = shim$1;
4538var didNotFindHydratableSuspenseInstance = shim$1;
4539
4540function _classCallCheck(instance, Constructor) {
4541 if (!(instance instanceof Constructor)) {
4542 throw new TypeError("Cannot call a class as a function");
4543 }
4544}
4545
4546// Modules provided by RN:
4547var _nativeFabricUIManage$1 = nativeFabricUIManager;
4548var createNode = _nativeFabricUIManage$1.createNode;
4549var cloneNode = _nativeFabricUIManage$1.cloneNode;
4550var cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren;
4551var cloneNodeWithNewChildrenAndProps =
4552 _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps;
4553var cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps;
4554var createChildNodeSet = _nativeFabricUIManage$1.createChildSet;
4555var appendChildNode = _nativeFabricUIManage$1.appendChild;
4556var appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet;
4557var completeRoot = _nativeFabricUIManage$1.completeRoot;
4558var registerEventHandler = _nativeFabricUIManage$1.registerEventHandler;
4559var fabricMeasure = _nativeFabricUIManage$1.measure;
4560var fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow;
4561var fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout;
4562var getViewConfigForType =
4563 ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get;
4564
4565// Counter for uniquely identifying views.
4566// % 10 === 1 means it is a rootTag.
4567// % 2 === 0 means it is a Fabric tag.
4568// This means that they never overlap.
4569
4570var nextReactTag = 2;
4571
4572// TODO: Remove this conditional once all changes have propagated.
4573if (registerEventHandler) {
4574 /**
4575 * Register the event emitter with the native bridge
4576 */
4577 registerEventHandler(dispatchEvent);
4578}
4579
4580/**
4581 * This is used for refs on host components.
4582 */
4583
4584var ReactFabricHostComponent = (function() {
4585 function ReactFabricHostComponent(
4586 tag,
4587 viewConfig,
4588 props,
4589 internalInstanceHandle
4590 ) {
4591 _classCallCheck(this, ReactFabricHostComponent);
4592
4593 this._nativeTag = tag;
4594 this.viewConfig = viewConfig;
4595 this.currentProps = props;
4596 this._internalInstanceHandle = internalInstanceHandle;
4597 }
4598
4599 ReactFabricHostComponent.prototype.blur = function blur() {
4600 ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag);
4601 };
4602
4603 ReactFabricHostComponent.prototype.focus = function focus() {
4604 ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag);
4605 };
4606
4607 ReactFabricHostComponent.prototype.measure = function measure(callback) {
4608 fabricMeasure(
4609 this._internalInstanceHandle.stateNode.node,
4610 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
4611 );
4612 };
4613
4614 ReactFabricHostComponent.prototype.measureInWindow = function measureInWindow(
4615 callback
4616 ) {
4617 fabricMeasureInWindow(
4618 this._internalInstanceHandle.stateNode.node,
4619 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
4620 );
4621 };
4622
4623 ReactFabricHostComponent.prototype.measureLayout = function measureLayout(
4624 relativeToNativeNode,
4625 onSuccess,
4626 onFail /* currently unused */
4627 ) {
4628 if (
4629 typeof relativeToNativeNode === "number" ||
4630 !(relativeToNativeNode instanceof ReactFabricHostComponent)
4631 ) {
4632 warningWithoutStack$1(
4633 false,
4634 "Warning: ref.measureLayout must be called with a ref to a native component."
4635 );
4636
4637 return;
4638 }
4639
4640 fabricMeasureLayout(
4641 this._internalInstanceHandle.stateNode.node,
4642 relativeToNativeNode._internalInstanceHandle.stateNode.node,
4643 mountSafeCallback_NOT_REALLY_SAFE(this, onFail),
4644 mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess)
4645 );
4646 };
4647
4648 ReactFabricHostComponent.prototype.setNativeProps = function setNativeProps(
4649 nativeProps
4650 ) {
4651 warningWithoutStack$1(
4652 false,
4653 "Warning: setNativeProps is not currently supported in Fabric"
4654 );
4655
4656 return;
4657 };
4658
4659 return ReactFabricHostComponent;
4660})();
4661
4662function appendInitialChild(parentInstance, child) {
4663 appendChildNode(parentInstance.node, child.node);
4664}
4665
4666function createInstance(
4667 type,
4668 props,
4669 rootContainerInstance,
4670 hostContext,
4671 internalInstanceHandle
4672) {
4673 var tag = nextReactTag;
4674 nextReactTag += 2;
4675
4676 var viewConfig = getViewConfigForType(type);
4677
4678 {
4679 for (var key in viewConfig.validAttributes) {
4680 if (props.hasOwnProperty(key)) {
4681 ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev(
4682 props[key]
4683 );
4684 }
4685 }
4686 }
4687
4688 var updatePayload = create(props, viewConfig.validAttributes);
4689
4690 var node = createNode(
4691 tag, // reactTag
4692 viewConfig.uiViewClassName, // viewName
4693 rootContainerInstance, // rootTag
4694 updatePayload, // props
4695 internalInstanceHandle // internalInstanceHandle
4696 );
4697
4698 var component = new ReactFabricHostComponent(
4699 tag,
4700 viewConfig,
4701 props,
4702 internalInstanceHandle
4703 );
4704
4705 return {
4706 node: node,
4707 canonical: component
4708 };
4709}
4710
4711function createTextInstance(
4712 text,
4713 rootContainerInstance,
4714 hostContext,
4715 internalInstanceHandle
4716) {
4717 (function() {
4718 if (!hostContext.isInAParentText) {
4719 throw ReactError(
4720 Error("Text strings must be rendered within a <Text> component.")
4721 );
4722 }
4723 })();
4724
4725 var tag = nextReactTag;
4726 nextReactTag += 2;
4727
4728 var node = createNode(
4729 tag, // reactTag
4730 "RCTRawText", // viewName
4731 rootContainerInstance, // rootTag
4732 { text: text }, // props
4733 internalInstanceHandle // instance handle
4734 );
4735
4736 return {
4737 node: node
4738 };
4739}
4740
4741function finalizeInitialChildren(
4742 parentInstance,
4743 type,
4744 props,
4745 rootContainerInstance,
4746 hostContext
4747) {
4748 return false;
4749}
4750
4751function getRootHostContext(rootContainerInstance) {
4752 return { isInAParentText: false };
4753}
4754
4755function getChildHostContext(parentHostContext, type, rootContainerInstance) {
4756 var prevIsInAParentText = parentHostContext.isInAParentText;
4757 var isInAParentText =
4758 type === "AndroidTextInput" || // Android
4759 type === "RCTMultilineTextInputView" || // iOS
4760 type === "RCTSinglelineTextInputView" || // iOS
4761 type === "RCTText" ||
4762 type === "RCTVirtualText";
4763
4764 if (prevIsInAParentText !== isInAParentText) {
4765 return { isInAParentText: isInAParentText };
4766 } else {
4767 return parentHostContext;
4768 }
4769}
4770
4771function getPublicInstance(instance) {
4772 return instance.canonical;
4773}
4774
4775function prepareForCommit(containerInfo) {
4776 // Noop
4777}
4778
4779function prepareUpdate(
4780 instance,
4781 type,
4782 oldProps,
4783 newProps,
4784 rootContainerInstance,
4785 hostContext
4786) {
4787 var viewConfig = instance.canonical.viewConfig;
4788 var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes);
4789 // TODO: If the event handlers have changed, we need to update the current props
4790 // in the commit phase but there is no host config hook to do it yet.
4791 // So instead we hack it by updating it in the render phase.
4792 instance.canonical.currentProps = newProps;
4793 return updatePayload;
4794}
4795
4796function resetAfterCommit(containerInfo) {
4797 // Noop
4798}
4799
4800function shouldDeprioritizeSubtree(type, props) {
4801 return false;
4802}
4803
4804function shouldSetTextContent(type, props) {
4805 // TODO (bvaughn) Revisit this decision.
4806 // Always returning false simplifies the createInstance() implementation,
4807 // But creates an additional child Fiber for raw text children.
4808 // No additional native views are created though.
4809 // It's not clear to me which is better so I'm deferring for now.
4810 // More context @ github.com/facebook/react/pull/8560#discussion_r92111303
4811 return false;
4812}
4813
4814// The Fabric renderer is secondary to the existing React Native renderer.
4815var isPrimaryRenderer = false;
4816
4817// The Fabric renderer shouldn't trigger missing act() warnings
4818var warnsIfNotActing = false;
4819
4820var scheduleTimeout = setTimeout;
4821var cancelTimeout = clearTimeout;
4822var noTimeout = -1;
4823
4824// -------------------
4825// Persistence
4826// -------------------
4827
4828var supportsPersistence = true;
4829
4830function cloneInstance(
4831 instance,
4832 updatePayload,
4833 type,
4834 oldProps,
4835 newProps,
4836 internalInstanceHandle,
4837 keepChildren,
4838 recyclableInstance
4839) {
4840 var node = instance.node;
4841 var clone = void 0;
4842 if (keepChildren) {
4843 if (updatePayload !== null) {
4844 clone = cloneNodeWithNewProps(node, updatePayload);
4845 } else {
4846 clone = cloneNode(node);
4847 }
4848 } else {
4849 if (updatePayload !== null) {
4850 clone = cloneNodeWithNewChildrenAndProps(node, updatePayload);
4851 } else {
4852 clone = cloneNodeWithNewChildren(node);
4853 }
4854 }
4855 return {
4856 node: clone,
4857 canonical: instance.canonical
4858 };
4859}
4860
4861function cloneHiddenInstance(instance, type, props, internalInstanceHandle) {
4862 var viewConfig = instance.canonical.viewConfig;
4863 var node = instance.node;
4864 var updatePayload = create(
4865 { style: { display: "none" } },
4866 viewConfig.validAttributes
4867 );
4868 return {
4869 node: cloneNodeWithNewProps(node, updatePayload),
4870 canonical: instance.canonical
4871 };
4872}
4873
4874function cloneHiddenTextInstance(instance, text, internalInstanceHandle) {
4875 throw new Error("Not yet implemented.");
4876}
4877
4878function createContainerChildSet(container) {
4879 return createChildNodeSet(container);
4880}
4881
4882function appendChildToContainerChildSet(childSet, child) {
4883 appendChildNodeToSet(childSet, child.node);
4884}
4885
4886function finalizeContainerChildren(container, newChildren) {
4887 completeRoot(container, newChildren);
4888}
4889
4890function mountResponderInstance(
4891 responder,
4892 responderInstance,
4893 props,
4894 state,
4895 instance,
4896 rootContainerInstance
4897) {
4898 if (enableFlareAPI) {
4899 var rootEventTypes = responder.rootEventTypes;
4900
4901 if (rootEventTypes !== null) {
4902 addRootEventTypesForResponderInstance(responderInstance, rootEventTypes);
4903 }
4904 mountEventResponder(responder, responderInstance, props, state);
4905 }
4906}
4907
4908function unmountResponderInstance(responderInstance) {
4909 if (enableFlareAPI) {
4910 // TODO stop listening to targetEventTypes
4911 unmountEventResponder(responderInstance);
4912 }
4913}
4914
4915function getFundamentalComponentInstance(fundamentalInstance) {
4916 throw new Error("Not yet implemented.");
4917}
4918
4919function mountFundamentalComponent(fundamentalInstance) {
4920 throw new Error("Not yet implemented.");
4921}
4922
4923function shouldUpdateFundamentalComponent(fundamentalInstance) {
4924 throw new Error("Not yet implemented.");
4925}
4926
4927function updateFundamentalComponent(fundamentalInstance) {
4928 throw new Error("Not yet implemented.");
4929}
4930
4931function unmountFundamentalComponent(fundamentalInstance) {
4932 throw new Error("Not yet implemented.");
4933}
4934
4935function cloneFundamentalInstance(fundamentalInstance) {
4936 throw new Error("Not yet implemented.");
4937}
4938
4939var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
4940
4941var describeComponentFrame = function(name, source, ownerName) {
4942 var sourceInfo = "";
4943 if (source) {
4944 var path = source.fileName;
4945 var fileName = path.replace(BEFORE_SLASH_RE, "");
4946 {
4947 // In DEV, include code for a common special case:
4948 // prefer "folder/index.js" instead of just "index.js".
4949 if (/^index\./.test(fileName)) {
4950 var match = path.match(BEFORE_SLASH_RE);
4951 if (match) {
4952 var pathBeforeSlash = match[1];
4953 if (pathBeforeSlash) {
4954 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, "");
4955 fileName = folderName + "/" + fileName;
4956 }
4957 }
4958 }
4959 }
4960 sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")";
4961 } else if (ownerName) {
4962 sourceInfo = " (created by " + ownerName + ")";
4963 }
4964 return "\n in " + (name || "Unknown") + sourceInfo;
4965};
4966
4967var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
4968
4969function describeFiber(fiber) {
4970 switch (fiber.tag) {
4971 case HostRoot:
4972 case HostPortal:
4973 case HostText:
4974 case Fragment:
4975 case ContextProvider:
4976 case ContextConsumer:
4977 return "";
4978 default:
4979 var owner = fiber._debugOwner;
4980 var source = fiber._debugSource;
4981 var name = getComponentName(fiber.type);
4982 var ownerName = null;
4983 if (owner) {
4984 ownerName = getComponentName(owner.type);
4985 }
4986 return describeComponentFrame(name, source, ownerName);
4987 }
4988}
4989
4990function getStackByFiberInDevAndProd(workInProgress) {
4991 var info = "";
4992 var node = workInProgress;
4993 do {
4994 info += describeFiber(node);
4995 node = node.return;
4996 } while (node);
4997 return info;
4998}
4999
5000var current = null;
5001var phase = null;
5002
5003function getCurrentFiberOwnerNameInDevOrNull() {
5004 {
5005 if (current === null) {
5006 return null;
5007 }
5008 var owner = current._debugOwner;
5009 if (owner !== null && typeof owner !== "undefined") {
5010 return getComponentName(owner.type);
5011 }
5012 }
5013 return null;
5014}
5015
5016function getCurrentFiberStackInDev() {
5017 {
5018 if (current === null) {
5019 return "";
5020 }
5021 // Safe because if current fiber exists, we are reconciling,
5022 // and it is guaranteed to be the work-in-progress version.
5023 return getStackByFiberInDevAndProd(current);
5024 }
5025 return "";
5026}
5027
5028function resetCurrentFiber() {
5029 {
5030 ReactDebugCurrentFrame.getCurrentStack = null;
5031 current = null;
5032 phase = null;
5033 }
5034}
5035
5036function setCurrentFiber(fiber) {
5037 {
5038 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
5039 current = fiber;
5040 phase = null;
5041 }
5042}
5043
5044function setCurrentPhase(lifeCyclePhase) {
5045 {
5046 phase = lifeCyclePhase;
5047 }
5048}
5049
5050// Prefix measurements so that it's possible to filter them.
5051// Longer prefixes are hard to read in DevTools.
5052var reactEmoji = "\u269B";
5053var warningEmoji = "\u26D4";
5054var supportsUserTiming =
5055 typeof performance !== "undefined" &&
5056 typeof performance.mark === "function" &&
5057 typeof performance.clearMarks === "function" &&
5058 typeof performance.measure === "function" &&
5059 typeof performance.clearMeasures === "function";
5060
5061// Keep track of current fiber so that we know the path to unwind on pause.
5062// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
5063var currentFiber = null;
5064// If we're in the middle of user code, which fiber and method is it?
5065// Reusing `currentFiber` would be confusing for this because user code fiber
5066// can change during commit phase too, but we don't need to unwind it (since
5067// lifecycles in the commit phase don't resemble a tree).
5068var currentPhase = null;
5069var currentPhaseFiber = null;
5070// Did lifecycle hook schedule an update? This is often a performance problem,
5071// so we will keep track of it, and include it in the report.
5072// Track commits caused by cascading updates.
5073var isCommitting = false;
5074var hasScheduledUpdateInCurrentCommit = false;
5075var hasScheduledUpdateInCurrentPhase = false;
5076var commitCountInCurrentWorkLoop = 0;
5077var effectCountInCurrentCommit = 0;
5078var isWaitingForCallback = false;
5079// During commits, we only show a measurement once per method name
5080// to avoid stretch the commit phase with measurement overhead.
5081var labelsInCurrentCommit = new Set();
5082
5083var formatMarkName = function(markName) {
5084 return reactEmoji + " " + markName;
5085};
5086
5087var formatLabel = function(label, warning) {
5088 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
5089 var suffix = warning ? " Warning: " + warning : "";
5090 return "" + prefix + label + suffix;
5091};
5092
5093var beginMark = function(markName) {
5094 performance.mark(formatMarkName(markName));
5095};
5096
5097var clearMark = function(markName) {
5098 performance.clearMarks(formatMarkName(markName));
5099};
5100
5101var endMark = function(label, markName, warning) {
5102 var formattedMarkName = formatMarkName(markName);
5103 var formattedLabel = formatLabel(label, warning);
5104 try {
5105 performance.measure(formattedLabel, formattedMarkName);
5106 } catch (err) {}
5107 // If previous mark was missing for some reason, this will throw.
5108 // This could only happen if React crashed in an unexpected place earlier.
5109 // Don't pile on with more errors.
5110
5111 // Clear marks immediately to avoid growing buffer.
5112 performance.clearMarks(formattedMarkName);
5113 performance.clearMeasures(formattedLabel);
5114};
5115
5116var getFiberMarkName = function(label, debugID) {
5117 return label + " (#" + debugID + ")";
5118};
5119
5120var getFiberLabel = function(componentName, isMounted, phase) {
5121 if (phase === null) {
5122 // These are composite component total time measurements.
5123 return componentName + " [" + (isMounted ? "update" : "mount") + "]";
5124 } else {
5125 // Composite component methods.
5126 return componentName + "." + phase;
5127 }
5128};
5129
5130var beginFiberMark = function(fiber, phase) {
5131 var componentName = getComponentName(fiber.type) || "Unknown";
5132 var debugID = fiber._debugID;
5133 var isMounted = fiber.alternate !== null;
5134 var label = getFiberLabel(componentName, isMounted, phase);
5135
5136 if (isCommitting && labelsInCurrentCommit.has(label)) {
5137 // During the commit phase, we don't show duplicate labels because
5138 // there is a fixed overhead for every measurement, and we don't
5139 // want to stretch the commit phase beyond necessary.
5140 return false;
5141 }
5142 labelsInCurrentCommit.add(label);
5143
5144 var markName = getFiberMarkName(label, debugID);
5145 beginMark(markName);
5146 return true;
5147};
5148
5149var clearFiberMark = function(fiber, phase) {
5150 var componentName = getComponentName(fiber.type) || "Unknown";
5151 var debugID = fiber._debugID;
5152 var isMounted = fiber.alternate !== null;
5153 var label = getFiberLabel(componentName, isMounted, phase);
5154 var markName = getFiberMarkName(label, debugID);
5155 clearMark(markName);
5156};
5157
5158var endFiberMark = function(fiber, phase, warning) {
5159 var componentName = getComponentName(fiber.type) || "Unknown";
5160 var debugID = fiber._debugID;
5161 var isMounted = fiber.alternate !== null;
5162 var label = getFiberLabel(componentName, isMounted, phase);
5163 var markName = getFiberMarkName(label, debugID);
5164 endMark(label, markName, warning);
5165};
5166
5167var shouldIgnoreFiber = function(fiber) {
5168 // Host components should be skipped in the timeline.
5169 // We could check typeof fiber.type, but does this work with RN?
5170 switch (fiber.tag) {
5171 case HostRoot:
5172 case HostComponent:
5173 case HostText:
5174 case HostPortal:
5175 case Fragment:
5176 case ContextProvider:
5177 case ContextConsumer:
5178 case Mode:
5179 return true;
5180 default:
5181 return false;
5182 }
5183};
5184
5185var clearPendingPhaseMeasurement = function() {
5186 if (currentPhase !== null && currentPhaseFiber !== null) {
5187 clearFiberMark(currentPhaseFiber, currentPhase);
5188 }
5189 currentPhaseFiber = null;
5190 currentPhase = null;
5191 hasScheduledUpdateInCurrentPhase = false;
5192};
5193
5194var pauseTimers = function() {
5195 // Stops all currently active measurements so that they can be resumed
5196 // if we continue in a later deferred loop from the same unit of work.
5197 var fiber = currentFiber;
5198 while (fiber) {
5199 if (fiber._debugIsCurrentlyTiming) {
5200 endFiberMark(fiber, null, null);
5201 }
5202 fiber = fiber.return;
5203 }
5204};
5205
5206var resumeTimersRecursively = function(fiber) {
5207 if (fiber.return !== null) {
5208 resumeTimersRecursively(fiber.return);
5209 }
5210 if (fiber._debugIsCurrentlyTiming) {
5211 beginFiberMark(fiber, null);
5212 }
5213};
5214
5215var resumeTimers = function() {
5216 // Resumes all measurements that were active during the last deferred loop.
5217 if (currentFiber !== null) {
5218 resumeTimersRecursively(currentFiber);
5219 }
5220};
5221
5222function recordEffect() {
5223 if (enableUserTimingAPI) {
5224 effectCountInCurrentCommit++;
5225 }
5226}
5227
5228function recordScheduleUpdate() {
5229 if (enableUserTimingAPI) {
5230 if (isCommitting) {
5231 hasScheduledUpdateInCurrentCommit = true;
5232 }
5233 if (
5234 currentPhase !== null &&
5235 currentPhase !== "componentWillMount" &&
5236 currentPhase !== "componentWillReceiveProps"
5237 ) {
5238 hasScheduledUpdateInCurrentPhase = true;
5239 }
5240 }
5241}
5242
5243function startRequestCallbackTimer() {
5244 if (enableUserTimingAPI) {
5245 if (supportsUserTiming && !isWaitingForCallback) {
5246 isWaitingForCallback = true;
5247 beginMark("(Waiting for async callback...)");
5248 }
5249 }
5250}
5251
5252function stopRequestCallbackTimer(didExpire) {
5253 if (enableUserTimingAPI) {
5254 if (supportsUserTiming) {
5255 isWaitingForCallback = false;
5256 var warning = didExpire
5257 ? "Update expired; will flush synchronously"
5258 : null;
5259 endMark(
5260 "(Waiting for async callback...)",
5261 "(Waiting for async callback...)",
5262 warning
5263 );
5264 }
5265 }
5266}
5267
5268function startWorkTimer(fiber) {
5269 if (enableUserTimingAPI) {
5270 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5271 return;
5272 }
5273 // If we pause, this is the fiber to unwind from.
5274 currentFiber = fiber;
5275 if (!beginFiberMark(fiber, null)) {
5276 return;
5277 }
5278 fiber._debugIsCurrentlyTiming = true;
5279 }
5280}
5281
5282function cancelWorkTimer(fiber) {
5283 if (enableUserTimingAPI) {
5284 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5285 return;
5286 }
5287 // Remember we shouldn't complete measurement for this fiber.
5288 // Otherwise flamechart will be deep even for small updates.
5289 fiber._debugIsCurrentlyTiming = false;
5290 clearFiberMark(fiber, null);
5291 }
5292}
5293
5294function stopWorkTimer(fiber) {
5295 if (enableUserTimingAPI) {
5296 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5297 return;
5298 }
5299 // If we pause, its parent is the fiber to unwind from.
5300 currentFiber = fiber.return;
5301 if (!fiber._debugIsCurrentlyTiming) {
5302 return;
5303 }
5304 fiber._debugIsCurrentlyTiming = false;
5305 endFiberMark(fiber, null, null);
5306 }
5307}
5308
5309function stopFailedWorkTimer(fiber) {
5310 if (enableUserTimingAPI) {
5311 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
5312 return;
5313 }
5314 // If we pause, its parent is the fiber to unwind from.
5315 currentFiber = fiber.return;
5316 if (!fiber._debugIsCurrentlyTiming) {
5317 return;
5318 }
5319 fiber._debugIsCurrentlyTiming = false;
5320 var warning =
5321 fiber.tag === SuspenseComponent ||
5322 fiber.tag === DehydratedSuspenseComponent
5323 ? "Rendering was suspended"
5324 : "An error was thrown inside this error boundary";
5325 endFiberMark(fiber, null, warning);
5326 }
5327}
5328
5329function startPhaseTimer(fiber, phase) {
5330 if (enableUserTimingAPI) {
5331 if (!supportsUserTiming) {
5332 return;
5333 }
5334 clearPendingPhaseMeasurement();
5335 if (!beginFiberMark(fiber, phase)) {
5336 return;
5337 }
5338 currentPhaseFiber = fiber;
5339 currentPhase = phase;
5340 }
5341}
5342
5343function stopPhaseTimer() {
5344 if (enableUserTimingAPI) {
5345 if (!supportsUserTiming) {
5346 return;
5347 }
5348 if (currentPhase !== null && currentPhaseFiber !== null) {
5349 var warning = hasScheduledUpdateInCurrentPhase
5350 ? "Scheduled a cascading update"
5351 : null;
5352 endFiberMark(currentPhaseFiber, currentPhase, warning);
5353 }
5354 currentPhase = null;
5355 currentPhaseFiber = null;
5356 }
5357}
5358
5359function startWorkLoopTimer(nextUnitOfWork) {
5360 if (enableUserTimingAPI) {
5361 currentFiber = nextUnitOfWork;
5362 if (!supportsUserTiming) {
5363 return;
5364 }
5365 commitCountInCurrentWorkLoop = 0;
5366 // This is top level call.
5367 // Any other measurements are performed within.
5368 beginMark("(React Tree Reconciliation)");
5369 // Resume any measurements that were in progress during the last loop.
5370 resumeTimers();
5371 }
5372}
5373
5374function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
5375 if (enableUserTimingAPI) {
5376 if (!supportsUserTiming) {
5377 return;
5378 }
5379 var warning = null;
5380 if (interruptedBy !== null) {
5381 if (interruptedBy.tag === HostRoot) {
5382 warning = "A top-level update interrupted the previous render";
5383 } else {
5384 var componentName = getComponentName(interruptedBy.type) || "Unknown";
5385 warning =
5386 "An update to " + componentName + " interrupted the previous render";
5387 }
5388 } else if (commitCountInCurrentWorkLoop > 1) {
5389 warning = "There were cascading updates";
5390 }
5391 commitCountInCurrentWorkLoop = 0;
5392 var label = didCompleteRoot
5393 ? "(React Tree Reconciliation: Completed Root)"
5394 : "(React Tree Reconciliation: Yielded)";
5395 // Pause any measurements until the next loop.
5396 pauseTimers();
5397 endMark(label, "(React Tree Reconciliation)", warning);
5398 }
5399}
5400
5401function startCommitTimer() {
5402 if (enableUserTimingAPI) {
5403 if (!supportsUserTiming) {
5404 return;
5405 }
5406 isCommitting = true;
5407 hasScheduledUpdateInCurrentCommit = false;
5408 labelsInCurrentCommit.clear();
5409 beginMark("(Committing Changes)");
5410 }
5411}
5412
5413function stopCommitTimer() {
5414 if (enableUserTimingAPI) {
5415 if (!supportsUserTiming) {
5416 return;
5417 }
5418
5419 var warning = null;
5420 if (hasScheduledUpdateInCurrentCommit) {
5421 warning = "Lifecycle hook scheduled a cascading update";
5422 } else if (commitCountInCurrentWorkLoop > 0) {
5423 warning = "Caused by a cascading update in earlier commit";
5424 }
5425 hasScheduledUpdateInCurrentCommit = false;
5426 commitCountInCurrentWorkLoop++;
5427 isCommitting = false;
5428 labelsInCurrentCommit.clear();
5429
5430 endMark("(Committing Changes)", "(Committing Changes)", warning);
5431 }
5432}
5433
5434function startCommitSnapshotEffectsTimer() {
5435 if (enableUserTimingAPI) {
5436 if (!supportsUserTiming) {
5437 return;
5438 }
5439 effectCountInCurrentCommit = 0;
5440 beginMark("(Committing Snapshot Effects)");
5441 }
5442}
5443
5444function stopCommitSnapshotEffectsTimer() {
5445 if (enableUserTimingAPI) {
5446 if (!supportsUserTiming) {
5447 return;
5448 }
5449 var count = effectCountInCurrentCommit;
5450 effectCountInCurrentCommit = 0;
5451 endMark(
5452 "(Committing Snapshot Effects: " + count + " Total)",
5453 "(Committing Snapshot Effects)",
5454 null
5455 );
5456 }
5457}
5458
5459function startCommitHostEffectsTimer() {
5460 if (enableUserTimingAPI) {
5461 if (!supportsUserTiming) {
5462 return;
5463 }
5464 effectCountInCurrentCommit = 0;
5465 beginMark("(Committing Host Effects)");
5466 }
5467}
5468
5469function stopCommitHostEffectsTimer() {
5470 if (enableUserTimingAPI) {
5471 if (!supportsUserTiming) {
5472 return;
5473 }
5474 var count = effectCountInCurrentCommit;
5475 effectCountInCurrentCommit = 0;
5476 endMark(
5477 "(Committing Host Effects: " + count + " Total)",
5478 "(Committing Host Effects)",
5479 null
5480 );
5481 }
5482}
5483
5484function startCommitLifeCyclesTimer() {
5485 if (enableUserTimingAPI) {
5486 if (!supportsUserTiming) {
5487 return;
5488 }
5489 effectCountInCurrentCommit = 0;
5490 beginMark("(Calling Lifecycle Methods)");
5491 }
5492}
5493
5494function stopCommitLifeCyclesTimer() {
5495 if (enableUserTimingAPI) {
5496 if (!supportsUserTiming) {
5497 return;
5498 }
5499 var count = effectCountInCurrentCommit;
5500 effectCountInCurrentCommit = 0;
5501 endMark(
5502 "(Calling Lifecycle Methods: " + count + " Total)",
5503 "(Calling Lifecycle Methods)",
5504 null
5505 );
5506 }
5507}
5508
5509var valueStack = [];
5510
5511var fiberStack = void 0;
5512
5513{
5514 fiberStack = [];
5515}
5516
5517var index = -1;
5518
5519function createCursor(defaultValue) {
5520 return {
5521 current: defaultValue
5522 };
5523}
5524
5525function pop(cursor, fiber) {
5526 if (index < 0) {
5527 {
5528 warningWithoutStack$1(false, "Unexpected pop.");
5529 }
5530 return;
5531 }
5532
5533 {
5534 if (fiber !== fiberStack[index]) {
5535 warningWithoutStack$1(false, "Unexpected Fiber popped.");
5536 }
5537 }
5538
5539 cursor.current = valueStack[index];
5540
5541 valueStack[index] = null;
5542
5543 {
5544 fiberStack[index] = null;
5545 }
5546
5547 index--;
5548}
5549
5550function push(cursor, value, fiber) {
5551 index++;
5552
5553 valueStack[index] = cursor.current;
5554
5555 {
5556 fiberStack[index] = fiber;
5557 }
5558
5559 cursor.current = value;
5560}
5561
5562var warnedAboutMissingGetChildContext = void 0;
5563
5564{
5565 warnedAboutMissingGetChildContext = {};
5566}
5567
5568var emptyContextObject = {};
5569{
5570 Object.freeze(emptyContextObject);
5571}
5572
5573// A cursor to the current merged context object on the stack.
5574var contextStackCursor = createCursor(emptyContextObject);
5575// A cursor to a boolean indicating whether the context has changed.
5576var didPerformWorkStackCursor = createCursor(false);
5577// Keep track of the previous context object that was on the stack.
5578// We use this to get access to the parent context after we have already
5579// pushed the next context provider, and now need to merge their contexts.
5580var previousContext = emptyContextObject;
5581
5582function getUnmaskedContext(
5583 workInProgress,
5584 Component,
5585 didPushOwnContextIfProvider
5586) {
5587 if (disableLegacyContext) {
5588 return emptyContextObject;
5589 } else {
5590 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
5591 // If the fiber is a context provider itself, when we read its context
5592 // we may have already pushed its own child context on the stack. A context
5593 // provider should not "see" its own child context. Therefore we read the
5594 // previous (parent) context instead for a context provider.
5595 return previousContext;
5596 }
5597 return contextStackCursor.current;
5598 }
5599}
5600
5601function cacheContext(workInProgress, unmaskedContext, maskedContext) {
5602 if (disableLegacyContext) {
5603 return;
5604 } else {
5605 var instance = workInProgress.stateNode;
5606 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
5607 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
5608 }
5609}
5610
5611function getMaskedContext(workInProgress, unmaskedContext) {
5612 if (disableLegacyContext) {
5613 return emptyContextObject;
5614 } else {
5615 var type = workInProgress.type;
5616 var contextTypes = type.contextTypes;
5617 if (!contextTypes) {
5618 return emptyContextObject;
5619 }
5620
5621 // Avoid recreating masked context unless unmasked context has changed.
5622 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
5623 // This may trigger infinite loops if componentWillReceiveProps calls setState.
5624 var instance = workInProgress.stateNode;
5625 if (
5626 instance &&
5627 instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext
5628 ) {
5629 return instance.__reactInternalMemoizedMaskedChildContext;
5630 }
5631
5632 var context = {};
5633 for (var key in contextTypes) {
5634 context[key] = unmaskedContext[key];
5635 }
5636
5637 {
5638 var name = getComponentName(type) || "Unknown";
5639 checkPropTypes(
5640 contextTypes,
5641 context,
5642 "context",
5643 name,
5644 getCurrentFiberStackInDev
5645 );
5646 }
5647
5648 // Cache unmasked context so we can avoid recreating masked context unless necessary.
5649 // Context is created before the class component is instantiated so check for instance.
5650 if (instance) {
5651 cacheContext(workInProgress, unmaskedContext, context);
5652 }
5653
5654 return context;
5655 }
5656}
5657
5658function hasContextChanged() {
5659 if (disableLegacyContext) {
5660 return false;
5661 } else {
5662 return didPerformWorkStackCursor.current;
5663 }
5664}
5665
5666function isContextProvider(type) {
5667 if (disableLegacyContext) {
5668 return false;
5669 } else {
5670 var childContextTypes = type.childContextTypes;
5671 return childContextTypes !== null && childContextTypes !== undefined;
5672 }
5673}
5674
5675function popContext(fiber) {
5676 if (disableLegacyContext) {
5677 return;
5678 } else {
5679 pop(didPerformWorkStackCursor, fiber);
5680 pop(contextStackCursor, fiber);
5681 }
5682}
5683
5684function popTopLevelContextObject(fiber) {
5685 if (disableLegacyContext) {
5686 return;
5687 } else {
5688 pop(didPerformWorkStackCursor, fiber);
5689 pop(contextStackCursor, fiber);
5690 }
5691}
5692
5693function pushTopLevelContextObject(fiber, context, didChange) {
5694 if (disableLegacyContext) {
5695 return;
5696 } else {
5697 (function() {
5698 if (!(contextStackCursor.current === emptyContextObject)) {
5699 throw ReactError(
5700 Error(
5701 "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue."
5702 )
5703 );
5704 }
5705 })();
5706
5707 push(contextStackCursor, context, fiber);
5708 push(didPerformWorkStackCursor, didChange, fiber);
5709 }
5710}
5711
5712function processChildContext(fiber, type, parentContext) {
5713 if (disableLegacyContext) {
5714 return parentContext;
5715 } else {
5716 var instance = fiber.stateNode;
5717 var childContextTypes = type.childContextTypes;
5718
5719 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
5720 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
5721 if (typeof instance.getChildContext !== "function") {
5722 {
5723 var componentName = getComponentName(type) || "Unknown";
5724
5725 if (!warnedAboutMissingGetChildContext[componentName]) {
5726 warnedAboutMissingGetChildContext[componentName] = true;
5727 warningWithoutStack$1(
5728 false,
5729 "%s.childContextTypes is specified but there is no getChildContext() method " +
5730 "on the instance. You can either define getChildContext() on %s or remove " +
5731 "childContextTypes from it.",
5732 componentName,
5733 componentName
5734 );
5735 }
5736 }
5737 return parentContext;
5738 }
5739
5740 var childContext = void 0;
5741 {
5742 setCurrentPhase("getChildContext");
5743 }
5744 startPhaseTimer(fiber, "getChildContext");
5745 childContext = instance.getChildContext();
5746 stopPhaseTimer();
5747 {
5748 setCurrentPhase(null);
5749 }
5750 for (var contextKey in childContext) {
5751 (function() {
5752 if (!(contextKey in childContextTypes)) {
5753 throw ReactError(
5754 Error(
5755 (getComponentName(type) || "Unknown") +
5756 '.getChildContext(): key "' +
5757 contextKey +
5758 '" is not defined in childContextTypes.'
5759 )
5760 );
5761 }
5762 })();
5763 }
5764 {
5765 var name = getComponentName(type) || "Unknown";
5766 checkPropTypes(
5767 childContextTypes,
5768 childContext,
5769 "child context",
5770 name,
5771 // In practice, there is one case in which we won't get a stack. It's when
5772 // somebody calls unstable_renderSubtreeIntoContainer() and we process
5773 // context from the parent component instance. The stack will be missing
5774 // because it's outside of the reconciliation, and so the pointer has not
5775 // been set. This is rare and doesn't matter. We'll also remove that API.
5776 getCurrentFiberStackInDev
5777 );
5778 }
5779
5780 return Object.assign({}, parentContext, childContext);
5781 }
5782}
5783
5784function pushContextProvider(workInProgress) {
5785 if (disableLegacyContext) {
5786 return false;
5787 } else {
5788 var instance = workInProgress.stateNode;
5789 // We push the context as early as possible to ensure stack integrity.
5790 // If the instance does not exist yet, we will push null at first,
5791 // and replace it on the stack later when invalidating the context.
5792 var memoizedMergedChildContext =
5793 (instance && instance.__reactInternalMemoizedMergedChildContext) ||
5794 emptyContextObject;
5795
5796 // Remember the parent context so we can merge with it later.
5797 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
5798 previousContext = contextStackCursor.current;
5799 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
5800 push(
5801 didPerformWorkStackCursor,
5802 didPerformWorkStackCursor.current,
5803 workInProgress
5804 );
5805
5806 return true;
5807 }
5808}
5809
5810function invalidateContextProvider(workInProgress, type, didChange) {
5811 if (disableLegacyContext) {
5812 return;
5813 } else {
5814 var instance = workInProgress.stateNode;
5815 (function() {
5816 if (!instance) {
5817 throw ReactError(
5818 Error(
5819 "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue."
5820 )
5821 );
5822 }
5823 })();
5824
5825 if (didChange) {
5826 // Merge parent and own context.
5827 // Skip this if we're not updating due to sCU.
5828 // This avoids unnecessarily recomputing memoized values.
5829 var mergedContext = processChildContext(
5830 workInProgress,
5831 type,
5832 previousContext
5833 );
5834 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
5835
5836 // Replace the old (or empty) context with the new one.
5837 // It is important to unwind the context in the reverse order.
5838 pop(didPerformWorkStackCursor, workInProgress);
5839 pop(contextStackCursor, workInProgress);
5840 // Now push the new context and mark that it has changed.
5841 push(contextStackCursor, mergedContext, workInProgress);
5842 push(didPerformWorkStackCursor, didChange, workInProgress);
5843 } else {
5844 pop(didPerformWorkStackCursor, workInProgress);
5845 push(didPerformWorkStackCursor, didChange, workInProgress);
5846 }
5847 }
5848}
5849
5850function findCurrentUnmaskedContext(fiber) {
5851 if (disableLegacyContext) {
5852 return emptyContextObject;
5853 } else {
5854 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
5855 // makes sense elsewhere
5856 (function() {
5857 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
5858 throw ReactError(
5859 Error(
5860 "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue."
5861 )
5862 );
5863 }
5864 })();
5865
5866 var node = fiber;
5867 do {
5868 switch (node.tag) {
5869 case HostRoot:
5870 return node.stateNode.context;
5871 case ClassComponent: {
5872 var Component = node.type;
5873 if (isContextProvider(Component)) {
5874 return node.stateNode.__reactInternalMemoizedMergedChildContext;
5875 }
5876 break;
5877 }
5878 }
5879 node = node.return;
5880 } while (node !== null);
5881 (function() {
5882 {
5883 throw ReactError(
5884 Error(
5885 "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue."
5886 )
5887 );
5888 }
5889 })();
5890 }
5891}
5892
5893var LegacyRoot = 0;
5894var BatchedRoot = 1;
5895var ConcurrentRoot = 2;
5896
5897// Intentionally not named imports because Rollup would use dynamic dispatch for
5898// CommonJS interop named imports.
5899var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority;
5900var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback;
5901var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback;
5902var Scheduler_shouldYield = Scheduler.unstable_shouldYield;
5903var Scheduler_requestPaint = Scheduler.unstable_requestPaint;
5904var Scheduler_now = Scheduler.unstable_now;
5905var Scheduler_getCurrentPriorityLevel =
5906 Scheduler.unstable_getCurrentPriorityLevel;
5907var Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority;
5908var Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
5909var Scheduler_NormalPriority = Scheduler.unstable_NormalPriority;
5910var Scheduler_LowPriority = Scheduler.unstable_LowPriority;
5911var Scheduler_IdlePriority = Scheduler.unstable_IdlePriority;
5912
5913if (enableSchedulerTracing) {
5914 // Provide explicit error message when production+profiling bundle of e.g.
5915 // react-dom is used with production (non-profiling) bundle of
5916 // scheduler/tracing
5917 (function() {
5918 if (
5919 !(
5920 tracing.__interactionsRef != null &&
5921 tracing.__interactionsRef.current != null
5922 )
5923 ) {
5924 throw ReactError(
5925 Error(
5926 "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling"
5927 )
5928 );
5929 }
5930 })();
5931}
5932
5933var fakeCallbackNode = {};
5934
5935// Except for NoPriority, these correspond to Scheduler priorities. We use
5936// ascending numbers so we can compare them like numbers. They start at 90 to
5937// avoid clashing with Scheduler's priorities.
5938var ImmediatePriority = 99;
5939var UserBlockingPriority$1 = 98;
5940var NormalPriority = 97;
5941var LowPriority = 96;
5942var IdlePriority = 95;
5943// NoPriority is the absence of priority. Also React-only.
5944var NoPriority = 90;
5945
5946var shouldYield = Scheduler_shouldYield;
5947var requestPaint =
5948 // Fall back gracefully if we're running an older version of Scheduler.
5949 Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {};
5950
5951var syncQueue = null;
5952var immediateQueueCallbackNode = null;
5953var isFlushingSyncQueue = false;
5954var initialTimeMs = Scheduler_now();
5955
5956// If the initial timestamp is reasonably small, use Scheduler's `now` directly.
5957// This will be the case for modern browsers that support `performance.now`. In
5958// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
5959// timestamp. In that case, subtract the module initialization time to simulate
5960// the behavior of performance.now and keep our times small enough to fit
5961// within 32 bits.
5962// TODO: Consider lifting this into Scheduler.
5963var now =
5964 initialTimeMs < 10000
5965 ? Scheduler_now
5966 : function() {
5967 return Scheduler_now() - initialTimeMs;
5968 };
5969
5970function getCurrentPriorityLevel() {
5971 switch (Scheduler_getCurrentPriorityLevel()) {
5972 case Scheduler_ImmediatePriority:
5973 return ImmediatePriority;
5974 case Scheduler_UserBlockingPriority:
5975 return UserBlockingPriority$1;
5976 case Scheduler_NormalPriority:
5977 return NormalPriority;
5978 case Scheduler_LowPriority:
5979 return LowPriority;
5980 case Scheduler_IdlePriority:
5981 return IdlePriority;
5982 default:
5983 (function() {
5984 {
5985 throw ReactError(Error("Unknown priority level."));
5986 }
5987 })();
5988 }
5989}
5990
5991function reactPriorityToSchedulerPriority(reactPriorityLevel) {
5992 switch (reactPriorityLevel) {
5993 case ImmediatePriority:
5994 return Scheduler_ImmediatePriority;
5995 case UserBlockingPriority$1:
5996 return Scheduler_UserBlockingPriority;
5997 case NormalPriority:
5998 return Scheduler_NormalPriority;
5999 case LowPriority:
6000 return Scheduler_LowPriority;
6001 case IdlePriority:
6002 return Scheduler_IdlePriority;
6003 default:
6004 (function() {
6005 {
6006 throw ReactError(Error("Unknown priority level."));
6007 }
6008 })();
6009 }
6010}
6011
6012function runWithPriority$1(reactPriorityLevel, fn) {
6013 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
6014 return Scheduler_runWithPriority(priorityLevel, fn);
6015}
6016
6017function scheduleCallback(reactPriorityLevel, callback, options) {
6018 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
6019 return Scheduler_scheduleCallback(priorityLevel, callback, options);
6020}
6021
6022function scheduleSyncCallback(callback) {
6023 // Push this callback into an internal queue. We'll flush these either in
6024 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
6025 if (syncQueue === null) {
6026 syncQueue = [callback];
6027 // Flush the queue in the next tick, at the earliest.
6028 immediateQueueCallbackNode = Scheduler_scheduleCallback(
6029 Scheduler_ImmediatePriority,
6030 flushSyncCallbackQueueImpl
6031 );
6032 } else {
6033 // Push onto existing queue. Don't need to schedule a callback because
6034 // we already scheduled one when we created the queue.
6035 syncQueue.push(callback);
6036 }
6037 return fakeCallbackNode;
6038}
6039
6040function cancelCallback(callbackNode) {
6041 if (callbackNode !== fakeCallbackNode) {
6042 Scheduler_cancelCallback(callbackNode);
6043 }
6044}
6045
6046function flushSyncCallbackQueue() {
6047 if (immediateQueueCallbackNode !== null) {
6048 Scheduler_cancelCallback(immediateQueueCallbackNode);
6049 }
6050 flushSyncCallbackQueueImpl();
6051}
6052
6053function flushSyncCallbackQueueImpl() {
6054 if (!isFlushingSyncQueue && syncQueue !== null) {
6055 // Prevent re-entrancy.
6056 isFlushingSyncQueue = true;
6057 var i = 0;
6058 try {
6059 var _isSync = true;
6060 var queue = syncQueue;
6061 runWithPriority$1(ImmediatePriority, function() {
6062 for (; i < queue.length; i++) {
6063 var callback = queue[i];
6064 do {
6065 callback = callback(_isSync);
6066 } while (callback !== null);
6067 }
6068 });
6069 syncQueue = null;
6070 } catch (error) {
6071 // If something throws, leave the remaining callbacks on the queue.
6072 if (syncQueue !== null) {
6073 syncQueue = syncQueue.slice(i + 1);
6074 }
6075 // Resume flushing in the next tick
6076 Scheduler_scheduleCallback(
6077 Scheduler_ImmediatePriority,
6078 flushSyncCallbackQueue
6079 );
6080 throw error;
6081 } finally {
6082 isFlushingSyncQueue = false;
6083 }
6084 }
6085}
6086
6087var NoMode = 0;
6088var StrictMode = 1;
6089// TODO: Remove BatchedMode and ConcurrentMode by reading from the root
6090// tag instead
6091var BatchedMode = 2;
6092var ConcurrentMode = 4;
6093var ProfileMode = 8;
6094
6095// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
6096// Math.pow(2, 30) - 1
6097// 0b111111111111111111111111111111
6098var MAX_SIGNED_31_BIT_INT = 1073741823;
6099
6100var NoWork = 0;
6101var Never = 1;
6102var Sync = MAX_SIGNED_31_BIT_INT;
6103var Batched = Sync - 1;
6104
6105var UNIT_SIZE = 10;
6106var MAGIC_NUMBER_OFFSET = Batched - 1;
6107
6108// 1 unit of expiration time represents 10ms.
6109function msToExpirationTime(ms) {
6110 // Always add an offset so that we don't clash with the magic number for NoWork.
6111 return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0);
6112}
6113
6114function expirationTimeToMs(expirationTime) {
6115 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
6116}
6117
6118function ceiling(num, precision) {
6119 return (((num / precision) | 0) + 1) * precision;
6120}
6121
6122function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
6123 return (
6124 MAGIC_NUMBER_OFFSET -
6125 ceiling(
6126 MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE,
6127 bucketSizeMs / UNIT_SIZE
6128 )
6129 );
6130}
6131
6132// TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
6133// the names to reflect.
6134var LOW_PRIORITY_EXPIRATION = 5000;
6135var LOW_PRIORITY_BATCH_SIZE = 250;
6136
6137function computeAsyncExpiration(currentTime) {
6138 return computeExpirationBucket(
6139 currentTime,
6140 LOW_PRIORITY_EXPIRATION,
6141 LOW_PRIORITY_BATCH_SIZE
6142 );
6143}
6144
6145function computeSuspenseExpiration(currentTime, timeoutMs) {
6146 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
6147 return computeExpirationBucket(
6148 currentTime,
6149 timeoutMs,
6150 LOW_PRIORITY_BATCH_SIZE
6151 );
6152}
6153
6154// We intentionally set a higher expiration time for interactive updates in
6155// dev than in production.
6156//
6157// If the main thread is being blocked so long that you hit the expiration,
6158// it's a problem that could be solved with better scheduling.
6159//
6160// People will be more likely to notice this and fix it with the long
6161// expiration time in development.
6162//
6163// In production we opt for better UX at the risk of masking scheduling
6164// problems, by expiring fast.
6165var HIGH_PRIORITY_EXPIRATION = 500;
6166var HIGH_PRIORITY_BATCH_SIZE = 100;
6167
6168function computeInteractiveExpiration(currentTime) {
6169 return computeExpirationBucket(
6170 currentTime,
6171 HIGH_PRIORITY_EXPIRATION,
6172 HIGH_PRIORITY_BATCH_SIZE
6173 );
6174}
6175
6176function inferPriorityFromExpirationTime(currentTime, expirationTime) {
6177 if (expirationTime === Sync) {
6178 return ImmediatePriority;
6179 }
6180 if (expirationTime === Never) {
6181 return IdlePriority;
6182 }
6183 var msUntil =
6184 expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
6185 if (msUntil <= 0) {
6186 return ImmediatePriority;
6187 }
6188 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
6189 return UserBlockingPriority$1;
6190 }
6191 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
6192 return NormalPriority;
6193 }
6194
6195 // TODO: Handle LowPriority
6196
6197 // Assume anything lower has idle priority
6198 return IdlePriority;
6199}
6200
6201/**
6202 * inlined Object.is polyfill to avoid requiring consumers ship their own
6203 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
6204 */
6205function is(x, y) {
6206 return (
6207 (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare
6208 );
6209}
6210
6211var hasOwnProperty = Object.prototype.hasOwnProperty;
6212
6213/**
6214 * Performs equality by iterating through keys on an object and returning false
6215 * when any key has values which are not strictly equal between the arguments.
6216 * Returns true when the values of all keys are strictly equal.
6217 */
6218function shallowEqual(objA, objB) {
6219 if (is(objA, objB)) {
6220 return true;
6221 }
6222
6223 if (
6224 typeof objA !== "object" ||
6225 objA === null ||
6226 typeof objB !== "object" ||
6227 objB === null
6228 ) {
6229 return false;
6230 }
6231
6232 var keysA = Object.keys(objA);
6233 var keysB = Object.keys(objB);
6234
6235 if (keysA.length !== keysB.length) {
6236 return false;
6237 }
6238
6239 // Test for A's keys different from B.
6240 for (var i = 0; i < keysA.length; i++) {
6241 if (
6242 !hasOwnProperty.call(objB, keysA[i]) ||
6243 !is(objA[keysA[i]], objB[keysA[i]])
6244 ) {
6245 return false;
6246 }
6247 }
6248
6249 return true;
6250}
6251
6252/**
6253 * Forked from fbjs/warning:
6254 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
6255 *
6256 * Only change is we use console.warn instead of console.error,
6257 * and do nothing when 'console' is not supported.
6258 * This really simplifies the code.
6259 * ---
6260 * Similar to invariant but only logs a warning if the condition is not met.
6261 * This can be used to log issues in development environments in critical
6262 * paths. Removing the logging code for production environments will keep the
6263 * same logic and follow the same code paths.
6264 */
6265
6266var lowPriorityWarning = function() {};
6267
6268{
6269 var printWarning = function(format) {
6270 for (
6271 var _len = arguments.length,
6272 args = Array(_len > 1 ? _len - 1 : 0),
6273 _key = 1;
6274 _key < _len;
6275 _key++
6276 ) {
6277 args[_key - 1] = arguments[_key];
6278 }
6279
6280 var argIndex = 0;
6281 var message =
6282 "Warning: " +
6283 format.replace(/%s/g, function() {
6284 return args[argIndex++];
6285 });
6286 if (typeof console !== "undefined") {
6287 console.warn(message);
6288 }
6289 try {
6290 // --- Welcome to debugging React ---
6291 // This error was thrown as a convenience so that you can use this stack
6292 // to find the callsite that caused this warning to fire.
6293 throw new Error(message);
6294 } catch (x) {}
6295 };
6296
6297 lowPriorityWarning = function(condition, format) {
6298 if (format === undefined) {
6299 throw new Error(
6300 "`lowPriorityWarning(condition, format, ...args)` requires a warning " +
6301 "message argument"
6302 );
6303 }
6304 if (!condition) {
6305 for (
6306 var _len2 = arguments.length,
6307 args = Array(_len2 > 2 ? _len2 - 2 : 0),
6308 _key2 = 2;
6309 _key2 < _len2;
6310 _key2++
6311 ) {
6312 args[_key2 - 2] = arguments[_key2];
6313 }
6314
6315 printWarning.apply(undefined, [format].concat(args));
6316 }
6317 };
6318}
6319
6320var lowPriorityWarning$1 = lowPriorityWarning;
6321
6322var ReactStrictModeWarnings = {
6323 recordUnsafeLifecycleWarnings: function(fiber, instance) {},
6324 flushPendingUnsafeLifecycleWarnings: function() {},
6325 recordLegacyContextWarning: function(fiber, instance) {},
6326 flushLegacyContextWarning: function() {},
6327 discardPendingWarnings: function() {}
6328};
6329
6330{
6331 var findStrictRoot = function(fiber) {
6332 var maybeStrictRoot = null;
6333
6334 var node = fiber;
6335 while (node !== null) {
6336 if (node.mode & StrictMode) {
6337 maybeStrictRoot = node;
6338 }
6339 node = node.return;
6340 }
6341
6342 return maybeStrictRoot;
6343 };
6344
6345 var setToSortedString = function(set) {
6346 var array = [];
6347 set.forEach(function(value) {
6348 array.push(value);
6349 });
6350 return array.sort().join(", ");
6351 };
6352
6353 var pendingComponentWillMountWarnings = [];
6354 var pendingUNSAFE_ComponentWillMountWarnings = [];
6355 var pendingComponentWillReceivePropsWarnings = [];
6356 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
6357 var pendingComponentWillUpdateWarnings = [];
6358 var pendingUNSAFE_ComponentWillUpdateWarnings = [];
6359
6360 // Tracks components we have already warned about.
6361 var didWarnAboutUnsafeLifecycles = new Set();
6362
6363 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function(
6364 fiber,
6365 instance
6366 ) {
6367 // Dedup strategy: Warn once per component.
6368 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
6369 return;
6370 }
6371
6372 if (
6373 typeof instance.componentWillMount === "function" &&
6374 // Don't warn about react-lifecycles-compat polyfilled components.
6375 instance.componentWillMount.__suppressDeprecationWarning !== true
6376 ) {
6377 pendingComponentWillMountWarnings.push(fiber);
6378 }
6379
6380 if (
6381 fiber.mode & StrictMode &&
6382 typeof instance.UNSAFE_componentWillMount === "function"
6383 ) {
6384 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
6385 }
6386
6387 if (
6388 typeof instance.componentWillReceiveProps === "function" &&
6389 instance.componentWillReceiveProps.__suppressDeprecationWarning !== true
6390 ) {
6391 pendingComponentWillReceivePropsWarnings.push(fiber);
6392 }
6393
6394 if (
6395 fiber.mode & StrictMode &&
6396 typeof instance.UNSAFE_componentWillReceiveProps === "function"
6397 ) {
6398 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
6399 }
6400
6401 if (
6402 typeof instance.componentWillUpdate === "function" &&
6403 instance.componentWillUpdate.__suppressDeprecationWarning !== true
6404 ) {
6405 pendingComponentWillUpdateWarnings.push(fiber);
6406 }
6407
6408 if (
6409 fiber.mode & StrictMode &&
6410 typeof instance.UNSAFE_componentWillUpdate === "function"
6411 ) {
6412 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
6413 }
6414 };
6415
6416 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() {
6417 // We do an initial pass to gather component names
6418 var componentWillMountUniqueNames = new Set();
6419 if (pendingComponentWillMountWarnings.length > 0) {
6420 pendingComponentWillMountWarnings.forEach(function(fiber) {
6421 componentWillMountUniqueNames.add(
6422 getComponentName(fiber.type) || "Component"
6423 );
6424 didWarnAboutUnsafeLifecycles.add(fiber.type);
6425 });
6426 pendingComponentWillMountWarnings = [];
6427 }
6428
6429 var UNSAFE_componentWillMountUniqueNames = new Set();
6430 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
6431 pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) {
6432 UNSAFE_componentWillMountUniqueNames.add(
6433 getComponentName(fiber.type) || "Component"
6434 );
6435 didWarnAboutUnsafeLifecycles.add(fiber.type);
6436 });
6437 pendingUNSAFE_ComponentWillMountWarnings = [];
6438 }
6439
6440 var componentWillReceivePropsUniqueNames = new Set();
6441 if (pendingComponentWillReceivePropsWarnings.length > 0) {
6442 pendingComponentWillReceivePropsWarnings.forEach(function(fiber) {
6443 componentWillReceivePropsUniqueNames.add(
6444 getComponentName(fiber.type) || "Component"
6445 );
6446 didWarnAboutUnsafeLifecycles.add(fiber.type);
6447 });
6448
6449 pendingComponentWillReceivePropsWarnings = [];
6450 }
6451
6452 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
6453 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
6454 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) {
6455 UNSAFE_componentWillReceivePropsUniqueNames.add(
6456 getComponentName(fiber.type) || "Component"
6457 );
6458 didWarnAboutUnsafeLifecycles.add(fiber.type);
6459 });
6460
6461 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
6462 }
6463
6464 var componentWillUpdateUniqueNames = new Set();
6465 if (pendingComponentWillUpdateWarnings.length > 0) {
6466 pendingComponentWillUpdateWarnings.forEach(function(fiber) {
6467 componentWillUpdateUniqueNames.add(
6468 getComponentName(fiber.type) || "Component"
6469 );
6470 didWarnAboutUnsafeLifecycles.add(fiber.type);
6471 });
6472
6473 pendingComponentWillUpdateWarnings = [];
6474 }
6475
6476 var UNSAFE_componentWillUpdateUniqueNames = new Set();
6477 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
6478 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) {
6479 UNSAFE_componentWillUpdateUniqueNames.add(
6480 getComponentName(fiber.type) || "Component"
6481 );
6482 didWarnAboutUnsafeLifecycles.add(fiber.type);
6483 });
6484
6485 pendingUNSAFE_ComponentWillUpdateWarnings = [];
6486 }
6487
6488 // Finally, we flush all the warnings
6489 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
6490 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
6491 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
6492 warningWithoutStack$1(
6493 false,
6494 "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " +
6495 "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" +
6496 "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" +
6497 "\nPlease update the following components: %s",
6498 sortedNames
6499 );
6500 }
6501
6502 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
6503 var _sortedNames = setToSortedString(
6504 UNSAFE_componentWillReceivePropsUniqueNames
6505 );
6506 warningWithoutStack$1(
6507 false,
6508 "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " +
6509 "and may indicate bugs in your code. " +
6510 "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" +
6511 "* Move data fetching code or side effects to componentDidUpdate.\n" +
6512 "* If you're updating state whenever props change, " +
6513 "refactor your code to use memoization techniques or move it to " +
6514 "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" +
6515 "\nPlease update the following components: %s",
6516 _sortedNames
6517 );
6518 }
6519
6520 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
6521 var _sortedNames2 = setToSortedString(
6522 UNSAFE_componentWillUpdateUniqueNames
6523 );
6524 warningWithoutStack$1(
6525 false,
6526 "Using UNSAFE_componentWillUpdate in strict mode is not recommended " +
6527 "and may indicate bugs in your code. " +
6528 "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" +
6529 "* Move data fetching code or side effects to componentDidUpdate.\n" +
6530 "\nPlease update the following components: %s",
6531 _sortedNames2
6532 );
6533 }
6534
6535 if (componentWillMountUniqueNames.size > 0) {
6536 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
6537
6538 lowPriorityWarning$1(
6539 false,
6540 "componentWillMount has been renamed, and is not recommended for use. " +
6541 "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" +
6542 "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" +
6543 "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " +
6544 "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " +
6545 "To rename all deprecated lifecycles to their new names, you can run " +
6546 "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" +
6547 "\nPlease update the following components: %s",
6548 _sortedNames3
6549 );
6550 }
6551
6552 if (componentWillReceivePropsUniqueNames.size > 0) {
6553 var _sortedNames4 = setToSortedString(
6554 componentWillReceivePropsUniqueNames
6555 );
6556
6557 lowPriorityWarning$1(
6558 false,
6559 "componentWillReceiveProps has been renamed, and is not recommended for use. " +
6560 "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" +
6561 "* Move data fetching code or side effects to componentDidUpdate.\n" +
6562 "* If you're updating state whenever props change, refactor your " +
6563 "code to use memoization techniques or move it to " +
6564 "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" +
6565 "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " +
6566 "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " +
6567 "To rename all deprecated lifecycles to their new names, you can run " +
6568 "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" +
6569 "\nPlease update the following components: %s",
6570 _sortedNames4
6571 );
6572 }
6573
6574 if (componentWillUpdateUniqueNames.size > 0) {
6575 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
6576
6577 lowPriorityWarning$1(
6578 false,
6579 "componentWillUpdate has been renamed, and is not recommended for use. " +
6580 "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" +
6581 "* Move data fetching code or side effects to componentDidUpdate.\n" +
6582 "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " +
6583 "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " +
6584 "To rename all deprecated lifecycles to their new names, you can run " +
6585 "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" +
6586 "\nPlease update the following components: %s",
6587 _sortedNames5
6588 );
6589 }
6590 };
6591
6592 var pendingLegacyContextWarning = new Map();
6593
6594 // Tracks components we have already warned about.
6595 var didWarnAboutLegacyContext = new Set();
6596
6597 ReactStrictModeWarnings.recordLegacyContextWarning = function(
6598 fiber,
6599 instance
6600 ) {
6601 var strictRoot = findStrictRoot(fiber);
6602 if (strictRoot === null) {
6603 warningWithoutStack$1(
6604 false,
6605 "Expected to find a StrictMode component in a strict mode tree. " +
6606 "This error is likely caused by a bug in React. Please file an issue."
6607 );
6608 return;
6609 }
6610
6611 // Dedup strategy: Warn once per component.
6612 if (didWarnAboutLegacyContext.has(fiber.type)) {
6613 return;
6614 }
6615
6616 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
6617
6618 if (
6619 fiber.type.contextTypes != null ||
6620 fiber.type.childContextTypes != null ||
6621 (instance !== null && typeof instance.getChildContext === "function")
6622 ) {
6623 if (warningsForRoot === undefined) {
6624 warningsForRoot = [];
6625 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
6626 }
6627 warningsForRoot.push(fiber);
6628 }
6629 };
6630
6631 ReactStrictModeWarnings.flushLegacyContextWarning = function() {
6632 pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) {
6633 var uniqueNames = new Set();
6634 fiberArray.forEach(function(fiber) {
6635 uniqueNames.add(getComponentName(fiber.type) || "Component");
6636 didWarnAboutLegacyContext.add(fiber.type);
6637 });
6638
6639 var sortedNames = setToSortedString(uniqueNames);
6640 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
6641
6642 warningWithoutStack$1(
6643 false,
6644 "Legacy context API has been detected within a strict-mode tree: %s" +
6645 "\n\nThe old API will be supported in all 16.x releases, but applications " +
6646 "using it should migrate to the new version." +
6647 "\n\nPlease update the following components: %s" +
6648 "\n\nLearn more about this warning here:" +
6649 "\nhttps://fb.me/react-legacy-context",
6650 strictRootComponentStack,
6651 sortedNames
6652 );
6653 });
6654 };
6655
6656 ReactStrictModeWarnings.discardPendingWarnings = function() {
6657 pendingComponentWillMountWarnings = [];
6658 pendingUNSAFE_ComponentWillMountWarnings = [];
6659 pendingComponentWillReceivePropsWarnings = [];
6660 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
6661 pendingComponentWillUpdateWarnings = [];
6662 pendingUNSAFE_ComponentWillUpdateWarnings = [];
6663 pendingLegacyContextWarning = new Map();
6664 };
6665}
6666
6667// Resolves type to a family.
6668
6669// Used by React Refresh runtime through DevTools Global Hook.
6670
6671var resolveFamily = null;
6672// $FlowFixMe Flow gets confused by a WeakSet feature check below.
6673var failedBoundaries = null;
6674
6675var setRefreshHandler = function(handler) {
6676 {
6677 resolveFamily = handler;
6678 }
6679};
6680
6681function resolveFunctionForHotReloading(type) {
6682 {
6683 if (resolveFamily === null) {
6684 // Hot reloading is disabled.
6685 return type;
6686 }
6687 var family = resolveFamily(type);
6688 if (family === undefined) {
6689 return type;
6690 }
6691 // Use the latest known implementation.
6692 return family.current;
6693 }
6694}
6695
6696function resolveClassForHotReloading(type) {
6697 // No implementation differences.
6698 return resolveFunctionForHotReloading(type);
6699}
6700
6701function resolveForwardRefForHotReloading(type) {
6702 {
6703 if (resolveFamily === null) {
6704 // Hot reloading is disabled.
6705 return type;
6706 }
6707 var family = resolveFamily(type);
6708 if (family === undefined) {
6709 // Check if we're dealing with a real forwardRef. Don't want to crash early.
6710 if (
6711 type !== null &&
6712 type !== undefined &&
6713 typeof type.render === "function"
6714 ) {
6715 // ForwardRef is special because its resolved .type is an object,
6716 // but it's possible that we only have its inner render function in the map.
6717 // If that inner render function is different, we'll build a new forwardRef type.
6718 var currentRender = resolveFunctionForHotReloading(type.render);
6719 if (type.render !== currentRender) {
6720 var syntheticType = {
6721 $$typeof: REACT_FORWARD_REF_TYPE,
6722 render: currentRender
6723 };
6724 if (type.displayName !== undefined) {
6725 syntheticType.displayName = type.displayName;
6726 }
6727 return syntheticType;
6728 }
6729 }
6730 return type;
6731 }
6732 // Use the latest known implementation.
6733 return family.current;
6734 }
6735}
6736
6737function isCompatibleFamilyForHotReloading(fiber, element) {
6738 {
6739 if (resolveFamily === null) {
6740 // Hot reloading is disabled.
6741 return false;
6742 }
6743
6744 var prevType = fiber.elementType;
6745 var nextType = element.type;
6746
6747 // If we got here, we know types aren't === equal.
6748 var needsCompareFamilies = false;
6749
6750 var $$typeofNextType =
6751 typeof nextType === "object" && nextType !== null
6752 ? nextType.$$typeof
6753 : null;
6754
6755 switch (fiber.tag) {
6756 case ClassComponent: {
6757 if (typeof nextType === "function") {
6758 needsCompareFamilies = true;
6759 }
6760 break;
6761 }
6762 case FunctionComponent: {
6763 if (typeof nextType === "function") {
6764 needsCompareFamilies = true;
6765 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
6766 // We don't know the inner type yet.
6767 // We're going to assume that the lazy inner type is stable,
6768 // and so it is sufficient to avoid reconciling it away.
6769 // We're not going to unwrap or actually use the new lazy type.
6770 needsCompareFamilies = true;
6771 }
6772 break;
6773 }
6774 case ForwardRef: {
6775 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
6776 needsCompareFamilies = true;
6777 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
6778 needsCompareFamilies = true;
6779 }
6780 break;
6781 }
6782 case MemoComponent:
6783 case SimpleMemoComponent: {
6784 if ($$typeofNextType === REACT_MEMO_TYPE) {
6785 // TODO: if it was but can no longer be simple,
6786 // we shouldn't set this.
6787 needsCompareFamilies = true;
6788 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
6789 needsCompareFamilies = true;
6790 }
6791 break;
6792 }
6793 default:
6794 return false;
6795 }
6796
6797 // Check if both types have a family and it's the same one.
6798 if (needsCompareFamilies) {
6799 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
6800 // This means both of them need to be registered to preserve state.
6801 // If we unwrapped and compared the inner types for wrappers instead,
6802 // then we would risk falsely saying two separate memo(Foo)
6803 // calls are equivalent because they wrap the same Foo function.
6804 var prevFamily = resolveFamily(prevType);
6805 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
6806 return true;
6807 }
6808 }
6809 return false;
6810 }
6811}
6812
6813function markFailedErrorBoundaryForHotReloading(fiber) {
6814 {
6815 if (resolveFamily === null) {
6816 // Hot reloading is disabled.
6817 return;
6818 }
6819 if (typeof WeakSet !== "function") {
6820 return;
6821 }
6822 if (failedBoundaries === null) {
6823 failedBoundaries = new WeakSet();
6824 }
6825 failedBoundaries.add(fiber);
6826 }
6827}
6828
6829var scheduleRefresh = function(root, update) {
6830 {
6831 if (resolveFamily === null) {
6832 // Hot reloading is disabled.
6833 return;
6834 }
6835 var _staleFamilies = update.staleFamilies,
6836 _updatedFamilies = update.updatedFamilies;
6837
6838 flushPassiveEffects();
6839 flushSync(function() {
6840 scheduleFibersWithFamiliesRecursively(
6841 root.current,
6842 _updatedFamilies,
6843 _staleFamilies
6844 );
6845 });
6846 }
6847};
6848
6849var scheduleRoot = function(root, element) {
6850 {
6851 if (root.context !== emptyContextObject) {
6852 // Super edge case: root has a legacy _renderSubtree context
6853 // but we don't know the parentComponent so we can't pass it.
6854 // Just ignore. We'll delete this with _renderSubtree code path later.
6855 return;
6856 }
6857 flushPassiveEffects();
6858 updateContainerAtExpirationTime(element, root, null, Sync, null);
6859 }
6860};
6861
6862function scheduleFibersWithFamiliesRecursively(
6863 fiber,
6864 updatedFamilies,
6865 staleFamilies
6866) {
6867 {
6868 var alternate = fiber.alternate,
6869 child = fiber.child,
6870 sibling = fiber.sibling,
6871 tag = fiber.tag,
6872 type = fiber.type;
6873
6874 var candidateType = null;
6875 switch (tag) {
6876 case FunctionComponent:
6877 case SimpleMemoComponent:
6878 case ClassComponent:
6879 candidateType = type;
6880 break;
6881 case ForwardRef:
6882 candidateType = type.render;
6883 break;
6884 default:
6885 break;
6886 }
6887
6888 if (resolveFamily === null) {
6889 throw new Error("Expected resolveFamily to be set during hot reload.");
6890 }
6891
6892 var needsRender = false;
6893 var needsRemount = false;
6894 if (candidateType !== null) {
6895 var family = resolveFamily(candidateType);
6896 if (family !== undefined) {
6897 if (staleFamilies.has(family)) {
6898 needsRemount = true;
6899 } else if (updatedFamilies.has(family)) {
6900 if (tag === ClassComponent) {
6901 needsRemount = true;
6902 } else {
6903 needsRender = true;
6904 }
6905 }
6906 }
6907 }
6908 if (failedBoundaries !== null) {
6909 if (
6910 failedBoundaries.has(fiber) ||
6911 (alternate !== null && failedBoundaries.has(alternate))
6912 ) {
6913 needsRemount = true;
6914 }
6915 }
6916
6917 if (needsRemount) {
6918 fiber._debugNeedsRemount = true;
6919 }
6920 if (needsRemount || needsRender) {
6921 scheduleWork(fiber, Sync);
6922 }
6923 if (child !== null && !needsRemount) {
6924 scheduleFibersWithFamiliesRecursively(
6925 child,
6926 updatedFamilies,
6927 staleFamilies
6928 );
6929 }
6930 if (sibling !== null) {
6931 scheduleFibersWithFamiliesRecursively(
6932 sibling,
6933 updatedFamilies,
6934 staleFamilies
6935 );
6936 }
6937 }
6938}
6939
6940var findHostInstancesForRefresh = function(root, families) {
6941 {
6942 var hostInstances = new Set();
6943 var types = new Set(
6944 families.map(function(family) {
6945 return family.current;
6946 })
6947 );
6948 findHostInstancesForMatchingFibersRecursively(
6949 root.current,
6950 types,
6951 hostInstances
6952 );
6953 return hostInstances;
6954 }
6955};
6956
6957function findHostInstancesForMatchingFibersRecursively(
6958 fiber,
6959 types,
6960 hostInstances
6961) {
6962 {
6963 var child = fiber.child,
6964 sibling = fiber.sibling,
6965 tag = fiber.tag,
6966 type = fiber.type;
6967
6968 var candidateType = null;
6969 switch (tag) {
6970 case FunctionComponent:
6971 case SimpleMemoComponent:
6972 case ClassComponent:
6973 candidateType = type;
6974 break;
6975 case ForwardRef:
6976 candidateType = type.render;
6977 break;
6978 default:
6979 break;
6980 }
6981
6982 var didMatch = false;
6983 if (candidateType !== null) {
6984 if (types.has(candidateType)) {
6985 didMatch = true;
6986 }
6987 }
6988
6989 if (didMatch) {
6990 // We have a match. This only drills down to the closest host components.
6991 // There's no need to search deeper because for the purpose of giving
6992 // visual feedback, "flashing" outermost parent rectangles is sufficient.
6993 findHostInstancesForFiberShallowly(fiber, hostInstances);
6994 } else {
6995 // If there's no match, maybe there will be one further down in the child tree.
6996 if (child !== null) {
6997 findHostInstancesForMatchingFibersRecursively(
6998 child,
6999 types,
7000 hostInstances
7001 );
7002 }
7003 }
7004
7005 if (sibling !== null) {
7006 findHostInstancesForMatchingFibersRecursively(
7007 sibling,
7008 types,
7009 hostInstances
7010 );
7011 }
7012 }
7013}
7014
7015function findHostInstancesForFiberShallowly(fiber, hostInstances) {
7016 {
7017 var foundHostInstances = findChildHostInstancesForFiberShallowly(
7018 fiber,
7019 hostInstances
7020 );
7021 if (foundHostInstances) {
7022 return;
7023 }
7024 // If we didn't find any host children, fallback to closest host parent.
7025 var node = fiber;
7026 while (true) {
7027 switch (node.tag) {
7028 case HostComponent:
7029 hostInstances.add(node.stateNode);
7030 return;
7031 case HostPortal:
7032 hostInstances.add(node.stateNode.containerInfo);
7033 return;
7034 case HostRoot:
7035 hostInstances.add(node.stateNode.containerInfo);
7036 return;
7037 }
7038 if (node.return === null) {
7039 throw new Error("Expected to reach root first.");
7040 }
7041 node = node.return;
7042 }
7043 }
7044}
7045
7046function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
7047 {
7048 var node = fiber;
7049 var foundHostInstances = false;
7050 while (true) {
7051 if (node.tag === HostComponent) {
7052 // We got a match.
7053 foundHostInstances = true;
7054 hostInstances.add(node.stateNode);
7055 // There may still be more, so keep searching.
7056 } else if (node.child !== null) {
7057 node.child.return = node;
7058 node = node.child;
7059 continue;
7060 }
7061 if (node === fiber) {
7062 return foundHostInstances;
7063 }
7064 while (node.sibling === null) {
7065 if (node.return === null || node.return === fiber) {
7066 return foundHostInstances;
7067 }
7068 node = node.return;
7069 }
7070 node.sibling.return = node.return;
7071 node = node.sibling;
7072 }
7073 }
7074 return false;
7075}
7076
7077function resolveDefaultProps(Component, baseProps) {
7078 if (Component && Component.defaultProps) {
7079 // Resolve default props. Taken from ReactElement
7080 var props = Object.assign({}, baseProps);
7081 var defaultProps = Component.defaultProps;
7082 for (var propName in defaultProps) {
7083 if (props[propName] === undefined) {
7084 props[propName] = defaultProps[propName];
7085 }
7086 }
7087 return props;
7088 }
7089 return baseProps;
7090}
7091
7092function readLazyComponentType(lazyComponent) {
7093 var status = lazyComponent._status;
7094 var result = lazyComponent._result;
7095 switch (status) {
7096 case Resolved: {
7097 var Component = result;
7098 return Component;
7099 }
7100 case Rejected: {
7101 var error = result;
7102 throw error;
7103 }
7104 case Pending: {
7105 var thenable = result;
7106 throw thenable;
7107 }
7108 default: {
7109 lazyComponent._status = Pending;
7110 var ctor = lazyComponent._ctor;
7111 var _thenable = ctor();
7112 _thenable.then(
7113 function(moduleObject) {
7114 if (lazyComponent._status === Pending) {
7115 var defaultExport = moduleObject.default;
7116 {
7117 if (defaultExport === undefined) {
7118 warning$1(
7119 false,
7120 "lazy: Expected the result of a dynamic import() call. " +
7121 "Instead received: %s\n\nYour code should look like: \n " +
7122 "const MyComponent = lazy(() => import('./MyComponent'))",
7123 moduleObject
7124 );
7125 }
7126 }
7127 lazyComponent._status = Resolved;
7128 lazyComponent._result = defaultExport;
7129 }
7130 },
7131 function(error) {
7132 if (lazyComponent._status === Pending) {
7133 lazyComponent._status = Rejected;
7134 lazyComponent._result = error;
7135 }
7136 }
7137 );
7138 // Handle synchronous thenables.
7139 switch (lazyComponent._status) {
7140 case Resolved:
7141 return lazyComponent._result;
7142 case Rejected:
7143 throw lazyComponent._result;
7144 }
7145 lazyComponent._result = _thenable;
7146 throw _thenable;
7147 }
7148 }
7149}
7150
7151var valueCursor = createCursor(null);
7152
7153var rendererSigil = void 0;
7154{
7155 // Use this to detect multiple renderers using the same context
7156 rendererSigil = {};
7157}
7158
7159var currentlyRenderingFiber = null;
7160var lastContextDependency = null;
7161var lastContextWithAllBitsObserved = null;
7162
7163var isDisallowedContextReadInDEV = false;
7164
7165function resetContextDependencies() {
7166 // This is called right before React yields execution, to ensure `readContext`
7167 // cannot be called outside the render phase.
7168 currentlyRenderingFiber = null;
7169 lastContextDependency = null;
7170 lastContextWithAllBitsObserved = null;
7171 {
7172 isDisallowedContextReadInDEV = false;
7173 }
7174}
7175
7176function enterDisallowedContextReadInDEV() {
7177 {
7178 isDisallowedContextReadInDEV = true;
7179 }
7180}
7181
7182function exitDisallowedContextReadInDEV() {
7183 {
7184 isDisallowedContextReadInDEV = false;
7185 }
7186}
7187
7188function pushProvider(providerFiber, nextValue) {
7189 var context = providerFiber.type._context;
7190
7191 if (isPrimaryRenderer) {
7192 push(valueCursor, context._currentValue, providerFiber);
7193
7194 context._currentValue = nextValue;
7195 {
7196 !(
7197 context._currentRenderer === undefined ||
7198 context._currentRenderer === null ||
7199 context._currentRenderer === rendererSigil
7200 )
7201 ? warningWithoutStack$1(
7202 false,
7203 "Detected multiple renderers concurrently rendering the " +
7204 "same context provider. This is currently unsupported."
7205 )
7206 : void 0;
7207 context._currentRenderer = rendererSigil;
7208 }
7209 } else {
7210 push(valueCursor, context._currentValue2, providerFiber);
7211
7212 context._currentValue2 = nextValue;
7213 {
7214 !(
7215 context._currentRenderer2 === undefined ||
7216 context._currentRenderer2 === null ||
7217 context._currentRenderer2 === rendererSigil
7218 )
7219 ? warningWithoutStack$1(
7220 false,
7221 "Detected multiple renderers concurrently rendering the " +
7222 "same context provider. This is currently unsupported."
7223 )
7224 : void 0;
7225 context._currentRenderer2 = rendererSigil;
7226 }
7227 }
7228}
7229
7230function popProvider(providerFiber) {
7231 var currentValue = valueCursor.current;
7232
7233 pop(valueCursor, providerFiber);
7234
7235 var context = providerFiber.type._context;
7236 if (isPrimaryRenderer) {
7237 context._currentValue = currentValue;
7238 } else {
7239 context._currentValue2 = currentValue;
7240 }
7241}
7242
7243function calculateChangedBits(context, newValue, oldValue) {
7244 if (is(oldValue, newValue)) {
7245 // No change
7246 return 0;
7247 } else {
7248 var changedBits =
7249 typeof context._calculateChangedBits === "function"
7250 ? context._calculateChangedBits(oldValue, newValue)
7251 : MAX_SIGNED_31_BIT_INT;
7252
7253 {
7254 !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits)
7255 ? warning$1(
7256 false,
7257 "calculateChangedBits: Expected the return value to be a " +
7258 "31-bit integer. Instead received: %s",
7259 changedBits
7260 )
7261 : void 0;
7262 }
7263 return changedBits | 0;
7264 }
7265}
7266
7267function scheduleWorkOnParentPath(parent, renderExpirationTime) {
7268 // Update the child expiration time of all the ancestors, including
7269 // the alternates.
7270 var node = parent;
7271 while (node !== null) {
7272 var alternate = node.alternate;
7273 if (node.childExpirationTime < renderExpirationTime) {
7274 node.childExpirationTime = renderExpirationTime;
7275 if (
7276 alternate !== null &&
7277 alternate.childExpirationTime < renderExpirationTime
7278 ) {
7279 alternate.childExpirationTime = renderExpirationTime;
7280 }
7281 } else if (
7282 alternate !== null &&
7283 alternate.childExpirationTime < renderExpirationTime
7284 ) {
7285 alternate.childExpirationTime = renderExpirationTime;
7286 } else {
7287 // Neither alternate was updated, which means the rest of the
7288 // ancestor path already has sufficient priority.
7289 break;
7290 }
7291 node = node.return;
7292 }
7293}
7294
7295function propagateContextChange(
7296 workInProgress,
7297 context,
7298 changedBits,
7299 renderExpirationTime
7300) {
7301 var fiber = workInProgress.child;
7302 if (fiber !== null) {
7303 // Set the return pointer of the child to the work-in-progress fiber.
7304 fiber.return = workInProgress;
7305 }
7306 while (fiber !== null) {
7307 var nextFiber = void 0;
7308
7309 // Visit this fiber.
7310 var list = fiber.dependencies;
7311 if (list !== null) {
7312 nextFiber = fiber.child;
7313
7314 var dependency = list.firstContext;
7315 while (dependency !== null) {
7316 // Check if the context matches.
7317 if (
7318 dependency.context === context &&
7319 (dependency.observedBits & changedBits) !== 0
7320 ) {
7321 // Match! Schedule an update on this fiber.
7322
7323 if (fiber.tag === ClassComponent) {
7324 // Schedule a force update on the work-in-progress.
7325 var update = createUpdate(renderExpirationTime, null);
7326 update.tag = ForceUpdate;
7327 // TODO: Because we don't have a work-in-progress, this will add the
7328 // update to the current fiber, too, which means it will persist even if
7329 // this render is thrown away. Since it's a race condition, not sure it's
7330 // worth fixing.
7331 enqueueUpdate(fiber, update);
7332 }
7333
7334 if (fiber.expirationTime < renderExpirationTime) {
7335 fiber.expirationTime = renderExpirationTime;
7336 }
7337 var alternate = fiber.alternate;
7338 if (
7339 alternate !== null &&
7340 alternate.expirationTime < renderExpirationTime
7341 ) {
7342 alternate.expirationTime = renderExpirationTime;
7343 }
7344
7345 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
7346
7347 // Mark the expiration time on the list, too.
7348 if (list.expirationTime < renderExpirationTime) {
7349 list.expirationTime = renderExpirationTime;
7350 }
7351
7352 // Since we already found a match, we can stop traversing the
7353 // dependency list.
7354 break;
7355 }
7356 dependency = dependency.next;
7357 }
7358 } else if (fiber.tag === ContextProvider) {
7359 // Don't scan deeper if this is a matching provider
7360 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
7361 } else if (
7362 enableSuspenseServerRenderer &&
7363 fiber.tag === DehydratedSuspenseComponent
7364 ) {
7365 // If a dehydrated suspense component is in this subtree, we don't know
7366 // if it will have any context consumers in it. The best we can do is
7367 // mark it as having updates on its children.
7368 if (fiber.expirationTime < renderExpirationTime) {
7369 fiber.expirationTime = renderExpirationTime;
7370 }
7371 var _alternate = fiber.alternate;
7372 if (
7373 _alternate !== null &&
7374 _alternate.expirationTime < renderExpirationTime
7375 ) {
7376 _alternate.expirationTime = renderExpirationTime;
7377 }
7378 // This is intentionally passing this fiber as the parent
7379 // because we want to schedule this fiber as having work
7380 // on its children. We'll use the childExpirationTime on
7381 // this fiber to indicate that a context has changed.
7382 scheduleWorkOnParentPath(fiber, renderExpirationTime);
7383 nextFiber = fiber.sibling;
7384 } else {
7385 // Traverse down.
7386 nextFiber = fiber.child;
7387 }
7388
7389 if (nextFiber !== null) {
7390 // Set the return pointer of the child to the work-in-progress fiber.
7391 nextFiber.return = fiber;
7392 } else {
7393 // No child. Traverse to next sibling.
7394 nextFiber = fiber;
7395 while (nextFiber !== null) {
7396 if (nextFiber === workInProgress) {
7397 // We're back to the root of this subtree. Exit.
7398 nextFiber = null;
7399 break;
7400 }
7401 var sibling = nextFiber.sibling;
7402 if (sibling !== null) {
7403 // Set the return pointer of the sibling to the work-in-progress fiber.
7404 sibling.return = nextFiber.return;
7405 nextFiber = sibling;
7406 break;
7407 }
7408 // No more siblings. Traverse up.
7409 nextFiber = nextFiber.return;
7410 }
7411 }
7412 fiber = nextFiber;
7413 }
7414}
7415
7416function prepareToReadContext(workInProgress, renderExpirationTime) {
7417 currentlyRenderingFiber = workInProgress;
7418 lastContextDependency = null;
7419 lastContextWithAllBitsObserved = null;
7420
7421 var dependencies = workInProgress.dependencies;
7422 if (dependencies !== null) {
7423 var firstContext = dependencies.firstContext;
7424 if (firstContext !== null) {
7425 if (dependencies.expirationTime >= renderExpirationTime) {
7426 // Context list has a pending update. Mark that this fiber performed work.
7427 markWorkInProgressReceivedUpdate();
7428 }
7429 // Reset the work-in-progress list
7430 dependencies.firstContext = null;
7431 }
7432 }
7433}
7434
7435function readContext(context, observedBits) {
7436 {
7437 // This warning would fire if you read context inside a Hook like useMemo.
7438 // Unlike the class check below, it's not enforced in production for perf.
7439 !!isDisallowedContextReadInDEV
7440 ? warning$1(
7441 false,
7442 "Context can only be read while React is rendering. " +
7443 "In classes, you can read it in the render method or getDerivedStateFromProps. " +
7444 "In function components, you can read it directly in the function body, but not " +
7445 "inside Hooks like useReducer() or useMemo()."
7446 )
7447 : void 0;
7448 }
7449
7450 if (lastContextWithAllBitsObserved === context) {
7451 // Nothing to do. We already observe everything in this context.
7452 } else if (observedBits === false || observedBits === 0) {
7453 // Do not observe any updates.
7454 } else {
7455 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
7456 if (
7457 typeof observedBits !== "number" ||
7458 observedBits === MAX_SIGNED_31_BIT_INT
7459 ) {
7460 // Observe all updates.
7461 lastContextWithAllBitsObserved = context;
7462 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
7463 } else {
7464 resolvedObservedBits = observedBits;
7465 }
7466
7467 var contextItem = {
7468 context: context,
7469 observedBits: resolvedObservedBits,
7470 next: null
7471 };
7472
7473 if (lastContextDependency === null) {
7474 (function() {
7475 if (!(currentlyRenderingFiber !== null)) {
7476 throw ReactError(
7477 Error(
7478 "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()."
7479 )
7480 );
7481 }
7482 })();
7483
7484 // This is the first dependency for this component. Create a new list.
7485 lastContextDependency = contextItem;
7486 currentlyRenderingFiber.dependencies = {
7487 expirationTime: NoWork,
7488 firstContext: contextItem,
7489 responders: null
7490 };
7491 } else {
7492 // Append a new context item.
7493 lastContextDependency = lastContextDependency.next = contextItem;
7494 }
7495 }
7496 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
7497}
7498
7499// UpdateQueue is a linked list of prioritized updates.
7500//
7501// Like fibers, update queues come in pairs: a current queue, which represents
7502// the visible state of the screen, and a work-in-progress queue, which can be
7503// mutated and processed asynchronously before it is committed — a form of
7504// double buffering. If a work-in-progress render is discarded before finishing,
7505// we create a new work-in-progress by cloning the current queue.
7506//
7507// Both queues share a persistent, singly-linked list structure. To schedule an
7508// update, we append it to the end of both queues. Each queue maintains a
7509// pointer to first update in the persistent list that hasn't been processed.
7510// The work-in-progress pointer always has a position equal to or greater than
7511// the current queue, since we always work on that one. The current queue's
7512// pointer is only updated during the commit phase, when we swap in the
7513// work-in-progress.
7514//
7515// For example:
7516//
7517// Current pointer: A - B - C - D - E - F
7518// Work-in-progress pointer: D - E - F
7519// ^
7520// The work-in-progress queue has
7521// processed more updates than current.
7522//
7523// The reason we append to both queues is because otherwise we might drop
7524// updates without ever processing them. For example, if we only add updates to
7525// the work-in-progress queue, some updates could be lost whenever a work-in
7526// -progress render restarts by cloning from current. Similarly, if we only add
7527// updates to the current queue, the updates will be lost whenever an already
7528// in-progress queue commits and swaps with the current queue. However, by
7529// adding to both queues, we guarantee that the update will be part of the next
7530// work-in-progress. (And because the work-in-progress queue becomes the
7531// current queue once it commits, there's no danger of applying the same
7532// update twice.)
7533//
7534// Prioritization
7535// --------------
7536//
7537// Updates are not sorted by priority, but by insertion; new updates are always
7538// appended to the end of the list.
7539//
7540// The priority is still important, though. When processing the update queue
7541// during the render phase, only the updates with sufficient priority are
7542// included in the result. If we skip an update because it has insufficient
7543// priority, it remains in the queue to be processed later, during a lower
7544// priority render. Crucially, all updates subsequent to a skipped update also
7545// remain in the queue *regardless of their priority*. That means high priority
7546// updates are sometimes processed twice, at two separate priorities. We also
7547// keep track of a base state, that represents the state before the first
7548// update in the queue is applied.
7549//
7550// For example:
7551//
7552// Given a base state of '', and the following queue of updates
7553//
7554// A1 - B2 - C1 - D2
7555//
7556// where the number indicates the priority, and the update is applied to the
7557// previous state by appending a letter, React will process these updates as
7558// two separate renders, one per distinct priority level:
7559//
7560// First render, at priority 1:
7561// Base state: ''
7562// Updates: [A1, C1]
7563// Result state: 'AC'
7564//
7565// Second render, at priority 2:
7566// Base state: 'A' <- The base state does not include C1,
7567// because B2 was skipped.
7568// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
7569// Result state: 'ABCD'
7570//
7571// Because we process updates in insertion order, and rebase high priority
7572// updates when preceding updates are skipped, the final result is deterministic
7573// regardless of priority. Intermediate state may vary according to system
7574// resources, but the final state is always the same.
7575
7576var UpdateState = 0;
7577var ReplaceState = 1;
7578var ForceUpdate = 2;
7579var CaptureUpdate = 3;
7580
7581// Global state that is reset at the beginning of calling `processUpdateQueue`.
7582// It should only be read right after calling `processUpdateQueue`, via
7583// `checkHasForceUpdateAfterProcessing`.
7584var hasForceUpdate = false;
7585
7586var didWarnUpdateInsideUpdate = void 0;
7587var currentlyProcessingQueue = void 0;
7588
7589{
7590 didWarnUpdateInsideUpdate = false;
7591 currentlyProcessingQueue = null;
7592}
7593
7594function createUpdateQueue(baseState) {
7595 var queue = {
7596 baseState: baseState,
7597 firstUpdate: null,
7598 lastUpdate: null,
7599 firstCapturedUpdate: null,
7600 lastCapturedUpdate: null,
7601 firstEffect: null,
7602 lastEffect: null,
7603 firstCapturedEffect: null,
7604 lastCapturedEffect: null
7605 };
7606 return queue;
7607}
7608
7609function cloneUpdateQueue(currentQueue) {
7610 var queue = {
7611 baseState: currentQueue.baseState,
7612 firstUpdate: currentQueue.firstUpdate,
7613 lastUpdate: currentQueue.lastUpdate,
7614
7615 // TODO: With resuming, if we bail out and resuse the child tree, we should
7616 // keep these effects.
7617 firstCapturedUpdate: null,
7618 lastCapturedUpdate: null,
7619
7620 firstEffect: null,
7621 lastEffect: null,
7622
7623 firstCapturedEffect: null,
7624 lastCapturedEffect: null
7625 };
7626 return queue;
7627}
7628
7629function createUpdate(expirationTime, suspenseConfig) {
7630 var update = {
7631 expirationTime: expirationTime,
7632 suspenseConfig: suspenseConfig,
7633
7634 tag: UpdateState,
7635 payload: null,
7636 callback: null,
7637
7638 next: null,
7639 nextEffect: null
7640 };
7641 {
7642 update.priority = getCurrentPriorityLevel();
7643 }
7644 return update;
7645}
7646
7647function appendUpdateToQueue(queue, update) {
7648 // Append the update to the end of the list.
7649 if (queue.lastUpdate === null) {
7650 // Queue is empty
7651 queue.firstUpdate = queue.lastUpdate = update;
7652 } else {
7653 queue.lastUpdate.next = update;
7654 queue.lastUpdate = update;
7655 }
7656}
7657
7658function enqueueUpdate(fiber, update) {
7659 // Update queues are created lazily.
7660 var alternate = fiber.alternate;
7661 var queue1 = void 0;
7662 var queue2 = void 0;
7663 if (alternate === null) {
7664 // There's only one fiber.
7665 queue1 = fiber.updateQueue;
7666 queue2 = null;
7667 if (queue1 === null) {
7668 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
7669 }
7670 } else {
7671 // There are two owners.
7672 queue1 = fiber.updateQueue;
7673 queue2 = alternate.updateQueue;
7674 if (queue1 === null) {
7675 if (queue2 === null) {
7676 // Neither fiber has an update queue. Create new ones.
7677 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
7678 queue2 = alternate.updateQueue = createUpdateQueue(
7679 alternate.memoizedState
7680 );
7681 } else {
7682 // Only one fiber has an update queue. Clone to create a new one.
7683 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
7684 }
7685 } else {
7686 if (queue2 === null) {
7687 // Only one fiber has an update queue. Clone to create a new one.
7688 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
7689 } else {
7690 // Both owners have an update queue.
7691 }
7692 }
7693 }
7694 if (queue2 === null || queue1 === queue2) {
7695 // There's only a single queue.
7696 appendUpdateToQueue(queue1, update);
7697 } else {
7698 // There are two queues. We need to append the update to both queues,
7699 // while accounting for the persistent structure of the list — we don't
7700 // want the same update to be added multiple times.
7701 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
7702 // One of the queues is not empty. We must add the update to both queues.
7703 appendUpdateToQueue(queue1, update);
7704 appendUpdateToQueue(queue2, update);
7705 } else {
7706 // Both queues are non-empty. The last update is the same in both lists,
7707 // because of structural sharing. So, only append to one of the lists.
7708 appendUpdateToQueue(queue1, update);
7709 // But we still need to update the `lastUpdate` pointer of queue2.
7710 queue2.lastUpdate = update;
7711 }
7712 }
7713
7714 {
7715 if (
7716 fiber.tag === ClassComponent &&
7717 (currentlyProcessingQueue === queue1 ||
7718 (queue2 !== null && currentlyProcessingQueue === queue2)) &&
7719 !didWarnUpdateInsideUpdate
7720 ) {
7721 warningWithoutStack$1(
7722 false,
7723 "An update (setState, replaceState, or forceUpdate) was scheduled " +
7724 "from inside an update function. Update functions should be pure, " +
7725 "with zero side-effects. Consider using componentDidUpdate or a " +
7726 "callback."
7727 );
7728 didWarnUpdateInsideUpdate = true;
7729 }
7730 }
7731}
7732
7733function enqueueCapturedUpdate(workInProgress, update) {
7734 // Captured updates go into a separate list, and only on the work-in-
7735 // progress queue.
7736 var workInProgressQueue = workInProgress.updateQueue;
7737 if (workInProgressQueue === null) {
7738 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(
7739 workInProgress.memoizedState
7740 );
7741 } else {
7742 // TODO: I put this here rather than createWorkInProgress so that we don't
7743 // clone the queue unnecessarily. There's probably a better way to
7744 // structure this.
7745 workInProgressQueue = ensureWorkInProgressQueueIsAClone(
7746 workInProgress,
7747 workInProgressQueue
7748 );
7749 }
7750
7751 // Append the update to the end of the list.
7752 if (workInProgressQueue.lastCapturedUpdate === null) {
7753 // This is the first render phase update
7754 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
7755 } else {
7756 workInProgressQueue.lastCapturedUpdate.next = update;
7757 workInProgressQueue.lastCapturedUpdate = update;
7758 }
7759}
7760
7761function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
7762 var current = workInProgress.alternate;
7763 if (current !== null) {
7764 // If the work-in-progress queue is equal to the current queue,
7765 // we need to clone it first.
7766 if (queue === current.updateQueue) {
7767 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
7768 }
7769 }
7770 return queue;
7771}
7772
7773function getStateFromUpdate(
7774 workInProgress,
7775 queue,
7776 update,
7777 prevState,
7778 nextProps,
7779 instance
7780) {
7781 switch (update.tag) {
7782 case ReplaceState: {
7783 var _payload = update.payload;
7784 if (typeof _payload === "function") {
7785 // Updater function
7786 {
7787 enterDisallowedContextReadInDEV();
7788 if (
7789 debugRenderPhaseSideEffects ||
7790 (debugRenderPhaseSideEffectsForStrictMode &&
7791 workInProgress.mode & StrictMode)
7792 ) {
7793 _payload.call(instance, prevState, nextProps);
7794 }
7795 }
7796 var nextState = _payload.call(instance, prevState, nextProps);
7797 {
7798 exitDisallowedContextReadInDEV();
7799 }
7800 return nextState;
7801 }
7802 // State object
7803 return _payload;
7804 }
7805 case CaptureUpdate: {
7806 workInProgress.effectTag =
7807 (workInProgress.effectTag & ~ShouldCapture) | DidCapture;
7808 }
7809 // Intentional fallthrough
7810 case UpdateState: {
7811 var _payload2 = update.payload;
7812 var partialState = void 0;
7813 if (typeof _payload2 === "function") {
7814 // Updater function
7815 {
7816 enterDisallowedContextReadInDEV();
7817 if (
7818 debugRenderPhaseSideEffects ||
7819 (debugRenderPhaseSideEffectsForStrictMode &&
7820 workInProgress.mode & StrictMode)
7821 ) {
7822 _payload2.call(instance, prevState, nextProps);
7823 }
7824 }
7825 partialState = _payload2.call(instance, prevState, nextProps);
7826 {
7827 exitDisallowedContextReadInDEV();
7828 }
7829 } else {
7830 // Partial state object
7831 partialState = _payload2;
7832 }
7833 if (partialState === null || partialState === undefined) {
7834 // Null and undefined are treated as no-ops.
7835 return prevState;
7836 }
7837 // Merge the partial state and the previous state.
7838 return Object.assign({}, prevState, partialState);
7839 }
7840 case ForceUpdate: {
7841 hasForceUpdate = true;
7842 return prevState;
7843 }
7844 }
7845 return prevState;
7846}
7847
7848function processUpdateQueue(
7849 workInProgress,
7850 queue,
7851 props,
7852 instance,
7853 renderExpirationTime
7854) {
7855 hasForceUpdate = false;
7856
7857 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
7858
7859 {
7860 currentlyProcessingQueue = queue;
7861 }
7862
7863 // These values may change as we process the queue.
7864 var newBaseState = queue.baseState;
7865 var newFirstUpdate = null;
7866 var newExpirationTime = NoWork;
7867
7868 // Iterate through the list of updates to compute the result.
7869 var update = queue.firstUpdate;
7870 var resultState = newBaseState;
7871 while (update !== null) {
7872 var updateExpirationTime = update.expirationTime;
7873 if (updateExpirationTime < renderExpirationTime) {
7874 // This update does not have sufficient priority. Skip it.
7875 if (newFirstUpdate === null) {
7876 // This is the first skipped update. It will be the first update in
7877 // the new list.
7878 newFirstUpdate = update;
7879 // Since this is the first update that was skipped, the current result
7880 // is the new base state.
7881 newBaseState = resultState;
7882 }
7883 // Since this update will remain in the list, update the remaining
7884 // expiration time.
7885 if (newExpirationTime < updateExpirationTime) {
7886 newExpirationTime = updateExpirationTime;
7887 }
7888 } else {
7889 // This update does have sufficient priority.
7890
7891 // Mark the event time of this update as relevant to this render pass.
7892 // TODO: This should ideally use the true event time of this update rather than
7893 // its priority which is a derived and not reverseable value.
7894 // TODO: We should skip this update if it was already committed but currently
7895 // we have no way of detecting the difference between a committed and suspended
7896 // update here.
7897 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig);
7898
7899 // Process it and compute a new result.
7900 resultState = getStateFromUpdate(
7901 workInProgress,
7902 queue,
7903 update,
7904 resultState,
7905 props,
7906 instance
7907 );
7908 var _callback = update.callback;
7909 if (_callback !== null) {
7910 workInProgress.effectTag |= Callback;
7911 // Set this to null, in case it was mutated during an aborted render.
7912 update.nextEffect = null;
7913 if (queue.lastEffect === null) {
7914 queue.firstEffect = queue.lastEffect = update;
7915 } else {
7916 queue.lastEffect.nextEffect = update;
7917 queue.lastEffect = update;
7918 }
7919 }
7920 }
7921 // Continue to the next update.
7922 update = update.next;
7923 }
7924
7925 // Separately, iterate though the list of captured updates.
7926 var newFirstCapturedUpdate = null;
7927 update = queue.firstCapturedUpdate;
7928 while (update !== null) {
7929 var _updateExpirationTime = update.expirationTime;
7930 if (_updateExpirationTime < renderExpirationTime) {
7931 // This update does not have sufficient priority. Skip it.
7932 if (newFirstCapturedUpdate === null) {
7933 // This is the first skipped captured update. It will be the first
7934 // update in the new list.
7935 newFirstCapturedUpdate = update;
7936 // If this is the first update that was skipped, the current result is
7937 // the new base state.
7938 if (newFirstUpdate === null) {
7939 newBaseState = resultState;
7940 }
7941 }
7942 // Since this update will remain in the list, update the remaining
7943 // expiration time.
7944 if (newExpirationTime < _updateExpirationTime) {
7945 newExpirationTime = _updateExpirationTime;
7946 }
7947 } else {
7948 // This update does have sufficient priority. Process it and compute
7949 // a new result.
7950 resultState = getStateFromUpdate(
7951 workInProgress,
7952 queue,
7953 update,
7954 resultState,
7955 props,
7956 instance
7957 );
7958 var _callback2 = update.callback;
7959 if (_callback2 !== null) {
7960 workInProgress.effectTag |= Callback;
7961 // Set this to null, in case it was mutated during an aborted render.
7962 update.nextEffect = null;
7963 if (queue.lastCapturedEffect === null) {
7964 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
7965 } else {
7966 queue.lastCapturedEffect.nextEffect = update;
7967 queue.lastCapturedEffect = update;
7968 }
7969 }
7970 }
7971 update = update.next;
7972 }
7973
7974 if (newFirstUpdate === null) {
7975 queue.lastUpdate = null;
7976 }
7977 if (newFirstCapturedUpdate === null) {
7978 queue.lastCapturedUpdate = null;
7979 } else {
7980 workInProgress.effectTag |= Callback;
7981 }
7982 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
7983 // We processed every update, without skipping. That means the new base
7984 // state is the same as the result state.
7985 newBaseState = resultState;
7986 }
7987
7988 queue.baseState = newBaseState;
7989 queue.firstUpdate = newFirstUpdate;
7990 queue.firstCapturedUpdate = newFirstCapturedUpdate;
7991
7992 // Set the remaining expiration time to be whatever is remaining in the queue.
7993 // This should be fine because the only two other things that contribute to
7994 // expiration time are props and context. We're already in the middle of the
7995 // begin phase by the time we start processing the queue, so we've already
7996 // dealt with the props. Context in components that specify
7997 // shouldComponentUpdate is tricky; but we'll have to account for
7998 // that regardless.
7999 workInProgress.expirationTime = newExpirationTime;
8000 workInProgress.memoizedState = resultState;
8001
8002 {
8003 currentlyProcessingQueue = null;
8004 }
8005}
8006
8007function callCallback(callback, context) {
8008 (function() {
8009 if (!(typeof callback === "function")) {
8010 throw ReactError(
8011 Error(
8012 "Invalid argument passed as callback. Expected a function. Instead received: " +
8013 callback
8014 )
8015 );
8016 }
8017 })();
8018 callback.call(context);
8019}
8020
8021function resetHasForceUpdateBeforeProcessing() {
8022 hasForceUpdate = false;
8023}
8024
8025function checkHasForceUpdateAfterProcessing() {
8026 return hasForceUpdate;
8027}
8028
8029function commitUpdateQueue(
8030 finishedWork,
8031 finishedQueue,
8032 instance,
8033 renderExpirationTime
8034) {
8035 // If the finished render included captured updates, and there are still
8036 // lower priority updates left over, we need to keep the captured updates
8037 // in the queue so that they are rebased and not dropped once we process the
8038 // queue again at the lower priority.
8039 if (finishedQueue.firstCapturedUpdate !== null) {
8040 // Join the captured update list to the end of the normal list.
8041 if (finishedQueue.lastUpdate !== null) {
8042 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
8043 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
8044 }
8045 // Clear the list of captured updates.
8046 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
8047 }
8048
8049 // Commit the effects
8050 commitUpdateEffects(finishedQueue.firstEffect, instance);
8051 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
8052
8053 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
8054 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
8055}
8056
8057function commitUpdateEffects(effect, instance) {
8058 while (effect !== null) {
8059 var _callback3 = effect.callback;
8060 if (_callback3 !== null) {
8061 effect.callback = null;
8062 callCallback(_callback3, instance);
8063 }
8064 effect = effect.nextEffect;
8065 }
8066}
8067
8068var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
8069
8070function requestCurrentSuspenseConfig() {
8071 return ReactCurrentBatchConfig.suspense;
8072}
8073
8074var fakeInternalInstance = {};
8075var isArray$1 = Array.isArray;
8076
8077// React.Component uses a shared frozen object by default.
8078// We'll use it to determine whether we need to initialize legacy refs.
8079var emptyRefsObject = new React.Component().refs;
8080
8081var didWarnAboutStateAssignmentForComponent = void 0;
8082var didWarnAboutUninitializedState = void 0;
8083var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
8084var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
8085var didWarnAboutUndefinedDerivedState = void 0;
8086var warnOnUndefinedDerivedState = void 0;
8087var warnOnInvalidCallback = void 0;
8088var didWarnAboutDirectlyAssigningPropsToState = void 0;
8089var didWarnAboutContextTypeAndContextTypes = void 0;
8090var didWarnAboutInvalidateContextType = void 0;
8091
8092{
8093 didWarnAboutStateAssignmentForComponent = new Set();
8094 didWarnAboutUninitializedState = new Set();
8095 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
8096 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
8097 didWarnAboutDirectlyAssigningPropsToState = new Set();
8098 didWarnAboutUndefinedDerivedState = new Set();
8099 didWarnAboutContextTypeAndContextTypes = new Set();
8100 didWarnAboutInvalidateContextType = new Set();
8101
8102 var didWarnOnInvalidCallback = new Set();
8103
8104 warnOnInvalidCallback = function(callback, callerName) {
8105 if (callback === null || typeof callback === "function") {
8106 return;
8107 }
8108 var key = callerName + "_" + callback;
8109 if (!didWarnOnInvalidCallback.has(key)) {
8110 didWarnOnInvalidCallback.add(key);
8111 warningWithoutStack$1(
8112 false,
8113 "%s(...): Expected the last optional `callback` argument to be a " +
8114 "function. Instead received: %s.",
8115 callerName,
8116 callback
8117 );
8118 }
8119 };
8120
8121 warnOnUndefinedDerivedState = function(type, partialState) {
8122 if (partialState === undefined) {
8123 var componentName = getComponentName(type) || "Component";
8124 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
8125 didWarnAboutUndefinedDerivedState.add(componentName);
8126 warningWithoutStack$1(
8127 false,
8128 "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " +
8129 "You have returned undefined.",
8130 componentName
8131 );
8132 }
8133 }
8134 };
8135
8136 // This is so gross but it's at least non-critical and can be removed if
8137 // it causes problems. This is meant to give a nicer error message for
8138 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
8139 // ...)) which otherwise throws a "_processChildContext is not a function"
8140 // exception.
8141 Object.defineProperty(fakeInternalInstance, "_processChildContext", {
8142 enumerable: false,
8143 value: function() {
8144 (function() {
8145 {
8146 throw ReactError(
8147 Error(
8148 "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)."
8149 )
8150 );
8151 }
8152 })();
8153 }
8154 });
8155 Object.freeze(fakeInternalInstance);
8156}
8157
8158function applyDerivedStateFromProps(
8159 workInProgress,
8160 ctor,
8161 getDerivedStateFromProps,
8162 nextProps
8163) {
8164 var prevState = workInProgress.memoizedState;
8165
8166 {
8167 if (
8168 debugRenderPhaseSideEffects ||
8169 (debugRenderPhaseSideEffectsForStrictMode &&
8170 workInProgress.mode & StrictMode)
8171 ) {
8172 // Invoke the function an extra time to help detect side-effects.
8173 getDerivedStateFromProps(nextProps, prevState);
8174 }
8175 }
8176
8177 var partialState = getDerivedStateFromProps(nextProps, prevState);
8178
8179 {
8180 warnOnUndefinedDerivedState(ctor, partialState);
8181 }
8182 // Merge the partial state and the previous state.
8183 var memoizedState =
8184 partialState === null || partialState === undefined
8185 ? prevState
8186 : Object.assign({}, prevState, partialState);
8187 workInProgress.memoizedState = memoizedState;
8188
8189 // Once the update queue is empty, persist the derived state onto the
8190 // base state.
8191 var updateQueue = workInProgress.updateQueue;
8192 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
8193 updateQueue.baseState = memoizedState;
8194 }
8195}
8196
8197var classComponentUpdater = {
8198 isMounted: isMounted,
8199 enqueueSetState: function(inst, payload, callback) {
8200 var fiber = get(inst);
8201 var currentTime = requestCurrentTime();
8202 var suspenseConfig = requestCurrentSuspenseConfig();
8203 var expirationTime = computeExpirationForFiber(
8204 currentTime,
8205 fiber,
8206 suspenseConfig
8207 );
8208
8209 var update = createUpdate(expirationTime, suspenseConfig);
8210 update.payload = payload;
8211 if (callback !== undefined && callback !== null) {
8212 {
8213 warnOnInvalidCallback(callback, "setState");
8214 }
8215 update.callback = callback;
8216 }
8217
8218 if (revertPassiveEffectsChange) {
8219 flushPassiveEffects();
8220 }
8221 enqueueUpdate(fiber, update);
8222 scheduleWork(fiber, expirationTime);
8223 },
8224 enqueueReplaceState: function(inst, payload, callback) {
8225 var fiber = get(inst);
8226 var currentTime = requestCurrentTime();
8227 var suspenseConfig = requestCurrentSuspenseConfig();
8228 var expirationTime = computeExpirationForFiber(
8229 currentTime,
8230 fiber,
8231 suspenseConfig
8232 );
8233
8234 var update = createUpdate(expirationTime, suspenseConfig);
8235 update.tag = ReplaceState;
8236 update.payload = payload;
8237
8238 if (callback !== undefined && callback !== null) {
8239 {
8240 warnOnInvalidCallback(callback, "replaceState");
8241 }
8242 update.callback = callback;
8243 }
8244
8245 if (revertPassiveEffectsChange) {
8246 flushPassiveEffects();
8247 }
8248 enqueueUpdate(fiber, update);
8249 scheduleWork(fiber, expirationTime);
8250 },
8251 enqueueForceUpdate: function(inst, callback) {
8252 var fiber = get(inst);
8253 var currentTime = requestCurrentTime();
8254 var suspenseConfig = requestCurrentSuspenseConfig();
8255 var expirationTime = computeExpirationForFiber(
8256 currentTime,
8257 fiber,
8258 suspenseConfig
8259 );
8260
8261 var update = createUpdate(expirationTime, suspenseConfig);
8262 update.tag = ForceUpdate;
8263
8264 if (callback !== undefined && callback !== null) {
8265 {
8266 warnOnInvalidCallback(callback, "forceUpdate");
8267 }
8268 update.callback = callback;
8269 }
8270
8271 if (revertPassiveEffectsChange) {
8272 flushPassiveEffects();
8273 }
8274 enqueueUpdate(fiber, update);
8275 scheduleWork(fiber, expirationTime);
8276 }
8277};
8278
8279function checkShouldComponentUpdate(
8280 workInProgress,
8281 ctor,
8282 oldProps,
8283 newProps,
8284 oldState,
8285 newState,
8286 nextContext
8287) {
8288 var instance = workInProgress.stateNode;
8289 if (typeof instance.shouldComponentUpdate === "function") {
8290 startPhaseTimer(workInProgress, "shouldComponentUpdate");
8291 var shouldUpdate = instance.shouldComponentUpdate(
8292 newProps,
8293 newState,
8294 nextContext
8295 );
8296 stopPhaseTimer();
8297
8298 {
8299 !(shouldUpdate !== undefined)
8300 ? warningWithoutStack$1(
8301 false,
8302 "%s.shouldComponentUpdate(): Returned undefined instead of a " +
8303 "boolean value. Make sure to return true or false.",
8304 getComponentName(ctor) || "Component"
8305 )
8306 : void 0;
8307 }
8308
8309 return shouldUpdate;
8310 }
8311
8312 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
8313 return (
8314 !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
8315 );
8316 }
8317
8318 return true;
8319}
8320
8321function checkClassInstance(workInProgress, ctor, newProps) {
8322 var instance = workInProgress.stateNode;
8323 {
8324 var name = getComponentName(ctor) || "Component";
8325 var renderPresent = instance.render;
8326
8327 if (!renderPresent) {
8328 if (ctor.prototype && typeof ctor.prototype.render === "function") {
8329 warningWithoutStack$1(
8330 false,
8331 "%s(...): No `render` method found on the returned component " +
8332 "instance: did you accidentally return an object from the constructor?",
8333 name
8334 );
8335 } else {
8336 warningWithoutStack$1(
8337 false,
8338 "%s(...): No `render` method found on the returned component " +
8339 "instance: you may have forgotten to define `render`.",
8340 name
8341 );
8342 }
8343 }
8344
8345 var noGetInitialStateOnES6 =
8346 !instance.getInitialState ||
8347 instance.getInitialState.isReactClassApproved ||
8348 instance.state;
8349 !noGetInitialStateOnES6
8350 ? warningWithoutStack$1(
8351 false,
8352 "getInitialState was defined on %s, a plain JavaScript class. " +
8353 "This is only supported for classes created using React.createClass. " +
8354 "Did you mean to define a state property instead?",
8355 name
8356 )
8357 : void 0;
8358 var noGetDefaultPropsOnES6 =
8359 !instance.getDefaultProps ||
8360 instance.getDefaultProps.isReactClassApproved;
8361 !noGetDefaultPropsOnES6
8362 ? warningWithoutStack$1(
8363 false,
8364 "getDefaultProps was defined on %s, a plain JavaScript class. " +
8365 "This is only supported for classes created using React.createClass. " +
8366 "Use a static property to define defaultProps instead.",
8367 name
8368 )
8369 : void 0;
8370 var noInstancePropTypes = !instance.propTypes;
8371 !noInstancePropTypes
8372 ? warningWithoutStack$1(
8373 false,
8374 "propTypes was defined as an instance property on %s. Use a static " +
8375 "property to define propTypes instead.",
8376 name
8377 )
8378 : void 0;
8379 var noInstanceContextType = !instance.contextType;
8380 !noInstanceContextType
8381 ? warningWithoutStack$1(
8382 false,
8383 "contextType was defined as an instance property on %s. Use a static " +
8384 "property to define contextType instead.",
8385 name
8386 )
8387 : void 0;
8388
8389 if (disableLegacyContext) {
8390 if (ctor.childContextTypes) {
8391 warningWithoutStack$1(
8392 false,
8393 "%s uses the legacy childContextTypes API which is no longer supported. " +
8394 "Use React.createContext() instead.",
8395 name
8396 );
8397 }
8398 if (ctor.contextTypes) {
8399 warningWithoutStack$1(
8400 false,
8401 "%s uses the legacy contextTypes API which is no longer supported. " +
8402 "Use React.createContext() with static contextType instead.",
8403 name
8404 );
8405 }
8406 } else {
8407 var noInstanceContextTypes = !instance.contextTypes;
8408 !noInstanceContextTypes
8409 ? warningWithoutStack$1(
8410 false,
8411 "contextTypes was defined as an instance property on %s. Use a static " +
8412 "property to define contextTypes instead.",
8413 name
8414 )
8415 : void 0;
8416
8417 if (
8418 ctor.contextType &&
8419 ctor.contextTypes &&
8420 !didWarnAboutContextTypeAndContextTypes.has(ctor)
8421 ) {
8422 didWarnAboutContextTypeAndContextTypes.add(ctor);
8423 warningWithoutStack$1(
8424 false,
8425 "%s declares both contextTypes and contextType static properties. " +
8426 "The legacy contextTypes property will be ignored.",
8427 name
8428 );
8429 }
8430 }
8431
8432 var noComponentShouldUpdate =
8433 typeof instance.componentShouldUpdate !== "function";
8434 !noComponentShouldUpdate
8435 ? warningWithoutStack$1(
8436 false,
8437 "%s has a method called " +
8438 "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " +
8439 "The name is phrased as a question because the function is " +
8440 "expected to return a value.",
8441 name
8442 )
8443 : void 0;
8444 if (
8445 ctor.prototype &&
8446 ctor.prototype.isPureReactComponent &&
8447 typeof instance.shouldComponentUpdate !== "undefined"
8448 ) {
8449 warningWithoutStack$1(
8450 false,
8451 "%s has a method called shouldComponentUpdate(). " +
8452 "shouldComponentUpdate should not be used when extending React.PureComponent. " +
8453 "Please extend React.Component if shouldComponentUpdate is used.",
8454 getComponentName(ctor) || "A pure component"
8455 );
8456 }
8457 var noComponentDidUnmount =
8458 typeof instance.componentDidUnmount !== "function";
8459 !noComponentDidUnmount
8460 ? warningWithoutStack$1(
8461 false,
8462 "%s has a method called " +
8463 "componentDidUnmount(). But there is no such lifecycle method. " +
8464 "Did you mean componentWillUnmount()?",
8465 name
8466 )
8467 : void 0;
8468 var noComponentDidReceiveProps =
8469 typeof instance.componentDidReceiveProps !== "function";
8470 !noComponentDidReceiveProps
8471 ? warningWithoutStack$1(
8472 false,
8473 "%s has a method called " +
8474 "componentDidReceiveProps(). But there is no such lifecycle method. " +
8475 "If you meant to update the state in response to changing props, " +
8476 "use componentWillReceiveProps(). If you meant to fetch data or " +
8477 "run side-effects or mutations after React has updated the UI, use componentDidUpdate().",
8478 name
8479 )
8480 : void 0;
8481 var noComponentWillRecieveProps =
8482 typeof instance.componentWillRecieveProps !== "function";
8483 !noComponentWillRecieveProps
8484 ? warningWithoutStack$1(
8485 false,
8486 "%s has a method called " +
8487 "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?",
8488 name
8489 )
8490 : void 0;
8491 var noUnsafeComponentWillRecieveProps =
8492 typeof instance.UNSAFE_componentWillRecieveProps !== "function";
8493 !noUnsafeComponentWillRecieveProps
8494 ? warningWithoutStack$1(
8495 false,
8496 "%s has a method called " +
8497 "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?",
8498 name
8499 )
8500 : void 0;
8501 var hasMutatedProps = instance.props !== newProps;
8502 !(instance.props === undefined || !hasMutatedProps)
8503 ? warningWithoutStack$1(
8504 false,
8505 "%s(...): When calling super() in `%s`, make sure to pass " +
8506 "up the same props that your component's constructor was passed.",
8507 name,
8508 name
8509 )
8510 : void 0;
8511 var noInstanceDefaultProps = !instance.defaultProps;
8512 !noInstanceDefaultProps
8513 ? warningWithoutStack$1(
8514 false,
8515 "Setting defaultProps as an instance property on %s is not supported and will be ignored." +
8516 " Instead, define defaultProps as a static property on %s.",
8517 name,
8518 name
8519 )
8520 : void 0;
8521
8522 if (
8523 typeof instance.getSnapshotBeforeUpdate === "function" &&
8524 typeof instance.componentDidUpdate !== "function" &&
8525 !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)
8526 ) {
8527 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
8528 warningWithoutStack$1(
8529 false,
8530 "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " +
8531 "This component defines getSnapshotBeforeUpdate() only.",
8532 getComponentName(ctor)
8533 );
8534 }
8535
8536 var noInstanceGetDerivedStateFromProps =
8537 typeof instance.getDerivedStateFromProps !== "function";
8538 !noInstanceGetDerivedStateFromProps
8539 ? warningWithoutStack$1(
8540 false,
8541 "%s: getDerivedStateFromProps() is defined as an instance method " +
8542 "and will be ignored. Instead, declare it as a static method.",
8543 name
8544 )
8545 : void 0;
8546 var noInstanceGetDerivedStateFromCatch =
8547 typeof instance.getDerivedStateFromError !== "function";
8548 !noInstanceGetDerivedStateFromCatch
8549 ? warningWithoutStack$1(
8550 false,
8551 "%s: getDerivedStateFromError() is defined as an instance method " +
8552 "and will be ignored. Instead, declare it as a static method.",
8553 name
8554 )
8555 : void 0;
8556 var noStaticGetSnapshotBeforeUpdate =
8557 typeof ctor.getSnapshotBeforeUpdate !== "function";
8558 !noStaticGetSnapshotBeforeUpdate
8559 ? warningWithoutStack$1(
8560 false,
8561 "%s: getSnapshotBeforeUpdate() is defined as a static method " +
8562 "and will be ignored. Instead, declare it as an instance method.",
8563 name
8564 )
8565 : void 0;
8566 var _state = instance.state;
8567 if (_state && (typeof _state !== "object" || isArray$1(_state))) {
8568 warningWithoutStack$1(
8569 false,
8570 "%s.state: must be set to an object or null",
8571 name
8572 );
8573 }
8574 if (typeof instance.getChildContext === "function") {
8575 !(typeof ctor.childContextTypes === "object")
8576 ? warningWithoutStack$1(
8577 false,
8578 "%s.getChildContext(): childContextTypes must be defined in order to " +
8579 "use getChildContext().",
8580 name
8581 )
8582 : void 0;
8583 }
8584 }
8585}
8586
8587function adoptClassInstance(workInProgress, instance) {
8588 instance.updater = classComponentUpdater;
8589 workInProgress.stateNode = instance;
8590 // The instance needs access to the fiber so that it can schedule updates
8591 set(instance, workInProgress);
8592 {
8593 instance._reactInternalInstance = fakeInternalInstance;
8594 }
8595}
8596
8597function constructClassInstance(
8598 workInProgress,
8599 ctor,
8600 props,
8601 renderExpirationTime
8602) {
8603 var isLegacyContextConsumer = false;
8604 var unmaskedContext = emptyContextObject;
8605 var context = emptyContextObject;
8606 var contextType = ctor.contextType;
8607
8608 {
8609 if ("contextType" in ctor) {
8610 var isValid =
8611 // Allow null for conditional declaration
8612 contextType === null ||
8613 (contextType !== undefined &&
8614 contextType.$$typeof === REACT_CONTEXT_TYPE &&
8615 contextType._context === undefined); // Not a <Context.Consumer>
8616
8617 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
8618 didWarnAboutInvalidateContextType.add(ctor);
8619
8620 var addendum = "";
8621 if (contextType === undefined) {
8622 addendum =
8623 " However, it is set to undefined. " +
8624 "This can be caused by a typo or by mixing up named and default imports. " +
8625 "This can also happen due to a circular dependency, so " +
8626 "try moving the createContext() call to a separate file.";
8627 } else if (typeof contextType !== "object") {
8628 addendum = " However, it is set to a " + typeof contextType + ".";
8629 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
8630 addendum = " Did you accidentally pass the Context.Provider instead?";
8631 } else if (contextType._context !== undefined) {
8632 // <Context.Consumer>
8633 addendum = " Did you accidentally pass the Context.Consumer instead?";
8634 } else {
8635 addendum =
8636 " However, it is set to an object with keys {" +
8637 Object.keys(contextType).join(", ") +
8638 "}.";
8639 }
8640 warningWithoutStack$1(
8641 false,
8642 "%s defines an invalid contextType. " +
8643 "contextType should point to the Context object returned by React.createContext().%s",
8644 getComponentName(ctor) || "Component",
8645 addendum
8646 );
8647 }
8648 }
8649 }
8650
8651 if (typeof contextType === "object" && contextType !== null) {
8652 context = readContext(contextType);
8653 } else if (!disableLegacyContext) {
8654 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
8655 var contextTypes = ctor.contextTypes;
8656 isLegacyContextConsumer =
8657 contextTypes !== null && contextTypes !== undefined;
8658 context = isLegacyContextConsumer
8659 ? getMaskedContext(workInProgress, unmaskedContext)
8660 : emptyContextObject;
8661 }
8662
8663 // Instantiate twice to help detect side-effects.
8664 {
8665 if (
8666 debugRenderPhaseSideEffects ||
8667 (debugRenderPhaseSideEffectsForStrictMode &&
8668 workInProgress.mode & StrictMode)
8669 ) {
8670 new ctor(props, context); // eslint-disable-line no-new
8671 }
8672 }
8673
8674 var instance = new ctor(props, context);
8675 var state = (workInProgress.memoizedState =
8676 instance.state !== null && instance.state !== undefined
8677 ? instance.state
8678 : null);
8679 adoptClassInstance(workInProgress, instance);
8680
8681 {
8682 if (typeof ctor.getDerivedStateFromProps === "function" && state === null) {
8683 var componentName = getComponentName(ctor) || "Component";
8684 if (!didWarnAboutUninitializedState.has(componentName)) {
8685 didWarnAboutUninitializedState.add(componentName);
8686 warningWithoutStack$1(
8687 false,
8688 "`%s` uses `getDerivedStateFromProps` but its initial state is " +
8689 "%s. This is not recommended. Instead, define the initial state by " +
8690 "assigning an object to `this.state` in the constructor of `%s`. " +
8691 "This ensures that `getDerivedStateFromProps` arguments have a consistent shape.",
8692 componentName,
8693 instance.state === null ? "null" : "undefined",
8694 componentName
8695 );
8696 }
8697 }
8698
8699 // If new component APIs are defined, "unsafe" lifecycles won't be called.
8700 // Warn about these lifecycles if they are present.
8701 // Don't warn about react-lifecycles-compat polyfilled methods though.
8702 if (
8703 typeof ctor.getDerivedStateFromProps === "function" ||
8704 typeof instance.getSnapshotBeforeUpdate === "function"
8705 ) {
8706 var foundWillMountName = null;
8707 var foundWillReceivePropsName = null;
8708 var foundWillUpdateName = null;
8709 if (
8710 typeof instance.componentWillMount === "function" &&
8711 instance.componentWillMount.__suppressDeprecationWarning !== true
8712 ) {
8713 foundWillMountName = "componentWillMount";
8714 } else if (typeof instance.UNSAFE_componentWillMount === "function") {
8715 foundWillMountName = "UNSAFE_componentWillMount";
8716 }
8717 if (
8718 typeof instance.componentWillReceiveProps === "function" &&
8719 instance.componentWillReceiveProps.__suppressDeprecationWarning !== true
8720 ) {
8721 foundWillReceivePropsName = "componentWillReceiveProps";
8722 } else if (
8723 typeof instance.UNSAFE_componentWillReceiveProps === "function"
8724 ) {
8725 foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps";
8726 }
8727 if (
8728 typeof instance.componentWillUpdate === "function" &&
8729 instance.componentWillUpdate.__suppressDeprecationWarning !== true
8730 ) {
8731 foundWillUpdateName = "componentWillUpdate";
8732 } else if (typeof instance.UNSAFE_componentWillUpdate === "function") {
8733 foundWillUpdateName = "UNSAFE_componentWillUpdate";
8734 }
8735 if (
8736 foundWillMountName !== null ||
8737 foundWillReceivePropsName !== null ||
8738 foundWillUpdateName !== null
8739 ) {
8740 var _componentName = getComponentName(ctor) || "Component";
8741 var newApiName =
8742 typeof ctor.getDerivedStateFromProps === "function"
8743 ? "getDerivedStateFromProps()"
8744 : "getSnapshotBeforeUpdate()";
8745 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
8746 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
8747 warningWithoutStack$1(
8748 false,
8749 "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" +
8750 "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" +
8751 "The above lifecycles should be removed. Learn more about this warning here:\n" +
8752 "https://fb.me/react-async-component-lifecycle-hooks",
8753 _componentName,
8754 newApiName,
8755 foundWillMountName !== null ? "\n " + foundWillMountName : "",
8756 foundWillReceivePropsName !== null
8757 ? "\n " + foundWillReceivePropsName
8758 : "",
8759 foundWillUpdateName !== null ? "\n " + foundWillUpdateName : ""
8760 );
8761 }
8762 }
8763 }
8764 }
8765
8766 // Cache unmasked context so we can avoid recreating masked context unless necessary.
8767 // ReactFiberContext usually updates this cache but can't for newly-created instances.
8768 if (isLegacyContextConsumer) {
8769 cacheContext(workInProgress, unmaskedContext, context);
8770 }
8771
8772 return instance;
8773}
8774
8775function callComponentWillMount(workInProgress, instance) {
8776 startPhaseTimer(workInProgress, "componentWillMount");
8777 var oldState = instance.state;
8778
8779 if (typeof instance.componentWillMount === "function") {
8780 instance.componentWillMount();
8781 }
8782 if (typeof instance.UNSAFE_componentWillMount === "function") {
8783 instance.UNSAFE_componentWillMount();
8784 }
8785
8786 stopPhaseTimer();
8787
8788 if (oldState !== instance.state) {
8789 {
8790 warningWithoutStack$1(
8791 false,
8792 "%s.componentWillMount(): Assigning directly to this.state is " +
8793 "deprecated (except inside a component's " +
8794 "constructor). Use setState instead.",
8795 getComponentName(workInProgress.type) || "Component"
8796 );
8797 }
8798 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
8799 }
8800}
8801
8802function callComponentWillReceiveProps(
8803 workInProgress,
8804 instance,
8805 newProps,
8806 nextContext
8807) {
8808 var oldState = instance.state;
8809 startPhaseTimer(workInProgress, "componentWillReceiveProps");
8810 if (typeof instance.componentWillReceiveProps === "function") {
8811 instance.componentWillReceiveProps(newProps, nextContext);
8812 }
8813 if (typeof instance.UNSAFE_componentWillReceiveProps === "function") {
8814 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
8815 }
8816 stopPhaseTimer();
8817
8818 if (instance.state !== oldState) {
8819 {
8820 var componentName = getComponentName(workInProgress.type) || "Component";
8821 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
8822 didWarnAboutStateAssignmentForComponent.add(componentName);
8823 warningWithoutStack$1(
8824 false,
8825 "%s.componentWillReceiveProps(): Assigning directly to " +
8826 "this.state is deprecated (except inside a component's " +
8827 "constructor). Use setState instead.",
8828 componentName
8829 );
8830 }
8831 }
8832 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
8833 }
8834}
8835
8836// Invokes the mount life-cycles on a previously never rendered instance.
8837function mountClassInstance(
8838 workInProgress,
8839 ctor,
8840 newProps,
8841 renderExpirationTime
8842) {
8843 {
8844 checkClassInstance(workInProgress, ctor, newProps);
8845 }
8846
8847 var instance = workInProgress.stateNode;
8848 instance.props = newProps;
8849 instance.state = workInProgress.memoizedState;
8850 instance.refs = emptyRefsObject;
8851
8852 var contextType = ctor.contextType;
8853 if (typeof contextType === "object" && contextType !== null) {
8854 instance.context = readContext(contextType);
8855 } else if (disableLegacyContext) {
8856 instance.context = emptyContextObject;
8857 } else {
8858 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
8859 instance.context = getMaskedContext(workInProgress, unmaskedContext);
8860 }
8861
8862 {
8863 if (instance.state === newProps) {
8864 var componentName = getComponentName(ctor) || "Component";
8865 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
8866 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
8867 warningWithoutStack$1(
8868 false,
8869 "%s: It is not recommended to assign props directly to state " +
8870 "because updates to props won't be reflected in state. " +
8871 "In most cases, it is better to use props directly.",
8872 componentName
8873 );
8874 }
8875 }
8876
8877 if (workInProgress.mode & StrictMode) {
8878 ReactStrictModeWarnings.recordLegacyContextWarning(
8879 workInProgress,
8880 instance
8881 );
8882 }
8883
8884 if (warnAboutDeprecatedLifecycles) {
8885 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(
8886 workInProgress,
8887 instance
8888 );
8889 }
8890 }
8891
8892 var updateQueue = workInProgress.updateQueue;
8893 if (updateQueue !== null) {
8894 processUpdateQueue(
8895 workInProgress,
8896 updateQueue,
8897 newProps,
8898 instance,
8899 renderExpirationTime
8900 );
8901 instance.state = workInProgress.memoizedState;
8902 }
8903
8904 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
8905 if (typeof getDerivedStateFromProps === "function") {
8906 applyDerivedStateFromProps(
8907 workInProgress,
8908 ctor,
8909 getDerivedStateFromProps,
8910 newProps
8911 );
8912 instance.state = workInProgress.memoizedState;
8913 }
8914
8915 // In order to support react-lifecycles-compat polyfilled components,
8916 // Unsafe lifecycles should not be invoked for components using the new APIs.
8917 if (
8918 typeof ctor.getDerivedStateFromProps !== "function" &&
8919 typeof instance.getSnapshotBeforeUpdate !== "function" &&
8920 (typeof instance.UNSAFE_componentWillMount === "function" ||
8921 typeof instance.componentWillMount === "function")
8922 ) {
8923 callComponentWillMount(workInProgress, instance);
8924 // If we had additional state updates during this life-cycle, let's
8925 // process them now.
8926 updateQueue = workInProgress.updateQueue;
8927 if (updateQueue !== null) {
8928 processUpdateQueue(
8929 workInProgress,
8930 updateQueue,
8931 newProps,
8932 instance,
8933 renderExpirationTime
8934 );
8935 instance.state = workInProgress.memoizedState;
8936 }
8937 }
8938
8939 if (typeof instance.componentDidMount === "function") {
8940 workInProgress.effectTag |= Update;
8941 }
8942}
8943
8944function resumeMountClassInstance(
8945 workInProgress,
8946 ctor,
8947 newProps,
8948 renderExpirationTime
8949) {
8950 var instance = workInProgress.stateNode;
8951
8952 var oldProps = workInProgress.memoizedProps;
8953 instance.props = oldProps;
8954
8955 var oldContext = instance.context;
8956 var contextType = ctor.contextType;
8957 var nextContext = emptyContextObject;
8958 if (typeof contextType === "object" && contextType !== null) {
8959 nextContext = readContext(contextType);
8960 } else if (!disableLegacyContext) {
8961 var nextLegacyUnmaskedContext = getUnmaskedContext(
8962 workInProgress,
8963 ctor,
8964 true
8965 );
8966 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
8967 }
8968
8969 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
8970 var hasNewLifecycles =
8971 typeof getDerivedStateFromProps === "function" ||
8972 typeof instance.getSnapshotBeforeUpdate === "function";
8973
8974 // Note: During these life-cycles, instance.props/instance.state are what
8975 // ever the previously attempted to render - not the "current". However,
8976 // during componentDidUpdate we pass the "current" props.
8977
8978 // In order to support react-lifecycles-compat polyfilled components,
8979 // Unsafe lifecycles should not be invoked for components using the new APIs.
8980 if (
8981 !hasNewLifecycles &&
8982 (typeof instance.UNSAFE_componentWillReceiveProps === "function" ||
8983 typeof instance.componentWillReceiveProps === "function")
8984 ) {
8985 if (oldProps !== newProps || oldContext !== nextContext) {
8986 callComponentWillReceiveProps(
8987 workInProgress,
8988 instance,
8989 newProps,
8990 nextContext
8991 );
8992 }
8993 }
8994
8995 resetHasForceUpdateBeforeProcessing();
8996
8997 var oldState = workInProgress.memoizedState;
8998 var newState = (instance.state = oldState);
8999 var updateQueue = workInProgress.updateQueue;
9000 if (updateQueue !== null) {
9001 processUpdateQueue(
9002 workInProgress,
9003 updateQueue,
9004 newProps,
9005 instance,
9006 renderExpirationTime
9007 );
9008 newState = workInProgress.memoizedState;
9009 }
9010 if (
9011 oldProps === newProps &&
9012 oldState === newState &&
9013 !hasContextChanged() &&
9014 !checkHasForceUpdateAfterProcessing()
9015 ) {
9016 // If an update was already in progress, we should schedule an Update
9017 // effect even though we're bailing out, so that cWU/cDU are called.
9018 if (typeof instance.componentDidMount === "function") {
9019 workInProgress.effectTag |= Update;
9020 }
9021 return false;
9022 }
9023
9024 if (typeof getDerivedStateFromProps === "function") {
9025 applyDerivedStateFromProps(
9026 workInProgress,
9027 ctor,
9028 getDerivedStateFromProps,
9029 newProps
9030 );
9031 newState = workInProgress.memoizedState;
9032 }
9033
9034 var shouldUpdate =
9035 checkHasForceUpdateAfterProcessing() ||
9036 checkShouldComponentUpdate(
9037 workInProgress,
9038 ctor,
9039 oldProps,
9040 newProps,
9041 oldState,
9042 newState,
9043 nextContext
9044 );
9045
9046 if (shouldUpdate) {
9047 // In order to support react-lifecycles-compat polyfilled components,
9048 // Unsafe lifecycles should not be invoked for components using the new APIs.
9049 if (
9050 !hasNewLifecycles &&
9051 (typeof instance.UNSAFE_componentWillMount === "function" ||
9052 typeof instance.componentWillMount === "function")
9053 ) {
9054 startPhaseTimer(workInProgress, "componentWillMount");
9055 if (typeof instance.componentWillMount === "function") {
9056 instance.componentWillMount();
9057 }
9058 if (typeof instance.UNSAFE_componentWillMount === "function") {
9059 instance.UNSAFE_componentWillMount();
9060 }
9061 stopPhaseTimer();
9062 }
9063 if (typeof instance.componentDidMount === "function") {
9064 workInProgress.effectTag |= Update;
9065 }
9066 } else {
9067 // If an update was already in progress, we should schedule an Update
9068 // effect even though we're bailing out, so that cWU/cDU are called.
9069 if (typeof instance.componentDidMount === "function") {
9070 workInProgress.effectTag |= Update;
9071 }
9072
9073 // If shouldComponentUpdate returned false, we should still update the
9074 // memoized state to indicate that this work can be reused.
9075 workInProgress.memoizedProps = newProps;
9076 workInProgress.memoizedState = newState;
9077 }
9078
9079 // Update the existing instance's state, props, and context pointers even
9080 // if shouldComponentUpdate returns false.
9081 instance.props = newProps;
9082 instance.state = newState;
9083 instance.context = nextContext;
9084
9085 return shouldUpdate;
9086}
9087
9088// Invokes the update life-cycles and returns false if it shouldn't rerender.
9089function updateClassInstance(
9090 current,
9091 workInProgress,
9092 ctor,
9093 newProps,
9094 renderExpirationTime
9095) {
9096 var instance = workInProgress.stateNode;
9097
9098 var oldProps = workInProgress.memoizedProps;
9099 instance.props =
9100 workInProgress.type === workInProgress.elementType
9101 ? oldProps
9102 : resolveDefaultProps(workInProgress.type, oldProps);
9103
9104 var oldContext = instance.context;
9105 var contextType = ctor.contextType;
9106 var nextContext = emptyContextObject;
9107 if (typeof contextType === "object" && contextType !== null) {
9108 nextContext = readContext(contextType);
9109 } else if (!disableLegacyContext) {
9110 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
9111 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
9112 }
9113
9114 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
9115 var hasNewLifecycles =
9116 typeof getDerivedStateFromProps === "function" ||
9117 typeof instance.getSnapshotBeforeUpdate === "function";
9118
9119 // Note: During these life-cycles, instance.props/instance.state are what
9120 // ever the previously attempted to render - not the "current". However,
9121 // during componentDidUpdate we pass the "current" props.
9122
9123 // In order to support react-lifecycles-compat polyfilled components,
9124 // Unsafe lifecycles should not be invoked for components using the new APIs.
9125 if (
9126 !hasNewLifecycles &&
9127 (typeof instance.UNSAFE_componentWillReceiveProps === "function" ||
9128 typeof instance.componentWillReceiveProps === "function")
9129 ) {
9130 if (oldProps !== newProps || oldContext !== nextContext) {
9131 callComponentWillReceiveProps(
9132 workInProgress,
9133 instance,
9134 newProps,
9135 nextContext
9136 );
9137 }
9138 }
9139
9140 resetHasForceUpdateBeforeProcessing();
9141
9142 var oldState = workInProgress.memoizedState;
9143 var newState = (instance.state = oldState);
9144 var updateQueue = workInProgress.updateQueue;
9145 if (updateQueue !== null) {
9146 processUpdateQueue(
9147 workInProgress,
9148 updateQueue,
9149 newProps,
9150 instance,
9151 renderExpirationTime
9152 );
9153 newState = workInProgress.memoizedState;
9154 }
9155
9156 if (
9157 oldProps === newProps &&
9158 oldState === newState &&
9159 !hasContextChanged() &&
9160 !checkHasForceUpdateAfterProcessing()
9161 ) {
9162 // If an update was already in progress, we should schedule an Update
9163 // effect even though we're bailing out, so that cWU/cDU are called.
9164 if (typeof instance.componentDidUpdate === "function") {
9165 if (
9166 oldProps !== current.memoizedProps ||
9167 oldState !== current.memoizedState
9168 ) {
9169 workInProgress.effectTag |= Update;
9170 }
9171 }
9172 if (typeof instance.getSnapshotBeforeUpdate === "function") {
9173 if (
9174 oldProps !== current.memoizedProps ||
9175 oldState !== current.memoizedState
9176 ) {
9177 workInProgress.effectTag |= Snapshot;
9178 }
9179 }
9180 return false;
9181 }
9182
9183 if (typeof getDerivedStateFromProps === "function") {
9184 applyDerivedStateFromProps(
9185 workInProgress,
9186 ctor,
9187 getDerivedStateFromProps,
9188 newProps
9189 );
9190 newState = workInProgress.memoizedState;
9191 }
9192
9193 var shouldUpdate =
9194 checkHasForceUpdateAfterProcessing() ||
9195 checkShouldComponentUpdate(
9196 workInProgress,
9197 ctor,
9198 oldProps,
9199 newProps,
9200 oldState,
9201 newState,
9202 nextContext
9203 );
9204
9205 if (shouldUpdate) {
9206 // In order to support react-lifecycles-compat polyfilled components,
9207 // Unsafe lifecycles should not be invoked for components using the new APIs.
9208 if (
9209 !hasNewLifecycles &&
9210 (typeof instance.UNSAFE_componentWillUpdate === "function" ||
9211 typeof instance.componentWillUpdate === "function")
9212 ) {
9213 startPhaseTimer(workInProgress, "componentWillUpdate");
9214 if (typeof instance.componentWillUpdate === "function") {
9215 instance.componentWillUpdate(newProps, newState, nextContext);
9216 }
9217 if (typeof instance.UNSAFE_componentWillUpdate === "function") {
9218 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
9219 }
9220 stopPhaseTimer();
9221 }
9222 if (typeof instance.componentDidUpdate === "function") {
9223 workInProgress.effectTag |= Update;
9224 }
9225 if (typeof instance.getSnapshotBeforeUpdate === "function") {
9226 workInProgress.effectTag |= Snapshot;
9227 }
9228 } else {
9229 // If an update was already in progress, we should schedule an Update
9230 // effect even though we're bailing out, so that cWU/cDU are called.
9231 if (typeof instance.componentDidUpdate === "function") {
9232 if (
9233 oldProps !== current.memoizedProps ||
9234 oldState !== current.memoizedState
9235 ) {
9236 workInProgress.effectTag |= Update;
9237 }
9238 }
9239 if (typeof instance.getSnapshotBeforeUpdate === "function") {
9240 if (
9241 oldProps !== current.memoizedProps ||
9242 oldState !== current.memoizedState
9243 ) {
9244 workInProgress.effectTag |= Snapshot;
9245 }
9246 }
9247
9248 // If shouldComponentUpdate returned false, we should still update the
9249 // memoized props/state to indicate that this work can be reused.
9250 workInProgress.memoizedProps = newProps;
9251 workInProgress.memoizedState = newState;
9252 }
9253
9254 // Update the existing instance's state, props, and context pointers even
9255 // if shouldComponentUpdate returns false.
9256 instance.props = newProps;
9257 instance.state = newState;
9258 instance.context = nextContext;
9259
9260 return shouldUpdate;
9261}
9262
9263var didWarnAboutMaps = void 0;
9264var didWarnAboutGenerators = void 0;
9265var didWarnAboutStringRefs = void 0;
9266var ownerHasKeyUseWarning = void 0;
9267var ownerHasFunctionTypeWarning = void 0;
9268var warnForMissingKey = function(child) {};
9269
9270{
9271 didWarnAboutMaps = false;
9272 didWarnAboutGenerators = false;
9273 didWarnAboutStringRefs = {};
9274
9275 /**
9276 * Warn if there's no key explicitly set on dynamic arrays of children or
9277 * object keys are not valid. This allows us to keep track of children between
9278 * updates.
9279 */
9280 ownerHasKeyUseWarning = {};
9281 ownerHasFunctionTypeWarning = {};
9282
9283 warnForMissingKey = function(child) {
9284 if (child === null || typeof child !== "object") {
9285 return;
9286 }
9287 if (!child._store || child._store.validated || child.key != null) {
9288 return;
9289 }
9290 (function() {
9291 if (!(typeof child._store === "object")) {
9292 throw ReactError(
9293 Error(
9294 "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue."
9295 )
9296 );
9297 }
9298 })();
9299 child._store.validated = true;
9300
9301 var currentComponentErrorInfo =
9302 "Each child in a list should have a unique " +
9303 '"key" prop. See https://fb.me/react-warning-keys for ' +
9304 "more information." +
9305 getCurrentFiberStackInDev();
9306 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
9307 return;
9308 }
9309 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
9310
9311 warning$1(
9312 false,
9313 "Each child in a list should have a unique " +
9314 '"key" prop. See https://fb.me/react-warning-keys for ' +
9315 "more information."
9316 );
9317 };
9318}
9319
9320var isArray = Array.isArray;
9321
9322function coerceRef(returnFiber, current$$1, element) {
9323 var mixedRef = element.ref;
9324 if (
9325 mixedRef !== null &&
9326 typeof mixedRef !== "function" &&
9327 typeof mixedRef !== "object"
9328 ) {
9329 {
9330 // TODO: Clean this up once we turn on the string ref warning for
9331 // everyone, because the strict mode case will no longer be relevant
9332 if (returnFiber.mode & StrictMode || warnAboutStringRefs) {
9333 var componentName = getComponentName(returnFiber.type) || "Component";
9334 if (!didWarnAboutStringRefs[componentName]) {
9335 if (warnAboutStringRefs) {
9336 warningWithoutStack$1(
9337 false,
9338 'Component "%s" contains the string ref "%s". Support for string refs ' +
9339 "will be removed in a future major release. We recommend using " +
9340 "useRef() or createRef() instead." +
9341 "\n%s" +
9342 "\n\nLearn more about using refs safely here:" +
9343 "\nhttps://fb.me/react-strict-mode-string-ref",
9344 componentName,
9345 mixedRef,
9346 getStackByFiberInDevAndProd(returnFiber)
9347 );
9348 } else {
9349 warningWithoutStack$1(
9350 false,
9351 'A string ref, "%s", has been found within a strict mode tree. ' +
9352 "String refs are a source of potential bugs and should be avoided. " +
9353 "We recommend using useRef() or createRef() instead." +
9354 "\n%s" +
9355 "\n\nLearn more about using refs safely here:" +
9356 "\nhttps://fb.me/react-strict-mode-string-ref",
9357 mixedRef,
9358 getStackByFiberInDevAndProd(returnFiber)
9359 );
9360 }
9361 didWarnAboutStringRefs[componentName] = true;
9362 }
9363 }
9364 }
9365
9366 if (element._owner) {
9367 var owner = element._owner;
9368 var inst = void 0;
9369 if (owner) {
9370 var ownerFiber = owner;
9371 (function() {
9372 if (!(ownerFiber.tag === ClassComponent)) {
9373 throw ReactError(
9374 Error(
9375 "Function components cannot have refs. Did you mean to use React.forwardRef()?"
9376 )
9377 );
9378 }
9379 })();
9380 inst = ownerFiber.stateNode;
9381 }
9382 (function() {
9383 if (!inst) {
9384 throw ReactError(
9385 Error(
9386 "Missing owner for string ref " +
9387 mixedRef +
9388 ". This error is likely caused by a bug in React. Please file an issue."
9389 )
9390 );
9391 }
9392 })();
9393 var stringRef = "" + mixedRef;
9394 // Check if previous string ref matches new string ref
9395 if (
9396 current$$1 !== null &&
9397 current$$1.ref !== null &&
9398 typeof current$$1.ref === "function" &&
9399 current$$1.ref._stringRef === stringRef
9400 ) {
9401 return current$$1.ref;
9402 }
9403 var ref = function(value) {
9404 var refs = inst.refs;
9405 if (refs === emptyRefsObject) {
9406 // This is a lazy pooled frozen object, so we need to initialize.
9407 refs = inst.refs = {};
9408 }
9409 if (value === null) {
9410 delete refs[stringRef];
9411 } else {
9412 refs[stringRef] = value;
9413 }
9414 };
9415 ref._stringRef = stringRef;
9416 return ref;
9417 } else {
9418 (function() {
9419 if (!(typeof mixedRef === "string")) {
9420 throw ReactError(
9421 Error(
9422 "Expected ref to be a function, a string, an object returned by React.createRef(), or null."
9423 )
9424 );
9425 }
9426 })();
9427 (function() {
9428 if (!element._owner) {
9429 throw ReactError(
9430 Error(
9431 "Element ref was specified as a string (" +
9432 mixedRef +
9433 ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information."
9434 )
9435 );
9436 }
9437 })();
9438 }
9439 }
9440 return mixedRef;
9441}
9442
9443function throwOnInvalidObjectType(returnFiber, newChild) {
9444 if (returnFiber.type !== "textarea") {
9445 var addendum = "";
9446 {
9447 addendum =
9448 " If you meant to render a collection of children, use an array " +
9449 "instead." +
9450 getCurrentFiberStackInDev();
9451 }
9452 (function() {
9453 {
9454 throw ReactError(
9455 Error(
9456 "Objects are not valid as a React child (found: " +
9457 (Object.prototype.toString.call(newChild) === "[object Object]"
9458 ? "object with keys {" + Object.keys(newChild).join(", ") + "}"
9459 : newChild) +
9460 ")." +
9461 addendum
9462 )
9463 );
9464 }
9465 })();
9466 }
9467}
9468
9469function warnOnFunctionType() {
9470 var currentComponentErrorInfo =
9471 "Functions are not valid as a React child. This may happen if " +
9472 "you return a Component instead of <Component /> from render. " +
9473 "Or maybe you meant to call this function rather than return it." +
9474 getCurrentFiberStackInDev();
9475
9476 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
9477 return;
9478 }
9479 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
9480
9481 warning$1(
9482 false,
9483 "Functions are not valid as a React child. This may happen if " +
9484 "you return a Component instead of <Component /> from render. " +
9485 "Or maybe you meant to call this function rather than return it."
9486 );
9487}
9488
9489// This wrapper function exists because I expect to clone the code in each path
9490// to be able to optimize each path individually by branching early. This needs
9491// a compiler or we can do it manually. Helpers that don't need this branching
9492// live outside of this function.
9493function ChildReconciler(shouldTrackSideEffects) {
9494 function deleteChild(returnFiber, childToDelete) {
9495 if (!shouldTrackSideEffects) {
9496 // Noop.
9497 return;
9498 }
9499 // Deletions are added in reversed order so we add it to the front.
9500 // At this point, the return fiber's effect list is empty except for
9501 // deletions, so we can just append the deletion to the list. The remaining
9502 // effects aren't added until the complete phase. Once we implement
9503 // resuming, this may not be true.
9504 var last = returnFiber.lastEffect;
9505 if (last !== null) {
9506 last.nextEffect = childToDelete;
9507 returnFiber.lastEffect = childToDelete;
9508 } else {
9509 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
9510 }
9511 childToDelete.nextEffect = null;
9512 childToDelete.effectTag = Deletion;
9513 }
9514
9515 function deleteRemainingChildren(returnFiber, currentFirstChild) {
9516 if (!shouldTrackSideEffects) {
9517 // Noop.
9518 return null;
9519 }
9520
9521 // TODO: For the shouldClone case, this could be micro-optimized a bit by
9522 // assuming that after the first child we've already added everything.
9523 var childToDelete = currentFirstChild;
9524 while (childToDelete !== null) {
9525 deleteChild(returnFiber, childToDelete);
9526 childToDelete = childToDelete.sibling;
9527 }
9528 return null;
9529 }
9530
9531 function mapRemainingChildren(returnFiber, currentFirstChild) {
9532 // Add the remaining children to a temporary map so that we can find them by
9533 // keys quickly. Implicit (null) keys get added to this set with their index
9534 var existingChildren = new Map();
9535
9536 var existingChild = currentFirstChild;
9537 while (existingChild !== null) {
9538 if (existingChild.key !== null) {
9539 existingChildren.set(existingChild.key, existingChild);
9540 } else {
9541 existingChildren.set(existingChild.index, existingChild);
9542 }
9543 existingChild = existingChild.sibling;
9544 }
9545 return existingChildren;
9546 }
9547
9548 function useFiber(fiber, pendingProps, expirationTime) {
9549 // We currently set sibling to null and index to 0 here because it is easy
9550 // to forget to do before returning it. E.g. for the single child case.
9551 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
9552 clone.index = 0;
9553 clone.sibling = null;
9554 return clone;
9555 }
9556
9557 function placeChild(newFiber, lastPlacedIndex, newIndex) {
9558 newFiber.index = newIndex;
9559 if (!shouldTrackSideEffects) {
9560 // Noop.
9561 return lastPlacedIndex;
9562 }
9563 var current$$1 = newFiber.alternate;
9564 if (current$$1 !== null) {
9565 var oldIndex = current$$1.index;
9566 if (oldIndex < lastPlacedIndex) {
9567 // This is a move.
9568 newFiber.effectTag = Placement;
9569 return lastPlacedIndex;
9570 } else {
9571 // This item can stay in place.
9572 return oldIndex;
9573 }
9574 } else {
9575 // This is an insertion.
9576 newFiber.effectTag = Placement;
9577 return lastPlacedIndex;
9578 }
9579 }
9580
9581 function placeSingleChild(newFiber) {
9582 // This is simpler for the single child case. We only need to do a
9583 // placement for inserting new children.
9584 if (shouldTrackSideEffects && newFiber.alternate === null) {
9585 newFiber.effectTag = Placement;
9586 }
9587 return newFiber;
9588 }
9589
9590 function updateTextNode(
9591 returnFiber,
9592 current$$1,
9593 textContent,
9594 expirationTime
9595 ) {
9596 if (current$$1 === null || current$$1.tag !== HostText) {
9597 // Insert
9598 var created = createFiberFromText(
9599 textContent,
9600 returnFiber.mode,
9601 expirationTime
9602 );
9603 created.return = returnFiber;
9604 return created;
9605 } else {
9606 // Update
9607 var existing = useFiber(current$$1, textContent, expirationTime);
9608 existing.return = returnFiber;
9609 return existing;
9610 }
9611 }
9612
9613 function updateElement(returnFiber, current$$1, element, expirationTime) {
9614 if (
9615 current$$1 !== null &&
9616 (current$$1.elementType === element.type ||
9617 // Keep this check inline so it only runs on the false path:
9618 isCompatibleFamilyForHotReloading(current$$1, element))
9619 ) {
9620 // Move based on index
9621 var existing = useFiber(current$$1, element.props, expirationTime);
9622 existing.ref = coerceRef(returnFiber, current$$1, element);
9623 existing.return = returnFiber;
9624 {
9625 existing._debugSource = element._source;
9626 existing._debugOwner = element._owner;
9627 }
9628 return existing;
9629 } else {
9630 // Insert
9631 var created = createFiberFromElement(
9632 element,
9633 returnFiber.mode,
9634 expirationTime
9635 );
9636 created.ref = coerceRef(returnFiber, current$$1, element);
9637 created.return = returnFiber;
9638 return created;
9639 }
9640 }
9641
9642 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
9643 if (
9644 current$$1 === null ||
9645 current$$1.tag !== HostPortal ||
9646 current$$1.stateNode.containerInfo !== portal.containerInfo ||
9647 current$$1.stateNode.implementation !== portal.implementation
9648 ) {
9649 // Insert
9650 var created = createFiberFromPortal(
9651 portal,
9652 returnFiber.mode,
9653 expirationTime
9654 );
9655 created.return = returnFiber;
9656 return created;
9657 } else {
9658 // Update
9659 var existing = useFiber(
9660 current$$1,
9661 portal.children || [],
9662 expirationTime
9663 );
9664 existing.return = returnFiber;
9665 return existing;
9666 }
9667 }
9668
9669 function updateFragment(
9670 returnFiber,
9671 current$$1,
9672 fragment,
9673 expirationTime,
9674 key
9675 ) {
9676 if (current$$1 === null || current$$1.tag !== Fragment) {
9677 // Insert
9678 var created = createFiberFromFragment(
9679 fragment,
9680 returnFiber.mode,
9681 expirationTime,
9682 key
9683 );
9684 created.return = returnFiber;
9685 return created;
9686 } else {
9687 // Update
9688 var existing = useFiber(current$$1, fragment, expirationTime);
9689 existing.return = returnFiber;
9690 return existing;
9691 }
9692 }
9693
9694 function createChild(returnFiber, newChild, expirationTime) {
9695 if (typeof newChild === "string" || typeof newChild === "number") {
9696 // Text nodes don't have keys. If the previous node is implicitly keyed
9697 // we can continue to replace it without aborting even if it is not a text
9698 // node.
9699 var created = createFiberFromText(
9700 "" + newChild,
9701 returnFiber.mode,
9702 expirationTime
9703 );
9704 created.return = returnFiber;
9705 return created;
9706 }
9707
9708 if (typeof newChild === "object" && newChild !== null) {
9709 switch (newChild.$$typeof) {
9710 case REACT_ELEMENT_TYPE: {
9711 var _created = createFiberFromElement(
9712 newChild,
9713 returnFiber.mode,
9714 expirationTime
9715 );
9716 _created.ref = coerceRef(returnFiber, null, newChild);
9717 _created.return = returnFiber;
9718 return _created;
9719 }
9720 case REACT_PORTAL_TYPE: {
9721 var _created2 = createFiberFromPortal(
9722 newChild,
9723 returnFiber.mode,
9724 expirationTime
9725 );
9726 _created2.return = returnFiber;
9727 return _created2;
9728 }
9729 }
9730
9731 if (isArray(newChild) || getIteratorFn(newChild)) {
9732 var _created3 = createFiberFromFragment(
9733 newChild,
9734 returnFiber.mode,
9735 expirationTime,
9736 null
9737 );
9738 _created3.return = returnFiber;
9739 return _created3;
9740 }
9741
9742 throwOnInvalidObjectType(returnFiber, newChild);
9743 }
9744
9745 {
9746 if (typeof newChild === "function") {
9747 warnOnFunctionType();
9748 }
9749 }
9750
9751 return null;
9752 }
9753
9754 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
9755 // Update the fiber if the keys match, otherwise return null.
9756
9757 var key = oldFiber !== null ? oldFiber.key : null;
9758
9759 if (typeof newChild === "string" || typeof newChild === "number") {
9760 // Text nodes don't have keys. If the previous node is implicitly keyed
9761 // we can continue to replace it without aborting even if it is not a text
9762 // node.
9763 if (key !== null) {
9764 return null;
9765 }
9766 return updateTextNode(
9767 returnFiber,
9768 oldFiber,
9769 "" + newChild,
9770 expirationTime
9771 );
9772 }
9773
9774 if (typeof newChild === "object" && newChild !== null) {
9775 switch (newChild.$$typeof) {
9776 case REACT_ELEMENT_TYPE: {
9777 if (newChild.key === key) {
9778 if (newChild.type === REACT_FRAGMENT_TYPE) {
9779 return updateFragment(
9780 returnFiber,
9781 oldFiber,
9782 newChild.props.children,
9783 expirationTime,
9784 key
9785 );
9786 }
9787 return updateElement(
9788 returnFiber,
9789 oldFiber,
9790 newChild,
9791 expirationTime
9792 );
9793 } else {
9794 return null;
9795 }
9796 }
9797 case REACT_PORTAL_TYPE: {
9798 if (newChild.key === key) {
9799 return updatePortal(
9800 returnFiber,
9801 oldFiber,
9802 newChild,
9803 expirationTime
9804 );
9805 } else {
9806 return null;
9807 }
9808 }
9809 }
9810
9811 if (isArray(newChild) || getIteratorFn(newChild)) {
9812 if (key !== null) {
9813 return null;
9814 }
9815
9816 return updateFragment(
9817 returnFiber,
9818 oldFiber,
9819 newChild,
9820 expirationTime,
9821 null
9822 );
9823 }
9824
9825 throwOnInvalidObjectType(returnFiber, newChild);
9826 }
9827
9828 {
9829 if (typeof newChild === "function") {
9830 warnOnFunctionType();
9831 }
9832 }
9833
9834 return null;
9835 }
9836
9837 function updateFromMap(
9838 existingChildren,
9839 returnFiber,
9840 newIdx,
9841 newChild,
9842 expirationTime
9843 ) {
9844 if (typeof newChild === "string" || typeof newChild === "number") {
9845 // Text nodes don't have keys, so we neither have to check the old nor
9846 // new node for the key. If both are text nodes, they match.
9847 var matchedFiber = existingChildren.get(newIdx) || null;
9848 return updateTextNode(
9849 returnFiber,
9850 matchedFiber,
9851 "" + newChild,
9852 expirationTime
9853 );
9854 }
9855
9856 if (typeof newChild === "object" && newChild !== null) {
9857 switch (newChild.$$typeof) {
9858 case REACT_ELEMENT_TYPE: {
9859 var _matchedFiber =
9860 existingChildren.get(
9861 newChild.key === null ? newIdx : newChild.key
9862 ) || null;
9863 if (newChild.type === REACT_FRAGMENT_TYPE) {
9864 return updateFragment(
9865 returnFiber,
9866 _matchedFiber,
9867 newChild.props.children,
9868 expirationTime,
9869 newChild.key
9870 );
9871 }
9872 return updateElement(
9873 returnFiber,
9874 _matchedFiber,
9875 newChild,
9876 expirationTime
9877 );
9878 }
9879 case REACT_PORTAL_TYPE: {
9880 var _matchedFiber2 =
9881 existingChildren.get(
9882 newChild.key === null ? newIdx : newChild.key
9883 ) || null;
9884 return updatePortal(
9885 returnFiber,
9886 _matchedFiber2,
9887 newChild,
9888 expirationTime
9889 );
9890 }
9891 }
9892
9893 if (isArray(newChild) || getIteratorFn(newChild)) {
9894 var _matchedFiber3 = existingChildren.get(newIdx) || null;
9895 return updateFragment(
9896 returnFiber,
9897 _matchedFiber3,
9898 newChild,
9899 expirationTime,
9900 null
9901 );
9902 }
9903
9904 throwOnInvalidObjectType(returnFiber, newChild);
9905 }
9906
9907 {
9908 if (typeof newChild === "function") {
9909 warnOnFunctionType();
9910 }
9911 }
9912
9913 return null;
9914 }
9915
9916 /**
9917 * Warns if there is a duplicate or missing key
9918 */
9919 function warnOnInvalidKey(child, knownKeys) {
9920 {
9921 if (typeof child !== "object" || child === null) {
9922 return knownKeys;
9923 }
9924 switch (child.$$typeof) {
9925 case REACT_ELEMENT_TYPE:
9926 case REACT_PORTAL_TYPE:
9927 warnForMissingKey(child);
9928 var key = child.key;
9929 if (typeof key !== "string") {
9930 break;
9931 }
9932 if (knownKeys === null) {
9933 knownKeys = new Set();
9934 knownKeys.add(key);
9935 break;
9936 }
9937 if (!knownKeys.has(key)) {
9938 knownKeys.add(key);
9939 break;
9940 }
9941 warning$1(
9942 false,
9943 "Encountered two children with the same key, `%s`. " +
9944 "Keys should be unique so that components maintain their identity " +
9945 "across updates. Non-unique keys may cause children to be " +
9946 "duplicated and/or omitted — the behavior is unsupported and " +
9947 "could change in a future version.",
9948 key
9949 );
9950 break;
9951 default:
9952 break;
9953 }
9954 }
9955 return knownKeys;
9956 }
9957
9958 function reconcileChildrenArray(
9959 returnFiber,
9960 currentFirstChild,
9961 newChildren,
9962 expirationTime
9963 ) {
9964 // This algorithm can't optimize by searching from both ends since we
9965 // don't have backpointers on fibers. I'm trying to see how far we can get
9966 // with that model. If it ends up not being worth the tradeoffs, we can
9967 // add it later.
9968
9969 // Even with a two ended optimization, we'd want to optimize for the case
9970 // where there are few changes and brute force the comparison instead of
9971 // going for the Map. It'd like to explore hitting that path first in
9972 // forward-only mode and only go for the Map once we notice that we need
9973 // lots of look ahead. This doesn't handle reversal as well as two ended
9974 // search but that's unusual. Besides, for the two ended optimization to
9975 // work on Iterables, we'd need to copy the whole set.
9976
9977 // In this first iteration, we'll just live with hitting the bad case
9978 // (adding everything to a Map) in for every insert/move.
9979
9980 // If you change this code, also update reconcileChildrenIterator() which
9981 // uses the same algorithm.
9982
9983 {
9984 // First, validate keys.
9985 var knownKeys = null;
9986 for (var i = 0; i < newChildren.length; i++) {
9987 var child = newChildren[i];
9988 knownKeys = warnOnInvalidKey(child, knownKeys);
9989 }
9990 }
9991
9992 var resultingFirstChild = null;
9993 var previousNewFiber = null;
9994
9995 var oldFiber = currentFirstChild;
9996 var lastPlacedIndex = 0;
9997 var newIdx = 0;
9998 var nextOldFiber = null;
9999 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
10000 if (oldFiber.index > newIdx) {
10001 nextOldFiber = oldFiber;
10002 oldFiber = null;
10003 } else {
10004 nextOldFiber = oldFiber.sibling;
10005 }
10006 var newFiber = updateSlot(
10007 returnFiber,
10008 oldFiber,
10009 newChildren[newIdx],
10010 expirationTime
10011 );
10012 if (newFiber === null) {
10013 // TODO: This breaks on empty slots like null children. That's
10014 // unfortunate because it triggers the slow path all the time. We need
10015 // a better way to communicate whether this was a miss or null,
10016 // boolean, undefined, etc.
10017 if (oldFiber === null) {
10018 oldFiber = nextOldFiber;
10019 }
10020 break;
10021 }
10022 if (shouldTrackSideEffects) {
10023 if (oldFiber && newFiber.alternate === null) {
10024 // We matched the slot, but we didn't reuse the existing fiber, so we
10025 // need to delete the existing child.
10026 deleteChild(returnFiber, oldFiber);
10027 }
10028 }
10029 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
10030 if (previousNewFiber === null) {
10031 // TODO: Move out of the loop. This only happens for the first run.
10032 resultingFirstChild = newFiber;
10033 } else {
10034 // TODO: Defer siblings if we're not at the right index for this slot.
10035 // I.e. if we had null values before, then we want to defer this
10036 // for each null value. However, we also don't want to call updateSlot
10037 // with the previous one.
10038 previousNewFiber.sibling = newFiber;
10039 }
10040 previousNewFiber = newFiber;
10041 oldFiber = nextOldFiber;
10042 }
10043
10044 if (newIdx === newChildren.length) {
10045 // We've reached the end of the new children. We can delete the rest.
10046 deleteRemainingChildren(returnFiber, oldFiber);
10047 return resultingFirstChild;
10048 }
10049
10050 if (oldFiber === null) {
10051 // If we don't have any more existing children we can choose a fast path
10052 // since the rest will all be insertions.
10053 for (; newIdx < newChildren.length; newIdx++) {
10054 var _newFiber = createChild(
10055 returnFiber,
10056 newChildren[newIdx],
10057 expirationTime
10058 );
10059 if (_newFiber === null) {
10060 continue;
10061 }
10062 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
10063 if (previousNewFiber === null) {
10064 // TODO: Move out of the loop. This only happens for the first run.
10065 resultingFirstChild = _newFiber;
10066 } else {
10067 previousNewFiber.sibling = _newFiber;
10068 }
10069 previousNewFiber = _newFiber;
10070 }
10071 return resultingFirstChild;
10072 }
10073
10074 // Add all children to a key map for quick lookups.
10075 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
10076
10077 // Keep scanning and use the map to restore deleted items as moves.
10078 for (; newIdx < newChildren.length; newIdx++) {
10079 var _newFiber2 = updateFromMap(
10080 existingChildren,
10081 returnFiber,
10082 newIdx,
10083 newChildren[newIdx],
10084 expirationTime
10085 );
10086 if (_newFiber2 !== null) {
10087 if (shouldTrackSideEffects) {
10088 if (_newFiber2.alternate !== null) {
10089 // The new fiber is a work in progress, but if there exists a
10090 // current, that means that we reused the fiber. We need to delete
10091 // it from the child list so that we don't add it to the deletion
10092 // list.
10093 existingChildren.delete(
10094 _newFiber2.key === null ? newIdx : _newFiber2.key
10095 );
10096 }
10097 }
10098 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
10099 if (previousNewFiber === null) {
10100 resultingFirstChild = _newFiber2;
10101 } else {
10102 previousNewFiber.sibling = _newFiber2;
10103 }
10104 previousNewFiber = _newFiber2;
10105 }
10106 }
10107
10108 if (shouldTrackSideEffects) {
10109 // Any existing children that weren't consumed above were deleted. We need
10110 // to add them to the deletion list.
10111 existingChildren.forEach(function(child) {
10112 return deleteChild(returnFiber, child);
10113 });
10114 }
10115
10116 return resultingFirstChild;
10117 }
10118
10119 function reconcileChildrenIterator(
10120 returnFiber,
10121 currentFirstChild,
10122 newChildrenIterable,
10123 expirationTime
10124 ) {
10125 // This is the same implementation as reconcileChildrenArray(),
10126 // but using the iterator instead.
10127
10128 var iteratorFn = getIteratorFn(newChildrenIterable);
10129 (function() {
10130 if (!(typeof iteratorFn === "function")) {
10131 throw ReactError(
10132 Error(
10133 "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue."
10134 )
10135 );
10136 }
10137 })();
10138
10139 {
10140 // We don't support rendering Generators because it's a mutation.
10141 // See https://github.com/facebook/react/issues/12995
10142 if (
10143 typeof Symbol === "function" &&
10144 // $FlowFixMe Flow doesn't know about toStringTag
10145 newChildrenIterable[Symbol.toStringTag] === "Generator"
10146 ) {
10147 !didWarnAboutGenerators
10148 ? warning$1(
10149 false,
10150 "Using Generators as children is unsupported and will likely yield " +
10151 "unexpected results because enumerating a generator mutates it. " +
10152 "You may convert it to an array with `Array.from()` or the " +
10153 "`[...spread]` operator before rendering. Keep in mind " +
10154 "you might need to polyfill these features for older browsers."
10155 )
10156 : void 0;
10157 didWarnAboutGenerators = true;
10158 }
10159
10160 // Warn about using Maps as children
10161 if (newChildrenIterable.entries === iteratorFn) {
10162 !didWarnAboutMaps
10163 ? warning$1(
10164 false,
10165 "Using Maps as children is unsupported and will likely yield " +
10166 "unexpected results. Convert it to a sequence/iterable of keyed " +
10167 "ReactElements instead."
10168 )
10169 : void 0;
10170 didWarnAboutMaps = true;
10171 }
10172
10173 // First, validate keys.
10174 // We'll get a different iterator later for the main pass.
10175 var _newChildren = iteratorFn.call(newChildrenIterable);
10176 if (_newChildren) {
10177 var knownKeys = null;
10178 var _step = _newChildren.next();
10179 for (; !_step.done; _step = _newChildren.next()) {
10180 var child = _step.value;
10181 knownKeys = warnOnInvalidKey(child, knownKeys);
10182 }
10183 }
10184 }
10185
10186 var newChildren = iteratorFn.call(newChildrenIterable);
10187 (function() {
10188 if (!(newChildren != null)) {
10189 throw ReactError(Error("An iterable object provided no iterator."));
10190 }
10191 })();
10192
10193 var resultingFirstChild = null;
10194 var previousNewFiber = null;
10195
10196 var oldFiber = currentFirstChild;
10197 var lastPlacedIndex = 0;
10198 var newIdx = 0;
10199 var nextOldFiber = null;
10200
10201 var step = newChildren.next();
10202 for (
10203 ;
10204 oldFiber !== null && !step.done;
10205 newIdx++, step = newChildren.next()
10206 ) {
10207 if (oldFiber.index > newIdx) {
10208 nextOldFiber = oldFiber;
10209 oldFiber = null;
10210 } else {
10211 nextOldFiber = oldFiber.sibling;
10212 }
10213 var newFiber = updateSlot(
10214 returnFiber,
10215 oldFiber,
10216 step.value,
10217 expirationTime
10218 );
10219 if (newFiber === null) {
10220 // TODO: This breaks on empty slots like null children. That's
10221 // unfortunate because it triggers the slow path all the time. We need
10222 // a better way to communicate whether this was a miss or null,
10223 // boolean, undefined, etc.
10224 if (oldFiber === null) {
10225 oldFiber = nextOldFiber;
10226 }
10227 break;
10228 }
10229 if (shouldTrackSideEffects) {
10230 if (oldFiber && newFiber.alternate === null) {
10231 // We matched the slot, but we didn't reuse the existing fiber, so we
10232 // need to delete the existing child.
10233 deleteChild(returnFiber, oldFiber);
10234 }
10235 }
10236 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
10237 if (previousNewFiber === null) {
10238 // TODO: Move out of the loop. This only happens for the first run.
10239 resultingFirstChild = newFiber;
10240 } else {
10241 // TODO: Defer siblings if we're not at the right index for this slot.
10242 // I.e. if we had null values before, then we want to defer this
10243 // for each null value. However, we also don't want to call updateSlot
10244 // with the previous one.
10245 previousNewFiber.sibling = newFiber;
10246 }
10247 previousNewFiber = newFiber;
10248 oldFiber = nextOldFiber;
10249 }
10250
10251 if (step.done) {
10252 // We've reached the end of the new children. We can delete the rest.
10253 deleteRemainingChildren(returnFiber, oldFiber);
10254 return resultingFirstChild;
10255 }
10256
10257 if (oldFiber === null) {
10258 // If we don't have any more existing children we can choose a fast path
10259 // since the rest will all be insertions.
10260 for (; !step.done; newIdx++, step = newChildren.next()) {
10261 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
10262 if (_newFiber3 === null) {
10263 continue;
10264 }
10265 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
10266 if (previousNewFiber === null) {
10267 // TODO: Move out of the loop. This only happens for the first run.
10268 resultingFirstChild = _newFiber3;
10269 } else {
10270 previousNewFiber.sibling = _newFiber3;
10271 }
10272 previousNewFiber = _newFiber3;
10273 }
10274 return resultingFirstChild;
10275 }
10276
10277 // Add all children to a key map for quick lookups.
10278 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
10279
10280 // Keep scanning and use the map to restore deleted items as moves.
10281 for (; !step.done; newIdx++, step = newChildren.next()) {
10282 var _newFiber4 = updateFromMap(
10283 existingChildren,
10284 returnFiber,
10285 newIdx,
10286 step.value,
10287 expirationTime
10288 );
10289 if (_newFiber4 !== null) {
10290 if (shouldTrackSideEffects) {
10291 if (_newFiber4.alternate !== null) {
10292 // The new fiber is a work in progress, but if there exists a
10293 // current, that means that we reused the fiber. We need to delete
10294 // it from the child list so that we don't add it to the deletion
10295 // list.
10296 existingChildren.delete(
10297 _newFiber4.key === null ? newIdx : _newFiber4.key
10298 );
10299 }
10300 }
10301 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
10302 if (previousNewFiber === null) {
10303 resultingFirstChild = _newFiber4;
10304 } else {
10305 previousNewFiber.sibling = _newFiber4;
10306 }
10307 previousNewFiber = _newFiber4;
10308 }
10309 }
10310
10311 if (shouldTrackSideEffects) {
10312 // Any existing children that weren't consumed above were deleted. We need
10313 // to add them to the deletion list.
10314 existingChildren.forEach(function(child) {
10315 return deleteChild(returnFiber, child);
10316 });
10317 }
10318
10319 return resultingFirstChild;
10320 }
10321
10322 function reconcileSingleTextNode(
10323 returnFiber,
10324 currentFirstChild,
10325 textContent,
10326 expirationTime
10327 ) {
10328 // There's no need to check for keys on text nodes since we don't have a
10329 // way to define them.
10330 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
10331 // We already have an existing node so let's just update it and delete
10332 // the rest.
10333 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
10334 var existing = useFiber(currentFirstChild, textContent, expirationTime);
10335 existing.return = returnFiber;
10336 return existing;
10337 }
10338 // The existing first child is not a text node so we need to create one
10339 // and delete the existing ones.
10340 deleteRemainingChildren(returnFiber, currentFirstChild);
10341 var created = createFiberFromText(
10342 textContent,
10343 returnFiber.mode,
10344 expirationTime
10345 );
10346 created.return = returnFiber;
10347 return created;
10348 }
10349
10350 function reconcileSingleElement(
10351 returnFiber,
10352 currentFirstChild,
10353 element,
10354 expirationTime
10355 ) {
10356 var key = element.key;
10357 var child = currentFirstChild;
10358 while (child !== null) {
10359 // TODO: If key === null and child.key === null, then this only applies to
10360 // the first item in the list.
10361 if (child.key === key) {
10362 if (
10363 child.tag === Fragment
10364 ? element.type === REACT_FRAGMENT_TYPE
10365 : child.elementType === element.type ||
10366 // Keep this check inline so it only runs on the false path:
10367 isCompatibleFamilyForHotReloading(child, element)
10368 ) {
10369 deleteRemainingChildren(returnFiber, child.sibling);
10370 var existing = useFiber(
10371 child,
10372 element.type === REACT_FRAGMENT_TYPE
10373 ? element.props.children
10374 : element.props,
10375 expirationTime
10376 );
10377 existing.ref = coerceRef(returnFiber, child, element);
10378 existing.return = returnFiber;
10379 {
10380 existing._debugSource = element._source;
10381 existing._debugOwner = element._owner;
10382 }
10383 return existing;
10384 } else {
10385 deleteRemainingChildren(returnFiber, child);
10386 break;
10387 }
10388 } else {
10389 deleteChild(returnFiber, child);
10390 }
10391 child = child.sibling;
10392 }
10393
10394 if (element.type === REACT_FRAGMENT_TYPE) {
10395 var created = createFiberFromFragment(
10396 element.props.children,
10397 returnFiber.mode,
10398 expirationTime,
10399 element.key
10400 );
10401 created.return = returnFiber;
10402 return created;
10403 } else {
10404 var _created4 = createFiberFromElement(
10405 element,
10406 returnFiber.mode,
10407 expirationTime
10408 );
10409 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
10410 _created4.return = returnFiber;
10411 return _created4;
10412 }
10413 }
10414
10415 function reconcileSinglePortal(
10416 returnFiber,
10417 currentFirstChild,
10418 portal,
10419 expirationTime
10420 ) {
10421 var key = portal.key;
10422 var child = currentFirstChild;
10423 while (child !== null) {
10424 // TODO: If key === null and child.key === null, then this only applies to
10425 // the first item in the list.
10426 if (child.key === key) {
10427 if (
10428 child.tag === HostPortal &&
10429 child.stateNode.containerInfo === portal.containerInfo &&
10430 child.stateNode.implementation === portal.implementation
10431 ) {
10432 deleteRemainingChildren(returnFiber, child.sibling);
10433 var existing = useFiber(child, portal.children || [], expirationTime);
10434 existing.return = returnFiber;
10435 return existing;
10436 } else {
10437 deleteRemainingChildren(returnFiber, child);
10438 break;
10439 }
10440 } else {
10441 deleteChild(returnFiber, child);
10442 }
10443 child = child.sibling;
10444 }
10445
10446 var created = createFiberFromPortal(
10447 portal,
10448 returnFiber.mode,
10449 expirationTime
10450 );
10451 created.return = returnFiber;
10452 return created;
10453 }
10454
10455 // This API will tag the children with the side-effect of the reconciliation
10456 // itself. They will be added to the side-effect list as we pass through the
10457 // children and the parent.
10458 function reconcileChildFibers(
10459 returnFiber,
10460 currentFirstChild,
10461 newChild,
10462 expirationTime
10463 ) {
10464 // This function is not recursive.
10465 // If the top level item is an array, we treat it as a set of children,
10466 // not as a fragment. Nested arrays on the other hand will be treated as
10467 // fragment nodes. Recursion happens at the normal flow.
10468
10469 // Handle top level unkeyed fragments as if they were arrays.
10470 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
10471 // We treat the ambiguous cases above the same.
10472 var isUnkeyedTopLevelFragment =
10473 typeof newChild === "object" &&
10474 newChild !== null &&
10475 newChild.type === REACT_FRAGMENT_TYPE &&
10476 newChild.key === null;
10477 if (isUnkeyedTopLevelFragment) {
10478 newChild = newChild.props.children;
10479 }
10480
10481 // Handle object types
10482 var isObject = typeof newChild === "object" && newChild !== null;
10483
10484 if (isObject) {
10485 switch (newChild.$$typeof) {
10486 case REACT_ELEMENT_TYPE:
10487 return placeSingleChild(
10488 reconcileSingleElement(
10489 returnFiber,
10490 currentFirstChild,
10491 newChild,
10492 expirationTime
10493 )
10494 );
10495 case REACT_PORTAL_TYPE:
10496 return placeSingleChild(
10497 reconcileSinglePortal(
10498 returnFiber,
10499 currentFirstChild,
10500 newChild,
10501 expirationTime
10502 )
10503 );
10504 }
10505 }
10506
10507 if (typeof newChild === "string" || typeof newChild === "number") {
10508 return placeSingleChild(
10509 reconcileSingleTextNode(
10510 returnFiber,
10511 currentFirstChild,
10512 "" + newChild,
10513 expirationTime
10514 )
10515 );
10516 }
10517
10518 if (isArray(newChild)) {
10519 return reconcileChildrenArray(
10520 returnFiber,
10521 currentFirstChild,
10522 newChild,
10523 expirationTime
10524 );
10525 }
10526
10527 if (getIteratorFn(newChild)) {
10528 return reconcileChildrenIterator(
10529 returnFiber,
10530 currentFirstChild,
10531 newChild,
10532 expirationTime
10533 );
10534 }
10535
10536 if (isObject) {
10537 throwOnInvalidObjectType(returnFiber, newChild);
10538 }
10539
10540 {
10541 if (typeof newChild === "function") {
10542 warnOnFunctionType();
10543 }
10544 }
10545 if (typeof newChild === "undefined" && !isUnkeyedTopLevelFragment) {
10546 // If the new child is undefined, and the return fiber is a composite
10547 // component, throw an error. If Fiber return types are disabled,
10548 // we already threw above.
10549 switch (returnFiber.tag) {
10550 case ClassComponent: {
10551 {
10552 var instance = returnFiber.stateNode;
10553 if (instance.render._isMockFunction) {
10554 // We allow auto-mocks to proceed as if they're returning null.
10555 break;
10556 }
10557 }
10558 }
10559 // Intentionally fall through to the next case, which handles both
10560 // functions and classes
10561 // eslint-disable-next-lined no-fallthrough
10562 case FunctionComponent: {
10563 var Component = returnFiber.type;
10564 (function() {
10565 {
10566 throw ReactError(
10567 Error(
10568 (Component.displayName || Component.name || "Component") +
10569 "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null."
10570 )
10571 );
10572 }
10573 })();
10574 }
10575 }
10576 }
10577
10578 // Remaining cases are all treated as empty.
10579 return deleteRemainingChildren(returnFiber, currentFirstChild);
10580 }
10581
10582 return reconcileChildFibers;
10583}
10584
10585var reconcileChildFibers = ChildReconciler(true);
10586var mountChildFibers = ChildReconciler(false);
10587
10588function cloneChildFibers(current$$1, workInProgress) {
10589 (function() {
10590 if (!(current$$1 === null || workInProgress.child === current$$1.child)) {
10591 throw ReactError(Error("Resuming work not yet implemented."));
10592 }
10593 })();
10594
10595 if (workInProgress.child === null) {
10596 return;
10597 }
10598
10599 var currentChild = workInProgress.child;
10600 var newChild = createWorkInProgress(
10601 currentChild,
10602 currentChild.pendingProps,
10603 currentChild.expirationTime
10604 );
10605 workInProgress.child = newChild;
10606
10607 newChild.return = workInProgress;
10608 while (currentChild.sibling !== null) {
10609 currentChild = currentChild.sibling;
10610 newChild = newChild.sibling = createWorkInProgress(
10611 currentChild,
10612 currentChild.pendingProps,
10613 currentChild.expirationTime
10614 );
10615 newChild.return = workInProgress;
10616 }
10617 newChild.sibling = null;
10618}
10619
10620// Reset a workInProgress child set to prepare it for a second pass.
10621function resetChildFibers(workInProgress, renderExpirationTime) {
10622 var child = workInProgress.child;
10623 while (child !== null) {
10624 resetWorkInProgress(child, renderExpirationTime);
10625 child = child.sibling;
10626 }
10627}
10628
10629var NO_CONTEXT = {};
10630
10631var contextStackCursor$1 = createCursor(NO_CONTEXT);
10632var contextFiberStackCursor = createCursor(NO_CONTEXT);
10633var rootInstanceStackCursor = createCursor(NO_CONTEXT);
10634
10635function requiredContext(c) {
10636 (function() {
10637 if (!(c !== NO_CONTEXT)) {
10638 throw ReactError(
10639 Error(
10640 "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue."
10641 )
10642 );
10643 }
10644 })();
10645 return c;
10646}
10647
10648function getRootHostContainer() {
10649 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10650 return rootInstance;
10651}
10652
10653function pushHostContainer(fiber, nextRootInstance) {
10654 // Push current root instance onto the stack;
10655 // This allows us to reset root when portals are popped.
10656 push(rootInstanceStackCursor, nextRootInstance, fiber);
10657 // Track the context and the Fiber that provided it.
10658 // This enables us to pop only Fibers that provide unique contexts.
10659 push(contextFiberStackCursor, fiber, fiber);
10660
10661 // Finally, we need to push the host context to the stack.
10662 // However, we can't just call getRootHostContext() and push it because
10663 // we'd have a different number of entries on the stack depending on
10664 // whether getRootHostContext() throws somewhere in renderer code or not.
10665 // So we push an empty value first. This lets us safely unwind on errors.
10666 push(contextStackCursor$1, NO_CONTEXT, fiber);
10667 var nextRootContext = getRootHostContext(nextRootInstance);
10668 // Now that we know this function doesn't throw, replace it.
10669 pop(contextStackCursor$1, fiber);
10670 push(contextStackCursor$1, nextRootContext, fiber);
10671}
10672
10673function popHostContainer(fiber) {
10674 pop(contextStackCursor$1, fiber);
10675 pop(contextFiberStackCursor, fiber);
10676 pop(rootInstanceStackCursor, fiber);
10677}
10678
10679function getHostContext() {
10680 var context = requiredContext(contextStackCursor$1.current);
10681 return context;
10682}
10683
10684function pushHostContext(fiber) {
10685 var rootInstance = requiredContext(rootInstanceStackCursor.current);
10686 var context = requiredContext(contextStackCursor$1.current);
10687 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
10688
10689 // Don't push this Fiber's context unless it's unique.
10690 if (context === nextContext) {
10691 return;
10692 }
10693
10694 // Track the context and the Fiber that provided it.
10695 // This enables us to pop only Fibers that provide unique contexts.
10696 push(contextFiberStackCursor, fiber, fiber);
10697 push(contextStackCursor$1, nextContext, fiber);
10698}
10699
10700function popHostContext(fiber) {
10701 // Do not pop unless this Fiber provided the current context.
10702 // pushHostContext() only pushes Fibers that provide unique contexts.
10703 if (contextFiberStackCursor.current !== fiber) {
10704 return;
10705 }
10706
10707 pop(contextStackCursor$1, fiber);
10708 pop(contextFiberStackCursor, fiber);
10709}
10710
10711var DefaultSuspenseContext = 0;
10712
10713// The Suspense Context is split into two parts. The lower bits is
10714// inherited deeply down the subtree. The upper bits only affect
10715// this immediate suspense boundary and gets reset each new
10716// boundary or suspense list.
10717var SubtreeSuspenseContextMask = 1;
10718
10719// Subtree Flags:
10720
10721// InvisibleParentSuspenseContext indicates that one of our parent Suspense
10722// boundaries is not currently showing visible main content.
10723// Either because it is already showing a fallback or is not mounted at all.
10724// We can use this to determine if it is desirable to trigger a fallback at
10725// the parent. If not, then we might need to trigger undesirable boundaries
10726// and/or suspend the commit to avoid hiding the parent content.
10727var InvisibleParentSuspenseContext = 1;
10728
10729// Shallow Flags:
10730
10731// ForceSuspenseFallback can be used by SuspenseList to force newly added
10732// items into their fallback state during one of the render passes.
10733var ForceSuspenseFallback = 2;
10734
10735var suspenseStackCursor = createCursor(DefaultSuspenseContext);
10736
10737function hasSuspenseContext(parentContext, flag) {
10738 return (parentContext & flag) !== 0;
10739}
10740
10741function setDefaultShallowSuspenseContext(parentContext) {
10742 return parentContext & SubtreeSuspenseContextMask;
10743}
10744
10745function setShallowSuspenseContext(parentContext, shallowContext) {
10746 return (parentContext & SubtreeSuspenseContextMask) | shallowContext;
10747}
10748
10749function addSubtreeSuspenseContext(parentContext, subtreeContext) {
10750 return parentContext | subtreeContext;
10751}
10752
10753function pushSuspenseContext(fiber, newContext) {
10754 push(suspenseStackCursor, newContext, fiber);
10755}
10756
10757function popSuspenseContext(fiber) {
10758 pop(suspenseStackCursor, fiber);
10759}
10760
10761// TODO: This is now an empty object. Should we switch this to a boolean?
10762// Alternatively we can make this use an effect tag similar to SuspenseList.
10763
10764function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
10765 // If it was the primary children that just suspended, capture and render the
10766 var nextState = workInProgress.memoizedState;
10767 if (nextState !== null) {
10768 return false;
10769 }
10770 var props = workInProgress.memoizedProps;
10771 // In order to capture, the Suspense component must have a fallback prop.
10772 if (props.fallback === undefined) {
10773 return false;
10774 }
10775 // Regular boundaries always capture.
10776 if (props.unstable_avoidThisFallback !== true) {
10777 return true;
10778 }
10779 // If it's a boundary we should avoid, then we prefer to bubble up to the
10780 // parent boundary if it is currently invisible.
10781 if (hasInvisibleParent) {
10782 return false;
10783 }
10784 // If the parent is not able to handle it, we must handle it.
10785 return true;
10786}
10787
10788function findFirstSuspended(row) {
10789 var node = row;
10790 while (node !== null) {
10791 if (node.tag === SuspenseComponent) {
10792 var state = node.memoizedState;
10793 if (state !== null) {
10794 return node;
10795 }
10796 } else if (
10797 node.tag === SuspenseListComponent &&
10798 // revealOrder undefined can't be trusted because it don't
10799 // keep track of whether it suspended or not.
10800 node.memoizedProps.revealOrder !== undefined
10801 ) {
10802 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
10803 if (didSuspend) {
10804 return node;
10805 }
10806 } else if (node.child !== null) {
10807 node.child.return = node;
10808 node = node.child;
10809 continue;
10810 }
10811 if (node === row) {
10812 return null;
10813 }
10814 while (node.sibling === null) {
10815 if (node.return === null || node.return === row) {
10816 return null;
10817 }
10818 node = node.return;
10819 }
10820 node.sibling.return = node.return;
10821 node = node.sibling;
10822 }
10823 return null;
10824}
10825
10826function createResponderListener(responder, props) {
10827 var eventResponderListener = {
10828 responder: responder,
10829 props: props
10830 };
10831 {
10832 Object.freeze(eventResponderListener);
10833 }
10834 return eventResponderListener;
10835}
10836
10837function createResponderInstance(
10838 responder,
10839 responderProps,
10840 responderState,
10841 target,
10842 fiber
10843) {
10844 return {
10845 fiber: fiber,
10846 props: responderProps,
10847 responder: responder,
10848 rootEventTypes: null,
10849 state: responderState,
10850 target: target
10851 };
10852}
10853
10854var NoEffect$1 = /* */ 0;
10855var UnmountSnapshot = /* */ 2;
10856var UnmountMutation = /* */ 4;
10857var MountMutation = /* */ 8;
10858var UnmountLayout = /* */ 16;
10859var MountLayout = /* */ 32;
10860var MountPassive = /* */ 64;
10861var UnmountPassive = /* */ 128;
10862
10863var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
10864
10865var didWarnAboutMismatchedHooksForComponent = void 0;
10866{
10867 didWarnAboutMismatchedHooksForComponent = new Set();
10868}
10869
10870// These are set right before calling the component.
10871var renderExpirationTime$1 = NoWork;
10872// The work-in-progress fiber. I've named it differently to distinguish it from
10873// the work-in-progress hook.
10874var currentlyRenderingFiber$1 = null;
10875
10876// Hooks are stored as a linked list on the fiber's memoizedState field. The
10877// current hook list is the list that belongs to the current fiber. The
10878// work-in-progress hook list is a new list that will be added to the
10879// work-in-progress fiber.
10880var currentHook = null;
10881var nextCurrentHook = null;
10882var firstWorkInProgressHook = null;
10883var workInProgressHook = null;
10884var nextWorkInProgressHook = null;
10885
10886var remainingExpirationTime = NoWork;
10887var componentUpdateQueue = null;
10888var sideEffectTag = 0;
10889
10890// Updates scheduled during render will trigger an immediate re-render at the
10891// end of the current pass. We can't store these updates on the normal queue,
10892// because if the work is aborted, they should be discarded. Because this is
10893// a relatively rare case, we also don't want to add an additional field to
10894// either the hook or queue object types. So we store them in a lazily create
10895// map of queue -> render-phase updates, which are discarded once the component
10896// completes without re-rendering.
10897
10898// Whether an update was scheduled during the currently executing render pass.
10899var didScheduleRenderPhaseUpdate = false;
10900// Lazily created map of render-phase updates
10901var renderPhaseUpdates = null;
10902// Counter to prevent infinite loops.
10903var numberOfReRenders = 0;
10904var RE_RENDER_LIMIT = 25;
10905
10906// In DEV, this is the name of the currently executing primitive hook
10907var currentHookNameInDev = null;
10908
10909// In DEV, this list ensures that hooks are called in the same order between renders.
10910// The list stores the order of hooks used during the initial render (mount).
10911// Subsequent renders (updates) reference this list.
10912var hookTypesDev = null;
10913var hookTypesUpdateIndexDev = -1;
10914
10915// In DEV, this tracks whether currently rendering component needs to ignore
10916// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
10917// When true, such Hooks will always be "remounted". Only used during hot reload.
10918var ignorePreviousDependencies = false;
10919
10920function mountHookTypesDev() {
10921 {
10922 var hookName = currentHookNameInDev;
10923
10924 if (hookTypesDev === null) {
10925 hookTypesDev = [hookName];
10926 } else {
10927 hookTypesDev.push(hookName);
10928 }
10929 }
10930}
10931
10932function updateHookTypesDev() {
10933 {
10934 var hookName = currentHookNameInDev;
10935
10936 if (hookTypesDev !== null) {
10937 hookTypesUpdateIndexDev++;
10938 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
10939 warnOnHookMismatchInDev(hookName);
10940 }
10941 }
10942 }
10943}
10944
10945function checkDepsAreArrayDev(deps) {
10946 {
10947 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
10948 // Verify deps, but only on mount to avoid extra checks.
10949 // It's unlikely their type would change as usually you define them inline.
10950 warning$1(
10951 false,
10952 "%s received a final argument that is not an array (instead, received `%s`). When " +
10953 "specified, the final argument must be an array.",
10954 currentHookNameInDev,
10955 typeof deps
10956 );
10957 }
10958 }
10959}
10960
10961function warnOnHookMismatchInDev(currentHookName) {
10962 {
10963 var componentName = getComponentName(currentlyRenderingFiber$1.type);
10964 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
10965 didWarnAboutMismatchedHooksForComponent.add(componentName);
10966
10967 if (hookTypesDev !== null) {
10968 var table = "";
10969
10970 var secondColumnStart = 30;
10971
10972 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
10973 var oldHookName = hookTypesDev[i];
10974 var newHookName =
10975 i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
10976
10977 var row = i + 1 + ". " + oldHookName;
10978
10979 // Extra space so second column lines up
10980 // lol @ IE not supporting String#repeat
10981 while (row.length < secondColumnStart) {
10982 row += " ";
10983 }
10984
10985 row += newHookName + "\n";
10986
10987 table += row;
10988 }
10989
10990 warning$1(
10991 false,
10992 "React has detected a change in the order of Hooks called by %s. " +
10993 "This will lead to bugs and errors if not fixed. " +
10994 "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" +
10995 " Previous render Next render\n" +
10996 " ------------------------------------------------------\n" +
10997 "%s" +
10998 " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
10999 componentName,
11000 table
11001 );
11002 }
11003 }
11004 }
11005}
11006
11007function throwInvalidHookError() {
11008 (function() {
11009 {
11010 throw ReactError(
11011 Error(
11012 "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem."
11013 )
11014 );
11015 }
11016 })();
11017}
11018
11019function areHookInputsEqual(nextDeps, prevDeps) {
11020 {
11021 if (ignorePreviousDependencies) {
11022 // Only true when this component is being hot reloaded.
11023 return false;
11024 }
11025 }
11026
11027 if (prevDeps === null) {
11028 {
11029 warning$1(
11030 false,
11031 "%s received a final argument during this render, but not during " +
11032 "the previous render. Even though the final argument is optional, " +
11033 "its type cannot change between renders.",
11034 currentHookNameInDev
11035 );
11036 }
11037 return false;
11038 }
11039
11040 {
11041 // Don't bother comparing lengths in prod because these arrays should be
11042 // passed inline.
11043 if (nextDeps.length !== prevDeps.length) {
11044 warning$1(
11045 false,
11046 "The final argument passed to %s changed size between renders. The " +
11047 "order and size of this array must remain constant.\n\n" +
11048 "Previous: %s\n" +
11049 "Incoming: %s",
11050 currentHookNameInDev,
11051 "[" + prevDeps.join(", ") + "]",
11052 "[" + nextDeps.join(", ") + "]"
11053 );
11054 }
11055 }
11056 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
11057 if (is(nextDeps[i], prevDeps[i])) {
11058 continue;
11059 }
11060 return false;
11061 }
11062 return true;
11063}
11064
11065function renderWithHooks(
11066 current,
11067 workInProgress,
11068 Component,
11069 props,
11070 refOrContext,
11071 nextRenderExpirationTime
11072) {
11073 renderExpirationTime$1 = nextRenderExpirationTime;
11074 currentlyRenderingFiber$1 = workInProgress;
11075 nextCurrentHook = current !== null ? current.memoizedState : null;
11076
11077 {
11078 hookTypesDev = current !== null ? current._debugHookTypes : null;
11079 hookTypesUpdateIndexDev = -1;
11080 // Used for hot reloading:
11081 ignorePreviousDependencies =
11082 current !== null && current.type !== workInProgress.type;
11083 }
11084
11085 // The following should have already been reset
11086 // currentHook = null;
11087 // workInProgressHook = null;
11088
11089 // remainingExpirationTime = NoWork;
11090 // componentUpdateQueue = null;
11091
11092 // didScheduleRenderPhaseUpdate = false;
11093 // renderPhaseUpdates = null;
11094 // numberOfReRenders = 0;
11095 // sideEffectTag = 0;
11096
11097 // TODO Warn if no hooks are used at all during mount, then some are used during update.
11098 // Currently we will identify the update render as a mount because nextCurrentHook === null.
11099 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
11100
11101 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
11102 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
11103 // so nextCurrentHook would be null during updates and mounts.
11104 {
11105 if (nextCurrentHook !== null) {
11106 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
11107 } else if (hookTypesDev !== null) {
11108 // This dispatcher handles an edge case where a component is updating,
11109 // but no stateful hooks have been used.
11110 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
11111 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
11112 // This dispatcher does that.
11113 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
11114 } else {
11115 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
11116 }
11117 }
11118
11119 var children = Component(props, refOrContext);
11120
11121 if (didScheduleRenderPhaseUpdate) {
11122 do {
11123 didScheduleRenderPhaseUpdate = false;
11124 numberOfReRenders += 1;
11125 {
11126 // Even when hot reloading, allow dependencies to stabilize
11127 // after first render to prevent infinite render phase updates.
11128 ignorePreviousDependencies = false;
11129 }
11130
11131 // Start over from the beginning of the list
11132 nextCurrentHook = current !== null ? current.memoizedState : null;
11133 nextWorkInProgressHook = firstWorkInProgressHook;
11134
11135 currentHook = null;
11136 workInProgressHook = null;
11137 componentUpdateQueue = null;
11138
11139 {
11140 // Also validate hook order for cascading updates.
11141 hookTypesUpdateIndexDev = -1;
11142 }
11143
11144 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
11145
11146 children = Component(props, refOrContext);
11147 } while (didScheduleRenderPhaseUpdate);
11148
11149 renderPhaseUpdates = null;
11150 numberOfReRenders = 0;
11151 }
11152
11153 // We can assume the previous dispatcher is always this one, since we set it
11154 // at the beginning of the render phase and there's no re-entrancy.
11155 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
11156
11157 var renderedWork = currentlyRenderingFiber$1;
11158
11159 renderedWork.memoizedState = firstWorkInProgressHook;
11160 renderedWork.expirationTime = remainingExpirationTime;
11161 renderedWork.updateQueue = componentUpdateQueue;
11162 renderedWork.effectTag |= sideEffectTag;
11163
11164 {
11165 renderedWork._debugHookTypes = hookTypesDev;
11166 }
11167
11168 // This check uses currentHook so that it works the same in DEV and prod bundles.
11169 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
11170 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
11171
11172 renderExpirationTime$1 = NoWork;
11173 currentlyRenderingFiber$1 = null;
11174
11175 currentHook = null;
11176 nextCurrentHook = null;
11177 firstWorkInProgressHook = null;
11178 workInProgressHook = null;
11179 nextWorkInProgressHook = null;
11180
11181 {
11182 currentHookNameInDev = null;
11183 hookTypesDev = null;
11184 hookTypesUpdateIndexDev = -1;
11185 }
11186
11187 remainingExpirationTime = NoWork;
11188 componentUpdateQueue = null;
11189 sideEffectTag = 0;
11190
11191 // These were reset above
11192 // didScheduleRenderPhaseUpdate = false;
11193 // renderPhaseUpdates = null;
11194 // numberOfReRenders = 0;
11195
11196 (function() {
11197 if (!!didRenderTooFewHooks) {
11198 throw ReactError(
11199 Error(
11200 "Rendered fewer hooks than expected. This may be caused by an accidental early return statement."
11201 )
11202 );
11203 }
11204 })();
11205
11206 return children;
11207}
11208
11209function bailoutHooks(current, workInProgress, expirationTime) {
11210 workInProgress.updateQueue = current.updateQueue;
11211 workInProgress.effectTag &= ~(Passive | Update);
11212 if (current.expirationTime <= expirationTime) {
11213 current.expirationTime = NoWork;
11214 }
11215}
11216
11217function resetHooks() {
11218 // We can assume the previous dispatcher is always this one, since we set it
11219 // at the beginning of the render phase and there's no re-entrancy.
11220 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
11221
11222 // This is used to reset the state of this module when a component throws.
11223 // It's also called inside mountIndeterminateComponent if we determine the
11224 // component is a module-style component.
11225 renderExpirationTime$1 = NoWork;
11226 currentlyRenderingFiber$1 = null;
11227
11228 currentHook = null;
11229 nextCurrentHook = null;
11230 firstWorkInProgressHook = null;
11231 workInProgressHook = null;
11232 nextWorkInProgressHook = null;
11233
11234 {
11235 hookTypesDev = null;
11236 hookTypesUpdateIndexDev = -1;
11237
11238 currentHookNameInDev = null;
11239 }
11240
11241 remainingExpirationTime = NoWork;
11242 componentUpdateQueue = null;
11243 sideEffectTag = 0;
11244
11245 didScheduleRenderPhaseUpdate = false;
11246 renderPhaseUpdates = null;
11247 numberOfReRenders = 0;
11248}
11249
11250function mountWorkInProgressHook() {
11251 var hook = {
11252 memoizedState: null,
11253
11254 baseState: null,
11255 queue: null,
11256 baseUpdate: null,
11257
11258 next: null
11259 };
11260
11261 if (workInProgressHook === null) {
11262 // This is the first hook in the list
11263 firstWorkInProgressHook = workInProgressHook = hook;
11264 } else {
11265 // Append to the end of the list
11266 workInProgressHook = workInProgressHook.next = hook;
11267 }
11268 return workInProgressHook;
11269}
11270
11271function updateWorkInProgressHook() {
11272 // This function is used both for updates and for re-renders triggered by a
11273 // render phase update. It assumes there is either a current hook we can
11274 // clone, or a work-in-progress hook from a previous render pass that we can
11275 // use as a base. When we reach the end of the base list, we must switch to
11276 // the dispatcher used for mounts.
11277 if (nextWorkInProgressHook !== null) {
11278 // There's already a work-in-progress. Reuse it.
11279 workInProgressHook = nextWorkInProgressHook;
11280 nextWorkInProgressHook = workInProgressHook.next;
11281
11282 currentHook = nextCurrentHook;
11283 nextCurrentHook = currentHook !== null ? currentHook.next : null;
11284 } else {
11285 // Clone from the current hook.
11286 (function() {
11287 if (!(nextCurrentHook !== null)) {
11288 throw ReactError(
11289 Error("Rendered more hooks than during the previous render.")
11290 );
11291 }
11292 })();
11293 currentHook = nextCurrentHook;
11294
11295 var newHook = {
11296 memoizedState: currentHook.memoizedState,
11297
11298 baseState: currentHook.baseState,
11299 queue: currentHook.queue,
11300 baseUpdate: currentHook.baseUpdate,
11301
11302 next: null
11303 };
11304
11305 if (workInProgressHook === null) {
11306 // This is the first hook in the list.
11307 workInProgressHook = firstWorkInProgressHook = newHook;
11308 } else {
11309 // Append to the end of the list.
11310 workInProgressHook = workInProgressHook.next = newHook;
11311 }
11312 nextCurrentHook = currentHook.next;
11313 }
11314 return workInProgressHook;
11315}
11316
11317function createFunctionComponentUpdateQueue() {
11318 return {
11319 lastEffect: null
11320 };
11321}
11322
11323function basicStateReducer(state, action) {
11324 return typeof action === "function" ? action(state) : action;
11325}
11326
11327function mountReducer(reducer, initialArg, init) {
11328 var hook = mountWorkInProgressHook();
11329 var initialState = void 0;
11330 if (init !== undefined) {
11331 initialState = init(initialArg);
11332 } else {
11333 initialState = initialArg;
11334 }
11335 hook.memoizedState = hook.baseState = initialState;
11336 var queue = (hook.queue = {
11337 last: null,
11338 dispatch: null,
11339 lastRenderedReducer: reducer,
11340 lastRenderedState: initialState
11341 });
11342 var dispatch = (queue.dispatch = dispatchAction.bind(
11343 null,
11344 // Flow doesn't know this is non-null, but we do.
11345 currentlyRenderingFiber$1,
11346 queue
11347 ));
11348 return [hook.memoizedState, dispatch];
11349}
11350
11351function updateReducer(reducer, initialArg, init) {
11352 var hook = updateWorkInProgressHook();
11353 var queue = hook.queue;
11354 (function() {
11355 if (!(queue !== null)) {
11356 throw ReactError(
11357 Error(
11358 "Should have a queue. This is likely a bug in React. Please file an issue."
11359 )
11360 );
11361 }
11362 })();
11363
11364 queue.lastRenderedReducer = reducer;
11365
11366 if (numberOfReRenders > 0) {
11367 // This is a re-render. Apply the new render phase updates to the previous
11368 var _dispatch = queue.dispatch;
11369 if (renderPhaseUpdates !== null) {
11370 // Render phase updates are stored in a map of queue -> linked list
11371 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
11372 if (firstRenderPhaseUpdate !== undefined) {
11373 renderPhaseUpdates.delete(queue);
11374 var newState = hook.memoizedState;
11375 var update = firstRenderPhaseUpdate;
11376 do {
11377 // Process this render phase update. We don't have to check the
11378 // priority because it will always be the same as the current
11379 // render's.
11380 var _action = update.action;
11381 newState = reducer(newState, _action);
11382 update = update.next;
11383 } while (update !== null);
11384
11385 // Mark that the fiber performed work, but only if the new state is
11386 // different from the current state.
11387 if (!is(newState, hook.memoizedState)) {
11388 markWorkInProgressReceivedUpdate();
11389 }
11390
11391 hook.memoizedState = newState;
11392 // Don't persist the state accumulated from the render phase updates to
11393 // the base state unless the queue is empty.
11394 // TODO: Not sure if this is the desired semantics, but it's what we
11395 // do for gDSFP. I can't remember why.
11396 if (hook.baseUpdate === queue.last) {
11397 hook.baseState = newState;
11398 }
11399
11400 queue.lastRenderedState = newState;
11401
11402 return [newState, _dispatch];
11403 }
11404 }
11405 return [hook.memoizedState, _dispatch];
11406 }
11407
11408 // The last update in the entire queue
11409 var last = queue.last;
11410 // The last update that is part of the base state.
11411 var baseUpdate = hook.baseUpdate;
11412 var baseState = hook.baseState;
11413
11414 // Find the first unprocessed update.
11415 var first = void 0;
11416 if (baseUpdate !== null) {
11417 if (last !== null) {
11418 // For the first update, the queue is a circular linked list where
11419 // `queue.last.next = queue.first`. Once the first update commits, and
11420 // the `baseUpdate` is no longer empty, we can unravel the list.
11421 last.next = null;
11422 }
11423 first = baseUpdate.next;
11424 } else {
11425 first = last !== null ? last.next : null;
11426 }
11427 if (first !== null) {
11428 var _newState = baseState;
11429 var newBaseState = null;
11430 var newBaseUpdate = null;
11431 var prevUpdate = baseUpdate;
11432 var _update = first;
11433 var didSkip = false;
11434 do {
11435 var updateExpirationTime = _update.expirationTime;
11436 if (updateExpirationTime < renderExpirationTime$1) {
11437 // Priority is insufficient. Skip this update. If this is the first
11438 // skipped update, the previous update/state is the new base
11439 // update/state.
11440 if (!didSkip) {
11441 didSkip = true;
11442 newBaseUpdate = prevUpdate;
11443 newBaseState = _newState;
11444 }
11445 // Update the remaining priority in the queue.
11446 if (updateExpirationTime > remainingExpirationTime) {
11447 remainingExpirationTime = updateExpirationTime;
11448 }
11449 } else {
11450 // This update does have sufficient priority.
11451
11452 // Mark the event time of this update as relevant to this render pass.
11453 // TODO: This should ideally use the true event time of this update rather than
11454 // its priority which is a derived and not reverseable value.
11455 // TODO: We should skip this update if it was already committed but currently
11456 // we have no way of detecting the difference between a committed and suspended
11457 // update here.
11458 markRenderEventTimeAndConfig(
11459 updateExpirationTime,
11460 _update.suspenseConfig
11461 );
11462
11463 // Process this update.
11464 if (_update.eagerReducer === reducer) {
11465 // If this update was processed eagerly, and its reducer matches the
11466 // current reducer, we can use the eagerly computed state.
11467 _newState = _update.eagerState;
11468 } else {
11469 var _action2 = _update.action;
11470 _newState = reducer(_newState, _action2);
11471 }
11472 }
11473 prevUpdate = _update;
11474 _update = _update.next;
11475 } while (_update !== null && _update !== first);
11476
11477 if (!didSkip) {
11478 newBaseUpdate = prevUpdate;
11479 newBaseState = _newState;
11480 }
11481
11482 // Mark that the fiber performed work, but only if the new state is
11483 // different from the current state.
11484 if (!is(_newState, hook.memoizedState)) {
11485 markWorkInProgressReceivedUpdate();
11486 }
11487
11488 hook.memoizedState = _newState;
11489 hook.baseUpdate = newBaseUpdate;
11490 hook.baseState = newBaseState;
11491
11492 queue.lastRenderedState = _newState;
11493 }
11494
11495 var dispatch = queue.dispatch;
11496 return [hook.memoizedState, dispatch];
11497}
11498
11499function mountState(initialState) {
11500 var hook = mountWorkInProgressHook();
11501 if (typeof initialState === "function") {
11502 initialState = initialState();
11503 }
11504 hook.memoizedState = hook.baseState = initialState;
11505 var queue = (hook.queue = {
11506 last: null,
11507 dispatch: null,
11508 lastRenderedReducer: basicStateReducer,
11509 lastRenderedState: initialState
11510 });
11511 var dispatch = (queue.dispatch = dispatchAction.bind(
11512 null,
11513 // Flow doesn't know this is non-null, but we do.
11514 currentlyRenderingFiber$1,
11515 queue
11516 ));
11517 return [hook.memoizedState, dispatch];
11518}
11519
11520function updateState(initialState) {
11521 return updateReducer(basicStateReducer, initialState);
11522}
11523
11524function pushEffect(tag, create, destroy, deps) {
11525 var effect = {
11526 tag: tag,
11527 create: create,
11528 destroy: destroy,
11529 deps: deps,
11530 // Circular
11531 next: null
11532 };
11533 if (componentUpdateQueue === null) {
11534 componentUpdateQueue = createFunctionComponentUpdateQueue();
11535 componentUpdateQueue.lastEffect = effect.next = effect;
11536 } else {
11537 var _lastEffect = componentUpdateQueue.lastEffect;
11538 if (_lastEffect === null) {
11539 componentUpdateQueue.lastEffect = effect.next = effect;
11540 } else {
11541 var firstEffect = _lastEffect.next;
11542 _lastEffect.next = effect;
11543 effect.next = firstEffect;
11544 componentUpdateQueue.lastEffect = effect;
11545 }
11546 }
11547 return effect;
11548}
11549
11550function mountRef(initialValue) {
11551 var hook = mountWorkInProgressHook();
11552 var ref = { current: initialValue };
11553 {
11554 Object.seal(ref);
11555 }
11556 hook.memoizedState = ref;
11557 return ref;
11558}
11559
11560function updateRef(initialValue) {
11561 var hook = updateWorkInProgressHook();
11562 return hook.memoizedState;
11563}
11564
11565function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
11566 var hook = mountWorkInProgressHook();
11567 var nextDeps = deps === undefined ? null : deps;
11568 sideEffectTag |= fiberEffectTag;
11569 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
11570}
11571
11572function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
11573 var hook = updateWorkInProgressHook();
11574 var nextDeps = deps === undefined ? null : deps;
11575 var destroy = undefined;
11576
11577 if (currentHook !== null) {
11578 var prevEffect = currentHook.memoizedState;
11579 destroy = prevEffect.destroy;
11580 if (nextDeps !== null) {
11581 var prevDeps = prevEffect.deps;
11582 if (areHookInputsEqual(nextDeps, prevDeps)) {
11583 pushEffect(NoEffect$1, create, destroy, nextDeps);
11584 return;
11585 }
11586 }
11587 }
11588
11589 sideEffectTag |= fiberEffectTag;
11590 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
11591}
11592
11593function mountEffect(create, deps) {
11594 {
11595 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
11596 if ("undefined" !== typeof jest) {
11597 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
11598 }
11599 }
11600 return mountEffectImpl(
11601 Update | Passive,
11602 UnmountPassive | MountPassive,
11603 create,
11604 deps
11605 );
11606}
11607
11608function updateEffect(create, deps) {
11609 {
11610 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
11611 if ("undefined" !== typeof jest) {
11612 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
11613 }
11614 }
11615 return updateEffectImpl(
11616 Update | Passive,
11617 UnmountPassive | MountPassive,
11618 create,
11619 deps
11620 );
11621}
11622
11623function mountLayoutEffect(create, deps) {
11624 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
11625}
11626
11627function updateLayoutEffect(create, deps) {
11628 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
11629}
11630
11631function imperativeHandleEffect(create, ref) {
11632 if (typeof ref === "function") {
11633 var refCallback = ref;
11634 var _inst = create();
11635 refCallback(_inst);
11636 return function() {
11637 refCallback(null);
11638 };
11639 } else if (ref !== null && ref !== undefined) {
11640 var refObject = ref;
11641 {
11642 !refObject.hasOwnProperty("current")
11643 ? warning$1(
11644 false,
11645 "Expected useImperativeHandle() first argument to either be a " +
11646 "ref callback or React.createRef() object. Instead received: %s.",
11647 "an object with keys {" + Object.keys(refObject).join(", ") + "}"
11648 )
11649 : void 0;
11650 }
11651 var _inst2 = create();
11652 refObject.current = _inst2;
11653 return function() {
11654 refObject.current = null;
11655 };
11656 }
11657}
11658
11659function mountImperativeHandle(ref, create, deps) {
11660 {
11661 !(typeof create === "function")
11662 ? warning$1(
11663 false,
11664 "Expected useImperativeHandle() second argument to be a function " +
11665 "that creates a handle. Instead received: %s.",
11666 create !== null ? typeof create : "null"
11667 )
11668 : void 0;
11669 }
11670
11671 // TODO: If deps are provided, should we skip comparing the ref itself?
11672 var effectDeps =
11673 deps !== null && deps !== undefined ? deps.concat([ref]) : null;
11674
11675 return mountEffectImpl(
11676 Update,
11677 UnmountMutation | MountLayout,
11678 imperativeHandleEffect.bind(null, create, ref),
11679 effectDeps
11680 );
11681}
11682
11683function updateImperativeHandle(ref, create, deps) {
11684 {
11685 !(typeof create === "function")
11686 ? warning$1(
11687 false,
11688 "Expected useImperativeHandle() second argument to be a function " +
11689 "that creates a handle. Instead received: %s.",
11690 create !== null ? typeof create : "null"
11691 )
11692 : void 0;
11693 }
11694
11695 // TODO: If deps are provided, should we skip comparing the ref itself?
11696 var effectDeps =
11697 deps !== null && deps !== undefined ? deps.concat([ref]) : null;
11698
11699 return updateEffectImpl(
11700 Update,
11701 UnmountMutation | MountLayout,
11702 imperativeHandleEffect.bind(null, create, ref),
11703 effectDeps
11704 );
11705}
11706
11707function mountDebugValue(value, formatterFn) {
11708 // This hook is normally a no-op.
11709 // The react-debug-hooks package injects its own implementation
11710 // so that e.g. DevTools can display custom hook values.
11711}
11712
11713var updateDebugValue = mountDebugValue;
11714
11715function mountCallback(callback, deps) {
11716 var hook = mountWorkInProgressHook();
11717 var nextDeps = deps === undefined ? null : deps;
11718 hook.memoizedState = [callback, nextDeps];
11719 return callback;
11720}
11721
11722function updateCallback(callback, deps) {
11723 var hook = updateWorkInProgressHook();
11724 var nextDeps = deps === undefined ? null : deps;
11725 var prevState = hook.memoizedState;
11726 if (prevState !== null) {
11727 if (nextDeps !== null) {
11728 var prevDeps = prevState[1];
11729 if (areHookInputsEqual(nextDeps, prevDeps)) {
11730 return prevState[0];
11731 }
11732 }
11733 }
11734 hook.memoizedState = [callback, nextDeps];
11735 return callback;
11736}
11737
11738function mountMemo(nextCreate, deps) {
11739 var hook = mountWorkInProgressHook();
11740 var nextDeps = deps === undefined ? null : deps;
11741 var nextValue = nextCreate();
11742 hook.memoizedState = [nextValue, nextDeps];
11743 return nextValue;
11744}
11745
11746function updateMemo(nextCreate, deps) {
11747 var hook = updateWorkInProgressHook();
11748 var nextDeps = deps === undefined ? null : deps;
11749 var prevState = hook.memoizedState;
11750 if (prevState !== null) {
11751 // Assume these are defined. If they're not, areHookInputsEqual will warn.
11752 if (nextDeps !== null) {
11753 var prevDeps = prevState[1];
11754 if (areHookInputsEqual(nextDeps, prevDeps)) {
11755 return prevState[0];
11756 }
11757 }
11758 }
11759 var nextValue = nextCreate();
11760 hook.memoizedState = [nextValue, nextDeps];
11761 return nextValue;
11762}
11763
11764function dispatchAction(fiber, queue, action) {
11765 (function() {
11766 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
11767 throw ReactError(
11768 Error(
11769 "Too many re-renders. React limits the number of renders to prevent an infinite loop."
11770 )
11771 );
11772 }
11773 })();
11774
11775 {
11776 !(arguments.length <= 3)
11777 ? warning$1(
11778 false,
11779 "State updates from the useState() and useReducer() Hooks don't support the " +
11780 "second callback argument. To execute a side effect after " +
11781 "rendering, declare it in the component body with useEffect()."
11782 )
11783 : void 0;
11784 }
11785
11786 var alternate = fiber.alternate;
11787 if (
11788 fiber === currentlyRenderingFiber$1 ||
11789 (alternate !== null && alternate === currentlyRenderingFiber$1)
11790 ) {
11791 // This is a render phase update. Stash it in a lazily-created map of
11792 // queue -> linked list of updates. After this render pass, we'll restart
11793 // and apply the stashed updates on top of the work-in-progress hook.
11794 didScheduleRenderPhaseUpdate = true;
11795 var update = {
11796 expirationTime: renderExpirationTime$1,
11797 suspenseConfig: null,
11798 action: action,
11799 eagerReducer: null,
11800 eagerState: null,
11801 next: null
11802 };
11803 {
11804 update.priority = getCurrentPriorityLevel();
11805 }
11806 if (renderPhaseUpdates === null) {
11807 renderPhaseUpdates = new Map();
11808 }
11809 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
11810 if (firstRenderPhaseUpdate === undefined) {
11811 renderPhaseUpdates.set(queue, update);
11812 } else {
11813 // Append the update to the end of the list.
11814 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
11815 while (lastRenderPhaseUpdate.next !== null) {
11816 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
11817 }
11818 lastRenderPhaseUpdate.next = update;
11819 }
11820 } else {
11821 if (revertPassiveEffectsChange) {
11822 flushPassiveEffects();
11823 }
11824
11825 var currentTime = requestCurrentTime();
11826 var _suspenseConfig = requestCurrentSuspenseConfig();
11827 var _expirationTime = computeExpirationForFiber(
11828 currentTime,
11829 fiber,
11830 _suspenseConfig
11831 );
11832
11833 var _update2 = {
11834 expirationTime: _expirationTime,
11835 suspenseConfig: _suspenseConfig,
11836 action: action,
11837 eagerReducer: null,
11838 eagerState: null,
11839 next: null
11840 };
11841
11842 {
11843 _update2.priority = getCurrentPriorityLevel();
11844 }
11845
11846 // Append the update to the end of the list.
11847 var _last = queue.last;
11848 if (_last === null) {
11849 // This is the first update. Create a circular list.
11850 _update2.next = _update2;
11851 } else {
11852 var first = _last.next;
11853 if (first !== null) {
11854 // Still circular.
11855 _update2.next = first;
11856 }
11857 _last.next = _update2;
11858 }
11859 queue.last = _update2;
11860
11861 if (
11862 fiber.expirationTime === NoWork &&
11863 (alternate === null || alternate.expirationTime === NoWork)
11864 ) {
11865 // The queue is currently empty, which means we can eagerly compute the
11866 // next state before entering the render phase. If the new state is the
11867 // same as the current state, we may be able to bail out entirely.
11868 var _lastRenderedReducer = queue.lastRenderedReducer;
11869 if (_lastRenderedReducer !== null) {
11870 var prevDispatcher = void 0;
11871 {
11872 prevDispatcher = ReactCurrentDispatcher$1.current;
11873 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
11874 }
11875 try {
11876 var currentState = queue.lastRenderedState;
11877 var _eagerState = _lastRenderedReducer(currentState, action);
11878 // Stash the eagerly computed state, and the reducer used to compute
11879 // it, on the update object. If the reducer hasn't changed by the
11880 // time we enter the render phase, then the eager state can be used
11881 // without calling the reducer again.
11882 _update2.eagerReducer = _lastRenderedReducer;
11883 _update2.eagerState = _eagerState;
11884 if (is(_eagerState, currentState)) {
11885 // Fast path. We can bail out without scheduling React to re-render.
11886 // It's still possible that we'll need to rebase this update later,
11887 // if the component re-renders for a different reason and by that
11888 // time the reducer has changed.
11889 return;
11890 }
11891 } catch (error) {
11892 // Suppress the error. It will throw again in the render phase.
11893 } finally {
11894 {
11895 ReactCurrentDispatcher$1.current = prevDispatcher;
11896 }
11897 }
11898 }
11899 }
11900 {
11901 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
11902 if ("undefined" !== typeof jest) {
11903 warnIfNotScopedWithMatchingAct(fiber);
11904 warnIfNotCurrentlyActingUpdatesInDev(fiber);
11905 }
11906 }
11907 scheduleWork(fiber, _expirationTime);
11908 }
11909}
11910
11911var ContextOnlyDispatcher = {
11912 readContext: readContext,
11913
11914 useCallback: throwInvalidHookError,
11915 useContext: throwInvalidHookError,
11916 useEffect: throwInvalidHookError,
11917 useImperativeHandle: throwInvalidHookError,
11918 useLayoutEffect: throwInvalidHookError,
11919 useMemo: throwInvalidHookError,
11920 useReducer: throwInvalidHookError,
11921 useRef: throwInvalidHookError,
11922 useState: throwInvalidHookError,
11923 useDebugValue: throwInvalidHookError,
11924 useResponder: throwInvalidHookError
11925};
11926
11927var HooksDispatcherOnMountInDEV = null;
11928var HooksDispatcherOnMountWithHookTypesInDEV = null;
11929var HooksDispatcherOnUpdateInDEV = null;
11930var InvalidNestedHooksDispatcherOnMountInDEV = null;
11931var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
11932
11933{
11934 var warnInvalidContextAccess = function() {
11935 warning$1(
11936 false,
11937 "Context can only be read while React is rendering. " +
11938 "In classes, you can read it in the render method or getDerivedStateFromProps. " +
11939 "In function components, you can read it directly in the function body, but not " +
11940 "inside Hooks like useReducer() or useMemo()."
11941 );
11942 };
11943
11944 var warnInvalidHookAccess = function() {
11945 warning$1(
11946 false,
11947 "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " +
11948 "You can only call Hooks at the top level of your React function. " +
11949 "For more information, see " +
11950 "https://fb.me/rules-of-hooks"
11951 );
11952 };
11953
11954 HooksDispatcherOnMountInDEV = {
11955 readContext: function(context, observedBits) {
11956 return readContext(context, observedBits);
11957 },
11958 useCallback: function(callback, deps) {
11959 currentHookNameInDev = "useCallback";
11960 mountHookTypesDev();
11961 checkDepsAreArrayDev(deps);
11962 return mountCallback(callback, deps);
11963 },
11964 useContext: function(context, observedBits) {
11965 currentHookNameInDev = "useContext";
11966 mountHookTypesDev();
11967 return readContext(context, observedBits);
11968 },
11969 useEffect: function(create, deps) {
11970 currentHookNameInDev = "useEffect";
11971 mountHookTypesDev();
11972 checkDepsAreArrayDev(deps);
11973 return mountEffect(create, deps);
11974 },
11975 useImperativeHandle: function(ref, create, deps) {
11976 currentHookNameInDev = "useImperativeHandle";
11977 mountHookTypesDev();
11978 checkDepsAreArrayDev(deps);
11979 return mountImperativeHandle(ref, create, deps);
11980 },
11981 useLayoutEffect: function(create, deps) {
11982 currentHookNameInDev = "useLayoutEffect";
11983 mountHookTypesDev();
11984 checkDepsAreArrayDev(deps);
11985 return mountLayoutEffect(create, deps);
11986 },
11987 useMemo: function(create, deps) {
11988 currentHookNameInDev = "useMemo";
11989 mountHookTypesDev();
11990 checkDepsAreArrayDev(deps);
11991 var prevDispatcher = ReactCurrentDispatcher$1.current;
11992 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
11993 try {
11994 return mountMemo(create, deps);
11995 } finally {
11996 ReactCurrentDispatcher$1.current = prevDispatcher;
11997 }
11998 },
11999 useReducer: function(reducer, initialArg, init) {
12000 currentHookNameInDev = "useReducer";
12001 mountHookTypesDev();
12002 var prevDispatcher = ReactCurrentDispatcher$1.current;
12003 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
12004 try {
12005 return mountReducer(reducer, initialArg, init);
12006 } finally {
12007 ReactCurrentDispatcher$1.current = prevDispatcher;
12008 }
12009 },
12010 useRef: function(initialValue) {
12011 currentHookNameInDev = "useRef";
12012 mountHookTypesDev();
12013 return mountRef(initialValue);
12014 },
12015 useState: function(initialState) {
12016 currentHookNameInDev = "useState";
12017 mountHookTypesDev();
12018 var prevDispatcher = ReactCurrentDispatcher$1.current;
12019 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
12020 try {
12021 return mountState(initialState);
12022 } finally {
12023 ReactCurrentDispatcher$1.current = prevDispatcher;
12024 }
12025 },
12026 useDebugValue: function(value, formatterFn) {
12027 currentHookNameInDev = "useDebugValue";
12028 mountHookTypesDev();
12029 return mountDebugValue(value, formatterFn);
12030 },
12031 useResponder: function(responder, props) {
12032 currentHookNameInDev = "useResponder";
12033 mountHookTypesDev();
12034 return createResponderListener(responder, props);
12035 }
12036 };
12037
12038 HooksDispatcherOnMountWithHookTypesInDEV = {
12039 readContext: function(context, observedBits) {
12040 return readContext(context, observedBits);
12041 },
12042 useCallback: function(callback, deps) {
12043 currentHookNameInDev = "useCallback";
12044 updateHookTypesDev();
12045 return mountCallback(callback, deps);
12046 },
12047 useContext: function(context, observedBits) {
12048 currentHookNameInDev = "useContext";
12049 updateHookTypesDev();
12050 return readContext(context, observedBits);
12051 },
12052 useEffect: function(create, deps) {
12053 currentHookNameInDev = "useEffect";
12054 updateHookTypesDev();
12055 return mountEffect(create, deps);
12056 },
12057 useImperativeHandle: function(ref, create, deps) {
12058 currentHookNameInDev = "useImperativeHandle";
12059 updateHookTypesDev();
12060 return mountImperativeHandle(ref, create, deps);
12061 },
12062 useLayoutEffect: function(create, deps) {
12063 currentHookNameInDev = "useLayoutEffect";
12064 updateHookTypesDev();
12065 return mountLayoutEffect(create, deps);
12066 },
12067 useMemo: function(create, deps) {
12068 currentHookNameInDev = "useMemo";
12069 updateHookTypesDev();
12070 var prevDispatcher = ReactCurrentDispatcher$1.current;
12071 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
12072 try {
12073 return mountMemo(create, deps);
12074 } finally {
12075 ReactCurrentDispatcher$1.current = prevDispatcher;
12076 }
12077 },
12078 useReducer: function(reducer, initialArg, init) {
12079 currentHookNameInDev = "useReducer";
12080 updateHookTypesDev();
12081 var prevDispatcher = ReactCurrentDispatcher$1.current;
12082 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
12083 try {
12084 return mountReducer(reducer, initialArg, init);
12085 } finally {
12086 ReactCurrentDispatcher$1.current = prevDispatcher;
12087 }
12088 },
12089 useRef: function(initialValue) {
12090 currentHookNameInDev = "useRef";
12091 updateHookTypesDev();
12092 return mountRef(initialValue);
12093 },
12094 useState: function(initialState) {
12095 currentHookNameInDev = "useState";
12096 updateHookTypesDev();
12097 var prevDispatcher = ReactCurrentDispatcher$1.current;
12098 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
12099 try {
12100 return mountState(initialState);
12101 } finally {
12102 ReactCurrentDispatcher$1.current = prevDispatcher;
12103 }
12104 },
12105 useDebugValue: function(value, formatterFn) {
12106 currentHookNameInDev = "useDebugValue";
12107 updateHookTypesDev();
12108 return mountDebugValue(value, formatterFn);
12109 },
12110 useResponder: function(responder, props) {
12111 currentHookNameInDev = "useResponder";
12112 updateHookTypesDev();
12113 return createResponderListener(responder, props);
12114 }
12115 };
12116
12117 HooksDispatcherOnUpdateInDEV = {
12118 readContext: function(context, observedBits) {
12119 return readContext(context, observedBits);
12120 },
12121 useCallback: function(callback, deps) {
12122 currentHookNameInDev = "useCallback";
12123 updateHookTypesDev();
12124 return updateCallback(callback, deps);
12125 },
12126 useContext: function(context, observedBits) {
12127 currentHookNameInDev = "useContext";
12128 updateHookTypesDev();
12129 return readContext(context, observedBits);
12130 },
12131 useEffect: function(create, deps) {
12132 currentHookNameInDev = "useEffect";
12133 updateHookTypesDev();
12134 return updateEffect(create, deps);
12135 },
12136 useImperativeHandle: function(ref, create, deps) {
12137 currentHookNameInDev = "useImperativeHandle";
12138 updateHookTypesDev();
12139 return updateImperativeHandle(ref, create, deps);
12140 },
12141 useLayoutEffect: function(create, deps) {
12142 currentHookNameInDev = "useLayoutEffect";
12143 updateHookTypesDev();
12144 return updateLayoutEffect(create, deps);
12145 },
12146 useMemo: function(create, deps) {
12147 currentHookNameInDev = "useMemo";
12148 updateHookTypesDev();
12149 var prevDispatcher = ReactCurrentDispatcher$1.current;
12150 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
12151 try {
12152 return updateMemo(create, deps);
12153 } finally {
12154 ReactCurrentDispatcher$1.current = prevDispatcher;
12155 }
12156 },
12157 useReducer: function(reducer, initialArg, init) {
12158 currentHookNameInDev = "useReducer";
12159 updateHookTypesDev();
12160 var prevDispatcher = ReactCurrentDispatcher$1.current;
12161 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
12162 try {
12163 return updateReducer(reducer, initialArg, init);
12164 } finally {
12165 ReactCurrentDispatcher$1.current = prevDispatcher;
12166 }
12167 },
12168 useRef: function(initialValue) {
12169 currentHookNameInDev = "useRef";
12170 updateHookTypesDev();
12171 return updateRef(initialValue);
12172 },
12173 useState: function(initialState) {
12174 currentHookNameInDev = "useState";
12175 updateHookTypesDev();
12176 var prevDispatcher = ReactCurrentDispatcher$1.current;
12177 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
12178 try {
12179 return updateState(initialState);
12180 } finally {
12181 ReactCurrentDispatcher$1.current = prevDispatcher;
12182 }
12183 },
12184 useDebugValue: function(value, formatterFn) {
12185 currentHookNameInDev = "useDebugValue";
12186 updateHookTypesDev();
12187 return updateDebugValue(value, formatterFn);
12188 },
12189 useResponder: function(responder, props) {
12190 currentHookNameInDev = "useResponder";
12191 updateHookTypesDev();
12192 return createResponderListener(responder, props);
12193 }
12194 };
12195
12196 InvalidNestedHooksDispatcherOnMountInDEV = {
12197 readContext: function(context, observedBits) {
12198 warnInvalidContextAccess();
12199 return readContext(context, observedBits);
12200 },
12201 useCallback: function(callback, deps) {
12202 currentHookNameInDev = "useCallback";
12203 warnInvalidHookAccess();
12204 mountHookTypesDev();
12205 return mountCallback(callback, deps);
12206 },
12207 useContext: function(context, observedBits) {
12208 currentHookNameInDev = "useContext";
12209 warnInvalidHookAccess();
12210 mountHookTypesDev();
12211 return readContext(context, observedBits);
12212 },
12213 useEffect: function(create, deps) {
12214 currentHookNameInDev = "useEffect";
12215 warnInvalidHookAccess();
12216 mountHookTypesDev();
12217 return mountEffect(create, deps);
12218 },
12219 useImperativeHandle: function(ref, create, deps) {
12220 currentHookNameInDev = "useImperativeHandle";
12221 warnInvalidHookAccess();
12222 mountHookTypesDev();
12223 return mountImperativeHandle(ref, create, deps);
12224 },
12225 useLayoutEffect: function(create, deps) {
12226 currentHookNameInDev = "useLayoutEffect";
12227 warnInvalidHookAccess();
12228 mountHookTypesDev();
12229 return mountLayoutEffect(create, deps);
12230 },
12231 useMemo: function(create, deps) {
12232 currentHookNameInDev = "useMemo";
12233 warnInvalidHookAccess();
12234 mountHookTypesDev();
12235 var prevDispatcher = ReactCurrentDispatcher$1.current;
12236 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
12237 try {
12238 return mountMemo(create, deps);
12239 } finally {
12240 ReactCurrentDispatcher$1.current = prevDispatcher;
12241 }
12242 },
12243 useReducer: function(reducer, initialArg, init) {
12244 currentHookNameInDev = "useReducer";
12245 warnInvalidHookAccess();
12246 mountHookTypesDev();
12247 var prevDispatcher = ReactCurrentDispatcher$1.current;
12248 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
12249 try {
12250 return mountReducer(reducer, initialArg, init);
12251 } finally {
12252 ReactCurrentDispatcher$1.current = prevDispatcher;
12253 }
12254 },
12255 useRef: function(initialValue) {
12256 currentHookNameInDev = "useRef";
12257 warnInvalidHookAccess();
12258 mountHookTypesDev();
12259 return mountRef(initialValue);
12260 },
12261 useState: function(initialState) {
12262 currentHookNameInDev = "useState";
12263 warnInvalidHookAccess();
12264 mountHookTypesDev();
12265 var prevDispatcher = ReactCurrentDispatcher$1.current;
12266 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
12267 try {
12268 return mountState(initialState);
12269 } finally {
12270 ReactCurrentDispatcher$1.current = prevDispatcher;
12271 }
12272 },
12273 useDebugValue: function(value, formatterFn) {
12274 currentHookNameInDev = "useDebugValue";
12275 warnInvalidHookAccess();
12276 mountHookTypesDev();
12277 return mountDebugValue(value, formatterFn);
12278 },
12279 useResponder: function(responder, props) {
12280 currentHookNameInDev = "useResponder";
12281 warnInvalidHookAccess();
12282 mountHookTypesDev();
12283 return createResponderListener(responder, props);
12284 }
12285 };
12286
12287 InvalidNestedHooksDispatcherOnUpdateInDEV = {
12288 readContext: function(context, observedBits) {
12289 warnInvalidContextAccess();
12290 return readContext(context, observedBits);
12291 },
12292 useCallback: function(callback, deps) {
12293 currentHookNameInDev = "useCallback";
12294 warnInvalidHookAccess();
12295 updateHookTypesDev();
12296 return updateCallback(callback, deps);
12297 },
12298 useContext: function(context, observedBits) {
12299 currentHookNameInDev = "useContext";
12300 warnInvalidHookAccess();
12301 updateHookTypesDev();
12302 return readContext(context, observedBits);
12303 },
12304 useEffect: function(create, deps) {
12305 currentHookNameInDev = "useEffect";
12306 warnInvalidHookAccess();
12307 updateHookTypesDev();
12308 return updateEffect(create, deps);
12309 },
12310 useImperativeHandle: function(ref, create, deps) {
12311 currentHookNameInDev = "useImperativeHandle";
12312 warnInvalidHookAccess();
12313 updateHookTypesDev();
12314 return updateImperativeHandle(ref, create, deps);
12315 },
12316 useLayoutEffect: function(create, deps) {
12317 currentHookNameInDev = "useLayoutEffect";
12318 warnInvalidHookAccess();
12319 updateHookTypesDev();
12320 return updateLayoutEffect(create, deps);
12321 },
12322 useMemo: function(create, deps) {
12323 currentHookNameInDev = "useMemo";
12324 warnInvalidHookAccess();
12325 updateHookTypesDev();
12326 var prevDispatcher = ReactCurrentDispatcher$1.current;
12327 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
12328 try {
12329 return updateMemo(create, deps);
12330 } finally {
12331 ReactCurrentDispatcher$1.current = prevDispatcher;
12332 }
12333 },
12334 useReducer: function(reducer, initialArg, init) {
12335 currentHookNameInDev = "useReducer";
12336 warnInvalidHookAccess();
12337 updateHookTypesDev();
12338 var prevDispatcher = ReactCurrentDispatcher$1.current;
12339 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
12340 try {
12341 return updateReducer(reducer, initialArg, init);
12342 } finally {
12343 ReactCurrentDispatcher$1.current = prevDispatcher;
12344 }
12345 },
12346 useRef: function(initialValue) {
12347 currentHookNameInDev = "useRef";
12348 warnInvalidHookAccess();
12349 updateHookTypesDev();
12350 return updateRef(initialValue);
12351 },
12352 useState: function(initialState) {
12353 currentHookNameInDev = "useState";
12354 warnInvalidHookAccess();
12355 updateHookTypesDev();
12356 var prevDispatcher = ReactCurrentDispatcher$1.current;
12357 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
12358 try {
12359 return updateState(initialState);
12360 } finally {
12361 ReactCurrentDispatcher$1.current = prevDispatcher;
12362 }
12363 },
12364 useDebugValue: function(value, formatterFn) {
12365 currentHookNameInDev = "useDebugValue";
12366 warnInvalidHookAccess();
12367 updateHookTypesDev();
12368 return updateDebugValue(value, formatterFn);
12369 },
12370 useResponder: function(responder, props) {
12371 currentHookNameInDev = "useResponder";
12372 warnInvalidHookAccess();
12373 updateHookTypesDev();
12374 return createResponderListener(responder, props);
12375 }
12376 };
12377}
12378
12379// Intentionally not named imports because Rollup would use dynamic dispatch for
12380// CommonJS interop named imports.
12381var now$1 = Scheduler.unstable_now;
12382
12383var commitTime = 0;
12384var profilerStartTime = -1;
12385
12386function getCommitTime() {
12387 return commitTime;
12388}
12389
12390function recordCommitTime() {
12391 if (!enableProfilerTimer) {
12392 return;
12393 }
12394 commitTime = now$1();
12395}
12396
12397function startProfilerTimer(fiber) {
12398 if (!enableProfilerTimer) {
12399 return;
12400 }
12401
12402 profilerStartTime = now$1();
12403
12404 if (fiber.actualStartTime < 0) {
12405 fiber.actualStartTime = now$1();
12406 }
12407}
12408
12409function stopProfilerTimerIfRunning(fiber) {
12410 if (!enableProfilerTimer) {
12411 return;
12412 }
12413 profilerStartTime = -1;
12414}
12415
12416function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
12417 if (!enableProfilerTimer) {
12418 return;
12419 }
12420
12421 if (profilerStartTime >= 0) {
12422 var elapsedTime = now$1() - profilerStartTime;
12423 fiber.actualDuration += elapsedTime;
12424 if (overrideBaseTime) {
12425 fiber.selfBaseDuration = elapsedTime;
12426 }
12427 profilerStartTime = -1;
12428 }
12429}
12430
12431// The deepest Fiber on the stack involved in a hydration context.
12432// This may have been an insertion or a hydration.
12433var hydrationParentFiber = null;
12434var nextHydratableInstance = null;
12435var isHydrating = false;
12436
12437function warnIfHydrating() {
12438 {
12439 !!isHydrating
12440 ? warning$1(
12441 false,
12442 "We should not be hydrating here. This is a bug in React. Please file a bug."
12443 )
12444 : void 0;
12445 }
12446}
12447
12448function enterHydrationState(fiber) {
12449 if (!supportsHydration) {
12450 return false;
12451 }
12452
12453 var parentInstance = fiber.stateNode.containerInfo;
12454 nextHydratableInstance = getFirstHydratableChild(parentInstance);
12455 hydrationParentFiber = fiber;
12456 isHydrating = true;
12457 return true;
12458}
12459
12460function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
12461 if (!supportsHydration) {
12462 return false;
12463 }
12464
12465 var suspenseInstance = fiber.stateNode;
12466 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
12467 popToNextHostParent(fiber);
12468 isHydrating = true;
12469 return true;
12470}
12471
12472function deleteHydratableInstance(returnFiber, instance) {
12473 {
12474 switch (returnFiber.tag) {
12475 case HostRoot:
12476 didNotHydrateContainerInstance(
12477 returnFiber.stateNode.containerInfo,
12478 instance
12479 );
12480 break;
12481 case HostComponent:
12482 didNotHydrateInstance(
12483 returnFiber.type,
12484 returnFiber.memoizedProps,
12485 returnFiber.stateNode,
12486 instance
12487 );
12488 break;
12489 }
12490 }
12491
12492 var childToDelete = createFiberFromHostInstanceForDeletion();
12493 childToDelete.stateNode = instance;
12494 childToDelete.return = returnFiber;
12495 childToDelete.effectTag = Deletion;
12496
12497 // This might seem like it belongs on progressedFirstDeletion. However,
12498 // these children are not part of the reconciliation list of children.
12499 // Even if we abort and rereconcile the children, that will try to hydrate
12500 // again and the nodes are still in the host tree so these will be
12501 // recreated.
12502 if (returnFiber.lastEffect !== null) {
12503 returnFiber.lastEffect.nextEffect = childToDelete;
12504 returnFiber.lastEffect = childToDelete;
12505 } else {
12506 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
12507 }
12508}
12509
12510function insertNonHydratedInstance(returnFiber, fiber) {
12511 fiber.effectTag |= Placement;
12512 {
12513 switch (returnFiber.tag) {
12514 case HostRoot: {
12515 var parentContainer = returnFiber.stateNode.containerInfo;
12516 switch (fiber.tag) {
12517 case HostComponent:
12518 var type = fiber.type;
12519 var props = fiber.pendingProps;
12520 didNotFindHydratableContainerInstance(parentContainer, type, props);
12521 break;
12522 case HostText:
12523 var text = fiber.pendingProps;
12524 didNotFindHydratableContainerTextInstance(parentContainer, text);
12525 break;
12526 case SuspenseComponent:
12527 didNotFindHydratableContainerSuspenseInstance(parentContainer);
12528 break;
12529 }
12530 break;
12531 }
12532 case HostComponent: {
12533 var parentType = returnFiber.type;
12534 var parentProps = returnFiber.memoizedProps;
12535 var parentInstance = returnFiber.stateNode;
12536 switch (fiber.tag) {
12537 case HostComponent:
12538 var _type = fiber.type;
12539 var _props = fiber.pendingProps;
12540 didNotFindHydratableInstance(
12541 parentType,
12542 parentProps,
12543 parentInstance,
12544 _type,
12545 _props
12546 );
12547 break;
12548 case HostText:
12549 var _text = fiber.pendingProps;
12550 didNotFindHydratableTextInstance(
12551 parentType,
12552 parentProps,
12553 parentInstance,
12554 _text
12555 );
12556 break;
12557 case SuspenseComponent:
12558 didNotFindHydratableSuspenseInstance(
12559 parentType,
12560 parentProps,
12561 parentInstance
12562 );
12563 break;
12564 }
12565 break;
12566 }
12567 default:
12568 return;
12569 }
12570 }
12571}
12572
12573function tryHydrate(fiber, nextInstance) {
12574 switch (fiber.tag) {
12575 case HostComponent: {
12576 var type = fiber.type;
12577 var props = fiber.pendingProps;
12578 var instance = canHydrateInstance(nextInstance, type, props);
12579 if (instance !== null) {
12580 fiber.stateNode = instance;
12581 return true;
12582 }
12583 return false;
12584 }
12585 case HostText: {
12586 var text = fiber.pendingProps;
12587 var textInstance = canHydrateTextInstance(nextInstance, text);
12588 if (textInstance !== null) {
12589 fiber.stateNode = textInstance;
12590 return true;
12591 }
12592 return false;
12593 }
12594 case SuspenseComponent: {
12595 if (enableSuspenseServerRenderer) {
12596 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
12597 if (suspenseInstance !== null) {
12598 // Downgrade the tag to a dehydrated component until we've hydrated it.
12599 fiber.tag = DehydratedSuspenseComponent;
12600 fiber.stateNode = suspenseInstance;
12601 return true;
12602 }
12603 }
12604 return false;
12605 }
12606 default:
12607 return false;
12608 }
12609}
12610
12611function tryToClaimNextHydratableInstance(fiber) {
12612 if (!isHydrating) {
12613 return;
12614 }
12615 var nextInstance = nextHydratableInstance;
12616 if (!nextInstance) {
12617 // Nothing to hydrate. Make it an insertion.
12618 insertNonHydratedInstance(hydrationParentFiber, fiber);
12619 isHydrating = false;
12620 hydrationParentFiber = fiber;
12621 return;
12622 }
12623 var firstAttemptedInstance = nextInstance;
12624 if (!tryHydrate(fiber, nextInstance)) {
12625 // If we can't hydrate this instance let's try the next one.
12626 // We use this as a heuristic. It's based on intuition and not data so it
12627 // might be flawed or unnecessary.
12628 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
12629 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
12630 // Nothing to hydrate. Make it an insertion.
12631 insertNonHydratedInstance(hydrationParentFiber, fiber);
12632 isHydrating = false;
12633 hydrationParentFiber = fiber;
12634 return;
12635 }
12636 // We matched the next one, we'll now assume that the first one was
12637 // superfluous and we'll delete it. Since we can't eagerly delete it
12638 // we'll have to schedule a deletion. To do that, this node needs a dummy
12639 // fiber associated with it.
12640 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
12641 }
12642 hydrationParentFiber = fiber;
12643 nextHydratableInstance = getFirstHydratableChild(nextInstance);
12644}
12645
12646function prepareToHydrateHostInstance(
12647 fiber,
12648 rootContainerInstance,
12649 hostContext
12650) {
12651 if (!supportsHydration) {
12652 (function() {
12653 {
12654 throw ReactError(
12655 Error(
12656 "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."
12657 )
12658 );
12659 }
12660 })();
12661 }
12662
12663 var instance = fiber.stateNode;
12664 var updatePayload = hydrateInstance(
12665 instance,
12666 fiber.type,
12667 fiber.memoizedProps,
12668 rootContainerInstance,
12669 hostContext,
12670 fiber
12671 );
12672 // TODO: Type this specific to this type of component.
12673 fiber.updateQueue = updatePayload;
12674 // If the update payload indicates that there is a change or if there
12675 // is a new ref we mark this as an update.
12676 if (updatePayload !== null) {
12677 return true;
12678 }
12679 return false;
12680}
12681
12682function prepareToHydrateHostTextInstance(fiber) {
12683 if (!supportsHydration) {
12684 (function() {
12685 {
12686 throw ReactError(
12687 Error(
12688 "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."
12689 )
12690 );
12691 }
12692 })();
12693 }
12694
12695 var textInstance = fiber.stateNode;
12696 var textContent = fiber.memoizedProps;
12697 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
12698 {
12699 if (shouldUpdate) {
12700 // We assume that prepareToHydrateHostTextInstance is called in a context where the
12701 // hydration parent is the parent host component of this host text.
12702 var returnFiber = hydrationParentFiber;
12703 if (returnFiber !== null) {
12704 switch (returnFiber.tag) {
12705 case HostRoot: {
12706 var parentContainer = returnFiber.stateNode.containerInfo;
12707 didNotMatchHydratedContainerTextInstance(
12708 parentContainer,
12709 textInstance,
12710 textContent
12711 );
12712 break;
12713 }
12714 case HostComponent: {
12715 var parentType = returnFiber.type;
12716 var parentProps = returnFiber.memoizedProps;
12717 var parentInstance = returnFiber.stateNode;
12718 didNotMatchHydratedTextInstance(
12719 parentType,
12720 parentProps,
12721 parentInstance,
12722 textInstance,
12723 textContent
12724 );
12725 break;
12726 }
12727 }
12728 }
12729 }
12730 }
12731 return shouldUpdate;
12732}
12733
12734function skipPastDehydratedSuspenseInstance(fiber) {
12735 if (!supportsHydration) {
12736 (function() {
12737 {
12738 throw ReactError(
12739 Error(
12740 "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."
12741 )
12742 );
12743 }
12744 })();
12745 }
12746 var suspenseInstance = fiber.stateNode;
12747 (function() {
12748 if (!suspenseInstance) {
12749 throw ReactError(
12750 Error(
12751 "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue."
12752 )
12753 );
12754 }
12755 })();
12756 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(
12757 suspenseInstance
12758 );
12759}
12760
12761function popToNextHostParent(fiber) {
12762 var parent = fiber.return;
12763 while (
12764 parent !== null &&
12765 parent.tag !== HostComponent &&
12766 parent.tag !== HostRoot &&
12767 parent.tag !== DehydratedSuspenseComponent
12768 ) {
12769 parent = parent.return;
12770 }
12771 hydrationParentFiber = parent;
12772}
12773
12774function popHydrationState(fiber) {
12775 if (!supportsHydration) {
12776 return false;
12777 }
12778 if (fiber !== hydrationParentFiber) {
12779 // We're deeper than the current hydration context, inside an inserted
12780 // tree.
12781 return false;
12782 }
12783 if (!isHydrating) {
12784 // If we're not currently hydrating but we're in a hydration context, then
12785 // we were an insertion and now need to pop up reenter hydration of our
12786 // siblings.
12787 popToNextHostParent(fiber);
12788 isHydrating = true;
12789 return false;
12790 }
12791
12792 var type = fiber.type;
12793
12794 // If we have any remaining hydratable nodes, we need to delete them now.
12795 // We only do this deeper than head and body since they tend to have random
12796 // other nodes in them. We also ignore components with pure text content in
12797 // side of them.
12798 // TODO: Better heuristic.
12799 if (
12800 fiber.tag !== HostComponent ||
12801 (type !== "head" &&
12802 type !== "body" &&
12803 !shouldSetTextContent(type, fiber.memoizedProps))
12804 ) {
12805 var nextInstance = nextHydratableInstance;
12806 while (nextInstance) {
12807 deleteHydratableInstance(fiber, nextInstance);
12808 nextInstance = getNextHydratableSibling(nextInstance);
12809 }
12810 }
12811
12812 popToNextHostParent(fiber);
12813 nextHydratableInstance = hydrationParentFiber
12814 ? getNextHydratableSibling(fiber.stateNode)
12815 : null;
12816 return true;
12817}
12818
12819function resetHydrationState() {
12820 if (!supportsHydration) {
12821 return;
12822 }
12823
12824 hydrationParentFiber = null;
12825 nextHydratableInstance = null;
12826 isHydrating = false;
12827}
12828
12829var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
12830
12831var didReceiveUpdate = false;
12832
12833var didWarnAboutBadClass = void 0;
12834var didWarnAboutModulePatternComponent = void 0;
12835var didWarnAboutContextTypeOnFunctionComponent = void 0;
12836var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
12837var didWarnAboutFunctionRefs = void 0;
12838var didWarnAboutReassigningProps = void 0;
12839var didWarnAboutMaxDuration = void 0;
12840var didWarnAboutRevealOrder = void 0;
12841var didWarnAboutTailOptions = void 0;
12842var didWarnAboutDefaultPropsOnFunctionComponent = void 0;
12843
12844{
12845 didWarnAboutBadClass = {};
12846 didWarnAboutModulePatternComponent = {};
12847 didWarnAboutContextTypeOnFunctionComponent = {};
12848 didWarnAboutGetDerivedStateOnFunctionComponent = {};
12849 didWarnAboutFunctionRefs = {};
12850 didWarnAboutReassigningProps = false;
12851 didWarnAboutMaxDuration = false;
12852 didWarnAboutRevealOrder = {};
12853 didWarnAboutTailOptions = {};
12854 didWarnAboutDefaultPropsOnFunctionComponent = {};
12855}
12856
12857function reconcileChildren(
12858 current$$1,
12859 workInProgress,
12860 nextChildren,
12861 renderExpirationTime
12862) {
12863 if (current$$1 === null) {
12864 // If this is a fresh new component that hasn't been rendered yet, we
12865 // won't update its child set by applying minimal side-effects. Instead,
12866 // we will add them all to the child before it gets rendered. That means
12867 // we can optimize this reconciliation pass by not tracking side-effects.
12868 workInProgress.child = mountChildFibers(
12869 workInProgress,
12870 null,
12871 nextChildren,
12872 renderExpirationTime
12873 );
12874 } else {
12875 // If the current child is the same as the work in progress, it means that
12876 // we haven't yet started any work on these children. Therefore, we use
12877 // the clone algorithm to create a copy of all the current children.
12878
12879 // If we had any progressed work already, that is invalid at this point so
12880 // let's throw it out.
12881 workInProgress.child = reconcileChildFibers(
12882 workInProgress,
12883 current$$1.child,
12884 nextChildren,
12885 renderExpirationTime
12886 );
12887 }
12888}
12889
12890function forceUnmountCurrentAndReconcile(
12891 current$$1,
12892 workInProgress,
12893 nextChildren,
12894 renderExpirationTime
12895) {
12896 // This function is fork of reconcileChildren. It's used in cases where we
12897 // want to reconcile without matching against the existing set. This has the
12898 // effect of all current children being unmounted; even if the type and key
12899 // are the same, the old child is unmounted and a new child is created.
12900 //
12901 // To do this, we're going to go through the reconcile algorithm twice. In
12902 // the first pass, we schedule a deletion for all the current children by
12903 // passing null.
12904 workInProgress.child = reconcileChildFibers(
12905 workInProgress,
12906 current$$1.child,
12907 null,
12908 renderExpirationTime
12909 );
12910 // In the second pass, we mount the new children. The trick here is that we
12911 // pass null in place of where we usually pass the current child set. This has
12912 // the effect of remounting all children regardless of whether their their
12913 // identity matches.
12914 workInProgress.child = reconcileChildFibers(
12915 workInProgress,
12916 null,
12917 nextChildren,
12918 renderExpirationTime
12919 );
12920}
12921
12922function updateForwardRef(
12923 current$$1,
12924 workInProgress,
12925 Component,
12926 nextProps,
12927 renderExpirationTime
12928) {
12929 // TODO: current can be non-null here even if the component
12930 // hasn't yet mounted. This happens after the first render suspends.
12931 // We'll need to figure out if this is fine or can cause issues.
12932
12933 {
12934 if (workInProgress.type !== workInProgress.elementType) {
12935 // Lazy component props can't be validated in createElement
12936 // because they're only guaranteed to be resolved here.
12937 var innerPropTypes = Component.propTypes;
12938 if (innerPropTypes) {
12939 checkPropTypes(
12940 innerPropTypes,
12941 nextProps, // Resolved props
12942 "prop",
12943 getComponentName(Component),
12944 getCurrentFiberStackInDev
12945 );
12946 }
12947 }
12948 }
12949
12950 var render = Component.render;
12951 var ref = workInProgress.ref;
12952
12953 // The rest is a fork of updateFunctionComponent
12954 var nextChildren = void 0;
12955 prepareToReadContext(workInProgress, renderExpirationTime);
12956 {
12957 ReactCurrentOwner$3.current = workInProgress;
12958 setCurrentPhase("render");
12959 nextChildren = renderWithHooks(
12960 current$$1,
12961 workInProgress,
12962 render,
12963 nextProps,
12964 ref,
12965 renderExpirationTime
12966 );
12967 if (
12968 debugRenderPhaseSideEffects ||
12969 (debugRenderPhaseSideEffectsForStrictMode &&
12970 workInProgress.mode & StrictMode)
12971 ) {
12972 // Only double-render components with Hooks
12973 if (workInProgress.memoizedState !== null) {
12974 nextChildren = renderWithHooks(
12975 current$$1,
12976 workInProgress,
12977 render,
12978 nextProps,
12979 ref,
12980 renderExpirationTime
12981 );
12982 }
12983 }
12984 setCurrentPhase(null);
12985 }
12986
12987 if (current$$1 !== null && !didReceiveUpdate) {
12988 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
12989 return bailoutOnAlreadyFinishedWork(
12990 current$$1,
12991 workInProgress,
12992 renderExpirationTime
12993 );
12994 }
12995
12996 // React DevTools reads this flag.
12997 workInProgress.effectTag |= PerformedWork;
12998 reconcileChildren(
12999 current$$1,
13000 workInProgress,
13001 nextChildren,
13002 renderExpirationTime
13003 );
13004 return workInProgress.child;
13005}
13006
13007function updateMemoComponent(
13008 current$$1,
13009 workInProgress,
13010 Component,
13011 nextProps,
13012 updateExpirationTime,
13013 renderExpirationTime
13014) {
13015 if (current$$1 === null) {
13016 var type = Component.type;
13017 if (
13018 isSimpleFunctionComponent(type) &&
13019 Component.compare === null &&
13020 // SimpleMemoComponent codepath doesn't resolve outer props either.
13021 Component.defaultProps === undefined
13022 ) {
13023 var resolvedType = type;
13024 {
13025 resolvedType = resolveFunctionForHotReloading(type);
13026 }
13027 // If this is a plain function component without default props,
13028 // and with only the default shallow comparison, we upgrade it
13029 // to a SimpleMemoComponent to allow fast path updates.
13030 workInProgress.tag = SimpleMemoComponent;
13031 workInProgress.type = resolvedType;
13032 {
13033 validateFunctionComponentInDev(workInProgress, type);
13034 }
13035 return updateSimpleMemoComponent(
13036 current$$1,
13037 workInProgress,
13038 resolvedType,
13039 nextProps,
13040 updateExpirationTime,
13041 renderExpirationTime
13042 );
13043 }
13044 {
13045 var innerPropTypes = type.propTypes;
13046 if (innerPropTypes) {
13047 // Inner memo component props aren't currently validated in createElement.
13048 // We could move it there, but we'd still need this for lazy code path.
13049 checkPropTypes(
13050 innerPropTypes,
13051 nextProps, // Resolved props
13052 "prop",
13053 getComponentName(type),
13054 getCurrentFiberStackInDev
13055 );
13056 }
13057 }
13058 var child = createFiberFromTypeAndProps(
13059 Component.type,
13060 null,
13061 nextProps,
13062 null,
13063 workInProgress.mode,
13064 renderExpirationTime
13065 );
13066 child.ref = workInProgress.ref;
13067 child.return = workInProgress;
13068 workInProgress.child = child;
13069 return child;
13070 }
13071 {
13072 var _type = Component.type;
13073 var _innerPropTypes = _type.propTypes;
13074 if (_innerPropTypes) {
13075 // Inner memo component props aren't currently validated in createElement.
13076 // We could move it there, but we'd still need this for lazy code path.
13077 checkPropTypes(
13078 _innerPropTypes,
13079 nextProps, // Resolved props
13080 "prop",
13081 getComponentName(_type),
13082 getCurrentFiberStackInDev
13083 );
13084 }
13085 }
13086 var currentChild = current$$1.child; // This is always exactly one child
13087 if (updateExpirationTime < renderExpirationTime) {
13088 // This will be the props with resolved defaultProps,
13089 // unlike current.memoizedProps which will be the unresolved ones.
13090 var prevProps = currentChild.memoizedProps;
13091 // Default to shallow comparison
13092 var compare = Component.compare;
13093 compare = compare !== null ? compare : shallowEqual;
13094 if (
13095 compare(prevProps, nextProps) &&
13096 current$$1.ref === workInProgress.ref
13097 ) {
13098 return bailoutOnAlreadyFinishedWork(
13099 current$$1,
13100 workInProgress,
13101 renderExpirationTime
13102 );
13103 }
13104 }
13105 // React DevTools reads this flag.
13106 workInProgress.effectTag |= PerformedWork;
13107 var newChild = createWorkInProgress(
13108 currentChild,
13109 nextProps,
13110 renderExpirationTime
13111 );
13112 newChild.ref = workInProgress.ref;
13113 newChild.return = workInProgress;
13114 workInProgress.child = newChild;
13115 return newChild;
13116}
13117
13118function updateSimpleMemoComponent(
13119 current$$1,
13120 workInProgress,
13121 Component,
13122 nextProps,
13123 updateExpirationTime,
13124 renderExpirationTime
13125) {
13126 // TODO: current can be non-null here even if the component
13127 // hasn't yet mounted. This happens when the inner render suspends.
13128 // We'll need to figure out if this is fine or can cause issues.
13129
13130 {
13131 if (workInProgress.type !== workInProgress.elementType) {
13132 // Lazy component props can't be validated in createElement
13133 // because they're only guaranteed to be resolved here.
13134 var outerMemoType = workInProgress.elementType;
13135 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
13136 // We warn when you define propTypes on lazy()
13137 // so let's just skip over it to find memo() outer wrapper.
13138 // Inner props for memo are validated later.
13139 outerMemoType = refineResolvedLazyComponent(outerMemoType);
13140 }
13141 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
13142 if (outerPropTypes) {
13143 checkPropTypes(
13144 outerPropTypes,
13145 nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
13146 "prop",
13147 getComponentName(outerMemoType),
13148 getCurrentFiberStackInDev
13149 );
13150 }
13151 // Inner propTypes will be validated in the function component path.
13152 }
13153 }
13154 if (current$$1 !== null) {
13155 var prevProps = current$$1.memoizedProps;
13156 if (
13157 shallowEqual(prevProps, nextProps) &&
13158 current$$1.ref === workInProgress.ref &&
13159 // Prevent bailout if the implementation changed due to hot reload:
13160 workInProgress.type === current$$1.type
13161 ) {
13162 didReceiveUpdate = false;
13163 if (updateExpirationTime < renderExpirationTime) {
13164 return bailoutOnAlreadyFinishedWork(
13165 current$$1,
13166 workInProgress,
13167 renderExpirationTime
13168 );
13169 }
13170 }
13171 }
13172 return updateFunctionComponent(
13173 current$$1,
13174 workInProgress,
13175 Component,
13176 nextProps,
13177 renderExpirationTime
13178 );
13179}
13180
13181function updateFragment(current$$1, workInProgress, renderExpirationTime) {
13182 var nextChildren = workInProgress.pendingProps;
13183 reconcileChildren(
13184 current$$1,
13185 workInProgress,
13186 nextChildren,
13187 renderExpirationTime
13188 );
13189 return workInProgress.child;
13190}
13191
13192function updateMode(current$$1, workInProgress, renderExpirationTime) {
13193 var nextChildren = workInProgress.pendingProps.children;
13194 reconcileChildren(
13195 current$$1,
13196 workInProgress,
13197 nextChildren,
13198 renderExpirationTime
13199 );
13200 return workInProgress.child;
13201}
13202
13203function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
13204 if (enableProfilerTimer) {
13205 workInProgress.effectTag |= Update;
13206 }
13207 var nextProps = workInProgress.pendingProps;
13208 var nextChildren = nextProps.children;
13209 reconcileChildren(
13210 current$$1,
13211 workInProgress,
13212 nextChildren,
13213 renderExpirationTime
13214 );
13215 return workInProgress.child;
13216}
13217
13218function markRef(current$$1, workInProgress) {
13219 var ref = workInProgress.ref;
13220 if (
13221 (current$$1 === null && ref !== null) ||
13222 (current$$1 !== null && current$$1.ref !== ref)
13223 ) {
13224 // Schedule a Ref effect
13225 workInProgress.effectTag |= Ref;
13226 }
13227}
13228
13229function updateFunctionComponent(
13230 current$$1,
13231 workInProgress,
13232 Component,
13233 nextProps,
13234 renderExpirationTime
13235) {
13236 {
13237 if (workInProgress.type !== workInProgress.elementType) {
13238 // Lazy component props can't be validated in createElement
13239 // because they're only guaranteed to be resolved here.
13240 var innerPropTypes = Component.propTypes;
13241 if (innerPropTypes) {
13242 checkPropTypes(
13243 innerPropTypes,
13244 nextProps, // Resolved props
13245 "prop",
13246 getComponentName(Component),
13247 getCurrentFiberStackInDev
13248 );
13249 }
13250 }
13251 }
13252
13253 var context = void 0;
13254 if (!disableLegacyContext) {
13255 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
13256 context = getMaskedContext(workInProgress, unmaskedContext);
13257 }
13258
13259 var nextChildren = void 0;
13260 prepareToReadContext(workInProgress, renderExpirationTime);
13261 {
13262 ReactCurrentOwner$3.current = workInProgress;
13263 setCurrentPhase("render");
13264 nextChildren = renderWithHooks(
13265 current$$1,
13266 workInProgress,
13267 Component,
13268 nextProps,
13269 context,
13270 renderExpirationTime
13271 );
13272 if (
13273 debugRenderPhaseSideEffects ||
13274 (debugRenderPhaseSideEffectsForStrictMode &&
13275 workInProgress.mode & StrictMode)
13276 ) {
13277 // Only double-render components with Hooks
13278 if (workInProgress.memoizedState !== null) {
13279 nextChildren = renderWithHooks(
13280 current$$1,
13281 workInProgress,
13282 Component,
13283 nextProps,
13284 context,
13285 renderExpirationTime
13286 );
13287 }
13288 }
13289 setCurrentPhase(null);
13290 }
13291
13292 if (current$$1 !== null && !didReceiveUpdate) {
13293 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
13294 return bailoutOnAlreadyFinishedWork(
13295 current$$1,
13296 workInProgress,
13297 renderExpirationTime
13298 );
13299 }
13300
13301 // React DevTools reads this flag.
13302 workInProgress.effectTag |= PerformedWork;
13303 reconcileChildren(
13304 current$$1,
13305 workInProgress,
13306 nextChildren,
13307 renderExpirationTime
13308 );
13309 return workInProgress.child;
13310}
13311
13312function updateClassComponent(
13313 current$$1,
13314 workInProgress,
13315 Component,
13316 nextProps,
13317 renderExpirationTime
13318) {
13319 {
13320 if (workInProgress.type !== workInProgress.elementType) {
13321 // Lazy component props can't be validated in createElement
13322 // because they're only guaranteed to be resolved here.
13323 var innerPropTypes = Component.propTypes;
13324 if (innerPropTypes) {
13325 checkPropTypes(
13326 innerPropTypes,
13327 nextProps, // Resolved props
13328 "prop",
13329 getComponentName(Component),
13330 getCurrentFiberStackInDev
13331 );
13332 }
13333 }
13334 }
13335
13336 // Push context providers early to prevent context stack mismatches.
13337 // During mounting we don't know the child context yet as the instance doesn't exist.
13338 // We will invalidate the child context in finishClassComponent() right after rendering.
13339 var hasContext = void 0;
13340 if (isContextProvider(Component)) {
13341 hasContext = true;
13342 pushContextProvider(workInProgress);
13343 } else {
13344 hasContext = false;
13345 }
13346 prepareToReadContext(workInProgress, renderExpirationTime);
13347
13348 var instance = workInProgress.stateNode;
13349 var shouldUpdate = void 0;
13350 if (instance === null) {
13351 if (current$$1 !== null) {
13352 // An class component without an instance only mounts if it suspended
13353 // inside a non- concurrent tree, in an inconsistent state. We want to
13354 // tree it like a new mount, even though an empty version of it already
13355 // committed. Disconnect the alternate pointers.
13356 current$$1.alternate = null;
13357 workInProgress.alternate = null;
13358 // Since this is conceptually a new fiber, schedule a Placement effect
13359 workInProgress.effectTag |= Placement;
13360 }
13361 // In the initial pass we might need to construct the instance.
13362 constructClassInstance(
13363 workInProgress,
13364 Component,
13365 nextProps,
13366 renderExpirationTime
13367 );
13368 mountClassInstance(
13369 workInProgress,
13370 Component,
13371 nextProps,
13372 renderExpirationTime
13373 );
13374 shouldUpdate = true;
13375 } else if (current$$1 === null) {
13376 // In a resume, we'll already have an instance we can reuse.
13377 shouldUpdate = resumeMountClassInstance(
13378 workInProgress,
13379 Component,
13380 nextProps,
13381 renderExpirationTime
13382 );
13383 } else {
13384 shouldUpdate = updateClassInstance(
13385 current$$1,
13386 workInProgress,
13387 Component,
13388 nextProps,
13389 renderExpirationTime
13390 );
13391 }
13392 var nextUnitOfWork = finishClassComponent(
13393 current$$1,
13394 workInProgress,
13395 Component,
13396 shouldUpdate,
13397 hasContext,
13398 renderExpirationTime
13399 );
13400 {
13401 var inst = workInProgress.stateNode;
13402 if (inst.props !== nextProps) {
13403 !didWarnAboutReassigningProps
13404 ? warning$1(
13405 false,
13406 "It looks like %s is reassigning its own `this.props` while rendering. " +
13407 "This is not supported and can lead to confusing bugs.",
13408 getComponentName(workInProgress.type) || "a component"
13409 )
13410 : void 0;
13411 didWarnAboutReassigningProps = true;
13412 }
13413 }
13414 return nextUnitOfWork;
13415}
13416
13417function finishClassComponent(
13418 current$$1,
13419 workInProgress,
13420 Component,
13421 shouldUpdate,
13422 hasContext,
13423 renderExpirationTime
13424) {
13425 // Refs should update even if shouldComponentUpdate returns false
13426 markRef(current$$1, workInProgress);
13427
13428 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
13429
13430 if (!shouldUpdate && !didCaptureError) {
13431 // Context providers should defer to sCU for rendering
13432 if (hasContext) {
13433 invalidateContextProvider(workInProgress, Component, false);
13434 }
13435
13436 return bailoutOnAlreadyFinishedWork(
13437 current$$1,
13438 workInProgress,
13439 renderExpirationTime
13440 );
13441 }
13442
13443 var instance = workInProgress.stateNode;
13444
13445 // Rerender
13446 ReactCurrentOwner$3.current = workInProgress;
13447 var nextChildren = void 0;
13448 if (
13449 didCaptureError &&
13450 typeof Component.getDerivedStateFromError !== "function"
13451 ) {
13452 // If we captured an error, but getDerivedStateFrom catch is not defined,
13453 // unmount all the children. componentDidCatch will schedule an update to
13454 // re-render a fallback. This is temporary until we migrate everyone to
13455 // the new API.
13456 // TODO: Warn in a future release.
13457 nextChildren = null;
13458
13459 if (enableProfilerTimer) {
13460 stopProfilerTimerIfRunning(workInProgress);
13461 }
13462 } else {
13463 {
13464 setCurrentPhase("render");
13465 nextChildren = instance.render();
13466 if (
13467 debugRenderPhaseSideEffects ||
13468 (debugRenderPhaseSideEffectsForStrictMode &&
13469 workInProgress.mode & StrictMode)
13470 ) {
13471 instance.render();
13472 }
13473 setCurrentPhase(null);
13474 }
13475 }
13476
13477 // React DevTools reads this flag.
13478 workInProgress.effectTag |= PerformedWork;
13479 if (current$$1 !== null && didCaptureError) {
13480 // If we're recovering from an error, reconcile without reusing any of
13481 // the existing children. Conceptually, the normal children and the children
13482 // that are shown on error are two different sets, so we shouldn't reuse
13483 // normal children even if their identities match.
13484 forceUnmountCurrentAndReconcile(
13485 current$$1,
13486 workInProgress,
13487 nextChildren,
13488 renderExpirationTime
13489 );
13490 } else {
13491 reconcileChildren(
13492 current$$1,
13493 workInProgress,
13494 nextChildren,
13495 renderExpirationTime
13496 );
13497 }
13498
13499 // Memoize state using the values we just used to render.
13500 // TODO: Restructure so we never read values from the instance.
13501 workInProgress.memoizedState = instance.state;
13502
13503 // The context might have changed so we need to recalculate it.
13504 if (hasContext) {
13505 invalidateContextProvider(workInProgress, Component, true);
13506 }
13507
13508 return workInProgress.child;
13509}
13510
13511function pushHostRootContext(workInProgress) {
13512 var root = workInProgress.stateNode;
13513 if (root.pendingContext) {
13514 pushTopLevelContextObject(
13515 workInProgress,
13516 root.pendingContext,
13517 root.pendingContext !== root.context
13518 );
13519 } else if (root.context) {
13520 // Should always be set
13521 pushTopLevelContextObject(workInProgress, root.context, false);
13522 }
13523 pushHostContainer(workInProgress, root.containerInfo);
13524}
13525
13526function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
13527 pushHostRootContext(workInProgress);
13528 var updateQueue = workInProgress.updateQueue;
13529 (function() {
13530 if (!(updateQueue !== null)) {
13531 throw ReactError(
13532 Error(
13533 "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue."
13534 )
13535 );
13536 }
13537 })();
13538 var nextProps = workInProgress.pendingProps;
13539 var prevState = workInProgress.memoizedState;
13540 var prevChildren = prevState !== null ? prevState.element : null;
13541 processUpdateQueue(
13542 workInProgress,
13543 updateQueue,
13544 nextProps,
13545 null,
13546 renderExpirationTime
13547 );
13548 var nextState = workInProgress.memoizedState;
13549 // Caution: React DevTools currently depends on this property
13550 // being called "element".
13551 var nextChildren = nextState.element;
13552 if (nextChildren === prevChildren) {
13553 // If the state is the same as before, that's a bailout because we had
13554 // no work that expires at this time.
13555 resetHydrationState();
13556 return bailoutOnAlreadyFinishedWork(
13557 current$$1,
13558 workInProgress,
13559 renderExpirationTime
13560 );
13561 }
13562 var root = workInProgress.stateNode;
13563 if (
13564 (current$$1 === null || current$$1.child === null) &&
13565 root.hydrate &&
13566 enterHydrationState(workInProgress)
13567 ) {
13568 // If we don't have any current children this might be the first pass.
13569 // We always try to hydrate. If this isn't a hydration pass there won't
13570 // be any children to hydrate which is effectively the same thing as
13571 // not hydrating.
13572
13573 // This is a bit of a hack. We track the host root as a placement to
13574 // know that we're currently in a mounting state. That way isMounted
13575 // works as expected. We must reset this before committing.
13576 // TODO: Delete this when we delete isMounted and findDOMNode.
13577 workInProgress.effectTag |= Placement;
13578
13579 // Ensure that children mount into this root without tracking
13580 // side-effects. This ensures that we don't store Placement effects on
13581 // nodes that will be hydrated.
13582 workInProgress.child = mountChildFibers(
13583 workInProgress,
13584 null,
13585 nextChildren,
13586 renderExpirationTime
13587 );
13588 } else {
13589 // Otherwise reset hydration state in case we aborted and resumed another
13590 // root.
13591 reconcileChildren(
13592 current$$1,
13593 workInProgress,
13594 nextChildren,
13595 renderExpirationTime
13596 );
13597 resetHydrationState();
13598 }
13599 return workInProgress.child;
13600}
13601
13602function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
13603 pushHostContext(workInProgress);
13604
13605 if (current$$1 === null) {
13606 tryToClaimNextHydratableInstance(workInProgress);
13607 }
13608
13609 var type = workInProgress.type;
13610 var nextProps = workInProgress.pendingProps;
13611 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
13612
13613 var nextChildren = nextProps.children;
13614 var isDirectTextChild = shouldSetTextContent(type, nextProps);
13615
13616 if (isDirectTextChild) {
13617 // We special case a direct text child of a host node. This is a common
13618 // case. We won't handle it as a reified child. We will instead handle
13619 // this in the host environment that also have access to this prop. That
13620 // avoids allocating another HostText fiber and traversing it.
13621 nextChildren = null;
13622 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
13623 // If we're switching from a direct text child to a normal child, or to
13624 // empty, we need to schedule the text content to be reset.
13625 workInProgress.effectTag |= ContentReset;
13626 }
13627
13628 markRef(current$$1, workInProgress);
13629
13630 // Check the host config to see if the children are offscreen/hidden.
13631 if (
13632 workInProgress.mode & ConcurrentMode &&
13633 renderExpirationTime !== Never &&
13634 shouldDeprioritizeSubtree(type, nextProps)
13635 ) {
13636 if (enableSchedulerTracing) {
13637 markSpawnedWork(Never);
13638 }
13639 // Schedule this fiber to re-render at offscreen priority. Then bailout.
13640 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
13641 return null;
13642 }
13643
13644 reconcileChildren(
13645 current$$1,
13646 workInProgress,
13647 nextChildren,
13648 renderExpirationTime
13649 );
13650 return workInProgress.child;
13651}
13652
13653function updateHostText(current$$1, workInProgress) {
13654 if (current$$1 === null) {
13655 tryToClaimNextHydratableInstance(workInProgress);
13656 }
13657 // Nothing to do here. This is terminal. We'll do the completion step
13658 // immediately after.
13659 return null;
13660}
13661
13662function mountLazyComponent(
13663 _current,
13664 workInProgress,
13665 elementType,
13666 updateExpirationTime,
13667 renderExpirationTime
13668) {
13669 if (_current !== null) {
13670 // An lazy component only mounts if it suspended inside a non-
13671 // concurrent tree, in an inconsistent state. We want to treat it like
13672 // a new mount, even though an empty version of it already committed.
13673 // Disconnect the alternate pointers.
13674 _current.alternate = null;
13675 workInProgress.alternate = null;
13676 // Since this is conceptually a new fiber, schedule a Placement effect
13677 workInProgress.effectTag |= Placement;
13678 }
13679
13680 var props = workInProgress.pendingProps;
13681 // We can't start a User Timing measurement with correct label yet.
13682 // Cancel and resume right after we know the tag.
13683 cancelWorkTimer(workInProgress);
13684 var Component = readLazyComponentType(elementType);
13685 // Store the unwrapped component in the type.
13686 workInProgress.type = Component;
13687 var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component));
13688 startWorkTimer(workInProgress);
13689 var resolvedProps = resolveDefaultProps(Component, props);
13690 var child = void 0;
13691 switch (resolvedTag) {
13692 case FunctionComponent: {
13693 {
13694 validateFunctionComponentInDev(workInProgress, Component);
13695 workInProgress.type = Component = resolveFunctionForHotReloading(
13696 Component
13697 );
13698 }
13699 child = updateFunctionComponent(
13700 null,
13701 workInProgress,
13702 Component,
13703 resolvedProps,
13704 renderExpirationTime
13705 );
13706 break;
13707 }
13708 case ClassComponent: {
13709 {
13710 workInProgress.type = Component = resolveClassForHotReloading(
13711 Component
13712 );
13713 }
13714 child = updateClassComponent(
13715 null,
13716 workInProgress,
13717 Component,
13718 resolvedProps,
13719 renderExpirationTime
13720 );
13721 break;
13722 }
13723 case ForwardRef: {
13724 {
13725 workInProgress.type = Component = resolveForwardRefForHotReloading(
13726 Component
13727 );
13728 }
13729 child = updateForwardRef(
13730 null,
13731 workInProgress,
13732 Component,
13733 resolvedProps,
13734 renderExpirationTime
13735 );
13736 break;
13737 }
13738 case MemoComponent: {
13739 {
13740 if (workInProgress.type !== workInProgress.elementType) {
13741 var outerPropTypes = Component.propTypes;
13742 if (outerPropTypes) {
13743 checkPropTypes(
13744 outerPropTypes,
13745 resolvedProps, // Resolved for outer only
13746 "prop",
13747 getComponentName(Component),
13748 getCurrentFiberStackInDev
13749 );
13750 }
13751 }
13752 }
13753 child = updateMemoComponent(
13754 null,
13755 workInProgress,
13756 Component,
13757 resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
13758 updateExpirationTime,
13759 renderExpirationTime
13760 );
13761 break;
13762 }
13763 default: {
13764 var hint = "";
13765 {
13766 if (
13767 Component !== null &&
13768 typeof Component === "object" &&
13769 Component.$$typeof === REACT_LAZY_TYPE
13770 ) {
13771 hint = " Did you wrap a component in React.lazy() more than once?";
13772 }
13773 }
13774 // This message intentionally doesn't mention ForwardRef or MemoComponent
13775 // because the fact that it's a separate type of work is an
13776 // implementation detail.
13777 (function() {
13778 {
13779 throw ReactError(
13780 Error(
13781 "Element type is invalid. Received a promise that resolves to: " +
13782 Component +
13783 ". Lazy element type must resolve to a class or function." +
13784 hint
13785 )
13786 );
13787 }
13788 })();
13789 }
13790 }
13791 return child;
13792}
13793
13794function mountIncompleteClassComponent(
13795 _current,
13796 workInProgress,
13797 Component,
13798 nextProps,
13799 renderExpirationTime
13800) {
13801 if (_current !== null) {
13802 // An incomplete component only mounts if it suspended inside a non-
13803 // concurrent tree, in an inconsistent state. We want to treat it like
13804 // a new mount, even though an empty version of it already committed.
13805 // Disconnect the alternate pointers.
13806 _current.alternate = null;
13807 workInProgress.alternate = null;
13808 // Since this is conceptually a new fiber, schedule a Placement effect
13809 workInProgress.effectTag |= Placement;
13810 }
13811
13812 // Promote the fiber to a class and try rendering again.
13813 workInProgress.tag = ClassComponent;
13814
13815 // The rest of this function is a fork of `updateClassComponent`
13816
13817 // Push context providers early to prevent context stack mismatches.
13818 // During mounting we don't know the child context yet as the instance doesn't exist.
13819 // We will invalidate the child context in finishClassComponent() right after rendering.
13820 var hasContext = void 0;
13821 if (isContextProvider(Component)) {
13822 hasContext = true;
13823 pushContextProvider(workInProgress);
13824 } else {
13825 hasContext = false;
13826 }
13827 prepareToReadContext(workInProgress, renderExpirationTime);
13828
13829 constructClassInstance(
13830 workInProgress,
13831 Component,
13832 nextProps,
13833 renderExpirationTime
13834 );
13835 mountClassInstance(
13836 workInProgress,
13837 Component,
13838 nextProps,
13839 renderExpirationTime
13840 );
13841
13842 return finishClassComponent(
13843 null,
13844 workInProgress,
13845 Component,
13846 true,
13847 hasContext,
13848 renderExpirationTime
13849 );
13850}
13851
13852function mountIndeterminateComponent(
13853 _current,
13854 workInProgress,
13855 Component,
13856 renderExpirationTime
13857) {
13858 if (_current !== null) {
13859 // An indeterminate component only mounts if it suspended inside a non-
13860 // concurrent tree, in an inconsistent state. We want to treat it like
13861 // a new mount, even though an empty version of it already committed.
13862 // Disconnect the alternate pointers.
13863 _current.alternate = null;
13864 workInProgress.alternate = null;
13865 // Since this is conceptually a new fiber, schedule a Placement effect
13866 workInProgress.effectTag |= Placement;
13867 }
13868
13869 var props = workInProgress.pendingProps;
13870 var context = void 0;
13871 if (!disableLegacyContext) {
13872 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
13873 context = getMaskedContext(workInProgress, unmaskedContext);
13874 }
13875
13876 prepareToReadContext(workInProgress, renderExpirationTime);
13877 var value = void 0;
13878
13879 {
13880 if (
13881 Component.prototype &&
13882 typeof Component.prototype.render === "function"
13883 ) {
13884 var componentName = getComponentName(Component) || "Unknown";
13885
13886 if (!didWarnAboutBadClass[componentName]) {
13887 warningWithoutStack$1(
13888 false,
13889 "The <%s /> component appears to have a render method, but doesn't extend React.Component. " +
13890 "This is likely to cause errors. Change %s to extend React.Component instead.",
13891 componentName,
13892 componentName
13893 );
13894 didWarnAboutBadClass[componentName] = true;
13895 }
13896 }
13897
13898 if (workInProgress.mode & StrictMode) {
13899 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
13900 }
13901
13902 ReactCurrentOwner$3.current = workInProgress;
13903 value = renderWithHooks(
13904 null,
13905 workInProgress,
13906 Component,
13907 props,
13908 context,
13909 renderExpirationTime
13910 );
13911 }
13912 // React DevTools reads this flag.
13913 workInProgress.effectTag |= PerformedWork;
13914
13915 if (
13916 typeof value === "object" &&
13917 value !== null &&
13918 typeof value.render === "function" &&
13919 value.$$typeof === undefined
13920 ) {
13921 {
13922 var _componentName = getComponentName(Component) || "Unknown";
13923 if (!didWarnAboutModulePatternComponent[_componentName]) {
13924 warningWithoutStack$1(
13925 false,
13926 "The <%s /> component appears to be a function component that returns a class instance. " +
13927 "Change %s to a class that extends React.Component instead. " +
13928 "If you can't use a class try assigning the prototype on the function as a workaround. " +
13929 "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " +
13930 "cannot be called with `new` by React.",
13931 _componentName,
13932 _componentName,
13933 _componentName
13934 );
13935 didWarnAboutModulePatternComponent[_componentName] = true;
13936 }
13937 }
13938
13939 // Proceed under the assumption that this is a class instance
13940 workInProgress.tag = ClassComponent;
13941
13942 // Throw out any hooks that were used.
13943 resetHooks();
13944
13945 // Push context providers early to prevent context stack mismatches.
13946 // During mounting we don't know the child context yet as the instance doesn't exist.
13947 // We will invalidate the child context in finishClassComponent() right after rendering.
13948 var hasContext = false;
13949 if (isContextProvider(Component)) {
13950 hasContext = true;
13951 pushContextProvider(workInProgress);
13952 } else {
13953 hasContext = false;
13954 }
13955
13956 workInProgress.memoizedState =
13957 value.state !== null && value.state !== undefined ? value.state : null;
13958
13959 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
13960 if (typeof getDerivedStateFromProps === "function") {
13961 applyDerivedStateFromProps(
13962 workInProgress,
13963 Component,
13964 getDerivedStateFromProps,
13965 props
13966 );
13967 }
13968
13969 adoptClassInstance(workInProgress, value);
13970 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
13971 return finishClassComponent(
13972 null,
13973 workInProgress,
13974 Component,
13975 true,
13976 hasContext,
13977 renderExpirationTime
13978 );
13979 } else {
13980 // Proceed under the assumption that this is a function component
13981 workInProgress.tag = FunctionComponent;
13982 {
13983 if (disableLegacyContext && Component.contextTypes) {
13984 warningWithoutStack$1(
13985 false,
13986 "%s uses the legacy contextTypes API which is no longer supported. " +
13987 "Use React.createContext() with React.useContext() instead.",
13988 getComponentName(Component) || "Unknown"
13989 );
13990 }
13991
13992 if (
13993 debugRenderPhaseSideEffects ||
13994 (debugRenderPhaseSideEffectsForStrictMode &&
13995 workInProgress.mode & StrictMode)
13996 ) {
13997 // Only double-render components with Hooks
13998 if (workInProgress.memoizedState !== null) {
13999 value = renderWithHooks(
14000 null,
14001 workInProgress,
14002 Component,
14003 props,
14004 context,
14005 renderExpirationTime
14006 );
14007 }
14008 }
14009 }
14010 reconcileChildren(null, workInProgress, value, renderExpirationTime);
14011 {
14012 validateFunctionComponentInDev(workInProgress, Component);
14013 }
14014 return workInProgress.child;
14015 }
14016}
14017
14018function validateFunctionComponentInDev(workInProgress, Component) {
14019 if (Component) {
14020 !!Component.childContextTypes
14021 ? warningWithoutStack$1(
14022 false,
14023 "%s(...): childContextTypes cannot be defined on a function component.",
14024 Component.displayName || Component.name || "Component"
14025 )
14026 : void 0;
14027 }
14028 if (workInProgress.ref !== null) {
14029 var info = "";
14030 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
14031 if (ownerName) {
14032 info += "\n\nCheck the render method of `" + ownerName + "`.";
14033 }
14034
14035 var warningKey = ownerName || workInProgress._debugID || "";
14036 var debugSource = workInProgress._debugSource;
14037 if (debugSource) {
14038 warningKey = debugSource.fileName + ":" + debugSource.lineNumber;
14039 }
14040 if (!didWarnAboutFunctionRefs[warningKey]) {
14041 didWarnAboutFunctionRefs[warningKey] = true;
14042 warning$1(
14043 false,
14044 "Function components cannot be given refs. " +
14045 "Attempts to access this ref will fail. " +
14046 "Did you mean to use React.forwardRef()?%s",
14047 info
14048 );
14049 }
14050 }
14051
14052 if (
14053 warnAboutDefaultPropsOnFunctionComponents &&
14054 Component.defaultProps !== undefined
14055 ) {
14056 var componentName = getComponentName(Component) || "Unknown";
14057
14058 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
14059 warningWithoutStack$1(
14060 false,
14061 "%s: Support for defaultProps will be removed from function components " +
14062 "in a future major release. Use JavaScript default parameters instead.",
14063 componentName
14064 );
14065 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
14066 }
14067 }
14068
14069 if (typeof Component.getDerivedStateFromProps === "function") {
14070 var _componentName2 = getComponentName(Component) || "Unknown";
14071
14072 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
14073 warningWithoutStack$1(
14074 false,
14075 "%s: Function components do not support getDerivedStateFromProps.",
14076 _componentName2
14077 );
14078 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
14079 }
14080 }
14081
14082 if (
14083 typeof Component.contextType === "object" &&
14084 Component.contextType !== null
14085 ) {
14086 var _componentName3 = getComponentName(Component) || "Unknown";
14087
14088 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
14089 warningWithoutStack$1(
14090 false,
14091 "%s: Function components do not support contextType.",
14092 _componentName3
14093 );
14094 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
14095 }
14096 }
14097}
14098
14099// TODO: This is now an empty object. Should we just make it a boolean?
14100var SUSPENDED_MARKER = {};
14101
14102function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) {
14103 // If the context is telling us that we should show a fallback, and we're not
14104 // already showing content, then we should show the fallback instead.
14105 return (
14106 hasSuspenseContext(suspenseContext, ForceSuspenseFallback) &&
14107 (current$$1 === null || current$$1.memoizedState !== null)
14108 );
14109}
14110
14111function updateSuspenseComponent(
14112 current$$1,
14113 workInProgress,
14114 renderExpirationTime
14115) {
14116 var mode = workInProgress.mode;
14117 var nextProps = workInProgress.pendingProps;
14118
14119 // This is used by DevTools to force a boundary to suspend.
14120 {
14121 if (shouldSuspend(workInProgress)) {
14122 workInProgress.effectTag |= DidCapture;
14123 }
14124 }
14125
14126 var suspenseContext = suspenseStackCursor.current;
14127
14128 var nextState = null;
14129 var nextDidTimeout = false;
14130
14131 if (
14132 (workInProgress.effectTag & DidCapture) !== NoEffect ||
14133 shouldRemainOnFallback(suspenseContext, current$$1, workInProgress)
14134 ) {
14135 // Something in this boundary's subtree already suspended. Switch to
14136 // rendering the fallback children.
14137 nextState = SUSPENDED_MARKER;
14138 nextDidTimeout = true;
14139 workInProgress.effectTag &= ~DidCapture;
14140 } else {
14141 // Attempting the main content
14142 if (current$$1 === null || current$$1.memoizedState !== null) {
14143 // This is a new mount or this boundary is already showing a fallback state.
14144 // Mark this subtree context as having at least one invisible parent that could
14145 // handle the fallback state.
14146 // Boundaries without fallbacks or should be avoided are not considered since
14147 // they cannot handle preferred fallback states.
14148 if (
14149 nextProps.fallback !== undefined &&
14150 nextProps.unstable_avoidThisFallback !== true
14151 ) {
14152 suspenseContext = addSubtreeSuspenseContext(
14153 suspenseContext,
14154 InvisibleParentSuspenseContext
14155 );
14156 }
14157 }
14158 }
14159
14160 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
14161
14162 pushSuspenseContext(workInProgress, suspenseContext);
14163
14164 {
14165 if ("maxDuration" in nextProps) {
14166 if (!didWarnAboutMaxDuration) {
14167 didWarnAboutMaxDuration = true;
14168 warning$1(
14169 false,
14170 "maxDuration has been removed from React. " +
14171 "Remove the maxDuration prop."
14172 );
14173 }
14174 }
14175 }
14176
14177 // This next part is a bit confusing. If the children timeout, we switch to
14178 // showing the fallback children in place of the "primary" children.
14179 // However, we don't want to delete the primary children because then their
14180 // state will be lost (both the React state and the host state, e.g.
14181 // uncontrolled form inputs). Instead we keep them mounted and hide them.
14182 // Both the fallback children AND the primary children are rendered at the
14183 // same time. Once the primary children are un-suspended, we can delete
14184 // the fallback children — don't need to preserve their state.
14185 //
14186 // The two sets of children are siblings in the host environment, but
14187 // semantically, for purposes of reconciliation, they are two separate sets.
14188 // So we store them using two fragment fibers.
14189 //
14190 // However, we want to avoid allocating extra fibers for every placeholder.
14191 // They're only necessary when the children time out, because that's the
14192 // only time when both sets are mounted.
14193 //
14194 // So, the extra fragment fibers are only used if the children time out.
14195 // Otherwise, we render the primary children directly. This requires some
14196 // custom reconciliation logic to preserve the state of the primary
14197 // children. It's essentially a very basic form of re-parenting.
14198
14199 // `child` points to the child fiber. In the normal case, this is the first
14200 // fiber of the primary children set. In the timed-out case, it's a
14201 // a fragment fiber containing the primary children.
14202 var child = void 0;
14203 // `next` points to the next fiber React should render. In the normal case,
14204 // it's the same as `child`: the first fiber of the primary children set.
14205 // In the timed-out case, it's a fragment fiber containing the *fallback*
14206 // children -- we skip over the primary children entirely.
14207 var next = void 0;
14208 if (current$$1 === null) {
14209 if (enableSuspenseServerRenderer) {
14210 // If we're currently hydrating, try to hydrate this boundary.
14211 // But only if this has a fallback.
14212 if (nextProps.fallback !== undefined) {
14213 tryToClaimNextHydratableInstance(workInProgress);
14214 // This could've changed the tag if this was a dehydrated suspense component.
14215 if (workInProgress.tag === DehydratedSuspenseComponent) {
14216 popSuspenseContext(workInProgress);
14217 return updateDehydratedSuspenseComponent(
14218 null,
14219 workInProgress,
14220 renderExpirationTime
14221 );
14222 }
14223 }
14224 }
14225
14226 // This is the initial mount. This branch is pretty simple because there's
14227 // no previous state that needs to be preserved.
14228 if (nextDidTimeout) {
14229 // Mount separate fragments for primary and fallback children.
14230 var nextFallbackChildren = nextProps.fallback;
14231 var primaryChildFragment = createFiberFromFragment(
14232 null,
14233 mode,
14234 NoWork,
14235 null
14236 );
14237 primaryChildFragment.return = workInProgress;
14238
14239 if ((workInProgress.mode & BatchedMode) === NoMode) {
14240 // Outside of batched mode, we commit the effects from the
14241 var progressedState = workInProgress.memoizedState;
14242 var progressedPrimaryChild =
14243 progressedState !== null
14244 ? workInProgress.child.child
14245 : workInProgress.child;
14246 primaryChildFragment.child = progressedPrimaryChild;
14247 var progressedChild = progressedPrimaryChild;
14248 while (progressedChild !== null) {
14249 progressedChild.return = primaryChildFragment;
14250 progressedChild = progressedChild.sibling;
14251 }
14252 }
14253
14254 var fallbackChildFragment = createFiberFromFragment(
14255 nextFallbackChildren,
14256 mode,
14257 renderExpirationTime,
14258 null
14259 );
14260 fallbackChildFragment.return = workInProgress;
14261 primaryChildFragment.sibling = fallbackChildFragment;
14262 child = primaryChildFragment;
14263 // Skip the primary children, and continue working on the
14264 // fallback children.
14265 next = fallbackChildFragment;
14266 } else {
14267 // Mount the primary children without an intermediate fragment fiber.
14268 var nextPrimaryChildren = nextProps.children;
14269 child = next = mountChildFibers(
14270 workInProgress,
14271 null,
14272 nextPrimaryChildren,
14273 renderExpirationTime
14274 );
14275 }
14276 } else {
14277 // This is an update. This branch is more complicated because we need to
14278 // ensure the state of the primary children is preserved.
14279 var prevState = current$$1.memoizedState;
14280 var prevDidTimeout = prevState !== null;
14281 if (prevDidTimeout) {
14282 // The current tree already timed out. That means each child set is
14283 var currentPrimaryChildFragment = current$$1.child;
14284 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
14285 if (nextDidTimeout) {
14286 // Still timed out. Reuse the current primary children by cloning
14287 // its fragment. We're going to skip over these entirely.
14288 var _nextFallbackChildren = nextProps.fallback;
14289 var _primaryChildFragment = createWorkInProgress(
14290 currentPrimaryChildFragment,
14291 currentPrimaryChildFragment.pendingProps,
14292 NoWork
14293 );
14294 _primaryChildFragment.return = workInProgress;
14295
14296 if ((workInProgress.mode & BatchedMode) === NoMode) {
14297 // Outside of batched mode, we commit the effects from the
14298 var _progressedState = workInProgress.memoizedState;
14299 var _progressedPrimaryChild =
14300 _progressedState !== null
14301 ? workInProgress.child.child
14302 : workInProgress.child;
14303 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
14304 _primaryChildFragment.child = _progressedPrimaryChild;
14305 var _progressedChild = _progressedPrimaryChild;
14306 while (_progressedChild !== null) {
14307 _progressedChild.return = _primaryChildFragment;
14308 _progressedChild = _progressedChild.sibling;
14309 }
14310 }
14311 }
14312
14313 // Because primaryChildFragment is a new fiber that we're inserting as the
14314 // parent of a new tree, we need to set its treeBaseDuration.
14315 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
14316 // treeBaseDuration is the sum of all the child tree base durations.
14317 var treeBaseDuration = 0;
14318 var hiddenChild = _primaryChildFragment.child;
14319 while (hiddenChild !== null) {
14320 treeBaseDuration += hiddenChild.treeBaseDuration;
14321 hiddenChild = hiddenChild.sibling;
14322 }
14323 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
14324 }
14325
14326 // Clone the fallback child fragment, too. These we'll continue
14327 // working on.
14328 var _fallbackChildFragment = createWorkInProgress(
14329 currentFallbackChildFragment,
14330 _nextFallbackChildren,
14331 currentFallbackChildFragment.expirationTime
14332 );
14333 _fallbackChildFragment.return = workInProgress;
14334 _primaryChildFragment.sibling = _fallbackChildFragment;
14335 child = _primaryChildFragment;
14336 _primaryChildFragment.childExpirationTime = NoWork;
14337 // Skip the primary children, and continue working on the
14338 // fallback children.
14339 next = _fallbackChildFragment;
14340 } else {
14341 // No longer suspended. Switch back to showing the primary children,
14342 // and remove the intermediate fragment fiber.
14343 var _nextPrimaryChildren = nextProps.children;
14344 var currentPrimaryChild = currentPrimaryChildFragment.child;
14345 var primaryChild = reconcileChildFibers(
14346 workInProgress,
14347 currentPrimaryChild,
14348 _nextPrimaryChildren,
14349 renderExpirationTime
14350 );
14351
14352 // If this render doesn't suspend, we need to delete the fallback
14353 // children. Wait until the complete phase, after we've confirmed the
14354 // fallback is no longer needed.
14355 // TODO: Would it be better to store the fallback fragment on
14356 // the stateNode?
14357
14358 // Continue rendering the children, like we normally do.
14359 child = next = primaryChild;
14360 }
14361 } else {
14362 // The current tree has not already timed out. That means the primary
14363 // children are not wrapped in a fragment fiber.
14364 var _currentPrimaryChild = current$$1.child;
14365 if (nextDidTimeout) {
14366 // Timed out. Wrap the children in a fragment fiber to keep them
14367 // separate from the fallback children.
14368 var _nextFallbackChildren2 = nextProps.fallback;
14369 var _primaryChildFragment2 = createFiberFromFragment(
14370 // It shouldn't matter what the pending props are because we aren't
14371 // going to render this fragment.
14372 null,
14373 mode,
14374 NoWork,
14375 null
14376 );
14377 _primaryChildFragment2.return = workInProgress;
14378 _primaryChildFragment2.child = _currentPrimaryChild;
14379 if (_currentPrimaryChild !== null) {
14380 _currentPrimaryChild.return = _primaryChildFragment2;
14381 }
14382
14383 // Even though we're creating a new fiber, there are no new children,
14384 // because we're reusing an already mounted tree. So we don't need to
14385 // schedule a placement.
14386 // primaryChildFragment.effectTag |= Placement;
14387
14388 if ((workInProgress.mode & BatchedMode) === NoMode) {
14389 // Outside of batched mode, we commit the effects from the
14390 var _progressedState2 = workInProgress.memoizedState;
14391 var _progressedPrimaryChild2 =
14392 _progressedState2 !== null
14393 ? workInProgress.child.child
14394 : workInProgress.child;
14395 _primaryChildFragment2.child = _progressedPrimaryChild2;
14396 var _progressedChild2 = _progressedPrimaryChild2;
14397 while (_progressedChild2 !== null) {
14398 _progressedChild2.return = _primaryChildFragment2;
14399 _progressedChild2 = _progressedChild2.sibling;
14400 }
14401 }
14402
14403 // Because primaryChildFragment is a new fiber that we're inserting as the
14404 // parent of a new tree, we need to set its treeBaseDuration.
14405 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
14406 // treeBaseDuration is the sum of all the child tree base durations.
14407 var _treeBaseDuration = 0;
14408 var _hiddenChild = _primaryChildFragment2.child;
14409 while (_hiddenChild !== null) {
14410 _treeBaseDuration += _hiddenChild.treeBaseDuration;
14411 _hiddenChild = _hiddenChild.sibling;
14412 }
14413 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
14414 }
14415
14416 // Create a fragment from the fallback children, too.
14417 var _fallbackChildFragment2 = createFiberFromFragment(
14418 _nextFallbackChildren2,
14419 mode,
14420 renderExpirationTime,
14421 null
14422 );
14423 _fallbackChildFragment2.return = workInProgress;
14424 _primaryChildFragment2.sibling = _fallbackChildFragment2;
14425 _fallbackChildFragment2.effectTag |= Placement;
14426 child = _primaryChildFragment2;
14427 _primaryChildFragment2.childExpirationTime = NoWork;
14428 // Skip the primary children, and continue working on the
14429 // fallback children.
14430 next = _fallbackChildFragment2;
14431 } else {
14432 // Still haven't timed out. Continue rendering the children, like we
14433 // normally do.
14434 var _nextPrimaryChildren2 = nextProps.children;
14435 next = child = reconcileChildFibers(
14436 workInProgress,
14437 _currentPrimaryChild,
14438 _nextPrimaryChildren2,
14439 renderExpirationTime
14440 );
14441 }
14442 }
14443 workInProgress.stateNode = current$$1.stateNode;
14444 }
14445
14446 workInProgress.memoizedState = nextState;
14447 workInProgress.child = child;
14448 return next;
14449}
14450
14451function retrySuspenseComponentWithoutHydrating(
14452 current$$1,
14453 workInProgress,
14454 renderExpirationTime
14455) {
14456 // Detach from the current dehydrated boundary.
14457 current$$1.alternate = null;
14458 workInProgress.alternate = null;
14459
14460 // Insert a deletion in the effect list.
14461 var returnFiber = workInProgress.return;
14462 (function() {
14463 if (!(returnFiber !== null)) {
14464 throw ReactError(
14465 Error(
14466 "Suspense boundaries are never on the root. This is probably a bug in React."
14467 )
14468 );
14469 }
14470 })();
14471 var last = returnFiber.lastEffect;
14472 if (last !== null) {
14473 last.nextEffect = current$$1;
14474 returnFiber.lastEffect = current$$1;
14475 } else {
14476 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
14477 }
14478 current$$1.nextEffect = null;
14479 current$$1.effectTag = Deletion;
14480
14481 popSuspenseContext(workInProgress);
14482
14483 // Upgrade this work in progress to a real Suspense component.
14484 workInProgress.tag = SuspenseComponent;
14485 workInProgress.stateNode = null;
14486 workInProgress.memoizedState = null;
14487 // This is now an insertion.
14488 workInProgress.effectTag |= Placement;
14489 // Retry as a real Suspense component.
14490 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
14491}
14492
14493function updateDehydratedSuspenseComponent(
14494 current$$1,
14495 workInProgress,
14496 renderExpirationTime
14497) {
14498 pushSuspenseContext(
14499 workInProgress,
14500 setDefaultShallowSuspenseContext(suspenseStackCursor.current)
14501 );
14502 var suspenseInstance = workInProgress.stateNode;
14503 if (current$$1 === null) {
14504 // During the first pass, we'll bail out and not drill into the children.
14505 // Instead, we'll leave the content in place and try to hydrate it later.
14506 if (isSuspenseInstanceFallback(suspenseInstance)) {
14507 // This is a client-only boundary. Since we won't get any content from the server
14508 // for this, we need to schedule that at a higher priority based on when it would
14509 // have timed out. In theory we could render it in this pass but it would have the
14510 // wrong priority associated with it and will prevent hydration of parent path.
14511 // Instead, we'll leave work left on it to render it in a separate commit.
14512
14513 // TODO This time should be the time at which the server rendered response that is
14514 // a parent to this boundary was displayed. However, since we currently don't have
14515 // a protocol to transfer that time, we'll just estimate it by using the current
14516 // time. This will mean that Suspense timeouts are slightly shifted to later than
14517 // they should be.
14518 var serverDisplayTime = requestCurrentTime();
14519 // Schedule a normal pri update to render this content.
14520 workInProgress.expirationTime = computeAsyncExpiration(serverDisplayTime);
14521 } else {
14522 // We'll continue hydrating the rest at offscreen priority since we'll already
14523 // be showing the right content coming from the server, it is no rush.
14524 workInProgress.expirationTime = Never;
14525 }
14526 return null;
14527 }
14528
14529 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
14530 // Something suspended. Leave the existing children in place.
14531 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
14532 workInProgress.child = null;
14533 return null;
14534 }
14535
14536 // We should never be hydrating at this point because it is the first pass,
14537 // but after we've already committed once.
14538 warnIfHydrating();
14539
14540 if (isSuspenseInstanceFallback(suspenseInstance)) {
14541 // This boundary is in a permanent fallback state. In this case, we'll never
14542 // get an update and we'll never be able to hydrate the final content. Let's just try the
14543 // client side render instead.
14544 return retrySuspenseComponentWithoutHydrating(
14545 current$$1,
14546 workInProgress,
14547 renderExpirationTime
14548 );
14549 }
14550 // We use childExpirationTime to indicate that a child might depend on context, so if
14551 // any context has changed, we need to treat is as if the input might have changed.
14552 var hasContextChanged$$1 =
14553 current$$1.childExpirationTime >= renderExpirationTime;
14554 if (didReceiveUpdate || hasContextChanged$$1) {
14555 // This boundary has changed since the first render. This means that we are now unable to
14556 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
14557 // during this render we can't. Instead, we're going to delete the whole subtree and
14558 // instead inject a new real Suspense boundary to take its place, which may render content
14559 // or fallback. The real Suspense boundary will suspend for a while so we have some time
14560 // to ensure it can produce real content, but all state and pending events will be lost.
14561 return retrySuspenseComponentWithoutHydrating(
14562 current$$1,
14563 workInProgress,
14564 renderExpirationTime
14565 );
14566 } else if (isSuspenseInstancePending(suspenseInstance)) {
14567 // This component is still pending more data from the server, so we can't hydrate its
14568 // content. We treat it as if this component suspended itself. It might seem as if
14569 // we could just try to render it client-side instead. However, this will perform a
14570 // lot of unnecessary work and is unlikely to complete since it often will suspend
14571 // on missing data anyway. Additionally, the server might be able to render more
14572 // than we can on the client yet. In that case we'd end up with more fallback states
14573 // on the client than if we just leave it alone. If the server times out or errors
14574 // these should update this boundary to the permanent Fallback state instead.
14575 // Mark it as having captured (i.e. suspended).
14576 workInProgress.effectTag |= DidCapture;
14577 // Leave the children in place. I.e. empty.
14578 workInProgress.child = null;
14579 // Register a callback to retry this boundary once the server has sent the result.
14580 registerSuspenseInstanceRetry(
14581 suspenseInstance,
14582 retryTimedOutBoundary.bind(null, current$$1)
14583 );
14584 return null;
14585 } else {
14586 // This is the first attempt.
14587 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
14588 var nextProps = workInProgress.pendingProps;
14589 var nextChildren = nextProps.children;
14590 workInProgress.child = mountChildFibers(
14591 workInProgress,
14592 null,
14593 nextChildren,
14594 renderExpirationTime
14595 );
14596 return workInProgress.child;
14597 }
14598}
14599
14600function propagateSuspenseContextChange(
14601 workInProgress,
14602 firstChild,
14603 renderExpirationTime
14604) {
14605 // Mark any Suspense boundaries with fallbacks as having work to do.
14606 // If they were previously forced into fallbacks, they may now be able
14607 // to unblock.
14608 var node = firstChild;
14609 while (node !== null) {
14610 if (node.tag === SuspenseComponent) {
14611 var state = node.memoizedState;
14612 if (state !== null) {
14613 if (node.expirationTime < renderExpirationTime) {
14614 node.expirationTime = renderExpirationTime;
14615 }
14616 var alternate = node.alternate;
14617 if (
14618 alternate !== null &&
14619 alternate.expirationTime < renderExpirationTime
14620 ) {
14621 alternate.expirationTime = renderExpirationTime;
14622 }
14623 scheduleWorkOnParentPath(node.return, renderExpirationTime);
14624 }
14625 } else if (node.child !== null) {
14626 node.child.return = node;
14627 node = node.child;
14628 continue;
14629 }
14630 if (node === workInProgress) {
14631 return;
14632 }
14633 while (node.sibling === null) {
14634 if (node.return === null || node.return === workInProgress) {
14635 return;
14636 }
14637 node = node.return;
14638 }
14639 node.sibling.return = node.return;
14640 node = node.sibling;
14641 }
14642}
14643
14644function findLastContentRow(firstChild) {
14645 // This is going to find the last row among these children that is already
14646 // showing content on the screen, as opposed to being in fallback state or
14647 // new. If a row has multiple Suspense boundaries, any of them being in the
14648 // fallback state, counts as the whole row being in a fallback state.
14649 // Note that the "rows" will be workInProgress, but any nested children
14650 // will still be current since we haven't rendered them yet. The mounted
14651 // order may not be the same as the new order. We use the new order.
14652 var row = firstChild;
14653 var lastContentRow = null;
14654 while (row !== null) {
14655 var currentRow = row.alternate;
14656 // New rows can't be content rows.
14657 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
14658 lastContentRow = row;
14659 }
14660 row = row.sibling;
14661 }
14662 return lastContentRow;
14663}
14664
14665function validateRevealOrder(revealOrder) {
14666 {
14667 if (
14668 revealOrder !== undefined &&
14669 revealOrder !== "forwards" &&
14670 revealOrder !== "backwards" &&
14671 revealOrder !== "together" &&
14672 !didWarnAboutRevealOrder[revealOrder]
14673 ) {
14674 didWarnAboutRevealOrder[revealOrder] = true;
14675 if (typeof revealOrder === "string") {
14676 switch (revealOrder.toLowerCase()) {
14677 case "together":
14678 case "forwards":
14679 case "backwards": {
14680 warning$1(
14681 false,
14682 '"%s" is not a valid value for revealOrder on <SuspenseList />. ' +
14683 'Use lowercase "%s" instead.',
14684 revealOrder,
14685 revealOrder.toLowerCase()
14686 );
14687 break;
14688 }
14689 case "forward":
14690 case "backward": {
14691 warning$1(
14692 false,
14693 '"%s" is not a valid value for revealOrder on <SuspenseList />. ' +
14694 'React uses the -s suffix in the spelling. Use "%ss" instead.',
14695 revealOrder,
14696 revealOrder.toLowerCase()
14697 );
14698 break;
14699 }
14700 default:
14701 warning$1(
14702 false,
14703 '"%s" is not a supported revealOrder on <SuspenseList />. ' +
14704 'Did you mean "together", "forwards" or "backwards"?',
14705 revealOrder
14706 );
14707 break;
14708 }
14709 } else {
14710 warning$1(
14711 false,
14712 "%s is not a supported value for revealOrder on <SuspenseList />. " +
14713 'Did you mean "together", "forwards" or "backwards"?',
14714 revealOrder
14715 );
14716 }
14717 }
14718 }
14719}
14720
14721function validateTailOptions(tailMode, revealOrder) {
14722 {
14723 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
14724 if (tailMode !== "collapsed" && tailMode !== "hidden") {
14725 didWarnAboutTailOptions[tailMode] = true;
14726 warning$1(
14727 false,
14728 '"%s" is not a supported value for tail on <SuspenseList />. ' +
14729 'Did you mean "collapsed" or "hidden"?',
14730 tailMode
14731 );
14732 } else if (revealOrder !== "forwards" && revealOrder !== "backwards") {
14733 didWarnAboutTailOptions[tailMode] = true;
14734 warning$1(
14735 false,
14736 '<SuspenseList tail="%s" /> is only valid if revealOrder is ' +
14737 '"forwards" or "backwards". ' +
14738 'Did you mean to specify revealOrder="forwards"?',
14739 tailMode
14740 );
14741 }
14742 }
14743 }
14744}
14745
14746function validateSuspenseListNestedChild(childSlot, index) {
14747 {
14748 var isArray = Array.isArray(childSlot);
14749 var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function";
14750 if (isArray || isIterable) {
14751 var type = isArray ? "array" : "iterable";
14752 warning$1(
14753 false,
14754 "A nested %s was passed to row #%s in <SuspenseList />. Wrap it in " +
14755 "an additional SuspenseList to configure its revealOrder: " +
14756 "<SuspenseList revealOrder=...> ... " +
14757 "<SuspenseList revealOrder=...>{%s}</SuspenseList> ... " +
14758 "</SuspenseList>",
14759 type,
14760 index,
14761 type
14762 );
14763 return false;
14764 }
14765 }
14766 return true;
14767}
14768
14769function validateSuspenseListChildren(children, revealOrder) {
14770 {
14771 if (
14772 (revealOrder === "forwards" || revealOrder === "backwards") &&
14773 children !== undefined &&
14774 children !== null &&
14775 children !== false
14776 ) {
14777 if (Array.isArray(children)) {
14778 for (var i = 0; i < children.length; i++) {
14779 if (!validateSuspenseListNestedChild(children[i], i)) {
14780 return;
14781 }
14782 }
14783 } else {
14784 var iteratorFn = getIteratorFn(children);
14785 if (typeof iteratorFn === "function") {
14786 var childrenIterator = iteratorFn.call(children);
14787 if (childrenIterator) {
14788 var step = childrenIterator.next();
14789 var _i = 0;
14790 for (; !step.done; step = childrenIterator.next()) {
14791 if (!validateSuspenseListNestedChild(step.value, _i)) {
14792 return;
14793 }
14794 _i++;
14795 }
14796 }
14797 } else {
14798 warning$1(
14799 false,
14800 'A single row was passed to a <SuspenseList revealOrder="%s" />. ' +
14801 "This is not useful since it needs multiple rows. " +
14802 "Did you mean to pass multiple children or an array?",
14803 revealOrder
14804 );
14805 }
14806 }
14807 }
14808 }
14809}
14810
14811function initSuspenseListRenderState(
14812 workInProgress,
14813 isBackwards,
14814 tail,
14815 lastContentRow,
14816 tailMode
14817) {
14818 var renderState = workInProgress.memoizedState;
14819 if (renderState === null) {
14820 workInProgress.memoizedState = {
14821 isBackwards: isBackwards,
14822 rendering: null,
14823 last: lastContentRow,
14824 tail: tail,
14825 tailExpiration: 0,
14826 tailMode: tailMode
14827 };
14828 } else {
14829 // We can reuse the existing object from previous renders.
14830 renderState.isBackwards = isBackwards;
14831 renderState.rendering = null;
14832 renderState.last = lastContentRow;
14833 renderState.tail = tail;
14834 renderState.tailExpiration = 0;
14835 renderState.tailMode = tailMode;
14836 }
14837}
14838
14839// This can end up rendering this component multiple passes.
14840// The first pass splits the children fibers into two sets. A head and tail.
14841// We first render the head. If anything is in fallback state, we do another
14842// pass through beginWork to rerender all children (including the tail) with
14843// the force suspend context. If the first render didn't have anything in
14844// in fallback state. Then we render each row in the tail one-by-one.
14845// That happens in the completeWork phase without going back to beginWork.
14846function updateSuspenseListComponent(
14847 current$$1,
14848 workInProgress,
14849 renderExpirationTime
14850) {
14851 var nextProps = workInProgress.pendingProps;
14852 var revealOrder = nextProps.revealOrder;
14853 var tailMode = nextProps.tail;
14854 var newChildren = nextProps.children;
14855
14856 validateRevealOrder(revealOrder);
14857 validateTailOptions(tailMode, revealOrder);
14858 validateSuspenseListChildren(newChildren, revealOrder);
14859
14860 reconcileChildren(
14861 current$$1,
14862 workInProgress,
14863 newChildren,
14864 renderExpirationTime
14865 );
14866
14867 var suspenseContext = suspenseStackCursor.current;
14868
14869 var shouldForceFallback = hasSuspenseContext(
14870 suspenseContext,
14871 ForceSuspenseFallback
14872 );
14873 if (shouldForceFallback) {
14874 suspenseContext = setShallowSuspenseContext(
14875 suspenseContext,
14876 ForceSuspenseFallback
14877 );
14878 workInProgress.effectTag |= DidCapture;
14879 } else {
14880 var didSuspendBefore =
14881 current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect;
14882 if (didSuspendBefore) {
14883 // If we previously forced a fallback, we need to schedule work
14884 // on any nested boundaries to let them know to try to render
14885 // again. This is the same as context updating.
14886 propagateSuspenseContextChange(
14887 workInProgress,
14888 workInProgress.child,
14889 renderExpirationTime
14890 );
14891 }
14892 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
14893 }
14894 pushSuspenseContext(workInProgress, suspenseContext);
14895
14896 if ((workInProgress.mode & BatchedMode) === NoMode) {
14897 // Outside of batched mode, SuspenseList doesn't work so we just
14898 // use make it a noop by treating it as the default revealOrder.
14899 workInProgress.memoizedState = null;
14900 } else {
14901 switch (revealOrder) {
14902 case "forwards": {
14903 var lastContentRow = findLastContentRow(workInProgress.child);
14904 var tail = void 0;
14905 if (lastContentRow === null) {
14906 // The whole list is part of the tail.
14907 // TODO: We could fast path by just rendering the tail now.
14908 tail = workInProgress.child;
14909 workInProgress.child = null;
14910 } else {
14911 // Disconnect the tail rows after the content row.
14912 // We're going to render them separately later.
14913 tail = lastContentRow.sibling;
14914 lastContentRow.sibling = null;
14915 }
14916 initSuspenseListRenderState(
14917 workInProgress,
14918 false, // isBackwards
14919 tail,
14920 lastContentRow,
14921 tailMode
14922 );
14923 break;
14924 }
14925 case "backwards": {
14926 // We're going to find the first row that has existing content.
14927 // At the same time we're going to reverse the list of everything
14928 // we pass in the meantime. That's going to be our tail in reverse
14929 // order.
14930 var _tail = null;
14931 var row = workInProgress.child;
14932 workInProgress.child = null;
14933 while (row !== null) {
14934 var currentRow = row.alternate;
14935 // New rows can't be content rows.
14936 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
14937 // This is the beginning of the main content.
14938 workInProgress.child = row;
14939 break;
14940 }
14941 var nextRow = row.sibling;
14942 row.sibling = _tail;
14943 _tail = row;
14944 row = nextRow;
14945 }
14946 // TODO: If workInProgress.child is null, we can continue on the tail immediately.
14947 initSuspenseListRenderState(
14948 workInProgress,
14949 true, // isBackwards
14950 _tail,
14951 null, // last
14952 tailMode
14953 );
14954 break;
14955 }
14956 case "together": {
14957 initSuspenseListRenderState(
14958 workInProgress,
14959 false, // isBackwards
14960 null, // tail
14961 null, // last
14962 undefined
14963 );
14964 break;
14965 }
14966 default: {
14967 // The default reveal order is the same as not having
14968 // a boundary.
14969 workInProgress.memoizedState = null;
14970 }
14971 }
14972 }
14973 return workInProgress.child;
14974}
14975
14976function updatePortalComponent(
14977 current$$1,
14978 workInProgress,
14979 renderExpirationTime
14980) {
14981 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
14982 var nextChildren = workInProgress.pendingProps;
14983 if (current$$1 === null) {
14984 // Portals are special because we don't append the children during mount
14985 // but at commit. Therefore we need to track insertions which the normal
14986 // flow doesn't do during mount. This doesn't happen at the root because
14987 // the root always starts with a "current" with a null child.
14988 // TODO: Consider unifying this with how the root works.
14989 workInProgress.child = reconcileChildFibers(
14990 workInProgress,
14991 null,
14992 nextChildren,
14993 renderExpirationTime
14994 );
14995 } else {
14996 reconcileChildren(
14997 current$$1,
14998 workInProgress,
14999 nextChildren,
15000 renderExpirationTime
15001 );
15002 }
15003 return workInProgress.child;
15004}
15005
15006function updateContextProvider(
15007 current$$1,
15008 workInProgress,
15009 renderExpirationTime
15010) {
15011 var providerType = workInProgress.type;
15012 var context = providerType._context;
15013
15014 var newProps = workInProgress.pendingProps;
15015 var oldProps = workInProgress.memoizedProps;
15016
15017 var newValue = newProps.value;
15018
15019 {
15020 var providerPropTypes = workInProgress.type.propTypes;
15021
15022 if (providerPropTypes) {
15023 checkPropTypes(
15024 providerPropTypes,
15025 newProps,
15026 "prop",
15027 "Context.Provider",
15028 getCurrentFiberStackInDev
15029 );
15030 }
15031 }
15032
15033 pushProvider(workInProgress, newValue);
15034
15035 if (oldProps !== null) {
15036 var oldValue = oldProps.value;
15037 var changedBits = calculateChangedBits(context, newValue, oldValue);
15038 if (changedBits === 0) {
15039 // No change. Bailout early if children are the same.
15040 if (oldProps.children === newProps.children && !hasContextChanged()) {
15041 return bailoutOnAlreadyFinishedWork(
15042 current$$1,
15043 workInProgress,
15044 renderExpirationTime
15045 );
15046 }
15047 } else {
15048 // The context value changed. Search for matching consumers and schedule
15049 // them to update.
15050 propagateContextChange(
15051 workInProgress,
15052 context,
15053 changedBits,
15054 renderExpirationTime
15055 );
15056 }
15057 }
15058
15059 var newChildren = newProps.children;
15060 reconcileChildren(
15061 current$$1,
15062 workInProgress,
15063 newChildren,
15064 renderExpirationTime
15065 );
15066 return workInProgress.child;
15067}
15068
15069var hasWarnedAboutUsingContextAsConsumer = false;
15070
15071function updateContextConsumer(
15072 current$$1,
15073 workInProgress,
15074 renderExpirationTime
15075) {
15076 var context = workInProgress.type;
15077 // The logic below for Context differs depending on PROD or DEV mode. In
15078 // DEV mode, we create a separate object for Context.Consumer that acts
15079 // like a proxy to Context. This proxy object adds unnecessary code in PROD
15080 // so we use the old behaviour (Context.Consumer references Context) to
15081 // reduce size and overhead. The separate object references context via
15082 // a property called "_context", which also gives us the ability to check
15083 // in DEV mode if this property exists or not and warn if it does not.
15084 {
15085 if (context._context === undefined) {
15086 // This may be because it's a Context (rather than a Consumer).
15087 // Or it may be because it's older React where they're the same thing.
15088 // We only want to warn if we're sure it's a new React.
15089 if (context !== context.Consumer) {
15090 if (!hasWarnedAboutUsingContextAsConsumer) {
15091 hasWarnedAboutUsingContextAsConsumer = true;
15092 warning$1(
15093 false,
15094 "Rendering <Context> directly is not supported and will be removed in " +
15095 "a future major release. Did you mean to render <Context.Consumer> instead?"
15096 );
15097 }
15098 }
15099 } else {
15100 context = context._context;
15101 }
15102 }
15103 var newProps = workInProgress.pendingProps;
15104 var render = newProps.children;
15105
15106 {
15107 !(typeof render === "function")
15108 ? warningWithoutStack$1(
15109 false,
15110 "A context consumer was rendered with multiple children, or a child " +
15111 "that isn't a function. A context consumer expects a single child " +
15112 "that is a function. If you did pass a function, make sure there " +
15113 "is no trailing or leading whitespace around it."
15114 )
15115 : void 0;
15116 }
15117
15118 prepareToReadContext(workInProgress, renderExpirationTime);
15119 var newValue = readContext(context, newProps.unstable_observedBits);
15120 var newChildren = void 0;
15121 {
15122 ReactCurrentOwner$3.current = workInProgress;
15123 setCurrentPhase("render");
15124 newChildren = render(newValue);
15125 setCurrentPhase(null);
15126 }
15127
15128 // React DevTools reads this flag.
15129 workInProgress.effectTag |= PerformedWork;
15130 reconcileChildren(
15131 current$$1,
15132 workInProgress,
15133 newChildren,
15134 renderExpirationTime
15135 );
15136 return workInProgress.child;
15137}
15138
15139function updateFundamentalComponent$1(
15140 current$$1,
15141 workInProgress,
15142 renderExpirationTime
15143) {
15144 var fundamentalImpl = workInProgress.type.impl;
15145 if (fundamentalImpl.reconcileChildren === false) {
15146 return null;
15147 }
15148 var nextProps = workInProgress.pendingProps;
15149 var nextChildren = nextProps.children;
15150
15151 reconcileChildren(
15152 current$$1,
15153 workInProgress,
15154 nextChildren,
15155 renderExpirationTime
15156 );
15157 return workInProgress.child;
15158}
15159
15160function markWorkInProgressReceivedUpdate() {
15161 didReceiveUpdate = true;
15162}
15163
15164function bailoutOnAlreadyFinishedWork(
15165 current$$1,
15166 workInProgress,
15167 renderExpirationTime
15168) {
15169 cancelWorkTimer(workInProgress);
15170
15171 if (current$$1 !== null) {
15172 // Reuse previous dependencies
15173 workInProgress.dependencies = current$$1.dependencies;
15174 }
15175
15176 if (enableProfilerTimer) {
15177 // Don't update "base" render times for bailouts.
15178 stopProfilerTimerIfRunning(workInProgress);
15179 }
15180
15181 // Check if the children have any pending work.
15182 var childExpirationTime = workInProgress.childExpirationTime;
15183 if (childExpirationTime < renderExpirationTime) {
15184 // The children don't have any work either. We can skip them.
15185 // TODO: Once we add back resuming, we should check if the children are
15186 // a work-in-progress set. If so, we need to transfer their effects.
15187 return null;
15188 } else {
15189 // This fiber doesn't have work, but its subtree does. Clone the child
15190 // fibers and continue.
15191 cloneChildFibers(current$$1, workInProgress);
15192 return workInProgress.child;
15193 }
15194}
15195
15196function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) {
15197 {
15198 var returnFiber = oldWorkInProgress.return;
15199 if (returnFiber === null) {
15200 throw new Error("Cannot swap the root fiber.");
15201 }
15202
15203 // Disconnect from the old current.
15204 // It will get deleted.
15205 current$$1.alternate = null;
15206 oldWorkInProgress.alternate = null;
15207
15208 // Connect to the new tree.
15209 newWorkInProgress.index = oldWorkInProgress.index;
15210 newWorkInProgress.sibling = oldWorkInProgress.sibling;
15211 newWorkInProgress.return = oldWorkInProgress.return;
15212 newWorkInProgress.ref = oldWorkInProgress.ref;
15213
15214 // Replace the child/sibling pointers above it.
15215 if (oldWorkInProgress === returnFiber.child) {
15216 returnFiber.child = newWorkInProgress;
15217 } else {
15218 var prevSibling = returnFiber.child;
15219 if (prevSibling === null) {
15220 throw new Error("Expected parent to have a child.");
15221 }
15222 while (prevSibling.sibling !== oldWorkInProgress) {
15223 prevSibling = prevSibling.sibling;
15224 if (prevSibling === null) {
15225 throw new Error("Expected to find the previous sibling.");
15226 }
15227 }
15228 prevSibling.sibling = newWorkInProgress;
15229 }
15230
15231 // Delete the old fiber and place the new one.
15232 // Since the old fiber is disconnected, we have to schedule it manually.
15233 var last = returnFiber.lastEffect;
15234 if (last !== null) {
15235 last.nextEffect = current$$1;
15236 returnFiber.lastEffect = current$$1;
15237 } else {
15238 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
15239 }
15240 current$$1.nextEffect = null;
15241 current$$1.effectTag = Deletion;
15242
15243 newWorkInProgress.effectTag |= Placement;
15244
15245 // Restart work from the new fiber.
15246 return newWorkInProgress;
15247 }
15248}
15249
15250function beginWork$1(current$$1, workInProgress, renderExpirationTime) {
15251 var updateExpirationTime = workInProgress.expirationTime;
15252
15253 {
15254 if (workInProgress._debugNeedsRemount && current$$1 !== null) {
15255 // This will restart the begin phase with a new fiber.
15256 return remountFiber(
15257 current$$1,
15258 workInProgress,
15259 createFiberFromTypeAndProps(
15260 workInProgress.type,
15261 workInProgress.key,
15262 workInProgress.pendingProps,
15263 workInProgress._debugOwner || null,
15264 workInProgress.mode,
15265 workInProgress.expirationTime
15266 )
15267 );
15268 }
15269 }
15270
15271 if (current$$1 !== null) {
15272 var oldProps = current$$1.memoizedProps;
15273 var newProps = workInProgress.pendingProps;
15274
15275 if (
15276 oldProps !== newProps ||
15277 hasContextChanged() ||
15278 // Force a re-render if the implementation changed due to hot reload:
15279 workInProgress.type !== current$$1.type
15280 ) {
15281 // If props or context changed, mark the fiber as having performed work.
15282 // This may be unset if the props are determined to be equal later (memo).
15283 didReceiveUpdate = true;
15284 } else if (updateExpirationTime < renderExpirationTime) {
15285 didReceiveUpdate = false;
15286 // This fiber does not have any pending work. Bailout without entering
15287 // the begin phase. There's still some bookkeeping we that needs to be done
15288 // in this optimized path, mostly pushing stuff onto the stack.
15289 switch (workInProgress.tag) {
15290 case HostRoot:
15291 pushHostRootContext(workInProgress);
15292 resetHydrationState();
15293 break;
15294 case HostComponent:
15295 pushHostContext(workInProgress);
15296 if (
15297 workInProgress.mode & ConcurrentMode &&
15298 renderExpirationTime !== Never &&
15299 shouldDeprioritizeSubtree(workInProgress.type, newProps)
15300 ) {
15301 if (enableSchedulerTracing) {
15302 markSpawnedWork(Never);
15303 }
15304 // Schedule this fiber to re-render at offscreen priority. Then bailout.
15305 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
15306 return null;
15307 }
15308 break;
15309 case ClassComponent: {
15310 var Component = workInProgress.type;
15311 if (isContextProvider(Component)) {
15312 pushContextProvider(workInProgress);
15313 }
15314 break;
15315 }
15316 case HostPortal:
15317 pushHostContainer(
15318 workInProgress,
15319 workInProgress.stateNode.containerInfo
15320 );
15321 break;
15322 case ContextProvider: {
15323 var newValue = workInProgress.memoizedProps.value;
15324 pushProvider(workInProgress, newValue);
15325 break;
15326 }
15327 case Profiler:
15328 if (enableProfilerTimer) {
15329 workInProgress.effectTag |= Update;
15330 }
15331 break;
15332 case SuspenseComponent: {
15333 var state = workInProgress.memoizedState;
15334 var didTimeout = state !== null;
15335 if (didTimeout) {
15336 // If this boundary is currently timed out, we need to decide
15337 // whether to retry the primary children, or to skip over it and
15338 // go straight to the fallback. Check the priority of the primary
15339 var primaryChildFragment = workInProgress.child;
15340 var primaryChildExpirationTime =
15341 primaryChildFragment.childExpirationTime;
15342 if (
15343 primaryChildExpirationTime !== NoWork &&
15344 primaryChildExpirationTime >= renderExpirationTime
15345 ) {
15346 // The primary children have pending work. Use the normal path
15347 // to attempt to render the primary children again.
15348 return updateSuspenseComponent(
15349 current$$1,
15350 workInProgress,
15351 renderExpirationTime
15352 );
15353 } else {
15354 pushSuspenseContext(
15355 workInProgress,
15356 setDefaultShallowSuspenseContext(suspenseStackCursor.current)
15357 );
15358 // The primary children do not have pending work with sufficient
15359 // priority. Bailout.
15360 var child = bailoutOnAlreadyFinishedWork(
15361 current$$1,
15362 workInProgress,
15363 renderExpirationTime
15364 );
15365 if (child !== null) {
15366 // The fallback children have pending work. Skip over the
15367 // primary children and work on the fallback.
15368 return child.sibling;
15369 } else {
15370 return null;
15371 }
15372 }
15373 } else {
15374 pushSuspenseContext(
15375 workInProgress,
15376 setDefaultShallowSuspenseContext(suspenseStackCursor.current)
15377 );
15378 }
15379 break;
15380 }
15381 case DehydratedSuspenseComponent: {
15382 if (enableSuspenseServerRenderer) {
15383 pushSuspenseContext(
15384 workInProgress,
15385 setDefaultShallowSuspenseContext(suspenseStackCursor.current)
15386 );
15387 // We know that this component will suspend again because if it has
15388 // been unsuspended it has committed as a regular Suspense component.
15389 // If it needs to be retried, it should have work scheduled on it.
15390 workInProgress.effectTag |= DidCapture;
15391 }
15392 break;
15393 }
15394 case SuspenseListComponent: {
15395 var didSuspendBefore =
15396 (current$$1.effectTag & DidCapture) !== NoEffect;
15397
15398 var hasChildWork =
15399 workInProgress.childExpirationTime >= renderExpirationTime;
15400
15401 if (didSuspendBefore) {
15402 if (hasChildWork) {
15403 // If something was in fallback state last time, and we have all the
15404 // same children then we're still in progressive loading state.
15405 // Something might get unblocked by state updates or retries in the
15406 // tree which will affect the tail. So we need to use the normal
15407 // path to compute the correct tail.
15408 return updateSuspenseListComponent(
15409 current$$1,
15410 workInProgress,
15411 renderExpirationTime
15412 );
15413 }
15414 // If none of the children had any work, that means that none of
15415 // them got retried so they'll still be blocked in the same way
15416 // as before. We can fast bail out.
15417 workInProgress.effectTag |= DidCapture;
15418 }
15419
15420 // If nothing suspended before and we're rendering the same children,
15421 // then the tail doesn't matter. Anything new that suspends will work
15422 // in the "together" mode, so we can continue from the state we had.
15423 var renderState = workInProgress.memoizedState;
15424 if (renderState !== null) {
15425 // Reset to the "together" mode in case we've started a different
15426 // update in the past but didn't complete it.
15427 renderState.rendering = null;
15428 renderState.tail = null;
15429 }
15430 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
15431
15432 if (hasChildWork) {
15433 break;
15434 } else {
15435 // If none of the children had any work, that means that none of
15436 // them got retried so they'll still be blocked in the same way
15437 // as before. We can fast bail out.
15438 return null;
15439 }
15440 }
15441 }
15442 return bailoutOnAlreadyFinishedWork(
15443 current$$1,
15444 workInProgress,
15445 renderExpirationTime
15446 );
15447 }
15448 } else {
15449 didReceiveUpdate = false;
15450 }
15451
15452 // Before entering the begin phase, clear the expiration time.
15453 workInProgress.expirationTime = NoWork;
15454
15455 switch (workInProgress.tag) {
15456 case IndeterminateComponent: {
15457 return mountIndeterminateComponent(
15458 current$$1,
15459 workInProgress,
15460 workInProgress.type,
15461 renderExpirationTime
15462 );
15463 }
15464 case LazyComponent: {
15465 var elementType = workInProgress.elementType;
15466 return mountLazyComponent(
15467 current$$1,
15468 workInProgress,
15469 elementType,
15470 updateExpirationTime,
15471 renderExpirationTime
15472 );
15473 }
15474 case FunctionComponent: {
15475 var _Component = workInProgress.type;
15476 var unresolvedProps = workInProgress.pendingProps;
15477 var resolvedProps =
15478 workInProgress.elementType === _Component
15479 ? unresolvedProps
15480 : resolveDefaultProps(_Component, unresolvedProps);
15481 return updateFunctionComponent(
15482 current$$1,
15483 workInProgress,
15484 _Component,
15485 resolvedProps,
15486 renderExpirationTime
15487 );
15488 }
15489 case ClassComponent: {
15490 var _Component2 = workInProgress.type;
15491 var _unresolvedProps = workInProgress.pendingProps;
15492 var _resolvedProps =
15493 workInProgress.elementType === _Component2
15494 ? _unresolvedProps
15495 : resolveDefaultProps(_Component2, _unresolvedProps);
15496 return updateClassComponent(
15497 current$$1,
15498 workInProgress,
15499 _Component2,
15500 _resolvedProps,
15501 renderExpirationTime
15502 );
15503 }
15504 case HostRoot:
15505 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
15506 case HostComponent:
15507 return updateHostComponent(
15508 current$$1,
15509 workInProgress,
15510 renderExpirationTime
15511 );
15512 case HostText:
15513 return updateHostText(current$$1, workInProgress);
15514 case SuspenseComponent:
15515 return updateSuspenseComponent(
15516 current$$1,
15517 workInProgress,
15518 renderExpirationTime
15519 );
15520 case HostPortal:
15521 return updatePortalComponent(
15522 current$$1,
15523 workInProgress,
15524 renderExpirationTime
15525 );
15526 case ForwardRef: {
15527 var type = workInProgress.type;
15528 var _unresolvedProps2 = workInProgress.pendingProps;
15529 var _resolvedProps2 =
15530 workInProgress.elementType === type
15531 ? _unresolvedProps2
15532 : resolveDefaultProps(type, _unresolvedProps2);
15533 return updateForwardRef(
15534 current$$1,
15535 workInProgress,
15536 type,
15537 _resolvedProps2,
15538 renderExpirationTime
15539 );
15540 }
15541 case Fragment:
15542 return updateFragment(current$$1, workInProgress, renderExpirationTime);
15543 case Mode:
15544 return updateMode(current$$1, workInProgress, renderExpirationTime);
15545 case Profiler:
15546 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
15547 case ContextProvider:
15548 return updateContextProvider(
15549 current$$1,
15550 workInProgress,
15551 renderExpirationTime
15552 );
15553 case ContextConsumer:
15554 return updateContextConsumer(
15555 current$$1,
15556 workInProgress,
15557 renderExpirationTime
15558 );
15559 case MemoComponent: {
15560 var _type2 = workInProgress.type;
15561 var _unresolvedProps3 = workInProgress.pendingProps;
15562 // Resolve outer props first, then resolve inner props.
15563 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
15564 {
15565 if (workInProgress.type !== workInProgress.elementType) {
15566 var outerPropTypes = _type2.propTypes;
15567 if (outerPropTypes) {
15568 checkPropTypes(
15569 outerPropTypes,
15570 _resolvedProps3, // Resolved for outer only
15571 "prop",
15572 getComponentName(_type2),
15573 getCurrentFiberStackInDev
15574 );
15575 }
15576 }
15577 }
15578 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
15579 return updateMemoComponent(
15580 current$$1,
15581 workInProgress,
15582 _type2,
15583 _resolvedProps3,
15584 updateExpirationTime,
15585 renderExpirationTime
15586 );
15587 }
15588 case SimpleMemoComponent: {
15589 return updateSimpleMemoComponent(
15590 current$$1,
15591 workInProgress,
15592 workInProgress.type,
15593 workInProgress.pendingProps,
15594 updateExpirationTime,
15595 renderExpirationTime
15596 );
15597 }
15598 case IncompleteClassComponent: {
15599 var _Component3 = workInProgress.type;
15600 var _unresolvedProps4 = workInProgress.pendingProps;
15601 var _resolvedProps4 =
15602 workInProgress.elementType === _Component3
15603 ? _unresolvedProps4
15604 : resolveDefaultProps(_Component3, _unresolvedProps4);
15605 return mountIncompleteClassComponent(
15606 current$$1,
15607 workInProgress,
15608 _Component3,
15609 _resolvedProps4,
15610 renderExpirationTime
15611 );
15612 }
15613 case DehydratedSuspenseComponent: {
15614 if (enableSuspenseServerRenderer) {
15615 return updateDehydratedSuspenseComponent(
15616 current$$1,
15617 workInProgress,
15618 renderExpirationTime
15619 );
15620 }
15621 break;
15622 }
15623 case SuspenseListComponent: {
15624 return updateSuspenseListComponent(
15625 current$$1,
15626 workInProgress,
15627 renderExpirationTime
15628 );
15629 }
15630 case FundamentalComponent: {
15631 if (enableFundamentalAPI) {
15632 return updateFundamentalComponent$1(
15633 current$$1,
15634 workInProgress,
15635 renderExpirationTime
15636 );
15637 }
15638 break;
15639 }
15640 }
15641 (function() {
15642 {
15643 throw ReactError(
15644 Error(
15645 "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue."
15646 )
15647 );
15648 }
15649 })();
15650}
15651
15652function createFundamentalStateInstance(currentFiber, props, impl, state) {
15653 return {
15654 currentFiber: currentFiber,
15655 impl: impl,
15656 instance: null,
15657 prevProps: null,
15658 props: props,
15659 state: state
15660 };
15661}
15662
15663var emptyObject$1 = {};
15664var isArray$2 = Array.isArray;
15665
15666function markUpdate(workInProgress) {
15667 // Tag the fiber with an update effect. This turns a Placement into
15668 // a PlacementAndUpdate.
15669 workInProgress.effectTag |= Update;
15670}
15671
15672function markRef$1(workInProgress) {
15673 workInProgress.effectTag |= Ref;
15674}
15675
15676var appendAllChildren = void 0;
15677var updateHostContainer = void 0;
15678var updateHostComponent$1 = void 0;
15679var updateHostText$1 = void 0;
15680if (supportsMutation) {
15681 // Mutation mode
15682
15683 appendAllChildren = function(
15684 parent,
15685 workInProgress,
15686 needsVisibilityToggle,
15687 isHidden
15688 ) {
15689 // We only have the top Fiber that was created but we need recurse down its
15690 // children to find all the terminal nodes.
15691 var node = workInProgress.child;
15692 while (node !== null) {
15693 if (node.tag === HostComponent || node.tag === HostText) {
15694 appendInitialChild(parent, node.stateNode);
15695 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
15696 appendInitialChild(parent, node.stateNode.instance);
15697 } else if (node.tag === HostPortal) {
15698 // If we have a portal child, then we don't want to traverse
15699 // down its children. Instead, we'll get insertions from each child in
15700 // the portal directly.
15701 } else if (node.child !== null) {
15702 node.child.return = node;
15703 node = node.child;
15704 continue;
15705 }
15706 if (node === workInProgress) {
15707 return;
15708 }
15709 while (node.sibling === null) {
15710 if (node.return === null || node.return === workInProgress) {
15711 return;
15712 }
15713 node = node.return;
15714 }
15715 node.sibling.return = node.return;
15716 node = node.sibling;
15717 }
15718 };
15719
15720 updateHostContainer = function(workInProgress) {
15721 // Noop
15722 };
15723 updateHostComponent$1 = function(
15724 current,
15725 workInProgress,
15726 type,
15727 newProps,
15728 rootContainerInstance
15729 ) {
15730 // If we have an alternate, that means this is an update and we need to
15731 // schedule a side-effect to do the updates.
15732 var oldProps = current.memoizedProps;
15733 if (oldProps === newProps) {
15734 // In mutation mode, this is sufficient for a bailout because
15735 // we won't touch this node even if children changed.
15736 return;
15737 }
15738
15739 // If we get updated because one of our children updated, we don't
15740 // have newProps so we'll have to reuse them.
15741 // TODO: Split the update API as separate for the props vs. children.
15742 // Even better would be if children weren't special cased at all tho.
15743 var instance = workInProgress.stateNode;
15744 var currentHostContext = getHostContext();
15745 // TODO: Experiencing an error where oldProps is null. Suggests a host
15746 // component is hitting the resume path. Figure out why. Possibly
15747 // related to `hidden`.
15748 var updatePayload = prepareUpdate(
15749 instance,
15750 type,
15751 oldProps,
15752 newProps,
15753 rootContainerInstance,
15754 currentHostContext
15755 );
15756 // TODO: Type this specific to this type of component.
15757 workInProgress.updateQueue = updatePayload;
15758 // If the update payload indicates that there is a change or if there
15759 // is a new ref we mark this as an update. All the work is done in commitWork.
15760 if (updatePayload) {
15761 markUpdate(workInProgress);
15762 }
15763 };
15764 updateHostText$1 = function(current, workInProgress, oldText, newText) {
15765 // If the text differs, mark it as an update. All the work in done in commitWork.
15766 if (oldText !== newText) {
15767 markUpdate(workInProgress);
15768 }
15769 };
15770} else if (supportsPersistence) {
15771 // Persistent host tree mode
15772
15773 appendAllChildren = function(
15774 parent,
15775 workInProgress,
15776 needsVisibilityToggle,
15777 isHidden
15778 ) {
15779 // We only have the top Fiber that was created but we need recurse down its
15780 // children to find all the terminal nodes.
15781 var node = workInProgress.child;
15782 while (node !== null) {
15783 // eslint-disable-next-line no-labels
15784 branches: if (node.tag === HostComponent) {
15785 var instance = node.stateNode;
15786 if (needsVisibilityToggle && isHidden) {
15787 // This child is inside a timed out tree. Hide it.
15788 var props = node.memoizedProps;
15789 var type = node.type;
15790 instance = cloneHiddenInstance(instance, type, props, node);
15791 }
15792 appendInitialChild(parent, instance);
15793 } else if (node.tag === HostText) {
15794 var _instance = node.stateNode;
15795 if (needsVisibilityToggle && isHidden) {
15796 // This child is inside a timed out tree. Hide it.
15797 var text = node.memoizedProps;
15798 _instance = cloneHiddenTextInstance(_instance, text, node);
15799 }
15800 appendInitialChild(parent, _instance);
15801 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
15802 var _instance2 = node.stateNode.instance;
15803 if (needsVisibilityToggle && isHidden) {
15804 // This child is inside a timed out tree. Hide it.
15805 var _props = node.memoizedProps;
15806 var _type = node.type;
15807 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
15808 }
15809 appendInitialChild(parent, _instance2);
15810 } else if (node.tag === HostPortal) {
15811 // If we have a portal child, then we don't want to traverse
15812 // down its children. Instead, we'll get insertions from each child in
15813 // the portal directly.
15814 } else if (node.tag === SuspenseComponent) {
15815 if ((node.effectTag & Update) !== NoEffect) {
15816 // Need to toggle the visibility of the primary children.
15817 var newIsHidden = node.memoizedState !== null;
15818 if (newIsHidden) {
15819 var primaryChildParent = node.child;
15820 if (primaryChildParent !== null) {
15821 if (primaryChildParent.child !== null) {
15822 primaryChildParent.child.return = primaryChildParent;
15823 appendAllChildren(
15824 parent,
15825 primaryChildParent,
15826 true,
15827 newIsHidden
15828 );
15829 }
15830 var fallbackChildParent = primaryChildParent.sibling;
15831 if (fallbackChildParent !== null) {
15832 fallbackChildParent.return = node;
15833 node = fallbackChildParent;
15834 continue;
15835 }
15836 }
15837 }
15838 }
15839 if (node.child !== null) {
15840 // Continue traversing like normal
15841 node.child.return = node;
15842 node = node.child;
15843 continue;
15844 }
15845 } else if (node.child !== null) {
15846 node.child.return = node;
15847 node = node.child;
15848 continue;
15849 }
15850 // $FlowFixMe This is correct but Flow is confused by the labeled break.
15851 node = node;
15852 if (node === workInProgress) {
15853 return;
15854 }
15855 while (node.sibling === null) {
15856 if (node.return === null || node.return === workInProgress) {
15857 return;
15858 }
15859 node = node.return;
15860 }
15861 node.sibling.return = node.return;
15862 node = node.sibling;
15863 }
15864 };
15865
15866 // An unfortunate fork of appendAllChildren because we have two different parent types.
15867 var appendAllChildrenToContainer = function(
15868 containerChildSet,
15869 workInProgress,
15870 needsVisibilityToggle,
15871 isHidden
15872 ) {
15873 // We only have the top Fiber that was created but we need recurse down its
15874 // children to find all the terminal nodes.
15875 var node = workInProgress.child;
15876 while (node !== null) {
15877 // eslint-disable-next-line no-labels
15878 branches: if (node.tag === HostComponent) {
15879 var instance = node.stateNode;
15880 if (needsVisibilityToggle && isHidden) {
15881 // This child is inside a timed out tree. Hide it.
15882 var props = node.memoizedProps;
15883 var type = node.type;
15884 instance = cloneHiddenInstance(instance, type, props, node);
15885 }
15886 appendChildToContainerChildSet(containerChildSet, instance);
15887 } else if (node.tag === HostText) {
15888 var _instance3 = node.stateNode;
15889 if (needsVisibilityToggle && isHidden) {
15890 // This child is inside a timed out tree. Hide it.
15891 var text = node.memoizedProps;
15892 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
15893 }
15894 appendChildToContainerChildSet(containerChildSet, _instance3);
15895 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
15896 var _instance4 = node.stateNode.instance;
15897 if (needsVisibilityToggle && isHidden) {
15898 // This child is inside a timed out tree. Hide it.
15899 var _props2 = node.memoizedProps;
15900 var _type2 = node.type;
15901 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
15902 }
15903 appendChildToContainerChildSet(containerChildSet, _instance4);
15904 } else if (node.tag === HostPortal) {
15905 // If we have a portal child, then we don't want to traverse
15906 // down its children. Instead, we'll get insertions from each child in
15907 // the portal directly.
15908 } else if (node.tag === SuspenseComponent) {
15909 if ((node.effectTag & Update) !== NoEffect) {
15910 // Need to toggle the visibility of the primary children.
15911 var newIsHidden = node.memoizedState !== null;
15912 if (newIsHidden) {
15913 var primaryChildParent = node.child;
15914 if (primaryChildParent !== null) {
15915 if (primaryChildParent.child !== null) {
15916 primaryChildParent.child.return = primaryChildParent;
15917 appendAllChildrenToContainer(
15918 containerChildSet,
15919 primaryChildParent,
15920 true,
15921 newIsHidden
15922 );
15923 }
15924 var fallbackChildParent = primaryChildParent.sibling;
15925 if (fallbackChildParent !== null) {
15926 fallbackChildParent.return = node;
15927 node = fallbackChildParent;
15928 continue;
15929 }
15930 }
15931 }
15932 }
15933 if (node.child !== null) {
15934 // Continue traversing like normal
15935 node.child.return = node;
15936 node = node.child;
15937 continue;
15938 }
15939 } else if (node.child !== null) {
15940 node.child.return = node;
15941 node = node.child;
15942 continue;
15943 }
15944 // $FlowFixMe This is correct but Flow is confused by the labeled break.
15945 node = node;
15946 if (node === workInProgress) {
15947 return;
15948 }
15949 while (node.sibling === null) {
15950 if (node.return === null || node.return === workInProgress) {
15951 return;
15952 }
15953 node = node.return;
15954 }
15955 node.sibling.return = node.return;
15956 node = node.sibling;
15957 }
15958 };
15959 updateHostContainer = function(workInProgress) {
15960 var portalOrRoot = workInProgress.stateNode;
15961 var childrenUnchanged = workInProgress.firstEffect === null;
15962 if (childrenUnchanged) {
15963 // No changes, just reuse the existing instance.
15964 } else {
15965 var container = portalOrRoot.containerInfo;
15966 var newChildSet = createContainerChildSet(container);
15967 // If children might have changed, we have to add them all to the set.
15968 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
15969 portalOrRoot.pendingChildren = newChildSet;
15970 // Schedule an update on the container to swap out the container.
15971 markUpdate(workInProgress);
15972 finalizeContainerChildren(container, newChildSet);
15973 }
15974 };
15975 updateHostComponent$1 = function(
15976 current,
15977 workInProgress,
15978 type,
15979 newProps,
15980 rootContainerInstance
15981 ) {
15982 var currentInstance = current.stateNode;
15983 var oldProps = current.memoizedProps;
15984 // If there are no effects associated with this node, then none of our children had any updates.
15985 // This guarantees that we can reuse all of them.
15986 var childrenUnchanged = workInProgress.firstEffect === null;
15987 if (childrenUnchanged && oldProps === newProps) {
15988 // No changes, just reuse the existing instance.
15989 // Note that this might release a previous clone.
15990 workInProgress.stateNode = currentInstance;
15991 return;
15992 }
15993 var recyclableInstance = workInProgress.stateNode;
15994 var currentHostContext = getHostContext();
15995 var updatePayload = null;
15996 if (oldProps !== newProps) {
15997 updatePayload = prepareUpdate(
15998 recyclableInstance,
15999 type,
16000 oldProps,
16001 newProps,
16002 rootContainerInstance,
16003 currentHostContext
16004 );
16005 }
16006 if (childrenUnchanged && updatePayload === null) {
16007 // No changes, just reuse the existing instance.
16008 // Note that this might release a previous clone.
16009 workInProgress.stateNode = currentInstance;
16010 return;
16011 }
16012 var newInstance = cloneInstance(
16013 currentInstance,
16014 updatePayload,
16015 type,
16016 oldProps,
16017 newProps,
16018 workInProgress,
16019 childrenUnchanged,
16020 recyclableInstance
16021 );
16022 if (
16023 finalizeInitialChildren(
16024 newInstance,
16025 type,
16026 newProps,
16027 rootContainerInstance,
16028 currentHostContext
16029 )
16030 ) {
16031 markUpdate(workInProgress);
16032 }
16033 workInProgress.stateNode = newInstance;
16034 if (childrenUnchanged) {
16035 // If there are no other effects in this tree, we need to flag this node as having one.
16036 // Even though we're not going to use it for anything.
16037 // Otherwise parents won't know that there are new children to propagate upwards.
16038 markUpdate(workInProgress);
16039 } else {
16040 // If children might have changed, we have to add them all to the set.
16041 appendAllChildren(newInstance, workInProgress, false, false);
16042 }
16043 };
16044 updateHostText$1 = function(current, workInProgress, oldText, newText) {
16045 if (oldText !== newText) {
16046 // If the text content differs, we'll create a new text instance for it.
16047 var rootContainerInstance = getRootHostContainer();
16048 var currentHostContext = getHostContext();
16049 workInProgress.stateNode = createTextInstance(
16050 newText,
16051 rootContainerInstance,
16052 currentHostContext,
16053 workInProgress
16054 );
16055 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
16056 // This lets the parents know that at least one of their children has changed.
16057 markUpdate(workInProgress);
16058 }
16059 };
16060} else {
16061 // No host operations
16062 updateHostContainer = function(workInProgress) {
16063 // Noop
16064 };
16065 updateHostComponent$1 = function(
16066 current,
16067 workInProgress,
16068 type,
16069 newProps,
16070 rootContainerInstance
16071 ) {
16072 // Noop
16073 };
16074 updateHostText$1 = function(current, workInProgress, oldText, newText) {
16075 // Noop
16076 };
16077}
16078
16079function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
16080 switch (renderState.tailMode) {
16081 case "hidden": {
16082 // Any insertions at the end of the tail list after this point
16083 // should be invisible. If there are already mounted boundaries
16084 // anything before them are not considered for collapsing.
16085 // Therefore we need to go through the whole tail to find if
16086 // there are any.
16087 var tailNode = renderState.tail;
16088 var lastTailNode = null;
16089 while (tailNode !== null) {
16090 if (tailNode.alternate !== null) {
16091 lastTailNode = tailNode;
16092 }
16093 tailNode = tailNode.sibling;
16094 }
16095 // Next we're simply going to delete all insertions after the
16096 // last rendered item.
16097 if (lastTailNode === null) {
16098 // All remaining items in the tail are insertions.
16099 renderState.tail = null;
16100 } else {
16101 // Detach the insertion after the last node that was already
16102 // inserted.
16103 lastTailNode.sibling = null;
16104 }
16105 break;
16106 }
16107 case "collapsed": {
16108 // Any insertions at the end of the tail list after this point
16109 // should be invisible. If there are already mounted boundaries
16110 // anything before them are not considered for collapsing.
16111 // Therefore we need to go through the whole tail to find if
16112 // there are any.
16113 var _tailNode = renderState.tail;
16114 var _lastTailNode = null;
16115 while (_tailNode !== null) {
16116 if (_tailNode.alternate !== null) {
16117 _lastTailNode = _tailNode;
16118 }
16119 _tailNode = _tailNode.sibling;
16120 }
16121 // Next we're simply going to delete all insertions after the
16122 // last rendered item.
16123 if (_lastTailNode === null) {
16124 // All remaining items in the tail are insertions.
16125 if (!hasRenderedATailFallback && renderState.tail !== null) {
16126 // We suspended during the head. We want to show at least one
16127 // row at the tail. So we'll keep on and cut off the rest.
16128 renderState.tail.sibling = null;
16129 } else {
16130 renderState.tail = null;
16131 }
16132 } else {
16133 // Detach the insertion after the last node that was already
16134 // inserted.
16135 _lastTailNode.sibling = null;
16136 }
16137 break;
16138 }
16139 }
16140}
16141
16142function completeWork(current, workInProgress, renderExpirationTime) {
16143 var newProps = workInProgress.pendingProps;
16144
16145 switch (workInProgress.tag) {
16146 case IndeterminateComponent:
16147 break;
16148 case LazyComponent:
16149 break;
16150 case SimpleMemoComponent:
16151 case FunctionComponent:
16152 break;
16153 case ClassComponent: {
16154 var Component = workInProgress.type;
16155 if (isContextProvider(Component)) {
16156 popContext(workInProgress);
16157 }
16158 break;
16159 }
16160 case HostRoot: {
16161 popHostContainer(workInProgress);
16162 popTopLevelContextObject(workInProgress);
16163 var fiberRoot = workInProgress.stateNode;
16164 if (fiberRoot.pendingContext) {
16165 fiberRoot.context = fiberRoot.pendingContext;
16166 fiberRoot.pendingContext = null;
16167 }
16168 if (current === null || current.child === null) {
16169 // If we hydrated, pop so that we can delete any remaining children
16170 // that weren't hydrated.
16171 popHydrationState(workInProgress);
16172 // This resets the hacky state to fix isMounted before committing.
16173 // TODO: Delete this when we delete isMounted and findDOMNode.
16174 workInProgress.effectTag &= ~Placement;
16175 }
16176 updateHostContainer(workInProgress);
16177 break;
16178 }
16179 case HostComponent: {
16180 popHostContext(workInProgress);
16181 var rootContainerInstance = getRootHostContainer();
16182 var type = workInProgress.type;
16183 if (current !== null && workInProgress.stateNode != null) {
16184 updateHostComponent$1(
16185 current,
16186 workInProgress,
16187 type,
16188 newProps,
16189 rootContainerInstance
16190 );
16191
16192 if (enableFlareAPI) {
16193 var prevListeners = current.memoizedProps.listeners;
16194 var nextListeners = newProps.listeners;
16195 var instance = workInProgress.stateNode;
16196 if (prevListeners !== nextListeners) {
16197 updateEventListeners(
16198 nextListeners,
16199 instance,
16200 rootContainerInstance,
16201 workInProgress
16202 );
16203 }
16204 }
16205
16206 if (current.ref !== workInProgress.ref) {
16207 markRef$1(workInProgress);
16208 }
16209 } else {
16210 if (!newProps) {
16211 (function() {
16212 if (!(workInProgress.stateNode !== null)) {
16213 throw ReactError(
16214 Error(
16215 "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue."
16216 )
16217 );
16218 }
16219 })();
16220 // This can happen when we abort work.
16221 break;
16222 }
16223
16224 var currentHostContext = getHostContext();
16225 // TODO: Move createInstance to beginWork and keep it on a context
16226 // "stack" as the parent. Then append children as we go in beginWork
16227 // or completeWork depending on we want to add then top->down or
16228 // bottom->up. Top->down is faster in IE11.
16229 var wasHydrated = popHydrationState(workInProgress);
16230 if (wasHydrated) {
16231 // TODO: Move this and createInstance step into the beginPhase
16232 // to consolidate.
16233 if (
16234 prepareToHydrateHostInstance(
16235 workInProgress,
16236 rootContainerInstance,
16237 currentHostContext
16238 )
16239 ) {
16240 // If changes to the hydrated node needs to be applied at the
16241 // commit-phase we mark this as such.
16242 markUpdate(workInProgress);
16243 }
16244 if (enableFlareAPI) {
16245 var _instance5 = workInProgress.stateNode;
16246 var listeners = newProps.listeners;
16247 if (listeners != null) {
16248 updateEventListeners(
16249 listeners,
16250 _instance5,
16251 rootContainerInstance,
16252 workInProgress
16253 );
16254 }
16255 }
16256 } else {
16257 var _instance6 = createInstance(
16258 type,
16259 newProps,
16260 rootContainerInstance,
16261 currentHostContext,
16262 workInProgress
16263 );
16264
16265 appendAllChildren(_instance6, workInProgress, false, false);
16266
16267 if (enableFlareAPI) {
16268 var _listeners = newProps.listeners;
16269 if (_listeners != null) {
16270 updateEventListeners(
16271 _listeners,
16272 _instance6,
16273 rootContainerInstance,
16274 workInProgress
16275 );
16276 }
16277 }
16278
16279 // Certain renderers require commit-time effects for initial mount.
16280 // (eg DOM renderer supports auto-focus for certain elements).
16281 // Make sure such renderers get scheduled for later work.
16282 if (
16283 finalizeInitialChildren(
16284 _instance6,
16285 type,
16286 newProps,
16287 rootContainerInstance,
16288 currentHostContext
16289 )
16290 ) {
16291 markUpdate(workInProgress);
16292 }
16293 workInProgress.stateNode = _instance6;
16294 }
16295
16296 if (workInProgress.ref !== null) {
16297 // If there is a ref on a host node we need to schedule a callback
16298 markRef$1(workInProgress);
16299 }
16300 }
16301 break;
16302 }
16303 case HostText: {
16304 var newText = newProps;
16305 if (current && workInProgress.stateNode != null) {
16306 var oldText = current.memoizedProps;
16307 // If we have an alternate, that means this is an update and we need
16308 // to schedule a side-effect to do the updates.
16309 updateHostText$1(current, workInProgress, oldText, newText);
16310 } else {
16311 if (typeof newText !== "string") {
16312 (function() {
16313 if (!(workInProgress.stateNode !== null)) {
16314 throw ReactError(
16315 Error(
16316 "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue."
16317 )
16318 );
16319 }
16320 })();
16321 // This can happen when we abort work.
16322 }
16323 var _rootContainerInstance = getRootHostContainer();
16324 var _currentHostContext = getHostContext();
16325 var _wasHydrated = popHydrationState(workInProgress);
16326 if (_wasHydrated) {
16327 if (prepareToHydrateHostTextInstance(workInProgress)) {
16328 markUpdate(workInProgress);
16329 }
16330 } else {
16331 workInProgress.stateNode = createTextInstance(
16332 newText,
16333 _rootContainerInstance,
16334 _currentHostContext,
16335 workInProgress
16336 );
16337 }
16338 }
16339 break;
16340 }
16341 case ForwardRef:
16342 break;
16343 case SuspenseComponent: {
16344 popSuspenseContext(workInProgress);
16345 var nextState = workInProgress.memoizedState;
16346 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
16347 // Something suspended. Re-render with the fallback children.
16348 workInProgress.expirationTime = renderExpirationTime;
16349 // Do not reset the effect list.
16350 return workInProgress;
16351 }
16352
16353 var nextDidTimeout = nextState !== null;
16354 var prevDidTimeout = false;
16355 if (current === null) {
16356 // In cases where we didn't find a suitable hydration boundary we never
16357 // downgraded this to a DehydratedSuspenseComponent, but we still need to
16358 // pop the hydration state since we might be inside the insertion tree.
16359 popHydrationState(workInProgress);
16360 } else {
16361 var prevState = current.memoizedState;
16362 prevDidTimeout = prevState !== null;
16363 if (!nextDidTimeout && prevState !== null) {
16364 // We just switched from the fallback to the normal children.
16365 // Delete the fallback.
16366 // TODO: Would it be better to store the fallback fragment on
16367 var currentFallbackChild = current.child.sibling;
16368 if (currentFallbackChild !== null) {
16369 // Deletions go at the beginning of the return fiber's effect list
16370 var first = workInProgress.firstEffect;
16371 if (first !== null) {
16372 workInProgress.firstEffect = currentFallbackChild;
16373 currentFallbackChild.nextEffect = first;
16374 } else {
16375 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
16376 currentFallbackChild.nextEffect = null;
16377 }
16378 currentFallbackChild.effectTag = Deletion;
16379 }
16380 }
16381 }
16382
16383 if (nextDidTimeout && !prevDidTimeout) {
16384 // If this subtreee is running in batched mode we can suspend,
16385 // otherwise we won't suspend.
16386 // TODO: This will still suspend a synchronous tree if anything
16387 // in the concurrent tree already suspended during this render.
16388 // This is a known bug.
16389 if ((workInProgress.mode & BatchedMode) !== NoMode) {
16390 // TODO: Move this back to throwException because this is too late
16391 // if this is a large tree which is common for initial loads. We
16392 // don't know if we should restart a render or not until we get
16393 // this marker, and this is too late.
16394 // If this render already had a ping or lower pri updates,
16395 // and this is the first time we know we're going to suspend we
16396 // should be able to immediately restart from within throwException.
16397 var hasInvisibleChildContext =
16398 current === null &&
16399 workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
16400 if (
16401 hasInvisibleChildContext ||
16402 hasSuspenseContext(
16403 suspenseStackCursor.current,
16404 InvisibleParentSuspenseContext
16405 )
16406 ) {
16407 // If this was in an invisible tree or a new render, then showing
16408 // this boundary is ok.
16409 renderDidSuspend();
16410 } else {
16411 // Otherwise, we're going to have to hide content so we should
16412 // suspend for longer if possible.
16413 renderDidSuspendDelayIfPossible();
16414 }
16415 }
16416 }
16417
16418 if (supportsPersistence) {
16419 // TODO: Only schedule updates if not prevDidTimeout.
16420 if (nextDidTimeout) {
16421 // If this boundary just timed out, schedule an effect to attach a
16422 // retry listener to the proimse. This flag is also used to hide the
16423 // primary children.
16424 workInProgress.effectTag |= Update;
16425 }
16426 }
16427 if (supportsMutation) {
16428 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
16429 if (nextDidTimeout || prevDidTimeout) {
16430 // If this boundary just timed out, schedule an effect to attach a
16431 // retry listener to the proimse. This flag is also used to hide the
16432 // primary children. In mutation mode, we also need the flag to
16433 // *unhide* children that were previously hidden, so check if the
16434 // is currently timed out, too.
16435 workInProgress.effectTag |= Update;
16436 }
16437 }
16438 if (
16439 enableSuspenseCallback &&
16440 workInProgress.updateQueue !== null &&
16441 workInProgress.memoizedProps.suspenseCallback != null
16442 ) {
16443 // Always notify the callback
16444 workInProgress.effectTag |= Update;
16445 }
16446 break;
16447 }
16448 case Fragment:
16449 break;
16450 case Mode:
16451 break;
16452 case Profiler:
16453 break;
16454 case HostPortal:
16455 popHostContainer(workInProgress);
16456 updateHostContainer(workInProgress);
16457 break;
16458 case ContextProvider:
16459 // Pop provider fiber
16460 popProvider(workInProgress);
16461 break;
16462 case ContextConsumer:
16463 break;
16464 case MemoComponent:
16465 break;
16466 case IncompleteClassComponent: {
16467 // Same as class component case. I put it down here so that the tags are
16468 // sequential to ensure this switch is compiled to a jump table.
16469 var _Component = workInProgress.type;
16470 if (isContextProvider(_Component)) {
16471 popContext(workInProgress);
16472 }
16473 break;
16474 }
16475 case DehydratedSuspenseComponent: {
16476 if (enableSuspenseServerRenderer) {
16477 popSuspenseContext(workInProgress);
16478 if (current === null) {
16479 var _wasHydrated2 = popHydrationState(workInProgress);
16480 (function() {
16481 if (!_wasHydrated2) {
16482 throw ReactError(
16483 Error(
16484 "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React."
16485 )
16486 );
16487 }
16488 })();
16489 if (enableSchedulerTracing) {
16490 markSpawnedWork(Never);
16491 }
16492 skipPastDehydratedSuspenseInstance(workInProgress);
16493 } else {
16494 // We should never have been in a hydration state if we didn't have a current.
16495 // However, in some of those paths, we might have reentered a hydration state
16496 // and then we might be inside a hydration state. In that case, we'll need to
16497 // exit out of it.
16498 resetHydrationState();
16499 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
16500 // This boundary did not suspend so it's now hydrated.
16501 // To handle any future suspense cases, we're going to now upgrade it
16502 // to a Suspense component. We detach it from the existing current fiber.
16503 current.alternate = null;
16504 workInProgress.alternate = null;
16505 workInProgress.tag = SuspenseComponent;
16506 workInProgress.memoizedState = null;
16507 workInProgress.stateNode = null;
16508 }
16509 }
16510 }
16511 break;
16512 }
16513 case SuspenseListComponent: {
16514 popSuspenseContext(workInProgress);
16515
16516 var renderState = workInProgress.memoizedState;
16517
16518 if (renderState === null) {
16519 // We're running in the default, "independent" mode. We don't do anything
16520 // in this mode.
16521 break;
16522 }
16523
16524 var didSuspendAlready =
16525 (workInProgress.effectTag & DidCapture) !== NoEffect;
16526
16527 var renderedTail = renderState.rendering;
16528 if (renderedTail === null) {
16529 // We just rendered the head.
16530 if (!didSuspendAlready) {
16531 // This is the first pass. We need to figure out if anything is still
16532 // suspended in the rendered set.
16533
16534 // If new content unsuspended, but there's still some content that
16535 // didn't. Then we need to do a second pass that forces everything
16536 // to keep showing their fallbacks.
16537
16538 // We might be suspended if something in this render pass suspended, or
16539 // something in the previous committed pass suspended. Otherwise,
16540 // there's no chance so we can skip the expensive call to
16541 // findFirstSuspended.
16542 var cannotBeSuspended =
16543 renderHasNotSuspendedYet() &&
16544 (current === null || (current.effectTag & DidCapture) === NoEffect);
16545 if (!cannotBeSuspended) {
16546 var row = workInProgress.child;
16547 while (row !== null) {
16548 var suspended = findFirstSuspended(row);
16549 if (suspended !== null) {
16550 didSuspendAlready = true;
16551 workInProgress.effectTag |= DidCapture;
16552 cutOffTailIfNeeded(renderState, false);
16553
16554 // If this is a newly suspended tree, it might not get committed as
16555 // part of the second pass. In that case nothing will subscribe to
16556 // its thennables. Instead, we'll transfer its thennables to the
16557 // SuspenseList so that it can retry if they resolve.
16558 // There might be multiple of these in the list but since we're
16559 // going to wait for all of them anyway, it doesn't really matter
16560 // which ones gets to ping. In theory we could get clever and keep
16561 // track of how many dependencies remain but it gets tricky because
16562 // in the meantime, we can add/remove/change items and dependencies.
16563 // We might bail out of the loop before finding any but that
16564 // doesn't matter since that means that the other boundaries that
16565 // we did find already has their listeners attached.
16566 var newThennables = suspended.updateQueue;
16567 if (newThennables !== null) {
16568 workInProgress.updateQueue = newThennables;
16569 workInProgress.effectTag |= Update;
16570 }
16571
16572 // Rerender the whole list, but this time, we'll force fallbacks
16573 // to stay in place.
16574 // Reset the effect list before doing the second pass since that's now invalid.
16575 workInProgress.firstEffect = workInProgress.lastEffect = null;
16576 // Reset the child fibers to their original state.
16577 resetChildFibers(workInProgress, renderExpirationTime);
16578
16579 // Set up the Suspense Context to force suspense and immediately
16580 // rerender the children.
16581 pushSuspenseContext(
16582 workInProgress,
16583 setShallowSuspenseContext(
16584 suspenseStackCursor.current,
16585 ForceSuspenseFallback
16586 )
16587 );
16588 return workInProgress.child;
16589 }
16590 row = row.sibling;
16591 }
16592 }
16593 } else {
16594 cutOffTailIfNeeded(renderState, false);
16595 }
16596 // Next we're going to render the tail.
16597 } else {
16598 // Append the rendered row to the child list.
16599 if (!didSuspendAlready) {
16600 var _suspended = findFirstSuspended(renderedTail);
16601 if (_suspended !== null) {
16602 workInProgress.effectTag |= DidCapture;
16603 didSuspendAlready = true;
16604 cutOffTailIfNeeded(renderState, true);
16605 // This might have been modified.
16606 if (
16607 renderState.tail === null &&
16608 renderState.tailMode === "hidden"
16609 ) {
16610 // We need to delete the row we just rendered.
16611 // Ensure we transfer the update queue to the parent.
16612 var _newThennables = _suspended.updateQueue;
16613 if (_newThennables !== null) {
16614 workInProgress.updateQueue = _newThennables;
16615 workInProgress.effectTag |= Update;
16616 }
16617 // Reset the effect list to what it w as before we rendered this
16618 // child. The nested children have already appended themselves.
16619 var lastEffect = (workInProgress.lastEffect =
16620 renderState.lastEffect);
16621 // Remove any effects that were appended after this point.
16622 if (lastEffect !== null) {
16623 lastEffect.nextEffect = null;
16624 }
16625 // We're done.
16626 return null;
16627 }
16628 } else if (
16629 now() > renderState.tailExpiration &&
16630 renderExpirationTime > Never
16631 ) {
16632 // We have now passed our CPU deadline and we'll just give up further
16633 // attempts to render the main content and only render fallbacks.
16634 // The assumption is that this is usually faster.
16635 workInProgress.effectTag |= DidCapture;
16636 didSuspendAlready = true;
16637
16638 cutOffTailIfNeeded(renderState, false);
16639
16640 // Since nothing actually suspended, there will nothing to ping this
16641 // to get it started back up to attempt the next item. If we can show
16642 // them, then they really have the same priority as this render.
16643 // So we'll pick it back up the very next render pass once we've had
16644 // an opportunity to yield for paint.
16645
16646 var nextPriority = renderExpirationTime - 1;
16647 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
16648 if (enableSchedulerTracing) {
16649 markSpawnedWork(nextPriority);
16650 }
16651 }
16652 }
16653 if (renderState.isBackwards) {
16654 // The effect list of the backwards tail will have been added
16655 // to the end. This breaks the guarantee that life-cycles fire in
16656 // sibling order but that isn't a strong guarantee promised by React.
16657 // Especially since these might also just pop in during future commits.
16658 // Append to the beginning of the list.
16659 renderedTail.sibling = workInProgress.child;
16660 workInProgress.child = renderedTail;
16661 } else {
16662 var previousSibling = renderState.last;
16663 if (previousSibling !== null) {
16664 previousSibling.sibling = renderedTail;
16665 } else {
16666 workInProgress.child = renderedTail;
16667 }
16668 renderState.last = renderedTail;
16669 }
16670 }
16671
16672 if (renderState.tail !== null) {
16673 // We still have tail rows to render.
16674 if (renderState.tailExpiration === 0) {
16675 // Heuristic for how long we're willing to spend rendering rows
16676 // until we just give up and show what we have so far.
16677 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
16678 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
16679 }
16680 // Pop a row.
16681 var next = renderState.tail;
16682 renderState.rendering = next;
16683 renderState.tail = next.sibling;
16684 renderState.lastEffect = workInProgress.lastEffect;
16685 next.sibling = null;
16686
16687 // Restore the context.
16688 // TODO: We can probably just avoid popping it instead and only
16689 // setting it the first time we go from not suspended to suspended.
16690 var suspenseContext = suspenseStackCursor.current;
16691 if (didSuspendAlready) {
16692 suspenseContext = setShallowSuspenseContext(
16693 suspenseContext,
16694 ForceSuspenseFallback
16695 );
16696 } else {
16697 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
16698 }
16699 pushSuspenseContext(workInProgress, suspenseContext);
16700 // Do a pass over the next row.
16701 return next;
16702 }
16703 break;
16704 }
16705 case FundamentalComponent: {
16706 if (enableFundamentalAPI) {
16707 var fundamentalImpl = workInProgress.type.impl;
16708 var fundamentalInstance = workInProgress.stateNode;
16709
16710 if (fundamentalInstance === null) {
16711 var getInitialState = fundamentalImpl.getInitialState;
16712 var fundamentalState = void 0;
16713 if (getInitialState !== undefined) {
16714 fundamentalState = getInitialState(newProps);
16715 }
16716 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(
16717 workInProgress,
16718 newProps,
16719 fundamentalImpl,
16720 fundamentalState || {}
16721 );
16722 var _instance7 = getFundamentalComponentInstance(fundamentalInstance);
16723 fundamentalInstance.instance = _instance7;
16724 if (fundamentalImpl.reconcileChildren === false) {
16725 return null;
16726 }
16727 appendAllChildren(_instance7, workInProgress, false, false);
16728 mountFundamentalComponent(fundamentalInstance);
16729 } else {
16730 // We fire update in commit phase
16731 var prevProps = fundamentalInstance.props;
16732 fundamentalInstance.prevProps = prevProps;
16733 fundamentalInstance.props = newProps;
16734 fundamentalInstance.currentFiber = workInProgress;
16735 if (supportsPersistence) {
16736 var _instance8 = cloneFundamentalInstance(fundamentalInstance);
16737 fundamentalInstance.instance = _instance8;
16738 appendAllChildren(_instance8, workInProgress, false, false);
16739 }
16740 var shouldUpdate = shouldUpdateFundamentalComponent(
16741 fundamentalInstance
16742 );
16743 if (shouldUpdate) {
16744 markUpdate(workInProgress);
16745 }
16746 }
16747 }
16748 break;
16749 }
16750 default:
16751 (function() {
16752 {
16753 throw ReactError(
16754 Error(
16755 "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue."
16756 )
16757 );
16758 }
16759 })();
16760 }
16761
16762 return null;
16763}
16764
16765function mountEventResponder$1(
16766 responder,
16767 responderProps,
16768 instance,
16769 rootContainerInstance,
16770 fiber,
16771 respondersMap
16772) {
16773 var responderState = emptyObject$1;
16774 var getInitialState = responder.getInitialState;
16775 if (getInitialState !== null) {
16776 responderState = getInitialState(responderProps);
16777 }
16778 var responderInstance = createResponderInstance(
16779 responder,
16780 responderProps,
16781 responderState,
16782 instance,
16783 fiber
16784 );
16785 mountResponderInstance(
16786 responder,
16787 responderInstance,
16788 responderProps,
16789 responderState,
16790 instance,
16791 rootContainerInstance
16792 );
16793 respondersMap.set(responder, responderInstance);
16794}
16795
16796function updateEventListener(
16797 listener,
16798 fiber,
16799 visistedResponders,
16800 respondersMap,
16801 instance,
16802 rootContainerInstance
16803) {
16804 var responder = void 0;
16805 var props = void 0;
16806
16807 if (listener) {
16808 responder = listener.responder;
16809 props = listener.props;
16810 }
16811 (function() {
16812 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
16813 throw ReactError(
16814 Error(
16815 "An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponer()."
16816 )
16817 );
16818 }
16819 })();
16820 var listenerProps = props;
16821 if (visistedResponders.has(responder)) {
16822 // show warning
16823 {
16824 warning$1(
16825 false,
16826 'Duplicate event responder "%s" found in event listeners. ' +
16827 "Event listeners passed to elements cannot use the same event responder more than once.",
16828 responder.displayName
16829 );
16830 }
16831 return;
16832 }
16833 visistedResponders.add(responder);
16834 var responderInstance = respondersMap.get(responder);
16835
16836 if (responderInstance === undefined) {
16837 // Mount
16838 mountEventResponder$1(
16839 responder,
16840 listenerProps,
16841 instance,
16842 rootContainerInstance,
16843 fiber,
16844 respondersMap
16845 );
16846 } else {
16847 // Update
16848 responderInstance.props = listenerProps;
16849 responderInstance.fiber = fiber;
16850 }
16851}
16852
16853function updateEventListeners(
16854 listeners,
16855 instance,
16856 rootContainerInstance,
16857 fiber
16858) {
16859 var visistedResponders = new Set();
16860 var dependencies = fiber.dependencies;
16861 if (listeners != null) {
16862 if (dependencies === null) {
16863 dependencies = fiber.dependencies = {
16864 expirationTime: NoWork,
16865 firstContext: null,
16866 responders: new Map()
16867 };
16868 }
16869 var respondersMap = dependencies.responders;
16870 if (respondersMap === null) {
16871 respondersMap = new Map();
16872 }
16873 if (isArray$2(listeners)) {
16874 for (var i = 0, length = listeners.length; i < length; i++) {
16875 var listener = listeners[i];
16876 updateEventListener(
16877 listener,
16878 fiber,
16879 visistedResponders,
16880 respondersMap,
16881 instance,
16882 rootContainerInstance
16883 );
16884 }
16885 } else {
16886 updateEventListener(
16887 listeners,
16888 fiber,
16889 visistedResponders,
16890 respondersMap,
16891 instance,
16892 rootContainerInstance
16893 );
16894 }
16895 }
16896 if (dependencies !== null) {
16897 var _respondersMap = dependencies.responders;
16898 if (_respondersMap !== null) {
16899 // Unmount
16900 var mountedResponders = Array.from(_respondersMap.keys());
16901 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
16902 var mountedResponder = mountedResponders[_i];
16903 if (!visistedResponders.has(mountedResponder)) {
16904 var responderInstance = _respondersMap.get(mountedResponder);
16905 unmountResponderInstance(responderInstance);
16906 _respondersMap.delete(mountedResponder);
16907 }
16908 }
16909 }
16910 }
16911}
16912
16913function unwindWork(workInProgress, renderExpirationTime) {
16914 switch (workInProgress.tag) {
16915 case ClassComponent: {
16916 var Component = workInProgress.type;
16917 if (isContextProvider(Component)) {
16918 popContext(workInProgress);
16919 }
16920 var effectTag = workInProgress.effectTag;
16921 if (effectTag & ShouldCapture) {
16922 workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture;
16923 return workInProgress;
16924 }
16925 return null;
16926 }
16927 case HostRoot: {
16928 popHostContainer(workInProgress);
16929 popTopLevelContextObject(workInProgress);
16930 var _effectTag = workInProgress.effectTag;
16931 (function() {
16932 if (!((_effectTag & DidCapture) === NoEffect)) {
16933 throw ReactError(
16934 Error(
16935 "The root failed to unmount after an error. This is likely a bug in React. Please file an issue."
16936 )
16937 );
16938 }
16939 })();
16940 workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture;
16941 return workInProgress;
16942 }
16943 case HostComponent: {
16944 // TODO: popHydrationState
16945 popHostContext(workInProgress);
16946 return null;
16947 }
16948 case SuspenseComponent: {
16949 popSuspenseContext(workInProgress);
16950 var _effectTag2 = workInProgress.effectTag;
16951 if (_effectTag2 & ShouldCapture) {
16952 workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture;
16953 // Captured a suspense effect. Re-render the boundary.
16954 return workInProgress;
16955 }
16956 return null;
16957 }
16958 case DehydratedSuspenseComponent: {
16959 if (enableSuspenseServerRenderer) {
16960 popSuspenseContext(workInProgress);
16961 if (workInProgress.alternate === null) {
16962 // TODO: popHydrationState
16963 } else {
16964 resetHydrationState();
16965 }
16966 var _effectTag3 = workInProgress.effectTag;
16967 if (_effectTag3 & ShouldCapture) {
16968 workInProgress.effectTag =
16969 (_effectTag3 & ~ShouldCapture) | DidCapture;
16970 // Captured a suspense effect. Re-render the boundary.
16971 return workInProgress;
16972 }
16973 }
16974 return null;
16975 }
16976 case SuspenseListComponent: {
16977 popSuspenseContext(workInProgress);
16978 // SuspenseList doesn't actually catch anything. It should've been
16979 // caught by a nested boundary. If not, it should bubble through.
16980 return null;
16981 }
16982 case HostPortal:
16983 popHostContainer(workInProgress);
16984 return null;
16985 case ContextProvider:
16986 popProvider(workInProgress);
16987 return null;
16988 default:
16989 return null;
16990 }
16991}
16992
16993function unwindInterruptedWork(interruptedWork) {
16994 switch (interruptedWork.tag) {
16995 case ClassComponent: {
16996 var childContextTypes = interruptedWork.type.childContextTypes;
16997 if (childContextTypes !== null && childContextTypes !== undefined) {
16998 popContext(interruptedWork);
16999 }
17000 break;
17001 }
17002 case HostRoot: {
17003 popHostContainer(interruptedWork);
17004 popTopLevelContextObject(interruptedWork);
17005 break;
17006 }
17007 case HostComponent: {
17008 popHostContext(interruptedWork);
17009 break;
17010 }
17011 case HostPortal:
17012 popHostContainer(interruptedWork);
17013 break;
17014 case SuspenseComponent:
17015 popSuspenseContext(interruptedWork);
17016 break;
17017 case DehydratedSuspenseComponent:
17018 if (enableSuspenseServerRenderer) {
17019 popSuspenseContext(interruptedWork);
17020 }
17021 break;
17022 case SuspenseListComponent:
17023 popSuspenseContext(interruptedWork);
17024 break;
17025 case ContextProvider:
17026 popProvider(interruptedWork);
17027 break;
17028 default:
17029 break;
17030 }
17031}
17032
17033function createCapturedValue(value, source) {
17034 // If the value is an error, call this function immediately after it is thrown
17035 // so the stack is accurate.
17036 return {
17037 value: value,
17038 source: source,
17039 stack: getStackByFiberInDevAndProd(source)
17040 };
17041}
17042
17043// Module provided by RN:
17044(function() {
17045 if (
17046 !(
17047 typeof ReactNativePrivateInterface.ReactFiberErrorDialog
17048 .showErrorDialog === "function"
17049 )
17050 ) {
17051 throw ReactError(
17052 Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.")
17053 );
17054 }
17055})();
17056
17057function showErrorDialog(capturedError) {
17058 return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog(
17059 capturedError
17060 );
17061}
17062
17063function logCapturedError(capturedError) {
17064 var logError = showErrorDialog(capturedError);
17065
17066 // Allow injected showErrorDialog() to prevent default console.error logging.
17067 // This enables renderers like ReactNative to better manage redbox behavior.
17068 if (logError === false) {
17069 return;
17070 }
17071
17072 var error = capturedError.error;
17073 {
17074 var componentName = capturedError.componentName,
17075 componentStack = capturedError.componentStack,
17076 errorBoundaryName = capturedError.errorBoundaryName,
17077 errorBoundaryFound = capturedError.errorBoundaryFound,
17078 willRetry = capturedError.willRetry;
17079
17080 // Browsers support silencing uncaught errors by calling
17081 // `preventDefault()` in window `error` handler.
17082 // We record this information as an expando on the error.
17083
17084 if (error != null && error._suppressLogging) {
17085 if (errorBoundaryFound && willRetry) {
17086 // The error is recoverable and was silenced.
17087 // Ignore it and don't print the stack addendum.
17088 // This is handy for testing error boundaries without noise.
17089 return;
17090 }
17091 // The error is fatal. Since the silencing might have
17092 // been accidental, we'll surface it anyway.
17093 // However, the browser would have silenced the original error
17094 // so we'll print it first, and then print the stack addendum.
17095 console.error(error);
17096 // For a more detailed description of this block, see:
17097 // https://github.com/facebook/react/pull/13384
17098 }
17099
17100 var componentNameMessage = componentName
17101 ? "The above error occurred in the <" + componentName + "> component:"
17102 : "The above error occurred in one of your React components:";
17103
17104 var errorBoundaryMessage = void 0;
17105 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
17106 if (errorBoundaryFound && errorBoundaryName) {
17107 if (willRetry) {
17108 errorBoundaryMessage =
17109 "React will try to recreate this component tree from scratch " +
17110 ("using the error boundary you provided, " + errorBoundaryName + ".");
17111 } else {
17112 errorBoundaryMessage =
17113 "This error was initially handled by the error boundary " +
17114 errorBoundaryName +
17115 ".\n" +
17116 "Recreating the tree from scratch failed so React will unmount the tree.";
17117 }
17118 } else {
17119 errorBoundaryMessage =
17120 "Consider adding an error boundary to your tree to customize error handling behavior.\n" +
17121 "Visit https://fb.me/react-error-boundaries to learn more about error boundaries.";
17122 }
17123 var combinedMessage =
17124 "" +
17125 componentNameMessage +
17126 componentStack +
17127 "\n\n" +
17128 ("" + errorBoundaryMessage);
17129
17130 // In development, we provide our own message with just the component stack.
17131 // We don't include the original error message and JS stack because the browser
17132 // has already printed it. Even if the application swallows the error, it is still
17133 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
17134 console.error(combinedMessage);
17135 }
17136}
17137
17138var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
17139{
17140 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
17141}
17142
17143var PossiblyWeakSet$1 = typeof WeakSet === "function" ? WeakSet : Set;
17144
17145function logError(boundary, errorInfo) {
17146 var source = errorInfo.source;
17147 var stack = errorInfo.stack;
17148 if (stack === null && source !== null) {
17149 stack = getStackByFiberInDevAndProd(source);
17150 }
17151
17152 var capturedError = {
17153 componentName: source !== null ? getComponentName(source.type) : null,
17154 componentStack: stack !== null ? stack : "",
17155 error: errorInfo.value,
17156 errorBoundary: null,
17157 errorBoundaryName: null,
17158 errorBoundaryFound: false,
17159 willRetry: false
17160 };
17161
17162 if (boundary !== null && boundary.tag === ClassComponent) {
17163 capturedError.errorBoundary = boundary.stateNode;
17164 capturedError.errorBoundaryName = getComponentName(boundary.type);
17165 capturedError.errorBoundaryFound = true;
17166 capturedError.willRetry = true;
17167 }
17168
17169 try {
17170 logCapturedError(capturedError);
17171 } catch (e) {
17172 // This method must not throw, or React internal state will get messed up.
17173 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
17174 // we want to report this error outside of the normal stack as a last resort.
17175 // https://github.com/facebook/react/issues/13188
17176 setTimeout(function() {
17177 throw e;
17178 });
17179 }
17180}
17181
17182var callComponentWillUnmountWithTimer = function(current$$1, instance) {
17183 startPhaseTimer(current$$1, "componentWillUnmount");
17184 instance.props = current$$1.memoizedProps;
17185 instance.state = current$$1.memoizedState;
17186 instance.componentWillUnmount();
17187 stopPhaseTimer();
17188};
17189
17190// Capture errors so they don't interrupt unmounting.
17191function safelyCallComponentWillUnmount(current$$1, instance) {
17192 {
17193 invokeGuardedCallback(
17194 null,
17195 callComponentWillUnmountWithTimer,
17196 null,
17197 current$$1,
17198 instance
17199 );
17200 if (hasCaughtError()) {
17201 var unmountError = clearCaughtError();
17202 captureCommitPhaseError(current$$1, unmountError);
17203 }
17204 }
17205}
17206
17207function safelyDetachRef(current$$1) {
17208 var ref = current$$1.ref;
17209 if (ref !== null) {
17210 if (typeof ref === "function") {
17211 {
17212 invokeGuardedCallback(null, ref, null, null);
17213 if (hasCaughtError()) {
17214 var refError = clearCaughtError();
17215 captureCommitPhaseError(current$$1, refError);
17216 }
17217 }
17218 } else {
17219 ref.current = null;
17220 }
17221 }
17222}
17223
17224function safelyCallDestroy(current$$1, destroy) {
17225 {
17226 invokeGuardedCallback(null, destroy, null);
17227 if (hasCaughtError()) {
17228 var error = clearCaughtError();
17229 captureCommitPhaseError(current$$1, error);
17230 }
17231 }
17232}
17233
17234function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
17235 switch (finishedWork.tag) {
17236 case FunctionComponent:
17237 case ForwardRef:
17238 case SimpleMemoComponent: {
17239 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
17240 return;
17241 }
17242 case ClassComponent: {
17243 if (finishedWork.effectTag & Snapshot) {
17244 if (current$$1 !== null) {
17245 var prevProps = current$$1.memoizedProps;
17246 var prevState = current$$1.memoizedState;
17247 startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate");
17248 var instance = finishedWork.stateNode;
17249 // We could update instance props and state here,
17250 // but instead we rely on them being set during last render.
17251 // TODO: revisit this when we implement resuming.
17252 {
17253 if (
17254 finishedWork.type === finishedWork.elementType &&
17255 !didWarnAboutReassigningProps
17256 ) {
17257 !(instance.props === finishedWork.memoizedProps)
17258 ? warning$1(
17259 false,
17260 "Expected %s props to match memoized props before " +
17261 "getSnapshotBeforeUpdate. " +
17262 "This might either be because of a bug in React, or because " +
17263 "a component reassigns its own `this.props`. " +
17264 "Please file an issue.",
17265 getComponentName(finishedWork.type) || "instance"
17266 )
17267 : void 0;
17268 !(instance.state === finishedWork.memoizedState)
17269 ? warning$1(
17270 false,
17271 "Expected %s state to match memoized state before " +
17272 "getSnapshotBeforeUpdate. " +
17273 "This might either be because of a bug in React, or because " +
17274 "a component reassigns its own `this.props`. " +
17275 "Please file an issue.",
17276 getComponentName(finishedWork.type) || "instance"
17277 )
17278 : void 0;
17279 }
17280 }
17281 var snapshot = instance.getSnapshotBeforeUpdate(
17282 finishedWork.elementType === finishedWork.type
17283 ? prevProps
17284 : resolveDefaultProps(finishedWork.type, prevProps),
17285 prevState
17286 );
17287 {
17288 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
17289 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
17290 didWarnSet.add(finishedWork.type);
17291 warningWithoutStack$1(
17292 false,
17293 "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " +
17294 "must be returned. You have returned undefined.",
17295 getComponentName(finishedWork.type)
17296 );
17297 }
17298 }
17299 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
17300 stopPhaseTimer();
17301 }
17302 }
17303 return;
17304 }
17305 case HostRoot:
17306 case HostComponent:
17307 case HostText:
17308 case HostPortal:
17309 case IncompleteClassComponent:
17310 // Nothing to do for these component types
17311 return;
17312 default: {
17313 (function() {
17314 {
17315 throw ReactError(
17316 Error(
17317 "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."
17318 )
17319 );
17320 }
17321 })();
17322 }
17323 }
17324}
17325
17326function commitHookEffectList(unmountTag, mountTag, finishedWork) {
17327 var updateQueue = finishedWork.updateQueue;
17328 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
17329 if (lastEffect !== null) {
17330 var firstEffect = lastEffect.next;
17331 var effect = firstEffect;
17332 do {
17333 if ((effect.tag & unmountTag) !== NoEffect$1) {
17334 // Unmount
17335 var destroy = effect.destroy;
17336 effect.destroy = undefined;
17337 if (destroy !== undefined) {
17338 destroy();
17339 }
17340 }
17341 if ((effect.tag & mountTag) !== NoEffect$1) {
17342 // Mount
17343 var create = effect.create;
17344 effect.destroy = create();
17345
17346 {
17347 var _destroy = effect.destroy;
17348 if (_destroy !== undefined && typeof _destroy !== "function") {
17349 var addendum = void 0;
17350 if (_destroy === null) {
17351 addendum =
17352 " You returned null. If your effect does not require clean " +
17353 "up, return undefined (or nothing).";
17354 } else if (typeof _destroy.then === "function") {
17355 addendum =
17356 "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " +
17357 "Instead, write the async function inside your effect " +
17358 "and call it immediately:\n\n" +
17359 "useEffect(() => {\n" +
17360 " async function fetchData() {\n" +
17361 " // You can await here\n" +
17362 " const response = await MyAPI.getData(someId);\n" +
17363 " // ...\n" +
17364 " }\n" +
17365 " fetchData();\n" +
17366 "}, [someId]); // Or [] if effect doesn't need props or state\n\n" +
17367 "Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching";
17368 } else {
17369 addendum = " You returned: " + _destroy;
17370 }
17371 warningWithoutStack$1(
17372 false,
17373 "An effect function must not return anything besides a function, " +
17374 "which is used for clean-up.%s%s",
17375 addendum,
17376 getStackByFiberInDevAndProd(finishedWork)
17377 );
17378 }
17379 }
17380 }
17381 effect = effect.next;
17382 } while (effect !== firstEffect);
17383 }
17384}
17385
17386function commitPassiveHookEffects(finishedWork) {
17387 if ((finishedWork.effectTag & Passive) !== NoEffect) {
17388 switch (finishedWork.tag) {
17389 case FunctionComponent:
17390 case ForwardRef:
17391 case SimpleMemoComponent: {
17392 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
17393 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
17394 break;
17395 }
17396 default:
17397 break;
17398 }
17399 }
17400}
17401
17402function commitLifeCycles(
17403 finishedRoot,
17404 current$$1,
17405 finishedWork,
17406 committedExpirationTime
17407) {
17408 switch (finishedWork.tag) {
17409 case FunctionComponent:
17410 case ForwardRef:
17411 case SimpleMemoComponent: {
17412 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
17413 break;
17414 }
17415 case ClassComponent: {
17416 var instance = finishedWork.stateNode;
17417 if (finishedWork.effectTag & Update) {
17418 if (current$$1 === null) {
17419 startPhaseTimer(finishedWork, "componentDidMount");
17420 // We could update instance props and state here,
17421 // but instead we rely on them being set during last render.
17422 // TODO: revisit this when we implement resuming.
17423 {
17424 if (
17425 finishedWork.type === finishedWork.elementType &&
17426 !didWarnAboutReassigningProps
17427 ) {
17428 !(instance.props === finishedWork.memoizedProps)
17429 ? warning$1(
17430 false,
17431 "Expected %s props to match memoized props before " +
17432 "componentDidMount. " +
17433 "This might either be because of a bug in React, or because " +
17434 "a component reassigns its own `this.props`. " +
17435 "Please file an issue.",
17436 getComponentName(finishedWork.type) || "instance"
17437 )
17438 : void 0;
17439 !(instance.state === finishedWork.memoizedState)
17440 ? warning$1(
17441 false,
17442 "Expected %s state to match memoized state before " +
17443 "componentDidMount. " +
17444 "This might either be because of a bug in React, or because " +
17445 "a component reassigns its own `this.props`. " +
17446 "Please file an issue.",
17447 getComponentName(finishedWork.type) || "instance"
17448 )
17449 : void 0;
17450 }
17451 }
17452 instance.componentDidMount();
17453 stopPhaseTimer();
17454 } else {
17455 var prevProps =
17456 finishedWork.elementType === finishedWork.type
17457 ? current$$1.memoizedProps
17458 : resolveDefaultProps(
17459 finishedWork.type,
17460 current$$1.memoizedProps
17461 );
17462 var prevState = current$$1.memoizedState;
17463 startPhaseTimer(finishedWork, "componentDidUpdate");
17464 // We could update instance props and state here,
17465 // but instead we rely on them being set during last render.
17466 // TODO: revisit this when we implement resuming.
17467 {
17468 if (
17469 finishedWork.type === finishedWork.elementType &&
17470 !didWarnAboutReassigningProps
17471 ) {
17472 !(instance.props === finishedWork.memoizedProps)
17473 ? warning$1(
17474 false,
17475 "Expected %s props to match memoized props before " +
17476 "componentDidUpdate. " +
17477 "This might either be because of a bug in React, or because " +
17478 "a component reassigns its own `this.props`. " +
17479 "Please file an issue.",
17480 getComponentName(finishedWork.type) || "instance"
17481 )
17482 : void 0;
17483 !(instance.state === finishedWork.memoizedState)
17484 ? warning$1(
17485 false,
17486 "Expected %s state to match memoized state before " +
17487 "componentDidUpdate. " +
17488 "This might either be because of a bug in React, or because " +
17489 "a component reassigns its own `this.props`. " +
17490 "Please file an issue.",
17491 getComponentName(finishedWork.type) || "instance"
17492 )
17493 : void 0;
17494 }
17495 }
17496 instance.componentDidUpdate(
17497 prevProps,
17498 prevState,
17499 instance.__reactInternalSnapshotBeforeUpdate
17500 );
17501 stopPhaseTimer();
17502 }
17503 }
17504 var updateQueue = finishedWork.updateQueue;
17505 if (updateQueue !== null) {
17506 {
17507 if (
17508 finishedWork.type === finishedWork.elementType &&
17509 !didWarnAboutReassigningProps
17510 ) {
17511 !(instance.props === finishedWork.memoizedProps)
17512 ? warning$1(
17513 false,
17514 "Expected %s props to match memoized props before " +
17515 "processing the update queue. " +
17516 "This might either be because of a bug in React, or because " +
17517 "a component reassigns its own `this.props`. " +
17518 "Please file an issue.",
17519 getComponentName(finishedWork.type) || "instance"
17520 )
17521 : void 0;
17522 !(instance.state === finishedWork.memoizedState)
17523 ? warning$1(
17524 false,
17525 "Expected %s state to match memoized state before " +
17526 "processing the update queue. " +
17527 "This might either be because of a bug in React, or because " +
17528 "a component reassigns its own `this.props`. " +
17529 "Please file an issue.",
17530 getComponentName(finishedWork.type) || "instance"
17531 )
17532 : void 0;
17533 }
17534 }
17535 // We could update instance props and state here,
17536 // but instead we rely on them being set during last render.
17537 // TODO: revisit this when we implement resuming.
17538 commitUpdateQueue(
17539 finishedWork,
17540 updateQueue,
17541 instance,
17542 committedExpirationTime
17543 );
17544 }
17545 return;
17546 }
17547 case HostRoot: {
17548 var _updateQueue = finishedWork.updateQueue;
17549 if (_updateQueue !== null) {
17550 var _instance = null;
17551 if (finishedWork.child !== null) {
17552 switch (finishedWork.child.tag) {
17553 case HostComponent:
17554 _instance = getPublicInstance(finishedWork.child.stateNode);
17555 break;
17556 case ClassComponent:
17557 _instance = finishedWork.child.stateNode;
17558 break;
17559 }
17560 }
17561 commitUpdateQueue(
17562 finishedWork,
17563 _updateQueue,
17564 _instance,
17565 committedExpirationTime
17566 );
17567 }
17568 return;
17569 }
17570 case HostComponent: {
17571 var _instance2 = finishedWork.stateNode;
17572
17573 // Renderers may schedule work to be done after host components are mounted
17574 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
17575 // These effects should only be committed when components are first mounted,
17576 // aka when there is no current/alternate.
17577 if (current$$1 === null && finishedWork.effectTag & Update) {
17578 var type = finishedWork.type;
17579 var props = finishedWork.memoizedProps;
17580 commitMount(_instance2, type, props, finishedWork);
17581 }
17582
17583 return;
17584 }
17585 case HostText: {
17586 // We have no life-cycles associated with text.
17587 return;
17588 }
17589 case HostPortal: {
17590 // We have no life-cycles associated with portals.
17591 return;
17592 }
17593 case Profiler: {
17594 if (enableProfilerTimer) {
17595 var onRender = finishedWork.memoizedProps.onRender;
17596
17597 if (typeof onRender === "function") {
17598 if (enableSchedulerTracing) {
17599 onRender(
17600 finishedWork.memoizedProps.id,
17601 current$$1 === null ? "mount" : "update",
17602 finishedWork.actualDuration,
17603 finishedWork.treeBaseDuration,
17604 finishedWork.actualStartTime,
17605 getCommitTime(),
17606 finishedRoot.memoizedInteractions
17607 );
17608 } else {
17609 onRender(
17610 finishedWork.memoizedProps.id,
17611 current$$1 === null ? "mount" : "update",
17612 finishedWork.actualDuration,
17613 finishedWork.treeBaseDuration,
17614 finishedWork.actualStartTime,
17615 getCommitTime()
17616 );
17617 }
17618 }
17619 }
17620 return;
17621 }
17622 case SuspenseComponent:
17623 case SuspenseListComponent:
17624 case IncompleteClassComponent:
17625 case FundamentalComponent:
17626 return;
17627 default: {
17628 (function() {
17629 {
17630 throw ReactError(
17631 Error(
17632 "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."
17633 )
17634 );
17635 }
17636 })();
17637 }
17638 }
17639}
17640
17641function hideOrUnhideAllChildren(finishedWork, isHidden) {
17642 if (supportsMutation) {
17643 // We only have the top Fiber that was inserted but we need to recurse down its
17644 var node = finishedWork;
17645 while (true) {
17646 if (node.tag === HostComponent) {
17647 var instance = node.stateNode;
17648 if (isHidden) {
17649 hideInstance(instance);
17650 } else {
17651 unhideInstance(node.stateNode, node.memoizedProps);
17652 }
17653 } else if (node.tag === HostText) {
17654 var _instance3 = node.stateNode;
17655 if (isHidden) {
17656 hideTextInstance(_instance3);
17657 } else {
17658 unhideTextInstance(_instance3, node.memoizedProps);
17659 }
17660 } else if (
17661 node.tag === SuspenseComponent &&
17662 node.memoizedState !== null
17663 ) {
17664 // Found a nested Suspense component that timed out. Skip over the
17665 var fallbackChildFragment = node.child.sibling;
17666 fallbackChildFragment.return = node;
17667 node = fallbackChildFragment;
17668 continue;
17669 } else if (node.child !== null) {
17670 node.child.return = node;
17671 node = node.child;
17672 continue;
17673 }
17674 if (node === finishedWork) {
17675 return;
17676 }
17677 while (node.sibling === null) {
17678 if (node.return === null || node.return === finishedWork) {
17679 return;
17680 }
17681 node = node.return;
17682 }
17683 node.sibling.return = node.return;
17684 node = node.sibling;
17685 }
17686 }
17687}
17688
17689function commitAttachRef(finishedWork) {
17690 var ref = finishedWork.ref;
17691 if (ref !== null) {
17692 var instance = finishedWork.stateNode;
17693 var instanceToUse = void 0;
17694 switch (finishedWork.tag) {
17695 case HostComponent:
17696 instanceToUse = getPublicInstance(instance);
17697 break;
17698 default:
17699 instanceToUse = instance;
17700 }
17701 if (typeof ref === "function") {
17702 ref(instanceToUse);
17703 } else {
17704 {
17705 if (!ref.hasOwnProperty("current")) {
17706 warningWithoutStack$1(
17707 false,
17708 "Unexpected ref object provided for %s. " +
17709 "Use either a ref-setter function or React.createRef().%s",
17710 getComponentName(finishedWork.type),
17711 getStackByFiberInDevAndProd(finishedWork)
17712 );
17713 }
17714 }
17715
17716 ref.current = instanceToUse;
17717 }
17718 }
17719}
17720
17721function commitDetachRef(current$$1) {
17722 var currentRef = current$$1.ref;
17723 if (currentRef !== null) {
17724 if (typeof currentRef === "function") {
17725 currentRef(null);
17726 } else {
17727 currentRef.current = null;
17728 }
17729 }
17730}
17731
17732// User-originating errors (lifecycles and refs) should not interrupt
17733// deletion, so don't let them throw. Host-originating errors should
17734// interrupt deletion, so it's okay
17735function commitUnmount(current$$1, renderPriorityLevel) {
17736 onCommitUnmount(current$$1);
17737
17738 switch (current$$1.tag) {
17739 case FunctionComponent:
17740 case ForwardRef:
17741 case MemoComponent:
17742 case SimpleMemoComponent: {
17743 var updateQueue = current$$1.updateQueue;
17744 if (updateQueue !== null) {
17745 var lastEffect = updateQueue.lastEffect;
17746 if (lastEffect !== null) {
17747 var firstEffect = lastEffect.next;
17748
17749 // When the owner fiber is deleted, the destroy function of a passive
17750 // effect hook is called during the synchronous commit phase. This is
17751 // a concession to implementation complexity. Calling it in the
17752 // passive effect phase (like they usually are, when dependencies
17753 // change during an update) would require either traversing the
17754 // children of the deleted fiber again, or including unmount effects
17755 // as part of the fiber effect list.
17756 //
17757 // Because this is during the sync commit phase, we need to change
17758 // the priority.
17759 //
17760 // TODO: Reconsider this implementation trade off.
17761 var priorityLevel =
17762 renderPriorityLevel > NormalPriority
17763 ? NormalPriority
17764 : renderPriorityLevel;
17765 runWithPriority$1(priorityLevel, function() {
17766 var effect = firstEffect;
17767 do {
17768 var destroy = effect.destroy;
17769 if (destroy !== undefined) {
17770 safelyCallDestroy(current$$1, destroy);
17771 }
17772 effect = effect.next;
17773 } while (effect !== firstEffect);
17774 });
17775 }
17776 }
17777 break;
17778 }
17779 case ClassComponent: {
17780 safelyDetachRef(current$$1);
17781 var instance = current$$1.stateNode;
17782 if (typeof instance.componentWillUnmount === "function") {
17783 safelyCallComponentWillUnmount(current$$1, instance);
17784 }
17785 return;
17786 }
17787 case HostComponent: {
17788 if (enableFlareAPI) {
17789 var dependencies = current$$1.dependencies;
17790
17791 if (dependencies !== null) {
17792 var respondersMap = dependencies.responders;
17793 if (respondersMap !== null) {
17794 var responderInstances = Array.from(respondersMap.values());
17795 for (
17796 var i = 0, length = responderInstances.length;
17797 i < length;
17798 i++
17799 ) {
17800 var responderInstance = responderInstances[i];
17801 unmountResponderInstance(responderInstance);
17802 }
17803 dependencies.responders = null;
17804 }
17805 }
17806 }
17807 safelyDetachRef(current$$1);
17808 return;
17809 }
17810 case HostPortal: {
17811 // TODO: this is recursive.
17812 // We are also not using this parent because
17813 // the portal will get pushed immediately.
17814 if (supportsMutation) {
17815 unmountHostComponents(current$$1, renderPriorityLevel);
17816 } else if (supportsPersistence) {
17817 emptyPortalContainer(current$$1);
17818 }
17819 return;
17820 }
17821 case FundamentalComponent: {
17822 if (enableFundamentalAPI) {
17823 var fundamentalInstance = current$$1.stateNode;
17824 if (fundamentalInstance !== null) {
17825 unmountFundamentalComponent(fundamentalInstance);
17826 current$$1.stateNode = null;
17827 }
17828 }
17829 }
17830 }
17831}
17832
17833function commitNestedUnmounts(root, renderPriorityLevel) {
17834 // While we're inside a removed host node we don't want to call
17835 // removeChild on the inner nodes because they're removed by the top
17836 // call anyway. We also want to call componentWillUnmount on all
17837 // composites before this host node is removed from the tree. Therefore
17838 var node = root;
17839 while (true) {
17840 commitUnmount(node, renderPriorityLevel);
17841 // Visit children because they may contain more composite or host nodes.
17842 // Skip portals because commitUnmount() currently visits them recursively.
17843 if (
17844 node.child !== null &&
17845 // If we use mutation we drill down into portals using commitUnmount above.
17846 // If we don't use mutation we drill down into portals here instead.
17847 (!supportsMutation || node.tag !== HostPortal)
17848 ) {
17849 node.child.return = node;
17850 node = node.child;
17851 continue;
17852 }
17853 if (node === root) {
17854 return;
17855 }
17856 while (node.sibling === null) {
17857 if (node.return === null || node.return === root) {
17858 return;
17859 }
17860 node = node.return;
17861 }
17862 node.sibling.return = node.return;
17863 node = node.sibling;
17864 }
17865}
17866
17867function detachFiber(current$$1) {
17868 var alternate = current$$1.alternate;
17869 // Cut off the return pointers to disconnect it from the tree. Ideally, we
17870 // should clear the child pointer of the parent alternate to let this
17871 // get GC:ed but we don't know which for sure which parent is the current
17872 // one so we'll settle for GC:ing the subtree of this child. This child
17873 // itself will be GC:ed when the parent updates the next time.
17874 current$$1.return = null;
17875 current$$1.child = null;
17876 current$$1.memoizedState = null;
17877 current$$1.updateQueue = null;
17878 current$$1.dependencies = null;
17879 current$$1.alternate = null;
17880 current$$1.firstEffect = null;
17881 current$$1.lastEffect = null;
17882 current$$1.pendingProps = null;
17883 current$$1.memoizedProps = null;
17884 if (alternate !== null) {
17885 detachFiber(alternate);
17886 }
17887}
17888
17889function emptyPortalContainer(current$$1) {
17890 if (!supportsPersistence) {
17891 return;
17892 }
17893
17894 var portal = current$$1.stateNode;
17895 var containerInfo = portal.containerInfo;
17896
17897 var emptyChildSet = createContainerChildSet(containerInfo);
17898}
17899
17900function commitContainer(finishedWork) {
17901 if (!supportsPersistence) {
17902 return;
17903 }
17904
17905 switch (finishedWork.tag) {
17906 case ClassComponent:
17907 case HostComponent:
17908 case HostText:
17909 case FundamentalComponent: {
17910 return;
17911 }
17912 case HostRoot:
17913 case HostPortal: {
17914 var portalOrRoot = finishedWork.stateNode;
17915 var containerInfo = portalOrRoot.containerInfo,
17916 _pendingChildren = portalOrRoot.pendingChildren;
17917
17918 return;
17919 }
17920 default: {
17921 (function() {
17922 {
17923 throw ReactError(
17924 Error(
17925 "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."
17926 )
17927 );
17928 }
17929 })();
17930 }
17931 }
17932}
17933
17934function getHostParentFiber(fiber) {
17935 var parent = fiber.return;
17936 while (parent !== null) {
17937 if (isHostParent(parent)) {
17938 return parent;
17939 }
17940 parent = parent.return;
17941 }
17942 (function() {
17943 {
17944 throw ReactError(
17945 Error(
17946 "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue."
17947 )
17948 );
17949 }
17950 })();
17951}
17952
17953function isHostParent(fiber) {
17954 return (
17955 fiber.tag === HostComponent ||
17956 fiber.tag === HostRoot ||
17957 fiber.tag === HostPortal
17958 );
17959}
17960
17961function getHostSibling(fiber) {
17962 // We're going to search forward into the tree until we find a sibling host
17963 // node. Unfortunately, if multiple insertions are done in a row we have to
17964 // search past them. This leads to exponential search for the next sibling.
17965 var node = fiber;
17966 siblings: while (true) {
17967 // If we didn't find anything, let's try the next sibling.
17968 while (node.sibling === null) {
17969 if (node.return === null || isHostParent(node.return)) {
17970 // If we pop out of the root or hit the parent the fiber we are the
17971 // last sibling.
17972 return null;
17973 }
17974 node = node.return;
17975 }
17976 node.sibling.return = node.return;
17977 node = node.sibling;
17978 while (
17979 node.tag !== HostComponent &&
17980 node.tag !== HostText &&
17981 node.tag !== DehydratedSuspenseComponent
17982 ) {
17983 // If it is not host node and, we might have a host node inside it.
17984 // Try to search down until we find one.
17985 if (node.effectTag & Placement) {
17986 // If we don't have a child, try the siblings instead.
17987 continue siblings;
17988 }
17989 // If we don't have a child, try the siblings instead.
17990 // We also skip portals because they are not part of this host tree.
17991 if (node.child === null || node.tag === HostPortal) {
17992 continue siblings;
17993 } else {
17994 node.child.return = node;
17995 node = node.child;
17996 }
17997 }
17998 // Check if this host node is stable or about to be placed.
17999 if (!(node.effectTag & Placement)) {
18000 // Found it!
18001 return node.stateNode;
18002 }
18003 }
18004}
18005
18006function commitPlacement(finishedWork) {
18007 if (!supportsMutation) {
18008 return;
18009 }
18010
18011 // Recursively insert all host nodes into the parent.
18012 var parentFiber = getHostParentFiber(finishedWork);
18013
18014 // Note: these two variables *must* always be updated together.
18015 var parent = void 0;
18016 var isContainer = void 0;
18017 var parentStateNode = parentFiber.stateNode;
18018 switch (parentFiber.tag) {
18019 case HostComponent:
18020 parent = parentStateNode;
18021 isContainer = false;
18022 break;
18023 case HostRoot:
18024 parent = parentStateNode.containerInfo;
18025 isContainer = true;
18026 break;
18027 case HostPortal:
18028 parent = parentStateNode.containerInfo;
18029 isContainer = true;
18030 break;
18031 case FundamentalComponent:
18032 if (enableFundamentalAPI) {
18033 parent = parentStateNode.instance;
18034 isContainer = false;
18035 }
18036 // eslint-disable-next-line-no-fallthrough
18037 default:
18038 (function() {
18039 {
18040 throw ReactError(
18041 Error(
18042 "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue."
18043 )
18044 );
18045 }
18046 })();
18047 }
18048 if (parentFiber.effectTag & ContentReset) {
18049 // Reset the text content of the parent before doing any insertions
18050 resetTextContent(parent);
18051 // Clear ContentReset from the effect tag
18052 parentFiber.effectTag &= ~ContentReset;
18053 }
18054
18055 var before = getHostSibling(finishedWork);
18056 // We only have the top Fiber that was inserted but we need to recurse down its
18057 // children to find all the terminal nodes.
18058 var node = finishedWork;
18059 while (true) {
18060 var isHost = node.tag === HostComponent || node.tag === HostText;
18061 if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) {
18062 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
18063 if (before) {
18064 if (isContainer) {
18065 insertInContainerBefore(parent, stateNode, before);
18066 } else {
18067 insertBefore(parent, stateNode, before);
18068 }
18069 } else {
18070 if (isContainer) {
18071 appendChildToContainer(parent, stateNode);
18072 } else {
18073 appendChild(parent, stateNode);
18074 }
18075 }
18076 } else if (node.tag === HostPortal) {
18077 // If the insertion itself is a portal, then we don't want to traverse
18078 // down its children. Instead, we'll get insertions from each child in
18079 // the portal directly.
18080 } else if (node.child !== null) {
18081 node.child.return = node;
18082 node = node.child;
18083 continue;
18084 }
18085 if (node === finishedWork) {
18086 return;
18087 }
18088 while (node.sibling === null) {
18089 if (node.return === null || node.return === finishedWork) {
18090 return;
18091 }
18092 node = node.return;
18093 }
18094 node.sibling.return = node.return;
18095 node = node.sibling;
18096 }
18097}
18098
18099function unmountHostComponents(current$$1, renderPriorityLevel) {
18100 // We only have the top Fiber that was deleted but we need to recurse down its
18101 var node = current$$1;
18102
18103 // Each iteration, currentParent is populated with node's host parent if not
18104 // currentParentIsValid.
18105 var currentParentIsValid = false;
18106
18107 // Note: these two variables *must* always be updated together.
18108 var currentParent = void 0;
18109 var currentParentIsContainer = void 0;
18110
18111 while (true) {
18112 if (!currentParentIsValid) {
18113 var parent = node.return;
18114 findParent: while (true) {
18115 (function() {
18116 if (!(parent !== null)) {
18117 throw ReactError(
18118 Error(
18119 "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue."
18120 )
18121 );
18122 }
18123 })();
18124 var parentStateNode = parent.stateNode;
18125 switch (parent.tag) {
18126 case HostComponent:
18127 currentParent = parentStateNode;
18128 currentParentIsContainer = false;
18129 break findParent;
18130 case HostRoot:
18131 currentParent = parentStateNode.containerInfo;
18132 currentParentIsContainer = true;
18133 break findParent;
18134 case HostPortal:
18135 currentParent = parentStateNode.containerInfo;
18136 currentParentIsContainer = true;
18137 break findParent;
18138 case FundamentalComponent:
18139 if (enableFundamentalAPI) {
18140 currentParent = parentStateNode.instance;
18141 currentParentIsContainer = false;
18142 }
18143 }
18144 parent = parent.return;
18145 }
18146 currentParentIsValid = true;
18147 }
18148
18149 if (node.tag === HostComponent || node.tag === HostText) {
18150 commitNestedUnmounts(node, renderPriorityLevel);
18151 // After all the children have unmounted, it is now safe to remove the
18152 // node from the tree.
18153 if (currentParentIsContainer) {
18154 removeChildFromContainer(currentParent, node.stateNode);
18155 } else {
18156 removeChild(currentParent, node.stateNode);
18157 }
18158 // Don't visit children because we already visited them.
18159 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
18160 var fundamentalNode = node.stateNode.instance;
18161 commitNestedUnmounts(node, renderPriorityLevel);
18162 // After all the children have unmounted, it is now safe to remove the
18163 // node from the tree.
18164 if (currentParentIsContainer) {
18165 removeChildFromContainer(currentParent, fundamentalNode);
18166 } else {
18167 removeChild(currentParent, fundamentalNode);
18168 }
18169 } else if (
18170 enableSuspenseServerRenderer &&
18171 node.tag === DehydratedSuspenseComponent
18172 ) {
18173 // Delete the dehydrated suspense boundary and all of its content.
18174 if (currentParentIsContainer) {
18175 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
18176 } else {
18177 clearSuspenseBoundary(currentParent, node.stateNode);
18178 }
18179 } else if (node.tag === HostPortal) {
18180 if (node.child !== null) {
18181 // When we go into a portal, it becomes the parent to remove from.
18182 // We will reassign it back when we pop the portal on the way up.
18183 currentParent = node.stateNode.containerInfo;
18184 currentParentIsContainer = true;
18185 // Visit children because portals might contain host components.
18186 node.child.return = node;
18187 node = node.child;
18188 continue;
18189 }
18190 } else {
18191 commitUnmount(node, renderPriorityLevel);
18192 // Visit children because we may find more host components below.
18193 if (node.child !== null) {
18194 node.child.return = node;
18195 node = node.child;
18196 continue;
18197 }
18198 }
18199 if (node === current$$1) {
18200 return;
18201 }
18202 while (node.sibling === null) {
18203 if (node.return === null || node.return === current$$1) {
18204 return;
18205 }
18206 node = node.return;
18207 if (node.tag === HostPortal) {
18208 // When we go out of the portal, we need to restore the parent.
18209 // Since we don't keep a stack of them, we will search for it.
18210 currentParentIsValid = false;
18211 }
18212 }
18213 node.sibling.return = node.return;
18214 node = node.sibling;
18215 }
18216}
18217
18218function commitDeletion(current$$1, renderPriorityLevel) {
18219 if (supportsMutation) {
18220 // Recursively delete all host nodes from the parent.
18221 // Detach refs and call componentWillUnmount() on the whole subtree.
18222 unmountHostComponents(current$$1, renderPriorityLevel);
18223 } else {
18224 // Detach refs and call componentWillUnmount() on the whole subtree.
18225 commitNestedUnmounts(current$$1, renderPriorityLevel);
18226 }
18227 detachFiber(current$$1);
18228}
18229
18230function commitWork(current$$1, finishedWork) {
18231 if (!supportsMutation) {
18232 switch (finishedWork.tag) {
18233 case FunctionComponent:
18234 case ForwardRef:
18235 case MemoComponent:
18236 case SimpleMemoComponent: {
18237 // Note: We currently never use MountMutation, but useLayout uses
18238 // UnmountMutation.
18239 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
18240 return;
18241 }
18242 case Profiler: {
18243 return;
18244 }
18245 case SuspenseComponent: {
18246 commitSuspenseComponent(finishedWork);
18247 attachSuspenseRetryListeners(finishedWork);
18248 return;
18249 }
18250 case SuspenseListComponent: {
18251 attachSuspenseRetryListeners(finishedWork);
18252 return;
18253 }
18254 }
18255
18256 commitContainer(finishedWork);
18257 return;
18258 }
18259
18260 switch (finishedWork.tag) {
18261 case FunctionComponent:
18262 case ForwardRef:
18263 case MemoComponent:
18264 case SimpleMemoComponent: {
18265 // Note: We currently never use MountMutation, but useLayout uses
18266 // UnmountMutation.
18267 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
18268 return;
18269 }
18270 case ClassComponent: {
18271 return;
18272 }
18273 case HostComponent: {
18274 var instance = finishedWork.stateNode;
18275 if (instance != null) {
18276 // Commit the work prepared earlier.
18277 var newProps = finishedWork.memoizedProps;
18278 // For hydration we reuse the update path but we treat the oldProps
18279 // as the newProps. The updatePayload will contain the real change in
18280 // this case.
18281 var oldProps =
18282 current$$1 !== null ? current$$1.memoizedProps : newProps;
18283 var type = finishedWork.type;
18284 // TODO: Type the updateQueue to be specific to host components.
18285 var updatePayload = finishedWork.updateQueue;
18286 finishedWork.updateQueue = null;
18287 if (updatePayload !== null) {
18288 commitUpdate(
18289 instance,
18290 updatePayload,
18291 type,
18292 oldProps,
18293 newProps,
18294 finishedWork
18295 );
18296 }
18297 }
18298 return;
18299 }
18300 case HostText: {
18301 (function() {
18302 if (!(finishedWork.stateNode !== null)) {
18303 throw ReactError(
18304 Error(
18305 "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue."
18306 )
18307 );
18308 }
18309 })();
18310 var textInstance = finishedWork.stateNode;
18311 var newText = finishedWork.memoizedProps;
18312 // For hydration we reuse the update path but we treat the oldProps
18313 // as the newProps. The updatePayload will contain the real change in
18314 // this case.
18315 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
18316 commitTextUpdate(textInstance, oldText, newText);
18317 return;
18318 }
18319 case HostRoot: {
18320 return;
18321 }
18322 case Profiler: {
18323 return;
18324 }
18325 case SuspenseComponent: {
18326 commitSuspenseComponent(finishedWork);
18327 attachSuspenseRetryListeners(finishedWork);
18328 return;
18329 }
18330 case SuspenseListComponent: {
18331 attachSuspenseRetryListeners(finishedWork);
18332 return;
18333 }
18334 case IncompleteClassComponent: {
18335 return;
18336 }
18337 case FundamentalComponent: {
18338 if (enableFundamentalAPI) {
18339 var fundamentalInstance = finishedWork.stateNode;
18340 updateFundamentalComponent(fundamentalInstance);
18341 }
18342 return;
18343 }
18344 default: {
18345 (function() {
18346 {
18347 throw ReactError(
18348 Error(
18349 "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."
18350 )
18351 );
18352 }
18353 })();
18354 }
18355 }
18356}
18357
18358function commitSuspenseComponent(finishedWork) {
18359 var newState = finishedWork.memoizedState;
18360
18361 var newDidTimeout = void 0;
18362 var primaryChildParent = finishedWork;
18363 if (newState === null) {
18364 newDidTimeout = false;
18365 } else {
18366 newDidTimeout = true;
18367 primaryChildParent = finishedWork.child;
18368 markCommitTimeOfFallback();
18369 }
18370
18371 if (supportsMutation && primaryChildParent !== null) {
18372 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
18373 }
18374
18375 if (enableSuspenseCallback && newState !== null) {
18376 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
18377 if (typeof suspenseCallback === "function") {
18378 var thenables = finishedWork.updateQueue;
18379 if (thenables !== null) {
18380 suspenseCallback(new Set(thenables));
18381 }
18382 } else {
18383 if (suspenseCallback !== undefined) {
18384 warning$1(false, "Unexpected type for suspenseCallback.");
18385 }
18386 }
18387 }
18388}
18389
18390function attachSuspenseRetryListeners(finishedWork) {
18391 // If this boundary just timed out, then it will have a set of thenables.
18392 // For each thenable, attach a listener so that when it resolves, React
18393 var thenables = finishedWork.updateQueue;
18394 if (thenables !== null) {
18395 finishedWork.updateQueue = null;
18396 var retryCache = finishedWork.stateNode;
18397 if (retryCache === null) {
18398 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
18399 }
18400 thenables.forEach(function(thenable) {
18401 // Memoize using the boundary fiber to prevent redundant listeners.
18402 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
18403 if (!retryCache.has(thenable)) {
18404 if (enableSchedulerTracing) {
18405 retry = tracing.unstable_wrap(retry);
18406 }
18407 retryCache.add(thenable);
18408 thenable.then(retry, retry);
18409 }
18410 });
18411 }
18412}
18413
18414function commitResetTextContent(current$$1) {
18415 if (!supportsMutation) {
18416 return;
18417 }
18418 resetTextContent(current$$1.stateNode);
18419}
18420
18421var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set;
18422var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map;
18423
18424function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
18425 var update = createUpdate(expirationTime, null);
18426 // Unmount the root by rendering null.
18427 update.tag = CaptureUpdate;
18428 // Caution: React DevTools currently depends on this property
18429 // being called "element".
18430 update.payload = { element: null };
18431 var error = errorInfo.value;
18432 update.callback = function() {
18433 onUncaughtError(error);
18434 logError(fiber, errorInfo);
18435 };
18436 return update;
18437}
18438
18439function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
18440 var update = createUpdate(expirationTime, null);
18441 update.tag = CaptureUpdate;
18442 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
18443 if (typeof getDerivedStateFromError === "function") {
18444 var error = errorInfo.value;
18445 update.payload = function() {
18446 logError(fiber, errorInfo);
18447 return getDerivedStateFromError(error);
18448 };
18449 }
18450
18451 var inst = fiber.stateNode;
18452 if (inst !== null && typeof inst.componentDidCatch === "function") {
18453 update.callback = function callback() {
18454 {
18455 markFailedErrorBoundaryForHotReloading(fiber);
18456 }
18457 if (typeof getDerivedStateFromError !== "function") {
18458 // To preserve the preexisting retry behavior of error boundaries,
18459 // we keep track of which ones already failed during this batch.
18460 // This gets reset before we yield back to the browser.
18461 // TODO: Warn in strict mode if getDerivedStateFromError is
18462 // not defined.
18463 markLegacyErrorBoundaryAsFailed(this);
18464
18465 // Only log here if componentDidCatch is the only error boundary method defined
18466 logError(fiber, errorInfo);
18467 }
18468 var error = errorInfo.value;
18469 var stack = errorInfo.stack;
18470 this.componentDidCatch(error, {
18471 componentStack: stack !== null ? stack : ""
18472 });
18473 {
18474 if (typeof getDerivedStateFromError !== "function") {
18475 // If componentDidCatch is the only error boundary method defined,
18476 // then it needs to call setState to recover from errors.
18477 // If no state update is scheduled then the boundary will swallow the error.
18478 !(fiber.expirationTime === Sync)
18479 ? warningWithoutStack$1(
18480 false,
18481 "%s: Error boundaries should implement getDerivedStateFromError(). " +
18482 "In that method, return a state update to display an error message or fallback UI.",
18483 getComponentName(fiber.type) || "Unknown"
18484 )
18485 : void 0;
18486 }
18487 }
18488 };
18489 } else {
18490 update.callback = function() {
18491 markFailedErrorBoundaryForHotReloading(fiber);
18492 };
18493 }
18494 return update;
18495}
18496
18497function attachPingListener(root, renderExpirationTime, thenable) {
18498 // Attach a listener to the promise to "ping" the root and retry. But
18499 // only if one does not already exist for the current render expiration
18500 // time (which acts like a "thread ID" here).
18501 var pingCache = root.pingCache;
18502 var threadIDs = void 0;
18503 if (pingCache === null) {
18504 pingCache = root.pingCache = new PossiblyWeakMap();
18505 threadIDs = new Set();
18506 pingCache.set(thenable, threadIDs);
18507 } else {
18508 threadIDs = pingCache.get(thenable);
18509 if (threadIDs === undefined) {
18510 threadIDs = new Set();
18511 pingCache.set(thenable, threadIDs);
18512 }
18513 }
18514 if (!threadIDs.has(renderExpirationTime)) {
18515 // Memoize using the thread ID to prevent redundant listeners.
18516 threadIDs.add(renderExpirationTime);
18517 var ping = pingSuspendedRoot.bind(
18518 null,
18519 root,
18520 thenable,
18521 renderExpirationTime
18522 );
18523 if (enableSchedulerTracing) {
18524 ping = tracing.unstable_wrap(ping);
18525 }
18526 thenable.then(ping, ping);
18527 }
18528}
18529
18530function throwException(
18531 root,
18532 returnFiber,
18533 sourceFiber,
18534 value,
18535 renderExpirationTime
18536) {
18537 // The source fiber did not complete.
18538 sourceFiber.effectTag |= Incomplete;
18539 // Its effect list is no longer valid.
18540 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
18541
18542 if (
18543 value !== null &&
18544 typeof value === "object" &&
18545 typeof value.then === "function"
18546 ) {
18547 // This is a thenable.
18548 var thenable = value;
18549
18550 checkForWrongSuspensePriorityInDEV(sourceFiber);
18551
18552 var hasInvisibleParentBoundary = hasSuspenseContext(
18553 suspenseStackCursor.current,
18554 InvisibleParentSuspenseContext
18555 );
18556
18557 // Schedule the nearest Suspense to re-render the timed out view.
18558 var _workInProgress = returnFiber;
18559 do {
18560 if (
18561 _workInProgress.tag === SuspenseComponent &&
18562 shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)
18563 ) {
18564 // Found the nearest boundary.
18565
18566 // Stash the promise on the boundary fiber. If the boundary times out, we'll
18567 var thenables = _workInProgress.updateQueue;
18568 if (thenables === null) {
18569 var updateQueue = new Set();
18570 updateQueue.add(thenable);
18571 _workInProgress.updateQueue = updateQueue;
18572 } else {
18573 thenables.add(thenable);
18574 }
18575
18576 // If the boundary is outside of batched mode, we should *not*
18577 // suspend the commit. Pretend as if the suspended component rendered
18578 // null and keep rendering. In the commit phase, we'll schedule a
18579 // subsequent synchronous update to re-render the Suspense.
18580 //
18581 // Note: It doesn't matter whether the component that suspended was
18582 // inside a batched mode tree. If the Suspense is outside of it, we
18583 // should *not* suspend the commit.
18584 if ((_workInProgress.mode & BatchedMode) === NoMode) {
18585 _workInProgress.effectTag |= DidCapture;
18586
18587 // We're going to commit this fiber even though it didn't complete.
18588 // But we shouldn't call any lifecycle methods or callbacks. Remove
18589 // all lifecycle effect tags.
18590 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
18591
18592 if (sourceFiber.tag === ClassComponent) {
18593 var currentSourceFiber = sourceFiber.alternate;
18594 if (currentSourceFiber === null) {
18595 // This is a new mount. Change the tag so it's not mistaken for a
18596 // completed class component. For example, we should not call
18597 // componentWillUnmount if it is deleted.
18598 sourceFiber.tag = IncompleteClassComponent;
18599 } else {
18600 // When we try rendering again, we should not reuse the current fiber,
18601 // since it's known to be in an inconsistent state. Use a force update to
18602 // prevent a bail out.
18603 var update = createUpdate(Sync, null);
18604 update.tag = ForceUpdate;
18605 enqueueUpdate(sourceFiber, update);
18606 }
18607 }
18608
18609 // The source fiber did not complete. Mark it with Sync priority to
18610 // indicate that it still has pending work.
18611 sourceFiber.expirationTime = Sync;
18612
18613 // Exit without suspending.
18614 return;
18615 }
18616
18617 // Confirmed that the boundary is in a concurrent mode tree. Continue
18618 // with the normal suspend path.
18619 //
18620 // After this we'll use a set of heuristics to determine whether this
18621 // render pass will run to completion or restart or "suspend" the commit.
18622 // The actual logic for this is spread out in different places.
18623 //
18624 // This first principle is that if we're going to suspend when we complete
18625 // a root, then we should also restart if we get an update or ping that
18626 // might unsuspend it, and vice versa. The only reason to suspend is
18627 // because you think you might want to restart before committing. However,
18628 // it doesn't make sense to restart only while in the period we're suspended.
18629 //
18630 // Restarting too aggressively is also not good because it starves out any
18631 // intermediate loading state. So we use heuristics to determine when.
18632
18633 // Suspense Heuristics
18634 //
18635 // If nothing threw a Promise or all the same fallbacks are already showing,
18636 // then don't suspend/restart.
18637 //
18638 // If this is an initial render of a new tree of Suspense boundaries and
18639 // those trigger a fallback, then don't suspend/restart. We want to ensure
18640 // that we can show the initial loading state as quickly as possible.
18641 //
18642 // If we hit a "Delayed" case, such as when we'd switch from content back into
18643 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
18644 // this case. If none is defined, JND is used instead.
18645 //
18646 // If we're already showing a fallback and it gets "retried", allowing us to show
18647 // another level, but there's still an inner boundary that would show a fallback,
18648 // then we suspend/restart for 500ms since the last time we showed a fallback
18649 // anywhere in the tree. This effectively throttles progressive loading into a
18650 // consistent train of commits. This also gives us an opportunity to restart to
18651 // get to the completed state slightly earlier.
18652 //
18653 // If there's ambiguity due to batching it's resolved in preference of:
18654 // 1) "delayed", 2) "initial render", 3) "retry".
18655 //
18656 // We want to ensure that a "busy" state doesn't get force committed. We want to
18657 // ensure that new initial loading states can commit as soon as possible.
18658
18659 attachPingListener(root, renderExpirationTime, thenable);
18660
18661 _workInProgress.effectTag |= ShouldCapture;
18662 _workInProgress.expirationTime = renderExpirationTime;
18663
18664 return;
18665 } else if (
18666 enableSuspenseServerRenderer &&
18667 _workInProgress.tag === DehydratedSuspenseComponent
18668 ) {
18669 attachPingListener(root, renderExpirationTime, thenable);
18670
18671 // Since we already have a current fiber, we can eagerly add a retry listener.
18672 var retryCache = _workInProgress.memoizedState;
18673 if (retryCache === null) {
18674 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
18675 var current$$1 = _workInProgress.alternate;
18676 (function() {
18677 if (!current$$1) {
18678 throw ReactError(
18679 Error(
18680 "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React."
18681 )
18682 );
18683 }
18684 })();
18685 current$$1.memoizedState = retryCache;
18686 }
18687 // Memoize using the boundary fiber to prevent redundant listeners.
18688 if (!retryCache.has(thenable)) {
18689 retryCache.add(thenable);
18690 var retry = resolveRetryThenable.bind(
18691 null,
18692 _workInProgress,
18693 thenable
18694 );
18695 if (enableSchedulerTracing) {
18696 retry = tracing.unstable_wrap(retry);
18697 }
18698 thenable.then(retry, retry);
18699 }
18700 _workInProgress.effectTag |= ShouldCapture;
18701 _workInProgress.expirationTime = renderExpirationTime;
18702 return;
18703 }
18704 // This boundary already captured during this render. Continue to the next
18705 // boundary.
18706 _workInProgress = _workInProgress.return;
18707 } while (_workInProgress !== null);
18708 // No boundary was found. Fallthrough to error mode.
18709 // TODO: Use invariant so the message is stripped in prod?
18710 value = new Error(
18711 (getComponentName(sourceFiber.type) || "A React component") +
18712 " suspended while rendering, but no fallback UI was specified.\n" +
18713 "\n" +
18714 "Add a <Suspense fallback=...> component higher in the tree to " +
18715 "provide a loading indicator or placeholder to display." +
18716 getStackByFiberInDevAndProd(sourceFiber)
18717 );
18718 }
18719
18720 // We didn't find a boundary that could handle this type of exception. Start
18721 // over and traverse parent path again, this time treating the exception
18722 // as an error.
18723 renderDidError();
18724 value = createCapturedValue(value, sourceFiber);
18725 var workInProgress = returnFiber;
18726 do {
18727 switch (workInProgress.tag) {
18728 case HostRoot: {
18729 var _errorInfo = value;
18730 workInProgress.effectTag |= ShouldCapture;
18731 workInProgress.expirationTime = renderExpirationTime;
18732 var _update = createRootErrorUpdate(
18733 workInProgress,
18734 _errorInfo,
18735 renderExpirationTime
18736 );
18737 enqueueCapturedUpdate(workInProgress, _update);
18738 return;
18739 }
18740 case ClassComponent:
18741 // Capture and retry
18742 var errorInfo = value;
18743 var ctor = workInProgress.type;
18744 var instance = workInProgress.stateNode;
18745 if (
18746 (workInProgress.effectTag & DidCapture) === NoEffect &&
18747 (typeof ctor.getDerivedStateFromError === "function" ||
18748 (instance !== null &&
18749 typeof instance.componentDidCatch === "function" &&
18750 !isAlreadyFailedLegacyErrorBoundary(instance)))
18751 ) {
18752 workInProgress.effectTag |= ShouldCapture;
18753 workInProgress.expirationTime = renderExpirationTime;
18754 // Schedule the error boundary to re-render using updated state
18755 var _update2 = createClassErrorUpdate(
18756 workInProgress,
18757 errorInfo,
18758 renderExpirationTime
18759 );
18760 enqueueCapturedUpdate(workInProgress, _update2);
18761 return;
18762 }
18763 break;
18764 default:
18765 break;
18766 }
18767 workInProgress = workInProgress.return;
18768 } while (workInProgress !== null);
18769}
18770
18771// The scheduler is imported here *only* to detect whether it's been mocked
18772// DEV stuff
18773var ceil = Math.ceil;
18774
18775var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
18776var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
18777var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
18778
18779var NoContext = /* */ 0;
18780var BatchedContext = /* */ 1;
18781var EventContext = /* */ 2;
18782var DiscreteEventContext = /* */ 4;
18783var LegacyUnbatchedContext = /* */ 8;
18784var RenderContext = /* */ 16;
18785var CommitContext = /* */ 32;
18786
18787var RootIncomplete = 0;
18788var RootErrored = 1;
18789var RootSuspended = 2;
18790var RootSuspendedWithDelay = 3;
18791var RootCompleted = 4;
18792
18793// Describes where we are in the React execution stack
18794var executionContext = NoContext;
18795// The root we're working on
18796var workInProgressRoot = null;
18797// The fiber we're working on
18798var workInProgress = null;
18799// The expiration time we're rendering
18800var renderExpirationTime = NoWork;
18801// Whether to root completed, errored, suspended, etc.
18802var workInProgressRootExitStatus = RootIncomplete;
18803// Most recent event time among processed updates during this render.
18804// This is conceptually a time stamp but expressed in terms of an ExpirationTime
18805// because we deal mostly with expiration times in the hot path, so this avoids
18806// the conversion happening in the hot path.
18807var workInProgressRootLatestProcessedExpirationTime = Sync;
18808var workInProgressRootLatestSuspenseTimeout = Sync;
18809var workInProgressRootCanSuspendUsingConfig = null;
18810// If we're pinged while rendering we don't always restart immediately.
18811// This flag determines if it might be worthwhile to restart if an opportunity
18812// happens latere.
18813var workInProgressRootHasPendingPing = false;
18814// The most recent time we committed a fallback. This lets us ensure a train
18815// model where we don't commit new loading states in too quick succession.
18816var globalMostRecentFallbackTime = 0;
18817var FALLBACK_THROTTLE_MS = 500;
18818
18819var nextEffect = null;
18820var hasUncaughtError = false;
18821var firstUncaughtError = null;
18822var legacyErrorBoundariesThatAlreadyFailed = null;
18823
18824var rootDoesHavePassiveEffects = false;
18825var rootWithPendingPassiveEffects = null;
18826var pendingPassiveEffectsRenderPriority = NoPriority;
18827var pendingPassiveEffectsExpirationTime = NoWork;
18828
18829var rootsWithPendingDiscreteUpdates = null;
18830
18831// Use these to prevent an infinite loop of nested updates
18832var NESTED_UPDATE_LIMIT = 50;
18833var nestedUpdateCount = 0;
18834var rootWithNestedUpdates = null;
18835
18836var NESTED_PASSIVE_UPDATE_LIMIT = 50;
18837var nestedPassiveUpdateCount = 0;
18838
18839var interruptedBy = null;
18840
18841// Marks the need to reschedule pending interactions at these expiration times
18842// during the commit phase. This enables them to be traced across components
18843// that spawn new work during render. E.g. hidden boundaries, suspended SSR
18844// hydration or SuspenseList.
18845var spawnedWorkDuringRender = null;
18846
18847// Expiration times are computed by adding to the current time (the start
18848// time). However, if two updates are scheduled within the same event, we
18849// should treat their start times as simultaneous, even if the actual clock
18850// time has advanced between the first and second call.
18851
18852// In other words, because expiration times determine how updates are batched,
18853// we want all updates of like priority that occur within the same event to
18854// receive the same expiration time. Otherwise we get tearing.
18855var currentEventTime = NoWork;
18856
18857function requestCurrentTime() {
18858 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
18859 // We're inside React, so it's fine to read the actual time.
18860 return msToExpirationTime(now());
18861 }
18862 // We're not inside React, so we may be in the middle of a browser event.
18863 if (currentEventTime !== NoWork) {
18864 // Use the same start time for all updates until we enter React again.
18865 return currentEventTime;
18866 }
18867 // This is the first update since React yielded. Compute a new start time.
18868 currentEventTime = msToExpirationTime(now());
18869 return currentEventTime;
18870}
18871
18872function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
18873 var mode = fiber.mode;
18874 if ((mode & BatchedMode) === NoMode) {
18875 return Sync;
18876 }
18877
18878 var priorityLevel = getCurrentPriorityLevel();
18879 if ((mode & ConcurrentMode) === NoMode) {
18880 return priorityLevel === ImmediatePriority ? Sync : Batched;
18881 }
18882
18883 if ((executionContext & RenderContext) !== NoContext) {
18884 // Use whatever time we're already rendering
18885 return renderExpirationTime;
18886 }
18887
18888 var expirationTime = void 0;
18889 if (suspenseConfig !== null) {
18890 // Compute an expiration time based on the Suspense timeout.
18891 expirationTime = computeSuspenseExpiration(
18892 currentTime,
18893 suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION
18894 );
18895 } else {
18896 // Compute an expiration time based on the Scheduler priority.
18897 switch (priorityLevel) {
18898 case ImmediatePriority:
18899 expirationTime = Sync;
18900 break;
18901 case UserBlockingPriority$1:
18902 // TODO: Rename this to computeUserBlockingExpiration
18903 expirationTime = computeInteractiveExpiration(currentTime);
18904 break;
18905 case NormalPriority:
18906 case LowPriority:
18907 // TODO: Handle LowPriority
18908 // TODO: Rename this to... something better.
18909 expirationTime = computeAsyncExpiration(currentTime);
18910 break;
18911 case IdlePriority:
18912 expirationTime = Never;
18913 break;
18914 default:
18915 (function() {
18916 {
18917 throw ReactError(Error("Expected a valid priority level"));
18918 }
18919 })();
18920 }
18921 }
18922
18923 // If we're in the middle of rendering a tree, do not update at the same
18924 // expiration time that is already rendering.
18925 // TODO: We shouldn't have to do this if the update is on a different root.
18926 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
18927 // the root when we check for this condition.
18928 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
18929 // This is a trick to move this update into a separate batch
18930 expirationTime -= 1;
18931 }
18932
18933 return expirationTime;
18934}
18935
18936function scheduleUpdateOnFiber(fiber, expirationTime) {
18937 checkForNestedUpdates();
18938 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
18939
18940 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
18941 if (root === null) {
18942 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
18943 return;
18944 }
18945
18946 root.pingTime = NoWork;
18947
18948 checkForInterruption(fiber, expirationTime);
18949 recordScheduleUpdate();
18950
18951 // TODO: computeExpirationForFiber also reads the priority. Pass the
18952 // priority as an argument to that function and this one.
18953 var priorityLevel = getCurrentPriorityLevel();
18954
18955 if (expirationTime === Sync) {
18956 if (
18957 // Check if we're inside unbatchedUpdates
18958 (executionContext & LegacyUnbatchedContext) !== NoContext &&
18959 // Check if we're not already rendering
18960 (executionContext & (RenderContext | CommitContext)) === NoContext
18961 ) {
18962 // Register pending interactions on the root to avoid losing traced interaction data.
18963 schedulePendingInteractions(root, expirationTime);
18964
18965 // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
18966 // root inside of batchedUpdates should be synchronous, but layout updates
18967 // should be deferred until the end of the batch.
18968 var callback = renderRoot(root, Sync, true);
18969 while (callback !== null) {
18970 callback = callback(true);
18971 }
18972 } else {
18973 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
18974 if (executionContext === NoContext) {
18975 // Flush the synchronous work now, wnless we're already working or inside
18976 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
18977 // scheduleCallbackForFiber to preserve the ability to schedule a callback
18978 // without immediately flushing it. We only do this for user-initiated
18979 // updates, to preserve historical behavior of sync mode.
18980 flushSyncCallbackQueue();
18981 }
18982 }
18983 } else {
18984 scheduleCallbackForRoot(root, priorityLevel, expirationTime);
18985 }
18986
18987 if (
18988 (executionContext & DiscreteEventContext) !== NoContext &&
18989 // Only updates at user-blocking priority or greater are considered
18990 // discrete, even inside a discrete event.
18991 (priorityLevel === UserBlockingPriority$1 ||
18992 priorityLevel === ImmediatePriority)
18993 ) {
18994 // This is the result of a discrete event. Track the lowest priority
18995 // discrete update per root so we can flush them early, if needed.
18996 if (rootsWithPendingDiscreteUpdates === null) {
18997 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
18998 } else {
18999 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
19000 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
19001 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
19002 }
19003 }
19004 }
19005}
19006var scheduleWork = scheduleUpdateOnFiber;
19007
19008// This is split into a separate function so we can mark a fiber with pending
19009// work without treating it as a typical update that originates from an event;
19010// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
19011// on a fiber.
19012function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
19013 // Update the source fiber's expiration time
19014 if (fiber.expirationTime < expirationTime) {
19015 fiber.expirationTime = expirationTime;
19016 }
19017 var alternate = fiber.alternate;
19018 if (alternate !== null && alternate.expirationTime < expirationTime) {
19019 alternate.expirationTime = expirationTime;
19020 }
19021 // Walk the parent path to the root and update the child expiration time.
19022 var node = fiber.return;
19023 var root = null;
19024 if (node === null && fiber.tag === HostRoot) {
19025 root = fiber.stateNode;
19026 } else {
19027 while (node !== null) {
19028 alternate = node.alternate;
19029 if (node.childExpirationTime < expirationTime) {
19030 node.childExpirationTime = expirationTime;
19031 if (
19032 alternate !== null &&
19033 alternate.childExpirationTime < expirationTime
19034 ) {
19035 alternate.childExpirationTime = expirationTime;
19036 }
19037 } else if (
19038 alternate !== null &&
19039 alternate.childExpirationTime < expirationTime
19040 ) {
19041 alternate.childExpirationTime = expirationTime;
19042 }
19043 if (node.return === null && node.tag === HostRoot) {
19044 root = node.stateNode;
19045 break;
19046 }
19047 node = node.return;
19048 }
19049 }
19050
19051 if (root !== null) {
19052 // Update the first and last pending expiration times in this root
19053 var firstPendingTime = root.firstPendingTime;
19054 if (expirationTime > firstPendingTime) {
19055 root.firstPendingTime = expirationTime;
19056 }
19057 var lastPendingTime = root.lastPendingTime;
19058 if (lastPendingTime === NoWork || expirationTime < lastPendingTime) {
19059 root.lastPendingTime = expirationTime;
19060 }
19061 }
19062
19063 return root;
19064}
19065
19066// Use this function, along with runRootCallback, to ensure that only a single
19067// callback per root is scheduled. It's still possible to call renderRoot
19068// directly, but scheduling via this function helps avoid excessive callbacks.
19069// It works by storing the callback node and expiration time on the root. When a
19070// new callback comes in, it compares the expiration time to determine if it
19071// should cancel the previous one. It also relies on commitRoot scheduling a
19072// callback to render the next level, because that means we don't need a
19073// separate callback per expiration time.
19074function scheduleCallbackForRoot(root, priorityLevel, expirationTime) {
19075 var existingCallbackExpirationTime = root.callbackExpirationTime;
19076 if (existingCallbackExpirationTime < expirationTime) {
19077 // New callback has higher priority than the existing one.
19078 var existingCallbackNode = root.callbackNode;
19079 if (existingCallbackNode !== null) {
19080 cancelCallback(existingCallbackNode);
19081 }
19082 root.callbackExpirationTime = expirationTime;
19083
19084 if (expirationTime === Sync) {
19085 // Sync React callbacks are scheduled on a special internal queue
19086 root.callbackNode = scheduleSyncCallback(
19087 runRootCallback.bind(
19088 null,
19089 root,
19090 renderRoot.bind(null, root, expirationTime)
19091 )
19092 );
19093 } else {
19094 var options = null;
19095 if (
19096 !disableSchedulerTimeoutBasedOnReactExpirationTime &&
19097 expirationTime !== Never
19098 ) {
19099 var timeout = expirationTimeToMs(expirationTime) - now();
19100 options = { timeout: timeout };
19101 }
19102
19103 root.callbackNode = scheduleCallback(
19104 priorityLevel,
19105 runRootCallback.bind(
19106 null,
19107 root,
19108 renderRoot.bind(null, root, expirationTime)
19109 ),
19110 options
19111 );
19112 if (
19113 enableUserTimingAPI &&
19114 expirationTime !== Sync &&
19115 (executionContext & (RenderContext | CommitContext)) === NoContext
19116 ) {
19117 // Scheduled an async callback, and we're not already working. Add an
19118 // entry to the flamegraph that shows we're waiting for a callback
19119 // to fire.
19120 startRequestCallbackTimer();
19121 }
19122 }
19123 }
19124
19125 // Associate the current interactions with this new root+priority.
19126 schedulePendingInteractions(root, expirationTime);
19127}
19128
19129function runRootCallback(root, callback, isSync) {
19130 var prevCallbackNode = root.callbackNode;
19131 var continuation = null;
19132 try {
19133 continuation = callback(isSync);
19134 if (continuation !== null) {
19135 return runRootCallback.bind(null, root, continuation);
19136 } else {
19137 return null;
19138 }
19139 } finally {
19140 // If the callback exits without returning a continuation, remove the
19141 // corresponding callback node from the root. Unless the callback node
19142 // has changed, which implies that it was already cancelled by a high
19143 // priority update.
19144 if (continuation === null && prevCallbackNode === root.callbackNode) {
19145 root.callbackNode = null;
19146 root.callbackExpirationTime = NoWork;
19147 }
19148 }
19149}
19150
19151function flushDiscreteUpdates() {
19152 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
19153 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
19154 // those two cases. Need to fix this before exposing flushDiscreteUpdates
19155 // as a public API.
19156 if (
19157 (executionContext & (BatchedContext | RenderContext | CommitContext)) !==
19158 NoContext
19159 ) {
19160 if (true && (executionContext & RenderContext) !== NoContext) {
19161 warning$1(
19162 false,
19163 "unstable_flushDiscreteUpdates: Cannot flush updates when React is " +
19164 "already rendering."
19165 );
19166 }
19167 // We're already rendering, so we can't synchronously flush pending work.
19168 // This is probably a nested event dispatch triggered by a lifecycle/effect,
19169 // like `el.focus()`. Exit.
19170 return;
19171 }
19172 flushPendingDiscreteUpdates();
19173 if (!revertPassiveEffectsChange) {
19174 // If the discrete updates scheduled passive effects, flush them now so that
19175 // they fire before the next serial event.
19176 flushPassiveEffects();
19177 }
19178}
19179
19180function resolveLocksOnRoot(root, expirationTime) {
19181 var firstBatch = root.firstBatch;
19182 if (
19183 firstBatch !== null &&
19184 firstBatch._defer &&
19185 firstBatch._expirationTime >= expirationTime
19186 ) {
19187 scheduleCallback(NormalPriority, function() {
19188 firstBatch._onComplete();
19189 return null;
19190 });
19191 return true;
19192 } else {
19193 return false;
19194 }
19195}
19196
19197function flushPendingDiscreteUpdates() {
19198 if (rootsWithPendingDiscreteUpdates !== null) {
19199 // For each root with pending discrete updates, schedule a callback to
19200 // immediately flush them.
19201 var roots = rootsWithPendingDiscreteUpdates;
19202 rootsWithPendingDiscreteUpdates = null;
19203 roots.forEach(function(expirationTime, root) {
19204 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
19205 });
19206 // Now flush the immediate queue.
19207 flushSyncCallbackQueue();
19208 }
19209}
19210
19211function batchedUpdates$1(fn, a) {
19212 var prevExecutionContext = executionContext;
19213 executionContext |= BatchedContext;
19214 try {
19215 return fn(a);
19216 } finally {
19217 executionContext = prevExecutionContext;
19218 if (executionContext === NoContext) {
19219 // Flush the immediate callbacks that were scheduled during this batch
19220 flushSyncCallbackQueue();
19221 }
19222 }
19223}
19224
19225function batchedEventUpdates$1(fn, a) {
19226 var prevExecutionContext = executionContext;
19227 executionContext |= EventContext;
19228 try {
19229 return fn(a);
19230 } finally {
19231 executionContext = prevExecutionContext;
19232 if (executionContext === NoContext) {
19233 // Flush the immediate callbacks that were scheduled during this batch
19234 flushSyncCallbackQueue();
19235 }
19236 }
19237}
19238
19239function discreteUpdates$1(fn, a, b, c) {
19240 var prevExecutionContext = executionContext;
19241 executionContext |= DiscreteEventContext;
19242 try {
19243 // Should this
19244 return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c));
19245 } finally {
19246 executionContext = prevExecutionContext;
19247 if (executionContext === NoContext) {
19248 // Flush the immediate callbacks that were scheduled during this batch
19249 flushSyncCallbackQueue();
19250 }
19251 }
19252}
19253
19254function flushSync(fn, a) {
19255 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
19256 (function() {
19257 {
19258 throw ReactError(
19259 Error(
19260 "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering."
19261 )
19262 );
19263 }
19264 })();
19265 }
19266 var prevExecutionContext = executionContext;
19267 executionContext |= BatchedContext;
19268 try {
19269 return runWithPriority$1(ImmediatePriority, fn.bind(null, a));
19270 } finally {
19271 executionContext = prevExecutionContext;
19272 // Flush the immediate callbacks that were scheduled during this batch.
19273 // Note that this will happen even if batchedUpdates is higher up
19274 // the stack.
19275 flushSyncCallbackQueue();
19276 }
19277}
19278
19279function prepareFreshStack(root, expirationTime) {
19280 root.finishedWork = null;
19281 root.finishedExpirationTime = NoWork;
19282
19283 var timeoutHandle = root.timeoutHandle;
19284 if (timeoutHandle !== noTimeout) {
19285 // The root previous suspended and scheduled a timeout to commit a fallback
19286 // state. Now that we have additional work, cancel the timeout.
19287 root.timeoutHandle = noTimeout;
19288 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
19289 cancelTimeout(timeoutHandle);
19290 }
19291
19292 if (workInProgress !== null) {
19293 var interruptedWork = workInProgress.return;
19294 while (interruptedWork !== null) {
19295 unwindInterruptedWork(interruptedWork);
19296 interruptedWork = interruptedWork.return;
19297 }
19298 }
19299 workInProgressRoot = root;
19300 workInProgress = createWorkInProgress(root.current, null, expirationTime);
19301 renderExpirationTime = expirationTime;
19302 workInProgressRootExitStatus = RootIncomplete;
19303 workInProgressRootLatestProcessedExpirationTime = Sync;
19304 workInProgressRootLatestSuspenseTimeout = Sync;
19305 workInProgressRootCanSuspendUsingConfig = null;
19306 workInProgressRootHasPendingPing = false;
19307
19308 if (enableSchedulerTracing) {
19309 spawnedWorkDuringRender = null;
19310 }
19311
19312 {
19313 ReactStrictModeWarnings.discardPendingWarnings();
19314 componentsThatTriggeredHighPriSuspend = null;
19315 }
19316}
19317
19318function renderRoot(root, expirationTime, isSync) {
19319 (function() {
19320 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
19321 throw ReactError(Error("Should not already be working."));
19322 }
19323 })();
19324
19325 if (enableUserTimingAPI && expirationTime !== Sync) {
19326 var didExpire = isSync;
19327 stopRequestCallbackTimer(didExpire);
19328 }
19329
19330 if (root.firstPendingTime < expirationTime) {
19331 // If there's no work left at this expiration time, exit immediately. This
19332 // happens when multiple callbacks are scheduled for a single root, but an
19333 // earlier callback flushes the work of a later one.
19334 return null;
19335 }
19336
19337 if (isSync && root.finishedExpirationTime === expirationTime) {
19338 // There's already a pending commit at this expiration time.
19339 // TODO: This is poorly factored. This case only exists for the
19340 // batch.commit() API.
19341 return commitRoot.bind(null, root);
19342 }
19343
19344 flushPassiveEffects();
19345
19346 // If the root or expiration time have changed, throw out the existing stack
19347 // and prepare a fresh one. Otherwise we'll continue where we left off.
19348 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
19349 prepareFreshStack(root, expirationTime);
19350 startWorkOnPendingInteractions(root, expirationTime);
19351 } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
19352 // We could've received an update at a lower priority while we yielded.
19353 // We're suspended in a delayed state. Once we complete this render we're
19354 // just going to try to recover at the last pending time anyway so we might
19355 // as well start doing that eagerly.
19356 // Ideally we should be able to do this even for retries but we don't yet
19357 // know if we're going to process an update which wants to commit earlier,
19358 // and this path happens very early so it would happen too often. Instead,
19359 // for that case, we'll wait until we complete.
19360 if (workInProgressRootHasPendingPing) {
19361 // We have a ping at this expiration. Let's restart to see if we get unblocked.
19362 prepareFreshStack(root, expirationTime);
19363 } else {
19364 var lastPendingTime = root.lastPendingTime;
19365 if (lastPendingTime < expirationTime) {
19366 // There's lower priority work. It might be unsuspended. Try rendering
19367 // at that level immediately, while preserving the position in the queue.
19368 return renderRoot.bind(null, root, lastPendingTime);
19369 }
19370 }
19371 }
19372
19373 // If we have a work-in-progress fiber, it means there's still work to do
19374 // in this root.
19375 if (workInProgress !== null) {
19376 var prevExecutionContext = executionContext;
19377 executionContext |= RenderContext;
19378 var prevDispatcher = ReactCurrentDispatcher.current;
19379 if (prevDispatcher === null) {
19380 // The React isomorphic package does not include a default dispatcher.
19381 // Instead the first renderer will lazily attach one, in order to give
19382 // nicer error messages.
19383 prevDispatcher = ContextOnlyDispatcher;
19384 }
19385 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
19386 var prevInteractions = null;
19387 if (enableSchedulerTracing) {
19388 prevInteractions = tracing.__interactionsRef.current;
19389 tracing.__interactionsRef.current = root.memoizedInteractions;
19390 }
19391
19392 startWorkLoopTimer(workInProgress);
19393
19394 // TODO: Fork renderRoot into renderRootSync and renderRootAsync
19395 if (isSync) {
19396 if (expirationTime !== Sync) {
19397 // An async update expired. There may be other expired updates on
19398 // this root. We should render all the expired work in a
19399 // single batch.
19400 var currentTime = requestCurrentTime();
19401 if (currentTime < expirationTime) {
19402 // Restart at the current time.
19403 executionContext = prevExecutionContext;
19404 resetContextDependencies();
19405 ReactCurrentDispatcher.current = prevDispatcher;
19406 if (enableSchedulerTracing) {
19407 tracing.__interactionsRef.current = prevInteractions;
19408 }
19409 return renderRoot.bind(null, root, currentTime);
19410 }
19411 }
19412 } else {
19413 // Since we know we're in a React event, we can clear the current
19414 // event time. The next update will compute a new event time.
19415 currentEventTime = NoWork;
19416 }
19417
19418 do {
19419 try {
19420 if (isSync) {
19421 workLoopSync();
19422 } else {
19423 workLoop();
19424 }
19425 break;
19426 } catch (thrownValue) {
19427 // Reset module-level state that was set during the render phase.
19428 resetContextDependencies();
19429 resetHooks();
19430
19431 var sourceFiber = workInProgress;
19432 if (sourceFiber === null || sourceFiber.return === null) {
19433 // Expected to be working on a non-root fiber. This is a fatal error
19434 // because there's no ancestor that can handle it; the root is
19435 // supposed to capture all errors that weren't caught by an error
19436 // boundary.
19437 prepareFreshStack(root, expirationTime);
19438 executionContext = prevExecutionContext;
19439 throw thrownValue;
19440 }
19441
19442 if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {
19443 // Record the time spent rendering before an error was thrown. This
19444 // avoids inaccurate Profiler durations in the case of a
19445 // suspended render.
19446 stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);
19447 }
19448
19449 var returnFiber = sourceFiber.return;
19450 throwException(
19451 root,
19452 returnFiber,
19453 sourceFiber,
19454 thrownValue,
19455 renderExpirationTime
19456 );
19457 workInProgress = completeUnitOfWork(sourceFiber);
19458 }
19459 } while (true);
19460
19461 executionContext = prevExecutionContext;
19462 resetContextDependencies();
19463 ReactCurrentDispatcher.current = prevDispatcher;
19464 if (enableSchedulerTracing) {
19465 tracing.__interactionsRef.current = prevInteractions;
19466 }
19467
19468 if (workInProgress !== null) {
19469 // There's still work left over. Return a continuation.
19470 stopInterruptedWorkLoopTimer();
19471 if (expirationTime !== Sync) {
19472 startRequestCallbackTimer();
19473 }
19474 return renderRoot.bind(null, root, expirationTime);
19475 }
19476 }
19477
19478 // We now have a consistent tree. The next step is either to commit it, or, if
19479 // something suspended, wait to commit it after a timeout.
19480 stopFinishedWorkLoopTimer();
19481
19482 root.finishedWork = root.current.alternate;
19483 root.finishedExpirationTime = expirationTime;
19484
19485 var isLocked = resolveLocksOnRoot(root, expirationTime);
19486 if (isLocked) {
19487 // This root has a lock that prevents it from committing. Exit. If we begin
19488 // work on the root again, without any intervening updates, it will finish
19489 // without doing additional work.
19490 return null;
19491 }
19492
19493 // Set this to null to indicate there's no in-progress render.
19494 workInProgressRoot = null;
19495
19496 switch (workInProgressRootExitStatus) {
19497 case RootIncomplete: {
19498 (function() {
19499 {
19500 throw ReactError(Error("Should have a work-in-progress."));
19501 }
19502 })();
19503 }
19504 // Flow knows about invariant, so it complains if I add a break statement,
19505 // but eslint doesn't know about invariant, so it complains if I do.
19506 // eslint-disable-next-line no-fallthrough
19507 case RootErrored: {
19508 // An error was thrown. First check if there is lower priority work
19509 // scheduled on this root.
19510 var _lastPendingTime = root.lastPendingTime;
19511 if (_lastPendingTime < expirationTime) {
19512 // There's lower priority work. Before raising the error, try rendering
19513 // at the lower priority to see if it fixes it. Use a continuation to
19514 // maintain the existing priority and position in the queue.
19515 return renderRoot.bind(null, root, _lastPendingTime);
19516 }
19517 if (!isSync) {
19518 // If we're rendering asynchronously, it's possible the error was
19519 // caused by tearing due to a mutation during an event. Try rendering
19520 // one more time without yiedling to events.
19521 prepareFreshStack(root, expirationTime);
19522 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
19523 return null;
19524 }
19525 // If we're already rendering synchronously, commit the root in its
19526 // errored state.
19527 return commitRoot.bind(null, root);
19528 }
19529 case RootSuspended: {
19530 flushSuspensePriorityWarningInDEV();
19531
19532 // We have an acceptable loading state. We need to figure out if we should
19533 // immediately commit it or wait a bit.
19534
19535 // If we have processed new updates during this render, we may now have a
19536 // new loading state ready. We want to ensure that we commit that as soon as
19537 // possible.
19538 var hasNotProcessedNewUpdates =
19539 workInProgressRootLatestProcessedExpirationTime === Sync;
19540 if (
19541 hasNotProcessedNewUpdates &&
19542 !isSync &&
19543 // do not delay if we're inside an act() scope
19544 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)
19545 ) {
19546 // If we have not processed any new updates during this pass, then this is
19547 // either a retry of an existing fallback state or a hidden tree.
19548 // Hidden trees shouldn't be batched with other work and after that's
19549 // fixed it can only be a retry.
19550 // We're going to throttle committing retries so that we don't show too
19551 // many loading states too quickly.
19552 var msUntilTimeout =
19553 globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
19554 // Don't bother with a very short suspense time.
19555 if (msUntilTimeout > 10) {
19556 if (workInProgressRootHasPendingPing) {
19557 // This render was pinged but we didn't get to restart earlier so try
19558 // restarting now instead.
19559 prepareFreshStack(root, expirationTime);
19560 return renderRoot.bind(null, root, expirationTime);
19561 }
19562 var _lastPendingTime2 = root.lastPendingTime;
19563 if (_lastPendingTime2 < expirationTime) {
19564 // There's lower priority work. It might be unsuspended. Try rendering
19565 // at that level.
19566 return renderRoot.bind(null, root, _lastPendingTime2);
19567 }
19568 // The render is suspended, it hasn't timed out, and there's no lower
19569 // priority work to do. Instead of committing the fallback
19570 // immediately, wait for more data to arrive.
19571 root.timeoutHandle = scheduleTimeout(
19572 commitRoot.bind(null, root),
19573 msUntilTimeout
19574 );
19575 return null;
19576 }
19577 }
19578 // The work expired. Commit immediately.
19579 return commitRoot.bind(null, root);
19580 }
19581 case RootSuspendedWithDelay: {
19582 flushSuspensePriorityWarningInDEV();
19583
19584 if (
19585 !isSync &&
19586 // do not delay if we're inside an act() scope
19587 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)
19588 ) {
19589 // We're suspended in a state that should be avoided. We'll try to avoid committing
19590 // it for as long as the timeouts let us.
19591 if (workInProgressRootHasPendingPing) {
19592 // This render was pinged but we didn't get to restart earlier so try
19593 // restarting now instead.
19594 prepareFreshStack(root, expirationTime);
19595 return renderRoot.bind(null, root, expirationTime);
19596 }
19597 var _lastPendingTime3 = root.lastPendingTime;
19598 if (_lastPendingTime3 < expirationTime) {
19599 // There's lower priority work. It might be unsuspended. Try rendering
19600 // at that level immediately.
19601 return renderRoot.bind(null, root, _lastPendingTime3);
19602 }
19603
19604 var _msUntilTimeout = void 0;
19605 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
19606 // We have processed a suspense config whose expiration time we can use as
19607 // the timeout.
19608 _msUntilTimeout =
19609 expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
19610 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
19611 // This should never normally happen because only new updates cause
19612 // delayed states, so we should have processed something. However,
19613 // this could also happen in an offscreen tree.
19614 _msUntilTimeout = 0;
19615 } else {
19616 // If we don't have a suspense config, we're going to use a heuristic to
19617 var eventTimeMs = inferTimeFromExpirationTime(
19618 workInProgressRootLatestProcessedExpirationTime
19619 );
19620 var currentTimeMs = now();
19621 var timeUntilExpirationMs =
19622 expirationTimeToMs(expirationTime) - currentTimeMs;
19623 var timeElapsed = currentTimeMs - eventTimeMs;
19624 if (timeElapsed < 0) {
19625 // We get this wrong some time since we estimate the time.
19626 timeElapsed = 0;
19627 }
19628
19629 _msUntilTimeout = jnd(timeElapsed) - timeElapsed;
19630
19631 // Clamp the timeout to the expiration time.
19632 // TODO: Once the event time is exact instead of inferred from expiration time
19633 // we don't need this.
19634 if (timeUntilExpirationMs < _msUntilTimeout) {
19635 _msUntilTimeout = timeUntilExpirationMs;
19636 }
19637 }
19638
19639 // Don't bother with a very short suspense time.
19640 if (_msUntilTimeout > 10) {
19641 // The render is suspended, it hasn't timed out, and there's no lower
19642 // priority work to do. Instead of committing the fallback
19643 // immediately, wait for more data to arrive.
19644 root.timeoutHandle = scheduleTimeout(
19645 commitRoot.bind(null, root),
19646 _msUntilTimeout
19647 );
19648 return null;
19649 }
19650 }
19651 // The work expired. Commit immediately.
19652 return commitRoot.bind(null, root);
19653 }
19654 case RootCompleted: {
19655 // The work completed. Ready to commit.
19656 if (
19657 !isSync &&
19658 // do not delay if we're inside an act() scope
19659 !(
19660 true &&
19661 flushSuspenseFallbacksInTests &&
19662 IsThisRendererActing.current
19663 ) &&
19664 workInProgressRootLatestProcessedExpirationTime !== Sync &&
19665 workInProgressRootCanSuspendUsingConfig !== null
19666 ) {
19667 // If we have exceeded the minimum loading delay, which probably
19668 // means we have shown a spinner already, we might have to suspend
19669 // a bit longer to ensure that the spinner is shown for enough time.
19670 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(
19671 workInProgressRootLatestProcessedExpirationTime,
19672 expirationTime,
19673 workInProgressRootCanSuspendUsingConfig
19674 );
19675 if (_msUntilTimeout2 > 10) {
19676 root.timeoutHandle = scheduleTimeout(
19677 commitRoot.bind(null, root),
19678 _msUntilTimeout2
19679 );
19680 return null;
19681 }
19682 }
19683 return commitRoot.bind(null, root);
19684 }
19685 default: {
19686 (function() {
19687 {
19688 throw ReactError(Error("Unknown root exit status."));
19689 }
19690 })();
19691 }
19692 }
19693}
19694
19695function markCommitTimeOfFallback() {
19696 globalMostRecentFallbackTime = now();
19697}
19698
19699function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
19700 if (
19701 expirationTime < workInProgressRootLatestProcessedExpirationTime &&
19702 expirationTime > Never
19703 ) {
19704 workInProgressRootLatestProcessedExpirationTime = expirationTime;
19705 }
19706 if (suspenseConfig !== null) {
19707 if (
19708 expirationTime < workInProgressRootLatestSuspenseTimeout &&
19709 expirationTime > Never
19710 ) {
19711 workInProgressRootLatestSuspenseTimeout = expirationTime;
19712 // Most of the time we only have one config and getting wrong is not bad.
19713 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
19714 }
19715 }
19716}
19717
19718function renderDidSuspend() {
19719 if (workInProgressRootExitStatus === RootIncomplete) {
19720 workInProgressRootExitStatus = RootSuspended;
19721 }
19722}
19723
19724function renderDidSuspendDelayIfPossible() {
19725 if (
19726 workInProgressRootExitStatus === RootIncomplete ||
19727 workInProgressRootExitStatus === RootSuspended
19728 ) {
19729 workInProgressRootExitStatus = RootSuspendedWithDelay;
19730 }
19731}
19732
19733function renderDidError() {
19734 if (workInProgressRootExitStatus !== RootCompleted) {
19735 workInProgressRootExitStatus = RootErrored;
19736 }
19737}
19738
19739// Called during render to determine if anything has suspended.
19740// Returns false if we're not sure.
19741function renderHasNotSuspendedYet() {
19742 // If something errored or completed, we can't really be sure,
19743 // so those are false.
19744 return workInProgressRootExitStatus === RootIncomplete;
19745}
19746
19747function inferTimeFromExpirationTime(expirationTime) {
19748 // We don't know exactly when the update was scheduled, but we can infer an
19749 // approximate start time from the expiration time.
19750 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
19751 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
19752}
19753
19754function inferTimeFromExpirationTimeWithSuspenseConfig(
19755 expirationTime,
19756 suspenseConfig
19757) {
19758 // We don't know exactly when the update was scheduled, but we can infer an
19759 // approximate start time from the expiration time by subtracting the timeout
19760 // that was added to the event time.
19761 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
19762 return (
19763 earliestExpirationTimeMs -
19764 (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION)
19765 );
19766}
19767
19768function workLoopSync() {
19769 // Already timed out, so perform work without checking if we need to yield.
19770 while (workInProgress !== null) {
19771 workInProgress = performUnitOfWork(workInProgress);
19772 }
19773}
19774
19775function workLoop() {
19776 // Perform work until Scheduler asks us to yield
19777 while (workInProgress !== null && !shouldYield()) {
19778 workInProgress = performUnitOfWork(workInProgress);
19779 }
19780}
19781
19782function performUnitOfWork(unitOfWork) {
19783 // The current, flushed, state of this fiber is the alternate. Ideally
19784 // nothing should rely on this, but relying on it here means that we don't
19785 // need an additional field on the work in progress.
19786 var current$$1 = unitOfWork.alternate;
19787
19788 startWorkTimer(unitOfWork);
19789 setCurrentFiber(unitOfWork);
19790
19791 var next = void 0;
19792 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
19793 startProfilerTimer(unitOfWork);
19794 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
19795 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
19796 } else {
19797 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
19798 }
19799
19800 resetCurrentFiber();
19801 unitOfWork.memoizedProps = unitOfWork.pendingProps;
19802 if (next === null) {
19803 // If this doesn't spawn new work, complete the current work.
19804 next = completeUnitOfWork(unitOfWork);
19805 }
19806
19807 ReactCurrentOwner$2.current = null;
19808 return next;
19809}
19810
19811function completeUnitOfWork(unitOfWork) {
19812 // Attempt to complete the current unit of work, then move to the next
19813 // sibling. If there are no more siblings, return to the parent fiber.
19814 workInProgress = unitOfWork;
19815 do {
19816 // The current, flushed, state of this fiber is the alternate. Ideally
19817 // nothing should rely on this, but relying on it here means that we don't
19818 // need an additional field on the work in progress.
19819 var current$$1 = workInProgress.alternate;
19820 var returnFiber = workInProgress.return;
19821
19822 // Check if the work completed or if something threw.
19823 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
19824 setCurrentFiber(workInProgress);
19825 var next = void 0;
19826 if (
19827 !enableProfilerTimer ||
19828 (workInProgress.mode & ProfileMode) === NoMode
19829 ) {
19830 next = completeWork(current$$1, workInProgress, renderExpirationTime);
19831 } else {
19832 startProfilerTimer(workInProgress);
19833 next = completeWork(current$$1, workInProgress, renderExpirationTime);
19834 // Update render duration assuming we didn't error.
19835 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
19836 }
19837 stopWorkTimer(workInProgress);
19838 resetCurrentFiber();
19839 resetChildExpirationTime(workInProgress);
19840
19841 if (next !== null) {
19842 // Completing this fiber spawned new work. Work on that next.
19843 return next;
19844 }
19845
19846 if (
19847 returnFiber !== null &&
19848 // Do not append effects to parents if a sibling failed to complete
19849 (returnFiber.effectTag & Incomplete) === NoEffect
19850 ) {
19851 // Append all the effects of the subtree and this fiber onto the effect
19852 // list of the parent. The completion order of the children affects the
19853 // side-effect order.
19854 if (returnFiber.firstEffect === null) {
19855 returnFiber.firstEffect = workInProgress.firstEffect;
19856 }
19857 if (workInProgress.lastEffect !== null) {
19858 if (returnFiber.lastEffect !== null) {
19859 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
19860 }
19861 returnFiber.lastEffect = workInProgress.lastEffect;
19862 }
19863
19864 // If this fiber had side-effects, we append it AFTER the children's
19865 // side-effects. We can perform certain side-effects earlier if needed,
19866 // by doing multiple passes over the effect list. We don't want to
19867 // schedule our own side-effect on our own list because if end up
19868 // reusing children we'll schedule this effect onto itself since we're
19869 // at the end.
19870 var effectTag = workInProgress.effectTag;
19871
19872 // Skip both NoWork and PerformedWork tags when creating the effect
19873 // list. PerformedWork effect is read by React DevTools but shouldn't be
19874 // committed.
19875 if (effectTag > PerformedWork) {
19876 if (returnFiber.lastEffect !== null) {
19877 returnFiber.lastEffect.nextEffect = workInProgress;
19878 } else {
19879 returnFiber.firstEffect = workInProgress;
19880 }
19881 returnFiber.lastEffect = workInProgress;
19882 }
19883 }
19884 } else {
19885 // This fiber did not complete because something threw. Pop values off
19886 // the stack without entering the complete phase. If this is a boundary,
19887 // capture values if possible.
19888 var _next = unwindWork(workInProgress, renderExpirationTime);
19889
19890 // Because this fiber did not complete, don't reset its expiration time.
19891
19892 if (
19893 enableProfilerTimer &&
19894 (workInProgress.mode & ProfileMode) !== NoMode
19895 ) {
19896 // Record the render duration for the fiber that errored.
19897 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
19898
19899 // Include the time spent working on failed children before continuing.
19900 var actualDuration = workInProgress.actualDuration;
19901 var child = workInProgress.child;
19902 while (child !== null) {
19903 actualDuration += child.actualDuration;
19904 child = child.sibling;
19905 }
19906 workInProgress.actualDuration = actualDuration;
19907 }
19908
19909 if (_next !== null) {
19910 // If completing this work spawned new work, do that next. We'll come
19911 // back here again.
19912 // Since we're restarting, remove anything that is not a host effect
19913 // from the effect tag.
19914 // TODO: The name stopFailedWorkTimer is misleading because Suspense
19915 // also captures and restarts.
19916 stopFailedWorkTimer(workInProgress);
19917 _next.effectTag &= HostEffectMask;
19918 return _next;
19919 }
19920 stopWorkTimer(workInProgress);
19921
19922 if (returnFiber !== null) {
19923 // Mark the parent fiber as incomplete and clear its effect list.
19924 returnFiber.firstEffect = returnFiber.lastEffect = null;
19925 returnFiber.effectTag |= Incomplete;
19926 }
19927 }
19928
19929 var siblingFiber = workInProgress.sibling;
19930 if (siblingFiber !== null) {
19931 // If there is more work to do in this returnFiber, do that next.
19932 return siblingFiber;
19933 }
19934 // Otherwise, return to the parent
19935 workInProgress = returnFiber;
19936 } while (workInProgress !== null);
19937
19938 // We've reached the root.
19939 if (workInProgressRootExitStatus === RootIncomplete) {
19940 workInProgressRootExitStatus = RootCompleted;
19941 }
19942 return null;
19943}
19944
19945function resetChildExpirationTime(completedWork) {
19946 if (
19947 renderExpirationTime !== Never &&
19948 completedWork.childExpirationTime === Never
19949 ) {
19950 // The children of this component are hidden. Don't bubble their
19951 // expiration times.
19952 return;
19953 }
19954
19955 var newChildExpirationTime = NoWork;
19956
19957 // Bubble up the earliest expiration time.
19958 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
19959 // In profiling mode, resetChildExpirationTime is also used to reset
19960 // profiler durations.
19961 var actualDuration = completedWork.actualDuration;
19962 var treeBaseDuration = completedWork.selfBaseDuration;
19963
19964 // When a fiber is cloned, its actualDuration is reset to 0. This value will
19965 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
19966 // When work is done, it should bubble to the parent's actualDuration. If
19967 // the fiber has not been cloned though, (meaning no work was done), then
19968 // this value will reflect the amount of time spent working on a previous
19969 // render. In that case it should not bubble. We determine whether it was
19970 // cloned by comparing the child pointer.
19971 var shouldBubbleActualDurations =
19972 completedWork.alternate === null ||
19973 completedWork.child !== completedWork.alternate.child;
19974
19975 var child = completedWork.child;
19976 while (child !== null) {
19977 var childUpdateExpirationTime = child.expirationTime;
19978 var childChildExpirationTime = child.childExpirationTime;
19979 if (childUpdateExpirationTime > newChildExpirationTime) {
19980 newChildExpirationTime = childUpdateExpirationTime;
19981 }
19982 if (childChildExpirationTime > newChildExpirationTime) {
19983 newChildExpirationTime = childChildExpirationTime;
19984 }
19985 if (shouldBubbleActualDurations) {
19986 actualDuration += child.actualDuration;
19987 }
19988 treeBaseDuration += child.treeBaseDuration;
19989 child = child.sibling;
19990 }
19991 completedWork.actualDuration = actualDuration;
19992 completedWork.treeBaseDuration = treeBaseDuration;
19993 } else {
19994 var _child = completedWork.child;
19995 while (_child !== null) {
19996 var _childUpdateExpirationTime = _child.expirationTime;
19997 var _childChildExpirationTime = _child.childExpirationTime;
19998 if (_childUpdateExpirationTime > newChildExpirationTime) {
19999 newChildExpirationTime = _childUpdateExpirationTime;
20000 }
20001 if (_childChildExpirationTime > newChildExpirationTime) {
20002 newChildExpirationTime = _childChildExpirationTime;
20003 }
20004 _child = _child.sibling;
20005 }
20006 }
20007
20008 completedWork.childExpirationTime = newChildExpirationTime;
20009}
20010
20011function commitRoot(root) {
20012 var renderPriorityLevel = getCurrentPriorityLevel();
20013 runWithPriority$1(
20014 ImmediatePriority,
20015 commitRootImpl.bind(null, root, renderPriorityLevel)
20016 );
20017 // If there are passive effects, schedule a callback to flush them. This goes
20018 // outside commitRootImpl so that it inherits the priority of the render.
20019 if (rootWithPendingPassiveEffects !== null) {
20020 scheduleCallback(NormalPriority, function() {
20021 flushPassiveEffects();
20022 return null;
20023 });
20024 }
20025 return null;
20026}
20027
20028function commitRootImpl(root, renderPriorityLevel) {
20029 flushPassiveEffects();
20030 flushRenderPhaseStrictModeWarningsInDEV();
20031
20032 (function() {
20033 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
20034 throw ReactError(Error("Should not already be working."));
20035 }
20036 })();
20037
20038 var finishedWork = root.finishedWork;
20039 var expirationTime = root.finishedExpirationTime;
20040 if (finishedWork === null) {
20041 return null;
20042 }
20043 root.finishedWork = null;
20044 root.finishedExpirationTime = NoWork;
20045
20046 (function() {
20047 if (!(finishedWork !== root.current)) {
20048 throw ReactError(
20049 Error(
20050 "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue."
20051 )
20052 );
20053 }
20054 })();
20055
20056 // commitRoot never returns a continuation; it always finishes synchronously.
20057 // So we can clear these now to allow a new callback to be scheduled.
20058 root.callbackNode = null;
20059 root.callbackExpirationTime = NoWork;
20060
20061 startCommitTimer();
20062
20063 // Update the first and last pending times on this root. The new first
20064 // pending time is whatever is left on the root fiber.
20065 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
20066 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
20067 var firstPendingTimeBeforeCommit =
20068 childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit
20069 ? childExpirationTimeBeforeCommit
20070 : updateExpirationTimeBeforeCommit;
20071 root.firstPendingTime = firstPendingTimeBeforeCommit;
20072 if (firstPendingTimeBeforeCommit < root.lastPendingTime) {
20073 // This usually means we've finished all the work, but it can also happen
20074 // when something gets downprioritized during render, like a hidden tree.
20075 root.lastPendingTime = firstPendingTimeBeforeCommit;
20076 }
20077
20078 if (root === workInProgressRoot) {
20079 // We can reset these now that they are finished.
20080 workInProgressRoot = null;
20081 workInProgress = null;
20082 renderExpirationTime = NoWork;
20083 } else {
20084 }
20085 // This indicates that the last root we worked on is not the same one that
20086 // we're committing now. This most commonly happens when a suspended root
20087 // times out.
20088
20089 // Get the list of effects.
20090 var firstEffect = void 0;
20091 if (finishedWork.effectTag > PerformedWork) {
20092 // A fiber's effect list consists only of its children, not itself. So if
20093 // the root has an effect, we need to add it to the end of the list. The
20094 // resulting list is the set that would belong to the root's parent, if it
20095 // had one; that is, all the effects in the tree including the root.
20096 if (finishedWork.lastEffect !== null) {
20097 finishedWork.lastEffect.nextEffect = finishedWork;
20098 firstEffect = finishedWork.firstEffect;
20099 } else {
20100 firstEffect = finishedWork;
20101 }
20102 } else {
20103 // There is no effect on the root.
20104 firstEffect = finishedWork.firstEffect;
20105 }
20106
20107 if (firstEffect !== null) {
20108 var prevExecutionContext = executionContext;
20109 executionContext |= CommitContext;
20110 var prevInteractions = null;
20111 if (enableSchedulerTracing) {
20112 prevInteractions = tracing.__interactionsRef.current;
20113 tracing.__interactionsRef.current = root.memoizedInteractions;
20114 }
20115
20116 // Reset this to null before calling lifecycles
20117 ReactCurrentOwner$2.current = null;
20118
20119 // The commit phase is broken into several sub-phases. We do a separate pass
20120 // of the effect list for each phase: all mutation effects come before all
20121 // layout effects, and so on.
20122
20123 // The first phase a "before mutation" phase. We use this phase to read the
20124 // state of the host tree right before we mutate it. This is where
20125 // getSnapshotBeforeUpdate is called.
20126 startCommitSnapshotEffectsTimer();
20127 prepareForCommit(root.containerInfo);
20128 nextEffect = firstEffect;
20129 do {
20130 {
20131 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
20132 if (hasCaughtError()) {
20133 (function() {
20134 if (!(nextEffect !== null)) {
20135 throw ReactError(Error("Should be working on an effect."));
20136 }
20137 })();
20138 var error = clearCaughtError();
20139 captureCommitPhaseError(nextEffect, error);
20140 nextEffect = nextEffect.nextEffect;
20141 }
20142 }
20143 } while (nextEffect !== null);
20144 stopCommitSnapshotEffectsTimer();
20145
20146 if (enableProfilerTimer) {
20147 // Mark the current commit time to be shared by all Profilers in this
20148 // batch. This enables them to be grouped later.
20149 recordCommitTime();
20150 }
20151
20152 // The next phase is the mutation phase, where we mutate the host tree.
20153 startCommitHostEffectsTimer();
20154 nextEffect = firstEffect;
20155 do {
20156 {
20157 invokeGuardedCallback(
20158 null,
20159 commitMutationEffects,
20160 null,
20161 renderPriorityLevel
20162 );
20163 if (hasCaughtError()) {
20164 (function() {
20165 if (!(nextEffect !== null)) {
20166 throw ReactError(Error("Should be working on an effect."));
20167 }
20168 })();
20169 var _error = clearCaughtError();
20170 captureCommitPhaseError(nextEffect, _error);
20171 nextEffect = nextEffect.nextEffect;
20172 }
20173 }
20174 } while (nextEffect !== null);
20175 stopCommitHostEffectsTimer();
20176 resetAfterCommit(root.containerInfo);
20177
20178 // The work-in-progress tree is now the current tree. This must come after
20179 // the mutation phase, so that the previous tree is still current during
20180 // componentWillUnmount, but before the layout phase, so that the finished
20181 // work is current during componentDidMount/Update.
20182 root.current = finishedWork;
20183
20184 // The next phase is the layout phase, where we call effects that read
20185 // the host tree after it's been mutated. The idiomatic use case for this is
20186 // layout, but class component lifecycles also fire here for legacy reasons.
20187 startCommitLifeCyclesTimer();
20188 nextEffect = firstEffect;
20189 do {
20190 {
20191 invokeGuardedCallback(
20192 null,
20193 commitLayoutEffects,
20194 null,
20195 root,
20196 expirationTime
20197 );
20198 if (hasCaughtError()) {
20199 (function() {
20200 if (!(nextEffect !== null)) {
20201 throw ReactError(Error("Should be working on an effect."));
20202 }
20203 })();
20204 var _error2 = clearCaughtError();
20205 captureCommitPhaseError(nextEffect, _error2);
20206 nextEffect = nextEffect.nextEffect;
20207 }
20208 }
20209 } while (nextEffect !== null);
20210 stopCommitLifeCyclesTimer();
20211
20212 nextEffect = null;
20213
20214 // Tell Scheduler to yield at the end of the frame, so the browser has an
20215 // opportunity to paint.
20216 requestPaint();
20217
20218 if (enableSchedulerTracing) {
20219 tracing.__interactionsRef.current = prevInteractions;
20220 }
20221 executionContext = prevExecutionContext;
20222 } else {
20223 // No effects.
20224 root.current = finishedWork;
20225 // Measure these anyway so the flamegraph explicitly shows that there were
20226 // no effects.
20227 // TODO: Maybe there's a better way to report this.
20228 startCommitSnapshotEffectsTimer();
20229 stopCommitSnapshotEffectsTimer();
20230 if (enableProfilerTimer) {
20231 recordCommitTime();
20232 }
20233 startCommitHostEffectsTimer();
20234 stopCommitHostEffectsTimer();
20235 startCommitLifeCyclesTimer();
20236 stopCommitLifeCyclesTimer();
20237 }
20238
20239 stopCommitTimer();
20240
20241 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
20242
20243 if (rootDoesHavePassiveEffects) {
20244 // This commit has passive effects. Stash a reference to them. But don't
20245 // schedule a callback until after flushing layout work.
20246 rootDoesHavePassiveEffects = false;
20247 rootWithPendingPassiveEffects = root;
20248 pendingPassiveEffectsExpirationTime = expirationTime;
20249 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
20250 } else {
20251 // We are done with the effect chain at this point so let's clear the
20252 // nextEffect pointers to assist with GC. If we have passive effects, we'll
20253 // clear this in flushPassiveEffects.
20254 nextEffect = firstEffect;
20255 while (nextEffect !== null) {
20256 var nextNextEffect = nextEffect.nextEffect;
20257 nextEffect.nextEffect = null;
20258 nextEffect = nextNextEffect;
20259 }
20260 }
20261
20262 // Check if there's remaining work on this root
20263 var remainingExpirationTime = root.firstPendingTime;
20264 if (remainingExpirationTime !== NoWork) {
20265 var currentTime = requestCurrentTime();
20266 var priorityLevel = inferPriorityFromExpirationTime(
20267 currentTime,
20268 remainingExpirationTime
20269 );
20270
20271 if (enableSchedulerTracing) {
20272 if (spawnedWorkDuringRender !== null) {
20273 var expirationTimes = spawnedWorkDuringRender;
20274 spawnedWorkDuringRender = null;
20275 for (var i = 0; i < expirationTimes.length; i++) {
20276 scheduleInteractions(
20277 root,
20278 expirationTimes[i],
20279 root.memoizedInteractions
20280 );
20281 }
20282 }
20283 }
20284
20285 scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);
20286 } else {
20287 // If there's no remaining work, we can clear the set of already failed
20288 // error boundaries.
20289 legacyErrorBoundariesThatAlreadyFailed = null;
20290 }
20291
20292 if (enableSchedulerTracing) {
20293 if (!rootDidHavePassiveEffects) {
20294 // If there are no passive effects, then we can complete the pending interactions.
20295 // Otherwise, we'll wait until after the passive effects are flushed.
20296 // Wait to do this until after remaining work has been scheduled,
20297 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
20298 finishPendingInteractions(root, expirationTime);
20299 }
20300 }
20301
20302 onCommitRoot(finishedWork.stateNode, expirationTime);
20303
20304 if (remainingExpirationTime === Sync) {
20305 // Count the number of times the root synchronously re-renders without
20306 // finishing. If there are too many, it indicates an infinite update loop.
20307 if (root === rootWithNestedUpdates) {
20308 nestedUpdateCount++;
20309 } else {
20310 nestedUpdateCount = 0;
20311 rootWithNestedUpdates = root;
20312 }
20313 } else {
20314 nestedUpdateCount = 0;
20315 }
20316
20317 if (hasUncaughtError) {
20318 hasUncaughtError = false;
20319 var _error3 = firstUncaughtError;
20320 firstUncaughtError = null;
20321 throw _error3;
20322 }
20323
20324 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
20325 // This is a legacy edge case. We just committed the initial mount of
20326 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
20327 // synchronously, but layout updates should be deferred until the end
20328 // of the batch.
20329 return null;
20330 }
20331
20332 // If layout work was scheduled, flush it now.
20333 flushSyncCallbackQueue();
20334 return null;
20335}
20336
20337function commitBeforeMutationEffects() {
20338 while (nextEffect !== null) {
20339 if ((nextEffect.effectTag & Snapshot) !== NoEffect) {
20340 setCurrentFiber(nextEffect);
20341 recordEffect();
20342
20343 var current$$1 = nextEffect.alternate;
20344 commitBeforeMutationLifeCycles(current$$1, nextEffect);
20345
20346 resetCurrentFiber();
20347 }
20348 nextEffect = nextEffect.nextEffect;
20349 }
20350}
20351
20352function commitMutationEffects(renderPriorityLevel) {
20353 // TODO: Should probably move the bulk of this function to commitWork.
20354 while (nextEffect !== null) {
20355 setCurrentFiber(nextEffect);
20356
20357 var effectTag = nextEffect.effectTag;
20358
20359 if (effectTag & ContentReset) {
20360 commitResetTextContent(nextEffect);
20361 }
20362
20363 if (effectTag & Ref) {
20364 var current$$1 = nextEffect.alternate;
20365 if (current$$1 !== null) {
20366 commitDetachRef(current$$1);
20367 }
20368 }
20369
20370 // The following switch statement is only concerned about placement,
20371 // updates, and deletions. To avoid needing to add a case for every possible
20372 // bitmap value, we remove the secondary effects from the effect tag and
20373 // switch on that value.
20374 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
20375 switch (primaryEffectTag) {
20376 case Placement: {
20377 commitPlacement(nextEffect);
20378 // Clear the "placement" from effect tag so that we know that this is
20379 // inserted, before any life-cycles like componentDidMount gets called.
20380 // TODO: findDOMNode doesn't rely on this any more but isMounted does
20381 // and isMounted is deprecated anyway so we should be able to kill this.
20382 nextEffect.effectTag &= ~Placement;
20383 break;
20384 }
20385 case PlacementAndUpdate: {
20386 // Placement
20387 commitPlacement(nextEffect);
20388 // Clear the "placement" from effect tag so that we know that this is
20389 // inserted, before any life-cycles like componentDidMount gets called.
20390 nextEffect.effectTag &= ~Placement;
20391
20392 // Update
20393 var _current = nextEffect.alternate;
20394 commitWork(_current, nextEffect);
20395 break;
20396 }
20397 case Update: {
20398 var _current2 = nextEffect.alternate;
20399 commitWork(_current2, nextEffect);
20400 break;
20401 }
20402 case Deletion: {
20403 commitDeletion(nextEffect, renderPriorityLevel);
20404 break;
20405 }
20406 }
20407
20408 // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
20409 recordEffect();
20410
20411 resetCurrentFiber();
20412 nextEffect = nextEffect.nextEffect;
20413 }
20414}
20415
20416function commitLayoutEffects(root, committedExpirationTime) {
20417 // TODO: Should probably move the bulk of this function to commitWork.
20418 while (nextEffect !== null) {
20419 setCurrentFiber(nextEffect);
20420
20421 var effectTag = nextEffect.effectTag;
20422
20423 if (effectTag & (Update | Callback)) {
20424 recordEffect();
20425 var current$$1 = nextEffect.alternate;
20426 commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime);
20427 }
20428
20429 if (effectTag & Ref) {
20430 recordEffect();
20431 commitAttachRef(nextEffect);
20432 }
20433
20434 if (effectTag & Passive) {
20435 rootDoesHavePassiveEffects = true;
20436 }
20437
20438 resetCurrentFiber();
20439 nextEffect = nextEffect.nextEffect;
20440 }
20441}
20442
20443function flushPassiveEffects() {
20444 if (rootWithPendingPassiveEffects === null) {
20445 return false;
20446 }
20447 var root = rootWithPendingPassiveEffects;
20448 var expirationTime = pendingPassiveEffectsExpirationTime;
20449 var renderPriorityLevel = pendingPassiveEffectsRenderPriority;
20450 rootWithPendingPassiveEffects = null;
20451 pendingPassiveEffectsExpirationTime = NoWork;
20452 pendingPassiveEffectsRenderPriority = NoPriority;
20453 var priorityLevel =
20454 renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
20455 return runWithPriority$1(
20456 priorityLevel,
20457 flushPassiveEffectsImpl.bind(null, root, expirationTime)
20458 );
20459}
20460
20461function flushPassiveEffectsImpl(root, expirationTime) {
20462 var prevInteractions = null;
20463 if (enableSchedulerTracing) {
20464 prevInteractions = tracing.__interactionsRef.current;
20465 tracing.__interactionsRef.current = root.memoizedInteractions;
20466 }
20467
20468 (function() {
20469 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
20470 throw ReactError(
20471 Error("Cannot flush passive effects while already rendering.")
20472 );
20473 }
20474 })();
20475 var prevExecutionContext = executionContext;
20476 executionContext |= CommitContext;
20477
20478 // Note: This currently assumes there are no passive effects on the root
20479 // fiber, because the root is not part of its own effect list. This could
20480 // change in the future.
20481 var effect = root.current.firstEffect;
20482 while (effect !== null) {
20483 {
20484 setCurrentFiber(effect);
20485 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
20486 if (hasCaughtError()) {
20487 (function() {
20488 if (!(effect !== null)) {
20489 throw ReactError(Error("Should be working on an effect."));
20490 }
20491 })();
20492 var error = clearCaughtError();
20493 captureCommitPhaseError(effect, error);
20494 }
20495 resetCurrentFiber();
20496 }
20497 var nextNextEffect = effect.nextEffect;
20498 // Remove nextEffect pointer to assist GC
20499 effect.nextEffect = null;
20500 effect = nextNextEffect;
20501 }
20502
20503 if (enableSchedulerTracing) {
20504 tracing.__interactionsRef.current = prevInteractions;
20505 finishPendingInteractions(root, expirationTime);
20506 }
20507
20508 executionContext = prevExecutionContext;
20509 flushSyncCallbackQueue();
20510
20511 // If additional passive effects were scheduled, increment a counter. If this
20512 // exceeds the limit, we'll fire a warning.
20513 nestedPassiveUpdateCount =
20514 rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
20515
20516 return true;
20517}
20518
20519function isAlreadyFailedLegacyErrorBoundary(instance) {
20520 return (
20521 legacyErrorBoundariesThatAlreadyFailed !== null &&
20522 legacyErrorBoundariesThatAlreadyFailed.has(instance)
20523 );
20524}
20525
20526function markLegacyErrorBoundaryAsFailed(instance) {
20527 if (legacyErrorBoundariesThatAlreadyFailed === null) {
20528 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
20529 } else {
20530 legacyErrorBoundariesThatAlreadyFailed.add(instance);
20531 }
20532}
20533
20534function prepareToThrowUncaughtError(error) {
20535 if (!hasUncaughtError) {
20536 hasUncaughtError = true;
20537 firstUncaughtError = error;
20538 }
20539}
20540var onUncaughtError = prepareToThrowUncaughtError;
20541
20542function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
20543 var errorInfo = createCapturedValue(error, sourceFiber);
20544 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
20545 enqueueUpdate(rootFiber, update);
20546 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
20547 if (root !== null) {
20548 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
20549 }
20550}
20551
20552function captureCommitPhaseError(sourceFiber, error) {
20553 if (sourceFiber.tag === HostRoot) {
20554 // Error was thrown at the root. There is no parent, so the root
20555 // itself should capture it.
20556 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
20557 return;
20558 }
20559
20560 var fiber = sourceFiber.return;
20561 while (fiber !== null) {
20562 if (fiber.tag === HostRoot) {
20563 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
20564 return;
20565 } else if (fiber.tag === ClassComponent) {
20566 var ctor = fiber.type;
20567 var instance = fiber.stateNode;
20568 if (
20569 typeof ctor.getDerivedStateFromError === "function" ||
20570 (typeof instance.componentDidCatch === "function" &&
20571 !isAlreadyFailedLegacyErrorBoundary(instance))
20572 ) {
20573 var errorInfo = createCapturedValue(error, sourceFiber);
20574 var update = createClassErrorUpdate(
20575 fiber,
20576 errorInfo,
20577 // TODO: This is always sync
20578 Sync
20579 );
20580 enqueueUpdate(fiber, update);
20581 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
20582 if (root !== null) {
20583 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
20584 }
20585 return;
20586 }
20587 }
20588 fiber = fiber.return;
20589 }
20590}
20591
20592function pingSuspendedRoot(root, thenable, suspendedTime) {
20593 var pingCache = root.pingCache;
20594 if (pingCache !== null) {
20595 // The thenable resolved, so we no longer need to memoize, because it will
20596 // never be thrown again.
20597 pingCache.delete(thenable);
20598 }
20599
20600 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
20601 // Received a ping at the same priority level at which we're currently
20602 // rendering. We might want to restart this render. This should mirror
20603 // the logic of whether or not a root suspends once it completes.
20604
20605 // TODO: If we're rendering sync either due to Sync, Batched or expired,
20606 // we should probably never restart.
20607
20608 // If we're suspended with delay, we'll always suspend so we can always
20609 // restart. If we're suspended without any updates, it might be a retry.
20610 // If it's early in the retry we can restart. We can't know for sure
20611 // whether we'll eventually process an update during this render pass,
20612 // but it's somewhat unlikely that we get to a ping before that, since
20613 // getting to the root most update is usually very fast.
20614 if (
20615 workInProgressRootExitStatus === RootSuspendedWithDelay ||
20616 (workInProgressRootExitStatus === RootSuspended &&
20617 workInProgressRootLatestProcessedExpirationTime === Sync &&
20618 now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS)
20619 ) {
20620 // Restart from the root. Don't need to schedule a ping because
20621 // we're already working on this tree.
20622 prepareFreshStack(root, renderExpirationTime);
20623 } else {
20624 // Even though we can't restart right now, we might get an
20625 // opportunity later. So we mark this render as having a ping.
20626 workInProgressRootHasPendingPing = true;
20627 }
20628 return;
20629 }
20630
20631 var lastPendingTime = root.lastPendingTime;
20632 if (lastPendingTime < suspendedTime) {
20633 // The root is no longer suspended at this time.
20634 return;
20635 }
20636
20637 var pingTime = root.pingTime;
20638 if (pingTime !== NoWork && pingTime < suspendedTime) {
20639 // There's already a lower priority ping scheduled.
20640 return;
20641 }
20642
20643 // Mark the time at which this ping was scheduled.
20644 root.pingTime = suspendedTime;
20645
20646 if (root.finishedExpirationTime === suspendedTime) {
20647 // If there's a pending fallback waiting to commit, throw it away.
20648 root.finishedExpirationTime = NoWork;
20649 root.finishedWork = null;
20650 }
20651
20652 var currentTime = requestCurrentTime();
20653 var priorityLevel = inferPriorityFromExpirationTime(
20654 currentTime,
20655 suspendedTime
20656 );
20657 scheduleCallbackForRoot(root, priorityLevel, suspendedTime);
20658}
20659
20660function retryTimedOutBoundary(boundaryFiber) {
20661 // The boundary fiber (a Suspense component or SuspenseList component)
20662 // previously was rendered in its fallback state. One of the promises that
20663 // suspended it has resolved, which means at least part of the tree was
20664 // likely unblocked. Try rendering again, at a new expiration time.
20665 var currentTime = requestCurrentTime();
20666 var suspenseConfig = null; // Retries don't carry over the already committed update.
20667 var retryTime = computeExpirationForFiber(
20668 currentTime,
20669 boundaryFiber,
20670 suspenseConfig
20671 );
20672 // TODO: Special case idle priority?
20673 var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);
20674 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
20675 if (root !== null) {
20676 scheduleCallbackForRoot(root, priorityLevel, retryTime);
20677 }
20678}
20679
20680function resolveRetryThenable(boundaryFiber, thenable) {
20681 var retryCache = void 0;
20682 if (enableSuspenseServerRenderer) {
20683 switch (boundaryFiber.tag) {
20684 case SuspenseComponent:
20685 retryCache = boundaryFiber.stateNode;
20686 break;
20687 case DehydratedSuspenseComponent:
20688 retryCache = boundaryFiber.memoizedState;
20689 break;
20690 default:
20691 (function() {
20692 {
20693 throw ReactError(
20694 Error(
20695 "Pinged unknown suspense boundary type. This is probably a bug in React."
20696 )
20697 );
20698 }
20699 })();
20700 }
20701 } else {
20702 retryCache = boundaryFiber.stateNode;
20703 }
20704
20705 if (retryCache !== null) {
20706 // The thenable resolved, so we no longer need to memoize, because it will
20707 // never be thrown again.
20708 retryCache.delete(thenable);
20709 }
20710
20711 retryTimedOutBoundary(boundaryFiber);
20712}
20713
20714// Computes the next Just Noticeable Difference (JND) boundary.
20715// The theory is that a person can't tell the difference between small differences in time.
20716// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
20717// difference in the experience. However, waiting for longer might mean that we can avoid
20718// showing an intermediate loading state. The longer we have already waited, the harder it
20719// is to tell small differences in time. Therefore, the longer we've already waited,
20720// the longer we can wait additionally. At some point we have to give up though.
20721// We pick a train model where the next boundary commits at a consistent schedule.
20722// These particular numbers are vague estimates. We expect to adjust them based on research.
20723function jnd(timeElapsed) {
20724 return timeElapsed < 120
20725 ? 120
20726 : timeElapsed < 480
20727 ? 480
20728 : timeElapsed < 1080
20729 ? 1080
20730 : timeElapsed < 1920
20731 ? 1920
20732 : timeElapsed < 3000
20733 ? 3000
20734 : timeElapsed < 4320
20735 ? 4320
20736 : ceil(timeElapsed / 1960) * 1960;
20737}
20738
20739function computeMsUntilSuspenseLoadingDelay(
20740 mostRecentEventTime,
20741 committedExpirationTime,
20742 suspenseConfig
20743) {
20744 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
20745 if (busyMinDurationMs <= 0) {
20746 return 0;
20747 }
20748 var busyDelayMs = suspenseConfig.busyDelayMs | 0;
20749
20750 // Compute the time until this render pass would expire.
20751 var currentTimeMs = now();
20752 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(
20753 mostRecentEventTime,
20754 suspenseConfig
20755 );
20756 var timeElapsed = currentTimeMs - eventTimeMs;
20757 if (timeElapsed <= busyDelayMs) {
20758 // If we haven't yet waited longer than the initial delay, we don't
20759 // have to wait any additional time.
20760 return 0;
20761 }
20762 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed;
20763 // This is the value that is passed to `setTimeout`.
20764 return msUntilTimeout;
20765}
20766
20767function checkForNestedUpdates() {
20768 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
20769 nestedUpdateCount = 0;
20770 rootWithNestedUpdates = null;
20771 (function() {
20772 {
20773 throw ReactError(
20774 Error(
20775 "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops."
20776 )
20777 );
20778 }
20779 })();
20780 }
20781
20782 {
20783 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
20784 nestedPassiveUpdateCount = 0;
20785 warning$1(
20786 false,
20787 "Maximum update depth exceeded. This can happen when a component " +
20788 "calls setState inside useEffect, but useEffect either doesn't " +
20789 "have a dependency array, or one of the dependencies changes on " +
20790 "every render."
20791 );
20792 }
20793 }
20794}
20795
20796function flushRenderPhaseStrictModeWarningsInDEV() {
20797 {
20798 ReactStrictModeWarnings.flushLegacyContextWarning();
20799
20800 if (warnAboutDeprecatedLifecycles) {
20801 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
20802 }
20803 }
20804}
20805
20806function stopFinishedWorkLoopTimer() {
20807 var didCompleteRoot = true;
20808 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
20809 interruptedBy = null;
20810}
20811
20812function stopInterruptedWorkLoopTimer() {
20813 // TODO: Track which fiber caused the interruption.
20814 var didCompleteRoot = false;
20815 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
20816 interruptedBy = null;
20817}
20818
20819function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
20820 if (
20821 enableUserTimingAPI &&
20822 workInProgressRoot !== null &&
20823 updateExpirationTime > renderExpirationTime
20824 ) {
20825 interruptedBy = fiberThatReceivedUpdate;
20826 }
20827}
20828
20829var didWarnStateUpdateForUnmountedComponent = null;
20830function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
20831 {
20832 var tag = fiber.tag;
20833 if (
20834 tag !== HostRoot &&
20835 tag !== ClassComponent &&
20836 tag !== FunctionComponent &&
20837 tag !== ForwardRef &&
20838 tag !== MemoComponent &&
20839 tag !== SimpleMemoComponent
20840 ) {
20841 // Only warn for user-defined components, not internal ones like Suspense.
20842 return;
20843 }
20844 // We show the whole stack but dedupe on the top component's name because
20845 // the problematic code almost always lies inside that component.
20846 var componentName = getComponentName(fiber.type) || "ReactComponent";
20847 if (didWarnStateUpdateForUnmountedComponent !== null) {
20848 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
20849 return;
20850 }
20851 didWarnStateUpdateForUnmountedComponent.add(componentName);
20852 } else {
20853 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
20854 }
20855 warningWithoutStack$1(
20856 false,
20857 "Can't perform a React state update on an unmounted component. This " +
20858 "is a no-op, but it indicates a memory leak in your application. To " +
20859 "fix, cancel all subscriptions and asynchronous tasks in %s.%s",
20860 tag === ClassComponent
20861 ? "the componentWillUnmount method"
20862 : "a useEffect cleanup function",
20863 getStackByFiberInDevAndProd(fiber)
20864 );
20865 }
20866}
20867
20868var beginWork$$1 = void 0;
20869if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
20870 var dummyFiber = null;
20871 beginWork$$1 = function(current$$1, unitOfWork, expirationTime) {
20872 // If a component throws an error, we replay it again in a synchronously
20873 // dispatched event, so that the debugger will treat it as an uncaught
20874 // error See ReactErrorUtils for more information.
20875
20876 // Before entering the begin phase, copy the work-in-progress onto a dummy
20877 // fiber. If beginWork throws, we'll use this to reset the state.
20878 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(
20879 dummyFiber,
20880 unitOfWork
20881 );
20882 try {
20883 return beginWork$1(current$$1, unitOfWork, expirationTime);
20884 } catch (originalError) {
20885 if (
20886 originalError !== null &&
20887 typeof originalError === "object" &&
20888 typeof originalError.then === "function"
20889 ) {
20890 // Don't replay promises. Treat everything else like an error.
20891 throw originalError;
20892 }
20893
20894 // Keep this code in sync with renderRoot; any changes here must have
20895 // corresponding changes there.
20896 resetContextDependencies();
20897 resetHooks();
20898
20899 // Unwind the failed stack frame
20900 unwindInterruptedWork(unitOfWork);
20901
20902 // Restore the original properties of the fiber.
20903 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
20904
20905 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
20906 // Reset the profiler timer.
20907 startProfilerTimer(unitOfWork);
20908 }
20909
20910 // Run beginWork again.
20911 invokeGuardedCallback(
20912 null,
20913 beginWork$1,
20914 null,
20915 current$$1,
20916 unitOfWork,
20917 expirationTime
20918 );
20919
20920 if (hasCaughtError()) {
20921 var replayError = clearCaughtError();
20922 // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
20923 // Rethrow this error instead of the original one.
20924 throw replayError;
20925 } else {
20926 // This branch is reachable if the render phase is impure.
20927 throw originalError;
20928 }
20929 }
20930 };
20931} else {
20932 beginWork$$1 = beginWork$1;
20933}
20934
20935var didWarnAboutUpdateInRender = false;
20936var didWarnAboutUpdateInGetChildContext = false;
20937function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
20938 {
20939 if (fiber.tag === ClassComponent) {
20940 switch (phase) {
20941 case "getChildContext":
20942 if (didWarnAboutUpdateInGetChildContext) {
20943 return;
20944 }
20945 warningWithoutStack$1(
20946 false,
20947 "setState(...): Cannot call setState() inside getChildContext()"
20948 );
20949 didWarnAboutUpdateInGetChildContext = true;
20950 break;
20951 case "render":
20952 if (didWarnAboutUpdateInRender) {
20953 return;
20954 }
20955 warningWithoutStack$1(
20956 false,
20957 "Cannot update during an existing state transition (such as " +
20958 "within `render`). Render methods should be a pure function of " +
20959 "props and state."
20960 );
20961 didWarnAboutUpdateInRender = true;
20962 break;
20963 }
20964 }
20965 }
20966}
20967
20968// a 'shared' variable that changes when act() opens/closes in tests.
20969var IsThisRendererActing = { current: false };
20970
20971function warnIfNotScopedWithMatchingAct(fiber) {
20972 {
20973 if (
20974 warnsIfNotActing === true &&
20975 IsSomeRendererActing.current === true &&
20976 IsThisRendererActing.current !== true
20977 ) {
20978 warningWithoutStack$1(
20979 false,
20980 "It looks like you're using the wrong act() around your test interactions.\n" +
20981 "Be sure to use the matching version of act() corresponding to your renderer:\n\n" +
20982 "// for react-dom:\n" +
20983 "import {act} from 'react-dom/test-utils';\n" +
20984 "// ...\n" +
20985 "act(() => ...);\n\n" +
20986 "// for react-test-renderer:\n" +
20987 "import TestRenderer from 'react-test-renderer';\n" +
20988 "const {act} = TestRenderer;\n" +
20989 "// ...\n" +
20990 "act(() => ...);" +
20991 "%s",
20992 getStackByFiberInDevAndProd(fiber)
20993 );
20994 }
20995 }
20996}
20997
20998function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
20999 {
21000 if (
21001 warnsIfNotActing === true &&
21002 (fiber.mode & StrictMode) !== NoMode &&
21003 IsSomeRendererActing.current === false &&
21004 IsThisRendererActing.current === false
21005 ) {
21006 warningWithoutStack$1(
21007 false,
21008 "An update to %s ran an effect, but was not wrapped in act(...).\n\n" +
21009 "When testing, code that causes React state updates should be " +
21010 "wrapped into act(...):\n\n" +
21011 "act(() => {\n" +
21012 " /* fire events that update state */\n" +
21013 "});\n" +
21014 "/* assert on the output */\n\n" +
21015 "This ensures that you're testing the behavior the user would see " +
21016 "in the browser." +
21017 " Learn more at https://fb.me/react-wrap-tests-with-act" +
21018 "%s",
21019 getComponentName(fiber.type),
21020 getStackByFiberInDevAndProd(fiber)
21021 );
21022 }
21023 }
21024}
21025
21026function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
21027 {
21028 if (
21029 warnsIfNotActing === true &&
21030 executionContext === NoContext &&
21031 IsSomeRendererActing.current === false &&
21032 IsThisRendererActing.current === false
21033 ) {
21034 warningWithoutStack$1(
21035 false,
21036 "An update to %s inside a test was not wrapped in act(...).\n\n" +
21037 "When testing, code that causes React state updates should be " +
21038 "wrapped into act(...):\n\n" +
21039 "act(() => {\n" +
21040 " /* fire events that update state */\n" +
21041 "});\n" +
21042 "/* assert on the output */\n\n" +
21043 "This ensures that you're testing the behavior the user would see " +
21044 "in the browser." +
21045 " Learn more at https://fb.me/react-wrap-tests-with-act" +
21046 "%s",
21047 getComponentName(fiber.type),
21048 getStackByFiberInDevAndProd(fiber)
21049 );
21050 }
21051 }
21052}
21053
21054var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV;
21055
21056// In tests, we want to enforce a mocked scheduler.
21057var didWarnAboutUnmockedScheduler = false;
21058// TODO Before we release concurrent mode, revisit this and decide whether a mocked
21059// scheduler is the actual recommendation. The alternative could be a testing build,
21060// a new lib, or whatever; we dunno just yet. This message is for early adopters
21061// to get their tests right.
21062
21063function warnIfUnmockedScheduler(fiber) {
21064 {
21065 if (
21066 didWarnAboutUnmockedScheduler === false &&
21067 Scheduler.unstable_flushAllWithoutAsserting === undefined
21068 ) {
21069 if (fiber.mode & BatchedMode || fiber.mode & ConcurrentMode) {
21070 didWarnAboutUnmockedScheduler = true;
21071 warningWithoutStack$1(
21072 false,
21073 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' +
21074 "to guarantee consistent behaviour across tests and browsers. " +
21075 "For example, with jest: \n" +
21076 "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" +
21077 "For more info, visit https://fb.me/react-mock-scheduler"
21078 );
21079 } else if (warnAboutUnmockedScheduler === true) {
21080 didWarnAboutUnmockedScheduler = true;
21081 warningWithoutStack$1(
21082 false,
21083 'Starting from React v17, the "scheduler" module will need to be mocked ' +
21084 "to guarantee consistent behaviour across tests and browsers. " +
21085 "For example, with jest: \n" +
21086 "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" +
21087 "For more info, visit https://fb.me/react-mock-scheduler"
21088 );
21089 }
21090 }
21091 }
21092}
21093
21094var componentsThatTriggeredHighPriSuspend = null;
21095function checkForWrongSuspensePriorityInDEV(sourceFiber) {
21096 {
21097 var currentPriorityLevel = getCurrentPriorityLevel();
21098 if (
21099 (sourceFiber.mode & ConcurrentMode) !== NoEffect &&
21100 (currentPriorityLevel === UserBlockingPriority$1 ||
21101 currentPriorityLevel === ImmediatePriority)
21102 ) {
21103 var workInProgressNode = sourceFiber;
21104 while (workInProgressNode !== null) {
21105 // Add the component that triggered the suspense
21106 var current$$1 = workInProgressNode.alternate;
21107 if (current$$1 !== null) {
21108 // TODO: warn component that triggers the high priority
21109 // suspend is the HostRoot
21110 switch (workInProgressNode.tag) {
21111 case ClassComponent:
21112 // Loop through the component's update queue and see whether the component
21113 // has triggered any high priority updates
21114 var updateQueue = current$$1.updateQueue;
21115 if (updateQueue !== null) {
21116 var update = updateQueue.firstUpdate;
21117 while (update !== null) {
21118 var priorityLevel = update.priority;
21119 if (
21120 priorityLevel === UserBlockingPriority$1 ||
21121 priorityLevel === ImmediatePriority
21122 ) {
21123 if (componentsThatTriggeredHighPriSuspend === null) {
21124 componentsThatTriggeredHighPriSuspend = new Set([
21125 getComponentName(workInProgressNode.type)
21126 ]);
21127 } else {
21128 componentsThatTriggeredHighPriSuspend.add(
21129 getComponentName(workInProgressNode.type)
21130 );
21131 }
21132 break;
21133 }
21134 update = update.next;
21135 }
21136 }
21137 break;
21138 case FunctionComponent:
21139 case ForwardRef:
21140 case SimpleMemoComponent:
21141 if (
21142 workInProgressNode.memoizedState !== null &&
21143 workInProgressNode.memoizedState.baseUpdate !== null
21144 ) {
21145 var _update = workInProgressNode.memoizedState.baseUpdate;
21146 // Loop through the functional component's memoized state to see whether
21147 // the component has triggered any high pri updates
21148 while (_update !== null) {
21149 var priority = _update.priority;
21150 if (
21151 priority === UserBlockingPriority$1 ||
21152 priority === ImmediatePriority
21153 ) {
21154 if (componentsThatTriggeredHighPriSuspend === null) {
21155 componentsThatTriggeredHighPriSuspend = new Set([
21156 getComponentName(workInProgressNode.type)
21157 ]);
21158 } else {
21159 componentsThatTriggeredHighPriSuspend.add(
21160 getComponentName(workInProgressNode.type)
21161 );
21162 }
21163 break;
21164 }
21165 if (
21166 _update.next === workInProgressNode.memoizedState.baseUpdate
21167 ) {
21168 break;
21169 }
21170 _update = _update.next;
21171 }
21172 }
21173 break;
21174 default:
21175 break;
21176 }
21177 }
21178 workInProgressNode = workInProgressNode.return;
21179 }
21180 }
21181 }
21182}
21183
21184function flushSuspensePriorityWarningInDEV() {
21185 {
21186 if (componentsThatTriggeredHighPriSuspend !== null) {
21187 var componentNames = [];
21188 componentsThatTriggeredHighPriSuspend.forEach(function(name) {
21189 return componentNames.push(name);
21190 });
21191 componentsThatTriggeredHighPriSuspend = null;
21192
21193 if (componentNames.length > 0) {
21194 warningWithoutStack$1(
21195 false,
21196 "%s triggered a user-blocking update that suspended." +
21197 "\n\n" +
21198 "The fix is to split the update into multiple parts: a user-blocking " +
21199 "update to provide immediate feedback, and another update that " +
21200 "triggers the bulk of the changes." +
21201 "\n\n" +
21202 "Refer to the documentation for useSuspenseTransition to learn how " +
21203 "to implement this pattern.",
21204 // TODO: Add link to React docs with more information, once it exists
21205 componentNames.sort().join(", ")
21206 );
21207 }
21208 }
21209 }
21210}
21211
21212function computeThreadID(root, expirationTime) {
21213 // Interaction threads are unique per root and expiration time.
21214 return expirationTime * 1000 + root.interactionThreadID;
21215}
21216
21217function markSpawnedWork(expirationTime) {
21218 if (!enableSchedulerTracing) {
21219 return;
21220 }
21221 if (spawnedWorkDuringRender === null) {
21222 spawnedWorkDuringRender = [expirationTime];
21223 } else {
21224 spawnedWorkDuringRender.push(expirationTime);
21225 }
21226}
21227
21228function scheduleInteractions(root, expirationTime, interactions) {
21229 if (!enableSchedulerTracing) {
21230 return;
21231 }
21232
21233 if (interactions.size > 0) {
21234 var pendingInteractionMap = root.pendingInteractionMap;
21235 var pendingInteractions = pendingInteractionMap.get(expirationTime);
21236 if (pendingInteractions != null) {
21237 interactions.forEach(function(interaction) {
21238 if (!pendingInteractions.has(interaction)) {
21239 // Update the pending async work count for previously unscheduled interaction.
21240 interaction.__count++;
21241 }
21242
21243 pendingInteractions.add(interaction);
21244 });
21245 } else {
21246 pendingInteractionMap.set(expirationTime, new Set(interactions));
21247
21248 // Update the pending async work count for the current interactions.
21249 interactions.forEach(function(interaction) {
21250 interaction.__count++;
21251 });
21252 }
21253
21254 var subscriber = tracing.__subscriberRef.current;
21255 if (subscriber !== null) {
21256 var threadID = computeThreadID(root, expirationTime);
21257 subscriber.onWorkScheduled(interactions, threadID);
21258 }
21259 }
21260}
21261
21262function schedulePendingInteractions(root, expirationTime) {
21263 // This is called when work is scheduled on a root.
21264 // It associates the current interactions with the newly-scheduled expiration.
21265 // They will be restored when that expiration is later committed.
21266 if (!enableSchedulerTracing) {
21267 return;
21268 }
21269
21270 scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current);
21271}
21272
21273function startWorkOnPendingInteractions(root, expirationTime) {
21274 // This is called when new work is started on a root.
21275 if (!enableSchedulerTracing) {
21276 return;
21277 }
21278
21279 // Determine which interactions this batch of work currently includes, So that
21280 // we can accurately attribute time spent working on it, And so that cascading
21281 // work triggered during the render phase will be associated with it.
21282 var interactions = new Set();
21283 root.pendingInteractionMap.forEach(function(
21284 scheduledInteractions,
21285 scheduledExpirationTime
21286 ) {
21287 if (scheduledExpirationTime >= expirationTime) {
21288 scheduledInteractions.forEach(function(interaction) {
21289 return interactions.add(interaction);
21290 });
21291 }
21292 });
21293
21294 // Store the current set of interactions on the FiberRoot for a few reasons:
21295 // We can re-use it in hot functions like renderRoot() without having to
21296 // recalculate it. We will also use it in commitWork() to pass to any Profiler
21297 // onRender() hooks. This also provides DevTools with a way to access it when
21298 // the onCommitRoot() hook is called.
21299 root.memoizedInteractions = interactions;
21300
21301 if (interactions.size > 0) {
21302 var subscriber = tracing.__subscriberRef.current;
21303 if (subscriber !== null) {
21304 var threadID = computeThreadID(root, expirationTime);
21305 try {
21306 subscriber.onWorkStarted(interactions, threadID);
21307 } catch (error) {
21308 // If the subscriber throws, rethrow it in a separate task
21309 scheduleCallback(ImmediatePriority, function() {
21310 throw error;
21311 });
21312 }
21313 }
21314 }
21315}
21316
21317function finishPendingInteractions(root, committedExpirationTime) {
21318 if (!enableSchedulerTracing) {
21319 return;
21320 }
21321
21322 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
21323
21324 var subscriber = void 0;
21325
21326 try {
21327 subscriber = tracing.__subscriberRef.current;
21328 if (subscriber !== null && root.memoizedInteractions.size > 0) {
21329 var threadID = computeThreadID(root, committedExpirationTime);
21330 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
21331 }
21332 } catch (error) {
21333 // If the subscriber throws, rethrow it in a separate task
21334 scheduleCallback(ImmediatePriority, function() {
21335 throw error;
21336 });
21337 } finally {
21338 // Clear completed interactions from the pending Map.
21339 // Unless the render was suspended or cascading work was scheduled,
21340 // In which case– leave pending interactions until the subsequent render.
21341 var pendingInteractionMap = root.pendingInteractionMap;
21342 pendingInteractionMap.forEach(function(
21343 scheduledInteractions,
21344 scheduledExpirationTime
21345 ) {
21346 // Only decrement the pending interaction count if we're done.
21347 // If there's still work at the current priority,
21348 // That indicates that we are waiting for suspense data.
21349 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
21350 pendingInteractionMap.delete(scheduledExpirationTime);
21351
21352 scheduledInteractions.forEach(function(interaction) {
21353 interaction.__count--;
21354
21355 if (subscriber !== null && interaction.__count === 0) {
21356 try {
21357 subscriber.onInteractionScheduledWorkCompleted(interaction);
21358 } catch (error) {
21359 // If the subscriber throws, rethrow it in a separate task
21360 scheduleCallback(ImmediatePriority, function() {
21361 throw error;
21362 });
21363 }
21364 }
21365 });
21366 }
21367 });
21368 }
21369}
21370
21371var onCommitFiberRoot = null;
21372var onCommitFiberUnmount = null;
21373var hasLoggedError = false;
21374
21375var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined";
21376
21377function injectInternals(internals) {
21378 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") {
21379 // No DevTools
21380 return false;
21381 }
21382 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
21383 if (hook.isDisabled) {
21384 // This isn't a real property on the hook, but it can be set to opt out
21385 // of DevTools integration and associated warnings and logs.
21386 // https://github.com/facebook/react/issues/3877
21387 return true;
21388 }
21389 if (!hook.supportsFiber) {
21390 {
21391 warningWithoutStack$1(
21392 false,
21393 "The installed version of React DevTools is too old and will not work " +
21394 "with the current version of React. Please update React DevTools. " +
21395 "https://fb.me/react-devtools"
21396 );
21397 }
21398 // DevTools exists, even though it doesn't support Fiber.
21399 return true;
21400 }
21401 try {
21402 var rendererID = hook.inject(internals);
21403 // We have successfully injected, so now it is safe to set up hooks.
21404 onCommitFiberRoot = function(root, expirationTime) {
21405 try {
21406 var didError = (root.current.effectTag & DidCapture) === DidCapture;
21407 if (enableProfilerTimer) {
21408 var currentTime = requestCurrentTime();
21409 var priorityLevel = inferPriorityFromExpirationTime(
21410 currentTime,
21411 expirationTime
21412 );
21413 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
21414 } else {
21415 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
21416 }
21417 } catch (err) {
21418 if (true && !hasLoggedError) {
21419 hasLoggedError = true;
21420 warningWithoutStack$1(
21421 false,
21422 "React DevTools encountered an error: %s",
21423 err
21424 );
21425 }
21426 }
21427 };
21428 onCommitFiberUnmount = function(fiber) {
21429 try {
21430 hook.onCommitFiberUnmount(rendererID, fiber);
21431 } catch (err) {
21432 if (true && !hasLoggedError) {
21433 hasLoggedError = true;
21434 warningWithoutStack$1(
21435 false,
21436 "React DevTools encountered an error: %s",
21437 err
21438 );
21439 }
21440 }
21441 };
21442 } catch (err) {
21443 // Catch all errors because it is unsafe to throw during initialization.
21444 {
21445 warningWithoutStack$1(
21446 false,
21447 "React DevTools encountered an error: %s.",
21448 err
21449 );
21450 }
21451 }
21452 // DevTools exists
21453 return true;
21454}
21455
21456function onCommitRoot(root, expirationTime) {
21457 if (typeof onCommitFiberRoot === "function") {
21458 onCommitFiberRoot(root, expirationTime);
21459 }
21460}
21461
21462function onCommitUnmount(fiber) {
21463 if (typeof onCommitFiberUnmount === "function") {
21464 onCommitFiberUnmount(fiber);
21465 }
21466}
21467
21468var hasBadMapPolyfill = void 0;
21469
21470{
21471 hasBadMapPolyfill = false;
21472 try {
21473 var nonExtensibleObject = Object.preventExtensions({});
21474 var testMap = new Map([[nonExtensibleObject, null]]);
21475 var testSet = new Set([nonExtensibleObject]);
21476 // This is necessary for Rollup to not consider these unused.
21477 // https://github.com/rollup/rollup/issues/1771
21478 // TODO: we can remove these if Rollup fixes the bug.
21479 testMap.set(0, 0);
21480 testSet.add(0);
21481 } catch (e) {
21482 // TODO: Consider warning about bad polyfills
21483 hasBadMapPolyfill = true;
21484 }
21485}
21486
21487// A Fiber is work on a Component that needs to be done or was done. There can
21488// be more than one per component.
21489
21490var debugCounter = void 0;
21491
21492{
21493 debugCounter = 1;
21494}
21495
21496function FiberNode(tag, pendingProps, key, mode) {
21497 // Instance
21498 this.tag = tag;
21499 this.key = key;
21500 this.elementType = null;
21501 this.type = null;
21502 this.stateNode = null;
21503
21504 // Fiber
21505 this.return = null;
21506 this.child = null;
21507 this.sibling = null;
21508 this.index = 0;
21509
21510 this.ref = null;
21511
21512 this.pendingProps = pendingProps;
21513 this.memoizedProps = null;
21514 this.updateQueue = null;
21515 this.memoizedState = null;
21516 this.dependencies = null;
21517
21518 this.mode = mode;
21519
21520 // Effects
21521 this.effectTag = NoEffect;
21522 this.nextEffect = null;
21523
21524 this.firstEffect = null;
21525 this.lastEffect = null;
21526
21527 this.expirationTime = NoWork;
21528 this.childExpirationTime = NoWork;
21529
21530 this.alternate = null;
21531
21532 if (enableProfilerTimer) {
21533 // Note: The following is done to avoid a v8 performance cliff.
21534 //
21535 // Initializing the fields below to smis and later updating them with
21536 // double values will cause Fibers to end up having separate shapes.
21537 // This behavior/bug has something to do with Object.preventExtension().
21538 // Fortunately this only impacts DEV builds.
21539 // Unfortunately it makes React unusably slow for some applications.
21540 // To work around this, initialize the fields below with doubles.
21541 //
21542 // Learn more about this here:
21543 // https://github.com/facebook/react/issues/14365
21544 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
21545 this.actualDuration = Number.NaN;
21546 this.actualStartTime = Number.NaN;
21547 this.selfBaseDuration = Number.NaN;
21548 this.treeBaseDuration = Number.NaN;
21549
21550 // It's okay to replace the initial doubles with smis after initialization.
21551 // This won't trigger the performance cliff mentioned above,
21552 // and it simplifies other profiler code (including DevTools).
21553 this.actualDuration = 0;
21554 this.actualStartTime = -1;
21555 this.selfBaseDuration = 0;
21556 this.treeBaseDuration = 0;
21557 }
21558
21559 {
21560 this._debugID = debugCounter++;
21561 this._debugSource = null;
21562 this._debugOwner = null;
21563 this._debugIsCurrentlyTiming = false;
21564 this._debugNeedsRemount = false;
21565 this._debugHookTypes = null;
21566 if (!hasBadMapPolyfill && typeof Object.preventExtensions === "function") {
21567 Object.preventExtensions(this);
21568 }
21569 }
21570}
21571
21572// This is a constructor function, rather than a POJO constructor, still
21573// please ensure we do the following:
21574// 1) Nobody should add any instance methods on this. Instance methods can be
21575// more difficult to predict when they get optimized and they are almost
21576// never inlined properly in static compilers.
21577// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
21578// always know when it is a fiber.
21579// 3) We might want to experiment with using numeric keys since they are easier
21580// to optimize in a non-JIT environment.
21581// 4) We can easily go from a constructor to a createFiber object literal if that
21582// is faster.
21583// 5) It should be easy to port this to a C struct and keep a C implementation
21584// compatible.
21585var createFiber = function(tag, pendingProps, key, mode) {
21586 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
21587 return new FiberNode(tag, pendingProps, key, mode);
21588};
21589
21590function shouldConstruct(Component) {
21591 var prototype = Component.prototype;
21592 return !!(prototype && prototype.isReactComponent);
21593}
21594
21595function isSimpleFunctionComponent(type) {
21596 return (
21597 typeof type === "function" &&
21598 !shouldConstruct(type) &&
21599 type.defaultProps === undefined
21600 );
21601}
21602
21603function resolveLazyComponentTag(Component) {
21604 if (typeof Component === "function") {
21605 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
21606 } else if (Component !== undefined && Component !== null) {
21607 var $$typeof = Component.$$typeof;
21608 if ($$typeof === REACT_FORWARD_REF_TYPE) {
21609 return ForwardRef;
21610 }
21611 if ($$typeof === REACT_MEMO_TYPE) {
21612 return MemoComponent;
21613 }
21614 }
21615 return IndeterminateComponent;
21616}
21617
21618// This is used to create an alternate fiber to do work on.
21619function createWorkInProgress(current, pendingProps, expirationTime) {
21620 var workInProgress = current.alternate;
21621 if (workInProgress === null) {
21622 // We use a double buffering pooling technique because we know that we'll
21623 // only ever need at most two versions of a tree. We pool the "other" unused
21624 // node that we're free to reuse. This is lazily created to avoid allocating
21625 // extra objects for things that are never updated. It also allow us to
21626 // reclaim the extra memory if needed.
21627 workInProgress = createFiber(
21628 current.tag,
21629 pendingProps,
21630 current.key,
21631 current.mode
21632 );
21633 workInProgress.elementType = current.elementType;
21634 workInProgress.type = current.type;
21635 workInProgress.stateNode = current.stateNode;
21636
21637 {
21638 // DEV-only fields
21639 workInProgress._debugID = current._debugID;
21640 workInProgress._debugSource = current._debugSource;
21641 workInProgress._debugOwner = current._debugOwner;
21642 workInProgress._debugHookTypes = current._debugHookTypes;
21643 }
21644
21645 workInProgress.alternate = current;
21646 current.alternate = workInProgress;
21647 } else {
21648 workInProgress.pendingProps = pendingProps;
21649
21650 // We already have an alternate.
21651 // Reset the effect tag.
21652 workInProgress.effectTag = NoEffect;
21653
21654 // The effect list is no longer valid.
21655 workInProgress.nextEffect = null;
21656 workInProgress.firstEffect = null;
21657 workInProgress.lastEffect = null;
21658
21659 if (enableProfilerTimer) {
21660 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
21661 // This prevents time from endlessly accumulating in new commits.
21662 // This has the downside of resetting values for different priority renders,
21663 // But works for yielding (the common case) and should support resuming.
21664 workInProgress.actualDuration = 0;
21665 workInProgress.actualStartTime = -1;
21666 }
21667 }
21668
21669 workInProgress.childExpirationTime = current.childExpirationTime;
21670 workInProgress.expirationTime = current.expirationTime;
21671
21672 workInProgress.child = current.child;
21673 workInProgress.memoizedProps = current.memoizedProps;
21674 workInProgress.memoizedState = current.memoizedState;
21675 workInProgress.updateQueue = current.updateQueue;
21676
21677 // Clone the dependencies object. This is mutated during the render phase, so
21678 // it cannot be shared with the current fiber.
21679 var currentDependencies = current.dependencies;
21680 workInProgress.dependencies =
21681 currentDependencies === null
21682 ? null
21683 : {
21684 expirationTime: currentDependencies.expirationTime,
21685 firstContext: currentDependencies.firstContext,
21686 responders: currentDependencies.responders
21687 };
21688
21689 // These will be overridden during the parent's reconciliation
21690 workInProgress.sibling = current.sibling;
21691 workInProgress.index = current.index;
21692 workInProgress.ref = current.ref;
21693
21694 if (enableProfilerTimer) {
21695 workInProgress.selfBaseDuration = current.selfBaseDuration;
21696 workInProgress.treeBaseDuration = current.treeBaseDuration;
21697 }
21698
21699 {
21700 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
21701 switch (workInProgress.tag) {
21702 case IndeterminateComponent:
21703 case FunctionComponent:
21704 case SimpleMemoComponent:
21705 workInProgress.type = resolveFunctionForHotReloading(current.type);
21706 break;
21707 case ClassComponent:
21708 workInProgress.type = resolveClassForHotReloading(current.type);
21709 break;
21710 case ForwardRef:
21711 workInProgress.type = resolveForwardRefForHotReloading(current.type);
21712 break;
21713 default:
21714 break;
21715 }
21716 }
21717
21718 return workInProgress;
21719}
21720
21721// Used to reuse a Fiber for a second pass.
21722function resetWorkInProgress(workInProgress, renderExpirationTime) {
21723 // This resets the Fiber to what createFiber or createWorkInProgress would
21724 // have set the values to before during the first pass. Ideally this wouldn't
21725 // be necessary but unfortunately many code paths reads from the workInProgress
21726 // when they should be reading from current and writing to workInProgress.
21727
21728 // We assume pendingProps, index, key, ref, return are still untouched to
21729 // avoid doing another reconciliation.
21730
21731 // Reset the effect tag but keep any Placement tags, since that's something
21732 // that child fiber is setting, not the reconciliation.
21733 workInProgress.effectTag &= Placement;
21734
21735 // The effect list is no longer valid.
21736 workInProgress.nextEffect = null;
21737 workInProgress.firstEffect = null;
21738 workInProgress.lastEffect = null;
21739
21740 var current = workInProgress.alternate;
21741 if (current === null) {
21742 // Reset to createFiber's initial values.
21743 workInProgress.childExpirationTime = NoWork;
21744 workInProgress.expirationTime = renderExpirationTime;
21745
21746 workInProgress.child = null;
21747 workInProgress.memoizedProps = null;
21748 workInProgress.memoizedState = null;
21749 workInProgress.updateQueue = null;
21750
21751 workInProgress.dependencies = null;
21752
21753 if (enableProfilerTimer) {
21754 // Note: We don't reset the actualTime counts. It's useful to accumulate
21755 // actual time across multiple render passes.
21756 workInProgress.selfBaseDuration = 0;
21757 workInProgress.treeBaseDuration = 0;
21758 }
21759 } else {
21760 // Reset to the cloned values that createWorkInProgress would've.
21761 workInProgress.childExpirationTime = current.childExpirationTime;
21762 workInProgress.expirationTime = current.expirationTime;
21763
21764 workInProgress.child = current.child;
21765 workInProgress.memoizedProps = current.memoizedProps;
21766 workInProgress.memoizedState = current.memoizedState;
21767 workInProgress.updateQueue = current.updateQueue;
21768
21769 // Clone the dependencies object. This is mutated during the render phase, so
21770 // it cannot be shared with the current fiber.
21771 var currentDependencies = current.dependencies;
21772 workInProgress.dependencies =
21773 currentDependencies === null
21774 ? null
21775 : {
21776 expirationTime: currentDependencies.expirationTime,
21777 firstContext: currentDependencies.firstContext,
21778 responders: currentDependencies.responders
21779 };
21780
21781 if (enableProfilerTimer) {
21782 // Note: We don't reset the actualTime counts. It's useful to accumulate
21783 // actual time across multiple render passes.
21784 workInProgress.selfBaseDuration = current.selfBaseDuration;
21785 workInProgress.treeBaseDuration = current.treeBaseDuration;
21786 }
21787 }
21788
21789 return workInProgress;
21790}
21791
21792function createHostRootFiber(tag) {
21793 var mode = void 0;
21794 if (tag === ConcurrentRoot) {
21795 mode = ConcurrentMode | BatchedMode | StrictMode;
21796 } else if (tag === BatchedRoot) {
21797 mode = BatchedMode | StrictMode;
21798 } else {
21799 mode = NoMode;
21800 }
21801
21802 if (enableProfilerTimer && isDevToolsPresent) {
21803 // Always collect profile timings when DevTools are present.
21804 // This enables DevTools to start capturing timing at any point–
21805 // Without some nodes in the tree having empty base times.
21806 mode |= ProfileMode;
21807 }
21808
21809 return createFiber(HostRoot, null, null, mode);
21810}
21811
21812function createFiberFromTypeAndProps(
21813 type, // React$ElementType
21814 key,
21815 pendingProps,
21816 owner,
21817 mode,
21818 expirationTime
21819) {
21820 var fiber = void 0;
21821
21822 var fiberTag = IndeterminateComponent;
21823 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
21824 var resolvedType = type;
21825 if (typeof type === "function") {
21826 if (shouldConstruct(type)) {
21827 fiberTag = ClassComponent;
21828 {
21829 resolvedType = resolveClassForHotReloading(resolvedType);
21830 }
21831 } else {
21832 {
21833 resolvedType = resolveFunctionForHotReloading(resolvedType);
21834 }
21835 }
21836 } else if (typeof type === "string") {
21837 fiberTag = HostComponent;
21838 } else {
21839 getTag: switch (type) {
21840 case REACT_FRAGMENT_TYPE:
21841 return createFiberFromFragment(
21842 pendingProps.children,
21843 mode,
21844 expirationTime,
21845 key
21846 );
21847 case REACT_CONCURRENT_MODE_TYPE:
21848 fiberTag = Mode;
21849 mode |= ConcurrentMode | BatchedMode | StrictMode;
21850 break;
21851 case REACT_STRICT_MODE_TYPE:
21852 fiberTag = Mode;
21853 mode |= StrictMode;
21854 break;
21855 case REACT_PROFILER_TYPE:
21856 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
21857 case REACT_SUSPENSE_TYPE:
21858 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
21859 case REACT_SUSPENSE_LIST_TYPE:
21860 return createFiberFromSuspenseList(
21861 pendingProps,
21862 mode,
21863 expirationTime,
21864 key
21865 );
21866 default: {
21867 if (typeof type === "object" && type !== null) {
21868 switch (type.$$typeof) {
21869 case REACT_PROVIDER_TYPE:
21870 fiberTag = ContextProvider;
21871 break getTag;
21872 case REACT_CONTEXT_TYPE:
21873 // This is a consumer
21874 fiberTag = ContextConsumer;
21875 break getTag;
21876 case REACT_FORWARD_REF_TYPE:
21877 fiberTag = ForwardRef;
21878 {
21879 resolvedType = resolveForwardRefForHotReloading(resolvedType);
21880 }
21881 break getTag;
21882 case REACT_MEMO_TYPE:
21883 fiberTag = MemoComponent;
21884 break getTag;
21885 case REACT_LAZY_TYPE:
21886 fiberTag = LazyComponent;
21887 resolvedType = null;
21888 break getTag;
21889 case REACT_FUNDAMENTAL_TYPE:
21890 if (enableFundamentalAPI) {
21891 return createFiberFromFundamental(
21892 type,
21893 pendingProps,
21894 mode,
21895 expirationTime,
21896 key
21897 );
21898 }
21899 break;
21900 }
21901 }
21902 var info = "";
21903 {
21904 if (
21905 type === undefined ||
21906 (typeof type === "object" &&
21907 type !== null &&
21908 Object.keys(type).length === 0)
21909 ) {
21910 info +=
21911 " You likely forgot to export your component from the file " +
21912 "it's defined in, or you might have mixed up default and " +
21913 "named imports.";
21914 }
21915 var ownerName = owner ? getComponentName(owner.type) : null;
21916 if (ownerName) {
21917 info += "\n\nCheck the render method of `" + ownerName + "`.";
21918 }
21919 }
21920 (function() {
21921 {
21922 throw ReactError(
21923 Error(
21924 "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " +
21925 (type == null ? type : typeof type) +
21926 "." +
21927 info
21928 )
21929 );
21930 }
21931 })();
21932 }
21933 }
21934 }
21935
21936 fiber = createFiber(fiberTag, pendingProps, key, mode);
21937 fiber.elementType = type;
21938 fiber.type = resolvedType;
21939 fiber.expirationTime = expirationTime;
21940
21941 return fiber;
21942}
21943
21944function createFiberFromElement(element, mode, expirationTime) {
21945 var owner = null;
21946 {
21947 owner = element._owner;
21948 }
21949 var type = element.type;
21950 var key = element.key;
21951 var pendingProps = element.props;
21952 var fiber = createFiberFromTypeAndProps(
21953 type,
21954 key,
21955 pendingProps,
21956 owner,
21957 mode,
21958 expirationTime
21959 );
21960 {
21961 fiber._debugSource = element._source;
21962 fiber._debugOwner = element._owner;
21963 }
21964 return fiber;
21965}
21966
21967function createFiberFromFragment(elements, mode, expirationTime, key) {
21968 var fiber = createFiber(Fragment, elements, key, mode);
21969 fiber.expirationTime = expirationTime;
21970 return fiber;
21971}
21972
21973function createFiberFromFundamental(
21974 fundamentalComponent,
21975 pendingProps,
21976 mode,
21977 expirationTime,
21978 key
21979) {
21980 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
21981 fiber.elementType = fundamentalComponent;
21982 fiber.type = fundamentalComponent;
21983 fiber.expirationTime = expirationTime;
21984 return fiber;
21985}
21986
21987function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
21988 {
21989 if (
21990 typeof pendingProps.id !== "string" ||
21991 typeof pendingProps.onRender !== "function"
21992 ) {
21993 warningWithoutStack$1(
21994 false,
21995 'Profiler must specify an "id" string and "onRender" function as props'
21996 );
21997 }
21998 }
21999
22000 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
22001 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
22002 fiber.elementType = REACT_PROFILER_TYPE;
22003 fiber.type = REACT_PROFILER_TYPE;
22004 fiber.expirationTime = expirationTime;
22005
22006 return fiber;
22007}
22008
22009function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
22010 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
22011
22012 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
22013 // This needs to be fixed in getComponentName so that it relies on the tag
22014 // instead.
22015 fiber.type = REACT_SUSPENSE_TYPE;
22016 fiber.elementType = REACT_SUSPENSE_TYPE;
22017
22018 fiber.expirationTime = expirationTime;
22019 return fiber;
22020}
22021
22022function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
22023 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
22024 {
22025 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
22026 // This needs to be fixed in getComponentName so that it relies on the tag
22027 // instead.
22028 fiber.type = REACT_SUSPENSE_LIST_TYPE;
22029 }
22030 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
22031 fiber.expirationTime = expirationTime;
22032 return fiber;
22033}
22034
22035function createFiberFromText(content, mode, expirationTime) {
22036 var fiber = createFiber(HostText, content, null, mode);
22037 fiber.expirationTime = expirationTime;
22038 return fiber;
22039}
22040
22041function createFiberFromHostInstanceForDeletion() {
22042 var fiber = createFiber(HostComponent, null, null, NoMode);
22043 // TODO: These should not need a type.
22044 fiber.elementType = "DELETED";
22045 fiber.type = "DELETED";
22046 return fiber;
22047}
22048
22049function createFiberFromPortal(portal, mode, expirationTime) {
22050 var pendingProps = portal.children !== null ? portal.children : [];
22051 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
22052 fiber.expirationTime = expirationTime;
22053 fiber.stateNode = {
22054 containerInfo: portal.containerInfo,
22055 pendingChildren: null, // Used by persistent updates
22056 implementation: portal.implementation
22057 };
22058 return fiber;
22059}
22060
22061// Used for stashing WIP properties to replay failed work in DEV.
22062function assignFiberPropertiesInDEV(target, source) {
22063 if (target === null) {
22064 // This Fiber's initial properties will always be overwritten.
22065 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
22066 target = createFiber(IndeterminateComponent, null, null, NoMode);
22067 }
22068
22069 // This is intentionally written as a list of all properties.
22070 // We tried to use Object.assign() instead but this is called in
22071 // the hottest path, and Object.assign() was too slow:
22072 // https://github.com/facebook/react/issues/12502
22073 // This code is DEV-only so size is not a concern.
22074
22075 target.tag = source.tag;
22076 target.key = source.key;
22077 target.elementType = source.elementType;
22078 target.type = source.type;
22079 target.stateNode = source.stateNode;
22080 target.return = source.return;
22081 target.child = source.child;
22082 target.sibling = source.sibling;
22083 target.index = source.index;
22084 target.ref = source.ref;
22085 target.pendingProps = source.pendingProps;
22086 target.memoizedProps = source.memoizedProps;
22087 target.updateQueue = source.updateQueue;
22088 target.memoizedState = source.memoizedState;
22089 target.dependencies = source.dependencies;
22090 target.mode = source.mode;
22091 target.effectTag = source.effectTag;
22092 target.nextEffect = source.nextEffect;
22093 target.firstEffect = source.firstEffect;
22094 target.lastEffect = source.lastEffect;
22095 target.expirationTime = source.expirationTime;
22096 target.childExpirationTime = source.childExpirationTime;
22097 target.alternate = source.alternate;
22098 if (enableProfilerTimer) {
22099 target.actualDuration = source.actualDuration;
22100 target.actualStartTime = source.actualStartTime;
22101 target.selfBaseDuration = source.selfBaseDuration;
22102 target.treeBaseDuration = source.treeBaseDuration;
22103 }
22104 target._debugID = source._debugID;
22105 target._debugSource = source._debugSource;
22106 target._debugOwner = source._debugOwner;
22107 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
22108 target._debugNeedsRemount = source._debugNeedsRemount;
22109 target._debugHookTypes = source._debugHookTypes;
22110 return target;
22111}
22112
22113// TODO: This should be lifted into the renderer.
22114
22115// The following attributes are only used by interaction tracing builds.
22116// They enable interactions to be associated with their async work,
22117// And expose interaction metadata to the React DevTools Profiler plugin.
22118// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
22119
22120// Exported FiberRoot type includes all properties,
22121// To avoid requiring potentially error-prone :any casts throughout the project.
22122// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
22123// The types are defined separately within this file to ensure they stay in sync.
22124// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
22125
22126function FiberRootNode(containerInfo, tag, hydrate) {
22127 this.tag = tag;
22128 this.current = null;
22129 this.containerInfo = containerInfo;
22130 this.pendingChildren = null;
22131 this.pingCache = null;
22132 this.finishedExpirationTime = NoWork;
22133 this.finishedWork = null;
22134 this.timeoutHandle = noTimeout;
22135 this.context = null;
22136 this.pendingContext = null;
22137 this.hydrate = hydrate;
22138 this.firstBatch = null;
22139 this.callbackNode = null;
22140 this.callbackExpirationTime = NoWork;
22141 this.firstPendingTime = NoWork;
22142 this.lastPendingTime = NoWork;
22143 this.pingTime = NoWork;
22144
22145 if (enableSchedulerTracing) {
22146 this.interactionThreadID = tracing.unstable_getThreadID();
22147 this.memoizedInteractions = new Set();
22148 this.pendingInteractionMap = new Map();
22149 }
22150}
22151
22152function createFiberRoot(containerInfo, tag, hydrate) {
22153 var root = new FiberRootNode(containerInfo, tag, hydrate);
22154
22155 // Cyclic construction. This cheats the type system right now because
22156 // stateNode is any.
22157 var uninitializedFiber = createHostRootFiber(tag);
22158 root.current = uninitializedFiber;
22159 uninitializedFiber.stateNode = root;
22160
22161 return root;
22162}
22163
22164// This lets us hook into Fiber to debug what it's doing.
22165// See https://github.com/facebook/react/pull/8033.
22166// This is not part of the public API, not even for React DevTools.
22167// You may only inject a debugTool if you work on React Fiber itself.
22168var ReactFiberInstrumentation = {
22169 debugTool: null
22170};
22171
22172var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
22173
22174// 0 is PROD, 1 is DEV.
22175// Might add PROFILE later.
22176
22177var didWarnAboutNestedUpdates = void 0;
22178var didWarnAboutFindNodeInStrictMode = void 0;
22179
22180{
22181 didWarnAboutNestedUpdates = false;
22182 didWarnAboutFindNodeInStrictMode = {};
22183}
22184
22185function getContextForSubtree(parentComponent) {
22186 if (!parentComponent) {
22187 return emptyContextObject;
22188 }
22189
22190 var fiber = get(parentComponent);
22191 var parentContext = findCurrentUnmaskedContext(fiber);
22192
22193 if (fiber.tag === ClassComponent) {
22194 var Component = fiber.type;
22195 if (isContextProvider(Component)) {
22196 return processChildContext(fiber, Component, parentContext);
22197 }
22198 }
22199
22200 return parentContext;
22201}
22202
22203function scheduleRootUpdate(
22204 current$$1,
22205 element,
22206 expirationTime,
22207 suspenseConfig,
22208 callback
22209) {
22210 {
22211 if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) {
22212 didWarnAboutNestedUpdates = true;
22213 warningWithoutStack$1(
22214 false,
22215 "Render methods should be a pure function of props and state; " +
22216 "triggering nested component updates from render is not allowed. " +
22217 "If necessary, trigger nested updates in componentDidUpdate.\n\n" +
22218 "Check the render method of %s.",
22219 getComponentName(current.type) || "Unknown"
22220 );
22221 }
22222 }
22223
22224 var update = createUpdate(expirationTime, suspenseConfig);
22225 // Caution: React DevTools currently depends on this property
22226 // being called "element".
22227 update.payload = { element: element };
22228
22229 callback = callback === undefined ? null : callback;
22230 if (callback !== null) {
22231 !(typeof callback === "function")
22232 ? warningWithoutStack$1(
22233 false,
22234 "render(...): Expected the last optional `callback` argument to be a " +
22235 "function. Instead received: %s.",
22236 callback
22237 )
22238 : void 0;
22239 update.callback = callback;
22240 }
22241
22242 if (revertPassiveEffectsChange) {
22243 flushPassiveEffects();
22244 }
22245 enqueueUpdate(current$$1, update);
22246 scheduleWork(current$$1, expirationTime);
22247
22248 return expirationTime;
22249}
22250
22251function updateContainerAtExpirationTime(
22252 element,
22253 container,
22254 parentComponent,
22255 expirationTime,
22256 suspenseConfig,
22257 callback
22258) {
22259 // TODO: If this is a nested container, this won't be the root.
22260 var current$$1 = container.current;
22261
22262 {
22263 if (ReactFiberInstrumentation_1.debugTool) {
22264 if (current$$1.alternate === null) {
22265 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
22266 } else if (element === null) {
22267 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
22268 } else {
22269 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
22270 }
22271 }
22272 }
22273
22274 var context = getContextForSubtree(parentComponent);
22275 if (container.context === null) {
22276 container.context = context;
22277 } else {
22278 container.pendingContext = context;
22279 }
22280
22281 return scheduleRootUpdate(
22282 current$$1,
22283 element,
22284 expirationTime,
22285 suspenseConfig,
22286 callback
22287 );
22288}
22289
22290function findHostInstance(component) {
22291 var fiber = get(component);
22292 if (fiber === undefined) {
22293 if (typeof component.render === "function") {
22294 (function() {
22295 {
22296 throw ReactError(
22297 Error("Unable to find node on an unmounted component.")
22298 );
22299 }
22300 })();
22301 } else {
22302 (function() {
22303 {
22304 throw ReactError(
22305 Error(
22306 "Argument appears to not be a ReactComponent. Keys: " +
22307 Object.keys(component)
22308 )
22309 );
22310 }
22311 })();
22312 }
22313 }
22314 var hostFiber = findCurrentHostFiber(fiber);
22315 if (hostFiber === null) {
22316 return null;
22317 }
22318 return hostFiber.stateNode;
22319}
22320
22321function findHostInstanceWithWarning(component, methodName) {
22322 {
22323 var fiber = get(component);
22324 if (fiber === undefined) {
22325 if (typeof component.render === "function") {
22326 (function() {
22327 {
22328 throw ReactError(
22329 Error("Unable to find node on an unmounted component.")
22330 );
22331 }
22332 })();
22333 } else {
22334 (function() {
22335 {
22336 throw ReactError(
22337 Error(
22338 "Argument appears to not be a ReactComponent. Keys: " +
22339 Object.keys(component)
22340 )
22341 );
22342 }
22343 })();
22344 }
22345 }
22346 var hostFiber = findCurrentHostFiber(fiber);
22347 if (hostFiber === null) {
22348 return null;
22349 }
22350 if (hostFiber.mode & StrictMode) {
22351 var componentName = getComponentName(fiber.type) || "Component";
22352 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
22353 didWarnAboutFindNodeInStrictMode[componentName] = true;
22354 if (fiber.mode & StrictMode) {
22355 warningWithoutStack$1(
22356 false,
22357 "%s is deprecated in StrictMode. " +
22358 "%s was passed an instance of %s which is inside StrictMode. " +
22359 "Instead, add a ref directly to the element you want to reference." +
22360 "\n%s" +
22361 "\n\nLearn more about using refs safely here:" +
22362 "\nhttps://fb.me/react-strict-mode-find-node",
22363 methodName,
22364 methodName,
22365 componentName,
22366 getStackByFiberInDevAndProd(hostFiber)
22367 );
22368 } else {
22369 warningWithoutStack$1(
22370 false,
22371 "%s is deprecated in StrictMode. " +
22372 "%s was passed an instance of %s which renders StrictMode children. " +
22373 "Instead, add a ref directly to the element you want to reference." +
22374 "\n%s" +
22375 "\n\nLearn more about using refs safely here:" +
22376 "\nhttps://fb.me/react-strict-mode-find-node",
22377 methodName,
22378 methodName,
22379 componentName,
22380 getStackByFiberInDevAndProd(hostFiber)
22381 );
22382 }
22383 }
22384 }
22385 return hostFiber.stateNode;
22386 }
22387 return findHostInstance(component);
22388}
22389
22390function createContainer(containerInfo, tag, hydrate) {
22391 return createFiberRoot(containerInfo, tag, hydrate);
22392}
22393
22394function updateContainer(element, container, parentComponent, callback) {
22395 var current$$1 = container.current;
22396 var currentTime = requestCurrentTime();
22397 {
22398 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
22399 if ("undefined" !== typeof jest) {
22400 warnIfUnmockedScheduler(current$$1);
22401 warnIfNotScopedWithMatchingAct(current$$1);
22402 }
22403 }
22404 var suspenseConfig = requestCurrentSuspenseConfig();
22405 var expirationTime = computeExpirationForFiber(
22406 currentTime,
22407 current$$1,
22408 suspenseConfig
22409 );
22410 return updateContainerAtExpirationTime(
22411 element,
22412 container,
22413 parentComponent,
22414 expirationTime,
22415 suspenseConfig,
22416 callback
22417 );
22418}
22419
22420function getPublicRootInstance(container) {
22421 var containerFiber = container.current;
22422 if (!containerFiber.child) {
22423 return null;
22424 }
22425 switch (containerFiber.child.tag) {
22426 case HostComponent:
22427 return getPublicInstance(containerFiber.child.stateNode);
22428 default:
22429 return containerFiber.child.stateNode;
22430 }
22431}
22432
22433var shouldSuspendImpl = function(fiber) {
22434 return false;
22435};
22436
22437function shouldSuspend(fiber) {
22438 return shouldSuspendImpl(fiber);
22439}
22440
22441var overrideHookState = null;
22442var overrideProps = null;
22443var scheduleUpdate = null;
22444var setSuspenseHandler = null;
22445
22446{
22447 var copyWithSetImpl = function(obj, path, idx, value) {
22448 if (idx >= path.length) {
22449 return value;
22450 }
22451 var key = path[idx];
22452 var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj);
22453 // $FlowFixMe number or string is fine here
22454 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
22455 return updated;
22456 };
22457
22458 var copyWithSet = function(obj, path, value) {
22459 return copyWithSetImpl(obj, path, 0, value);
22460 };
22461
22462 // Support DevTools editable values for useState and useReducer.
22463 overrideHookState = function(fiber, id, path, value) {
22464 // For now, the "id" of stateful hooks is just the stateful hook index.
22465 // This may change in the future with e.g. nested hooks.
22466 var currentHook = fiber.memoizedState;
22467 while (currentHook !== null && id > 0) {
22468 currentHook = currentHook.next;
22469 id--;
22470 }
22471 if (currentHook !== null) {
22472 if (revertPassiveEffectsChange) {
22473 flushPassiveEffects();
22474 }
22475
22476 var newState = copyWithSet(currentHook.memoizedState, path, value);
22477 currentHook.memoizedState = newState;
22478 currentHook.baseState = newState;
22479
22480 // We aren't actually adding an update to the queue,
22481 // because there is no update we can add for useReducer hooks that won't trigger an error.
22482 // (There's no appropriate action type for DevTools overrides.)
22483 // As a result though, React will see the scheduled update as a noop and bailout.
22484 // Shallow cloning props works as a workaround for now to bypass the bailout check.
22485 fiber.memoizedProps = Object.assign({}, fiber.memoizedProps);
22486
22487 scheduleWork(fiber, Sync);
22488 }
22489 };
22490
22491 // Support DevTools props for function components, forwardRef, memo, host components, etc.
22492 overrideProps = function(fiber, path, value) {
22493 if (revertPassiveEffectsChange) {
22494 flushPassiveEffects();
22495 }
22496 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
22497 if (fiber.alternate) {
22498 fiber.alternate.pendingProps = fiber.pendingProps;
22499 }
22500 scheduleWork(fiber, Sync);
22501 };
22502
22503 scheduleUpdate = function(fiber) {
22504 if (revertPassiveEffectsChange) {
22505 flushPassiveEffects();
22506 }
22507 scheduleWork(fiber, Sync);
22508 };
22509
22510 setSuspenseHandler = function(newShouldSuspendImpl) {
22511 shouldSuspendImpl = newShouldSuspendImpl;
22512 };
22513}
22514
22515function injectIntoDevTools(devToolsConfig) {
22516 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
22517 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
22518
22519 return injectInternals(
22520 Object.assign({}, devToolsConfig, {
22521 overrideHookState: overrideHookState,
22522 overrideProps: overrideProps,
22523 setSuspenseHandler: setSuspenseHandler,
22524 scheduleUpdate: scheduleUpdate,
22525 currentDispatcherRef: ReactCurrentDispatcher,
22526 findHostInstanceByFiber: function(fiber) {
22527 var hostFiber = findCurrentHostFiber(fiber);
22528 if (hostFiber === null) {
22529 return null;
22530 }
22531 return hostFiber.stateNode;
22532 },
22533 findFiberByHostInstance: function(instance) {
22534 if (!findFiberByHostInstance) {
22535 // Might not be implemented by the renderer.
22536 return null;
22537 }
22538 return findFiberByHostInstance(instance);
22539 },
22540
22541 // React Refresh
22542 findHostInstancesForRefresh: findHostInstancesForRefresh,
22543 scheduleRefresh: scheduleRefresh,
22544 scheduleRoot: scheduleRoot,
22545 setRefreshHandler: setRefreshHandler,
22546 // Enables DevTools to append owner stacks to error messages in DEV mode.
22547 getCurrentFiber: function() {
22548 return current;
22549 }
22550 })
22551 );
22552}
22553
22554// This file intentionally does *not* have the Flow annotation.
22555// Don't add it. See `./inline-typed.js` for an explanation.
22556
22557function createPortal(
22558 children,
22559 containerInfo,
22560 // TODO: figure out the API for cross-renderer implementation.
22561 implementation
22562) {
22563 var key =
22564 arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
22565
22566 return {
22567 // This tag allow us to uniquely identify this as a React Portal
22568 $$typeof: REACT_PORTAL_TYPE,
22569 key: key == null ? null : "" + key,
22570 children: children,
22571 containerInfo: containerInfo,
22572 implementation: implementation
22573 };
22574}
22575
22576// TODO: this is special because it gets imported during build.
22577
22578var ReactVersion = "16.8.6";
22579
22580// Modules provided by RN:
22581var NativeMethodsMixin = function(findNodeHandle, findHostInstance) {
22582 /**
22583 * `NativeMethodsMixin` provides methods to access the underlying native
22584 * component directly. This can be useful in cases when you want to focus
22585 * a view or measure its on-screen dimensions, for example.
22586 *
22587 * The methods described here are available on most of the default components
22588 * provided by React Native. Note, however, that they are *not* available on
22589 * composite components that aren't directly backed by a native view. This will
22590 * generally include most components that you define in your own app. For more
22591 * information, see [Direct
22592 * Manipulation](docs/direct-manipulation.html).
22593 *
22594 * Note the Flow $Exact<> syntax is required to support mixins.
22595 * React createClass mixins can only be used with exact types.
22596 */
22597 var NativeMethodsMixin = {
22598 /**
22599 * Determines the location on screen, width, and height of the given view and
22600 * returns the values via an async callback. If successful, the callback will
22601 * be called with the following arguments:
22602 *
22603 * - x
22604 * - y
22605 * - width
22606 * - height
22607 * - pageX
22608 * - pageY
22609 *
22610 * Note that these measurements are not available until after the rendering
22611 * has been completed in native. If you need the measurements as soon as
22612 * possible, consider using the [`onLayout`
22613 * prop](docs/view.html#onlayout) instead.
22614 */
22615 measure: function(callback) {
22616 var maybeInstance = void 0;
22617
22618 // Fiber errors if findNodeHandle is called for an umounted component.
22619 // Tests using ReactTestRenderer will trigger this case indirectly.
22620 // Mimicking stack behavior, we should silently ignore this case.
22621 // TODO Fix ReactTestRenderer so we can remove this try/catch.
22622 try {
22623 maybeInstance = findHostInstance(this);
22624 } catch (error) {}
22625
22626 // If there is no host component beneath this we should fail silently.
22627 // This is not an error; it could mean a class component rendered null.
22628 if (maybeInstance == null) {
22629 return;
22630 }
22631
22632 if (maybeInstance.canonical) {
22633 // We can't call FabricUIManager here because it won't be loaded in paper
22634 // at initialization time. See https://github.com/facebook/react/pull/15490
22635 // for more info.
22636 nativeFabricUIManager.measure(
22637 maybeInstance.node,
22638 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
22639 );
22640 } else {
22641 ReactNativePrivateInterface.UIManager.measure(
22642 findNodeHandle(this),
22643 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
22644 );
22645 }
22646 },
22647
22648 /**
22649 * Determines the location of the given view in the window and returns the
22650 * values via an async callback. If the React root view is embedded in
22651 * another native view, this will give you the absolute coordinates. If
22652 * successful, the callback will be called with the following
22653 * arguments:
22654 *
22655 * - x
22656 * - y
22657 * - width
22658 * - height
22659 *
22660 * Note that these measurements are not available until after the rendering
22661 * has been completed in native.
22662 */
22663 measureInWindow: function(callback) {
22664 var maybeInstance = void 0;
22665
22666 // Fiber errors if findNodeHandle is called for an umounted component.
22667 // Tests using ReactTestRenderer will trigger this case indirectly.
22668 // Mimicking stack behavior, we should silently ignore this case.
22669 // TODO Fix ReactTestRenderer so we can remove this try/catch.
22670 try {
22671 maybeInstance = findHostInstance(this);
22672 } catch (error) {}
22673
22674 // If there is no host component beneath this we should fail silently.
22675 // This is not an error; it could mean a class component rendered null.
22676 if (maybeInstance == null) {
22677 return;
22678 }
22679
22680 if (maybeInstance.canonical) {
22681 // We can't call FabricUIManager here because it won't be loaded in paper
22682 // at initialization time. See https://github.com/facebook/react/pull/15490
22683 // for more info.
22684 nativeFabricUIManager.measureInWindow(
22685 maybeInstance.node,
22686 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
22687 );
22688 } else {
22689 ReactNativePrivateInterface.UIManager.measureInWindow(
22690 findNodeHandle(this),
22691 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
22692 );
22693 }
22694 },
22695
22696 /**
22697 * Like [`measure()`](#measure), but measures the view relative an ancestor,
22698 * specified as `relativeToNativeNode`. This means that the returned x, y
22699 * are relative to the origin x, y of the ancestor view.
22700 *
22701 * As always, to obtain a native node handle for a component, you can use
22702 * `findNodeHandle(component)`.
22703 */
22704 measureLayout: function(
22705 relativeToNativeNode,
22706 onSuccess,
22707 onFail /* currently unused */
22708 ) {
22709 var maybeInstance = void 0;
22710
22711 // Fiber errors if findNodeHandle is called for an umounted component.
22712 // Tests using ReactTestRenderer will trigger this case indirectly.
22713 // Mimicking stack behavior, we should silently ignore this case.
22714 // TODO Fix ReactTestRenderer so we can remove this try/catch.
22715 try {
22716 maybeInstance = findHostInstance(this);
22717 } catch (error) {}
22718
22719 // If there is no host component beneath this we should fail silently.
22720 // This is not an error; it could mean a class component rendered null.
22721 if (maybeInstance == null) {
22722 return;
22723 }
22724
22725 if (maybeInstance.canonical) {
22726 warningWithoutStack$1(
22727 false,
22728 "Warning: measureLayout on components using NativeMethodsMixin " +
22729 "or ReactNative.NativeComponent is not currently supported in Fabric. " +
22730 "measureLayout must be called on a native ref. Consider using forwardRef."
22731 );
22732 return;
22733 } else {
22734 var relativeNode = void 0;
22735
22736 if (typeof relativeToNativeNode === "number") {
22737 // Already a node handle
22738 relativeNode = relativeToNativeNode;
22739 } else if (relativeToNativeNode._nativeTag) {
22740 relativeNode = relativeToNativeNode._nativeTag;
22741 }
22742
22743 if (relativeNode == null) {
22744 warningWithoutStack$1(
22745 false,
22746 "Warning: ref.measureLayout must be called with a node handle or a ref to a native component."
22747 );
22748
22749 return;
22750 }
22751
22752 ReactNativePrivateInterface.UIManager.measureLayout(
22753 findNodeHandle(this),
22754 relativeNode,
22755 mountSafeCallback_NOT_REALLY_SAFE(this, onFail),
22756 mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess)
22757 );
22758 }
22759 },
22760
22761 /**
22762 * This function sends props straight to native. They will not participate in
22763 * future diff process - this means that if you do not include them in the
22764 * next render, they will remain active (see [Direct
22765 * Manipulation](docs/direct-manipulation.html)).
22766 */
22767 setNativeProps: function(nativeProps) {
22768 // Class components don't have viewConfig -> validateAttributes.
22769 // Nor does it make sense to set native props on a non-native component.
22770 // Instead, find the nearest host component and set props on it.
22771 // Use findNodeHandle() rather than findNodeHandle() because
22772 // We want the instance/wrapper (not the native tag).
22773 var maybeInstance = void 0;
22774
22775 // Fiber errors if findNodeHandle is called for an umounted component.
22776 // Tests using ReactTestRenderer will trigger this case indirectly.
22777 // Mimicking stack behavior, we should silently ignore this case.
22778 // TODO Fix ReactTestRenderer so we can remove this try/catch.
22779 try {
22780 maybeInstance = findHostInstance(this);
22781 } catch (error) {}
22782
22783 // If there is no host component beneath this we should fail silently.
22784 // This is not an error; it could mean a class component rendered null.
22785 if (maybeInstance == null) {
22786 return;
22787 }
22788
22789 if (maybeInstance.canonical) {
22790 warningWithoutStack$1(
22791 false,
22792 "Warning: setNativeProps is not currently supported in Fabric"
22793 );
22794 return;
22795 }
22796
22797 {
22798 if (warnAboutDeprecatedSetNativeProps) {
22799 warningWithoutStack$1(
22800 false,
22801 "Warning: Calling ref.setNativeProps(nativeProps) " +
22802 "is deprecated and will be removed in a future release. " +
22803 "Use the setNativeProps export from the react-native package instead." +
22804 "\n\timport {setNativeProps} from 'react-native';\n\tsetNativeProps(ref, nativeProps);\n"
22805 );
22806 }
22807 }
22808
22809 var nativeTag =
22810 maybeInstance._nativeTag || maybeInstance.canonical._nativeTag;
22811 var viewConfig =
22812 maybeInstance.viewConfig || maybeInstance.canonical.viewConfig;
22813
22814 {
22815 warnForStyleProps(nativeProps, viewConfig.validAttributes);
22816 }
22817
22818 var updatePayload = create(nativeProps, viewConfig.validAttributes);
22819
22820 // Avoid the overhead of bridge calls if there's no update.
22821 // This is an expensive no-op for Android, and causes an unnecessary
22822 // view invalidation for certain components (eg RCTTextInput) on iOS.
22823 if (updatePayload != null) {
22824 ReactNativePrivateInterface.UIManager.updateView(
22825 nativeTag,
22826 viewConfig.uiViewClassName,
22827 updatePayload
22828 );
22829 }
22830 },
22831
22832 /**
22833 * Requests focus for the given input or view. The exact behavior triggered
22834 * will depend on the platform and type of view.
22835 */
22836 focus: function() {
22837 ReactNativePrivateInterface.TextInputState.focusTextInput(
22838 findNodeHandle(this)
22839 );
22840 },
22841
22842 /**
22843 * Removes focus from an input or view. This is the opposite of `focus()`.
22844 */
22845 blur: function() {
22846 ReactNativePrivateInterface.TextInputState.blurTextInput(
22847 findNodeHandle(this)
22848 );
22849 }
22850 };
22851
22852 {
22853 // hide this from Flow since we can't define these properties outside of
22854 // true without actually implementing them (setting them to undefined
22855 // isn't allowed by ReactClass)
22856 var NativeMethodsMixin_DEV = NativeMethodsMixin;
22857 (function() {
22858 if (
22859 !(
22860 !NativeMethodsMixin_DEV.componentWillMount &&
22861 !NativeMethodsMixin_DEV.componentWillReceiveProps &&
22862 !NativeMethodsMixin_DEV.UNSAFE_componentWillMount &&
22863 !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps
22864 )
22865 ) {
22866 throw ReactError(Error("Do not override existing functions."));
22867 }
22868 })();
22869 // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native,
22870 // Once these lifecycles have been remove from the reconciler.
22871 NativeMethodsMixin_DEV.componentWillMount = function() {
22872 throwOnStylesProp(this, this.props);
22873 };
22874 NativeMethodsMixin_DEV.componentWillReceiveProps = function(newProps) {
22875 throwOnStylesProp(this, newProps);
22876 };
22877 NativeMethodsMixin_DEV.UNSAFE_componentWillMount = function() {
22878 throwOnStylesProp(this, this.props);
22879 };
22880 NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps = function(
22881 newProps
22882 ) {
22883 throwOnStylesProp(this, newProps);
22884 };
22885
22886 // React may warn about cWM/cWRP/cWU methods being deprecated.
22887 // Add a flag to suppress these warnings for this special case.
22888 // TODO (bvaughn) Remove this flag once the above methods have been removed.
22889 NativeMethodsMixin_DEV.componentWillMount.__suppressDeprecationWarning = true;
22890 NativeMethodsMixin_DEV.componentWillReceiveProps.__suppressDeprecationWarning = true;
22891 }
22892
22893 return NativeMethodsMixin;
22894};
22895
22896function _classCallCheck$2(instance, Constructor) {
22897 if (!(instance instanceof Constructor)) {
22898 throw new TypeError("Cannot call a class as a function");
22899 }
22900}
22901
22902function _possibleConstructorReturn$1(self, call) {
22903 if (!self) {
22904 throw new ReferenceError(
22905 "this hasn't been initialised - super() hasn't been called"
22906 );
22907 }
22908 return call && (typeof call === "object" || typeof call === "function")
22909 ? call
22910 : self;
22911}
22912
22913function _inherits$1(subClass, superClass) {
22914 if (typeof superClass !== "function" && superClass !== null) {
22915 throw new TypeError(
22916 "Super expression must either be null or a function, not " +
22917 typeof superClass
22918 );
22919 }
22920 subClass.prototype = Object.create(superClass && superClass.prototype, {
22921 constructor: {
22922 value: subClass,
22923 enumerable: false,
22924 writable: true,
22925 configurable: true
22926 }
22927 });
22928 if (superClass)
22929 Object.setPrototypeOf
22930 ? Object.setPrototypeOf(subClass, superClass)
22931 : (subClass.__proto__ = superClass);
22932}
22933
22934// Modules provided by RN:
22935var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) {
22936 /**
22937 * Superclass that provides methods to access the underlying native component.
22938 * This can be useful when you want to focus a view or measure its dimensions.
22939 *
22940 * Methods implemented by this class are available on most default components
22941 * provided by React Native. However, they are *not* available on composite
22942 * components that are not directly backed by a native view. For more
22943 * information, see [Direct Manipulation](docs/direct-manipulation.html).
22944 *
22945 * @abstract
22946 */
22947 var ReactNativeComponent = (function(_React$Component) {
22948 _inherits$1(ReactNativeComponent, _React$Component);
22949
22950 function ReactNativeComponent() {
22951 _classCallCheck$2(this, ReactNativeComponent);
22952
22953 return _possibleConstructorReturn$1(
22954 this,
22955 _React$Component.apply(this, arguments)
22956 );
22957 }
22958
22959 /**
22960 * Removes focus. This is the opposite of `focus()`.
22961 */
22962
22963 /**
22964 * Due to bugs in Flow's handling of React.createClass, some fields already
22965 * declared in the base class need to be redeclared below.
22966 */
22967 ReactNativeComponent.prototype.blur = function blur() {
22968 ReactNativePrivateInterface.TextInputState.blurTextInput(
22969 findNodeHandle(this)
22970 );
22971 };
22972
22973 /**
22974 * Requests focus. The exact behavior depends on the platform and view.
22975 */
22976
22977 ReactNativeComponent.prototype.focus = function focus() {
22978 ReactNativePrivateInterface.TextInputState.focusTextInput(
22979 findNodeHandle(this)
22980 );
22981 };
22982
22983 /**
22984 * Measures the on-screen location and dimensions. If successful, the callback
22985 * will be called asynchronously with the following arguments:
22986 *
22987 * - x
22988 * - y
22989 * - width
22990 * - height
22991 * - pageX
22992 * - pageY
22993 *
22994 * These values are not available until after natives rendering completes. If
22995 * you need the measurements as soon as possible, consider using the
22996 * [`onLayout` prop](docs/view.html#onlayout) instead.
22997 */
22998
22999 ReactNativeComponent.prototype.measure = function measure(callback) {
23000 var maybeInstance = void 0;
23001
23002 // Fiber errors if findNodeHandle is called for an umounted component.
23003 // Tests using ReactTestRenderer will trigger this case indirectly.
23004 // Mimicking stack behavior, we should silently ignore this case.
23005 // TODO Fix ReactTestRenderer so we can remove this try/catch.
23006 try {
23007 maybeInstance = findHostInstance(this);
23008 } catch (error) {}
23009
23010 // If there is no host component beneath this we should fail silently.
23011 // This is not an error; it could mean a class component rendered null.
23012 if (maybeInstance == null) {
23013 return;
23014 }
23015
23016 if (maybeInstance.canonical) {
23017 // We can't call FabricUIManager here because it won't be loaded in paper
23018 // at initialization time. See https://github.com/facebook/react/pull/15490
23019 // for more info.
23020 nativeFabricUIManager.measure(
23021 maybeInstance.node,
23022 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
23023 );
23024 } else {
23025 ReactNativePrivateInterface.UIManager.measure(
23026 findNodeHandle(this),
23027 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
23028 );
23029 }
23030 };
23031
23032 /**
23033 * Measures the on-screen location and dimensions. Even if the React Native
23034 * root view is embedded within another native view, this method will give you
23035 * the absolute coordinates measured from the window. If successful, the
23036 * callback will be called asynchronously with the following arguments:
23037 *
23038 * - x
23039 * - y
23040 * - width
23041 * - height
23042 *
23043 * These values are not available until after natives rendering completes.
23044 */
23045
23046 ReactNativeComponent.prototype.measureInWindow = function measureInWindow(
23047 callback
23048 ) {
23049 var maybeInstance = void 0;
23050
23051 // Fiber errors if findNodeHandle is called for an umounted component.
23052 // Tests using ReactTestRenderer will trigger this case indirectly.
23053 // Mimicking stack behavior, we should silently ignore this case.
23054 // TODO Fix ReactTestRenderer so we can remove this try/catch.
23055 try {
23056 maybeInstance = findHostInstance(this);
23057 } catch (error) {}
23058
23059 // If there is no host component beneath this we should fail silently.
23060 // This is not an error; it could mean a class component rendered null.
23061 if (maybeInstance == null) {
23062 return;
23063 }
23064
23065 if (maybeInstance.canonical) {
23066 // We can't call FabricUIManager here because it won't be loaded in paper
23067 // at initialization time. See https://github.com/facebook/react/pull/15490
23068 // for more info.
23069 nativeFabricUIManager.measureInWindow(
23070 maybeInstance.node,
23071 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
23072 );
23073 } else {
23074 ReactNativePrivateInterface.UIManager.measureInWindow(
23075 findNodeHandle(this),
23076 mountSafeCallback_NOT_REALLY_SAFE(this, callback)
23077 );
23078 }
23079 };
23080
23081 /**
23082 * Similar to [`measure()`](#measure), but the resulting location will be
23083 * relative to the supplied ancestor's location.
23084 *
23085 * Obtain a native node handle with `ReactNative.findNodeHandle(component)`.
23086 */
23087
23088 ReactNativeComponent.prototype.measureLayout = function measureLayout(
23089 relativeToNativeNode,
23090 onSuccess,
23091 onFail /* currently unused */
23092 ) {
23093 var maybeInstance = void 0;
23094
23095 // Fiber errors if findNodeHandle is called for an umounted component.
23096 // Tests using ReactTestRenderer will trigger this case indirectly.
23097 // Mimicking stack behavior, we should silently ignore this case.
23098 // TODO Fix ReactTestRenderer so we can remove this try/catch.
23099 try {
23100 maybeInstance = findHostInstance(this);
23101 } catch (error) {}
23102
23103 // If there is no host component beneath this we should fail silently.
23104 // This is not an error; it could mean a class component rendered null.
23105 if (maybeInstance == null) {
23106 return;
23107 }
23108
23109 if (maybeInstance.canonical) {
23110 warningWithoutStack$1(
23111 false,
23112 "Warning: measureLayout on components using NativeMethodsMixin " +
23113 "or ReactNative.NativeComponent is not currently supported in Fabric. " +
23114 "measureLayout must be called on a native ref. Consider using forwardRef."
23115 );
23116 return;
23117 } else {
23118 var relativeNode = void 0;
23119
23120 if (typeof relativeToNativeNode === "number") {
23121 // Already a node handle
23122 relativeNode = relativeToNativeNode;
23123 } else if (relativeToNativeNode._nativeTag) {
23124 relativeNode = relativeToNativeNode._nativeTag;
23125 }
23126
23127 if (relativeNode == null) {
23128 warningWithoutStack$1(
23129 false,
23130 "Warning: ref.measureLayout must be called with a node handle or a ref to a native component."
23131 );
23132
23133 return;
23134 }
23135
23136 ReactNativePrivateInterface.UIManager.measureLayout(
23137 findNodeHandle(this),
23138 relativeNode,
23139 mountSafeCallback_NOT_REALLY_SAFE(this, onFail),
23140 mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess)
23141 );
23142 }
23143 };
23144
23145 /**
23146 * This function sends props straight to native. They will not participate in
23147 * future diff process - this means that if you do not include them in the
23148 * next render, they will remain active (see [Direct
23149 * Manipulation](docs/direct-manipulation.html)).
23150 */
23151
23152 ReactNativeComponent.prototype.setNativeProps = function setNativeProps(
23153 nativeProps
23154 ) {
23155 // Class components don't have viewConfig -> validateAttributes.
23156 // Nor does it make sense to set native props on a non-native component.
23157 // Instead, find the nearest host component and set props on it.
23158 // Use findNodeHandle() rather than ReactNative.findNodeHandle() because
23159 // We want the instance/wrapper (not the native tag).
23160 var maybeInstance = void 0;
23161
23162 // Fiber errors if findNodeHandle is called for an umounted component.
23163 // Tests using ReactTestRenderer will trigger this case indirectly.
23164 // Mimicking stack behavior, we should silently ignore this case.
23165 // TODO Fix ReactTestRenderer so we can remove this try/catch.
23166 try {
23167 maybeInstance = findHostInstance(this);
23168 } catch (error) {}
23169
23170 // If there is no host component beneath this we should fail silently.
23171 // This is not an error; it could mean a class component rendered null.
23172 if (maybeInstance == null) {
23173 return;
23174 }
23175
23176 if (maybeInstance.canonical) {
23177 warningWithoutStack$1(
23178 false,
23179 "Warning: setNativeProps is not currently supported in Fabric"
23180 );
23181 return;
23182 }
23183
23184 {
23185 if (warnAboutDeprecatedSetNativeProps) {
23186 warningWithoutStack$1(
23187 false,
23188 "Warning: Calling ref.setNativeProps(nativeProps) " +
23189 "is deprecated and will be removed in a future release. " +
23190 "Use the setNativeProps export from the react-native package instead." +
23191 "\n\timport {setNativeProps} from 'react-native';\n\tsetNativeProps(ref, nativeProps);\n"
23192 );
23193 }
23194 }
23195
23196 var nativeTag =
23197 maybeInstance._nativeTag || maybeInstance.canonical._nativeTag;
23198 var viewConfig =
23199 maybeInstance.viewConfig || maybeInstance.canonical.viewConfig;
23200
23201 var updatePayload = create(nativeProps, viewConfig.validAttributes);
23202
23203 // Avoid the overhead of bridge calls if there's no update.
23204 // This is an expensive no-op for Android, and causes an unnecessary
23205 // view invalidation for certain components (eg RCTTextInput) on iOS.
23206 if (updatePayload != null) {
23207 ReactNativePrivateInterface.UIManager.updateView(
23208 nativeTag,
23209 viewConfig.uiViewClassName,
23210 updatePayload
23211 );
23212 }
23213 };
23214
23215 return ReactNativeComponent;
23216 })(React.Component);
23217
23218 // eslint-disable-next-line no-unused-expressions
23219
23220 return ReactNativeComponent;
23221};
23222
23223var instanceCache = new Map();
23224
23225function getInstanceFromTag(tag) {
23226 return instanceCache.get(tag) || null;
23227}
23228
23229// Module provided by RN:
23230var emptyObject$2 = {};
23231{
23232 Object.freeze(emptyObject$2);
23233}
23234
23235var getInspectorDataForViewTag = void 0;
23236
23237{
23238 var traverseOwnerTreeUp = function(hierarchy, instance) {
23239 if (instance) {
23240 hierarchy.unshift(instance);
23241 traverseOwnerTreeUp(hierarchy, instance._debugOwner);
23242 }
23243 };
23244
23245 var getOwnerHierarchy = function(instance) {
23246 var hierarchy = [];
23247 traverseOwnerTreeUp(hierarchy, instance);
23248 return hierarchy;
23249 };
23250
23251 var lastNonHostInstance = function(hierarchy) {
23252 for (var i = hierarchy.length - 1; i > 1; i--) {
23253 var instance = hierarchy[i];
23254
23255 if (instance.tag !== HostComponent) {
23256 return instance;
23257 }
23258 }
23259 return hierarchy[0];
23260 };
23261
23262 var getHostProps = function(fiber) {
23263 var host = findCurrentHostFiber(fiber);
23264 if (host) {
23265 return host.memoizedProps || emptyObject$2;
23266 }
23267 return emptyObject$2;
23268 };
23269
23270 var getHostNode = function(fiber, findNodeHandle) {
23271 var hostNode = void 0;
23272 // look for children first for the hostNode
23273 // as composite fibers do not have a hostNode
23274 while (fiber) {
23275 if (fiber.stateNode !== null && fiber.tag === HostComponent) {
23276 hostNode = findNodeHandle(fiber.stateNode);
23277 }
23278 if (hostNode) {
23279 return hostNode;
23280 }
23281 fiber = fiber.child;
23282 }
23283 return null;
23284 };
23285
23286 var createHierarchy = function(fiberHierarchy) {
23287 return fiberHierarchy.map(function(fiber) {
23288 return {
23289 name: getComponentName(fiber.type),
23290 getInspectorData: function(findNodeHandle) {
23291 return {
23292 measure: function(callback) {
23293 return ReactNativePrivateInterface.UIManager.measure(
23294 getHostNode(fiber, findNodeHandle),
23295 callback
23296 );
23297 },
23298 props: getHostProps(fiber),
23299 source: fiber._debugSource
23300 };
23301 }
23302 };
23303 });
23304 };
23305
23306 getInspectorDataForViewTag = function(viewTag) {
23307 var closestInstance = getInstanceFromTag(viewTag);
23308
23309 // Handle case where user clicks outside of ReactNative
23310 if (!closestInstance) {
23311 return {
23312 hierarchy: [],
23313 props: emptyObject$2,
23314 selection: null,
23315 source: null
23316 };
23317 }
23318
23319 var fiber = findCurrentFiberUsingSlowPath(closestInstance);
23320 var fiberHierarchy = getOwnerHierarchy(fiber);
23321 var instance = lastNonHostInstance(fiberHierarchy);
23322 var hierarchy = createHierarchy(fiberHierarchy);
23323 var props = getHostProps(instance);
23324 var source = instance._debugSource;
23325 var selection = fiberHierarchy.indexOf(instance);
23326
23327 return {
23328 hierarchy: hierarchy,
23329 props: props,
23330 selection: selection,
23331 source: source
23332 };
23333 };
23334}
23335
23336var _nativeFabricUIManage = nativeFabricUIManager;
23337var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand;
23338
23339var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
23340
23341function findNodeHandle(componentOrHandle) {
23342 {
23343 var owner = ReactCurrentOwner.current;
23344 if (owner !== null && owner.stateNode !== null) {
23345 !owner.stateNode._warnedAboutRefsInRender
23346 ? warningWithoutStack$1(
23347 false,
23348 "%s is accessing findNodeHandle inside its render(). " +
23349 "render() should be a pure function of props and state. It should " +
23350 "never access something that requires stale data from the previous " +
23351 "render, such as refs. Move this logic to componentDidMount and " +
23352 "componentDidUpdate instead.",
23353 getComponentName(owner.type) || "A component"
23354 )
23355 : void 0;
23356
23357 owner.stateNode._warnedAboutRefsInRender = true;
23358 }
23359 }
23360 if (componentOrHandle == null) {
23361 return null;
23362 }
23363 if (typeof componentOrHandle === "number") {
23364 // Already a node handle
23365 return componentOrHandle;
23366 }
23367 if (componentOrHandle._nativeTag) {
23368 return componentOrHandle._nativeTag;
23369 }
23370 if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) {
23371 return componentOrHandle.canonical._nativeTag;
23372 }
23373 var hostInstance = void 0;
23374 {
23375 hostInstance = findHostInstanceWithWarning(
23376 componentOrHandle,
23377 "findNodeHandle"
23378 );
23379 }
23380
23381 if (hostInstance == null) {
23382 return hostInstance;
23383 }
23384 // TODO: the code is right but the types here are wrong.
23385 // https://github.com/facebook/react/pull/12863
23386 if (hostInstance.canonical) {
23387 // Fabric
23388 return hostInstance.canonical._nativeTag;
23389 }
23390 return hostInstance._nativeTag;
23391}
23392
23393setBatchingImplementation(
23394 batchedUpdates$1,
23395 discreteUpdates$1,
23396 flushDiscreteUpdates,
23397 batchedEventUpdates$1
23398);
23399
23400var roots = new Map();
23401
23402var ReactFabric = {
23403 NativeComponent: ReactNativeComponent$1(findNodeHandle, findHostInstance),
23404
23405 findNodeHandle: findNodeHandle,
23406
23407 setNativeProps: function(handle, nativeProps) {
23408 warningWithoutStack$1(
23409 false,
23410 "Warning: setNativeProps is not currently supported in Fabric"
23411 );
23412
23413 return;
23414 },
23415 dispatchCommand: function(handle, command, args) {
23416 var invalid =
23417 handle._nativeTag == null || handle._internalInstanceHandle == null;
23418
23419 if (invalid) {
23420 !!invalid
23421 ? warningWithoutStack$1(
23422 false,
23423 "dispatchCommand was called with a ref that isn't a " +
23424 "native component. Use React.forwardRef to get access to the underlying native component"
23425 )
23426 : void 0;
23427 return;
23428 }
23429
23430 fabricDispatchCommand(
23431 handle._internalInstanceHandle.stateNode.node,
23432 command,
23433 args
23434 );
23435 },
23436 render: function(element, containerTag, callback) {
23437 var root = roots.get(containerTag);
23438
23439 if (!root) {
23440 // TODO (bvaughn): If we decide to keep the wrapper component,
23441 // We could create a wrapper for containerTag as well to reduce special casing.
23442 root = createContainer(containerTag, LegacyRoot, false);
23443 roots.set(containerTag, root);
23444 }
23445 updateContainer(element, root, null, callback);
23446
23447 return getPublicRootInstance(root);
23448 },
23449 unmountComponentAtNode: function(containerTag) {
23450 var root = roots.get(containerTag);
23451 if (root) {
23452 // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred?
23453 updateContainer(null, root, null, function() {
23454 roots.delete(containerTag);
23455 });
23456 }
23457 },
23458 createPortal: function(children, containerTag) {
23459 var key =
23460 arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
23461
23462 return createPortal(children, containerTag, null, key);
23463 },
23464
23465 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
23466 // Used as a mixin in many createClass-based components
23467 NativeMethodsMixin: NativeMethodsMixin(findNodeHandle, findHostInstance)
23468 }
23469};
23470
23471injectIntoDevTools({
23472 findFiberByHostInstance: getInstanceFromInstance,
23473 getInspectorDataForViewTag: getInspectorDataForViewTag,
23474 bundleType: 1,
23475 version: ReactVersion,
23476 rendererPackageName: "react-native-renderer"
23477});
23478
23479var ReactFabric$2 = Object.freeze({
23480 default: ReactFabric
23481});
23482
23483var ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2;
23484
23485// TODO: decide on the top-level export form.
23486// This is hacky but makes it work with both Rollup and Jest.
23487var fabric = ReactFabric$3.default || ReactFabric$3;
23488
23489module.exports = fabric;
23490
23491 })();
23492}