UNPKG

859 kBJavaScriptView Raw
1/** @license React v16.13.1
2 * react-dom.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18var React = require('react');
19var _assign = require('object-assign');
20var Scheduler = require('scheduler');
21var checkPropTypes = require('prop-types/checkPropTypes');
22var tracing = require('scheduler/tracing');
23
24var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
25// Current owner and dispatcher used to share the same ref,
26// but PR #14548 split them out to better support the react-debug-tools package.
27
28if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
29 ReactSharedInternals.ReactCurrentDispatcher = {
30 current: null
31 };
32}
33
34if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
35 ReactSharedInternals.ReactCurrentBatchConfig = {
36 suspense: null
37 };
38}
39
40// by calls to these methods by a Babel plugin.
41//
42// In PROD (or in packages without access to React internals),
43// they are left as they are instead.
44
45function warn(format) {
46 {
47 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
48 args[_key - 1] = arguments[_key];
49 }
50
51 printWarning('warn', format, args);
52 }
53}
54function error(format) {
55 {
56 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
57 args[_key2 - 1] = arguments[_key2];
58 }
59
60 printWarning('error', format, args);
61 }
62}
63
64function printWarning(level, format, args) {
65 // When changing this logic, you might want to also
66 // update consoleWithStackDev.www.js as well.
67 {
68 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
69
70 if (!hasExistingStack) {
71 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
72 var stack = ReactDebugCurrentFrame.getStackAddendum();
73
74 if (stack !== '') {
75 format += '%s';
76 args = args.concat([stack]);
77 }
78 }
79
80 var argsWithFormat = args.map(function (item) {
81 return '' + item;
82 }); // Careful: RN currently depends on this prefix
83
84 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
85 // breaks IE9: https://github.com/facebook/react/issues/13610
86 // eslint-disable-next-line react-internal/no-production-logging
87
88 Function.prototype.apply.call(console[level], console, argsWithFormat);
89
90 try {
91 // --- Welcome to debugging React ---
92 // This error was thrown as a convenience so that you can use this stack
93 // to find the callsite that caused this warning to fire.
94 var argIndex = 0;
95 var message = 'Warning: ' + format.replace(/%s/g, function () {
96 return args[argIndex++];
97 });
98 throw new Error(message);
99 } catch (x) {}
100 }
101}
102
103if (!React) {
104 {
105 throw Error( "ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM." );
106 }
107}
108
109var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
110 var funcArgs = Array.prototype.slice.call(arguments, 3);
111
112 try {
113 func.apply(context, funcArgs);
114 } catch (error) {
115 this.onError(error);
116 }
117};
118
119{
120 // In DEV mode, we swap out invokeGuardedCallback for a special version
121 // that plays more nicely with the browser's DevTools. The idea is to preserve
122 // "Pause on exceptions" behavior. Because React wraps all user-provided
123 // functions in invokeGuardedCallback, and the production version of
124 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
125 // like caught exceptions, and the DevTools won't pause unless the developer
126 // takes the extra step of enabling pause on caught exceptions. This is
127 // unintuitive, though, because even though React has caught the error, from
128 // the developer's perspective, the error is uncaught.
129 //
130 // To preserve the expected "Pause on exceptions" behavior, we don't use a
131 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
132 // DOM node, and call the user-provided callback from inside an event handler
133 // for that fake event. If the callback throws, the error is "captured" using
134 // a global event handler. But because the error happens in a different
135 // event loop context, it does not interrupt the normal program flow.
136 // Effectively, this gives us try-catch behavior without actually using
137 // try-catch. Neat!
138 // Check that the browser supports the APIs we need to implement our special
139 // DEV version of invokeGuardedCallback
140 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
141 var fakeNode = document.createElement('react');
142
143 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
144 // If document doesn't exist we know for sure we will crash in this method
145 // when we call document.createEvent(). However this can cause confusing
146 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
147 // So we preemptively throw with a better message instead.
148 if (!(typeof document !== 'undefined')) {
149 {
150 throw Error( "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." );
151 }
152 }
153
154 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
155 // set this to true at the beginning, then set it to false right after
156 // calling the function. If the function errors, `didError` will never be
157 // set to false. This strategy works even if the browser is flaky and
158 // fails to call our global error handler, because it doesn't rely on
159 // the error event at all.
160
161 var didError = true; // Keeps track of the value of window.event so that we can reset it
162 // during the callback to let user code access window.event in the
163 // browsers that support it.
164
165 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
166 // dispatching: https://github.com/facebook/react/issues/13688
167
168 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
169 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
170 // call the user-provided callback.
171
172 var funcArgs = Array.prototype.slice.call(arguments, 3);
173
174 function callCallback() {
175 // We immediately remove the callback from event listeners so that
176 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
177 // nested call would trigger the fake event handlers of any call higher
178 // in the stack.
179 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
180 // window.event assignment in both IE <= 10 as they throw an error
181 // "Member not found" in strict mode, and in Firefox which does not
182 // support window.event.
183
184 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
185 window.event = windowEvent;
186 }
187
188 func.apply(context, funcArgs);
189 didError = false;
190 } // Create a global error event handler. We use this to capture the value
191 // that was thrown. It's possible that this error handler will fire more
192 // than once; for example, if non-React code also calls `dispatchEvent`
193 // and a handler for that event throws. We should be resilient to most of
194 // those cases. Even if our error event handler fires more than once, the
195 // last error event is always used. If the callback actually does error,
196 // we know that the last error event is the correct one, because it's not
197 // possible for anything else to have happened in between our callback
198 // erroring and the code that follows the `dispatchEvent` call below. If
199 // the callback doesn't error, but the error event was fired, we know to
200 // ignore it because `didError` will be false, as described above.
201
202
203 var error; // Use this to track whether the error event is ever called.
204
205 var didSetError = false;
206 var isCrossOriginError = false;
207
208 function handleWindowError(event) {
209 error = event.error;
210 didSetError = true;
211
212 if (error === null && event.colno === 0 && event.lineno === 0) {
213 isCrossOriginError = true;
214 }
215
216 if (event.defaultPrevented) {
217 // Some other error handler has prevented default.
218 // Browsers silence the error report if this happens.
219 // We'll remember this to later decide whether to log it or not.
220 if (error != null && typeof error === 'object') {
221 try {
222 error._suppressLogging = true;
223 } catch (inner) {// Ignore.
224 }
225 }
226 }
227 } // Create a fake event type.
228
229
230 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
231
232 window.addEventListener('error', handleWindowError);
233 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
234 // errors, it will trigger our global error handler.
235
236 evt.initEvent(evtType, false, false);
237 fakeNode.dispatchEvent(evt);
238
239 if (windowEventDescriptor) {
240 Object.defineProperty(window, 'event', windowEventDescriptor);
241 }
242
243 if (didError) {
244 if (!didSetError) {
245 // The callback errored, but the error event never fired.
246 error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');
247 } else if (isCrossOriginError) {
248 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');
249 }
250
251 this.onError(error);
252 } // Remove our event listeners
253
254
255 window.removeEventListener('error', handleWindowError);
256 };
257
258 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
259 }
260}
261
262var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
263
264var hasError = false;
265var caughtError = null; // Used by event system to capture/rethrow the first error.
266
267var hasRethrowError = false;
268var rethrowError = null;
269var reporter = {
270 onError: function (error) {
271 hasError = true;
272 caughtError = error;
273 }
274};
275/**
276 * Call a function while guarding against errors that happens within it.
277 * Returns an error if it throws, otherwise null.
278 *
279 * In production, this is implemented using a try-catch. The reason we don't
280 * use a try-catch directly is so that we can swap out a different
281 * implementation in DEV mode.
282 *
283 * @param {String} name of the guard to use for logging or debugging
284 * @param {Function} func The function to invoke
285 * @param {*} context The context to use when calling the function
286 * @param {...*} args Arguments for function
287 */
288
289function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
290 hasError = false;
291 caughtError = null;
292 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
293}
294/**
295 * Same as invokeGuardedCallback, but instead of returning an error, it stores
296 * it in a global so it can be rethrown by `rethrowCaughtError` later.
297 * TODO: See if caughtError and rethrowError can be unified.
298 *
299 * @param {String} name of the guard to use for logging or debugging
300 * @param {Function} func The function to invoke
301 * @param {*} context The context to use when calling the function
302 * @param {...*} args Arguments for function
303 */
304
305function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
306 invokeGuardedCallback.apply(this, arguments);
307
308 if (hasError) {
309 var error = clearCaughtError();
310
311 if (!hasRethrowError) {
312 hasRethrowError = true;
313 rethrowError = error;
314 }
315 }
316}
317/**
318 * During execution of guarded functions we will capture the first error which
319 * we will rethrow to be handled by the top level error handler.
320 */
321
322function rethrowCaughtError() {
323 if (hasRethrowError) {
324 var error = rethrowError;
325 hasRethrowError = false;
326 rethrowError = null;
327 throw error;
328 }
329}
330function hasCaughtError() {
331 return hasError;
332}
333function clearCaughtError() {
334 if (hasError) {
335 var error = caughtError;
336 hasError = false;
337 caughtError = null;
338 return error;
339 } else {
340 {
341 {
342 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
343 }
344 }
345 }
346}
347
348var getFiberCurrentPropsFromNode = null;
349var getInstanceFromNode = null;
350var getNodeFromInstance = null;
351function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
352 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
353 getInstanceFromNode = getInstanceFromNodeImpl;
354 getNodeFromInstance = getNodeFromInstanceImpl;
355
356 {
357 if (!getNodeFromInstance || !getInstanceFromNode) {
358 error('EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.');
359 }
360 }
361}
362var validateEventDispatches;
363
364{
365 validateEventDispatches = function (event) {
366 var dispatchListeners = event._dispatchListeners;
367 var dispatchInstances = event._dispatchInstances;
368 var listenersIsArr = Array.isArray(dispatchListeners);
369 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
370 var instancesIsArr = Array.isArray(dispatchInstances);
371 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
372
373 if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
374 error('EventPluginUtils: Invalid `event`.');
375 }
376 };
377}
378/**
379 * Dispatch the event to the listener.
380 * @param {SyntheticEvent} event SyntheticEvent to handle
381 * @param {function} listener Application-level callback
382 * @param {*} inst Internal component instance
383 */
384
385
386function executeDispatch(event, listener, inst) {
387 var type = event.type || 'unknown-event';
388 event.currentTarget = getNodeFromInstance(inst);
389 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
390 event.currentTarget = null;
391}
392/**
393 * Standard/simple iteration through an event's collected dispatches.
394 */
395
396function executeDispatchesInOrder(event) {
397 var dispatchListeners = event._dispatchListeners;
398 var dispatchInstances = event._dispatchInstances;
399
400 {
401 validateEventDispatches(event);
402 }
403
404 if (Array.isArray(dispatchListeners)) {
405 for (var i = 0; i < dispatchListeners.length; i++) {
406 if (event.isPropagationStopped()) {
407 break;
408 } // Listeners and Instances are two parallel arrays that are always in sync.
409
410
411 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
412 }
413 } else if (dispatchListeners) {
414 executeDispatch(event, dispatchListeners, dispatchInstances);
415 }
416
417 event._dispatchListeners = null;
418 event._dispatchInstances = null;
419}
420
421var FunctionComponent = 0;
422var ClassComponent = 1;
423var IndeterminateComponent = 2; // Before we know whether it is function or class
424
425var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
426
427var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
428
429var HostComponent = 5;
430var HostText = 6;
431var Fragment = 7;
432var Mode = 8;
433var ContextConsumer = 9;
434var ContextProvider = 10;
435var ForwardRef = 11;
436var Profiler = 12;
437var SuspenseComponent = 13;
438var MemoComponent = 14;
439var SimpleMemoComponent = 15;
440var LazyComponent = 16;
441var IncompleteClassComponent = 17;
442var DehydratedFragment = 18;
443var SuspenseListComponent = 19;
444var FundamentalComponent = 20;
445var ScopeComponent = 21;
446var Block = 22;
447
448/**
449 * Injectable ordering of event plugins.
450 */
451var eventPluginOrder = null;
452/**
453 * Injectable mapping from names to event plugin modules.
454 */
455
456var namesToPlugins = {};
457/**
458 * Recomputes the plugin list using the injected plugins and plugin ordering.
459 *
460 * @private
461 */
462
463function recomputePluginOrdering() {
464 if (!eventPluginOrder) {
465 // Wait until an `eventPluginOrder` is injected.
466 return;
467 }
468
469 for (var pluginName in namesToPlugins) {
470 var pluginModule = namesToPlugins[pluginName];
471 var pluginIndex = eventPluginOrder.indexOf(pluginName);
472
473 if (!(pluginIndex > -1)) {
474 {
475 throw Error( "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + pluginName + "`." );
476 }
477 }
478
479 if (plugins[pluginIndex]) {
480 continue;
481 }
482
483 if (!pluginModule.extractEvents) {
484 {
485 throw Error( "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + pluginName + "` does not." );
486 }
487 }
488
489 plugins[pluginIndex] = pluginModule;
490 var publishedEvents = pluginModule.eventTypes;
491
492 for (var eventName in publishedEvents) {
493 if (!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName)) {
494 {
495 throw Error( "EventPluginRegistry: Failed to publish event `" + eventName + "` for plugin `" + pluginName + "`." );
496 }
497 }
498 }
499 }
500}
501/**
502 * Publishes an event so that it can be dispatched by the supplied plugin.
503 *
504 * @param {object} dispatchConfig Dispatch configuration for the event.
505 * @param {object} PluginModule Plugin publishing the event.
506 * @return {boolean} True if the event was successfully published.
507 * @private
508 */
509
510
511function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
512 if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) {
513 {
514 throw Error( "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + eventName + "`." );
515 }
516 }
517
518 eventNameDispatchConfigs[eventName] = dispatchConfig;
519 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
520
521 if (phasedRegistrationNames) {
522 for (var phaseName in phasedRegistrationNames) {
523 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
524 var phasedRegistrationName = phasedRegistrationNames[phaseName];
525 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
526 }
527 }
528
529 return true;
530 } else if (dispatchConfig.registrationName) {
531 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
532 return true;
533 }
534
535 return false;
536}
537/**
538 * Publishes a registration name that is used to identify dispatched events.
539 *
540 * @param {string} registrationName Registration name to add.
541 * @param {object} PluginModule Plugin publishing the event.
542 * @private
543 */
544
545
546function publishRegistrationName(registrationName, pluginModule, eventName) {
547 if (!!registrationNameModules[registrationName]) {
548 {
549 throw Error( "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + registrationName + "`." );
550 }
551 }
552
553 registrationNameModules[registrationName] = pluginModule;
554 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
555
556 {
557 var lowerCasedName = registrationName.toLowerCase();
558 possibleRegistrationNames[lowerCasedName] = registrationName;
559
560 if (registrationName === 'onDoubleClick') {
561 possibleRegistrationNames.ondblclick = registrationName;
562 }
563 }
564}
565/**
566 * Registers plugins so that they can extract and dispatch events.
567 */
568
569/**
570 * Ordered list of injected plugins.
571 */
572
573
574var plugins = [];
575/**
576 * Mapping from event name to dispatch config
577 */
578
579var eventNameDispatchConfigs = {};
580/**
581 * Mapping from registration name to plugin module
582 */
583
584var registrationNameModules = {};
585/**
586 * Mapping from registration name to event name
587 */
588
589var registrationNameDependencies = {};
590/**
591 * Mapping from lowercase registration names to the properly cased version,
592 * used to warn in the case of missing event handlers. Available
593 * only in true.
594 * @type {Object}
595 */
596
597var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
598
599/**
600 * Injects an ordering of plugins (by plugin name). This allows the ordering
601 * to be decoupled from injection of the actual plugins so that ordering is
602 * always deterministic regardless of packaging, on-the-fly injection, etc.
603 *
604 * @param {array} InjectedEventPluginOrder
605 * @internal
606 */
607
608function injectEventPluginOrder(injectedEventPluginOrder) {
609 if (!!eventPluginOrder) {
610 {
611 throw Error( "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." );
612 }
613 } // Clone the ordering so it cannot be dynamically mutated.
614
615
616 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
617 recomputePluginOrdering();
618}
619/**
620 * Injects plugins to be used by plugin event system. The plugin names must be
621 * in the ordering injected by `injectEventPluginOrder`.
622 *
623 * Plugins can be injected as part of page initialization or on-the-fly.
624 *
625 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
626 * @internal
627 */
628
629function injectEventPluginsByName(injectedNamesToPlugins) {
630 var isOrderingDirty = false;
631
632 for (var pluginName in injectedNamesToPlugins) {
633 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
634 continue;
635 }
636
637 var pluginModule = injectedNamesToPlugins[pluginName];
638
639 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
640 if (!!namesToPlugins[pluginName]) {
641 {
642 throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + pluginName + "`." );
643 }
644 }
645
646 namesToPlugins[pluginName] = pluginModule;
647 isOrderingDirty = true;
648 }
649 }
650
651 if (isOrderingDirty) {
652 recomputePluginOrdering();
653 }
654}
655
656var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
657
658var PLUGIN_EVENT_SYSTEM = 1;
659var IS_REPLAYED = 1 << 5;
660var IS_FIRST_ANCESTOR = 1 << 6;
661
662var restoreImpl = null;
663var restoreTarget = null;
664var restoreQueue = null;
665
666function restoreStateOfTarget(target) {
667 // We perform this translation at the end of the event loop so that we
668 // always receive the correct fiber here
669 var internalInstance = getInstanceFromNode(target);
670
671 if (!internalInstance) {
672 // Unmounted
673 return;
674 }
675
676 if (!(typeof restoreImpl === 'function')) {
677 {
678 throw Error( "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." );
679 }
680 }
681
682 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
683
684 if (stateNode) {
685 var _props = getFiberCurrentPropsFromNode(stateNode);
686
687 restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
688 }
689}
690
691function setRestoreImplementation(impl) {
692 restoreImpl = impl;
693}
694function enqueueStateRestore(target) {
695 if (restoreTarget) {
696 if (restoreQueue) {
697 restoreQueue.push(target);
698 } else {
699 restoreQueue = [target];
700 }
701 } else {
702 restoreTarget = target;
703 }
704}
705function needsStateRestore() {
706 return restoreTarget !== null || restoreQueue !== null;
707}
708function restoreStateIfNeeded() {
709 if (!restoreTarget) {
710 return;
711 }
712
713 var target = restoreTarget;
714 var queuedTargets = restoreQueue;
715 restoreTarget = null;
716 restoreQueue = null;
717 restoreStateOfTarget(target);
718
719 if (queuedTargets) {
720 for (var i = 0; i < queuedTargets.length; i++) {
721 restoreStateOfTarget(queuedTargets[i]);
722 }
723 }
724}
725
726var enableProfilerTimer = true; // Trace which interactions trigger each commit.
727
728var enableDeprecatedFlareAPI = false; // Experimental Host Component support.
729
730var enableFundamentalAPI = false; // Experimental Scope support.
731var warnAboutStringRefs = false;
732
733// the renderer. Such as when we're dispatching events or if third party
734// libraries need to call batchedUpdates. Eventually, this API will go away when
735// everything is batched by default. We'll then have a similar API to opt-out of
736// scheduled work and instead do synchronous work.
737// Defaults
738
739var batchedUpdatesImpl = function (fn, bookkeeping) {
740 return fn(bookkeeping);
741};
742
743var discreteUpdatesImpl = function (fn, a, b, c, d) {
744 return fn(a, b, c, d);
745};
746
747var flushDiscreteUpdatesImpl = function () {};
748
749var batchedEventUpdatesImpl = batchedUpdatesImpl;
750var isInsideEventHandler = false;
751var isBatchingEventUpdates = false;
752
753function finishEventHandler() {
754 // Here we wait until all updates have propagated, which is important
755 // when using controlled components within layers:
756 // https://github.com/facebook/react/issues/1698
757 // Then we restore state of any controlled component.
758 var controlledComponentsHavePendingUpdates = needsStateRestore();
759
760 if (controlledComponentsHavePendingUpdates) {
761 // If a controlled event was fired, we may need to restore the state of
762 // the DOM node back to the controlled value. This is necessary when React
763 // bails out of the update without touching the DOM.
764 flushDiscreteUpdatesImpl();
765 restoreStateIfNeeded();
766 }
767}
768
769function batchedUpdates(fn, bookkeeping) {
770 if (isInsideEventHandler) {
771 // If we are currently inside another batch, we need to wait until it
772 // fully completes before restoring state.
773 return fn(bookkeeping);
774 }
775
776 isInsideEventHandler = true;
777
778 try {
779 return batchedUpdatesImpl(fn, bookkeeping);
780 } finally {
781 isInsideEventHandler = false;
782 finishEventHandler();
783 }
784}
785function batchedEventUpdates(fn, a, b) {
786 if (isBatchingEventUpdates) {
787 // If we are currently inside another batch, we need to wait until it
788 // fully completes before restoring state.
789 return fn(a, b);
790 }
791
792 isBatchingEventUpdates = true;
793
794 try {
795 return batchedEventUpdatesImpl(fn, a, b);
796 } finally {
797 isBatchingEventUpdates = false;
798 finishEventHandler();
799 }
800} // This is for the React Flare event system
801function discreteUpdates(fn, a, b, c, d) {
802 var prevIsInsideEventHandler = isInsideEventHandler;
803 isInsideEventHandler = true;
804
805 try {
806 return discreteUpdatesImpl(fn, a, b, c, d);
807 } finally {
808 isInsideEventHandler = prevIsInsideEventHandler;
809
810 if (!isInsideEventHandler) {
811 finishEventHandler();
812 }
813 }
814}
815function flushDiscreteUpdatesIfNeeded(timeStamp) {
816 // event.timeStamp isn't overly reliable due to inconsistencies in
817 // how different browsers have historically provided the time stamp.
818 // Some browsers provide high-resolution time stamps for all events,
819 // some provide low-resolution time stamps for all events. FF < 52
820 // even mixes both time stamps together. Some browsers even report
821 // negative time stamps or time stamps that are 0 (iOS9) in some cases.
822 // Given we are only comparing two time stamps with equality (!==),
823 // we are safe from the resolution differences. If the time stamp is 0
824 // we bail-out of preventing the flush, which can affect semantics,
825 // such as if an earlier flush removes or adds event listeners that
826 // are fired in the subsequent flush. However, this is the same
827 // behaviour as we had before this change, so the risks are low.
828 if (!isInsideEventHandler && (!enableDeprecatedFlareAPI )) {
829 flushDiscreteUpdatesImpl();
830 }
831}
832function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {
833 batchedUpdatesImpl = _batchedUpdatesImpl;
834 discreteUpdatesImpl = _discreteUpdatesImpl;
835 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
836 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
837}
838
839var DiscreteEvent = 0;
840var UserBlockingEvent = 1;
841var ContinuousEvent = 2;
842
843// A reserved attribute.
844// It is handled by React separately and shouldn't be written to the DOM.
845var RESERVED = 0; // A simple string attribute.
846// Attributes that aren't in the whitelist are presumed to have this type.
847
848var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
849// "enumerated" attributes with "true" and "false" as possible values.
850// When true, it should be set to a "true" string.
851// When false, it should be set to a "false" string.
852
853var BOOLEANISH_STRING = 2; // A real boolean attribute.
854// When true, it should be present (set either to an empty string or its name).
855// When false, it should be omitted.
856
857var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
858// When true, it should be present (set either to an empty string or its name).
859// When false, it should be omitted.
860// For any other value, should be present with that value.
861
862var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
863// When falsy, it should be removed.
864
865var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
866// When falsy, it should be removed.
867
868var POSITIVE_NUMERIC = 6;
869
870/* eslint-disable max-len */
871var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
872/* eslint-enable max-len */
873
874var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
875var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
876var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
877var hasOwnProperty = Object.prototype.hasOwnProperty;
878var illegalAttributeNameCache = {};
879var validatedAttributeNameCache = {};
880function isAttributeNameSafe(attributeName) {
881 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
882 return true;
883 }
884
885 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
886 return false;
887 }
888
889 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
890 validatedAttributeNameCache[attributeName] = true;
891 return true;
892 }
893
894 illegalAttributeNameCache[attributeName] = true;
895
896 {
897 error('Invalid attribute name: `%s`', attributeName);
898 }
899
900 return false;
901}
902function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
903 if (propertyInfo !== null) {
904 return propertyInfo.type === RESERVED;
905 }
906
907 if (isCustomComponentTag) {
908 return false;
909 }
910
911 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
912 return true;
913 }
914
915 return false;
916}
917function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
918 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
919 return false;
920 }
921
922 switch (typeof value) {
923 case 'function': // $FlowIssue symbol is perfectly valid here
924
925 case 'symbol':
926 // eslint-disable-line
927 return true;
928
929 case 'boolean':
930 {
931 if (isCustomComponentTag) {
932 return false;
933 }
934
935 if (propertyInfo !== null) {
936 return !propertyInfo.acceptsBooleans;
937 } else {
938 var prefix = name.toLowerCase().slice(0, 5);
939 return prefix !== 'data-' && prefix !== 'aria-';
940 }
941 }
942
943 default:
944 return false;
945 }
946}
947function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
948 if (value === null || typeof value === 'undefined') {
949 return true;
950 }
951
952 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
953 return true;
954 }
955
956 if (isCustomComponentTag) {
957 return false;
958 }
959
960 if (propertyInfo !== null) {
961 switch (propertyInfo.type) {
962 case BOOLEAN:
963 return !value;
964
965 case OVERLOADED_BOOLEAN:
966 return value === false;
967
968 case NUMERIC:
969 return isNaN(value);
970
971 case POSITIVE_NUMERIC:
972 return isNaN(value) || value < 1;
973 }
974 }
975
976 return false;
977}
978function getPropertyInfo(name) {
979 return properties.hasOwnProperty(name) ? properties[name] : null;
980}
981
982function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL) {
983 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
984 this.attributeName = attributeName;
985 this.attributeNamespace = attributeNamespace;
986 this.mustUseProperty = mustUseProperty;
987 this.propertyName = name;
988 this.type = type;
989 this.sanitizeURL = sanitizeURL;
990} // When adding attributes to this list, be sure to also add them to
991// the `possibleStandardNames` module to ensure casing and incorrect
992// name warnings.
993
994
995var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
996
997var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
998// elements (not just inputs). Now that ReactDOMInput assigns to the
999// defaultValue property -- do we need this?
1000'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];
1001
1002reservedProps.forEach(function (name) {
1003 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
1004 name, // attributeName
1005 null, // attributeNamespace
1006 false);
1007}); // A few React string attributes have a different name.
1008// This is a mapping from React prop names to the attribute names.
1009
1010[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
1011 var name = _ref[0],
1012 attributeName = _ref[1];
1013 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1014 attributeName, // attributeName
1015 null, // attributeNamespace
1016 false);
1017}); // These are "enumerated" HTML attributes that accept "true" and "false".
1018// In React, we let users pass `true` and `false` even though technically
1019// these aren't boolean attributes (they are coerced to strings).
1020
1021['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
1022 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
1023 name.toLowerCase(), // attributeName
1024 null, // attributeNamespace
1025 false);
1026}); // These are "enumerated" SVG attributes that accept "true" and "false".
1027// In React, we let users pass `true` and `false` even though technically
1028// these aren't boolean attributes (they are coerced to strings).
1029// Since these are SVG attributes, their attribute names are case-sensitive.
1030
1031['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
1032 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
1033 name, // attributeName
1034 null, // attributeNamespace
1035 false);
1036}); // These are HTML boolean attributes.
1037
1038['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
1039// on the client side because the browsers are inconsistent. Instead we call focus().
1040'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
1041'itemScope'].forEach(function (name) {
1042 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
1043 name.toLowerCase(), // attributeName
1044 null, // attributeNamespace
1045 false);
1046}); // These are the few React props that we set as DOM properties
1047// rather than attributes. These are all booleans.
1048
1049['checked', // Note: `option.selected` is not updated if `select.multiple` is
1050// disabled with `removeAttribute`. We have special logic for handling this.
1051'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,
1052// you'll need to set attributeName to name.toLowerCase()
1053// instead in the assignment below.
1054].forEach(function (name) {
1055 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
1056 name, // attributeName
1057 null, // attributeNamespace
1058 false);
1059}); // These are HTML attributes that are "overloaded booleans": they behave like
1060// booleans, but can also accept a string value.
1061
1062['capture', 'download' // NOTE: if you add a camelCased prop to this list,
1063// you'll need to set attributeName to name.toLowerCase()
1064// instead in the assignment below.
1065].forEach(function (name) {
1066 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
1067 name, // attributeName
1068 null, // attributeNamespace
1069 false);
1070}); // These are HTML attributes that must be positive numbers.
1071
1072['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
1073// you'll need to set attributeName to name.toLowerCase()
1074// instead in the assignment below.
1075].forEach(function (name) {
1076 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
1077 name, // attributeName
1078 null, // attributeNamespace
1079 false);
1080}); // These are HTML attributes that must be numbers.
1081
1082['rowSpan', 'start'].forEach(function (name) {
1083 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
1084 name.toLowerCase(), // attributeName
1085 null, // attributeNamespace
1086 false);
1087});
1088var CAMELIZE = /[\-\:]([a-z])/g;
1089
1090var capitalize = function (token) {
1091 return token[1].toUpperCase();
1092}; // This is a list of all SVG attributes that need special casing, namespacing,
1093// or boolean value assignment. Regular attributes that just accept strings
1094// and have the same names are omitted, just like in the HTML whitelist.
1095// Some of these attributes can be hard to find. This list was created by
1096// scraping the MDN documentation.
1097
1098
1099['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height' // NOTE: if you add a camelCased prop to this list,
1100// you'll need to set attributeName to name.toLowerCase()
1101// instead in the assignment below.
1102].forEach(function (attributeName) {
1103 var name = attributeName.replace(CAMELIZE, capitalize);
1104 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1105 attributeName, null, // attributeNamespace
1106 false);
1107}); // String SVG attributes with the xlink namespace.
1108
1109['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
1110// you'll need to set attributeName to name.toLowerCase()
1111// instead in the assignment below.
1112].forEach(function (attributeName) {
1113 var name = attributeName.replace(CAMELIZE, capitalize);
1114 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1115 attributeName, 'http://www.w3.org/1999/xlink', false);
1116}); // String SVG attributes with the xml namespace.
1117
1118['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
1119// you'll need to set attributeName to name.toLowerCase()
1120// instead in the assignment below.
1121].forEach(function (attributeName) {
1122 var name = attributeName.replace(CAMELIZE, capitalize);
1123 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1124 attributeName, 'http://www.w3.org/XML/1998/namespace', false);
1125}); // These attribute exists both in HTML and SVG.
1126// The attribute name is case-sensitive in SVG so we can't just use
1127// the React name like we do for attributes that exist only in HTML.
1128
1129['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
1130 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
1131 attributeName.toLowerCase(), // attributeName
1132 null, // attributeNamespace
1133 false);
1134}); // These attributes accept URLs. These must not allow javascript: URLS.
1135// These will also need to accept Trusted Types object in the future.
1136
1137var xlinkHref = 'xlinkHref';
1138properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
1139'xlink:href', 'http://www.w3.org/1999/xlink', true);
1140['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
1141 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
1142 attributeName.toLowerCase(), // attributeName
1143 null, // attributeNamespace
1144 true);
1145});
1146
1147var ReactDebugCurrentFrame = null;
1148
1149{
1150 ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1151} // A javascript: URL can contain leading C0 control or \u0020 SPACE,
1152// and any newline or tab are filtered out as if they're not part of the URL.
1153// https://url.spec.whatwg.org/#url-parsing
1154// Tab or newline are defined as \r\n\t:
1155// https://infra.spec.whatwg.org/#ascii-tab-or-newline
1156// A C0 control is a code point in the range \u0000 NULL to \u001F
1157// INFORMATION SEPARATOR ONE, inclusive:
1158// https://infra.spec.whatwg.org/#c0-control-or-space
1159
1160/* eslint-disable max-len */
1161
1162
1163var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i;
1164var didWarn = false;
1165
1166function sanitizeURL(url) {
1167 {
1168 if (!didWarn && isJavaScriptProtocol.test(url)) {
1169 didWarn = true;
1170
1171 error('A future version of React will block javascript: URLs as a security precaution. ' + 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + 'using dangerouslySetInnerHTML instead. React was passed %s.', JSON.stringify(url));
1172 }
1173 }
1174}
1175
1176/**
1177 * Get the value for a property on a node. Only used in DEV for SSR validation.
1178 * The "expected" argument is used as a hint of what the expected value is.
1179 * Some properties have multiple equivalent values.
1180 */
1181function getValueForProperty(node, name, expected, propertyInfo) {
1182 {
1183 if (propertyInfo.mustUseProperty) {
1184 var propertyName = propertyInfo.propertyName;
1185 return node[propertyName];
1186 } else {
1187 if ( propertyInfo.sanitizeURL) {
1188 // If we haven't fully disabled javascript: URLs, and if
1189 // the hydration is successful of a javascript: URL, we
1190 // still want to warn on the client.
1191 sanitizeURL('' + expected);
1192 }
1193
1194 var attributeName = propertyInfo.attributeName;
1195 var stringValue = null;
1196
1197 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
1198 if (node.hasAttribute(attributeName)) {
1199 var value = node.getAttribute(attributeName);
1200
1201 if (value === '') {
1202 return true;
1203 }
1204
1205 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1206 return value;
1207 }
1208
1209 if (value === '' + expected) {
1210 return expected;
1211 }
1212
1213 return value;
1214 }
1215 } else if (node.hasAttribute(attributeName)) {
1216 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1217 // We had an attribute but shouldn't have had one, so read it
1218 // for the error message.
1219 return node.getAttribute(attributeName);
1220 }
1221
1222 if (propertyInfo.type === BOOLEAN) {
1223 // If this was a boolean, it doesn't matter what the value is
1224 // the fact that we have it is the same as the expected.
1225 return expected;
1226 } // Even if this property uses a namespace we use getAttribute
1227 // because we assume its namespaced name is the same as our config.
1228 // To use getAttributeNS we need the local name which we don't have
1229 // in our config atm.
1230
1231
1232 stringValue = node.getAttribute(attributeName);
1233 }
1234
1235 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1236 return stringValue === null ? expected : stringValue;
1237 } else if (stringValue === '' + expected) {
1238 return expected;
1239 } else {
1240 return stringValue;
1241 }
1242 }
1243 }
1244}
1245/**
1246 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
1247 * The third argument is used as a hint of what the expected value is. Some
1248 * attributes have multiple equivalent values.
1249 */
1250
1251function getValueForAttribute(node, name, expected) {
1252 {
1253 if (!isAttributeNameSafe(name)) {
1254 return;
1255 }
1256
1257 if (!node.hasAttribute(name)) {
1258 return expected === undefined ? undefined : null;
1259 }
1260
1261 var value = node.getAttribute(name);
1262
1263 if (value === '' + expected) {
1264 return expected;
1265 }
1266
1267 return value;
1268 }
1269}
1270/**
1271 * Sets the value for a property on a node.
1272 *
1273 * @param {DOMElement} node
1274 * @param {string} name
1275 * @param {*} value
1276 */
1277
1278function setValueForProperty(node, name, value, isCustomComponentTag) {
1279 var propertyInfo = getPropertyInfo(name);
1280
1281 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
1282 return;
1283 }
1284
1285 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
1286 value = null;
1287 } // If the prop isn't in the special list, treat it as a simple attribute.
1288
1289
1290 if (isCustomComponentTag || propertyInfo === null) {
1291 if (isAttributeNameSafe(name)) {
1292 var _attributeName = name;
1293
1294 if (value === null) {
1295 node.removeAttribute(_attributeName);
1296 } else {
1297 node.setAttribute(_attributeName, '' + value);
1298 }
1299 }
1300
1301 return;
1302 }
1303
1304 var mustUseProperty = propertyInfo.mustUseProperty;
1305
1306 if (mustUseProperty) {
1307 var propertyName = propertyInfo.propertyName;
1308
1309 if (value === null) {
1310 var type = propertyInfo.type;
1311 node[propertyName] = type === BOOLEAN ? false : '';
1312 } else {
1313 // Contrary to `setAttribute`, object properties are properly
1314 // `toString`ed by IE8/9.
1315 node[propertyName] = value;
1316 }
1317
1318 return;
1319 } // The rest are treated as attributes with special cases.
1320
1321
1322 var attributeName = propertyInfo.attributeName,
1323 attributeNamespace = propertyInfo.attributeNamespace;
1324
1325 if (value === null) {
1326 node.removeAttribute(attributeName);
1327 } else {
1328 var _type = propertyInfo.type;
1329 var attributeValue;
1330
1331 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
1332 // If attribute type is boolean, we know for sure it won't be an execution sink
1333 // and we won't require Trusted Type here.
1334 attributeValue = '';
1335 } else {
1336 // `setAttribute` with objects becomes only `[object]` in IE8/9,
1337 // ('' + value) makes it output the correct toString()-value.
1338 {
1339 attributeValue = '' + value;
1340 }
1341
1342 if (propertyInfo.sanitizeURL) {
1343 sanitizeURL(attributeValue.toString());
1344 }
1345 }
1346
1347 if (attributeNamespace) {
1348 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
1349 } else {
1350 node.setAttribute(attributeName, attributeValue);
1351 }
1352 }
1353}
1354
1355var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1356function describeComponentFrame (name, source, ownerName) {
1357 var sourceInfo = '';
1358
1359 if (source) {
1360 var path = source.fileName;
1361 var fileName = path.replace(BEFORE_SLASH_RE, '');
1362
1363 {
1364 // In DEV, include code for a common special case:
1365 // prefer "folder/index.js" instead of just "index.js".
1366 if (/^index\./.test(fileName)) {
1367 var match = path.match(BEFORE_SLASH_RE);
1368
1369 if (match) {
1370 var pathBeforeSlash = match[1];
1371
1372 if (pathBeforeSlash) {
1373 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1374 fileName = folderName + '/' + fileName;
1375 }
1376 }
1377 }
1378 }
1379
1380 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1381 } else if (ownerName) {
1382 sourceInfo = ' (created by ' + ownerName + ')';
1383 }
1384
1385 return '\n in ' + (name || 'Unknown') + sourceInfo;
1386}
1387
1388// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
1389// nor polyfill, then a plain number is used for performance.
1390var hasSymbol = typeof Symbol === 'function' && Symbol.for;
1391var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
1392var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
1393var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
1394var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
1395var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
1396var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
1397var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
1398var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
1399var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
1400var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
1401var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
1402var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
1403var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
1404var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
1405var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
1406var FAUX_ITERATOR_SYMBOL = '@@iterator';
1407function getIteratorFn(maybeIterable) {
1408 if (maybeIterable === null || typeof maybeIterable !== 'object') {
1409 return null;
1410 }
1411
1412 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
1413
1414 if (typeof maybeIterator === 'function') {
1415 return maybeIterator;
1416 }
1417
1418 return null;
1419}
1420
1421var Uninitialized = -1;
1422var Pending = 0;
1423var Resolved = 1;
1424var Rejected = 2;
1425function refineResolvedLazyComponent(lazyComponent) {
1426 return lazyComponent._status === Resolved ? lazyComponent._result : null;
1427}
1428function initializeLazyComponentType(lazyComponent) {
1429 if (lazyComponent._status === Uninitialized) {
1430 lazyComponent._status = Pending;
1431 var ctor = lazyComponent._ctor;
1432 var thenable = ctor();
1433 lazyComponent._result = thenable;
1434 thenable.then(function (moduleObject) {
1435 if (lazyComponent._status === Pending) {
1436 var defaultExport = moduleObject.default;
1437
1438 {
1439 if (defaultExport === undefined) {
1440 error('lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
1441 }
1442 }
1443
1444 lazyComponent._status = Resolved;
1445 lazyComponent._result = defaultExport;
1446 }
1447 }, function (error) {
1448 if (lazyComponent._status === Pending) {
1449 lazyComponent._status = Rejected;
1450 lazyComponent._result = error;
1451 }
1452 });
1453 }
1454}
1455
1456function getWrappedName(outerType, innerType, wrapperName) {
1457 var functionName = innerType.displayName || innerType.name || '';
1458 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
1459}
1460
1461function getComponentName(type) {
1462 if (type == null) {
1463 // Host root, text node or just invalid type.
1464 return null;
1465 }
1466
1467 {
1468 if (typeof type.tag === 'number') {
1469 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
1470 }
1471 }
1472
1473 if (typeof type === 'function') {
1474 return type.displayName || type.name || null;
1475 }
1476
1477 if (typeof type === 'string') {
1478 return type;
1479 }
1480
1481 switch (type) {
1482 case REACT_FRAGMENT_TYPE:
1483 return 'Fragment';
1484
1485 case REACT_PORTAL_TYPE:
1486 return 'Portal';
1487
1488 case REACT_PROFILER_TYPE:
1489 return "Profiler";
1490
1491 case REACT_STRICT_MODE_TYPE:
1492 return 'StrictMode';
1493
1494 case REACT_SUSPENSE_TYPE:
1495 return 'Suspense';
1496
1497 case REACT_SUSPENSE_LIST_TYPE:
1498 return 'SuspenseList';
1499 }
1500
1501 if (typeof type === 'object') {
1502 switch (type.$$typeof) {
1503 case REACT_CONTEXT_TYPE:
1504 return 'Context.Consumer';
1505
1506 case REACT_PROVIDER_TYPE:
1507 return 'Context.Provider';
1508
1509 case REACT_FORWARD_REF_TYPE:
1510 return getWrappedName(type, type.render, 'ForwardRef');
1511
1512 case REACT_MEMO_TYPE:
1513 return getComponentName(type.type);
1514
1515 case REACT_BLOCK_TYPE:
1516 return getComponentName(type.render);
1517
1518 case REACT_LAZY_TYPE:
1519 {
1520 var thenable = type;
1521 var resolvedThenable = refineResolvedLazyComponent(thenable);
1522
1523 if (resolvedThenable) {
1524 return getComponentName(resolvedThenable);
1525 }
1526
1527 break;
1528 }
1529 }
1530 }
1531
1532 return null;
1533}
1534
1535var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
1536
1537function describeFiber(fiber) {
1538 switch (fiber.tag) {
1539 case HostRoot:
1540 case HostPortal:
1541 case HostText:
1542 case Fragment:
1543 case ContextProvider:
1544 case ContextConsumer:
1545 return '';
1546
1547 default:
1548 var owner = fiber._debugOwner;
1549 var source = fiber._debugSource;
1550 var name = getComponentName(fiber.type);
1551 var ownerName = null;
1552
1553 if (owner) {
1554 ownerName = getComponentName(owner.type);
1555 }
1556
1557 return describeComponentFrame(name, source, ownerName);
1558 }
1559}
1560
1561function getStackByFiberInDevAndProd(workInProgress) {
1562 var info = '';
1563 var node = workInProgress;
1564
1565 do {
1566 info += describeFiber(node);
1567 node = node.return;
1568 } while (node);
1569
1570 return info;
1571}
1572var current = null;
1573var isRendering = false;
1574function getCurrentFiberOwnerNameInDevOrNull() {
1575 {
1576 if (current === null) {
1577 return null;
1578 }
1579
1580 var owner = current._debugOwner;
1581
1582 if (owner !== null && typeof owner !== 'undefined') {
1583 return getComponentName(owner.type);
1584 }
1585 }
1586
1587 return null;
1588}
1589function getCurrentFiberStackInDev() {
1590 {
1591 if (current === null) {
1592 return '';
1593 } // Safe because if current fiber exists, we are reconciling,
1594 // and it is guaranteed to be the work-in-progress version.
1595
1596
1597 return getStackByFiberInDevAndProd(current);
1598 }
1599}
1600function resetCurrentFiber() {
1601 {
1602 ReactDebugCurrentFrame$1.getCurrentStack = null;
1603 current = null;
1604 isRendering = false;
1605 }
1606}
1607function setCurrentFiber(fiber) {
1608 {
1609 ReactDebugCurrentFrame$1.getCurrentStack = getCurrentFiberStackInDev;
1610 current = fiber;
1611 isRendering = false;
1612 }
1613}
1614function setIsRendering(rendering) {
1615 {
1616 isRendering = rendering;
1617 }
1618}
1619
1620// Flow does not allow string concatenation of most non-string types. To work
1621// around this limitation, we use an opaque type that can only be obtained by
1622// passing the value through getToStringValue first.
1623function toString(value) {
1624 return '' + value;
1625}
1626function getToStringValue(value) {
1627 switch (typeof value) {
1628 case 'boolean':
1629 case 'number':
1630 case 'object':
1631 case 'string':
1632 case 'undefined':
1633 return value;
1634
1635 default:
1636 // function, symbol are assigned as empty strings
1637 return '';
1638 }
1639}
1640
1641var ReactDebugCurrentFrame$2 = null;
1642var ReactControlledValuePropTypes = {
1643 checkPropTypes: null
1644};
1645
1646{
1647 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
1648 var hasReadOnlyValue = {
1649 button: true,
1650 checkbox: true,
1651 image: true,
1652 hidden: true,
1653 radio: true,
1654 reset: true,
1655 submit: true
1656 };
1657 var propTypes = {
1658 value: function (props, propName, componentName) {
1659 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null || enableDeprecatedFlareAPI ) {
1660 return null;
1661 }
1662
1663 return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
1664 },
1665 checked: function (props, propName, componentName) {
1666 if (props.onChange || props.readOnly || props.disabled || props[propName] == null || enableDeprecatedFlareAPI ) {
1667 return null;
1668 }
1669
1670 return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
1671 }
1672 };
1673 /**
1674 * Provide a linked `value` attribute for controlled forms. You should not use
1675 * this outside of the ReactDOM controlled form components.
1676 */
1677
1678 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
1679 checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$2.getStackAddendum);
1680 };
1681}
1682
1683function isCheckable(elem) {
1684 var type = elem.type;
1685 var nodeName = elem.nodeName;
1686 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
1687}
1688
1689function getTracker(node) {
1690 return node._valueTracker;
1691}
1692
1693function detachTracker(node) {
1694 node._valueTracker = null;
1695}
1696
1697function getValueFromNode(node) {
1698 var value = '';
1699
1700 if (!node) {
1701 return value;
1702 }
1703
1704 if (isCheckable(node)) {
1705 value = node.checked ? 'true' : 'false';
1706 } else {
1707 value = node.value;
1708 }
1709
1710 return value;
1711}
1712
1713function trackValueOnNode(node) {
1714 var valueField = isCheckable(node) ? 'checked' : 'value';
1715 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
1716 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
1717 // and don't track value will cause over reporting of changes,
1718 // but it's better then a hard failure
1719 // (needed for certain tests that spyOn input values and Safari)
1720
1721 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
1722 return;
1723 }
1724
1725 var get = descriptor.get,
1726 set = descriptor.set;
1727 Object.defineProperty(node, valueField, {
1728 configurable: true,
1729 get: function () {
1730 return get.call(this);
1731 },
1732 set: function (value) {
1733 currentValue = '' + value;
1734 set.call(this, value);
1735 }
1736 }); // We could've passed this the first time
1737 // but it triggers a bug in IE11 and Edge 14/15.
1738 // Calling defineProperty() again should be equivalent.
1739 // https://github.com/facebook/react/issues/11768
1740
1741 Object.defineProperty(node, valueField, {
1742 enumerable: descriptor.enumerable
1743 });
1744 var tracker = {
1745 getValue: function () {
1746 return currentValue;
1747 },
1748 setValue: function (value) {
1749 currentValue = '' + value;
1750 },
1751 stopTracking: function () {
1752 detachTracker(node);
1753 delete node[valueField];
1754 }
1755 };
1756 return tracker;
1757}
1758
1759function track(node) {
1760 if (getTracker(node)) {
1761 return;
1762 } // TODO: Once it's just Fiber we can move this to node._wrapperState
1763
1764
1765 node._valueTracker = trackValueOnNode(node);
1766}
1767function updateValueIfChanged(node) {
1768 if (!node) {
1769 return false;
1770 }
1771
1772 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
1773 // that trying again will succeed
1774
1775 if (!tracker) {
1776 return true;
1777 }
1778
1779 var lastValue = tracker.getValue();
1780 var nextValue = getValueFromNode(node);
1781
1782 if (nextValue !== lastValue) {
1783 tracker.setValue(nextValue);
1784 return true;
1785 }
1786
1787 return false;
1788}
1789
1790var didWarnValueDefaultValue = false;
1791var didWarnCheckedDefaultChecked = false;
1792var didWarnControlledToUncontrolled = false;
1793var didWarnUncontrolledToControlled = false;
1794
1795function isControlled(props) {
1796 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
1797 return usesChecked ? props.checked != null : props.value != null;
1798}
1799/**
1800 * Implements an <input> host component that allows setting these optional
1801 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
1802 *
1803 * If `checked` or `value` are not supplied (or null/undefined), user actions
1804 * that affect the checked state or value will trigger updates to the element.
1805 *
1806 * If they are supplied (and not null/undefined), the rendered element will not
1807 * trigger updates to the element. Instead, the props must change in order for
1808 * the rendered element to be updated.
1809 *
1810 * The rendered element will be initialized as unchecked (or `defaultChecked`)
1811 * with an empty value (or `defaultValue`).
1812 *
1813 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
1814 */
1815
1816
1817function getHostProps(element, props) {
1818 var node = element;
1819 var checked = props.checked;
1820
1821 var hostProps = _assign({}, props, {
1822 defaultChecked: undefined,
1823 defaultValue: undefined,
1824 value: undefined,
1825 checked: checked != null ? checked : node._wrapperState.initialChecked
1826 });
1827
1828 return hostProps;
1829}
1830function initWrapperState(element, props) {
1831 {
1832 ReactControlledValuePropTypes.checkPropTypes('input', props);
1833
1834 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
1835 error('%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
1836
1837 didWarnCheckedDefaultChecked = true;
1838 }
1839
1840 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
1841 error('%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
1842
1843 didWarnValueDefaultValue = true;
1844 }
1845 }
1846
1847 var node = element;
1848 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
1849 node._wrapperState = {
1850 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
1851 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
1852 controlled: isControlled(props)
1853 };
1854}
1855function updateChecked(element, props) {
1856 var node = element;
1857 var checked = props.checked;
1858
1859 if (checked != null) {
1860 setValueForProperty(node, 'checked', checked, false);
1861 }
1862}
1863function updateWrapper(element, props) {
1864 var node = element;
1865
1866 {
1867 var controlled = isControlled(props);
1868
1869 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
1870 error('A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
1871
1872 didWarnUncontrolledToControlled = true;
1873 }
1874
1875 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
1876 error('A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
1877
1878 didWarnControlledToUncontrolled = true;
1879 }
1880 }
1881
1882 updateChecked(element, props);
1883 var value = getToStringValue(props.value);
1884 var type = props.type;
1885
1886 if (value != null) {
1887 if (type === 'number') {
1888 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
1889 // eslint-disable-next-line
1890 node.value != value) {
1891 node.value = toString(value);
1892 }
1893 } else if (node.value !== toString(value)) {
1894 node.value = toString(value);
1895 }
1896 } else if (type === 'submit' || type === 'reset') {
1897 // Submit/reset inputs need the attribute removed completely to avoid
1898 // blank-text buttons.
1899 node.removeAttribute('value');
1900 return;
1901 }
1902
1903 {
1904 // When syncing the value attribute, the value comes from a cascade of
1905 // properties:
1906 // 1. The value React property
1907 // 2. The defaultValue React property
1908 // 3. Otherwise there should be no change
1909 if (props.hasOwnProperty('value')) {
1910 setDefaultValue(node, props.type, value);
1911 } else if (props.hasOwnProperty('defaultValue')) {
1912 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
1913 }
1914 }
1915
1916 {
1917 // When syncing the checked attribute, it only changes when it needs
1918 // to be removed, such as transitioning from a checkbox into a text input
1919 if (props.checked == null && props.defaultChecked != null) {
1920 node.defaultChecked = !!props.defaultChecked;
1921 }
1922 }
1923}
1924function postMountWrapper(element, props, isHydrating) {
1925 var node = element; // Do not assign value if it is already set. This prevents user text input
1926 // from being lost during SSR hydration.
1927
1928 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
1929 var type = props.type;
1930 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
1931 // default value provided by the browser. See: #12872
1932
1933 if (isButton && (props.value === undefined || props.value === null)) {
1934 return;
1935 }
1936
1937 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
1938 // from being lost during SSR hydration.
1939
1940 if (!isHydrating) {
1941 {
1942 // When syncing the value attribute, the value property should use
1943 // the wrapperState._initialValue property. This uses:
1944 //
1945 // 1. The value React property when present
1946 // 2. The defaultValue React property when present
1947 // 3. An empty string
1948 if (initialValue !== node.value) {
1949 node.value = initialValue;
1950 }
1951 }
1952 }
1953
1954 {
1955 // Otherwise, the value attribute is synchronized to the property,
1956 // so we assign defaultValue to the same thing as the value property
1957 // assignment step above.
1958 node.defaultValue = initialValue;
1959 }
1960 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
1961 // this is needed to work around a chrome bug where setting defaultChecked
1962 // will sometimes influence the value of checked (even after detachment).
1963 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
1964 // We need to temporarily unset name to avoid disrupting radio button groups.
1965
1966
1967 var name = node.name;
1968
1969 if (name !== '') {
1970 node.name = '';
1971 }
1972
1973 {
1974 // When syncing the checked attribute, both the checked property and
1975 // attribute are assigned at the same time using defaultChecked. This uses:
1976 //
1977 // 1. The checked React property when present
1978 // 2. The defaultChecked React property when present
1979 // 3. Otherwise, false
1980 node.defaultChecked = !node.defaultChecked;
1981 node.defaultChecked = !!node._wrapperState.initialChecked;
1982 }
1983
1984 if (name !== '') {
1985 node.name = name;
1986 }
1987}
1988function restoreControlledState(element, props) {
1989 var node = element;
1990 updateWrapper(node, props);
1991 updateNamedCousins(node, props);
1992}
1993
1994function updateNamedCousins(rootNode, props) {
1995 var name = props.name;
1996
1997 if (props.type === 'radio' && name != null) {
1998 var queryRoot = rootNode;
1999
2000 while (queryRoot.parentNode) {
2001 queryRoot = queryRoot.parentNode;
2002 } // If `rootNode.form` was non-null, then we could try `form.elements`,
2003 // but that sometimes behaves strangely in IE8. We could also try using
2004 // `form.getElementsByName`, but that will only return direct children
2005 // and won't include inputs that use the HTML5 `form=` attribute. Since
2006 // the input might not even be in a form. It might not even be in the
2007 // document. Let's just use the local `querySelectorAll` to ensure we don't
2008 // miss anything.
2009
2010
2011 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
2012
2013 for (var i = 0; i < group.length; i++) {
2014 var otherNode = group[i];
2015
2016 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
2017 continue;
2018 } // This will throw if radio buttons rendered by different copies of React
2019 // and the same name are rendered into the same form (same as #1939).
2020 // That's probably okay; we don't support it just as we don't support
2021 // mixing React radio buttons with non-React ones.
2022
2023
2024 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
2025
2026 if (!otherProps) {
2027 {
2028 throw Error( "ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported." );
2029 }
2030 } // We need update the tracked value on the named cousin since the value
2031 // was changed but the input saw no event or value set
2032
2033
2034 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
2035 // was previously checked to update will cause it to be come re-checked
2036 // as appropriate.
2037
2038 updateWrapper(otherNode, otherProps);
2039 }
2040 }
2041} // In Chrome, assigning defaultValue to certain input types triggers input validation.
2042// For number inputs, the display value loses trailing decimal points. For email inputs,
2043// Chrome raises "The specified value <x> is not a valid email address".
2044//
2045// Here we check to see if the defaultValue has actually changed, avoiding these problems
2046// when the user is inputting text
2047//
2048// https://github.com/facebook/react/issues/7253
2049
2050
2051function setDefaultValue(node, type, value) {
2052 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
2053 type !== 'number' || node.ownerDocument.activeElement !== node) {
2054 if (value == null) {
2055 node.defaultValue = toString(node._wrapperState.initialValue);
2056 } else if (node.defaultValue !== toString(value)) {
2057 node.defaultValue = toString(value);
2058 }
2059 }
2060}
2061
2062var didWarnSelectedSetOnOption = false;
2063var didWarnInvalidChild = false;
2064
2065function flattenChildren(children) {
2066 var content = ''; // Flatten children. We'll warn if they are invalid
2067 // during validateProps() which runs for hydration too.
2068 // Note that this would throw on non-element objects.
2069 // Elements are stringified (which is normally irrelevant
2070 // but matters for <fbt>).
2071
2072 React.Children.forEach(children, function (child) {
2073 if (child == null) {
2074 return;
2075 }
2076
2077 content += child; // Note: we don't warn about invalid children here.
2078 // Instead, this is done separately below so that
2079 // it happens during the hydration codepath too.
2080 });
2081 return content;
2082}
2083/**
2084 * Implements an <option> host component that warns when `selected` is set.
2085 */
2086
2087
2088function validateProps(element, props) {
2089 {
2090 // This mirrors the codepath above, but runs for hydration too.
2091 // Warn about invalid children here so that client and hydration are consistent.
2092 // TODO: this seems like it could cause a DEV-only throw for hydration
2093 // if children contains a non-element object. We should try to avoid that.
2094 if (typeof props.children === 'object' && props.children !== null) {
2095 React.Children.forEach(props.children, function (child) {
2096 if (child == null) {
2097 return;
2098 }
2099
2100 if (typeof child === 'string' || typeof child === 'number') {
2101 return;
2102 }
2103
2104 if (typeof child.type !== 'string') {
2105 return;
2106 }
2107
2108 if (!didWarnInvalidChild) {
2109 didWarnInvalidChild = true;
2110
2111 error('Only strings and numbers are supported as <option> children.');
2112 }
2113 });
2114 } // TODO: Remove support for `selected` in <option>.
2115
2116
2117 if (props.selected != null && !didWarnSelectedSetOnOption) {
2118 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
2119
2120 didWarnSelectedSetOnOption = true;
2121 }
2122 }
2123}
2124function postMountWrapper$1(element, props) {
2125 // value="" should make a value attribute (#6219)
2126 if (props.value != null) {
2127 element.setAttribute('value', toString(getToStringValue(props.value)));
2128 }
2129}
2130function getHostProps$1(element, props) {
2131 var hostProps = _assign({
2132 children: undefined
2133 }, props);
2134
2135 var content = flattenChildren(props.children);
2136
2137 if (content) {
2138 hostProps.children = content;
2139 }
2140
2141 return hostProps;
2142}
2143
2144var didWarnValueDefaultValue$1;
2145
2146{
2147 didWarnValueDefaultValue$1 = false;
2148}
2149
2150function getDeclarationErrorAddendum() {
2151 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
2152
2153 if (ownerName) {
2154 return '\n\nCheck the render method of `' + ownerName + '`.';
2155 }
2156
2157 return '';
2158}
2159
2160var valuePropNames = ['value', 'defaultValue'];
2161/**
2162 * Validation function for `value` and `defaultValue`.
2163 */
2164
2165function checkSelectPropTypes(props) {
2166 {
2167 ReactControlledValuePropTypes.checkPropTypes('select', props);
2168
2169 for (var i = 0; i < valuePropNames.length; i++) {
2170 var propName = valuePropNames[i];
2171
2172 if (props[propName] == null) {
2173 continue;
2174 }
2175
2176 var isArray = Array.isArray(props[propName]);
2177
2178 if (props.multiple && !isArray) {
2179 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
2180 } else if (!props.multiple && isArray) {
2181 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
2182 }
2183 }
2184 }
2185}
2186
2187function updateOptions(node, multiple, propValue, setDefaultSelected) {
2188 var options = node.options;
2189
2190 if (multiple) {
2191 var selectedValues = propValue;
2192 var selectedValue = {};
2193
2194 for (var i = 0; i < selectedValues.length; i++) {
2195 // Prefix to avoid chaos with special keys.
2196 selectedValue['$' + selectedValues[i]] = true;
2197 }
2198
2199 for (var _i = 0; _i < options.length; _i++) {
2200 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
2201
2202 if (options[_i].selected !== selected) {
2203 options[_i].selected = selected;
2204 }
2205
2206 if (selected && setDefaultSelected) {
2207 options[_i].defaultSelected = true;
2208 }
2209 }
2210 } else {
2211 // Do not set `select.value` as exact behavior isn't consistent across all
2212 // browsers for all cases.
2213 var _selectedValue = toString(getToStringValue(propValue));
2214
2215 var defaultSelected = null;
2216
2217 for (var _i2 = 0; _i2 < options.length; _i2++) {
2218 if (options[_i2].value === _selectedValue) {
2219 options[_i2].selected = true;
2220
2221 if (setDefaultSelected) {
2222 options[_i2].defaultSelected = true;
2223 }
2224
2225 return;
2226 }
2227
2228 if (defaultSelected === null && !options[_i2].disabled) {
2229 defaultSelected = options[_i2];
2230 }
2231 }
2232
2233 if (defaultSelected !== null) {
2234 defaultSelected.selected = true;
2235 }
2236 }
2237}
2238/**
2239 * Implements a <select> host component that allows optionally setting the
2240 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
2241 * stringable. If `multiple` is true, the prop must be an array of stringables.
2242 *
2243 * If `value` is not supplied (or null/undefined), user actions that change the
2244 * selected option will trigger updates to the rendered options.
2245 *
2246 * If it is supplied (and not null/undefined), the rendered options will not
2247 * update in response to user actions. Instead, the `value` prop must change in
2248 * order for the rendered options to update.
2249 *
2250 * If `defaultValue` is provided, any options with the supplied values will be
2251 * selected.
2252 */
2253
2254
2255function getHostProps$2(element, props) {
2256 return _assign({}, props, {
2257 value: undefined
2258 });
2259}
2260function initWrapperState$1(element, props) {
2261 var node = element;
2262
2263 {
2264 checkSelectPropTypes(props);
2265 }
2266
2267 node._wrapperState = {
2268 wasMultiple: !!props.multiple
2269 };
2270
2271 {
2272 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
2273 error('Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components');
2274
2275 didWarnValueDefaultValue$1 = true;
2276 }
2277 }
2278}
2279function postMountWrapper$2(element, props) {
2280 var node = element;
2281 node.multiple = !!props.multiple;
2282 var value = props.value;
2283
2284 if (value != null) {
2285 updateOptions(node, !!props.multiple, value, false);
2286 } else if (props.defaultValue != null) {
2287 updateOptions(node, !!props.multiple, props.defaultValue, true);
2288 }
2289}
2290function postUpdateWrapper(element, props) {
2291 var node = element;
2292 var wasMultiple = node._wrapperState.wasMultiple;
2293 node._wrapperState.wasMultiple = !!props.multiple;
2294 var value = props.value;
2295
2296 if (value != null) {
2297 updateOptions(node, !!props.multiple, value, false);
2298 } else if (wasMultiple !== !!props.multiple) {
2299 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
2300 if (props.defaultValue != null) {
2301 updateOptions(node, !!props.multiple, props.defaultValue, true);
2302 } else {
2303 // Revert the select back to its default unselected state.
2304 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
2305 }
2306 }
2307}
2308function restoreControlledState$1(element, props) {
2309 var node = element;
2310 var value = props.value;
2311
2312 if (value != null) {
2313 updateOptions(node, !!props.multiple, value, false);
2314 }
2315}
2316
2317var didWarnValDefaultVal = false;
2318
2319/**
2320 * Implements a <textarea> host component that allows setting `value`, and
2321 * `defaultValue`. This differs from the traditional DOM API because value is
2322 * usually set as PCDATA children.
2323 *
2324 * If `value` is not supplied (or null/undefined), user actions that affect the
2325 * value will trigger updates to the element.
2326 *
2327 * If `value` is supplied (and not null/undefined), the rendered element will
2328 * not trigger updates to the element. Instead, the `value` prop must change in
2329 * order for the rendered element to be updated.
2330 *
2331 * The rendered element will be initialized with an empty value, the prop
2332 * `defaultValue` if specified, or the children content (deprecated).
2333 */
2334function getHostProps$3(element, props) {
2335 var node = element;
2336
2337 if (!(props.dangerouslySetInnerHTML == null)) {
2338 {
2339 throw Error( "`dangerouslySetInnerHTML` does not make sense on <textarea>." );
2340 }
2341 } // Always set children to the same thing. In IE9, the selection range will
2342 // get reset if `textContent` is mutated. We could add a check in setTextContent
2343 // to only set the value if/when the value differs from the node value (which would
2344 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
2345 // solution. The value can be a boolean or object so that's why it's forced
2346 // to be a string.
2347
2348
2349 var hostProps = _assign({}, props, {
2350 value: undefined,
2351 defaultValue: undefined,
2352 children: toString(node._wrapperState.initialValue)
2353 });
2354
2355 return hostProps;
2356}
2357function initWrapperState$2(element, props) {
2358 var node = element;
2359
2360 {
2361 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
2362
2363 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
2364 error('%s contains a textarea with both value and defaultValue props. ' + 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
2365
2366 didWarnValDefaultVal = true;
2367 }
2368 }
2369
2370 var initialValue = props.value; // Only bother fetching default value if we're going to use it
2371
2372 if (initialValue == null) {
2373 var children = props.children,
2374 defaultValue = props.defaultValue;
2375
2376 if (children != null) {
2377 {
2378 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
2379 }
2380
2381 {
2382 if (!(defaultValue == null)) {
2383 {
2384 throw Error( "If you supply `defaultValue` on a <textarea>, do not pass children." );
2385 }
2386 }
2387
2388 if (Array.isArray(children)) {
2389 if (!(children.length <= 1)) {
2390 {
2391 throw Error( "<textarea> can only have at most one child." );
2392 }
2393 }
2394
2395 children = children[0];
2396 }
2397
2398 defaultValue = children;
2399 }
2400 }
2401
2402 if (defaultValue == null) {
2403 defaultValue = '';
2404 }
2405
2406 initialValue = defaultValue;
2407 }
2408
2409 node._wrapperState = {
2410 initialValue: getToStringValue(initialValue)
2411 };
2412}
2413function updateWrapper$1(element, props) {
2414 var node = element;
2415 var value = getToStringValue(props.value);
2416 var defaultValue = getToStringValue(props.defaultValue);
2417
2418 if (value != null) {
2419 // Cast `value` to a string to ensure the value is set correctly. While
2420 // browsers typically do this as necessary, jsdom doesn't.
2421 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
2422
2423 if (newValue !== node.value) {
2424 node.value = newValue;
2425 }
2426
2427 if (props.defaultValue == null && node.defaultValue !== newValue) {
2428 node.defaultValue = newValue;
2429 }
2430 }
2431
2432 if (defaultValue != null) {
2433 node.defaultValue = toString(defaultValue);
2434 }
2435}
2436function postMountWrapper$3(element, props) {
2437 var node = element; // This is in postMount because we need access to the DOM node, which is not
2438 // available until after the component has mounted.
2439
2440 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
2441 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
2442 // will populate textContent as well.
2443 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
2444
2445 if (textContent === node._wrapperState.initialValue) {
2446 if (textContent !== '' && textContent !== null) {
2447 node.value = textContent;
2448 }
2449 }
2450}
2451function restoreControlledState$2(element, props) {
2452 // DOM component is still mounted; update
2453 updateWrapper$1(element, props);
2454}
2455
2456var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2457var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2458var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
2459var Namespaces = {
2460 html: HTML_NAMESPACE,
2461 mathml: MATH_NAMESPACE,
2462 svg: SVG_NAMESPACE
2463}; // Assumes there is no parent namespace.
2464
2465function getIntrinsicNamespace(type) {
2466 switch (type) {
2467 case 'svg':
2468 return SVG_NAMESPACE;
2469
2470 case 'math':
2471 return MATH_NAMESPACE;
2472
2473 default:
2474 return HTML_NAMESPACE;
2475 }
2476}
2477function getChildNamespace(parentNamespace, type) {
2478 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
2479 // No (or default) parent namespace: potential entry point.
2480 return getIntrinsicNamespace(type);
2481 }
2482
2483 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
2484 // We're leaving SVG.
2485 return HTML_NAMESPACE;
2486 } // By default, pass namespace below.
2487
2488
2489 return parentNamespace;
2490}
2491
2492/* globals MSApp */
2493
2494/**
2495 * Create a function which has 'unsafe' privileges (required by windows8 apps)
2496 */
2497var createMicrosoftUnsafeLocalFunction = function (func) {
2498 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
2499 return function (arg0, arg1, arg2, arg3) {
2500 MSApp.execUnsafeLocalFunction(function () {
2501 return func(arg0, arg1, arg2, arg3);
2502 });
2503 };
2504 } else {
2505 return func;
2506 }
2507};
2508
2509var reusableSVGContainer;
2510/**
2511 * Set the innerHTML property of a node
2512 *
2513 * @param {DOMElement} node
2514 * @param {string} html
2515 * @internal
2516 */
2517
2518var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
2519 if (node.namespaceURI === Namespaces.svg) {
2520
2521 if (!('innerHTML' in node)) {
2522 // IE does not have innerHTML for SVG nodes, so instead we inject the
2523 // new markup in a temp node and then move the child nodes across into
2524 // the target node
2525 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
2526 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
2527 var svgNode = reusableSVGContainer.firstChild;
2528
2529 while (node.firstChild) {
2530 node.removeChild(node.firstChild);
2531 }
2532
2533 while (svgNode.firstChild) {
2534 node.appendChild(svgNode.firstChild);
2535 }
2536
2537 return;
2538 }
2539 }
2540
2541 node.innerHTML = html;
2542});
2543
2544/**
2545 * HTML nodeType values that represent the type of the node
2546 */
2547var ELEMENT_NODE = 1;
2548var TEXT_NODE = 3;
2549var COMMENT_NODE = 8;
2550var DOCUMENT_NODE = 9;
2551var DOCUMENT_FRAGMENT_NODE = 11;
2552
2553/**
2554 * Set the textContent property of a node. For text updates, it's faster
2555 * to set the `nodeValue` of the Text node directly instead of using
2556 * `.textContent` which will remove the existing node and create a new one.
2557 *
2558 * @param {DOMElement} node
2559 * @param {string} text
2560 * @internal
2561 */
2562
2563var setTextContent = function (node, text) {
2564 if (text) {
2565 var firstChild = node.firstChild;
2566
2567 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
2568 firstChild.nodeValue = text;
2569 return;
2570 }
2571 }
2572
2573 node.textContent = text;
2574};
2575
2576// Do not use the below two methods directly!
2577// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
2578// (It is the only module that is allowed to access these methods.)
2579function unsafeCastStringToDOMTopLevelType(topLevelType) {
2580 return topLevelType;
2581}
2582function unsafeCastDOMTopLevelTypeToString(topLevelType) {
2583 return topLevelType;
2584}
2585
2586/**
2587 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
2588 *
2589 * @param {string} styleProp
2590 * @param {string} eventName
2591 * @returns {object}
2592 */
2593
2594function makePrefixMap(styleProp, eventName) {
2595 var prefixes = {};
2596 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
2597 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
2598 prefixes['Moz' + styleProp] = 'moz' + eventName;
2599 return prefixes;
2600}
2601/**
2602 * A list of event names to a configurable list of vendor prefixes.
2603 */
2604
2605
2606var vendorPrefixes = {
2607 animationend: makePrefixMap('Animation', 'AnimationEnd'),
2608 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
2609 animationstart: makePrefixMap('Animation', 'AnimationStart'),
2610 transitionend: makePrefixMap('Transition', 'TransitionEnd')
2611};
2612/**
2613 * Event names that have already been detected and prefixed (if applicable).
2614 */
2615
2616var prefixedEventNames = {};
2617/**
2618 * Element to check for prefixes on.
2619 */
2620
2621var style = {};
2622/**
2623 * Bootstrap if a DOM exists.
2624 */
2625
2626if (canUseDOM) {
2627 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
2628 // the un-prefixed "animation" and "transition" properties are defined on the
2629 // style object but the events that fire will still be prefixed, so we need
2630 // to check if the un-prefixed events are usable, and if not remove them from the map.
2631
2632 if (!('AnimationEvent' in window)) {
2633 delete vendorPrefixes.animationend.animation;
2634 delete vendorPrefixes.animationiteration.animation;
2635 delete vendorPrefixes.animationstart.animation;
2636 } // Same as above
2637
2638
2639 if (!('TransitionEvent' in window)) {
2640 delete vendorPrefixes.transitionend.transition;
2641 }
2642}
2643/**
2644 * Attempts to determine the correct vendor prefixed event name.
2645 *
2646 * @param {string} eventName
2647 * @returns {string}
2648 */
2649
2650
2651function getVendorPrefixedEventName(eventName) {
2652 if (prefixedEventNames[eventName]) {
2653 return prefixedEventNames[eventName];
2654 } else if (!vendorPrefixes[eventName]) {
2655 return eventName;
2656 }
2657
2658 var prefixMap = vendorPrefixes[eventName];
2659
2660 for (var styleProp in prefixMap) {
2661 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
2662 return prefixedEventNames[eventName] = prefixMap[styleProp];
2663 }
2664 }
2665
2666 return eventName;
2667}
2668
2669/**
2670 * To identify top level events in ReactDOM, we use constants defined by this
2671 * module. This is the only module that uses the unsafe* methods to express
2672 * that the constants actually correspond to the browser event names. This lets
2673 * us save some bundle size by avoiding a top level type -> event name map.
2674 * The rest of ReactDOM code should import top level types from this file.
2675 */
2676
2677var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
2678var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
2679var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
2680var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
2681var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
2682var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
2683var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
2684var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
2685var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
2686var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
2687var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
2688var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
2689var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
2690var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
2691var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
2692var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
2693var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
2694var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
2695var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
2696var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
2697var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
2698var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
2699var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
2700var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
2701var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
2702var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
2703var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
2704var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
2705var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
2706var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
2707var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
2708var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
2709var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
2710var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
2711var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
2712var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
2713var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
2714var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
2715var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
2716var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
2717var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
2718var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
2719var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
2720var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
2721var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
2722var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
2723var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
2724var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
2725var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
2726var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
2727var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
2728var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
2729var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
2730var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
2731var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
2732var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
2733var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
2734var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
2735var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
2736var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
2737var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
2738var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
2739var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
2740var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
2741var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
2742var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
2743var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
2744var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
2745var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
2746var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
2747var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
2748var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
2749var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
2750var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
2751var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
2752var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
2753var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
2754var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
2755var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
2756var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel'); // List of events that need to be individually attached to media elements.
2757// Note that events in this list will *not* be listened to at the top level
2758// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
2759
2760var mediaEventTypes = [TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_VOLUME_CHANGE, TOP_WAITING];
2761function getRawEventName(topLevelType) {
2762 return unsafeCastDOMTopLevelTypeToString(topLevelType);
2763}
2764
2765var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; // prettier-ignore
2766
2767var elementListenerMap = new PossiblyWeakMap();
2768function getListenerMapForElement(element) {
2769 var listenerMap = elementListenerMap.get(element);
2770
2771 if (listenerMap === undefined) {
2772 listenerMap = new Map();
2773 elementListenerMap.set(element, listenerMap);
2774 }
2775
2776 return listenerMap;
2777}
2778
2779/**
2780 * `ReactInstanceMap` maintains a mapping from a public facing stateful
2781 * instance (key) and the internal representation (value). This allows public
2782 * methods to accept the user facing instance as an argument and map them back
2783 * to internal methods.
2784 *
2785 * Note that this module is currently shared and assumed to be stateless.
2786 * If this becomes an actual Map, that will break.
2787 */
2788function get(key) {
2789 return key._reactInternalFiber;
2790}
2791function has(key) {
2792 return key._reactInternalFiber !== undefined;
2793}
2794function set(key, value) {
2795 key._reactInternalFiber = value;
2796}
2797
2798// Don't change these two values. They're used by React Dev Tools.
2799var NoEffect =
2800/* */
28010;
2802var PerformedWork =
2803/* */
28041; // You can change the rest (and add more).
2805
2806var Placement =
2807/* */
28082;
2809var Update =
2810/* */
28114;
2812var PlacementAndUpdate =
2813/* */
28146;
2815var Deletion =
2816/* */
28178;
2818var ContentReset =
2819/* */
282016;
2821var Callback =
2822/* */
282332;
2824var DidCapture =
2825/* */
282664;
2827var Ref =
2828/* */
2829128;
2830var Snapshot =
2831/* */
2832256;
2833var Passive =
2834/* */
2835512;
2836var Hydrating =
2837/* */
28381024;
2839var HydratingAndUpdate =
2840/* */
28411028; // Passive & Update & Callback & Ref & Snapshot
2842
2843var LifecycleEffectMask =
2844/* */
2845932; // Union of all host effects
2846
2847var HostEffectMask =
2848/* */
28492047;
2850var Incomplete =
2851/* */
28522048;
2853var ShouldCapture =
2854/* */
28554096;
2856
2857var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
2858function getNearestMountedFiber(fiber) {
2859 var node = fiber;
2860 var nearestMounted = fiber;
2861
2862 if (!fiber.alternate) {
2863 // If there is no alternate, this might be a new tree that isn't inserted
2864 // yet. If it is, then it will have a pending insertion effect on it.
2865 var nextNode = node;
2866
2867 do {
2868 node = nextNode;
2869
2870 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
2871 // This is an insertion or in-progress hydration. The nearest possible
2872 // mounted fiber is the parent but we need to continue to figure out
2873 // if that one is still mounted.
2874 nearestMounted = node.return;
2875 }
2876
2877 nextNode = node.return;
2878 } while (nextNode);
2879 } else {
2880 while (node.return) {
2881 node = node.return;
2882 }
2883 }
2884
2885 if (node.tag === HostRoot) {
2886 // TODO: Check if this was a nested HostRoot when used with
2887 // renderContainerIntoSubtree.
2888 return nearestMounted;
2889 } // If we didn't hit the root, that means that we're in an disconnected tree
2890 // that has been unmounted.
2891
2892
2893 return null;
2894}
2895function getSuspenseInstanceFromFiber(fiber) {
2896 if (fiber.tag === SuspenseComponent) {
2897 var suspenseState = fiber.memoizedState;
2898
2899 if (suspenseState === null) {
2900 var current = fiber.alternate;
2901
2902 if (current !== null) {
2903 suspenseState = current.memoizedState;
2904 }
2905 }
2906
2907 if (suspenseState !== null) {
2908 return suspenseState.dehydrated;
2909 }
2910 }
2911
2912 return null;
2913}
2914function getContainerFromFiber(fiber) {
2915 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
2916}
2917function isFiberMounted(fiber) {
2918 return getNearestMountedFiber(fiber) === fiber;
2919}
2920function isMounted(component) {
2921 {
2922 var owner = ReactCurrentOwner.current;
2923
2924 if (owner !== null && owner.tag === ClassComponent) {
2925 var ownerFiber = owner;
2926 var instance = ownerFiber.stateNode;
2927
2928 if (!instance._warnedAboutRefsInRender) {
2929 error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component');
2930 }
2931
2932 instance._warnedAboutRefsInRender = true;
2933 }
2934 }
2935
2936 var fiber = get(component);
2937
2938 if (!fiber) {
2939 return false;
2940 }
2941
2942 return getNearestMountedFiber(fiber) === fiber;
2943}
2944
2945function assertIsMounted(fiber) {
2946 if (!(getNearestMountedFiber(fiber) === fiber)) {
2947 {
2948 throw Error( "Unable to find node on an unmounted component." );
2949 }
2950 }
2951}
2952
2953function findCurrentFiberUsingSlowPath(fiber) {
2954 var alternate = fiber.alternate;
2955
2956 if (!alternate) {
2957 // If there is no alternate, then we only need to check if it is mounted.
2958 var nearestMounted = getNearestMountedFiber(fiber);
2959
2960 if (!(nearestMounted !== null)) {
2961 {
2962 throw Error( "Unable to find node on an unmounted component." );
2963 }
2964 }
2965
2966 if (nearestMounted !== fiber) {
2967 return null;
2968 }
2969
2970 return fiber;
2971 } // If we have two possible branches, we'll walk backwards up to the root
2972 // to see what path the root points to. On the way we may hit one of the
2973 // special cases and we'll deal with them.
2974
2975
2976 var a = fiber;
2977 var b = alternate;
2978
2979 while (true) {
2980 var parentA = a.return;
2981
2982 if (parentA === null) {
2983 // We're at the root.
2984 break;
2985 }
2986
2987 var parentB = parentA.alternate;
2988
2989 if (parentB === null) {
2990 // There is no alternate. This is an unusual case. Currently, it only
2991 // happens when a Suspense component is hidden. An extra fragment fiber
2992 // is inserted in between the Suspense fiber and its children. Skip
2993 // over this extra fragment fiber and proceed to the next parent.
2994 var nextParent = parentA.return;
2995
2996 if (nextParent !== null) {
2997 a = b = nextParent;
2998 continue;
2999 } // If there's no parent, we're at the root.
3000
3001
3002 break;
3003 } // If both copies of the parent fiber point to the same child, we can
3004 // assume that the child is current. This happens when we bailout on low
3005 // priority: the bailed out fiber's child reuses the current child.
3006
3007
3008 if (parentA.child === parentB.child) {
3009 var child = parentA.child;
3010
3011 while (child) {
3012 if (child === a) {
3013 // We've determined that A is the current branch.
3014 assertIsMounted(parentA);
3015 return fiber;
3016 }
3017
3018 if (child === b) {
3019 // We've determined that B is the current branch.
3020 assertIsMounted(parentA);
3021 return alternate;
3022 }
3023
3024 child = child.sibling;
3025 } // We should never have an alternate for any mounting node. So the only
3026 // way this could possibly happen is if this was unmounted, if at all.
3027
3028
3029 {
3030 {
3031 throw Error( "Unable to find node on an unmounted component." );
3032 }
3033 }
3034 }
3035
3036 if (a.return !== b.return) {
3037 // The return pointer of A and the return pointer of B point to different
3038 // fibers. We assume that return pointers never criss-cross, so A must
3039 // belong to the child set of A.return, and B must belong to the child
3040 // set of B.return.
3041 a = parentA;
3042 b = parentB;
3043 } else {
3044 // The return pointers point to the same fiber. We'll have to use the
3045 // default, slow path: scan the child sets of each parent alternate to see
3046 // which child belongs to which set.
3047 //
3048 // Search parent A's child set
3049 var didFindChild = false;
3050 var _child = parentA.child;
3051
3052 while (_child) {
3053 if (_child === a) {
3054 didFindChild = true;
3055 a = parentA;
3056 b = parentB;
3057 break;
3058 }
3059
3060 if (_child === b) {
3061 didFindChild = true;
3062 b = parentA;
3063 a = parentB;
3064 break;
3065 }
3066
3067 _child = _child.sibling;
3068 }
3069
3070 if (!didFindChild) {
3071 // Search parent B's child set
3072 _child = parentB.child;
3073
3074 while (_child) {
3075 if (_child === a) {
3076 didFindChild = true;
3077 a = parentB;
3078 b = parentA;
3079 break;
3080 }
3081
3082 if (_child === b) {
3083 didFindChild = true;
3084 b = parentB;
3085 a = parentA;
3086 break;
3087 }
3088
3089 _child = _child.sibling;
3090 }
3091
3092 if (!didFindChild) {
3093 {
3094 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." );
3095 }
3096 }
3097 }
3098 }
3099
3100 if (!(a.alternate === b)) {
3101 {
3102 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
3103 }
3104 }
3105 } // If the root is not a host container, we're in a disconnected tree. I.e.
3106 // unmounted.
3107
3108
3109 if (!(a.tag === HostRoot)) {
3110 {
3111 throw Error( "Unable to find node on an unmounted component." );
3112 }
3113 }
3114
3115 if (a.stateNode.current === a) {
3116 // We've determined that A is the current branch.
3117 return fiber;
3118 } // Otherwise B has to be current branch.
3119
3120
3121 return alternate;
3122}
3123function findCurrentHostFiber(parent) {
3124 var currentParent = findCurrentFiberUsingSlowPath(parent);
3125
3126 if (!currentParent) {
3127 return null;
3128 } // Next we'll drill down this component to find the first HostComponent/Text.
3129
3130
3131 var node = currentParent;
3132
3133 while (true) {
3134 if (node.tag === HostComponent || node.tag === HostText) {
3135 return node;
3136 } else if (node.child) {
3137 node.child.return = node;
3138 node = node.child;
3139 continue;
3140 }
3141
3142 if (node === currentParent) {
3143 return null;
3144 }
3145
3146 while (!node.sibling) {
3147 if (!node.return || node.return === currentParent) {
3148 return null;
3149 }
3150
3151 node = node.return;
3152 }
3153
3154 node.sibling.return = node.return;
3155 node = node.sibling;
3156 } // Flow needs the return null here, but ESLint complains about it.
3157 // eslint-disable-next-line no-unreachable
3158
3159
3160 return null;
3161}
3162function findCurrentHostFiberWithNoPortals(parent) {
3163 var currentParent = findCurrentFiberUsingSlowPath(parent);
3164
3165 if (!currentParent) {
3166 return null;
3167 } // Next we'll drill down this component to find the first HostComponent/Text.
3168
3169
3170 var node = currentParent;
3171
3172 while (true) {
3173 if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI ) {
3174 return node;
3175 } else if (node.child && node.tag !== HostPortal) {
3176 node.child.return = node;
3177 node = node.child;
3178 continue;
3179 }
3180
3181 if (node === currentParent) {
3182 return null;
3183 }
3184
3185 while (!node.sibling) {
3186 if (!node.return || node.return === currentParent) {
3187 return null;
3188 }
3189
3190 node = node.return;
3191 }
3192
3193 node.sibling.return = node.return;
3194 node = node.sibling;
3195 } // Flow needs the return null here, but ESLint complains about it.
3196 // eslint-disable-next-line no-unreachable
3197
3198
3199 return null;
3200}
3201
3202/**
3203 * Accumulates items that must not be null or undefined into the first one. This
3204 * is used to conserve memory by avoiding array allocations, and thus sacrifices
3205 * API cleanness. Since `current` can be null before being passed in and not
3206 * null after this function, make sure to assign it back to `current`:
3207 *
3208 * `a = accumulateInto(a, b);`
3209 *
3210 * This API should be sparingly used. Try `accumulate` for something cleaner.
3211 *
3212 * @return {*|array<*>} An accumulation of items.
3213 */
3214
3215function accumulateInto(current, next) {
3216 if (!(next != null)) {
3217 {
3218 throw Error( "accumulateInto(...): Accumulated items must not be null or undefined." );
3219 }
3220 }
3221
3222 if (current == null) {
3223 return next;
3224 } // Both are not empty. Warning: Never call x.concat(y) when you are not
3225 // certain that x is an Array (x could be a string with concat method).
3226
3227
3228 if (Array.isArray(current)) {
3229 if (Array.isArray(next)) {
3230 current.push.apply(current, next);
3231 return current;
3232 }
3233
3234 current.push(next);
3235 return current;
3236 }
3237
3238 if (Array.isArray(next)) {
3239 // A bit too dangerous to mutate `next`.
3240 return [current].concat(next);
3241 }
3242
3243 return [current, next];
3244}
3245
3246/**
3247 * @param {array} arr an "accumulation" of items which is either an Array or
3248 * a single item. Useful when paired with the `accumulate` module. This is a
3249 * simple utility that allows us to reason about a collection of items, but
3250 * handling the case when there is exactly one item (and we do not need to
3251 * allocate an array).
3252 * @param {function} cb Callback invoked with each element or a collection.
3253 * @param {?} [scope] Scope used as `this` in a callback.
3254 */
3255function forEachAccumulated(arr, cb, scope) {
3256 if (Array.isArray(arr)) {
3257 arr.forEach(cb, scope);
3258 } else if (arr) {
3259 cb.call(scope, arr);
3260 }
3261}
3262
3263/**
3264 * Internal queue of events that have accumulated their dispatches and are
3265 * waiting to have their dispatches executed.
3266 */
3267
3268var eventQueue = null;
3269/**
3270 * Dispatches an event and releases it back into the pool, unless persistent.
3271 *
3272 * @param {?object} event Synthetic event to be dispatched.
3273 * @private
3274 */
3275
3276var executeDispatchesAndRelease = function (event) {
3277 if (event) {
3278 executeDispatchesInOrder(event);
3279
3280 if (!event.isPersistent()) {
3281 event.constructor.release(event);
3282 }
3283 }
3284};
3285
3286var executeDispatchesAndReleaseTopLevel = function (e) {
3287 return executeDispatchesAndRelease(e);
3288};
3289
3290function runEventsInBatch(events) {
3291 if (events !== null) {
3292 eventQueue = accumulateInto(eventQueue, events);
3293 } // Set `eventQueue` to null before processing it so that we can tell if more
3294 // events get enqueued while processing.
3295
3296
3297 var processingEventQueue = eventQueue;
3298 eventQueue = null;
3299
3300 if (!processingEventQueue) {
3301 return;
3302 }
3303
3304 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
3305
3306 if (!!eventQueue) {
3307 {
3308 throw Error( "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." );
3309 }
3310 } // This would be a good time to rethrow if any of the event handlers threw.
3311
3312
3313 rethrowCaughtError();
3314}
3315
3316/**
3317 * Gets the target node from a native browser event by accounting for
3318 * inconsistencies in browser DOM APIs.
3319 *
3320 * @param {object} nativeEvent Native browser event.
3321 * @return {DOMEventTarget} Target node.
3322 */
3323
3324function getEventTarget(nativeEvent) {
3325 // Fallback to nativeEvent.srcElement for IE9
3326 // https://github.com/facebook/react/issues/12506
3327 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
3328
3329 if (target.correspondingUseElement) {
3330 target = target.correspondingUseElement;
3331 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
3332 // @see http://www.quirksmode.org/js/events_properties.html
3333
3334
3335 return target.nodeType === TEXT_NODE ? target.parentNode : target;
3336}
3337
3338/**
3339 * Checks if an event is supported in the current execution environment.
3340 *
3341 * NOTE: This will not work correctly for non-generic events such as `change`,
3342 * `reset`, `load`, `error`, and `select`.
3343 *
3344 * Borrows from Modernizr.
3345 *
3346 * @param {string} eventNameSuffix Event name, e.g. "click".
3347 * @return {boolean} True if the event is supported.
3348 * @internal
3349 * @license Modernizr 3.0.0pre (Custom Build) | MIT
3350 */
3351
3352function isEventSupported(eventNameSuffix) {
3353 if (!canUseDOM) {
3354 return false;
3355 }
3356
3357 var eventName = 'on' + eventNameSuffix;
3358 var isSupported = eventName in document;
3359
3360 if (!isSupported) {
3361 var element = document.createElement('div');
3362 element.setAttribute(eventName, 'return;');
3363 isSupported = typeof element[eventName] === 'function';
3364 }
3365
3366 return isSupported;
3367}
3368
3369/**
3370 * Summary of `DOMEventPluginSystem` event handling:
3371 *
3372 * - Top-level delegation is used to trap most native browser events. This
3373 * may only occur in the main thread and is the responsibility of
3374 * ReactDOMEventListener, which is injected and can therefore support
3375 * pluggable event sources. This is the only work that occurs in the main
3376 * thread.
3377 *
3378 * - We normalize and de-duplicate events to account for browser quirks. This
3379 * may be done in the worker thread.
3380 *
3381 * - Forward these native events (with the associated top-level type used to
3382 * trap it) to `EventPluginRegistry`, which in turn will ask plugins if they want
3383 * to extract any synthetic events.
3384 *
3385 * - The `EventPluginRegistry` will then process each event by annotating them with
3386 * "dispatches", a sequence of listeners and IDs that care about that event.
3387 *
3388 * - The `EventPluginRegistry` then dispatches the events.
3389 *
3390 * Overview of React and the event system:
3391 *
3392 * +------------+ .
3393 * | DOM | .
3394 * +------------+ .
3395 * | .
3396 * v .
3397 * +------------+ .
3398 * | ReactEvent | .
3399 * | Listener | .
3400 * +------------+ . +-----------+
3401 * | . +--------+|SimpleEvent|
3402 * | . | |Plugin |
3403 * +-----|------+ . v +-----------+
3404 * | | | . +--------------+ +------------+
3405 * | +-----------.--->|PluginRegistry| | Event |
3406 * | | . | | +-----------+ | Propagators|
3407 * | ReactEvent | . | | |TapEvent | |------------|
3408 * | Emitter | . | |<---+|Plugin | |other plugin|
3409 * | | . | | +-----------+ | utilities |
3410 * | +-----------.--->| | +------------+
3411 * | | | . +--------------+
3412 * +-----|------+ . ^ +-----------+
3413 * | . | |Enter/Leave|
3414 * + . +-------+|Plugin |
3415 * +-------------+ . +-----------+
3416 * | application | .
3417 * |-------------| .
3418 * | | .
3419 * | | .
3420 * +-------------+ .
3421 * .
3422 * React Core . General Purpose Event Plugin System
3423 */
3424
3425var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
3426var callbackBookkeepingPool = [];
3427
3428function releaseTopLevelCallbackBookKeeping(instance) {
3429 instance.topLevelType = null;
3430 instance.nativeEvent = null;
3431 instance.targetInst = null;
3432 instance.ancestors.length = 0;
3433
3434 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
3435 callbackBookkeepingPool.push(instance);
3436 }
3437} // Used to store ancestor hierarchy in top level callback
3438
3439
3440function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags) {
3441 if (callbackBookkeepingPool.length) {
3442 var instance = callbackBookkeepingPool.pop();
3443 instance.topLevelType = topLevelType;
3444 instance.eventSystemFlags = eventSystemFlags;
3445 instance.nativeEvent = nativeEvent;
3446 instance.targetInst = targetInst;
3447 return instance;
3448 }
3449
3450 return {
3451 topLevelType: topLevelType,
3452 eventSystemFlags: eventSystemFlags,
3453 nativeEvent: nativeEvent,
3454 targetInst: targetInst,
3455 ancestors: []
3456 };
3457}
3458/**
3459 * Find the deepest React component completely containing the root of the
3460 * passed-in instance (for use when entire React trees are nested within each
3461 * other). If React trees are not nested, returns null.
3462 */
3463
3464
3465function findRootContainerNode(inst) {
3466 if (inst.tag === HostRoot) {
3467 return inst.stateNode.containerInfo;
3468 } // TODO: It may be a good idea to cache this to prevent unnecessary DOM
3469 // traversal, but caching is difficult to do correctly without using a
3470 // mutation observer to listen for all DOM changes.
3471
3472
3473 while (inst.return) {
3474 inst = inst.return;
3475 }
3476
3477 if (inst.tag !== HostRoot) {
3478 // This can happen if we're in a detached tree.
3479 return null;
3480 }
3481
3482 return inst.stateNode.containerInfo;
3483}
3484/**
3485 * Allows registered plugins an opportunity to extract events from top-level
3486 * native browser events.
3487 *
3488 * @return {*} An accumulation of synthetic events.
3489 * @internal
3490 */
3491
3492
3493function extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
3494 var events = null;
3495
3496 for (var i = 0; i < plugins.length; i++) {
3497 // Not every plugin in the ordering may be loaded at runtime.
3498 var possiblePlugin = plugins[i];
3499
3500 if (possiblePlugin) {
3501 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
3502
3503 if (extractedEvents) {
3504 events = accumulateInto(events, extractedEvents);
3505 }
3506 }
3507 }
3508
3509 return events;
3510}
3511
3512function runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
3513 var events = extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
3514 runEventsInBatch(events);
3515}
3516
3517function handleTopLevel(bookKeeping) {
3518 var targetInst = bookKeeping.targetInst; // Loop through the hierarchy, in case there's any nested components.
3519 // It's important that we build the array of ancestors before calling any
3520 // event handlers, because event handlers can modify the DOM, leading to
3521 // inconsistencies with ReactMount's node cache. See #1105.
3522
3523 var ancestor = targetInst;
3524
3525 do {
3526 if (!ancestor) {
3527 var ancestors = bookKeeping.ancestors;
3528 ancestors.push(ancestor);
3529 break;
3530 }
3531
3532 var root = findRootContainerNode(ancestor);
3533
3534 if (!root) {
3535 break;
3536 }
3537
3538 var tag = ancestor.tag;
3539
3540 if (tag === HostComponent || tag === HostText) {
3541 bookKeeping.ancestors.push(ancestor);
3542 }
3543
3544 ancestor = getClosestInstanceFromNode(root);
3545 } while (ancestor);
3546
3547 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
3548 targetInst = bookKeeping.ancestors[i];
3549 var eventTarget = getEventTarget(bookKeeping.nativeEvent);
3550 var topLevelType = bookKeeping.topLevelType;
3551 var nativeEvent = bookKeeping.nativeEvent;
3552 var eventSystemFlags = bookKeeping.eventSystemFlags; // If this is the first ancestor, we mark it on the system flags
3553
3554 if (i === 0) {
3555 eventSystemFlags |= IS_FIRST_ANCESTOR;
3556 }
3557
3558 runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, eventTarget, eventSystemFlags);
3559 }
3560}
3561
3562function dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst) {
3563 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags);
3564
3565 try {
3566 // Event queue being processed in the same cycle allows
3567 // `preventDefault`.
3568 batchedEventUpdates(handleTopLevel, bookKeeping);
3569 } finally {
3570 releaseTopLevelCallbackBookKeeping(bookKeeping);
3571 }
3572}
3573/**
3574 * We listen for bubbled touch events on the document object.
3575 *
3576 * Firefox v8.01 (and possibly others) exhibited strange behavior when
3577 * mounting `onmousemove` events at some node that was not the document
3578 * element. The symptoms were that if your mouse is not moving over something
3579 * contained within that mount point (for example on the background) the
3580 * top-level listeners for `onmousemove` won't be called. However, if you
3581 * register the `mousemove` on the document object, then it will of course
3582 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
3583 * top-level listeners to the document object only, at least for these
3584 * movement types of events and possibly all events.
3585 *
3586 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
3587 *
3588 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
3589 * they bubble to document.
3590 *
3591 * @param {string} registrationName Name of listener (e.g. `onClick`).
3592 * @param {object} mountAt Container where to mount the listener
3593 */
3594
3595function legacyListenToEvent(registrationName, mountAt) {
3596 var listenerMap = getListenerMapForElement(mountAt);
3597 var dependencies = registrationNameDependencies[registrationName];
3598
3599 for (var i = 0; i < dependencies.length; i++) {
3600 var dependency = dependencies[i];
3601 legacyListenToTopLevelEvent(dependency, mountAt, listenerMap);
3602 }
3603}
3604function legacyListenToTopLevelEvent(topLevelType, mountAt, listenerMap) {
3605 if (!listenerMap.has(topLevelType)) {
3606 switch (topLevelType) {
3607 case TOP_SCROLL:
3608 trapCapturedEvent(TOP_SCROLL, mountAt);
3609 break;
3610
3611 case TOP_FOCUS:
3612 case TOP_BLUR:
3613 trapCapturedEvent(TOP_FOCUS, mountAt);
3614 trapCapturedEvent(TOP_BLUR, mountAt); // We set the flag for a single dependency later in this function,
3615 // but this ensures we mark both as attached rather than just one.
3616
3617 listenerMap.set(TOP_BLUR, null);
3618 listenerMap.set(TOP_FOCUS, null);
3619 break;
3620
3621 case TOP_CANCEL:
3622 case TOP_CLOSE:
3623 if (isEventSupported(getRawEventName(topLevelType))) {
3624 trapCapturedEvent(topLevelType, mountAt);
3625 }
3626
3627 break;
3628
3629 case TOP_INVALID:
3630 case TOP_SUBMIT:
3631 case TOP_RESET:
3632 // We listen to them on the target DOM elements.
3633 // Some of them bubble so we don't want them to fire twice.
3634 break;
3635
3636 default:
3637 // By default, listen on the top level to all non-media events.
3638 // Media events don't bubble so adding the listener wouldn't do anything.
3639 var isMediaEvent = mediaEventTypes.indexOf(topLevelType) !== -1;
3640
3641 if (!isMediaEvent) {
3642 trapBubbledEvent(topLevelType, mountAt);
3643 }
3644
3645 break;
3646 }
3647
3648 listenerMap.set(topLevelType, null);
3649 }
3650}
3651function isListeningToAllDependencies(registrationName, mountAt) {
3652 var listenerMap = getListenerMapForElement(mountAt);
3653 var dependencies = registrationNameDependencies[registrationName];
3654
3655 for (var i = 0; i < dependencies.length; i++) {
3656 var dependency = dependencies[i];
3657
3658 if (!listenerMap.has(dependency)) {
3659 return false;
3660 }
3661 }
3662
3663 return true;
3664}
3665
3666var attemptUserBlockingHydration;
3667function setAttemptUserBlockingHydration(fn) {
3668 attemptUserBlockingHydration = fn;
3669}
3670var attemptContinuousHydration;
3671function setAttemptContinuousHydration(fn) {
3672 attemptContinuousHydration = fn;
3673}
3674var attemptHydrationAtCurrentPriority;
3675function setAttemptHydrationAtCurrentPriority(fn) {
3676 attemptHydrationAtCurrentPriority = fn;
3677} // TODO: Upgrade this definition once we're on a newer version of Flow that
3678var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
3679
3680var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
3681// if the last target was dehydrated.
3682
3683var queuedFocus = null;
3684var queuedDrag = null;
3685var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
3686
3687var queuedPointers = new Map();
3688var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
3689
3690var queuedExplicitHydrationTargets = [];
3691function hasQueuedDiscreteEvents() {
3692 return queuedDiscreteEvents.length > 0;
3693}
3694var discreteReplayableEvents = [TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_TOUCH_CANCEL, TOP_TOUCH_END, TOP_TOUCH_START, TOP_AUX_CLICK, TOP_DOUBLE_CLICK, TOP_POINTER_CANCEL, TOP_POINTER_DOWN, TOP_POINTER_UP, TOP_DRAG_END, TOP_DRAG_START, TOP_DROP, TOP_COMPOSITION_END, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_INPUT, TOP_TEXT_INPUT, TOP_CLOSE, TOP_CANCEL, TOP_COPY, TOP_CUT, TOP_PASTE, TOP_CLICK, TOP_CHANGE, TOP_CONTEXT_MENU, TOP_RESET, TOP_SUBMIT];
3695var continuousReplayableEvents = [TOP_FOCUS, TOP_BLUR, TOP_DRAG_ENTER, TOP_DRAG_LEAVE, TOP_MOUSE_OVER, TOP_MOUSE_OUT, TOP_POINTER_OVER, TOP_POINTER_OUT, TOP_GOT_POINTER_CAPTURE, TOP_LOST_POINTER_CAPTURE];
3696function isReplayableDiscreteEvent(eventType) {
3697 return discreteReplayableEvents.indexOf(eventType) > -1;
3698}
3699
3700function trapReplayableEventForDocument(topLevelType, document, listenerMap) {
3701 legacyListenToTopLevelEvent(topLevelType, document, listenerMap);
3702}
3703
3704function eagerlyTrapReplayableEvents(container, document) {
3705 var listenerMapForDoc = getListenerMapForElement(document); // Discrete
3706
3707 discreteReplayableEvents.forEach(function (topLevelType) {
3708 trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);
3709 }); // Continuous
3710
3711 continuousReplayableEvents.forEach(function (topLevelType) {
3712 trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);
3713 });
3714}
3715
3716function createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3717 return {
3718 blockedOn: blockedOn,
3719 topLevelType: topLevelType,
3720 eventSystemFlags: eventSystemFlags | IS_REPLAYED,
3721 nativeEvent: nativeEvent,
3722 container: container
3723 };
3724}
3725
3726function queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3727 var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
3728 queuedDiscreteEvents.push(queuedEvent);
3729} // Resets the replaying for this type of continuous event to no event.
3730
3731function clearIfContinuousEvent(topLevelType, nativeEvent) {
3732 switch (topLevelType) {
3733 case TOP_FOCUS:
3734 case TOP_BLUR:
3735 queuedFocus = null;
3736 break;
3737
3738 case TOP_DRAG_ENTER:
3739 case TOP_DRAG_LEAVE:
3740 queuedDrag = null;
3741 break;
3742
3743 case TOP_MOUSE_OVER:
3744 case TOP_MOUSE_OUT:
3745 queuedMouse = null;
3746 break;
3747
3748 case TOP_POINTER_OVER:
3749 case TOP_POINTER_OUT:
3750 {
3751 var pointerId = nativeEvent.pointerId;
3752 queuedPointers.delete(pointerId);
3753 break;
3754 }
3755
3756 case TOP_GOT_POINTER_CAPTURE:
3757 case TOP_LOST_POINTER_CAPTURE:
3758 {
3759 var _pointerId = nativeEvent.pointerId;
3760 queuedPointerCaptures.delete(_pointerId);
3761 break;
3762 }
3763 }
3764}
3765
3766function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3767 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
3768 var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
3769
3770 if (blockedOn !== null) {
3771 var _fiber2 = getInstanceFromNode$1(blockedOn);
3772
3773 if (_fiber2 !== null) {
3774 // Attempt to increase the priority of this target.
3775 attemptContinuousHydration(_fiber2);
3776 }
3777 }
3778
3779 return queuedEvent;
3780 } // If we have already queued this exact event, then it's because
3781 // the different event systems have different DOM event listeners.
3782 // We can accumulate the flags and store a single event to be
3783 // replayed.
3784
3785
3786 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
3787 return existingQueuedEvent;
3788}
3789
3790function queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3791 // These set relatedTarget to null because the replayed event will be treated as if we
3792 // moved from outside the window (no target) onto the target once it hydrates.
3793 // Instead of mutating we could clone the event.
3794 switch (topLevelType) {
3795 case TOP_FOCUS:
3796 {
3797 var focusEvent = nativeEvent;
3798 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, topLevelType, eventSystemFlags, container, focusEvent);
3799 return true;
3800 }
3801
3802 case TOP_DRAG_ENTER:
3803 {
3804 var dragEvent = nativeEvent;
3805 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, topLevelType, eventSystemFlags, container, dragEvent);
3806 return true;
3807 }
3808
3809 case TOP_MOUSE_OVER:
3810 {
3811 var mouseEvent = nativeEvent;
3812 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, topLevelType, eventSystemFlags, container, mouseEvent);
3813 return true;
3814 }
3815
3816 case TOP_POINTER_OVER:
3817 {
3818 var pointerEvent = nativeEvent;
3819 var pointerId = pointerEvent.pointerId;
3820 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, topLevelType, eventSystemFlags, container, pointerEvent));
3821 return true;
3822 }
3823
3824 case TOP_GOT_POINTER_CAPTURE:
3825 {
3826 var _pointerEvent = nativeEvent;
3827 var _pointerId2 = _pointerEvent.pointerId;
3828 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, topLevelType, eventSystemFlags, container, _pointerEvent));
3829 return true;
3830 }
3831 }
3832
3833 return false;
3834} // Check if this target is unblocked. Returns true if it's unblocked.
3835
3836function attemptExplicitHydrationTarget(queuedTarget) {
3837 // TODO: This function shares a lot of logic with attemptToDispatchEvent.
3838 // Try to unify them. It's a bit tricky since it would require two return
3839 // values.
3840 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
3841
3842 if (targetInst !== null) {
3843 var nearestMounted = getNearestMountedFiber(targetInst);
3844
3845 if (nearestMounted !== null) {
3846 var tag = nearestMounted.tag;
3847
3848 if (tag === SuspenseComponent) {
3849 var instance = getSuspenseInstanceFromFiber(nearestMounted);
3850
3851 if (instance !== null) {
3852 // We're blocked on hydrating this boundary.
3853 // Increase its priority.
3854 queuedTarget.blockedOn = instance;
3855 Scheduler.unstable_runWithPriority(queuedTarget.priority, function () {
3856 attemptHydrationAtCurrentPriority(nearestMounted);
3857 });
3858 return;
3859 }
3860 } else if (tag === HostRoot) {
3861 var root = nearestMounted.stateNode;
3862
3863 if (root.hydrate) {
3864 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
3865 // a root other than sync.
3866
3867 return;
3868 }
3869 }
3870 }
3871 }
3872
3873 queuedTarget.blockedOn = null;
3874}
3875
3876function attemptReplayContinuousQueuedEvent(queuedEvent) {
3877 if (queuedEvent.blockedOn !== null) {
3878 return false;
3879 }
3880
3881 var nextBlockedOn = attemptToDispatchEvent(queuedEvent.topLevelType, queuedEvent.eventSystemFlags, queuedEvent.container, queuedEvent.nativeEvent);
3882
3883 if (nextBlockedOn !== null) {
3884 // We're still blocked. Try again later.
3885 var _fiber3 = getInstanceFromNode$1(nextBlockedOn);
3886
3887 if (_fiber3 !== null) {
3888 attemptContinuousHydration(_fiber3);
3889 }
3890
3891 queuedEvent.blockedOn = nextBlockedOn;
3892 return false;
3893 }
3894
3895 return true;
3896}
3897
3898function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
3899 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
3900 map.delete(key);
3901 }
3902}
3903
3904function replayUnblockedEvents() {
3905 hasScheduledReplayAttempt = false; // First replay discrete events.
3906
3907 while (queuedDiscreteEvents.length > 0) {
3908 var nextDiscreteEvent = queuedDiscreteEvents[0];
3909
3910 if (nextDiscreteEvent.blockedOn !== null) {
3911 // We're still blocked.
3912 // Increase the priority of this boundary to unblock
3913 // the next discrete event.
3914 var _fiber4 = getInstanceFromNode$1(nextDiscreteEvent.blockedOn);
3915
3916 if (_fiber4 !== null) {
3917 attemptUserBlockingHydration(_fiber4);
3918 }
3919
3920 break;
3921 }
3922
3923 var nextBlockedOn = attemptToDispatchEvent(nextDiscreteEvent.topLevelType, nextDiscreteEvent.eventSystemFlags, nextDiscreteEvent.container, nextDiscreteEvent.nativeEvent);
3924
3925 if (nextBlockedOn !== null) {
3926 // We're still blocked. Try again later.
3927 nextDiscreteEvent.blockedOn = nextBlockedOn;
3928 } else {
3929 // We've successfully replayed the first event. Let's try the next one.
3930 queuedDiscreteEvents.shift();
3931 }
3932 } // Next replay any continuous events.
3933
3934
3935 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
3936 queuedFocus = null;
3937 }
3938
3939 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
3940 queuedDrag = null;
3941 }
3942
3943 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
3944 queuedMouse = null;
3945 }
3946
3947 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
3948 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
3949}
3950
3951function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
3952 if (queuedEvent.blockedOn === unblocked) {
3953 queuedEvent.blockedOn = null;
3954
3955 if (!hasScheduledReplayAttempt) {
3956 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
3957 // now unblocked. This first might not actually be unblocked yet.
3958 // We could check it early to avoid scheduling an unnecessary callback.
3959
3960 Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, replayUnblockedEvents);
3961 }
3962 }
3963}
3964
3965function retryIfBlockedOn(unblocked) {
3966 // Mark anything that was blocked on this as no longer blocked
3967 // and eligible for a replay.
3968 if (queuedDiscreteEvents.length > 0) {
3969 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's
3970 // worth it because we expect very few discrete events to queue up and once
3971 // we are actually fully unblocked it will be fast to replay them.
3972
3973 for (var i = 1; i < queuedDiscreteEvents.length; i++) {
3974 var queuedEvent = queuedDiscreteEvents[i];
3975
3976 if (queuedEvent.blockedOn === unblocked) {
3977 queuedEvent.blockedOn = null;
3978 }
3979 }
3980 }
3981
3982 if (queuedFocus !== null) {
3983 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
3984 }
3985
3986 if (queuedDrag !== null) {
3987 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
3988 }
3989
3990 if (queuedMouse !== null) {
3991 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
3992 }
3993
3994 var unblock = function (queuedEvent) {
3995 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
3996 };
3997
3998 queuedPointers.forEach(unblock);
3999 queuedPointerCaptures.forEach(unblock);
4000
4001 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
4002 var queuedTarget = queuedExplicitHydrationTargets[_i];
4003
4004 if (queuedTarget.blockedOn === unblocked) {
4005 queuedTarget.blockedOn = null;
4006 }
4007 }
4008
4009 while (queuedExplicitHydrationTargets.length > 0) {
4010 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
4011
4012 if (nextExplicitTarget.blockedOn !== null) {
4013 // We're still blocked.
4014 break;
4015 } else {
4016 attemptExplicitHydrationTarget(nextExplicitTarget);
4017
4018 if (nextExplicitTarget.blockedOn === null) {
4019 // We're unblocked.
4020 queuedExplicitHydrationTargets.shift();
4021 }
4022 }
4023 }
4024}
4025
4026function addEventBubbleListener(element, eventType, listener) {
4027 element.addEventListener(eventType, listener, false);
4028}
4029function addEventCaptureListener(element, eventType, listener) {
4030 element.addEventListener(eventType, listener, true);
4031}
4032
4033// do it in two places, which duplicates logic
4034// and increases the bundle size, we do it all
4035// here once. If we remove or refactor the
4036// SimpleEventPlugin, we should also remove or
4037// update the below line.
4038
4039var simpleEventPluginEventTypes = {};
4040var topLevelEventsToDispatchConfig = new Map();
4041var eventPriorities = new Map(); // We store most of the events in this module in pairs of two strings so we can re-use
4042// the code required to apply the same logic for event prioritization and that of the
4043// SimpleEventPlugin. This complicates things slightly, but the aim is to reduce code
4044// duplication (for which there would be quite a bit). For the events that are not needed
4045// for the SimpleEventPlugin (otherDiscreteEvents) we process them separately as an
4046// array of top level events.
4047// Lastly, we ignore prettier so we can keep the formatting sane.
4048// prettier-ignore
4049
4050var discreteEventPairsForSimpleEventPlugin = [TOP_BLUR, 'blur', TOP_CANCEL, 'cancel', TOP_CLICK, 'click', TOP_CLOSE, 'close', TOP_CONTEXT_MENU, 'contextMenu', TOP_COPY, 'copy', TOP_CUT, 'cut', TOP_AUX_CLICK, 'auxClick', TOP_DOUBLE_CLICK, 'doubleClick', TOP_DRAG_END, 'dragEnd', TOP_DRAG_START, 'dragStart', TOP_DROP, 'drop', TOP_FOCUS, 'focus', TOP_INPUT, 'input', TOP_INVALID, 'invalid', TOP_KEY_DOWN, 'keyDown', TOP_KEY_PRESS, 'keyPress', TOP_KEY_UP, 'keyUp', TOP_MOUSE_DOWN, 'mouseDown', TOP_MOUSE_UP, 'mouseUp', TOP_PASTE, 'paste', TOP_PAUSE, 'pause', TOP_PLAY, 'play', TOP_POINTER_CANCEL, 'pointerCancel', TOP_POINTER_DOWN, 'pointerDown', TOP_POINTER_UP, 'pointerUp', TOP_RATE_CHANGE, 'rateChange', TOP_RESET, 'reset', TOP_SEEKED, 'seeked', TOP_SUBMIT, 'submit', TOP_TOUCH_CANCEL, 'touchCancel', TOP_TOUCH_END, 'touchEnd', TOP_TOUCH_START, 'touchStart', TOP_VOLUME_CHANGE, 'volumeChange'];
4051var otherDiscreteEvents = [TOP_CHANGE, TOP_SELECTION_CHANGE, TOP_TEXT_INPUT, TOP_COMPOSITION_START, TOP_COMPOSITION_END, TOP_COMPOSITION_UPDATE]; // prettier-ignore
4052
4053var userBlockingPairsForSimpleEventPlugin = [TOP_DRAG, 'drag', TOP_DRAG_ENTER, 'dragEnter', TOP_DRAG_EXIT, 'dragExit', TOP_DRAG_LEAVE, 'dragLeave', TOP_DRAG_OVER, 'dragOver', TOP_MOUSE_MOVE, 'mouseMove', TOP_MOUSE_OUT, 'mouseOut', TOP_MOUSE_OVER, 'mouseOver', TOP_POINTER_MOVE, 'pointerMove', TOP_POINTER_OUT, 'pointerOut', TOP_POINTER_OVER, 'pointerOver', TOP_SCROLL, 'scroll', TOP_TOGGLE, 'toggle', TOP_TOUCH_MOVE, 'touchMove', TOP_WHEEL, 'wheel']; // prettier-ignore
4054
4055var continuousPairsForSimpleEventPlugin = [TOP_ABORT, 'abort', TOP_ANIMATION_END, 'animationEnd', TOP_ANIMATION_ITERATION, 'animationIteration', TOP_ANIMATION_START, 'animationStart', TOP_CAN_PLAY, 'canPlay', TOP_CAN_PLAY_THROUGH, 'canPlayThrough', TOP_DURATION_CHANGE, 'durationChange', TOP_EMPTIED, 'emptied', TOP_ENCRYPTED, 'encrypted', TOP_ENDED, 'ended', TOP_ERROR, 'error', TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture', TOP_LOAD, 'load', TOP_LOADED_DATA, 'loadedData', TOP_LOADED_METADATA, 'loadedMetadata', TOP_LOAD_START, 'loadStart', TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture', TOP_PLAYING, 'playing', TOP_PROGRESS, 'progress', TOP_SEEKING, 'seeking', TOP_STALLED, 'stalled', TOP_SUSPEND, 'suspend', TOP_TIME_UPDATE, 'timeUpdate', TOP_TRANSITION_END, 'transitionEnd', TOP_WAITING, 'waiting'];
4056/**
4057 * Turns
4058 * ['abort', ...]
4059 * into
4060 * eventTypes = {
4061 * 'abort': {
4062 * phasedRegistrationNames: {
4063 * bubbled: 'onAbort',
4064 * captured: 'onAbortCapture',
4065 * },
4066 * dependencies: [TOP_ABORT],
4067 * },
4068 * ...
4069 * };
4070 * topLevelEventsToDispatchConfig = new Map([
4071 * [TOP_ABORT, { sameConfig }],
4072 * ]);
4073 */
4074
4075function processSimpleEventPluginPairsByPriority(eventTypes, priority) {
4076 // As the event types are in pairs of two, we need to iterate
4077 // through in twos. The events are in pairs of two to save code
4078 // and improve init perf of processing this array, as it will
4079 // result in far fewer object allocations and property accesses
4080 // if we only use three arrays to process all the categories of
4081 // instead of tuples.
4082 for (var i = 0; i < eventTypes.length; i += 2) {
4083 var topEvent = eventTypes[i];
4084 var event = eventTypes[i + 1];
4085 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4086 var onEvent = 'on' + capitalizedEvent;
4087 var config = {
4088 phasedRegistrationNames: {
4089 bubbled: onEvent,
4090 captured: onEvent + 'Capture'
4091 },
4092 dependencies: [topEvent],
4093 eventPriority: priority
4094 };
4095 eventPriorities.set(topEvent, priority);
4096 topLevelEventsToDispatchConfig.set(topEvent, config);
4097 simpleEventPluginEventTypes[event] = config;
4098 }
4099}
4100
4101function processTopEventPairsByPriority(eventTypes, priority) {
4102 for (var i = 0; i < eventTypes.length; i++) {
4103 eventPriorities.set(eventTypes[i], priority);
4104 }
4105} // SimpleEventPlugin
4106
4107
4108processSimpleEventPluginPairsByPriority(discreteEventPairsForSimpleEventPlugin, DiscreteEvent);
4109processSimpleEventPluginPairsByPriority(userBlockingPairsForSimpleEventPlugin, UserBlockingEvent);
4110processSimpleEventPluginPairsByPriority(continuousPairsForSimpleEventPlugin, ContinuousEvent); // Not used by SimpleEventPlugin
4111
4112processTopEventPairsByPriority(otherDiscreteEvents, DiscreteEvent);
4113function getEventPriorityForPluginSystem(topLevelType) {
4114 var priority = eventPriorities.get(topLevelType); // Default to a ContinuousEvent. Note: we might
4115 // want to warn if we can't detect the priority
4116 // for the event.
4117
4118 return priority === undefined ? ContinuousEvent : priority;
4119}
4120
4121// Intentionally not named imports because Rollup would use dynamic dispatch for
4122var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,
4123 runWithPriority = Scheduler.unstable_runWithPriority; // TODO: can we stop exporting these?
4124
4125var _enabled = true;
4126function setEnabled(enabled) {
4127 _enabled = !!enabled;
4128}
4129function isEnabled() {
4130 return _enabled;
4131}
4132function trapBubbledEvent(topLevelType, element) {
4133 trapEventForPluginEventSystem(element, topLevelType, false);
4134}
4135function trapCapturedEvent(topLevelType, element) {
4136 trapEventForPluginEventSystem(element, topLevelType, true);
4137}
4138
4139function trapEventForPluginEventSystem(container, topLevelType, capture) {
4140 var listener;
4141
4142 switch (getEventPriorityForPluginSystem(topLevelType)) {
4143 case DiscreteEvent:
4144 listener = dispatchDiscreteEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4145 break;
4146
4147 case UserBlockingEvent:
4148 listener = dispatchUserBlockingUpdate.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4149 break;
4150
4151 case ContinuousEvent:
4152 default:
4153 listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4154 break;
4155 }
4156
4157 var rawEventName = getRawEventName(topLevelType);
4158
4159 if (capture) {
4160 addEventCaptureListener(container, rawEventName, listener);
4161 } else {
4162 addEventBubbleListener(container, rawEventName, listener);
4163 }
4164}
4165
4166function dispatchDiscreteEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4167 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
4168 discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, container, nativeEvent);
4169}
4170
4171function dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, container, nativeEvent) {
4172 runWithPriority(UserBlockingPriority, dispatchEvent.bind(null, topLevelType, eventSystemFlags, container, nativeEvent));
4173}
4174
4175function dispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4176 if (!_enabled) {
4177 return;
4178 }
4179
4180 if (hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(topLevelType)) {
4181 // If we already have a queue of discrete events, and this is another discrete
4182 // event, then we can't dispatch it regardless of its target, since they
4183 // need to dispatch in order.
4184 queueDiscreteEvent(null, // Flags that we're not actually blocked on anything as far as we know.
4185 topLevelType, eventSystemFlags, container, nativeEvent);
4186 return;
4187 }
4188
4189 var blockedOn = attemptToDispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent);
4190
4191 if (blockedOn === null) {
4192 // We successfully dispatched this event.
4193 clearIfContinuousEvent(topLevelType, nativeEvent);
4194 return;
4195 }
4196
4197 if (isReplayableDiscreteEvent(topLevelType)) {
4198 // This this to be replayed later once the target is available.
4199 queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
4200 return;
4201 }
4202
4203 if (queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent)) {
4204 return;
4205 } // We need to clear only if we didn't queue because
4206 // queueing is accummulative.
4207
4208
4209 clearIfContinuousEvent(topLevelType, nativeEvent); // This is not replayable so we'll invoke it but without a target,
4210 // in case the event system needs to trace it.
4211
4212 {
4213 dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, null);
4214 }
4215} // Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
4216
4217function attemptToDispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4218 // TODO: Warn if _enabled is false.
4219 var nativeEventTarget = getEventTarget(nativeEvent);
4220 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4221
4222 if (targetInst !== null) {
4223 var nearestMounted = getNearestMountedFiber(targetInst);
4224
4225 if (nearestMounted === null) {
4226 // This tree has been unmounted already. Dispatch without a target.
4227 targetInst = null;
4228 } else {
4229 var tag = nearestMounted.tag;
4230
4231 if (tag === SuspenseComponent) {
4232 var instance = getSuspenseInstanceFromFiber(nearestMounted);
4233
4234 if (instance !== null) {
4235 // Queue the event to be replayed later. Abort dispatching since we
4236 // don't want this event dispatched twice through the event system.
4237 // TODO: If this is the first discrete event in the queue. Schedule an increased
4238 // priority for this boundary.
4239 return instance;
4240 } // This shouldn't happen, something went wrong but to avoid blocking
4241 // the whole system, dispatch the event without a target.
4242 // TODO: Warn.
4243
4244
4245 targetInst = null;
4246 } else if (tag === HostRoot) {
4247 var root = nearestMounted.stateNode;
4248
4249 if (root.hydrate) {
4250 // If this happens during a replay something went wrong and it might block
4251 // the whole system.
4252 return getContainerFromFiber(nearestMounted);
4253 }
4254
4255 targetInst = null;
4256 } else if (nearestMounted !== targetInst) {
4257 // If we get an event (ex: img onload) before committing that
4258 // component's mount, ignore it for now (that is, treat it as if it was an
4259 // event on a non-React tree). We might also consider queueing events and
4260 // dispatching them after the mount.
4261 targetInst = null;
4262 }
4263 }
4264 }
4265
4266 {
4267 dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
4268 } // We're not blocked on anything.
4269
4270
4271 return null;
4272}
4273
4274// List derived from Gecko source code:
4275// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
4276var shorthandToLonghand = {
4277 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
4278 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
4279 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
4280 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
4281 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
4282 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
4283 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
4284 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
4285 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
4286 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
4287 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
4288 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
4289 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
4290 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
4291 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
4292 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
4293 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
4294 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
4295 columns: ['columnCount', 'columnWidth'],
4296 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
4297 flexFlow: ['flexDirection', 'flexWrap'],
4298 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
4299 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
4300 gap: ['columnGap', 'rowGap'],
4301 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
4302 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
4303 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
4304 gridColumnGap: ['columnGap'],
4305 gridGap: ['columnGap', 'rowGap'],
4306 gridRow: ['gridRowEnd', 'gridRowStart'],
4307 gridRowGap: ['rowGap'],
4308 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
4309 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
4310 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
4311 marker: ['markerEnd', 'markerMid', 'markerStart'],
4312 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
4313 maskPosition: ['maskPositionX', 'maskPositionY'],
4314 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
4315 overflow: ['overflowX', 'overflowY'],
4316 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
4317 placeContent: ['alignContent', 'justifyContent'],
4318 placeItems: ['alignItems', 'justifyItems'],
4319 placeSelf: ['alignSelf', 'justifySelf'],
4320 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
4321 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
4322 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
4323 wordWrap: ['overflowWrap']
4324};
4325
4326/**
4327 * CSS properties which accept numbers but are not in units of "px".
4328 */
4329var isUnitlessNumber = {
4330 animationIterationCount: true,
4331 borderImageOutset: true,
4332 borderImageSlice: true,
4333 borderImageWidth: true,
4334 boxFlex: true,
4335 boxFlexGroup: true,
4336 boxOrdinalGroup: true,
4337 columnCount: true,
4338 columns: true,
4339 flex: true,
4340 flexGrow: true,
4341 flexPositive: true,
4342 flexShrink: true,
4343 flexNegative: true,
4344 flexOrder: true,
4345 gridArea: true,
4346 gridRow: true,
4347 gridRowEnd: true,
4348 gridRowSpan: true,
4349 gridRowStart: true,
4350 gridColumn: true,
4351 gridColumnEnd: true,
4352 gridColumnSpan: true,
4353 gridColumnStart: true,
4354 fontWeight: true,
4355 lineClamp: true,
4356 lineHeight: true,
4357 opacity: true,
4358 order: true,
4359 orphans: true,
4360 tabSize: true,
4361 widows: true,
4362 zIndex: true,
4363 zoom: true,
4364 // SVG-related properties
4365 fillOpacity: true,
4366 floodOpacity: true,
4367 stopOpacity: true,
4368 strokeDasharray: true,
4369 strokeDashoffset: true,
4370 strokeMiterlimit: true,
4371 strokeOpacity: true,
4372 strokeWidth: true
4373};
4374/**
4375 * @param {string} prefix vendor-specific prefix, eg: Webkit
4376 * @param {string} key style name, eg: transitionDuration
4377 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
4378 * WebkitTransitionDuration
4379 */
4380
4381function prefixKey(prefix, key) {
4382 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
4383}
4384/**
4385 * Support style names that may come passed in prefixed by adding permutations
4386 * of vendor prefixes.
4387 */
4388
4389
4390var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
4391// infinite loop, because it iterates over the newly added props too.
4392
4393Object.keys(isUnitlessNumber).forEach(function (prop) {
4394 prefixes.forEach(function (prefix) {
4395 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
4396 });
4397});
4398
4399/**
4400 * Convert a value into the proper css writable value. The style name `name`
4401 * should be logical (no hyphens), as specified
4402 * in `CSSProperty.isUnitlessNumber`.
4403 *
4404 * @param {string} name CSS property name such as `topMargin`.
4405 * @param {*} value CSS property value such as `10px`.
4406 * @return {string} Normalized style value with dimensions applied.
4407 */
4408
4409function dangerousStyleValue(name, value, isCustomProperty) {
4410 // Note that we've removed escapeTextForBrowser() calls here since the
4411 // whole string will be escaped when the attribute is injected into
4412 // the markup. If you provide unsafe user data here they can inject
4413 // arbitrary CSS which may be problematic (I couldn't repro this):
4414 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
4415 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
4416 // This is not an XSS hole but instead a potential CSS injection issue
4417 // which has lead to a greater discussion about how we're going to
4418 // trust URLs moving forward. See #2115901
4419 var isEmpty = value == null || typeof value === 'boolean' || value === '';
4420
4421 if (isEmpty) {
4422 return '';
4423 }
4424
4425 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
4426 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
4427 }
4428
4429 return ('' + value).trim();
4430}
4431
4432var uppercasePattern = /([A-Z])/g;
4433var msPattern = /^ms-/;
4434/**
4435 * Hyphenates a camelcased CSS property name, for example:
4436 *
4437 * > hyphenateStyleName('backgroundColor')
4438 * < "background-color"
4439 * > hyphenateStyleName('MozTransition')
4440 * < "-moz-transition"
4441 * > hyphenateStyleName('msTransition')
4442 * < "-ms-transition"
4443 *
4444 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
4445 * is converted to `-ms-`.
4446 */
4447
4448function hyphenateStyleName(name) {
4449 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
4450}
4451
4452var warnValidStyle = function () {};
4453
4454{
4455 // 'msTransform' is correct, but the other prefixes should be capitalized
4456 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
4457 var msPattern$1 = /^-ms-/;
4458 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
4459
4460 var badStyleValueWithSemicolonPattern = /;\s*$/;
4461 var warnedStyleNames = {};
4462 var warnedStyleValues = {};
4463 var warnedForNaNValue = false;
4464 var warnedForInfinityValue = false;
4465
4466 var camelize = function (string) {
4467 return string.replace(hyphenPattern, function (_, character) {
4468 return character.toUpperCase();
4469 });
4470 };
4471
4472 var warnHyphenatedStyleName = function (name) {
4473 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
4474 return;
4475 }
4476
4477 warnedStyleNames[name] = true;
4478
4479 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
4480 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
4481 // is converted to lowercase `ms`.
4482 camelize(name.replace(msPattern$1, 'ms-')));
4483 };
4484
4485 var warnBadVendoredStyleName = function (name) {
4486 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
4487 return;
4488 }
4489
4490 warnedStyleNames[name] = true;
4491
4492 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
4493 };
4494
4495 var warnStyleValueWithSemicolon = function (name, value) {
4496 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
4497 return;
4498 }
4499
4500 warnedStyleValues[value] = true;
4501
4502 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
4503 };
4504
4505 var warnStyleValueIsNaN = function (name, value) {
4506 if (warnedForNaNValue) {
4507 return;
4508 }
4509
4510 warnedForNaNValue = true;
4511
4512 error('`NaN` is an invalid value for the `%s` css style property.', name);
4513 };
4514
4515 var warnStyleValueIsInfinity = function (name, value) {
4516 if (warnedForInfinityValue) {
4517 return;
4518 }
4519
4520 warnedForInfinityValue = true;
4521
4522 error('`Infinity` is an invalid value for the `%s` css style property.', name);
4523 };
4524
4525 warnValidStyle = function (name, value) {
4526 if (name.indexOf('-') > -1) {
4527 warnHyphenatedStyleName(name);
4528 } else if (badVendoredStyleNamePattern.test(name)) {
4529 warnBadVendoredStyleName(name);
4530 } else if (badStyleValueWithSemicolonPattern.test(value)) {
4531 warnStyleValueWithSemicolon(name, value);
4532 }
4533
4534 if (typeof value === 'number') {
4535 if (isNaN(value)) {
4536 warnStyleValueIsNaN(name, value);
4537 } else if (!isFinite(value)) {
4538 warnStyleValueIsInfinity(name, value);
4539 }
4540 }
4541 };
4542}
4543
4544var warnValidStyle$1 = warnValidStyle;
4545
4546/**
4547 * Operations for dealing with CSS properties.
4548 */
4549
4550/**
4551 * This creates a string that is expected to be equivalent to the style
4552 * attribute generated by server-side rendering. It by-passes warnings and
4553 * security checks so it's not safe to use this value for anything other than
4554 * comparison. It is only used in DEV for SSR validation.
4555 */
4556
4557function createDangerousStringForStyles(styles) {
4558 {
4559 var serialized = '';
4560 var delimiter = '';
4561
4562 for (var styleName in styles) {
4563 if (!styles.hasOwnProperty(styleName)) {
4564 continue;
4565 }
4566
4567 var styleValue = styles[styleName];
4568
4569 if (styleValue != null) {
4570 var isCustomProperty = styleName.indexOf('--') === 0;
4571 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
4572 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
4573 delimiter = ';';
4574 }
4575 }
4576
4577 return serialized || null;
4578 }
4579}
4580/**
4581 * Sets the value for multiple styles on a node. If a value is specified as
4582 * '' (empty string), the corresponding style property will be unset.
4583 *
4584 * @param {DOMElement} node
4585 * @param {object} styles
4586 */
4587
4588function setValueForStyles(node, styles) {
4589 var style = node.style;
4590
4591 for (var styleName in styles) {
4592 if (!styles.hasOwnProperty(styleName)) {
4593 continue;
4594 }
4595
4596 var isCustomProperty = styleName.indexOf('--') === 0;
4597
4598 {
4599 if (!isCustomProperty) {
4600 warnValidStyle$1(styleName, styles[styleName]);
4601 }
4602 }
4603
4604 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
4605
4606 if (styleName === 'float') {
4607 styleName = 'cssFloat';
4608 }
4609
4610 if (isCustomProperty) {
4611 style.setProperty(styleName, styleValue);
4612 } else {
4613 style[styleName] = styleValue;
4614 }
4615 }
4616}
4617
4618function isValueEmpty(value) {
4619 return value == null || typeof value === 'boolean' || value === '';
4620}
4621/**
4622 * Given {color: 'red', overflow: 'hidden'} returns {
4623 * color: 'color',
4624 * overflowX: 'overflow',
4625 * overflowY: 'overflow',
4626 * }. This can be read as "the overflowY property was set by the overflow
4627 * shorthand". That is, the values are the property that each was derived from.
4628 */
4629
4630
4631function expandShorthandMap(styles) {
4632 var expanded = {};
4633
4634 for (var key in styles) {
4635 var longhands = shorthandToLonghand[key] || [key];
4636
4637 for (var i = 0; i < longhands.length; i++) {
4638 expanded[longhands[i]] = key;
4639 }
4640 }
4641
4642 return expanded;
4643}
4644/**
4645 * When mixing shorthand and longhand property names, we warn during updates if
4646 * we expect an incorrect result to occur. In particular, we warn for:
4647 *
4648 * Updating a shorthand property (longhand gets overwritten):
4649 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
4650 * becomes .style.font = 'baz'
4651 * Removing a shorthand property (longhand gets lost too):
4652 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
4653 * becomes .style.font = ''
4654 * Removing a longhand property (should revert to shorthand; doesn't):
4655 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
4656 * becomes .style.fontVariant = ''
4657 */
4658
4659
4660function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
4661 {
4662
4663 if (!nextStyles) {
4664 return;
4665 }
4666
4667 var expandedUpdates = expandShorthandMap(styleUpdates);
4668 var expandedStyles = expandShorthandMap(nextStyles);
4669 var warnedAbout = {};
4670
4671 for (var key in expandedUpdates) {
4672 var originalKey = expandedUpdates[key];
4673 var correctOriginalKey = expandedStyles[key];
4674
4675 if (correctOriginalKey && originalKey !== correctOriginalKey) {
4676 var warningKey = originalKey + ',' + correctOriginalKey;
4677
4678 if (warnedAbout[warningKey]) {
4679 continue;
4680 }
4681
4682 warnedAbout[warningKey] = true;
4683
4684 error('%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(styleUpdates[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey);
4685 }
4686 }
4687 }
4688}
4689
4690// For HTML, certain tags should omit their close tag. We keep a whitelist for
4691// those special-case tags.
4692var omittedCloseTags = {
4693 area: true,
4694 base: true,
4695 br: true,
4696 col: true,
4697 embed: true,
4698 hr: true,
4699 img: true,
4700 input: true,
4701 keygen: true,
4702 link: true,
4703 meta: true,
4704 param: true,
4705 source: true,
4706 track: true,
4707 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
4708
4709};
4710
4711// `omittedCloseTags` except that `menuitem` should still have its closing tag.
4712
4713var voidElementTags = _assign({
4714 menuitem: true
4715}, omittedCloseTags);
4716
4717var HTML = '__html';
4718var ReactDebugCurrentFrame$3 = null;
4719
4720{
4721 ReactDebugCurrentFrame$3 = ReactSharedInternals.ReactDebugCurrentFrame;
4722}
4723
4724function assertValidProps(tag, props) {
4725 if (!props) {
4726 return;
4727 } // Note the use of `==` which checks for null or undefined.
4728
4729
4730 if (voidElementTags[tag]) {
4731 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {
4732 {
4733 throw Error( tag + " is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`." + ( ReactDebugCurrentFrame$3.getStackAddendum() ) );
4734 }
4735 }
4736 }
4737
4738 if (props.dangerouslySetInnerHTML != null) {
4739 if (!(props.children == null)) {
4740 {
4741 throw Error( "Can only set one of `children` or `props.dangerouslySetInnerHTML`." );
4742 }
4743 }
4744
4745 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML)) {
4746 {
4747 throw Error( "`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information." );
4748 }
4749 }
4750 }
4751
4752 {
4753 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
4754 error('A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.');
4755 }
4756 }
4757
4758 if (!(props.style == null || typeof props.style === 'object')) {
4759 {
4760 throw Error( "The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX." + ( ReactDebugCurrentFrame$3.getStackAddendum() ) );
4761 }
4762 }
4763}
4764
4765function isCustomComponent(tagName, props) {
4766 if (tagName.indexOf('-') === -1) {
4767 return typeof props.is === 'string';
4768 }
4769
4770 switch (tagName) {
4771 // These are reserved SVG and MathML elements.
4772 // We don't mind this whitelist too much because we expect it to never grow.
4773 // The alternative is to track the namespace in a few places which is convoluted.
4774 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
4775 case 'annotation-xml':
4776 case 'color-profile':
4777 case 'font-face':
4778 case 'font-face-src':
4779 case 'font-face-uri':
4780 case 'font-face-format':
4781 case 'font-face-name':
4782 case 'missing-glyph':
4783 return false;
4784
4785 default:
4786 return true;
4787 }
4788}
4789
4790// When adding attributes to the HTML or SVG whitelist, be sure to
4791// also add them to this module to ensure casing and incorrect name
4792// warnings.
4793var possibleStandardNames = {
4794 // HTML
4795 accept: 'accept',
4796 acceptcharset: 'acceptCharset',
4797 'accept-charset': 'acceptCharset',
4798 accesskey: 'accessKey',
4799 action: 'action',
4800 allowfullscreen: 'allowFullScreen',
4801 alt: 'alt',
4802 as: 'as',
4803 async: 'async',
4804 autocapitalize: 'autoCapitalize',
4805 autocomplete: 'autoComplete',
4806 autocorrect: 'autoCorrect',
4807 autofocus: 'autoFocus',
4808 autoplay: 'autoPlay',
4809 autosave: 'autoSave',
4810 capture: 'capture',
4811 cellpadding: 'cellPadding',
4812 cellspacing: 'cellSpacing',
4813 challenge: 'challenge',
4814 charset: 'charSet',
4815 checked: 'checked',
4816 children: 'children',
4817 cite: 'cite',
4818 class: 'className',
4819 classid: 'classID',
4820 classname: 'className',
4821 cols: 'cols',
4822 colspan: 'colSpan',
4823 content: 'content',
4824 contenteditable: 'contentEditable',
4825 contextmenu: 'contextMenu',
4826 controls: 'controls',
4827 controlslist: 'controlsList',
4828 coords: 'coords',
4829 crossorigin: 'crossOrigin',
4830 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
4831 data: 'data',
4832 datetime: 'dateTime',
4833 default: 'default',
4834 defaultchecked: 'defaultChecked',
4835 defaultvalue: 'defaultValue',
4836 defer: 'defer',
4837 dir: 'dir',
4838 disabled: 'disabled',
4839 disablepictureinpicture: 'disablePictureInPicture',
4840 download: 'download',
4841 draggable: 'draggable',
4842 enctype: 'encType',
4843 for: 'htmlFor',
4844 form: 'form',
4845 formmethod: 'formMethod',
4846 formaction: 'formAction',
4847 formenctype: 'formEncType',
4848 formnovalidate: 'formNoValidate',
4849 formtarget: 'formTarget',
4850 frameborder: 'frameBorder',
4851 headers: 'headers',
4852 height: 'height',
4853 hidden: 'hidden',
4854 high: 'high',
4855 href: 'href',
4856 hreflang: 'hrefLang',
4857 htmlfor: 'htmlFor',
4858 httpequiv: 'httpEquiv',
4859 'http-equiv': 'httpEquiv',
4860 icon: 'icon',
4861 id: 'id',
4862 innerhtml: 'innerHTML',
4863 inputmode: 'inputMode',
4864 integrity: 'integrity',
4865 is: 'is',
4866 itemid: 'itemID',
4867 itemprop: 'itemProp',
4868 itemref: 'itemRef',
4869 itemscope: 'itemScope',
4870 itemtype: 'itemType',
4871 keyparams: 'keyParams',
4872 keytype: 'keyType',
4873 kind: 'kind',
4874 label: 'label',
4875 lang: 'lang',
4876 list: 'list',
4877 loop: 'loop',
4878 low: 'low',
4879 manifest: 'manifest',
4880 marginwidth: 'marginWidth',
4881 marginheight: 'marginHeight',
4882 max: 'max',
4883 maxlength: 'maxLength',
4884 media: 'media',
4885 mediagroup: 'mediaGroup',
4886 method: 'method',
4887 min: 'min',
4888 minlength: 'minLength',
4889 multiple: 'multiple',
4890 muted: 'muted',
4891 name: 'name',
4892 nomodule: 'noModule',
4893 nonce: 'nonce',
4894 novalidate: 'noValidate',
4895 open: 'open',
4896 optimum: 'optimum',
4897 pattern: 'pattern',
4898 placeholder: 'placeholder',
4899 playsinline: 'playsInline',
4900 poster: 'poster',
4901 preload: 'preload',
4902 profile: 'profile',
4903 radiogroup: 'radioGroup',
4904 readonly: 'readOnly',
4905 referrerpolicy: 'referrerPolicy',
4906 rel: 'rel',
4907 required: 'required',
4908 reversed: 'reversed',
4909 role: 'role',
4910 rows: 'rows',
4911 rowspan: 'rowSpan',
4912 sandbox: 'sandbox',
4913 scope: 'scope',
4914 scoped: 'scoped',
4915 scrolling: 'scrolling',
4916 seamless: 'seamless',
4917 selected: 'selected',
4918 shape: 'shape',
4919 size: 'size',
4920 sizes: 'sizes',
4921 span: 'span',
4922 spellcheck: 'spellCheck',
4923 src: 'src',
4924 srcdoc: 'srcDoc',
4925 srclang: 'srcLang',
4926 srcset: 'srcSet',
4927 start: 'start',
4928 step: 'step',
4929 style: 'style',
4930 summary: 'summary',
4931 tabindex: 'tabIndex',
4932 target: 'target',
4933 title: 'title',
4934 type: 'type',
4935 usemap: 'useMap',
4936 value: 'value',
4937 width: 'width',
4938 wmode: 'wmode',
4939 wrap: 'wrap',
4940 // SVG
4941 about: 'about',
4942 accentheight: 'accentHeight',
4943 'accent-height': 'accentHeight',
4944 accumulate: 'accumulate',
4945 additive: 'additive',
4946 alignmentbaseline: 'alignmentBaseline',
4947 'alignment-baseline': 'alignmentBaseline',
4948 allowreorder: 'allowReorder',
4949 alphabetic: 'alphabetic',
4950 amplitude: 'amplitude',
4951 arabicform: 'arabicForm',
4952 'arabic-form': 'arabicForm',
4953 ascent: 'ascent',
4954 attributename: 'attributeName',
4955 attributetype: 'attributeType',
4956 autoreverse: 'autoReverse',
4957 azimuth: 'azimuth',
4958 basefrequency: 'baseFrequency',
4959 baselineshift: 'baselineShift',
4960 'baseline-shift': 'baselineShift',
4961 baseprofile: 'baseProfile',
4962 bbox: 'bbox',
4963 begin: 'begin',
4964 bias: 'bias',
4965 by: 'by',
4966 calcmode: 'calcMode',
4967 capheight: 'capHeight',
4968 'cap-height': 'capHeight',
4969 clip: 'clip',
4970 clippath: 'clipPath',
4971 'clip-path': 'clipPath',
4972 clippathunits: 'clipPathUnits',
4973 cliprule: 'clipRule',
4974 'clip-rule': 'clipRule',
4975 color: 'color',
4976 colorinterpolation: 'colorInterpolation',
4977 'color-interpolation': 'colorInterpolation',
4978 colorinterpolationfilters: 'colorInterpolationFilters',
4979 'color-interpolation-filters': 'colorInterpolationFilters',
4980 colorprofile: 'colorProfile',
4981 'color-profile': 'colorProfile',
4982 colorrendering: 'colorRendering',
4983 'color-rendering': 'colorRendering',
4984 contentscripttype: 'contentScriptType',
4985 contentstyletype: 'contentStyleType',
4986 cursor: 'cursor',
4987 cx: 'cx',
4988 cy: 'cy',
4989 d: 'd',
4990 datatype: 'datatype',
4991 decelerate: 'decelerate',
4992 descent: 'descent',
4993 diffuseconstant: 'diffuseConstant',
4994 direction: 'direction',
4995 display: 'display',
4996 divisor: 'divisor',
4997 dominantbaseline: 'dominantBaseline',
4998 'dominant-baseline': 'dominantBaseline',
4999 dur: 'dur',
5000 dx: 'dx',
5001 dy: 'dy',
5002 edgemode: 'edgeMode',
5003 elevation: 'elevation',
5004 enablebackground: 'enableBackground',
5005 'enable-background': 'enableBackground',
5006 end: 'end',
5007 exponent: 'exponent',
5008 externalresourcesrequired: 'externalResourcesRequired',
5009 fill: 'fill',
5010 fillopacity: 'fillOpacity',
5011 'fill-opacity': 'fillOpacity',
5012 fillrule: 'fillRule',
5013 'fill-rule': 'fillRule',
5014 filter: 'filter',
5015 filterres: 'filterRes',
5016 filterunits: 'filterUnits',
5017 floodopacity: 'floodOpacity',
5018 'flood-opacity': 'floodOpacity',
5019 floodcolor: 'floodColor',
5020 'flood-color': 'floodColor',
5021 focusable: 'focusable',
5022 fontfamily: 'fontFamily',
5023 'font-family': 'fontFamily',
5024 fontsize: 'fontSize',
5025 'font-size': 'fontSize',
5026 fontsizeadjust: 'fontSizeAdjust',
5027 'font-size-adjust': 'fontSizeAdjust',
5028 fontstretch: 'fontStretch',
5029 'font-stretch': 'fontStretch',
5030 fontstyle: 'fontStyle',
5031 'font-style': 'fontStyle',
5032 fontvariant: 'fontVariant',
5033 'font-variant': 'fontVariant',
5034 fontweight: 'fontWeight',
5035 'font-weight': 'fontWeight',
5036 format: 'format',
5037 from: 'from',
5038 fx: 'fx',
5039 fy: 'fy',
5040 g1: 'g1',
5041 g2: 'g2',
5042 glyphname: 'glyphName',
5043 'glyph-name': 'glyphName',
5044 glyphorientationhorizontal: 'glyphOrientationHorizontal',
5045 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
5046 glyphorientationvertical: 'glyphOrientationVertical',
5047 'glyph-orientation-vertical': 'glyphOrientationVertical',
5048 glyphref: 'glyphRef',
5049 gradienttransform: 'gradientTransform',
5050 gradientunits: 'gradientUnits',
5051 hanging: 'hanging',
5052 horizadvx: 'horizAdvX',
5053 'horiz-adv-x': 'horizAdvX',
5054 horizoriginx: 'horizOriginX',
5055 'horiz-origin-x': 'horizOriginX',
5056 ideographic: 'ideographic',
5057 imagerendering: 'imageRendering',
5058 'image-rendering': 'imageRendering',
5059 in2: 'in2',
5060 in: 'in',
5061 inlist: 'inlist',
5062 intercept: 'intercept',
5063 k1: 'k1',
5064 k2: 'k2',
5065 k3: 'k3',
5066 k4: 'k4',
5067 k: 'k',
5068 kernelmatrix: 'kernelMatrix',
5069 kernelunitlength: 'kernelUnitLength',
5070 kerning: 'kerning',
5071 keypoints: 'keyPoints',
5072 keysplines: 'keySplines',
5073 keytimes: 'keyTimes',
5074 lengthadjust: 'lengthAdjust',
5075 letterspacing: 'letterSpacing',
5076 'letter-spacing': 'letterSpacing',
5077 lightingcolor: 'lightingColor',
5078 'lighting-color': 'lightingColor',
5079 limitingconeangle: 'limitingConeAngle',
5080 local: 'local',
5081 markerend: 'markerEnd',
5082 'marker-end': 'markerEnd',
5083 markerheight: 'markerHeight',
5084 markermid: 'markerMid',
5085 'marker-mid': 'markerMid',
5086 markerstart: 'markerStart',
5087 'marker-start': 'markerStart',
5088 markerunits: 'markerUnits',
5089 markerwidth: 'markerWidth',
5090 mask: 'mask',
5091 maskcontentunits: 'maskContentUnits',
5092 maskunits: 'maskUnits',
5093 mathematical: 'mathematical',
5094 mode: 'mode',
5095 numoctaves: 'numOctaves',
5096 offset: 'offset',
5097 opacity: 'opacity',
5098 operator: 'operator',
5099 order: 'order',
5100 orient: 'orient',
5101 orientation: 'orientation',
5102 origin: 'origin',
5103 overflow: 'overflow',
5104 overlineposition: 'overlinePosition',
5105 'overline-position': 'overlinePosition',
5106 overlinethickness: 'overlineThickness',
5107 'overline-thickness': 'overlineThickness',
5108 paintorder: 'paintOrder',
5109 'paint-order': 'paintOrder',
5110 panose1: 'panose1',
5111 'panose-1': 'panose1',
5112 pathlength: 'pathLength',
5113 patterncontentunits: 'patternContentUnits',
5114 patterntransform: 'patternTransform',
5115 patternunits: 'patternUnits',
5116 pointerevents: 'pointerEvents',
5117 'pointer-events': 'pointerEvents',
5118 points: 'points',
5119 pointsatx: 'pointsAtX',
5120 pointsaty: 'pointsAtY',
5121 pointsatz: 'pointsAtZ',
5122 prefix: 'prefix',
5123 preservealpha: 'preserveAlpha',
5124 preserveaspectratio: 'preserveAspectRatio',
5125 primitiveunits: 'primitiveUnits',
5126 property: 'property',
5127 r: 'r',
5128 radius: 'radius',
5129 refx: 'refX',
5130 refy: 'refY',
5131 renderingintent: 'renderingIntent',
5132 'rendering-intent': 'renderingIntent',
5133 repeatcount: 'repeatCount',
5134 repeatdur: 'repeatDur',
5135 requiredextensions: 'requiredExtensions',
5136 requiredfeatures: 'requiredFeatures',
5137 resource: 'resource',
5138 restart: 'restart',
5139 result: 'result',
5140 results: 'results',
5141 rotate: 'rotate',
5142 rx: 'rx',
5143 ry: 'ry',
5144 scale: 'scale',
5145 security: 'security',
5146 seed: 'seed',
5147 shaperendering: 'shapeRendering',
5148 'shape-rendering': 'shapeRendering',
5149 slope: 'slope',
5150 spacing: 'spacing',
5151 specularconstant: 'specularConstant',
5152 specularexponent: 'specularExponent',
5153 speed: 'speed',
5154 spreadmethod: 'spreadMethod',
5155 startoffset: 'startOffset',
5156 stddeviation: 'stdDeviation',
5157 stemh: 'stemh',
5158 stemv: 'stemv',
5159 stitchtiles: 'stitchTiles',
5160 stopcolor: 'stopColor',
5161 'stop-color': 'stopColor',
5162 stopopacity: 'stopOpacity',
5163 'stop-opacity': 'stopOpacity',
5164 strikethroughposition: 'strikethroughPosition',
5165 'strikethrough-position': 'strikethroughPosition',
5166 strikethroughthickness: 'strikethroughThickness',
5167 'strikethrough-thickness': 'strikethroughThickness',
5168 string: 'string',
5169 stroke: 'stroke',
5170 strokedasharray: 'strokeDasharray',
5171 'stroke-dasharray': 'strokeDasharray',
5172 strokedashoffset: 'strokeDashoffset',
5173 'stroke-dashoffset': 'strokeDashoffset',
5174 strokelinecap: 'strokeLinecap',
5175 'stroke-linecap': 'strokeLinecap',
5176 strokelinejoin: 'strokeLinejoin',
5177 'stroke-linejoin': 'strokeLinejoin',
5178 strokemiterlimit: 'strokeMiterlimit',
5179 'stroke-miterlimit': 'strokeMiterlimit',
5180 strokewidth: 'strokeWidth',
5181 'stroke-width': 'strokeWidth',
5182 strokeopacity: 'strokeOpacity',
5183 'stroke-opacity': 'strokeOpacity',
5184 suppresscontenteditablewarning: 'suppressContentEditableWarning',
5185 suppresshydrationwarning: 'suppressHydrationWarning',
5186 surfacescale: 'surfaceScale',
5187 systemlanguage: 'systemLanguage',
5188 tablevalues: 'tableValues',
5189 targetx: 'targetX',
5190 targety: 'targetY',
5191 textanchor: 'textAnchor',
5192 'text-anchor': 'textAnchor',
5193 textdecoration: 'textDecoration',
5194 'text-decoration': 'textDecoration',
5195 textlength: 'textLength',
5196 textrendering: 'textRendering',
5197 'text-rendering': 'textRendering',
5198 to: 'to',
5199 transform: 'transform',
5200 typeof: 'typeof',
5201 u1: 'u1',
5202 u2: 'u2',
5203 underlineposition: 'underlinePosition',
5204 'underline-position': 'underlinePosition',
5205 underlinethickness: 'underlineThickness',
5206 'underline-thickness': 'underlineThickness',
5207 unicode: 'unicode',
5208 unicodebidi: 'unicodeBidi',
5209 'unicode-bidi': 'unicodeBidi',
5210 unicoderange: 'unicodeRange',
5211 'unicode-range': 'unicodeRange',
5212 unitsperem: 'unitsPerEm',
5213 'units-per-em': 'unitsPerEm',
5214 unselectable: 'unselectable',
5215 valphabetic: 'vAlphabetic',
5216 'v-alphabetic': 'vAlphabetic',
5217 values: 'values',
5218 vectoreffect: 'vectorEffect',
5219 'vector-effect': 'vectorEffect',
5220 version: 'version',
5221 vertadvy: 'vertAdvY',
5222 'vert-adv-y': 'vertAdvY',
5223 vertoriginx: 'vertOriginX',
5224 'vert-origin-x': 'vertOriginX',
5225 vertoriginy: 'vertOriginY',
5226 'vert-origin-y': 'vertOriginY',
5227 vhanging: 'vHanging',
5228 'v-hanging': 'vHanging',
5229 videographic: 'vIdeographic',
5230 'v-ideographic': 'vIdeographic',
5231 viewbox: 'viewBox',
5232 viewtarget: 'viewTarget',
5233 visibility: 'visibility',
5234 vmathematical: 'vMathematical',
5235 'v-mathematical': 'vMathematical',
5236 vocab: 'vocab',
5237 widths: 'widths',
5238 wordspacing: 'wordSpacing',
5239 'word-spacing': 'wordSpacing',
5240 writingmode: 'writingMode',
5241 'writing-mode': 'writingMode',
5242 x1: 'x1',
5243 x2: 'x2',
5244 x: 'x',
5245 xchannelselector: 'xChannelSelector',
5246 xheight: 'xHeight',
5247 'x-height': 'xHeight',
5248 xlinkactuate: 'xlinkActuate',
5249 'xlink:actuate': 'xlinkActuate',
5250 xlinkarcrole: 'xlinkArcrole',
5251 'xlink:arcrole': 'xlinkArcrole',
5252 xlinkhref: 'xlinkHref',
5253 'xlink:href': 'xlinkHref',
5254 xlinkrole: 'xlinkRole',
5255 'xlink:role': 'xlinkRole',
5256 xlinkshow: 'xlinkShow',
5257 'xlink:show': 'xlinkShow',
5258 xlinktitle: 'xlinkTitle',
5259 'xlink:title': 'xlinkTitle',
5260 xlinktype: 'xlinkType',
5261 'xlink:type': 'xlinkType',
5262 xmlbase: 'xmlBase',
5263 'xml:base': 'xmlBase',
5264 xmllang: 'xmlLang',
5265 'xml:lang': 'xmlLang',
5266 xmlns: 'xmlns',
5267 'xml:space': 'xmlSpace',
5268 xmlnsxlink: 'xmlnsXlink',
5269 'xmlns:xlink': 'xmlnsXlink',
5270 xmlspace: 'xmlSpace',
5271 y1: 'y1',
5272 y2: 'y2',
5273 y: 'y',
5274 ychannelselector: 'yChannelSelector',
5275 z: 'z',
5276 zoomandpan: 'zoomAndPan'
5277};
5278
5279var ariaProperties = {
5280 'aria-current': 0,
5281 // state
5282 'aria-details': 0,
5283 'aria-disabled': 0,
5284 // state
5285 'aria-hidden': 0,
5286 // state
5287 'aria-invalid': 0,
5288 // state
5289 'aria-keyshortcuts': 0,
5290 'aria-label': 0,
5291 'aria-roledescription': 0,
5292 // Widget Attributes
5293 'aria-autocomplete': 0,
5294 'aria-checked': 0,
5295 'aria-expanded': 0,
5296 'aria-haspopup': 0,
5297 'aria-level': 0,
5298 'aria-modal': 0,
5299 'aria-multiline': 0,
5300 'aria-multiselectable': 0,
5301 'aria-orientation': 0,
5302 'aria-placeholder': 0,
5303 'aria-pressed': 0,
5304 'aria-readonly': 0,
5305 'aria-required': 0,
5306 'aria-selected': 0,
5307 'aria-sort': 0,
5308 'aria-valuemax': 0,
5309 'aria-valuemin': 0,
5310 'aria-valuenow': 0,
5311 'aria-valuetext': 0,
5312 // Live Region Attributes
5313 'aria-atomic': 0,
5314 'aria-busy': 0,
5315 'aria-live': 0,
5316 'aria-relevant': 0,
5317 // Drag-and-Drop Attributes
5318 'aria-dropeffect': 0,
5319 'aria-grabbed': 0,
5320 // Relationship Attributes
5321 'aria-activedescendant': 0,
5322 'aria-colcount': 0,
5323 'aria-colindex': 0,
5324 'aria-colspan': 0,
5325 'aria-controls': 0,
5326 'aria-describedby': 0,
5327 'aria-errormessage': 0,
5328 'aria-flowto': 0,
5329 'aria-labelledby': 0,
5330 'aria-owns': 0,
5331 'aria-posinset': 0,
5332 'aria-rowcount': 0,
5333 'aria-rowindex': 0,
5334 'aria-rowspan': 0,
5335 'aria-setsize': 0
5336};
5337
5338var warnedProperties = {};
5339var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
5340var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
5341var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
5342
5343function validateProperty(tagName, name) {
5344 {
5345 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
5346 return true;
5347 }
5348
5349 if (rARIACamel.test(name)) {
5350 var ariaName = 'aria-' + name.slice(4).toLowerCase();
5351 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
5352 // DOM properties, then it is an invalid aria-* attribute.
5353
5354 if (correctName == null) {
5355 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
5356
5357 warnedProperties[name] = true;
5358 return true;
5359 } // aria-* attributes should be lowercase; suggest the lowercase version.
5360
5361
5362 if (name !== correctName) {
5363 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
5364
5365 warnedProperties[name] = true;
5366 return true;
5367 }
5368 }
5369
5370 if (rARIA.test(name)) {
5371 var lowerCasedName = name.toLowerCase();
5372 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
5373 // DOM properties, then it is an invalid aria-* attribute.
5374
5375 if (standardName == null) {
5376 warnedProperties[name] = true;
5377 return false;
5378 } // aria-* attributes should be lowercase; suggest the lowercase version.
5379
5380
5381 if (name !== standardName) {
5382 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
5383
5384 warnedProperties[name] = true;
5385 return true;
5386 }
5387 }
5388 }
5389
5390 return true;
5391}
5392
5393function warnInvalidARIAProps(type, props) {
5394 {
5395 var invalidProps = [];
5396
5397 for (var key in props) {
5398 var isValid = validateProperty(type, key);
5399
5400 if (!isValid) {
5401 invalidProps.push(key);
5402 }
5403 }
5404
5405 var unknownPropString = invalidProps.map(function (prop) {
5406 return '`' + prop + '`';
5407 }).join(', ');
5408
5409 if (invalidProps.length === 1) {
5410 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
5411 } else if (invalidProps.length > 1) {
5412 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
5413 }
5414 }
5415}
5416
5417function validateProperties(type, props) {
5418 if (isCustomComponent(type, props)) {
5419 return;
5420 }
5421
5422 warnInvalidARIAProps(type, props);
5423}
5424
5425var didWarnValueNull = false;
5426function validateProperties$1(type, props) {
5427 {
5428 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
5429 return;
5430 }
5431
5432 if (props != null && props.value === null && !didWarnValueNull) {
5433 didWarnValueNull = true;
5434
5435 if (type === 'select' && props.multiple) {
5436 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type);
5437 } else {
5438 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
5439 }
5440 }
5441 }
5442}
5443
5444var validateProperty$1 = function () {};
5445
5446{
5447 var warnedProperties$1 = {};
5448 var _hasOwnProperty = Object.prototype.hasOwnProperty;
5449 var EVENT_NAME_REGEX = /^on./;
5450 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
5451 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
5452 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
5453
5454 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
5455 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
5456 return true;
5457 }
5458
5459 var lowerCasedName = name.toLowerCase();
5460
5461 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
5462 error('React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.');
5463
5464 warnedProperties$1[name] = true;
5465 return true;
5466 } // We can't rely on the event system being injected on the server.
5467
5468
5469 if (canUseEventSystem) {
5470 if (registrationNameModules.hasOwnProperty(name)) {
5471 return true;
5472 }
5473
5474 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
5475
5476 if (registrationName != null) {
5477 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
5478
5479 warnedProperties$1[name] = true;
5480 return true;
5481 }
5482
5483 if (EVENT_NAME_REGEX.test(name)) {
5484 error('Unknown event handler property `%s`. It will be ignored.', name);
5485
5486 warnedProperties$1[name] = true;
5487 return true;
5488 }
5489 } else if (EVENT_NAME_REGEX.test(name)) {
5490 // If no event plugins have been injected, we are in a server environment.
5491 // So we can't tell if the event name is correct for sure, but we can filter
5492 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
5493 if (INVALID_EVENT_NAME_REGEX.test(name)) {
5494 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
5495 }
5496
5497 warnedProperties$1[name] = true;
5498 return true;
5499 } // Let the ARIA attribute hook validate ARIA attributes
5500
5501
5502 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
5503 return true;
5504 }
5505
5506 if (lowerCasedName === 'innerhtml') {
5507 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
5508
5509 warnedProperties$1[name] = true;
5510 return true;
5511 }
5512
5513 if (lowerCasedName === 'aria') {
5514 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
5515
5516 warnedProperties$1[name] = true;
5517 return true;
5518 }
5519
5520 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
5521 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
5522
5523 warnedProperties$1[name] = true;
5524 return true;
5525 }
5526
5527 if (typeof value === 'number' && isNaN(value)) {
5528 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
5529
5530 warnedProperties$1[name] = true;
5531 return true;
5532 }
5533
5534 var propertyInfo = getPropertyInfo(name);
5535 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
5536
5537 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
5538 var standardName = possibleStandardNames[lowerCasedName];
5539
5540 if (standardName !== name) {
5541 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
5542
5543 warnedProperties$1[name] = true;
5544 return true;
5545 }
5546 } else if (!isReserved && name !== lowerCasedName) {
5547 // Unknown attributes should have lowercase casing since that's how they
5548 // will be cased anyway with server rendering.
5549 error('React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.', name, lowerCasedName);
5550
5551 warnedProperties$1[name] = true;
5552 return true;
5553 }
5554
5555 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
5556 if (value) {
5557 error('Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.', value, name, name, value, name);
5558 } else {
5559 error('Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name);
5560 }
5561
5562 warnedProperties$1[name] = true;
5563 return true;
5564 } // Now that we've validated casing, do not validate
5565 // data types for reserved props
5566
5567
5568 if (isReserved) {
5569 return true;
5570 } // Warn when a known attribute is a bad type
5571
5572
5573 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
5574 warnedProperties$1[name] = true;
5575 return false;
5576 } // Warn when passing the strings 'false' or 'true' into a boolean prop
5577
5578
5579 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
5580 error('Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', value, name, value === 'false' ? 'The browser will interpret it as a truthy value.' : 'Although this works, it will not work as expected if you pass the string "false".', name, value);
5581
5582 warnedProperties$1[name] = true;
5583 return true;
5584 }
5585
5586 return true;
5587 };
5588}
5589
5590var warnUnknownProperties = function (type, props, canUseEventSystem) {
5591 {
5592 var unknownProps = [];
5593
5594 for (var key in props) {
5595 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
5596
5597 if (!isValid) {
5598 unknownProps.push(key);
5599 }
5600 }
5601
5602 var unknownPropString = unknownProps.map(function (prop) {
5603 return '`' + prop + '`';
5604 }).join(', ');
5605
5606 if (unknownProps.length === 1) {
5607 error('Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type);
5608 } else if (unknownProps.length > 1) {
5609 error('Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type);
5610 }
5611 }
5612};
5613
5614function validateProperties$2(type, props, canUseEventSystem) {
5615 if (isCustomComponent(type, props)) {
5616 return;
5617 }
5618
5619 warnUnknownProperties(type, props, canUseEventSystem);
5620}
5621
5622var didWarnInvalidHydration = false;
5623var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
5624var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
5625var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
5626var AUTOFOCUS = 'autoFocus';
5627var CHILDREN = 'children';
5628var STYLE = 'style';
5629var HTML$1 = '__html';
5630var HTML_NAMESPACE$1 = Namespaces.html;
5631var warnedUnknownTags;
5632var suppressHydrationWarning;
5633var validatePropertiesInDevelopment;
5634var warnForTextDifference;
5635var warnForPropDifference;
5636var warnForExtraAttributes;
5637var warnForInvalidEventListener;
5638var canDiffStyleForHydrationWarning;
5639var normalizeMarkupForTextOrAttribute;
5640var normalizeHTML;
5641
5642{
5643 warnedUnknownTags = {
5644 // Chrome is the only major browser not shipping <time>. But as of July
5645 // 2017 it intends to ship it due to widespread usage. We intentionally
5646 // *don't* warn for <time> even if it's unrecognized by Chrome because
5647 // it soon will be, and many apps have been using it anyway.
5648 time: true,
5649 // There are working polyfills for <dialog>. Let people use it.
5650 dialog: true,
5651 // Electron ships a custom <webview> tag to display external web content in
5652 // an isolated frame and process.
5653 // This tag is not present in non Electron environments such as JSDom which
5654 // is often used for testing purposes.
5655 // @see https://electronjs.org/docs/api/webview-tag
5656 webview: true
5657 };
5658
5659 validatePropertiesInDevelopment = function (type, props) {
5660 validateProperties(type, props);
5661 validateProperties$1(type, props);
5662 validateProperties$2(type, props,
5663 /* canUseEventSystem */
5664 true);
5665 }; // IE 11 parses & normalizes the style attribute as opposed to other
5666 // browsers. It adds spaces and sorts the properties in some
5667 // non-alphabetical order. Handling that would require sorting CSS
5668 // properties in the client & server versions or applying
5669 // `expectedStyle` to a temporary DOM node to read its `style` attribute
5670 // normalized. Since it only affects IE, we're skipping style warnings
5671 // in that browser completely in favor of doing all that work.
5672 // See https://github.com/facebook/react/issues/11807
5673
5674
5675 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; // HTML parsing normalizes CR and CRLF to LF.
5676 // It also can turn \u0000 into \uFFFD inside attributes.
5677 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
5678 // If we have a mismatch, it might be caused by that.
5679 // We will still patch up in this case but not fire the warning.
5680
5681 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
5682 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
5683
5684 normalizeMarkupForTextOrAttribute = function (markup) {
5685 var markupString = typeof markup === 'string' ? markup : '' + markup;
5686 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
5687 };
5688
5689 warnForTextDifference = function (serverText, clientText) {
5690 if (didWarnInvalidHydration) {
5691 return;
5692 }
5693
5694 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
5695 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
5696
5697 if (normalizedServerText === normalizedClientText) {
5698 return;
5699 }
5700
5701 didWarnInvalidHydration = true;
5702
5703 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
5704 };
5705
5706 warnForPropDifference = function (propName, serverValue, clientValue) {
5707 if (didWarnInvalidHydration) {
5708 return;
5709 }
5710
5711 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
5712 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
5713
5714 if (normalizedServerValue === normalizedClientValue) {
5715 return;
5716 }
5717
5718 didWarnInvalidHydration = true;
5719
5720 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
5721 };
5722
5723 warnForExtraAttributes = function (attributeNames) {
5724 if (didWarnInvalidHydration) {
5725 return;
5726 }
5727
5728 didWarnInvalidHydration = true;
5729 var names = [];
5730 attributeNames.forEach(function (name) {
5731 names.push(name);
5732 });
5733
5734 error('Extra attributes from the server: %s', names);
5735 };
5736
5737 warnForInvalidEventListener = function (registrationName, listener) {
5738 if (listener === false) {
5739 error('Expected `%s` listener to be a function, instead got `false`.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', registrationName, registrationName, registrationName);
5740 } else {
5741 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
5742 }
5743 }; // Parse the HTML and read it back to normalize the HTML string so that it
5744 // can be used for comparison.
5745
5746
5747 normalizeHTML = function (parent, html) {
5748 // We could have created a separate document here to avoid
5749 // re-initializing custom elements if they exist. But this breaks
5750 // how <noscript> is being handled. So we use the same document.
5751 // See the discussion in https://github.com/facebook/react/pull/11157.
5752 var testElement = parent.namespaceURI === HTML_NAMESPACE$1 ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
5753 testElement.innerHTML = html;
5754 return testElement.innerHTML;
5755 };
5756}
5757
5758function ensureListeningTo(rootContainerElement, registrationName) {
5759 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
5760 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
5761 legacyListenToEvent(registrationName, doc);
5762}
5763
5764function getOwnerDocumentFromRootContainer(rootContainerElement) {
5765 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
5766}
5767
5768function noop() {}
5769
5770function trapClickOnNonInteractiveElement(node) {
5771 // Mobile Safari does not fire properly bubble click events on
5772 // non-interactive elements, which means delegated click listeners do not
5773 // fire. The workaround for this bug involves attaching an empty click
5774 // listener on the target node.
5775 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
5776 // Just set it using the onclick property so that we don't have to manage any
5777 // bookkeeping for it. Not sure if we need to clear it when the listener is
5778 // removed.
5779 // TODO: Only do this for the relevant Safaris maybe?
5780 node.onclick = noop;
5781}
5782
5783function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
5784 for (var propKey in nextProps) {
5785 if (!nextProps.hasOwnProperty(propKey)) {
5786 continue;
5787 }
5788
5789 var nextProp = nextProps[propKey];
5790
5791 if (propKey === STYLE) {
5792 {
5793 if (nextProp) {
5794 // Freeze the next style object so that we can assume it won't be
5795 // mutated. We have already warned for this in the past.
5796 Object.freeze(nextProp);
5797 }
5798 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
5799
5800
5801 setValueForStyles(domElement, nextProp);
5802 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
5803 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
5804
5805 if (nextHtml != null) {
5806 setInnerHTML(domElement, nextHtml);
5807 }
5808 } else if (propKey === CHILDREN) {
5809 if (typeof nextProp === 'string') {
5810 // Avoid setting initial textContent when the text is empty. In IE11 setting
5811 // textContent on a <textarea> will cause the placeholder to not
5812 // show within the <textarea> until it has been focused and blurred again.
5813 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
5814 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
5815
5816 if (canSetTextContent) {
5817 setTextContent(domElement, nextProp);
5818 }
5819 } else if (typeof nextProp === 'number') {
5820 setTextContent(domElement, '' + nextProp);
5821 }
5822 } else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameModules.hasOwnProperty(propKey)) {
5823 if (nextProp != null) {
5824 if ( typeof nextProp !== 'function') {
5825 warnForInvalidEventListener(propKey, nextProp);
5826 }
5827
5828 ensureListeningTo(rootContainerElement, propKey);
5829 }
5830 } else if (nextProp != null) {
5831 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
5832 }
5833 }
5834}
5835
5836function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
5837 // TODO: Handle wasCustomComponentTag
5838 for (var i = 0; i < updatePayload.length; i += 2) {
5839 var propKey = updatePayload[i];
5840 var propValue = updatePayload[i + 1];
5841
5842 if (propKey === STYLE) {
5843 setValueForStyles(domElement, propValue);
5844 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
5845 setInnerHTML(domElement, propValue);
5846 } else if (propKey === CHILDREN) {
5847 setTextContent(domElement, propValue);
5848 } else {
5849 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
5850 }
5851 }
5852}
5853
5854function createElement(type, props, rootContainerElement, parentNamespace) {
5855 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
5856 // tags get no namespace.
5857
5858 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
5859 var domElement;
5860 var namespaceURI = parentNamespace;
5861
5862 if (namespaceURI === HTML_NAMESPACE$1) {
5863 namespaceURI = getIntrinsicNamespace(type);
5864 }
5865
5866 if (namespaceURI === HTML_NAMESPACE$1) {
5867 {
5868 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
5869 // allow <SVG> or <mATH>.
5870
5871 if (!isCustomComponentTag && type !== type.toLowerCase()) {
5872 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
5873 }
5874 }
5875
5876 if (type === 'script') {
5877 // Create the script via .innerHTML so its "parser-inserted" flag is
5878 // set to true and it does not execute
5879 var div = ownerDocument.createElement('div');
5880
5881 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
5882 // This is guaranteed to yield a script element.
5883
5884 var firstChild = div.firstChild;
5885 domElement = div.removeChild(firstChild);
5886 } else if (typeof props.is === 'string') {
5887 // $FlowIssue `createElement` should be updated for Web Components
5888 domElement = ownerDocument.createElement(type, {
5889 is: props.is
5890 });
5891 } else {
5892 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
5893 // See discussion in https://github.com/facebook/react/pull/6896
5894 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
5895 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
5896 // attributes on `select`s needs to be added before `option`s are inserted.
5897 // This prevents:
5898 // - a bug where the `select` does not scroll to the correct option because singular
5899 // `select` elements automatically pick the first item #13222
5900 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
5901 // See https://github.com/facebook/react/issues/13222
5902 // and https://github.com/facebook/react/issues/14239
5903
5904 if (type === 'select') {
5905 var node = domElement;
5906
5907 if (props.multiple) {
5908 node.multiple = true;
5909 } else if (props.size) {
5910 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
5911 // it is possible that no option is selected.
5912 //
5913 // This is only necessary when a select in "single selection mode".
5914 node.size = props.size;
5915 }
5916 }
5917 }
5918 } else {
5919 domElement = ownerDocument.createElementNS(namespaceURI, type);
5920 }
5921
5922 {
5923 if (namespaceURI === HTML_NAMESPACE$1) {
5924 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
5925 warnedUnknownTags[type] = true;
5926
5927 error('The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
5928 }
5929 }
5930 }
5931
5932 return domElement;
5933}
5934function createTextNode(text, rootContainerElement) {
5935 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
5936}
5937function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
5938 var isCustomComponentTag = isCustomComponent(tag, rawProps);
5939
5940 {
5941 validatePropertiesInDevelopment(tag, rawProps);
5942 } // TODO: Make sure that we check isMounted before firing any of these events.
5943
5944
5945 var props;
5946
5947 switch (tag) {
5948 case 'iframe':
5949 case 'object':
5950 case 'embed':
5951 trapBubbledEvent(TOP_LOAD, domElement);
5952 props = rawProps;
5953 break;
5954
5955 case 'video':
5956 case 'audio':
5957 // Create listener for each media event
5958 for (var i = 0; i < mediaEventTypes.length; i++) {
5959 trapBubbledEvent(mediaEventTypes[i], domElement);
5960 }
5961
5962 props = rawProps;
5963 break;
5964
5965 case 'source':
5966 trapBubbledEvent(TOP_ERROR, domElement);
5967 props = rawProps;
5968 break;
5969
5970 case 'img':
5971 case 'image':
5972 case 'link':
5973 trapBubbledEvent(TOP_ERROR, domElement);
5974 trapBubbledEvent(TOP_LOAD, domElement);
5975 props = rawProps;
5976 break;
5977
5978 case 'form':
5979 trapBubbledEvent(TOP_RESET, domElement);
5980 trapBubbledEvent(TOP_SUBMIT, domElement);
5981 props = rawProps;
5982 break;
5983
5984 case 'details':
5985 trapBubbledEvent(TOP_TOGGLE, domElement);
5986 props = rawProps;
5987 break;
5988
5989 case 'input':
5990 initWrapperState(domElement, rawProps);
5991 props = getHostProps(domElement, rawProps);
5992 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
5993 // to onChange. Even if there is no listener.
5994
5995 ensureListeningTo(rootContainerElement, 'onChange');
5996 break;
5997
5998 case 'option':
5999 validateProps(domElement, rawProps);
6000 props = getHostProps$1(domElement, rawProps);
6001 break;
6002
6003 case 'select':
6004 initWrapperState$1(domElement, rawProps);
6005 props = getHostProps$2(domElement, rawProps);
6006 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6007 // to onChange. Even if there is no listener.
6008
6009 ensureListeningTo(rootContainerElement, 'onChange');
6010 break;
6011
6012 case 'textarea':
6013 initWrapperState$2(domElement, rawProps);
6014 props = getHostProps$3(domElement, rawProps);
6015 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6016 // to onChange. Even if there is no listener.
6017
6018 ensureListeningTo(rootContainerElement, 'onChange');
6019 break;
6020
6021 default:
6022 props = rawProps;
6023 }
6024
6025 assertValidProps(tag, props);
6026 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
6027
6028 switch (tag) {
6029 case 'input':
6030 // TODO: Make sure we check if this is still unmounted or do any clean
6031 // up necessary since we never stop tracking anymore.
6032 track(domElement);
6033 postMountWrapper(domElement, rawProps, false);
6034 break;
6035
6036 case 'textarea':
6037 // TODO: Make sure we check if this is still unmounted or do any clean
6038 // up necessary since we never stop tracking anymore.
6039 track(domElement);
6040 postMountWrapper$3(domElement);
6041 break;
6042
6043 case 'option':
6044 postMountWrapper$1(domElement, rawProps);
6045 break;
6046
6047 case 'select':
6048 postMountWrapper$2(domElement, rawProps);
6049 break;
6050
6051 default:
6052 if (typeof props.onClick === 'function') {
6053 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6054 trapClickOnNonInteractiveElement(domElement);
6055 }
6056
6057 break;
6058 }
6059} // Calculate the diff between the two objects.
6060
6061function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
6062 {
6063 validatePropertiesInDevelopment(tag, nextRawProps);
6064 }
6065
6066 var updatePayload = null;
6067 var lastProps;
6068 var nextProps;
6069
6070 switch (tag) {
6071 case 'input':
6072 lastProps = getHostProps(domElement, lastRawProps);
6073 nextProps = getHostProps(domElement, nextRawProps);
6074 updatePayload = [];
6075 break;
6076
6077 case 'option':
6078 lastProps = getHostProps$1(domElement, lastRawProps);
6079 nextProps = getHostProps$1(domElement, nextRawProps);
6080 updatePayload = [];
6081 break;
6082
6083 case 'select':
6084 lastProps = getHostProps$2(domElement, lastRawProps);
6085 nextProps = getHostProps$2(domElement, nextRawProps);
6086 updatePayload = [];
6087 break;
6088
6089 case 'textarea':
6090 lastProps = getHostProps$3(domElement, lastRawProps);
6091 nextProps = getHostProps$3(domElement, nextRawProps);
6092 updatePayload = [];
6093 break;
6094
6095 default:
6096 lastProps = lastRawProps;
6097 nextProps = nextRawProps;
6098
6099 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
6100 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6101 trapClickOnNonInteractiveElement(domElement);
6102 }
6103
6104 break;
6105 }
6106
6107 assertValidProps(tag, nextProps);
6108 var propKey;
6109 var styleName;
6110 var styleUpdates = null;
6111
6112 for (propKey in lastProps) {
6113 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
6114 continue;
6115 }
6116
6117 if (propKey === STYLE) {
6118 var lastStyle = lastProps[propKey];
6119
6120 for (styleName in lastStyle) {
6121 if (lastStyle.hasOwnProperty(styleName)) {
6122 if (!styleUpdates) {
6123 styleUpdates = {};
6124 }
6125
6126 styleUpdates[styleName] = '';
6127 }
6128 }
6129 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) ; else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameModules.hasOwnProperty(propKey)) {
6130 // This is a special case. If any listener updates we need to ensure
6131 // that the "current" fiber pointer gets updated so we need a commit
6132 // to update this element.
6133 if (!updatePayload) {
6134 updatePayload = [];
6135 }
6136 } else {
6137 // For all other deleted properties we add it to the queue. We use
6138 // the whitelist in the commit phase instead.
6139 (updatePayload = updatePayload || []).push(propKey, null);
6140 }
6141 }
6142
6143 for (propKey in nextProps) {
6144 var nextProp = nextProps[propKey];
6145 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
6146
6147 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
6148 continue;
6149 }
6150
6151 if (propKey === STYLE) {
6152 {
6153 if (nextProp) {
6154 // Freeze the next style object so that we can assume it won't be
6155 // mutated. We have already warned for this in the past.
6156 Object.freeze(nextProp);
6157 }
6158 }
6159
6160 if (lastProp) {
6161 // Unset styles on `lastProp` but not on `nextProp`.
6162 for (styleName in lastProp) {
6163 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
6164 if (!styleUpdates) {
6165 styleUpdates = {};
6166 }
6167
6168 styleUpdates[styleName] = '';
6169 }
6170 } // Update styles that changed since `lastProp`.
6171
6172
6173 for (styleName in nextProp) {
6174 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
6175 if (!styleUpdates) {
6176 styleUpdates = {};
6177 }
6178
6179 styleUpdates[styleName] = nextProp[styleName];
6180 }
6181 }
6182 } else {
6183 // Relies on `updateStylesByID` not mutating `styleUpdates`.
6184 if (!styleUpdates) {
6185 if (!updatePayload) {
6186 updatePayload = [];
6187 }
6188
6189 updatePayload.push(propKey, styleUpdates);
6190 }
6191
6192 styleUpdates = nextProp;
6193 }
6194 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
6195 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
6196 var lastHtml = lastProp ? lastProp[HTML$1] : undefined;
6197
6198 if (nextHtml != null) {
6199 if (lastHtml !== nextHtml) {
6200 (updatePayload = updatePayload || []).push(propKey, nextHtml);
6201 }
6202 }
6203 } else if (propKey === CHILDREN) {
6204 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
6205 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
6206 }
6207 } else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameModules.hasOwnProperty(propKey)) {
6208 if (nextProp != null) {
6209 // We eagerly listen to this even though we haven't committed yet.
6210 if ( typeof nextProp !== 'function') {
6211 warnForInvalidEventListener(propKey, nextProp);
6212 }
6213
6214 ensureListeningTo(rootContainerElement, propKey);
6215 }
6216
6217 if (!updatePayload && lastProp !== nextProp) {
6218 // This is a special case. If any listener updates we need to ensure
6219 // that the "current" props pointer gets updated so we need a commit
6220 // to update this element.
6221 updatePayload = [];
6222 }
6223 } else {
6224 // For any other property we always add it to the queue and then we
6225 // filter it out using the whitelist during the commit.
6226 (updatePayload = updatePayload || []).push(propKey, nextProp);
6227 }
6228 }
6229
6230 if (styleUpdates) {
6231 {
6232 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
6233 }
6234
6235 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
6236 }
6237
6238 return updatePayload;
6239} // Apply the diff.
6240
6241function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
6242 // Update checked *before* name.
6243 // In the middle of an update, it is possible to have multiple checked.
6244 // When a checked radio tries to change name, browser makes another radio's checked false.
6245 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
6246 updateChecked(domElement, nextRawProps);
6247 }
6248
6249 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
6250 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
6251
6252 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
6253 // changed.
6254
6255 switch (tag) {
6256 case 'input':
6257 // Update the wrapper around inputs *after* updating props. This has to
6258 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
6259 // raise warnings and prevent the new value from being assigned.
6260 updateWrapper(domElement, nextRawProps);
6261 break;
6262
6263 case 'textarea':
6264 updateWrapper$1(domElement, nextRawProps);
6265 break;
6266
6267 case 'select':
6268 // <select> value update needs to occur after <option> children
6269 // reconciliation
6270 postUpdateWrapper(domElement, nextRawProps);
6271 break;
6272 }
6273}
6274
6275function getPossibleStandardName(propName) {
6276 {
6277 var lowerCasedName = propName.toLowerCase();
6278
6279 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
6280 return null;
6281 }
6282
6283 return possibleStandardNames[lowerCasedName] || null;
6284 }
6285}
6286
6287function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
6288 var isCustomComponentTag;
6289 var extraAttributeNames;
6290
6291 {
6292 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true;
6293 isCustomComponentTag = isCustomComponent(tag, rawProps);
6294 validatePropertiesInDevelopment(tag, rawProps);
6295 } // TODO: Make sure that we check isMounted before firing any of these events.
6296
6297
6298 switch (tag) {
6299 case 'iframe':
6300 case 'object':
6301 case 'embed':
6302 trapBubbledEvent(TOP_LOAD, domElement);
6303 break;
6304
6305 case 'video':
6306 case 'audio':
6307 // Create listener for each media event
6308 for (var i = 0; i < mediaEventTypes.length; i++) {
6309 trapBubbledEvent(mediaEventTypes[i], domElement);
6310 }
6311
6312 break;
6313
6314 case 'source':
6315 trapBubbledEvent(TOP_ERROR, domElement);
6316 break;
6317
6318 case 'img':
6319 case 'image':
6320 case 'link':
6321 trapBubbledEvent(TOP_ERROR, domElement);
6322 trapBubbledEvent(TOP_LOAD, domElement);
6323 break;
6324
6325 case 'form':
6326 trapBubbledEvent(TOP_RESET, domElement);
6327 trapBubbledEvent(TOP_SUBMIT, domElement);
6328 break;
6329
6330 case 'details':
6331 trapBubbledEvent(TOP_TOGGLE, domElement);
6332 break;
6333
6334 case 'input':
6335 initWrapperState(domElement, rawProps);
6336 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6337 // to onChange. Even if there is no listener.
6338
6339 ensureListeningTo(rootContainerElement, 'onChange');
6340 break;
6341
6342 case 'option':
6343 validateProps(domElement, rawProps);
6344 break;
6345
6346 case 'select':
6347 initWrapperState$1(domElement, rawProps);
6348 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6349 // to onChange. Even if there is no listener.
6350
6351 ensureListeningTo(rootContainerElement, 'onChange');
6352 break;
6353
6354 case 'textarea':
6355 initWrapperState$2(domElement, rawProps);
6356 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6357 // to onChange. Even if there is no listener.
6358
6359 ensureListeningTo(rootContainerElement, 'onChange');
6360 break;
6361 }
6362
6363 assertValidProps(tag, rawProps);
6364
6365 {
6366 extraAttributeNames = new Set();
6367 var attributes = domElement.attributes;
6368
6369 for (var _i = 0; _i < attributes.length; _i++) {
6370 var name = attributes[_i].name.toLowerCase();
6371
6372 switch (name) {
6373 // Built-in SSR attribute is whitelisted
6374 case 'data-reactroot':
6375 break;
6376 // Controlled attributes are not validated
6377 // TODO: Only ignore them on controlled tags.
6378
6379 case 'value':
6380 break;
6381
6382 case 'checked':
6383 break;
6384
6385 case 'selected':
6386 break;
6387
6388 default:
6389 // Intentionally use the original name.
6390 // See discussion in https://github.com/facebook/react/pull/10676.
6391 extraAttributeNames.add(attributes[_i].name);
6392 }
6393 }
6394 }
6395
6396 var updatePayload = null;
6397
6398 for (var propKey in rawProps) {
6399 if (!rawProps.hasOwnProperty(propKey)) {
6400 continue;
6401 }
6402
6403 var nextProp = rawProps[propKey];
6404
6405 if (propKey === CHILDREN) {
6406 // For text content children we compare against textContent. This
6407 // might match additional HTML that is hidden when we read it using
6408 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
6409 // satisfies our requirement. Our requirement is not to produce perfect
6410 // HTML and attributes. Ideally we should preserve structure but it's
6411 // ok not to if the visible content is still enough to indicate what
6412 // even listeners these nodes might be wired up to.
6413 // TODO: Warn if there is more than a single textNode as a child.
6414 // TODO: Should we use domElement.firstChild.nodeValue to compare?
6415 if (typeof nextProp === 'string') {
6416 if (domElement.textContent !== nextProp) {
6417 if ( !suppressHydrationWarning) {
6418 warnForTextDifference(domElement.textContent, nextProp);
6419 }
6420
6421 updatePayload = [CHILDREN, nextProp];
6422 }
6423 } else if (typeof nextProp === 'number') {
6424 if (domElement.textContent !== '' + nextProp) {
6425 if ( !suppressHydrationWarning) {
6426 warnForTextDifference(domElement.textContent, nextProp);
6427 }
6428
6429 updatePayload = [CHILDREN, '' + nextProp];
6430 }
6431 }
6432 } else if (registrationNameModules.hasOwnProperty(propKey)) {
6433 if (nextProp != null) {
6434 if ( typeof nextProp !== 'function') {
6435 warnForInvalidEventListener(propKey, nextProp);
6436 }
6437
6438 ensureListeningTo(rootContainerElement, propKey);
6439 }
6440 } else if ( // Convince Flow we've calculated it (it's DEV-only in this method.)
6441 typeof isCustomComponentTag === 'boolean') {
6442 // Validate that the properties correspond to their expected values.
6443 var serverValue = void 0;
6444 var propertyInfo = getPropertyInfo(propKey);
6445
6446 if (suppressHydrationWarning) ; else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
6447 // TODO: Only ignore them on controlled tags.
6448 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
6449 var serverHTML = domElement.innerHTML;
6450 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
6451 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
6452
6453 if (expectedHTML !== serverHTML) {
6454 warnForPropDifference(propKey, serverHTML, expectedHTML);
6455 }
6456 } else if (propKey === STYLE) {
6457 // $FlowFixMe - Should be inferred as not undefined.
6458 extraAttributeNames.delete(propKey);
6459
6460 if (canDiffStyleForHydrationWarning) {
6461 var expectedStyle = createDangerousStringForStyles(nextProp);
6462 serverValue = domElement.getAttribute('style');
6463
6464 if (expectedStyle !== serverValue) {
6465 warnForPropDifference(propKey, serverValue, expectedStyle);
6466 }
6467 }
6468 } else if (isCustomComponentTag) {
6469 // $FlowFixMe - Should be inferred as not undefined.
6470 extraAttributeNames.delete(propKey.toLowerCase());
6471 serverValue = getValueForAttribute(domElement, propKey, nextProp);
6472
6473 if (nextProp !== serverValue) {
6474 warnForPropDifference(propKey, serverValue, nextProp);
6475 }
6476 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
6477 var isMismatchDueToBadCasing = false;
6478
6479 if (propertyInfo !== null) {
6480 // $FlowFixMe - Should be inferred as not undefined.
6481 extraAttributeNames.delete(propertyInfo.attributeName);
6482 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
6483 } else {
6484 var ownNamespace = parentNamespace;
6485
6486 if (ownNamespace === HTML_NAMESPACE$1) {
6487 ownNamespace = getIntrinsicNamespace(tag);
6488 }
6489
6490 if (ownNamespace === HTML_NAMESPACE$1) {
6491 // $FlowFixMe - Should be inferred as not undefined.
6492 extraAttributeNames.delete(propKey.toLowerCase());
6493 } else {
6494 var standardName = getPossibleStandardName(propKey);
6495
6496 if (standardName !== null && standardName !== propKey) {
6497 // If an SVG prop is supplied with bad casing, it will
6498 // be successfully parsed from HTML, but will produce a mismatch
6499 // (and would be incorrectly rendered on the client).
6500 // However, we already warn about bad casing elsewhere.
6501 // So we'll skip the misleading extra mismatch warning in this case.
6502 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
6503
6504 extraAttributeNames.delete(standardName);
6505 } // $FlowFixMe - Should be inferred as not undefined.
6506
6507
6508 extraAttributeNames.delete(propKey);
6509 }
6510
6511 serverValue = getValueForAttribute(domElement, propKey, nextProp);
6512 }
6513
6514 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
6515 warnForPropDifference(propKey, serverValue, nextProp);
6516 }
6517 }
6518 }
6519 }
6520
6521 {
6522 // $FlowFixMe - Should be inferred as not undefined.
6523 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
6524 // $FlowFixMe - Should be inferred as not undefined.
6525 warnForExtraAttributes(extraAttributeNames);
6526 }
6527 }
6528
6529 switch (tag) {
6530 case 'input':
6531 // TODO: Make sure we check if this is still unmounted or do any clean
6532 // up necessary since we never stop tracking anymore.
6533 track(domElement);
6534 postMountWrapper(domElement, rawProps, true);
6535 break;
6536
6537 case 'textarea':
6538 // TODO: Make sure we check if this is still unmounted or do any clean
6539 // up necessary since we never stop tracking anymore.
6540 track(domElement);
6541 postMountWrapper$3(domElement);
6542 break;
6543
6544 case 'select':
6545 case 'option':
6546 // For input and textarea we current always set the value property at
6547 // post mount to force it to diverge from attributes. However, for
6548 // option and select we don't quite do the same thing and select
6549 // is not resilient to the DOM state changing so we don't do that here.
6550 // TODO: Consider not doing this for input and textarea.
6551 break;
6552
6553 default:
6554 if (typeof rawProps.onClick === 'function') {
6555 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6556 trapClickOnNonInteractiveElement(domElement);
6557 }
6558
6559 break;
6560 }
6561
6562 return updatePayload;
6563}
6564function diffHydratedText(textNode, text) {
6565 var isDifferent = textNode.nodeValue !== text;
6566 return isDifferent;
6567}
6568function warnForUnmatchedText(textNode, text) {
6569 {
6570 warnForTextDifference(textNode.nodeValue, text);
6571 }
6572}
6573function warnForDeletedHydratableElement(parentNode, child) {
6574 {
6575 if (didWarnInvalidHydration) {
6576 return;
6577 }
6578
6579 didWarnInvalidHydration = true;
6580
6581 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
6582 }
6583}
6584function warnForDeletedHydratableText(parentNode, child) {
6585 {
6586 if (didWarnInvalidHydration) {
6587 return;
6588 }
6589
6590 didWarnInvalidHydration = true;
6591
6592 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
6593 }
6594}
6595function warnForInsertedHydratedElement(parentNode, tag, props) {
6596 {
6597 if (didWarnInvalidHydration) {
6598 return;
6599 }
6600
6601 didWarnInvalidHydration = true;
6602
6603 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
6604 }
6605}
6606function warnForInsertedHydratedText(parentNode, text) {
6607 {
6608 if (text === '') {
6609 // We expect to insert empty text nodes since they're not represented in
6610 // the HTML.
6611 // TODO: Remove this special case if we can just avoid inserting empty
6612 // text nodes.
6613 return;
6614 }
6615
6616 if (didWarnInvalidHydration) {
6617 return;
6618 }
6619
6620 didWarnInvalidHydration = true;
6621
6622 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
6623 }
6624}
6625function restoreControlledState$3(domElement, tag, props) {
6626 switch (tag) {
6627 case 'input':
6628 restoreControlledState(domElement, props);
6629 return;
6630
6631 case 'textarea':
6632 restoreControlledState$2(domElement, props);
6633 return;
6634
6635 case 'select':
6636 restoreControlledState$1(domElement, props);
6637 return;
6638 }
6639}
6640
6641function getActiveElement(doc) {
6642 doc = doc || (typeof document !== 'undefined' ? document : undefined);
6643
6644 if (typeof doc === 'undefined') {
6645 return null;
6646 }
6647
6648 try {
6649 return doc.activeElement || doc.body;
6650 } catch (e) {
6651 return doc.body;
6652 }
6653}
6654
6655/**
6656 * Given any node return the first leaf node without children.
6657 *
6658 * @param {DOMElement|DOMTextNode} node
6659 * @return {DOMElement|DOMTextNode}
6660 */
6661
6662function getLeafNode(node) {
6663 while (node && node.firstChild) {
6664 node = node.firstChild;
6665 }
6666
6667 return node;
6668}
6669/**
6670 * Get the next sibling within a container. This will walk up the
6671 * DOM if a node's siblings have been exhausted.
6672 *
6673 * @param {DOMElement|DOMTextNode} node
6674 * @return {?DOMElement|DOMTextNode}
6675 */
6676
6677
6678function getSiblingNode(node) {
6679 while (node) {
6680 if (node.nextSibling) {
6681 return node.nextSibling;
6682 }
6683
6684 node = node.parentNode;
6685 }
6686}
6687/**
6688 * Get object describing the nodes which contain characters at offset.
6689 *
6690 * @param {DOMElement|DOMTextNode} root
6691 * @param {number} offset
6692 * @return {?object}
6693 */
6694
6695
6696function getNodeForCharacterOffset(root, offset) {
6697 var node = getLeafNode(root);
6698 var nodeStart = 0;
6699 var nodeEnd = 0;
6700
6701 while (node) {
6702 if (node.nodeType === TEXT_NODE) {
6703 nodeEnd = nodeStart + node.textContent.length;
6704
6705 if (nodeStart <= offset && nodeEnd >= offset) {
6706 return {
6707 node: node,
6708 offset: offset - nodeStart
6709 };
6710 }
6711
6712 nodeStart = nodeEnd;
6713 }
6714
6715 node = getLeafNode(getSiblingNode(node));
6716 }
6717}
6718
6719/**
6720 * @param {DOMElement} outerNode
6721 * @return {?object}
6722 */
6723
6724function getOffsets(outerNode) {
6725 var ownerDocument = outerNode.ownerDocument;
6726 var win = ownerDocument && ownerDocument.defaultView || window;
6727 var selection = win.getSelection && win.getSelection();
6728
6729 if (!selection || selection.rangeCount === 0) {
6730 return null;
6731 }
6732
6733 var anchorNode = selection.anchorNode,
6734 anchorOffset = selection.anchorOffset,
6735 focusNode = selection.focusNode,
6736 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
6737 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
6738 // expose properties, triggering a "Permission denied error" if any of its
6739 // properties are accessed. The only seemingly possible way to avoid erroring
6740 // is to access a property that typically works for non-anonymous divs and
6741 // catch any error that may otherwise arise. See
6742 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
6743
6744 try {
6745 /* eslint-disable no-unused-expressions */
6746 anchorNode.nodeType;
6747 focusNode.nodeType;
6748 /* eslint-enable no-unused-expressions */
6749 } catch (e) {
6750 return null;
6751 }
6752
6753 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
6754}
6755/**
6756 * Returns {start, end} where `start` is the character/codepoint index of
6757 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
6758 * `end` is the index of (focusNode, focusOffset).
6759 *
6760 * Returns null if you pass in garbage input but we should probably just crash.
6761 *
6762 * Exported only for testing.
6763 */
6764
6765function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
6766 var length = 0;
6767 var start = -1;
6768 var end = -1;
6769 var indexWithinAnchor = 0;
6770 var indexWithinFocus = 0;
6771 var node = outerNode;
6772 var parentNode = null;
6773
6774 outer: while (true) {
6775 var next = null;
6776
6777 while (true) {
6778 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
6779 start = length + anchorOffset;
6780 }
6781
6782 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
6783 end = length + focusOffset;
6784 }
6785
6786 if (node.nodeType === TEXT_NODE) {
6787 length += node.nodeValue.length;
6788 }
6789
6790 if ((next = node.firstChild) === null) {
6791 break;
6792 } // Moving from `node` to its first child `next`.
6793
6794
6795 parentNode = node;
6796 node = next;
6797 }
6798
6799 while (true) {
6800 if (node === outerNode) {
6801 // If `outerNode` has children, this is always the second time visiting
6802 // it. If it has no children, this is still the first loop, and the only
6803 // valid selection is anchorNode and focusNode both equal to this node
6804 // and both offsets 0, in which case we will have handled above.
6805 break outer;
6806 }
6807
6808 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
6809 start = length;
6810 }
6811
6812 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
6813 end = length;
6814 }
6815
6816 if ((next = node.nextSibling) !== null) {
6817 break;
6818 }
6819
6820 node = parentNode;
6821 parentNode = node.parentNode;
6822 } // Moving from `node` to its next sibling `next`.
6823
6824
6825 node = next;
6826 }
6827
6828 if (start === -1 || end === -1) {
6829 // This should never happen. (Would happen if the anchor/focus nodes aren't
6830 // actually inside the passed-in node.)
6831 return null;
6832 }
6833
6834 return {
6835 start: start,
6836 end: end
6837 };
6838}
6839/**
6840 * In modern non-IE browsers, we can support both forward and backward
6841 * selections.
6842 *
6843 * Note: IE10+ supports the Selection object, but it does not support
6844 * the `extend` method, which means that even in modern IE, it's not possible
6845 * to programmatically create a backward selection. Thus, for all IE
6846 * versions, we use the old IE API to create our selections.
6847 *
6848 * @param {DOMElement|DOMTextNode} node
6849 * @param {object} offsets
6850 */
6851
6852function setOffsets(node, offsets) {
6853 var doc = node.ownerDocument || document;
6854 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
6855 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
6856 // fails when pasting 100+ items)
6857
6858 if (!win.getSelection) {
6859 return;
6860 }
6861
6862 var selection = win.getSelection();
6863 var length = node.textContent.length;
6864 var start = Math.min(offsets.start, length);
6865 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
6866 // Flip backward selections, so we can set with a single range.
6867
6868 if (!selection.extend && start > end) {
6869 var temp = end;
6870 end = start;
6871 start = temp;
6872 }
6873
6874 var startMarker = getNodeForCharacterOffset(node, start);
6875 var endMarker = getNodeForCharacterOffset(node, end);
6876
6877 if (startMarker && endMarker) {
6878 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
6879 return;
6880 }
6881
6882 var range = doc.createRange();
6883 range.setStart(startMarker.node, startMarker.offset);
6884 selection.removeAllRanges();
6885
6886 if (start > end) {
6887 selection.addRange(range);
6888 selection.extend(endMarker.node, endMarker.offset);
6889 } else {
6890 range.setEnd(endMarker.node, endMarker.offset);
6891 selection.addRange(range);
6892 }
6893 }
6894}
6895
6896function isTextNode(node) {
6897 return node && node.nodeType === TEXT_NODE;
6898}
6899
6900function containsNode(outerNode, innerNode) {
6901 if (!outerNode || !innerNode) {
6902 return false;
6903 } else if (outerNode === innerNode) {
6904 return true;
6905 } else if (isTextNode(outerNode)) {
6906 return false;
6907 } else if (isTextNode(innerNode)) {
6908 return containsNode(outerNode, innerNode.parentNode);
6909 } else if ('contains' in outerNode) {
6910 return outerNode.contains(innerNode);
6911 } else if (outerNode.compareDocumentPosition) {
6912 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
6913 } else {
6914 return false;
6915 }
6916}
6917
6918function isInDocument(node) {
6919 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
6920}
6921
6922function isSameOriginFrame(iframe) {
6923 try {
6924 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
6925 // to throw, e.g. if it has a cross-origin src attribute.
6926 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
6927 // iframe.contentDocument.defaultView;
6928 // A safety way is to access one of the cross origin properties: Window or Location
6929 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
6930 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
6931 return typeof iframe.contentWindow.location.href === 'string';
6932 } catch (err) {
6933 return false;
6934 }
6935}
6936
6937function getActiveElementDeep() {
6938 var win = window;
6939 var element = getActiveElement();
6940
6941 while (element instanceof win.HTMLIFrameElement) {
6942 if (isSameOriginFrame(element)) {
6943 win = element.contentWindow;
6944 } else {
6945 return element;
6946 }
6947
6948 element = getActiveElement(win.document);
6949 }
6950
6951 return element;
6952}
6953/**
6954 * @ReactInputSelection: React input selection module. Based on Selection.js,
6955 * but modified to be suitable for react and has a couple of bug fixes (doesn't
6956 * assume buttons have range selections allowed).
6957 * Input selection module for React.
6958 */
6959
6960/**
6961 * @hasSelectionCapabilities: we get the element types that support selection
6962 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
6963 * and `selectionEnd` rows.
6964 */
6965
6966
6967function hasSelectionCapabilities(elem) {
6968 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
6969 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
6970}
6971function getSelectionInformation() {
6972 var focusedElem = getActiveElementDeep();
6973 return {
6974 // Used by Flare
6975 activeElementDetached: null,
6976 focusedElem: focusedElem,
6977 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
6978 };
6979}
6980/**
6981 * @restoreSelection: If any selection information was potentially lost,
6982 * restore it. This is useful when performing operations that could remove dom
6983 * nodes and place them back in, resulting in focus being lost.
6984 */
6985
6986function restoreSelection(priorSelectionInformation) {
6987 var curFocusedElem = getActiveElementDeep();
6988 var priorFocusedElem = priorSelectionInformation.focusedElem;
6989 var priorSelectionRange = priorSelectionInformation.selectionRange;
6990
6991 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
6992 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
6993 setSelection(priorFocusedElem, priorSelectionRange);
6994 } // Focusing a node can change the scroll position, which is undesirable
6995
6996
6997 var ancestors = [];
6998 var ancestor = priorFocusedElem;
6999
7000 while (ancestor = ancestor.parentNode) {
7001 if (ancestor.nodeType === ELEMENT_NODE) {
7002 ancestors.push({
7003 element: ancestor,
7004 left: ancestor.scrollLeft,
7005 top: ancestor.scrollTop
7006 });
7007 }
7008 }
7009
7010 if (typeof priorFocusedElem.focus === 'function') {
7011 priorFocusedElem.focus();
7012 }
7013
7014 for (var i = 0; i < ancestors.length; i++) {
7015 var info = ancestors[i];
7016 info.element.scrollLeft = info.left;
7017 info.element.scrollTop = info.top;
7018 }
7019 }
7020}
7021/**
7022 * @getSelection: Gets the selection bounds of a focused textarea, input or
7023 * contentEditable node.
7024 * -@input: Look up selection bounds of this input
7025 * -@return {start: selectionStart, end: selectionEnd}
7026 */
7027
7028function getSelection(input) {
7029 var selection;
7030
7031 if ('selectionStart' in input) {
7032 // Modern browser with input or textarea.
7033 selection = {
7034 start: input.selectionStart,
7035 end: input.selectionEnd
7036 };
7037 } else {
7038 // Content editable or old IE textarea.
7039 selection = getOffsets(input);
7040 }
7041
7042 return selection || {
7043 start: 0,
7044 end: 0
7045 };
7046}
7047/**
7048 * @setSelection: Sets the selection bounds of a textarea or input and focuses
7049 * the input.
7050 * -@input Set selection bounds of this input or textarea
7051 * -@offsets Object of same form that is returned from get*
7052 */
7053
7054function setSelection(input, offsets) {
7055 var start = offsets.start,
7056 end = offsets.end;
7057
7058 if (end === undefined) {
7059 end = start;
7060 }
7061
7062 if ('selectionStart' in input) {
7063 input.selectionStart = start;
7064 input.selectionEnd = Math.min(end, input.value.length);
7065 } else {
7066 setOffsets(input, offsets);
7067 }
7068}
7069
7070var validateDOMNesting = function () {};
7071
7072var updatedAncestorInfo = function () {};
7073
7074{
7075 // This validation code was written based on the HTML5 parsing spec:
7076 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
7077 //
7078 // Note: this does not catch all invalid nesting, nor does it try to (as it's
7079 // not clear what practical benefit doing so provides); instead, we warn only
7080 // for cases where the parser will give a parse tree differing from what React
7081 // intended. For example, <b><div></div></b> is invalid but we don't warn
7082 // because it still parses correctly; we do warn for other cases like nested
7083 // <p> tags where the beginning of the second element implicitly closes the
7084 // first, causing a confusing mess.
7085 // https://html.spec.whatwg.org/multipage/syntax.html#special
7086 var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
7087
7088 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
7089 // TODO: Distinguish by namespace here -- for <title>, including it here
7090 // errs on the side of fewer warnings
7091 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
7092
7093 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
7094
7095 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
7096 var emptyAncestorInfo = {
7097 current: null,
7098 formTag: null,
7099 aTagInScope: null,
7100 buttonTagInScope: null,
7101 nobrTagInScope: null,
7102 pTagInButtonScope: null,
7103 listItemTagAutoclosing: null,
7104 dlItemTagAutoclosing: null
7105 };
7106
7107 updatedAncestorInfo = function (oldInfo, tag) {
7108 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
7109
7110 var info = {
7111 tag: tag
7112 };
7113
7114 if (inScopeTags.indexOf(tag) !== -1) {
7115 ancestorInfo.aTagInScope = null;
7116 ancestorInfo.buttonTagInScope = null;
7117 ancestorInfo.nobrTagInScope = null;
7118 }
7119
7120 if (buttonScopeTags.indexOf(tag) !== -1) {
7121 ancestorInfo.pTagInButtonScope = null;
7122 } // See rules for 'li', 'dd', 'dt' start tags in
7123 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
7124
7125
7126 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
7127 ancestorInfo.listItemTagAutoclosing = null;
7128 ancestorInfo.dlItemTagAutoclosing = null;
7129 }
7130
7131 ancestorInfo.current = info;
7132
7133 if (tag === 'form') {
7134 ancestorInfo.formTag = info;
7135 }
7136
7137 if (tag === 'a') {
7138 ancestorInfo.aTagInScope = info;
7139 }
7140
7141 if (tag === 'button') {
7142 ancestorInfo.buttonTagInScope = info;
7143 }
7144
7145 if (tag === 'nobr') {
7146 ancestorInfo.nobrTagInScope = info;
7147 }
7148
7149 if (tag === 'p') {
7150 ancestorInfo.pTagInButtonScope = info;
7151 }
7152
7153 if (tag === 'li') {
7154 ancestorInfo.listItemTagAutoclosing = info;
7155 }
7156
7157 if (tag === 'dd' || tag === 'dt') {
7158 ancestorInfo.dlItemTagAutoclosing = info;
7159 }
7160
7161 return ancestorInfo;
7162 };
7163 /**
7164 * Returns whether
7165 */
7166
7167
7168 var isTagValidWithParent = function (tag, parentTag) {
7169 // First, let's check if we're in an unusual parsing mode...
7170 switch (parentTag) {
7171 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
7172 case 'select':
7173 return tag === 'option' || tag === 'optgroup' || tag === '#text';
7174
7175 case 'optgroup':
7176 return tag === 'option' || tag === '#text';
7177 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
7178 // but
7179
7180 case 'option':
7181 return tag === '#text';
7182 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
7183 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
7184 // No special behavior since these rules fall back to "in body" mode for
7185 // all except special table nodes which cause bad parsing behavior anyway.
7186 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
7187
7188 case 'tr':
7189 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
7190 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
7191
7192 case 'tbody':
7193 case 'thead':
7194 case 'tfoot':
7195 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
7196 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
7197
7198 case 'colgroup':
7199 return tag === 'col' || tag === 'template';
7200 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
7201
7202 case 'table':
7203 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
7204 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
7205
7206 case 'head':
7207 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
7208 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
7209
7210 case 'html':
7211 return tag === 'head' || tag === 'body' || tag === 'frameset';
7212
7213 case 'frameset':
7214 return tag === 'frame';
7215
7216 case '#document':
7217 return tag === 'html';
7218 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
7219 // where the parsing rules cause implicit opens or closes to be added.
7220 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
7221
7222
7223 switch (tag) {
7224 case 'h1':
7225 case 'h2':
7226 case 'h3':
7227 case 'h4':
7228 case 'h5':
7229 case 'h6':
7230 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
7231
7232 case 'rp':
7233 case 'rt':
7234 return impliedEndTags.indexOf(parentTag) === -1;
7235
7236 case 'body':
7237 case 'caption':
7238 case 'col':
7239 case 'colgroup':
7240 case 'frameset':
7241 case 'frame':
7242 case 'head':
7243 case 'html':
7244 case 'tbody':
7245 case 'td':
7246 case 'tfoot':
7247 case 'th':
7248 case 'thead':
7249 case 'tr':
7250 // These tags are only valid with a few parents that have special child
7251 // parsing rules -- if we're down here, then none of those matched and
7252 // so we allow it only if we don't know what the parent is, as all other
7253 // cases are invalid.
7254 return parentTag == null;
7255 }
7256
7257 return true;
7258 };
7259 /**
7260 * Returns whether
7261 */
7262
7263
7264 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
7265 switch (tag) {
7266 case 'address':
7267 case 'article':
7268 case 'aside':
7269 case 'blockquote':
7270 case 'center':
7271 case 'details':
7272 case 'dialog':
7273 case 'dir':
7274 case 'div':
7275 case 'dl':
7276 case 'fieldset':
7277 case 'figcaption':
7278 case 'figure':
7279 case 'footer':
7280 case 'header':
7281 case 'hgroup':
7282 case 'main':
7283 case 'menu':
7284 case 'nav':
7285 case 'ol':
7286 case 'p':
7287 case 'section':
7288 case 'summary':
7289 case 'ul':
7290 case 'pre':
7291 case 'listing':
7292 case 'table':
7293 case 'hr':
7294 case 'xmp':
7295 case 'h1':
7296 case 'h2':
7297 case 'h3':
7298 case 'h4':
7299 case 'h5':
7300 case 'h6':
7301 return ancestorInfo.pTagInButtonScope;
7302
7303 case 'form':
7304 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
7305
7306 case 'li':
7307 return ancestorInfo.listItemTagAutoclosing;
7308
7309 case 'dd':
7310 case 'dt':
7311 return ancestorInfo.dlItemTagAutoclosing;
7312
7313 case 'button':
7314 return ancestorInfo.buttonTagInScope;
7315
7316 case 'a':
7317 // Spec says something about storing a list of markers, but it sounds
7318 // equivalent to this check.
7319 return ancestorInfo.aTagInScope;
7320
7321 case 'nobr':
7322 return ancestorInfo.nobrTagInScope;
7323 }
7324
7325 return null;
7326 };
7327
7328 var didWarn$1 = {};
7329
7330 validateDOMNesting = function (childTag, childText, ancestorInfo) {
7331 ancestorInfo = ancestorInfo || emptyAncestorInfo;
7332 var parentInfo = ancestorInfo.current;
7333 var parentTag = parentInfo && parentInfo.tag;
7334
7335 if (childText != null) {
7336 if (childTag != null) {
7337 error('validateDOMNesting: when childText is passed, childTag should be null');
7338 }
7339
7340 childTag = '#text';
7341 }
7342
7343 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
7344 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
7345 var invalidParentOrAncestor = invalidParent || invalidAncestor;
7346
7347 if (!invalidParentOrAncestor) {
7348 return;
7349 }
7350
7351 var ancestorTag = invalidParentOrAncestor.tag;
7352 var addendum = getCurrentFiberStackInDev();
7353 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
7354
7355 if (didWarn$1[warnKey]) {
7356 return;
7357 }
7358
7359 didWarn$1[warnKey] = true;
7360 var tagDisplayName = childTag;
7361 var whitespaceInfo = '';
7362
7363 if (childTag === '#text') {
7364 if (/\S/.test(childText)) {
7365 tagDisplayName = 'Text nodes';
7366 } else {
7367 tagDisplayName = 'Whitespace text nodes';
7368 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
7369 }
7370 } else {
7371 tagDisplayName = '<' + childTag + '>';
7372 }
7373
7374 if (invalidParent) {
7375 var info = '';
7376
7377 if (ancestorTag === 'table' && childTag === 'tr') {
7378 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
7379 }
7380
7381 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);
7382 } else {
7383 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);
7384 }
7385 };
7386}
7387
7388var SUPPRESS_HYDRATION_WARNING$1;
7389
7390{
7391 SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7392}
7393
7394var SUSPENSE_START_DATA = '$';
7395var SUSPENSE_END_DATA = '/$';
7396var SUSPENSE_PENDING_START_DATA = '$?';
7397var SUSPENSE_FALLBACK_START_DATA = '$!';
7398var STYLE$1 = 'style';
7399var eventsEnabled = null;
7400var selectionInformation = null;
7401
7402function shouldAutoFocusHostComponent(type, props) {
7403 switch (type) {
7404 case 'button':
7405 case 'input':
7406 case 'select':
7407 case 'textarea':
7408 return !!props.autoFocus;
7409 }
7410
7411 return false;
7412}
7413function getRootHostContext(rootContainerInstance) {
7414 var type;
7415 var namespace;
7416 var nodeType = rootContainerInstance.nodeType;
7417
7418 switch (nodeType) {
7419 case DOCUMENT_NODE:
7420 case DOCUMENT_FRAGMENT_NODE:
7421 {
7422 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
7423 var root = rootContainerInstance.documentElement;
7424 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
7425 break;
7426 }
7427
7428 default:
7429 {
7430 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
7431 var ownNamespace = container.namespaceURI || null;
7432 type = container.tagName;
7433 namespace = getChildNamespace(ownNamespace, type);
7434 break;
7435 }
7436 }
7437
7438 {
7439 var validatedTag = type.toLowerCase();
7440 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
7441 return {
7442 namespace: namespace,
7443 ancestorInfo: ancestorInfo
7444 };
7445 }
7446}
7447function getChildHostContext(parentHostContext, type, rootContainerInstance) {
7448 {
7449 var parentHostContextDev = parentHostContext;
7450 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
7451 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
7452 return {
7453 namespace: namespace,
7454 ancestorInfo: ancestorInfo
7455 };
7456 }
7457}
7458function getPublicInstance(instance) {
7459 return instance;
7460}
7461function prepareForCommit(containerInfo) {
7462 eventsEnabled = isEnabled();
7463 selectionInformation = getSelectionInformation();
7464 setEnabled(false);
7465}
7466function resetAfterCommit(containerInfo) {
7467 restoreSelection(selectionInformation);
7468 setEnabled(eventsEnabled);
7469 eventsEnabled = null;
7470
7471 selectionInformation = null;
7472}
7473function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
7474 var parentNamespace;
7475
7476 {
7477 // TODO: take namespace into account when validating.
7478 var hostContextDev = hostContext;
7479 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
7480
7481 if (typeof props.children === 'string' || typeof props.children === 'number') {
7482 var string = '' + props.children;
7483 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
7484 validateDOMNesting(null, string, ownAncestorInfo);
7485 }
7486
7487 parentNamespace = hostContextDev.namespace;
7488 }
7489
7490 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
7491 precacheFiberNode(internalInstanceHandle, domElement);
7492 updateFiberProps(domElement, props);
7493 return domElement;
7494}
7495function appendInitialChild(parentInstance, child) {
7496 parentInstance.appendChild(child);
7497}
7498function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
7499 setInitialProperties(domElement, type, props, rootContainerInstance);
7500 return shouldAutoFocusHostComponent(type, props);
7501}
7502function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
7503 {
7504 var hostContextDev = hostContext;
7505
7506 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
7507 var string = '' + newProps.children;
7508 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
7509 validateDOMNesting(null, string, ownAncestorInfo);
7510 }
7511 }
7512
7513 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
7514}
7515function shouldSetTextContent(type, props) {
7516 return type === 'textarea' || type === 'option' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
7517}
7518function shouldDeprioritizeSubtree(type, props) {
7519 return !!props.hidden;
7520}
7521function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
7522 {
7523 var hostContextDev = hostContext;
7524 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
7525 }
7526
7527 var textNode = createTextNode(text, rootContainerInstance);
7528 precacheFiberNode(internalInstanceHandle, textNode);
7529 return textNode;
7530}
7531// if a component just imports ReactDOM (e.g. for findDOMNode).
7532// Some environments might not have setTimeout or clearTimeout.
7533
7534var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
7535var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
7536var noTimeout = -1; // -------------------
7537function commitMount(domElement, type, newProps, internalInstanceHandle) {
7538 // Despite the naming that might imply otherwise, this method only
7539 // fires if there is an `Update` effect scheduled during mounting.
7540 // This happens if `finalizeInitialChildren` returns `true` (which it
7541 // does to implement the `autoFocus` attribute on the client). But
7542 // there are also other cases when this might happen (such as patching
7543 // up text content during hydration mismatch). So we'll check this again.
7544 if (shouldAutoFocusHostComponent(type, newProps)) {
7545 domElement.focus();
7546 }
7547}
7548function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
7549 // Update the props handle so that we know which props are the ones with
7550 // with current event handlers.
7551 updateFiberProps(domElement, newProps); // Apply the diff to the DOM node.
7552
7553 updateProperties(domElement, updatePayload, type, oldProps, newProps);
7554}
7555function resetTextContent(domElement) {
7556 setTextContent(domElement, '');
7557}
7558function commitTextUpdate(textInstance, oldText, newText) {
7559 textInstance.nodeValue = newText;
7560}
7561function appendChild(parentInstance, child) {
7562 parentInstance.appendChild(child);
7563}
7564function appendChildToContainer(container, child) {
7565 var parentNode;
7566
7567 if (container.nodeType === COMMENT_NODE) {
7568 parentNode = container.parentNode;
7569 parentNode.insertBefore(child, container);
7570 } else {
7571 parentNode = container;
7572 parentNode.appendChild(child);
7573 } // This container might be used for a portal.
7574 // If something inside a portal is clicked, that click should bubble
7575 // through the React tree. However, on Mobile Safari the click would
7576 // never bubble through the *DOM* tree unless an ancestor with onclick
7577 // event exists. So we wouldn't see it and dispatch it.
7578 // This is why we ensure that non React root containers have inline onclick
7579 // defined.
7580 // https://github.com/facebook/react/issues/11918
7581
7582
7583 var reactRootContainer = container._reactRootContainer;
7584
7585 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
7586 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7587 trapClickOnNonInteractiveElement(parentNode);
7588 }
7589}
7590function insertBefore(parentInstance, child, beforeChild) {
7591 parentInstance.insertBefore(child, beforeChild);
7592}
7593function insertInContainerBefore(container, child, beforeChild) {
7594 if (container.nodeType === COMMENT_NODE) {
7595 container.parentNode.insertBefore(child, beforeChild);
7596 } else {
7597 container.insertBefore(child, beforeChild);
7598 }
7599}
7600function removeChild(parentInstance, child) {
7601 parentInstance.removeChild(child);
7602}
7603function removeChildFromContainer(container, child) {
7604 if (container.nodeType === COMMENT_NODE) {
7605 container.parentNode.removeChild(child);
7606 } else {
7607 container.removeChild(child);
7608 }
7609}
7610
7611function hideInstance(instance) {
7612 // pass host context to this method?
7613
7614
7615 instance = instance;
7616 var style = instance.style;
7617
7618 if (typeof style.setProperty === 'function') {
7619 style.setProperty('display', 'none', 'important');
7620 } else {
7621 style.display = 'none';
7622 }
7623}
7624function hideTextInstance(textInstance) {
7625 textInstance.nodeValue = '';
7626}
7627function unhideInstance(instance, props) {
7628 instance = instance;
7629 var styleProp = props[STYLE$1];
7630 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
7631 instance.style.display = dangerousStyleValue('display', display);
7632}
7633function unhideTextInstance(textInstance, text) {
7634 textInstance.nodeValue = text;
7635} // -------------------
7636function canHydrateInstance(instance, type, props) {
7637 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
7638 return null;
7639 } // This has now been refined to an element node.
7640
7641
7642 return instance;
7643}
7644function canHydrateTextInstance(instance, text) {
7645 if (text === '' || instance.nodeType !== TEXT_NODE) {
7646 // Empty strings are not parsed by HTML so there won't be a correct match here.
7647 return null;
7648 } // This has now been refined to a text node.
7649
7650
7651 return instance;
7652}
7653function isSuspenseInstancePending(instance) {
7654 return instance.data === SUSPENSE_PENDING_START_DATA;
7655}
7656function isSuspenseInstanceFallback(instance) {
7657 return instance.data === SUSPENSE_FALLBACK_START_DATA;
7658}
7659
7660function getNextHydratable(node) {
7661 // Skip non-hydratable nodes.
7662 for (; node != null; node = node.nextSibling) {
7663 var nodeType = node.nodeType;
7664
7665 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
7666 break;
7667 }
7668 }
7669
7670 return node;
7671}
7672
7673function getNextHydratableSibling(instance) {
7674 return getNextHydratable(instance.nextSibling);
7675}
7676function getFirstHydratableChild(parentInstance) {
7677 return getNextHydratable(parentInstance.firstChild);
7678}
7679function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
7680 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
7681 // get attached.
7682
7683 updateFiberProps(instance, props);
7684 var parentNamespace;
7685
7686 {
7687 var hostContextDev = hostContext;
7688 parentNamespace = hostContextDev.namespace;
7689 }
7690
7691 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
7692}
7693function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
7694 precacheFiberNode(internalInstanceHandle, textInstance);
7695 return diffHydratedText(textInstance, text);
7696}
7697function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
7698 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
7699 // There might be nested nodes so we need to keep track of how
7700 // deep we are and only break out when we're back on top.
7701
7702 var depth = 0;
7703
7704 while (node) {
7705 if (node.nodeType === COMMENT_NODE) {
7706 var data = node.data;
7707
7708 if (data === SUSPENSE_END_DATA) {
7709 if (depth === 0) {
7710 return getNextHydratableSibling(node);
7711 } else {
7712 depth--;
7713 }
7714 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
7715 depth++;
7716 }
7717 }
7718
7719 node = node.nextSibling;
7720 } // TODO: Warn, we didn't find the end comment boundary.
7721
7722
7723 return null;
7724} // Returns the SuspenseInstance if this node is a direct child of a
7725// SuspenseInstance. I.e. if its previous sibling is a Comment with
7726// SUSPENSE_x_START_DATA. Otherwise, null.
7727
7728function getParentSuspenseInstance(targetInstance) {
7729 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
7730 // There might be nested nodes so we need to keep track of how
7731 // deep we are and only break out when we're back on top.
7732
7733 var depth = 0;
7734
7735 while (node) {
7736 if (node.nodeType === COMMENT_NODE) {
7737 var data = node.data;
7738
7739 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
7740 if (depth === 0) {
7741 return node;
7742 } else {
7743 depth--;
7744 }
7745 } else if (data === SUSPENSE_END_DATA) {
7746 depth++;
7747 }
7748 }
7749
7750 node = node.previousSibling;
7751 }
7752
7753 return null;
7754}
7755function commitHydratedContainer(container) {
7756 // Retry if any event replaying was blocked on this.
7757 retryIfBlockedOn(container);
7758}
7759function commitHydratedSuspenseInstance(suspenseInstance) {
7760 // Retry if any event replaying was blocked on this.
7761 retryIfBlockedOn(suspenseInstance);
7762}
7763function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
7764 {
7765 warnForUnmatchedText(textInstance, text);
7766 }
7767}
7768function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
7769 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7770 warnForUnmatchedText(textInstance, text);
7771 }
7772}
7773function didNotHydrateContainerInstance(parentContainer, instance) {
7774 {
7775 if (instance.nodeType === ELEMENT_NODE) {
7776 warnForDeletedHydratableElement(parentContainer, instance);
7777 } else if (instance.nodeType === COMMENT_NODE) ; else {
7778 warnForDeletedHydratableText(parentContainer, instance);
7779 }
7780 }
7781}
7782function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
7783 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7784 if (instance.nodeType === ELEMENT_NODE) {
7785 warnForDeletedHydratableElement(parentInstance, instance);
7786 } else if (instance.nodeType === COMMENT_NODE) ; else {
7787 warnForDeletedHydratableText(parentInstance, instance);
7788 }
7789 }
7790}
7791function didNotFindHydratableContainerInstance(parentContainer, type, props) {
7792 {
7793 warnForInsertedHydratedElement(parentContainer, type);
7794 }
7795}
7796function didNotFindHydratableContainerTextInstance(parentContainer, text) {
7797 {
7798 warnForInsertedHydratedText(parentContainer, text);
7799 }
7800}
7801function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
7802 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7803 warnForInsertedHydratedElement(parentInstance, type);
7804 }
7805}
7806function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
7807 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7808 warnForInsertedHydratedText(parentInstance, text);
7809 }
7810}
7811function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
7812 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) ;
7813}
7814
7815var randomKey = Math.random().toString(36).slice(2);
7816var internalInstanceKey = '__reactInternalInstance$' + randomKey;
7817var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
7818var internalContainerInstanceKey = '__reactContainere$' + randomKey;
7819function precacheFiberNode(hostInst, node) {
7820 node[internalInstanceKey] = hostInst;
7821}
7822function markContainerAsRoot(hostRoot, node) {
7823 node[internalContainerInstanceKey] = hostRoot;
7824}
7825function unmarkContainerAsRoot(node) {
7826 node[internalContainerInstanceKey] = null;
7827}
7828function isContainerMarkedAsRoot(node) {
7829 return !!node[internalContainerInstanceKey];
7830} // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
7831// If the target node is part of a hydrated or not yet rendered subtree, then
7832// this may also return a SuspenseComponent or HostRoot to indicate that.
7833// Conceptually the HostRoot fiber is a child of the Container node. So if you
7834// pass the Container node as the targetNode, you will not actually get the
7835// HostRoot back. To get to the HostRoot, you need to pass a child of it.
7836// The same thing applies to Suspense boundaries.
7837
7838function getClosestInstanceFromNode(targetNode) {
7839 var targetInst = targetNode[internalInstanceKey];
7840
7841 if (targetInst) {
7842 // Don't return HostRoot or SuspenseComponent here.
7843 return targetInst;
7844 } // If the direct event target isn't a React owned DOM node, we need to look
7845 // to see if one of its parents is a React owned DOM node.
7846
7847
7848 var parentNode = targetNode.parentNode;
7849
7850 while (parentNode) {
7851 // We'll check if this is a container root that could include
7852 // React nodes in the future. We need to check this first because
7853 // if we're a child of a dehydrated container, we need to first
7854 // find that inner container before moving on to finding the parent
7855 // instance. Note that we don't check this field on the targetNode
7856 // itself because the fibers are conceptually between the container
7857 // node and the first child. It isn't surrounding the container node.
7858 // If it's not a container, we check if it's an instance.
7859 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
7860
7861 if (targetInst) {
7862 // Since this wasn't the direct target of the event, we might have
7863 // stepped past dehydrated DOM nodes to get here. However they could
7864 // also have been non-React nodes. We need to answer which one.
7865 // If we the instance doesn't have any children, then there can't be
7866 // a nested suspense boundary within it. So we can use this as a fast
7867 // bailout. Most of the time, when people add non-React children to
7868 // the tree, it is using a ref to a child-less DOM node.
7869 // Normally we'd only need to check one of the fibers because if it
7870 // has ever gone from having children to deleting them or vice versa
7871 // it would have deleted the dehydrated boundary nested inside already.
7872 // However, since the HostRoot starts out with an alternate it might
7873 // have one on the alternate so we need to check in case this was a
7874 // root.
7875 var alternate = targetInst.alternate;
7876
7877 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
7878 // Next we need to figure out if the node that skipped past is
7879 // nested within a dehydrated boundary and if so, which one.
7880 var suspenseInstance = getParentSuspenseInstance(targetNode);
7881
7882 while (suspenseInstance !== null) {
7883 // We found a suspense instance. That means that we haven't
7884 // hydrated it yet. Even though we leave the comments in the
7885 // DOM after hydrating, and there are boundaries in the DOM
7886 // that could already be hydrated, we wouldn't have found them
7887 // through this pass since if the target is hydrated it would
7888 // have had an internalInstanceKey on it.
7889 // Let's get the fiber associated with the SuspenseComponent
7890 // as the deepest instance.
7891 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
7892
7893 if (targetSuspenseInst) {
7894 return targetSuspenseInst;
7895 } // If we don't find a Fiber on the comment, it might be because
7896 // we haven't gotten to hydrate it yet. There might still be a
7897 // parent boundary that hasn't above this one so we need to find
7898 // the outer most that is known.
7899
7900
7901 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
7902 // host component also hasn't hydrated yet. We can return it
7903 // below since it will bail out on the isMounted check later.
7904 }
7905 }
7906
7907 return targetInst;
7908 }
7909
7910 targetNode = parentNode;
7911 parentNode = targetNode.parentNode;
7912 }
7913
7914 return null;
7915}
7916/**
7917 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
7918 * instance, or null if the node was not rendered by this React.
7919 */
7920
7921function getInstanceFromNode$1(node) {
7922 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
7923
7924 if (inst) {
7925 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
7926 return inst;
7927 } else {
7928 return null;
7929 }
7930 }
7931
7932 return null;
7933}
7934/**
7935 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
7936 * DOM node.
7937 */
7938
7939function getNodeFromInstance$1(inst) {
7940 if (inst.tag === HostComponent || inst.tag === HostText) {
7941 // In Fiber this, is just the state node right now. We assume it will be
7942 // a host component or host text.
7943 return inst.stateNode;
7944 } // Without this first invariant, passing a non-DOM-component triggers the next
7945 // invariant for a missing parent, which is super confusing.
7946
7947
7948 {
7949 {
7950 throw Error( "getNodeFromInstance: Invalid argument." );
7951 }
7952 }
7953}
7954function getFiberCurrentPropsFromNode$1(node) {
7955 return node[internalEventHandlersKey] || null;
7956}
7957function updateFiberProps(node, props) {
7958 node[internalEventHandlersKey] = props;
7959}
7960
7961function getParent(inst) {
7962 do {
7963 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
7964 // That is depending on if we want nested subtrees (layers) to bubble
7965 // events to their parent. We could also go through parentNode on the
7966 // host node but that wouldn't work for React Native and doesn't let us
7967 // do the portal feature.
7968 } while (inst && inst.tag !== HostComponent);
7969
7970 if (inst) {
7971 return inst;
7972 }
7973
7974 return null;
7975}
7976/**
7977 * Return the lowest common ancestor of A and B, or null if they are in
7978 * different trees.
7979 */
7980
7981
7982function getLowestCommonAncestor(instA, instB) {
7983 var depthA = 0;
7984
7985 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
7986 depthA++;
7987 }
7988
7989 var depthB = 0;
7990
7991 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
7992 depthB++;
7993 } // If A is deeper, crawl up.
7994
7995
7996 while (depthA - depthB > 0) {
7997 instA = getParent(instA);
7998 depthA--;
7999 } // If B is deeper, crawl up.
8000
8001
8002 while (depthB - depthA > 0) {
8003 instB = getParent(instB);
8004 depthB--;
8005 } // Walk in lockstep until we find a match.
8006
8007
8008 var depth = depthA;
8009
8010 while (depth--) {
8011 if (instA === instB || instA === instB.alternate) {
8012 return instA;
8013 }
8014
8015 instA = getParent(instA);
8016 instB = getParent(instB);
8017 }
8018
8019 return null;
8020}
8021/**
8022 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
8023 */
8024
8025function traverseTwoPhase(inst, fn, arg) {
8026 var path = [];
8027
8028 while (inst) {
8029 path.push(inst);
8030 inst = getParent(inst);
8031 }
8032
8033 var i;
8034
8035 for (i = path.length; i-- > 0;) {
8036 fn(path[i], 'captured', arg);
8037 }
8038
8039 for (i = 0; i < path.length; i++) {
8040 fn(path[i], 'bubbled', arg);
8041 }
8042}
8043/**
8044 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
8045 * should would receive a `mouseEnter` or `mouseLeave` event.
8046 *
8047 * Does not invoke the callback on the nearest common ancestor because nothing
8048 * "entered" or "left" that element.
8049 */
8050
8051function traverseEnterLeave(from, to, fn, argFrom, argTo) {
8052 var common = from && to ? getLowestCommonAncestor(from, to) : null;
8053 var pathFrom = [];
8054
8055 while (true) {
8056 if (!from) {
8057 break;
8058 }
8059
8060 if (from === common) {
8061 break;
8062 }
8063
8064 var alternate = from.alternate;
8065
8066 if (alternate !== null && alternate === common) {
8067 break;
8068 }
8069
8070 pathFrom.push(from);
8071 from = getParent(from);
8072 }
8073
8074 var pathTo = [];
8075
8076 while (true) {
8077 if (!to) {
8078 break;
8079 }
8080
8081 if (to === common) {
8082 break;
8083 }
8084
8085 var _alternate = to.alternate;
8086
8087 if (_alternate !== null && _alternate === common) {
8088 break;
8089 }
8090
8091 pathTo.push(to);
8092 to = getParent(to);
8093 }
8094
8095 for (var i = 0; i < pathFrom.length; i++) {
8096 fn(pathFrom[i], 'bubbled', argFrom);
8097 }
8098
8099 for (var _i = pathTo.length; _i-- > 0;) {
8100 fn(pathTo[_i], 'captured', argTo);
8101 }
8102}
8103
8104function isInteractive(tag) {
8105 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
8106}
8107
8108function shouldPreventMouseEvent(name, type, props) {
8109 switch (name) {
8110 case 'onClick':
8111 case 'onClickCapture':
8112 case 'onDoubleClick':
8113 case 'onDoubleClickCapture':
8114 case 'onMouseDown':
8115 case 'onMouseDownCapture':
8116 case 'onMouseMove':
8117 case 'onMouseMoveCapture':
8118 case 'onMouseUp':
8119 case 'onMouseUpCapture':
8120 case 'onMouseEnter':
8121 return !!(props.disabled && isInteractive(type));
8122
8123 default:
8124 return false;
8125 }
8126}
8127/**
8128 * @param {object} inst The instance, which is the source of events.
8129 * @param {string} registrationName Name of listener (e.g. `onClick`).
8130 * @return {?function} The stored callback.
8131 */
8132
8133
8134function getListener(inst, registrationName) {
8135 var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
8136 // live here; needs to be moved to a better place soon
8137
8138 var stateNode = inst.stateNode;
8139
8140 if (!stateNode) {
8141 // Work in progress (ex: onload events in incremental mode).
8142 return null;
8143 }
8144
8145 var props = getFiberCurrentPropsFromNode(stateNode);
8146
8147 if (!props) {
8148 // Work in progress.
8149 return null;
8150 }
8151
8152 listener = props[registrationName];
8153
8154 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
8155 return null;
8156 }
8157
8158 if (!(!listener || typeof listener === 'function')) {
8159 {
8160 throw Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type." );
8161 }
8162 }
8163
8164 return listener;
8165}
8166
8167/**
8168 * Some event types have a notion of different registration names for different
8169 * "phases" of propagation. This finds listeners by a given phase.
8170 */
8171function listenerAtPhase(inst, event, propagationPhase) {
8172 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
8173 return getListener(inst, registrationName);
8174}
8175/**
8176 * A small set of propagation patterns, each of which will accept a small amount
8177 * of information, and generate a set of "dispatch ready event objects" - which
8178 * are sets of events that have already been annotated with a set of dispatched
8179 * listener functions/ids. The API is designed this way to discourage these
8180 * propagation strategies from actually executing the dispatches, since we
8181 * always want to collect the entire set of dispatches before executing even a
8182 * single one.
8183 */
8184
8185/**
8186 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
8187 * here, allows us to not have to bind or create functions for each event.
8188 * Mutating the event's members allows us to not have to create a wrapping
8189 * "dispatch" object that pairs the event with the listener.
8190 */
8191
8192
8193function accumulateDirectionalDispatches(inst, phase, event) {
8194 {
8195 if (!inst) {
8196 error('Dispatching inst must not be null');
8197 }
8198 }
8199
8200 var listener = listenerAtPhase(inst, event, phase);
8201
8202 if (listener) {
8203 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
8204 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
8205 }
8206}
8207/**
8208 * Collect dispatches (must be entirely collected before dispatching - see unit
8209 * tests). Lazily allocate the array to conserve memory. We must loop through
8210 * each event and perform the traversal for each one. We cannot perform a
8211 * single traversal for the entire collection of events because each event may
8212 * have a different target.
8213 */
8214
8215
8216function accumulateTwoPhaseDispatchesSingle(event) {
8217 if (event && event.dispatchConfig.phasedRegistrationNames) {
8218 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
8219 }
8220}
8221/**
8222 * Accumulates without regard to direction, does not look for phased
8223 * registration names. Same as `accumulateDirectDispatchesSingle` but without
8224 * requiring that the `dispatchMarker` be the same as the dispatched ID.
8225 */
8226
8227
8228function accumulateDispatches(inst, ignoredDirection, event) {
8229 if (inst && event && event.dispatchConfig.registrationName) {
8230 var registrationName = event.dispatchConfig.registrationName;
8231 var listener = getListener(inst, registrationName);
8232
8233 if (listener) {
8234 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
8235 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
8236 }
8237 }
8238}
8239/**
8240 * Accumulates dispatches on an `SyntheticEvent`, but only for the
8241 * `dispatchMarker`.
8242 * @param {SyntheticEvent} event
8243 */
8244
8245
8246function accumulateDirectDispatchesSingle(event) {
8247 if (event && event.dispatchConfig.registrationName) {
8248 accumulateDispatches(event._targetInst, null, event);
8249 }
8250}
8251
8252function accumulateTwoPhaseDispatches(events) {
8253 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
8254}
8255function accumulateEnterLeaveDispatches(leave, enter, from, to) {
8256 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
8257}
8258function accumulateDirectDispatches(events) {
8259 forEachAccumulated(events, accumulateDirectDispatchesSingle);
8260}
8261
8262/**
8263 * These variables store information about text content of a target node,
8264 * allowing comparison of content before and after a given event.
8265 *
8266 * Identify the node where selection currently begins, then observe
8267 * both its text content and its current position in the DOM. Since the
8268 * browser may natively replace the target node during composition, we can
8269 * use its position to find its replacement.
8270 *
8271 *
8272 */
8273var root = null;
8274var startText = null;
8275var fallbackText = null;
8276function initialize(nativeEventTarget) {
8277 root = nativeEventTarget;
8278 startText = getText();
8279 return true;
8280}
8281function reset() {
8282 root = null;
8283 startText = null;
8284 fallbackText = null;
8285}
8286function getData() {
8287 if (fallbackText) {
8288 return fallbackText;
8289 }
8290
8291 var start;
8292 var startValue = startText;
8293 var startLength = startValue.length;
8294 var end;
8295 var endValue = getText();
8296 var endLength = endValue.length;
8297
8298 for (start = 0; start < startLength; start++) {
8299 if (startValue[start] !== endValue[start]) {
8300 break;
8301 }
8302 }
8303
8304 var minEnd = startLength - start;
8305
8306 for (end = 1; end <= minEnd; end++) {
8307 if (startValue[startLength - end] !== endValue[endLength - end]) {
8308 break;
8309 }
8310 }
8311
8312 var sliceTail = end > 1 ? 1 - end : undefined;
8313 fallbackText = endValue.slice(start, sliceTail);
8314 return fallbackText;
8315}
8316function getText() {
8317 if ('value' in root) {
8318 return root.value;
8319 }
8320
8321 return root.textContent;
8322}
8323
8324var EVENT_POOL_SIZE = 10;
8325/**
8326 * @interface Event
8327 * @see http://www.w3.org/TR/DOM-Level-3-Events/
8328 */
8329
8330var EventInterface = {
8331 type: null,
8332 target: null,
8333 // currentTarget is set when dispatching; no use in copying it here
8334 currentTarget: function () {
8335 return null;
8336 },
8337 eventPhase: null,
8338 bubbles: null,
8339 cancelable: null,
8340 timeStamp: function (event) {
8341 return event.timeStamp || Date.now();
8342 },
8343 defaultPrevented: null,
8344 isTrusted: null
8345};
8346
8347function functionThatReturnsTrue() {
8348 return true;
8349}
8350
8351function functionThatReturnsFalse() {
8352 return false;
8353}
8354/**
8355 * Synthetic events are dispatched by event plugins, typically in response to a
8356 * top-level event delegation handler.
8357 *
8358 * These systems should generally use pooling to reduce the frequency of garbage
8359 * collection. The system should check `isPersistent` to determine whether the
8360 * event should be released into the pool after being dispatched. Users that
8361 * need a persisted event should invoke `persist`.
8362 *
8363 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
8364 * normalizing browser quirks. Subclasses do not necessarily have to implement a
8365 * DOM interface; custom application-specific events can also subclass this.
8366 *
8367 * @param {object} dispatchConfig Configuration used to dispatch this event.
8368 * @param {*} targetInst Marker identifying the event target.
8369 * @param {object} nativeEvent Native browser event.
8370 * @param {DOMEventTarget} nativeEventTarget Target node.
8371 */
8372
8373
8374function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
8375 {
8376 // these have a getter/setter for warnings
8377 delete this.nativeEvent;
8378 delete this.preventDefault;
8379 delete this.stopPropagation;
8380 delete this.isDefaultPrevented;
8381 delete this.isPropagationStopped;
8382 }
8383
8384 this.dispatchConfig = dispatchConfig;
8385 this._targetInst = targetInst;
8386 this.nativeEvent = nativeEvent;
8387 var Interface = this.constructor.Interface;
8388
8389 for (var propName in Interface) {
8390 if (!Interface.hasOwnProperty(propName)) {
8391 continue;
8392 }
8393
8394 {
8395 delete this[propName]; // this has a getter/setter for warnings
8396 }
8397
8398 var normalize = Interface[propName];
8399
8400 if (normalize) {
8401 this[propName] = normalize(nativeEvent);
8402 } else {
8403 if (propName === 'target') {
8404 this.target = nativeEventTarget;
8405 } else {
8406 this[propName] = nativeEvent[propName];
8407 }
8408 }
8409 }
8410
8411 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
8412
8413 if (defaultPrevented) {
8414 this.isDefaultPrevented = functionThatReturnsTrue;
8415 } else {
8416 this.isDefaultPrevented = functionThatReturnsFalse;
8417 }
8418
8419 this.isPropagationStopped = functionThatReturnsFalse;
8420 return this;
8421}
8422
8423_assign(SyntheticEvent.prototype, {
8424 preventDefault: function () {
8425 this.defaultPrevented = true;
8426 var event = this.nativeEvent;
8427
8428 if (!event) {
8429 return;
8430 }
8431
8432 if (event.preventDefault) {
8433 event.preventDefault();
8434 } else if (typeof event.returnValue !== 'unknown') {
8435 event.returnValue = false;
8436 }
8437
8438 this.isDefaultPrevented = functionThatReturnsTrue;
8439 },
8440 stopPropagation: function () {
8441 var event = this.nativeEvent;
8442
8443 if (!event) {
8444 return;
8445 }
8446
8447 if (event.stopPropagation) {
8448 event.stopPropagation();
8449 } else if (typeof event.cancelBubble !== 'unknown') {
8450 // The ChangeEventPlugin registers a "propertychange" event for
8451 // IE. This event does not support bubbling or cancelling, and
8452 // any references to cancelBubble throw "Member not found". A
8453 // typeof check of "unknown" circumvents this issue (and is also
8454 // IE specific).
8455 event.cancelBubble = true;
8456 }
8457
8458 this.isPropagationStopped = functionThatReturnsTrue;
8459 },
8460
8461 /**
8462 * We release all dispatched `SyntheticEvent`s after each event loop, adding
8463 * them back into the pool. This allows a way to hold onto a reference that
8464 * won't be added back into the pool.
8465 */
8466 persist: function () {
8467 this.isPersistent = functionThatReturnsTrue;
8468 },
8469
8470 /**
8471 * Checks if this event should be released back into the pool.
8472 *
8473 * @return {boolean} True if this should not be released, false otherwise.
8474 */
8475 isPersistent: functionThatReturnsFalse,
8476
8477 /**
8478 * `PooledClass` looks for `destructor` on each instance it releases.
8479 */
8480 destructor: function () {
8481 var Interface = this.constructor.Interface;
8482
8483 for (var propName in Interface) {
8484 {
8485 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
8486 }
8487 }
8488
8489 this.dispatchConfig = null;
8490 this._targetInst = null;
8491 this.nativeEvent = null;
8492 this.isDefaultPrevented = functionThatReturnsFalse;
8493 this.isPropagationStopped = functionThatReturnsFalse;
8494 this._dispatchListeners = null;
8495 this._dispatchInstances = null;
8496
8497 {
8498 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
8499 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
8500 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
8501 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
8502 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
8503 }
8504 }
8505});
8506
8507SyntheticEvent.Interface = EventInterface;
8508/**
8509 * Helper to reduce boilerplate when creating subclasses.
8510 */
8511
8512SyntheticEvent.extend = function (Interface) {
8513 var Super = this;
8514
8515 var E = function () {};
8516
8517 E.prototype = Super.prototype;
8518 var prototype = new E();
8519
8520 function Class() {
8521 return Super.apply(this, arguments);
8522 }
8523
8524 _assign(prototype, Class.prototype);
8525
8526 Class.prototype = prototype;
8527 Class.prototype.constructor = Class;
8528 Class.Interface = _assign({}, Super.Interface, Interface);
8529 Class.extend = Super.extend;
8530 addEventPoolingTo(Class);
8531 return Class;
8532};
8533
8534addEventPoolingTo(SyntheticEvent);
8535/**
8536 * Helper to nullify syntheticEvent instance properties when destructing
8537 *
8538 * @param {String} propName
8539 * @param {?object} getVal
8540 * @return {object} defineProperty object
8541 */
8542
8543function getPooledWarningPropertyDefinition(propName, getVal) {
8544 var isFunction = typeof getVal === 'function';
8545 return {
8546 configurable: true,
8547 set: set,
8548 get: get
8549 };
8550
8551 function set(val) {
8552 var action = isFunction ? 'setting the method' : 'setting the property';
8553 warn(action, 'This is effectively a no-op');
8554 return val;
8555 }
8556
8557 function get() {
8558 var action = isFunction ? 'accessing the method' : 'accessing the property';
8559 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
8560 warn(action, result);
8561 return getVal;
8562 }
8563
8564 function warn(action, result) {
8565 {
8566 error("This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result);
8567 }
8568 }
8569}
8570
8571function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
8572 var EventConstructor = this;
8573
8574 if (EventConstructor.eventPool.length) {
8575 var instance = EventConstructor.eventPool.pop();
8576 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
8577 return instance;
8578 }
8579
8580 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
8581}
8582
8583function releasePooledEvent(event) {
8584 var EventConstructor = this;
8585
8586 if (!(event instanceof EventConstructor)) {
8587 {
8588 throw Error( "Trying to release an event instance into a pool of a different type." );
8589 }
8590 }
8591
8592 event.destructor();
8593
8594 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
8595 EventConstructor.eventPool.push(event);
8596 }
8597}
8598
8599function addEventPoolingTo(EventConstructor) {
8600 EventConstructor.eventPool = [];
8601 EventConstructor.getPooled = getPooledEvent;
8602 EventConstructor.release = releasePooledEvent;
8603}
8604
8605/**
8606 * @interface Event
8607 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
8608 */
8609
8610var SyntheticCompositionEvent = SyntheticEvent.extend({
8611 data: null
8612});
8613
8614/**
8615 * @interface Event
8616 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
8617 * /#events-inputevents
8618 */
8619
8620var SyntheticInputEvent = SyntheticEvent.extend({
8621 data: null
8622});
8623
8624var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
8625
8626var START_KEYCODE = 229;
8627var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
8628var documentMode = null;
8629
8630if (canUseDOM && 'documentMode' in document) {
8631 documentMode = document.documentMode;
8632} // Webkit offers a very useful `textInput` event that can be used to
8633// directly represent `beforeInput`. The IE `textinput` event is not as
8634// useful, so we don't use it.
8635
8636
8637var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
8638// by the native compositionend event may be incorrect. Japanese ideographic
8639// spaces, for instance (\u3000) are not recorded correctly.
8640
8641var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
8642var SPACEBAR_CODE = 32;
8643var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); // Events and their corresponding property names.
8644
8645var eventTypes = {
8646 beforeInput: {
8647 phasedRegistrationNames: {
8648 bubbled: 'onBeforeInput',
8649 captured: 'onBeforeInputCapture'
8650 },
8651 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
8652 },
8653 compositionEnd: {
8654 phasedRegistrationNames: {
8655 bubbled: 'onCompositionEnd',
8656 captured: 'onCompositionEndCapture'
8657 },
8658 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8659 },
8660 compositionStart: {
8661 phasedRegistrationNames: {
8662 bubbled: 'onCompositionStart',
8663 captured: 'onCompositionStartCapture'
8664 },
8665 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8666 },
8667 compositionUpdate: {
8668 phasedRegistrationNames: {
8669 bubbled: 'onCompositionUpdate',
8670 captured: 'onCompositionUpdateCapture'
8671 },
8672 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8673 }
8674}; // Track whether we've ever handled a keypress on the space key.
8675
8676var hasSpaceKeypress = false;
8677/**
8678 * Return whether a native keypress event is assumed to be a command.
8679 * This is required because Firefox fires `keypress` events for key commands
8680 * (cut, copy, select-all, etc.) even though no character is inserted.
8681 */
8682
8683function isKeypressCommand(nativeEvent) {
8684 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
8685 !(nativeEvent.ctrlKey && nativeEvent.altKey);
8686}
8687/**
8688 * Translate native top level events into event types.
8689 *
8690 * @param {string} topLevelType
8691 * @return {object}
8692 */
8693
8694
8695function getCompositionEventType(topLevelType) {
8696 switch (topLevelType) {
8697 case TOP_COMPOSITION_START:
8698 return eventTypes.compositionStart;
8699
8700 case TOP_COMPOSITION_END:
8701 return eventTypes.compositionEnd;
8702
8703 case TOP_COMPOSITION_UPDATE:
8704 return eventTypes.compositionUpdate;
8705 }
8706}
8707/**
8708 * Does our fallback best-guess model think this event signifies that
8709 * composition has begun?
8710 *
8711 * @param {string} topLevelType
8712 * @param {object} nativeEvent
8713 * @return {boolean}
8714 */
8715
8716
8717function isFallbackCompositionStart(topLevelType, nativeEvent) {
8718 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
8719}
8720/**
8721 * Does our fallback mode think that this event is the end of composition?
8722 *
8723 * @param {string} topLevelType
8724 * @param {object} nativeEvent
8725 * @return {boolean}
8726 */
8727
8728
8729function isFallbackCompositionEnd(topLevelType, nativeEvent) {
8730 switch (topLevelType) {
8731 case TOP_KEY_UP:
8732 // Command keys insert or clear IME input.
8733 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
8734
8735 case TOP_KEY_DOWN:
8736 // Expect IME keyCode on each keydown. If we get any other
8737 // code we must have exited earlier.
8738 return nativeEvent.keyCode !== START_KEYCODE;
8739
8740 case TOP_KEY_PRESS:
8741 case TOP_MOUSE_DOWN:
8742 case TOP_BLUR:
8743 // Events are not possible without cancelling IME.
8744 return true;
8745
8746 default:
8747 return false;
8748 }
8749}
8750/**
8751 * Google Input Tools provides composition data via a CustomEvent,
8752 * with the `data` property populated in the `detail` object. If this
8753 * is available on the event object, use it. If not, this is a plain
8754 * composition event and we have nothing special to extract.
8755 *
8756 * @param {object} nativeEvent
8757 * @return {?string}
8758 */
8759
8760
8761function getDataFromCustomEvent(nativeEvent) {
8762 var detail = nativeEvent.detail;
8763
8764 if (typeof detail === 'object' && 'data' in detail) {
8765 return detail.data;
8766 }
8767
8768 return null;
8769}
8770/**
8771 * Check if a composition event was triggered by Korean IME.
8772 * Our fallback mode does not work well with IE's Korean IME,
8773 * so just use native composition events when Korean IME is used.
8774 * Although CompositionEvent.locale property is deprecated,
8775 * it is available in IE, where our fallback mode is enabled.
8776 *
8777 * @param {object} nativeEvent
8778 * @return {boolean}
8779 */
8780
8781
8782function isUsingKoreanIME(nativeEvent) {
8783 return nativeEvent.locale === 'ko';
8784} // Track the current IME composition status, if any.
8785
8786
8787var isComposing = false;
8788/**
8789 * @return {?object} A SyntheticCompositionEvent.
8790 */
8791
8792function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
8793 var eventType;
8794 var fallbackData;
8795
8796 if (canUseCompositionEvent) {
8797 eventType = getCompositionEventType(topLevelType);
8798 } else if (!isComposing) {
8799 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
8800 eventType = eventTypes.compositionStart;
8801 }
8802 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
8803 eventType = eventTypes.compositionEnd;
8804 }
8805
8806 if (!eventType) {
8807 return null;
8808 }
8809
8810 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
8811 // The current composition is stored statically and must not be
8812 // overwritten while composition continues.
8813 if (!isComposing && eventType === eventTypes.compositionStart) {
8814 isComposing = initialize(nativeEventTarget);
8815 } else if (eventType === eventTypes.compositionEnd) {
8816 if (isComposing) {
8817 fallbackData = getData();
8818 }
8819 }
8820 }
8821
8822 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
8823
8824 if (fallbackData) {
8825 // Inject data generated from fallback path into the synthetic event.
8826 // This matches the property of native CompositionEventInterface.
8827 event.data = fallbackData;
8828 } else {
8829 var customData = getDataFromCustomEvent(nativeEvent);
8830
8831 if (customData !== null) {
8832 event.data = customData;
8833 }
8834 }
8835
8836 accumulateTwoPhaseDispatches(event);
8837 return event;
8838}
8839/**
8840 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
8841 * @param {object} nativeEvent Native browser event.
8842 * @return {?string} The string corresponding to this `beforeInput` event.
8843 */
8844
8845
8846function getNativeBeforeInputChars(topLevelType, nativeEvent) {
8847 switch (topLevelType) {
8848 case TOP_COMPOSITION_END:
8849 return getDataFromCustomEvent(nativeEvent);
8850
8851 case TOP_KEY_PRESS:
8852 /**
8853 * If native `textInput` events are available, our goal is to make
8854 * use of them. However, there is a special case: the spacebar key.
8855 * In Webkit, preventing default on a spacebar `textInput` event
8856 * cancels character insertion, but it *also* causes the browser
8857 * to fall back to its default spacebar behavior of scrolling the
8858 * page.
8859 *
8860 * Tracking at:
8861 * https://code.google.com/p/chromium/issues/detail?id=355103
8862 *
8863 * To avoid this issue, use the keypress event as if no `textInput`
8864 * event is available.
8865 */
8866 var which = nativeEvent.which;
8867
8868 if (which !== SPACEBAR_CODE) {
8869 return null;
8870 }
8871
8872 hasSpaceKeypress = true;
8873 return SPACEBAR_CHAR;
8874
8875 case TOP_TEXT_INPUT:
8876 // Record the characters to be added to the DOM.
8877 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
8878 // it at the keypress level and bail immediately. Android Chrome
8879 // doesn't give us keycodes, so we need to ignore it.
8880
8881 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
8882 return null;
8883 }
8884
8885 return chars;
8886
8887 default:
8888 // For other native event types, do nothing.
8889 return null;
8890 }
8891}
8892/**
8893 * For browsers that do not provide the `textInput` event, extract the
8894 * appropriate string to use for SyntheticInputEvent.
8895 *
8896 * @param {number} topLevelType Number from `TopLevelEventTypes`.
8897 * @param {object} nativeEvent Native browser event.
8898 * @return {?string} The fallback string for this `beforeInput` event.
8899 */
8900
8901
8902function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
8903 // If we are currently composing (IME) and using a fallback to do so,
8904 // try to extract the composed characters from the fallback object.
8905 // If composition event is available, we extract a string only at
8906 // compositionevent, otherwise extract it at fallback events.
8907 if (isComposing) {
8908 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
8909 var chars = getData();
8910 reset();
8911 isComposing = false;
8912 return chars;
8913 }
8914
8915 return null;
8916 }
8917
8918 switch (topLevelType) {
8919 case TOP_PASTE:
8920 // If a paste event occurs after a keypress, throw out the input
8921 // chars. Paste events should not lead to BeforeInput events.
8922 return null;
8923
8924 case TOP_KEY_PRESS:
8925 /**
8926 * As of v27, Firefox may fire keypress events even when no character
8927 * will be inserted. A few possibilities:
8928 *
8929 * - `which` is `0`. Arrow keys, Esc key, etc.
8930 *
8931 * - `which` is the pressed key code, but no char is available.
8932 * Ex: 'AltGr + d` in Polish. There is no modified character for
8933 * this key combination and no character is inserted into the
8934 * document, but FF fires the keypress for char code `100` anyway.
8935 * No `input` event will occur.
8936 *
8937 * - `which` is the pressed key code, but a command combination is
8938 * being used. Ex: `Cmd+C`. No character is inserted, and no
8939 * `input` event will occur.
8940 */
8941 if (!isKeypressCommand(nativeEvent)) {
8942 // IE fires the `keypress` event when a user types an emoji via
8943 // Touch keyboard of Windows. In such a case, the `char` property
8944 // holds an emoji character like `\uD83D\uDE0A`. Because its length
8945 // is 2, the property `which` does not represent an emoji correctly.
8946 // In such a case, we directly return the `char` property instead of
8947 // using `which`.
8948 if (nativeEvent.char && nativeEvent.char.length > 1) {
8949 return nativeEvent.char;
8950 } else if (nativeEvent.which) {
8951 return String.fromCharCode(nativeEvent.which);
8952 }
8953 }
8954
8955 return null;
8956
8957 case TOP_COMPOSITION_END:
8958 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
8959
8960 default:
8961 return null;
8962 }
8963}
8964/**
8965 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
8966 * `textInput` or fallback behavior.
8967 *
8968 * @return {?object} A SyntheticInputEvent.
8969 */
8970
8971
8972function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
8973 var chars;
8974
8975 if (canUseTextInputEvent) {
8976 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
8977 } else {
8978 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
8979 } // If no characters are being inserted, no BeforeInput event should
8980 // be fired.
8981
8982
8983 if (!chars) {
8984 return null;
8985 }
8986
8987 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
8988 event.data = chars;
8989 accumulateTwoPhaseDispatches(event);
8990 return event;
8991}
8992/**
8993 * Create an `onBeforeInput` event to match
8994 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
8995 *
8996 * This event plugin is based on the native `textInput` event
8997 * available in Chrome, Safari, Opera, and IE. This event fires after
8998 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
8999 *
9000 * `beforeInput` is spec'd but not implemented in any browsers, and
9001 * the `input` event does not provide any useful information about what has
9002 * actually been added, contrary to the spec. Thus, `textInput` is the best
9003 * available event to identify the characters that have actually been inserted
9004 * into the target node.
9005 *
9006 * This plugin is also responsible for emitting `composition` events, thus
9007 * allowing us to share composition fallback code for both `beforeInput` and
9008 * `composition` event types.
9009 */
9010
9011
9012var BeforeInputEventPlugin = {
9013 eventTypes: eventTypes,
9014 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9015 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
9016 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
9017
9018 if (composition === null) {
9019 return beforeInput;
9020 }
9021
9022 if (beforeInput === null) {
9023 return composition;
9024 }
9025
9026 return [composition, beforeInput];
9027 }
9028};
9029
9030/**
9031 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
9032 */
9033var supportedInputTypes = {
9034 color: true,
9035 date: true,
9036 datetime: true,
9037 'datetime-local': true,
9038 email: true,
9039 month: true,
9040 number: true,
9041 password: true,
9042 range: true,
9043 search: true,
9044 tel: true,
9045 text: true,
9046 time: true,
9047 url: true,
9048 week: true
9049};
9050
9051function isTextInputElement(elem) {
9052 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
9053
9054 if (nodeName === 'input') {
9055 return !!supportedInputTypes[elem.type];
9056 }
9057
9058 if (nodeName === 'textarea') {
9059 return true;
9060 }
9061
9062 return false;
9063}
9064
9065var eventTypes$1 = {
9066 change: {
9067 phasedRegistrationNames: {
9068 bubbled: 'onChange',
9069 captured: 'onChangeCapture'
9070 },
9071 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
9072 }
9073};
9074
9075function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
9076 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
9077 event.type = 'change'; // Flag this event loop as needing state restore.
9078
9079 enqueueStateRestore(target);
9080 accumulateTwoPhaseDispatches(event);
9081 return event;
9082}
9083/**
9084 * For IE shims
9085 */
9086
9087
9088var activeElement = null;
9089var activeElementInst = null;
9090/**
9091 * SECTION: handle `change` event
9092 */
9093
9094function shouldUseChangeEvent(elem) {
9095 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
9096 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
9097}
9098
9099function manualDispatchChangeEvent(nativeEvent) {
9100 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
9101 // other events and have it go through ReactBrowserEventEmitter. Since it
9102 // doesn't, we manually listen for the events and so we have to enqueue and
9103 // process the abstract event manually.
9104 //
9105 // Batching is necessary here in order to ensure that all event handlers run
9106 // before the next rerender (including event handlers attached to ancestor
9107 // elements instead of directly on the input). Without this, controlled
9108 // components don't work properly in conjunction with event bubbling because
9109 // the component is rerendered and the value reverted before all the event
9110 // handlers can run. See https://github.com/facebook/react/issues/708.
9111
9112 batchedUpdates(runEventInBatch, event);
9113}
9114
9115function runEventInBatch(event) {
9116 runEventsInBatch(event);
9117}
9118
9119function getInstIfValueChanged(targetInst) {
9120 var targetNode = getNodeFromInstance$1(targetInst);
9121
9122 if (updateValueIfChanged(targetNode)) {
9123 return targetInst;
9124 }
9125}
9126
9127function getTargetInstForChangeEvent(topLevelType, targetInst) {
9128 if (topLevelType === TOP_CHANGE) {
9129 return targetInst;
9130 }
9131}
9132/**
9133 * SECTION: handle `input` event
9134 */
9135
9136
9137var isInputEventSupported = false;
9138
9139if (canUseDOM) {
9140 // IE9 claims to support the input event but fails to trigger it when
9141 // deleting text, so we ignore its input events.
9142 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
9143}
9144/**
9145 * (For IE <=9) Starts tracking propertychange events on the passed-in element
9146 * and override the value property so that we can distinguish user events from
9147 * value changes in JS.
9148 */
9149
9150
9151function startWatchingForValueChange(target, targetInst) {
9152 activeElement = target;
9153 activeElementInst = targetInst;
9154 activeElement.attachEvent('onpropertychange', handlePropertyChange);
9155}
9156/**
9157 * (For IE <=9) Removes the event listeners from the currently-tracked element,
9158 * if any exists.
9159 */
9160
9161
9162function stopWatchingForValueChange() {
9163 if (!activeElement) {
9164 return;
9165 }
9166
9167 activeElement.detachEvent('onpropertychange', handlePropertyChange);
9168 activeElement = null;
9169 activeElementInst = null;
9170}
9171/**
9172 * (For IE <=9) Handles a propertychange event, sending a `change` event if
9173 * the value of the active element has changed.
9174 */
9175
9176
9177function handlePropertyChange(nativeEvent) {
9178 if (nativeEvent.propertyName !== 'value') {
9179 return;
9180 }
9181
9182 if (getInstIfValueChanged(activeElementInst)) {
9183 manualDispatchChangeEvent(nativeEvent);
9184 }
9185}
9186
9187function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
9188 if (topLevelType === TOP_FOCUS) {
9189 // In IE9, propertychange fires for most input events but is buggy and
9190 // doesn't fire when text is deleted, but conveniently, selectionchange
9191 // appears to fire in all of the remaining cases so we catch those and
9192 // forward the event if the value has changed
9193 // In either case, we don't want to call the event handler if the value
9194 // is changed from JS so we redefine a setter for `.value` that updates
9195 // our activeElementValue variable, allowing us to ignore those changes
9196 //
9197 // stopWatching() should be a noop here but we call it just in case we
9198 // missed a blur event somehow.
9199 stopWatchingForValueChange();
9200 startWatchingForValueChange(target, targetInst);
9201 } else if (topLevelType === TOP_BLUR) {
9202 stopWatchingForValueChange();
9203 }
9204} // For IE8 and IE9.
9205
9206
9207function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
9208 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
9209 // On the selectionchange event, the target is just document which isn't
9210 // helpful for us so just check activeElement instead.
9211 //
9212 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
9213 // propertychange on the first input event after setting `value` from a
9214 // script and fires only keydown, keypress, keyup. Catching keyup usually
9215 // gets it and catching keydown lets us fire an event for the first
9216 // keystroke if user does a key repeat (it'll be a little delayed: right
9217 // before the second keystroke). Other input methods (e.g., paste) seem to
9218 // fire selectionchange normally.
9219 return getInstIfValueChanged(activeElementInst);
9220 }
9221}
9222/**
9223 * SECTION: handle `click` event
9224 */
9225
9226
9227function shouldUseClickEvent(elem) {
9228 // Use the `click` event to detect changes to checkbox and radio inputs.
9229 // This approach works across all browsers, whereas `change` does not fire
9230 // until `blur` in IE8.
9231 var nodeName = elem.nodeName;
9232 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
9233}
9234
9235function getTargetInstForClickEvent(topLevelType, targetInst) {
9236 if (topLevelType === TOP_CLICK) {
9237 return getInstIfValueChanged(targetInst);
9238 }
9239}
9240
9241function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
9242 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
9243 return getInstIfValueChanged(targetInst);
9244 }
9245}
9246
9247function handleControlledInputBlur(node) {
9248 var state = node._wrapperState;
9249
9250 if (!state || !state.controlled || node.type !== 'number') {
9251 return;
9252 }
9253
9254 {
9255 // If controlled, assign the value attribute to the current value on blur
9256 setDefaultValue(node, 'number', node.value);
9257 }
9258}
9259/**
9260 * This plugin creates an `onChange` event that normalizes change events
9261 * across form elements. This event fires at a time when it's possible to
9262 * change the element's value without seeing a flicker.
9263 *
9264 * Supported elements are:
9265 * - input (see `isTextInputElement`)
9266 * - textarea
9267 * - select
9268 */
9269
9270
9271var ChangeEventPlugin = {
9272 eventTypes: eventTypes$1,
9273 _isInputEventSupported: isInputEventSupported,
9274 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9275 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
9276 var getTargetInstFunc, handleEventFunc;
9277
9278 if (shouldUseChangeEvent(targetNode)) {
9279 getTargetInstFunc = getTargetInstForChangeEvent;
9280 } else if (isTextInputElement(targetNode)) {
9281 if (isInputEventSupported) {
9282 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
9283 } else {
9284 getTargetInstFunc = getTargetInstForInputEventPolyfill;
9285 handleEventFunc = handleEventsForInputEventPolyfill;
9286 }
9287 } else if (shouldUseClickEvent(targetNode)) {
9288 getTargetInstFunc = getTargetInstForClickEvent;
9289 }
9290
9291 if (getTargetInstFunc) {
9292 var inst = getTargetInstFunc(topLevelType, targetInst);
9293
9294 if (inst) {
9295 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
9296 return event;
9297 }
9298 }
9299
9300 if (handleEventFunc) {
9301 handleEventFunc(topLevelType, targetNode, targetInst);
9302 } // When blurring, set the value attribute for number inputs
9303
9304
9305 if (topLevelType === TOP_BLUR) {
9306 handleControlledInputBlur(targetNode);
9307 }
9308 }
9309};
9310
9311var SyntheticUIEvent = SyntheticEvent.extend({
9312 view: null,
9313 detail: null
9314});
9315
9316/**
9317 * Translation from modifier key to the associated property in the event.
9318 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
9319 */
9320var modifierKeyToProp = {
9321 Alt: 'altKey',
9322 Control: 'ctrlKey',
9323 Meta: 'metaKey',
9324 Shift: 'shiftKey'
9325}; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
9326// getModifierState. If getModifierState is not supported, we map it to a set of
9327// modifier keys exposed by the event. In this case, Lock-keys are not supported.
9328
9329function modifierStateGetter(keyArg) {
9330 var syntheticEvent = this;
9331 var nativeEvent = syntheticEvent.nativeEvent;
9332
9333 if (nativeEvent.getModifierState) {
9334 return nativeEvent.getModifierState(keyArg);
9335 }
9336
9337 var keyProp = modifierKeyToProp[keyArg];
9338 return keyProp ? !!nativeEvent[keyProp] : false;
9339}
9340
9341function getEventModifierState(nativeEvent) {
9342 return modifierStateGetter;
9343}
9344
9345var previousScreenX = 0;
9346var previousScreenY = 0; // Use flags to signal movementX/Y has already been set
9347
9348var isMovementXSet = false;
9349var isMovementYSet = false;
9350/**
9351 * @interface MouseEvent
9352 * @see http://www.w3.org/TR/DOM-Level-3-Events/
9353 */
9354
9355var SyntheticMouseEvent = SyntheticUIEvent.extend({
9356 screenX: null,
9357 screenY: null,
9358 clientX: null,
9359 clientY: null,
9360 pageX: null,
9361 pageY: null,
9362 ctrlKey: null,
9363 shiftKey: null,
9364 altKey: null,
9365 metaKey: null,
9366 getModifierState: getEventModifierState,
9367 button: null,
9368 buttons: null,
9369 relatedTarget: function (event) {
9370 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
9371 },
9372 movementX: function (event) {
9373 if ('movementX' in event) {
9374 return event.movementX;
9375 }
9376
9377 var screenX = previousScreenX;
9378 previousScreenX = event.screenX;
9379
9380 if (!isMovementXSet) {
9381 isMovementXSet = true;
9382 return 0;
9383 }
9384
9385 return event.type === 'mousemove' ? event.screenX - screenX : 0;
9386 },
9387 movementY: function (event) {
9388 if ('movementY' in event) {
9389 return event.movementY;
9390 }
9391
9392 var screenY = previousScreenY;
9393 previousScreenY = event.screenY;
9394
9395 if (!isMovementYSet) {
9396 isMovementYSet = true;
9397 return 0;
9398 }
9399
9400 return event.type === 'mousemove' ? event.screenY - screenY : 0;
9401 }
9402});
9403
9404/**
9405 * @interface PointerEvent
9406 * @see http://www.w3.org/TR/pointerevents/
9407 */
9408
9409var SyntheticPointerEvent = SyntheticMouseEvent.extend({
9410 pointerId: null,
9411 width: null,
9412 height: null,
9413 pressure: null,
9414 tangentialPressure: null,
9415 tiltX: null,
9416 tiltY: null,
9417 twist: null,
9418 pointerType: null,
9419 isPrimary: null
9420});
9421
9422var eventTypes$2 = {
9423 mouseEnter: {
9424 registrationName: 'onMouseEnter',
9425 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
9426 },
9427 mouseLeave: {
9428 registrationName: 'onMouseLeave',
9429 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
9430 },
9431 pointerEnter: {
9432 registrationName: 'onPointerEnter',
9433 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
9434 },
9435 pointerLeave: {
9436 registrationName: 'onPointerLeave',
9437 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
9438 }
9439};
9440var EnterLeaveEventPlugin = {
9441 eventTypes: eventTypes$2,
9442
9443 /**
9444 * For almost every interaction we care about, there will be both a top-level
9445 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
9446 * we do not extract duplicate events. However, moving the mouse into the
9447 * browser from outside will not fire a `mouseout` event. In this case, we use
9448 * the `mouseover` top-level event.
9449 */
9450 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9451 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
9452 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
9453
9454 if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0 && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
9455 // If this is an over event with a target, then we've already dispatched
9456 // the event in the out event of the other target. If this is replayed,
9457 // then it's because we couldn't dispatch against this target previously
9458 // so we have to do it now instead.
9459 return null;
9460 }
9461
9462 if (!isOutEvent && !isOverEvent) {
9463 // Must not be a mouse or pointer in or out - ignoring.
9464 return null;
9465 }
9466
9467 var win;
9468
9469 if (nativeEventTarget.window === nativeEventTarget) {
9470 // `nativeEventTarget` is probably a window object.
9471 win = nativeEventTarget;
9472 } else {
9473 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
9474 var doc = nativeEventTarget.ownerDocument;
9475
9476 if (doc) {
9477 win = doc.defaultView || doc.parentWindow;
9478 } else {
9479 win = window;
9480 }
9481 }
9482
9483 var from;
9484 var to;
9485
9486 if (isOutEvent) {
9487 from = targetInst;
9488 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
9489 to = related ? getClosestInstanceFromNode(related) : null;
9490
9491 if (to !== null) {
9492 var nearestMounted = getNearestMountedFiber(to);
9493
9494 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
9495 to = null;
9496 }
9497 }
9498 } else {
9499 // Moving to a node from outside the window.
9500 from = null;
9501 to = targetInst;
9502 }
9503
9504 if (from === to) {
9505 // Nothing pertains to our managed components.
9506 return null;
9507 }
9508
9509 var eventInterface, leaveEventType, enterEventType, eventTypePrefix;
9510
9511 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
9512 eventInterface = SyntheticMouseEvent;
9513 leaveEventType = eventTypes$2.mouseLeave;
9514 enterEventType = eventTypes$2.mouseEnter;
9515 eventTypePrefix = 'mouse';
9516 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
9517 eventInterface = SyntheticPointerEvent;
9518 leaveEventType = eventTypes$2.pointerLeave;
9519 enterEventType = eventTypes$2.pointerEnter;
9520 eventTypePrefix = 'pointer';
9521 }
9522
9523 var fromNode = from == null ? win : getNodeFromInstance$1(from);
9524 var toNode = to == null ? win : getNodeFromInstance$1(to);
9525 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
9526 leave.type = eventTypePrefix + 'leave';
9527 leave.target = fromNode;
9528 leave.relatedTarget = toNode;
9529 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
9530 enter.type = eventTypePrefix + 'enter';
9531 enter.target = toNode;
9532 enter.relatedTarget = fromNode;
9533 accumulateEnterLeaveDispatches(leave, enter, from, to); // If we are not processing the first ancestor, then we
9534 // should not process the same nativeEvent again, as we
9535 // will have already processed it in the first ancestor.
9536
9537 if ((eventSystemFlags & IS_FIRST_ANCESTOR) === 0) {
9538 return [leave];
9539 }
9540
9541 return [leave, enter];
9542 }
9543};
9544
9545/**
9546 * inlined Object.is polyfill to avoid requiring consumers ship their own
9547 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
9548 */
9549function is(x, y) {
9550 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
9551 ;
9552}
9553
9554var objectIs = typeof Object.is === 'function' ? Object.is : is;
9555
9556var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
9557/**
9558 * Performs equality by iterating through keys on an object and returning false
9559 * when any key has values which are not strictly equal between the arguments.
9560 * Returns true when the values of all keys are strictly equal.
9561 */
9562
9563function shallowEqual(objA, objB) {
9564 if (objectIs(objA, objB)) {
9565 return true;
9566 }
9567
9568 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
9569 return false;
9570 }
9571
9572 var keysA = Object.keys(objA);
9573 var keysB = Object.keys(objB);
9574
9575 if (keysA.length !== keysB.length) {
9576 return false;
9577 } // Test for A's keys different from B.
9578
9579
9580 for (var i = 0; i < keysA.length; i++) {
9581 if (!hasOwnProperty$2.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
9582 return false;
9583 }
9584 }
9585
9586 return true;
9587}
9588
9589var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
9590var eventTypes$3 = {
9591 select: {
9592 phasedRegistrationNames: {
9593 bubbled: 'onSelect',
9594 captured: 'onSelectCapture'
9595 },
9596 dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_DRAG_END, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE]
9597 }
9598};
9599var activeElement$1 = null;
9600var activeElementInst$1 = null;
9601var lastSelection = null;
9602var mouseDown = false;
9603/**
9604 * Get an object which is a unique representation of the current selection.
9605 *
9606 * The return value will not be consistent across nodes or browsers, but
9607 * two identical selections on the same node will return identical objects.
9608 *
9609 * @param {DOMElement} node
9610 * @return {object}
9611 */
9612
9613function getSelection$1(node) {
9614 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
9615 return {
9616 start: node.selectionStart,
9617 end: node.selectionEnd
9618 };
9619 } else {
9620 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
9621 var selection = win.getSelection();
9622 return {
9623 anchorNode: selection.anchorNode,
9624 anchorOffset: selection.anchorOffset,
9625 focusNode: selection.focusNode,
9626 focusOffset: selection.focusOffset
9627 };
9628 }
9629}
9630/**
9631 * Get document associated with the event target.
9632 *
9633 * @param {object} nativeEventTarget
9634 * @return {Document}
9635 */
9636
9637
9638function getEventTargetDocument(eventTarget) {
9639 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
9640}
9641/**
9642 * Poll selection to see whether it's changed.
9643 *
9644 * @param {object} nativeEvent
9645 * @param {object} nativeEventTarget
9646 * @return {?SyntheticEvent}
9647 */
9648
9649
9650function constructSelectEvent(nativeEvent, nativeEventTarget) {
9651 // Ensure we have the right element, and that the user is not dragging a
9652 // selection (this matches native `select` event behavior). In HTML5, select
9653 // fires only on input and textarea thus if there's no focused element we
9654 // won't dispatch.
9655 var doc = getEventTargetDocument(nativeEventTarget);
9656
9657 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
9658 return null;
9659 } // Only fire when selection has actually changed.
9660
9661
9662 var currentSelection = getSelection$1(activeElement$1);
9663
9664 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
9665 lastSelection = currentSelection;
9666 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
9667 syntheticEvent.type = 'select';
9668 syntheticEvent.target = activeElement$1;
9669 accumulateTwoPhaseDispatches(syntheticEvent);
9670 return syntheticEvent;
9671 }
9672
9673 return null;
9674}
9675/**
9676 * This plugin creates an `onSelect` event that normalizes select events
9677 * across form elements.
9678 *
9679 * Supported elements are:
9680 * - input (see `isTextInputElement`)
9681 * - textarea
9682 * - contentEditable
9683 *
9684 * This differs from native browser implementations in the following ways:
9685 * - Fires on contentEditable fields as well as inputs.
9686 * - Fires for collapsed selection.
9687 * - Fires after user input.
9688 */
9689
9690
9691var SelectEventPlugin = {
9692 eventTypes: eventTypes$3,
9693 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, container) {
9694 var containerOrDoc = container || getEventTargetDocument(nativeEventTarget); // Track whether all listeners exists for this plugin. If none exist, we do
9695 // not extract events. See #3639.
9696
9697 if (!containerOrDoc || !isListeningToAllDependencies('onSelect', containerOrDoc)) {
9698 return null;
9699 }
9700
9701 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
9702
9703 switch (topLevelType) {
9704 // Track the input node that has focus.
9705 case TOP_FOCUS:
9706 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
9707 activeElement$1 = targetNode;
9708 activeElementInst$1 = targetInst;
9709 lastSelection = null;
9710 }
9711
9712 break;
9713
9714 case TOP_BLUR:
9715 activeElement$1 = null;
9716 activeElementInst$1 = null;
9717 lastSelection = null;
9718 break;
9719 // Don't fire the event while the user is dragging. This matches the
9720 // semantics of the native select event.
9721
9722 case TOP_MOUSE_DOWN:
9723 mouseDown = true;
9724 break;
9725
9726 case TOP_CONTEXT_MENU:
9727 case TOP_MOUSE_UP:
9728 case TOP_DRAG_END:
9729 mouseDown = false;
9730 return constructSelectEvent(nativeEvent, nativeEventTarget);
9731 // Chrome and IE fire non-standard event when selection is changed (and
9732 // sometimes when it hasn't). IE's event fires out of order with respect
9733 // to key and input events on deletion, so we discard it.
9734 //
9735 // Firefox doesn't support selectionchange, so check selection status
9736 // after each key entry. The selection changes after keydown and before
9737 // keyup, but we check on keydown as well in the case of holding down a
9738 // key, when multiple keydown events are fired but only one keyup is.
9739 // This is also our approach for IE handling, for the reason above.
9740
9741 case TOP_SELECTION_CHANGE:
9742 if (skipSelectionChangeEvent) {
9743 break;
9744 }
9745
9746 // falls through
9747
9748 case TOP_KEY_DOWN:
9749 case TOP_KEY_UP:
9750 return constructSelectEvent(nativeEvent, nativeEventTarget);
9751 }
9752
9753 return null;
9754 }
9755};
9756
9757/**
9758 * @interface Event
9759 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
9760 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
9761 */
9762
9763var SyntheticAnimationEvent = SyntheticEvent.extend({
9764 animationName: null,
9765 elapsedTime: null,
9766 pseudoElement: null
9767});
9768
9769/**
9770 * @interface Event
9771 * @see http://www.w3.org/TR/clipboard-apis/
9772 */
9773
9774var SyntheticClipboardEvent = SyntheticEvent.extend({
9775 clipboardData: function (event) {
9776 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
9777 }
9778});
9779
9780/**
9781 * @interface FocusEvent
9782 * @see http://www.w3.org/TR/DOM-Level-3-Events/
9783 */
9784
9785var SyntheticFocusEvent = SyntheticUIEvent.extend({
9786 relatedTarget: null
9787});
9788
9789/**
9790 * `charCode` represents the actual "character code" and is safe to use with
9791 * `String.fromCharCode`. As such, only keys that correspond to printable
9792 * characters produce a valid `charCode`, the only exception to this is Enter.
9793 * The Tab-key is considered non-printable and does not have a `charCode`,
9794 * presumably because it does not produce a tab-character in browsers.
9795 *
9796 * @param {object} nativeEvent Native browser event.
9797 * @return {number} Normalized `charCode` property.
9798 */
9799function getEventCharCode(nativeEvent) {
9800 var charCode;
9801 var keyCode = nativeEvent.keyCode;
9802
9803 if ('charCode' in nativeEvent) {
9804 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
9805
9806 if (charCode === 0 && keyCode === 13) {
9807 charCode = 13;
9808 }
9809 } else {
9810 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
9811 charCode = keyCode;
9812 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
9813 // report Enter as charCode 10 when ctrl is pressed.
9814
9815
9816 if (charCode === 10) {
9817 charCode = 13;
9818 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
9819 // Must not discard the (non-)printable Enter-key.
9820
9821
9822 if (charCode >= 32 || charCode === 13) {
9823 return charCode;
9824 }
9825
9826 return 0;
9827}
9828
9829/**
9830 * Normalization of deprecated HTML5 `key` values
9831 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
9832 */
9833
9834var normalizeKey = {
9835 Esc: 'Escape',
9836 Spacebar: ' ',
9837 Left: 'ArrowLeft',
9838 Up: 'ArrowUp',
9839 Right: 'ArrowRight',
9840 Down: 'ArrowDown',
9841 Del: 'Delete',
9842 Win: 'OS',
9843 Menu: 'ContextMenu',
9844 Apps: 'ContextMenu',
9845 Scroll: 'ScrollLock',
9846 MozPrintableKey: 'Unidentified'
9847};
9848/**
9849 * Translation from legacy `keyCode` to HTML5 `key`
9850 * Only special keys supported, all others depend on keyboard layout or browser
9851 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
9852 */
9853
9854var translateToKey = {
9855 '8': 'Backspace',
9856 '9': 'Tab',
9857 '12': 'Clear',
9858 '13': 'Enter',
9859 '16': 'Shift',
9860 '17': 'Control',
9861 '18': 'Alt',
9862 '19': 'Pause',
9863 '20': 'CapsLock',
9864 '27': 'Escape',
9865 '32': ' ',
9866 '33': 'PageUp',
9867 '34': 'PageDown',
9868 '35': 'End',
9869 '36': 'Home',
9870 '37': 'ArrowLeft',
9871 '38': 'ArrowUp',
9872 '39': 'ArrowRight',
9873 '40': 'ArrowDown',
9874 '45': 'Insert',
9875 '46': 'Delete',
9876 '112': 'F1',
9877 '113': 'F2',
9878 '114': 'F3',
9879 '115': 'F4',
9880 '116': 'F5',
9881 '117': 'F6',
9882 '118': 'F7',
9883 '119': 'F8',
9884 '120': 'F9',
9885 '121': 'F10',
9886 '122': 'F11',
9887 '123': 'F12',
9888 '144': 'NumLock',
9889 '145': 'ScrollLock',
9890 '224': 'Meta'
9891};
9892/**
9893 * @param {object} nativeEvent Native browser event.
9894 * @return {string} Normalized `key` property.
9895 */
9896
9897function getEventKey(nativeEvent) {
9898 if (nativeEvent.key) {
9899 // Normalize inconsistent values reported by browsers due to
9900 // implementations of a working draft specification.
9901 // FireFox implements `key` but returns `MozPrintableKey` for all
9902 // printable characters (normalized to `Unidentified`), ignore it.
9903 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
9904
9905 if (key !== 'Unidentified') {
9906 return key;
9907 }
9908 } // Browser does not implement `key`, polyfill as much of it as we can.
9909
9910
9911 if (nativeEvent.type === 'keypress') {
9912 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
9913 // thus be captured by `keypress`, no other non-printable key should.
9914
9915 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
9916 }
9917
9918 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
9919 // While user keyboard layout determines the actual meaning of each
9920 // `keyCode` value, almost all function keys have a universal value.
9921 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
9922 }
9923
9924 return '';
9925}
9926
9927/**
9928 * @interface KeyboardEvent
9929 * @see http://www.w3.org/TR/DOM-Level-3-Events/
9930 */
9931
9932var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
9933 key: getEventKey,
9934 location: null,
9935 ctrlKey: null,
9936 shiftKey: null,
9937 altKey: null,
9938 metaKey: null,
9939 repeat: null,
9940 locale: null,
9941 getModifierState: getEventModifierState,
9942 // Legacy Interface
9943 charCode: function (event) {
9944 // `charCode` is the result of a KeyPress event and represents the value of
9945 // the actual printable character.
9946 // KeyPress is deprecated, but its replacement is not yet final and not
9947 // implemented in any major browser. Only KeyPress has charCode.
9948 if (event.type === 'keypress') {
9949 return getEventCharCode(event);
9950 }
9951
9952 return 0;
9953 },
9954 keyCode: function (event) {
9955 // `keyCode` is the result of a KeyDown/Up event and represents the value of
9956 // physical keyboard key.
9957 // The actual meaning of the value depends on the users' keyboard layout
9958 // which cannot be detected. Assuming that it is a US keyboard layout
9959 // provides a surprisingly accurate mapping for US and European users.
9960 // Due to this, it is left to the user to implement at this time.
9961 if (event.type === 'keydown' || event.type === 'keyup') {
9962 return event.keyCode;
9963 }
9964
9965 return 0;
9966 },
9967 which: function (event) {
9968 // `which` is an alias for either `keyCode` or `charCode` depending on the
9969 // type of the event.
9970 if (event.type === 'keypress') {
9971 return getEventCharCode(event);
9972 }
9973
9974 if (event.type === 'keydown' || event.type === 'keyup') {
9975 return event.keyCode;
9976 }
9977
9978 return 0;
9979 }
9980});
9981
9982/**
9983 * @interface DragEvent
9984 * @see http://www.w3.org/TR/DOM-Level-3-Events/
9985 */
9986
9987var SyntheticDragEvent = SyntheticMouseEvent.extend({
9988 dataTransfer: null
9989});
9990
9991/**
9992 * @interface TouchEvent
9993 * @see http://www.w3.org/TR/touch-events/
9994 */
9995
9996var SyntheticTouchEvent = SyntheticUIEvent.extend({
9997 touches: null,
9998 targetTouches: null,
9999 changedTouches: null,
10000 altKey: null,
10001 metaKey: null,
10002 ctrlKey: null,
10003 shiftKey: null,
10004 getModifierState: getEventModifierState
10005});
10006
10007/**
10008 * @interface Event
10009 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
10010 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
10011 */
10012
10013var SyntheticTransitionEvent = SyntheticEvent.extend({
10014 propertyName: null,
10015 elapsedTime: null,
10016 pseudoElement: null
10017});
10018
10019/**
10020 * @interface WheelEvent
10021 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10022 */
10023
10024var SyntheticWheelEvent = SyntheticMouseEvent.extend({
10025 deltaX: function (event) {
10026 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
10027 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
10028 },
10029 deltaY: function (event) {
10030 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
10031 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
10032 'wheelDelta' in event ? -event.wheelDelta : 0;
10033 },
10034 deltaZ: null,
10035 // Browsers without "deltaMode" is reporting in raw wheel delta where one
10036 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
10037 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
10038 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
10039 deltaMode: null
10040});
10041
10042var knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING];
10043var SimpleEventPlugin = {
10044 // simpleEventPluginEventTypes gets populated from
10045 // the DOMEventProperties module.
10046 eventTypes: simpleEventPluginEventTypes,
10047 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
10048 var dispatchConfig = topLevelEventsToDispatchConfig.get(topLevelType);
10049
10050 if (!dispatchConfig) {
10051 return null;
10052 }
10053
10054 var EventConstructor;
10055
10056 switch (topLevelType) {
10057 case TOP_KEY_PRESS:
10058 // Firefox creates a keypress event for function keys too. This removes
10059 // the unwanted keypress events. Enter is however both printable and
10060 // non-printable. One would expect Tab to be as well (but it isn't).
10061 if (getEventCharCode(nativeEvent) === 0) {
10062 return null;
10063 }
10064
10065 /* falls through */
10066
10067 case TOP_KEY_DOWN:
10068 case TOP_KEY_UP:
10069 EventConstructor = SyntheticKeyboardEvent;
10070 break;
10071
10072 case TOP_BLUR:
10073 case TOP_FOCUS:
10074 EventConstructor = SyntheticFocusEvent;
10075 break;
10076
10077 case TOP_CLICK:
10078 // Firefox creates a click event on right mouse clicks. This removes the
10079 // unwanted click events.
10080 if (nativeEvent.button === 2) {
10081 return null;
10082 }
10083
10084 /* falls through */
10085
10086 case TOP_AUX_CLICK:
10087 case TOP_DOUBLE_CLICK:
10088 case TOP_MOUSE_DOWN:
10089 case TOP_MOUSE_MOVE:
10090 case TOP_MOUSE_UP: // TODO: Disabled elements should not respond to mouse events
10091
10092 /* falls through */
10093
10094 case TOP_MOUSE_OUT:
10095 case TOP_MOUSE_OVER:
10096 case TOP_CONTEXT_MENU:
10097 EventConstructor = SyntheticMouseEvent;
10098 break;
10099
10100 case TOP_DRAG:
10101 case TOP_DRAG_END:
10102 case TOP_DRAG_ENTER:
10103 case TOP_DRAG_EXIT:
10104 case TOP_DRAG_LEAVE:
10105 case TOP_DRAG_OVER:
10106 case TOP_DRAG_START:
10107 case TOP_DROP:
10108 EventConstructor = SyntheticDragEvent;
10109 break;
10110
10111 case TOP_TOUCH_CANCEL:
10112 case TOP_TOUCH_END:
10113 case TOP_TOUCH_MOVE:
10114 case TOP_TOUCH_START:
10115 EventConstructor = SyntheticTouchEvent;
10116 break;
10117
10118 case TOP_ANIMATION_END:
10119 case TOP_ANIMATION_ITERATION:
10120 case TOP_ANIMATION_START:
10121 EventConstructor = SyntheticAnimationEvent;
10122 break;
10123
10124 case TOP_TRANSITION_END:
10125 EventConstructor = SyntheticTransitionEvent;
10126 break;
10127
10128 case TOP_SCROLL:
10129 EventConstructor = SyntheticUIEvent;
10130 break;
10131
10132 case TOP_WHEEL:
10133 EventConstructor = SyntheticWheelEvent;
10134 break;
10135
10136 case TOP_COPY:
10137 case TOP_CUT:
10138 case TOP_PASTE:
10139 EventConstructor = SyntheticClipboardEvent;
10140 break;
10141
10142 case TOP_GOT_POINTER_CAPTURE:
10143 case TOP_LOST_POINTER_CAPTURE:
10144 case TOP_POINTER_CANCEL:
10145 case TOP_POINTER_DOWN:
10146 case TOP_POINTER_MOVE:
10147 case TOP_POINTER_OUT:
10148 case TOP_POINTER_OVER:
10149 case TOP_POINTER_UP:
10150 EventConstructor = SyntheticPointerEvent;
10151 break;
10152
10153 default:
10154 {
10155 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
10156 error('SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
10157 }
10158 } // HTML Events
10159 // @see http://www.w3.org/TR/html5/index.html#events-0
10160
10161
10162 EventConstructor = SyntheticEvent;
10163 break;
10164 }
10165
10166 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
10167 accumulateTwoPhaseDispatches(event);
10168 return event;
10169 }
10170};
10171
10172/**
10173 * Specifies a deterministic ordering of `EventPlugin`s. A convenient way to
10174 * reason about plugins, without having to package every one of them. This
10175 * is better than having plugins be ordered in the same order that they
10176 * are injected because that ordering would be influenced by the packaging order.
10177 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
10178 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
10179 */
10180
10181var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
10182/**
10183 * Inject modules for resolving DOM hierarchy and plugin ordering.
10184 */
10185
10186injectEventPluginOrder(DOMEventPluginOrder);
10187setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
10188/**
10189 * Some important event plugins included by default (without having to require
10190 * them).
10191 */
10192
10193injectEventPluginsByName({
10194 SimpleEventPlugin: SimpleEventPlugin,
10195 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
10196 ChangeEventPlugin: ChangeEventPlugin,
10197 SelectEventPlugin: SelectEventPlugin,
10198 BeforeInputEventPlugin: BeforeInputEventPlugin
10199});
10200
10201// Prefix measurements so that it's possible to filter them.
10202// Longer prefixes are hard to read in DevTools.
10203var reactEmoji = "\u269B";
10204var warningEmoji = "\u26D4";
10205var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause.
10206// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
10207
10208var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
10209// Reusing `currentFiber` would be confusing for this because user code fiber
10210// can change during commit phase too, but we don't need to unwind it (since
10211// lifecycles in the commit phase don't resemble a tree).
10212
10213var currentPhase = null;
10214var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
10215// so we will keep track of it, and include it in the report.
10216// Track commits caused by cascading updates.
10217
10218var isCommitting = false;
10219var hasScheduledUpdateInCurrentCommit = false;
10220var hasScheduledUpdateInCurrentPhase = false;
10221var commitCountInCurrentWorkLoop = 0;
10222var effectCountInCurrentCommit = 0;
10223// to avoid stretch the commit phase with measurement overhead.
10224
10225var labelsInCurrentCommit = new Set();
10226
10227var formatMarkName = function (markName) {
10228 return reactEmoji + " " + markName;
10229};
10230
10231var formatLabel = function (label, warning) {
10232 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
10233 var suffix = warning ? " Warning: " + warning : '';
10234 return "" + prefix + label + suffix;
10235};
10236
10237var beginMark = function (markName) {
10238 performance.mark(formatMarkName(markName));
10239};
10240
10241var clearMark = function (markName) {
10242 performance.clearMarks(formatMarkName(markName));
10243};
10244
10245var endMark = function (label, markName, warning) {
10246 var formattedMarkName = formatMarkName(markName);
10247 var formattedLabel = formatLabel(label, warning);
10248
10249 try {
10250 performance.measure(formattedLabel, formattedMarkName);
10251 } catch (err) {} // If previous mark was missing for some reason, this will throw.
10252 // This could only happen if React crashed in an unexpected place earlier.
10253 // Don't pile on with more errors.
10254 // Clear marks immediately to avoid growing buffer.
10255
10256
10257 performance.clearMarks(formattedMarkName);
10258 performance.clearMeasures(formattedLabel);
10259};
10260
10261var getFiberMarkName = function (label, debugID) {
10262 return label + " (#" + debugID + ")";
10263};
10264
10265var getFiberLabel = function (componentName, isMounted, phase) {
10266 if (phase === null) {
10267 // These are composite component total time measurements.
10268 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
10269 } else {
10270 // Composite component methods.
10271 return componentName + "." + phase;
10272 }
10273};
10274
10275var beginFiberMark = function (fiber, phase) {
10276 var componentName = getComponentName(fiber.type) || 'Unknown';
10277 var debugID = fiber._debugID;
10278 var isMounted = fiber.alternate !== null;
10279 var label = getFiberLabel(componentName, isMounted, phase);
10280
10281 if (isCommitting && labelsInCurrentCommit.has(label)) {
10282 // During the commit phase, we don't show duplicate labels because
10283 // there is a fixed overhead for every measurement, and we don't
10284 // want to stretch the commit phase beyond necessary.
10285 return false;
10286 }
10287
10288 labelsInCurrentCommit.add(label);
10289 var markName = getFiberMarkName(label, debugID);
10290 beginMark(markName);
10291 return true;
10292};
10293
10294var clearFiberMark = function (fiber, phase) {
10295 var componentName = getComponentName(fiber.type) || 'Unknown';
10296 var debugID = fiber._debugID;
10297 var isMounted = fiber.alternate !== null;
10298 var label = getFiberLabel(componentName, isMounted, phase);
10299 var markName = getFiberMarkName(label, debugID);
10300 clearMark(markName);
10301};
10302
10303var endFiberMark = function (fiber, phase, warning) {
10304 var componentName = getComponentName(fiber.type) || 'Unknown';
10305 var debugID = fiber._debugID;
10306 var isMounted = fiber.alternate !== null;
10307 var label = getFiberLabel(componentName, isMounted, phase);
10308 var markName = getFiberMarkName(label, debugID);
10309 endMark(label, markName, warning);
10310};
10311
10312var shouldIgnoreFiber = function (fiber) {
10313 // Host components should be skipped in the timeline.
10314 // We could check typeof fiber.type, but does this work with RN?
10315 switch (fiber.tag) {
10316 case HostRoot:
10317 case HostComponent:
10318 case HostText:
10319 case HostPortal:
10320 case Fragment:
10321 case ContextProvider:
10322 case ContextConsumer:
10323 case Mode:
10324 return true;
10325
10326 default:
10327 return false;
10328 }
10329};
10330
10331var clearPendingPhaseMeasurement = function () {
10332 if (currentPhase !== null && currentPhaseFiber !== null) {
10333 clearFiberMark(currentPhaseFiber, currentPhase);
10334 }
10335
10336 currentPhaseFiber = null;
10337 currentPhase = null;
10338 hasScheduledUpdateInCurrentPhase = false;
10339};
10340
10341var pauseTimers = function () {
10342 // Stops all currently active measurements so that they can be resumed
10343 // if we continue in a later deferred loop from the same unit of work.
10344 var fiber = currentFiber;
10345
10346 while (fiber) {
10347 if (fiber._debugIsCurrentlyTiming) {
10348 endFiberMark(fiber, null, null);
10349 }
10350
10351 fiber = fiber.return;
10352 }
10353};
10354
10355var resumeTimersRecursively = function (fiber) {
10356 if (fiber.return !== null) {
10357 resumeTimersRecursively(fiber.return);
10358 }
10359
10360 if (fiber._debugIsCurrentlyTiming) {
10361 beginFiberMark(fiber, null);
10362 }
10363};
10364
10365var resumeTimers = function () {
10366 // Resumes all measurements that were active during the last deferred loop.
10367 if (currentFiber !== null) {
10368 resumeTimersRecursively(currentFiber);
10369 }
10370};
10371
10372function recordEffect() {
10373 {
10374 effectCountInCurrentCommit++;
10375 }
10376}
10377function recordScheduleUpdate() {
10378 {
10379 if (isCommitting) {
10380 hasScheduledUpdateInCurrentCommit = true;
10381 }
10382
10383 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
10384 hasScheduledUpdateInCurrentPhase = true;
10385 }
10386 }
10387}
10388function startWorkTimer(fiber) {
10389 {
10390 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10391 return;
10392 } // If we pause, this is the fiber to unwind from.
10393
10394
10395 currentFiber = fiber;
10396
10397 if (!beginFiberMark(fiber, null)) {
10398 return;
10399 }
10400
10401 fiber._debugIsCurrentlyTiming = true;
10402 }
10403}
10404function cancelWorkTimer(fiber) {
10405 {
10406 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10407 return;
10408 } // Remember we shouldn't complete measurement for this fiber.
10409 // Otherwise flamechart will be deep even for small updates.
10410
10411
10412 fiber._debugIsCurrentlyTiming = false;
10413 clearFiberMark(fiber, null);
10414 }
10415}
10416function stopWorkTimer(fiber) {
10417 {
10418 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10419 return;
10420 } // If we pause, its parent is the fiber to unwind from.
10421
10422
10423 currentFiber = fiber.return;
10424
10425 if (!fiber._debugIsCurrentlyTiming) {
10426 return;
10427 }
10428
10429 fiber._debugIsCurrentlyTiming = false;
10430 endFiberMark(fiber, null, null);
10431 }
10432}
10433function stopFailedWorkTimer(fiber) {
10434 {
10435 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10436 return;
10437 } // If we pause, its parent is the fiber to unwind from.
10438
10439
10440 currentFiber = fiber.return;
10441
10442 if (!fiber._debugIsCurrentlyTiming) {
10443 return;
10444 }
10445
10446 fiber._debugIsCurrentlyTiming = false;
10447 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
10448 endFiberMark(fiber, null, warning);
10449 }
10450}
10451function startPhaseTimer(fiber, phase) {
10452 {
10453 if (!supportsUserTiming) {
10454 return;
10455 }
10456
10457 clearPendingPhaseMeasurement();
10458
10459 if (!beginFiberMark(fiber, phase)) {
10460 return;
10461 }
10462
10463 currentPhaseFiber = fiber;
10464 currentPhase = phase;
10465 }
10466}
10467function stopPhaseTimer() {
10468 {
10469 if (!supportsUserTiming) {
10470 return;
10471 }
10472
10473 if (currentPhase !== null && currentPhaseFiber !== null) {
10474 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
10475 endFiberMark(currentPhaseFiber, currentPhase, warning);
10476 }
10477
10478 currentPhase = null;
10479 currentPhaseFiber = null;
10480 }
10481}
10482function startWorkLoopTimer(nextUnitOfWork) {
10483 {
10484 currentFiber = nextUnitOfWork;
10485
10486 if (!supportsUserTiming) {
10487 return;
10488 }
10489
10490 commitCountInCurrentWorkLoop = 0; // This is top level call.
10491 // Any other measurements are performed within.
10492
10493 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
10494
10495 resumeTimers();
10496 }
10497}
10498function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
10499 {
10500 if (!supportsUserTiming) {
10501 return;
10502 }
10503
10504 var warning = null;
10505
10506 if (interruptedBy !== null) {
10507 if (interruptedBy.tag === HostRoot) {
10508 warning = 'A top-level update interrupted the previous render';
10509 } else {
10510 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
10511 warning = "An update to " + componentName + " interrupted the previous render";
10512 }
10513 } else if (commitCountInCurrentWorkLoop > 1) {
10514 warning = 'There were cascading updates';
10515 }
10516
10517 commitCountInCurrentWorkLoop = 0;
10518 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
10519
10520 pauseTimers();
10521 endMark(label, '(React Tree Reconciliation)', warning);
10522 }
10523}
10524function startCommitTimer() {
10525 {
10526 if (!supportsUserTiming) {
10527 return;
10528 }
10529
10530 isCommitting = true;
10531 hasScheduledUpdateInCurrentCommit = false;
10532 labelsInCurrentCommit.clear();
10533 beginMark('(Committing Changes)');
10534 }
10535}
10536function stopCommitTimer() {
10537 {
10538 if (!supportsUserTiming) {
10539 return;
10540 }
10541
10542 var warning = null;
10543
10544 if (hasScheduledUpdateInCurrentCommit) {
10545 warning = 'Lifecycle hook scheduled a cascading update';
10546 } else if (commitCountInCurrentWorkLoop > 0) {
10547 warning = 'Caused by a cascading update in earlier commit';
10548 }
10549
10550 hasScheduledUpdateInCurrentCommit = false;
10551 commitCountInCurrentWorkLoop++;
10552 isCommitting = false;
10553 labelsInCurrentCommit.clear();
10554 endMark('(Committing Changes)', '(Committing Changes)', warning);
10555 }
10556}
10557function startCommitSnapshotEffectsTimer() {
10558 {
10559 if (!supportsUserTiming) {
10560 return;
10561 }
10562
10563 effectCountInCurrentCommit = 0;
10564 beginMark('(Committing Snapshot Effects)');
10565 }
10566}
10567function stopCommitSnapshotEffectsTimer() {
10568 {
10569 if (!supportsUserTiming) {
10570 return;
10571 }
10572
10573 var count = effectCountInCurrentCommit;
10574 effectCountInCurrentCommit = 0;
10575 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
10576 }
10577}
10578function startCommitHostEffectsTimer() {
10579 {
10580 if (!supportsUserTiming) {
10581 return;
10582 }
10583
10584 effectCountInCurrentCommit = 0;
10585 beginMark('(Committing Host Effects)');
10586 }
10587}
10588function stopCommitHostEffectsTimer() {
10589 {
10590 if (!supportsUserTiming) {
10591 return;
10592 }
10593
10594 var count = effectCountInCurrentCommit;
10595 effectCountInCurrentCommit = 0;
10596 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
10597 }
10598}
10599function startCommitLifeCyclesTimer() {
10600 {
10601 if (!supportsUserTiming) {
10602 return;
10603 }
10604
10605 effectCountInCurrentCommit = 0;
10606 beginMark('(Calling Lifecycle Methods)');
10607 }
10608}
10609function stopCommitLifeCyclesTimer() {
10610 {
10611 if (!supportsUserTiming) {
10612 return;
10613 }
10614
10615 var count = effectCountInCurrentCommit;
10616 effectCountInCurrentCommit = 0;
10617 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
10618 }
10619}
10620
10621var valueStack = [];
10622var fiberStack;
10623
10624{
10625 fiberStack = [];
10626}
10627
10628var index = -1;
10629
10630function createCursor(defaultValue) {
10631 return {
10632 current: defaultValue
10633 };
10634}
10635
10636function pop(cursor, fiber) {
10637 if (index < 0) {
10638 {
10639 error('Unexpected pop.');
10640 }
10641
10642 return;
10643 }
10644
10645 {
10646 if (fiber !== fiberStack[index]) {
10647 error('Unexpected Fiber popped.');
10648 }
10649 }
10650
10651 cursor.current = valueStack[index];
10652 valueStack[index] = null;
10653
10654 {
10655 fiberStack[index] = null;
10656 }
10657
10658 index--;
10659}
10660
10661function push(cursor, value, fiber) {
10662 index++;
10663 valueStack[index] = cursor.current;
10664
10665 {
10666 fiberStack[index] = fiber;
10667 }
10668
10669 cursor.current = value;
10670}
10671
10672var warnedAboutMissingGetChildContext;
10673
10674{
10675 warnedAboutMissingGetChildContext = {};
10676}
10677
10678var emptyContextObject = {};
10679
10680{
10681 Object.freeze(emptyContextObject);
10682} // A cursor to the current merged context object on the stack.
10683
10684
10685var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
10686
10687var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
10688// We use this to get access to the parent context after we have already
10689// pushed the next context provider, and now need to merge their contexts.
10690
10691var previousContext = emptyContextObject;
10692
10693function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
10694 {
10695 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
10696 // If the fiber is a context provider itself, when we read its context
10697 // we may have already pushed its own child context on the stack. A context
10698 // provider should not "see" its own child context. Therefore we read the
10699 // previous (parent) context instead for a context provider.
10700 return previousContext;
10701 }
10702
10703 return contextStackCursor.current;
10704 }
10705}
10706
10707function cacheContext(workInProgress, unmaskedContext, maskedContext) {
10708 {
10709 var instance = workInProgress.stateNode;
10710 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
10711 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
10712 }
10713}
10714
10715function getMaskedContext(workInProgress, unmaskedContext) {
10716 {
10717 var type = workInProgress.type;
10718 var contextTypes = type.contextTypes;
10719
10720 if (!contextTypes) {
10721 return emptyContextObject;
10722 } // Avoid recreating masked context unless unmasked context has changed.
10723 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
10724 // This may trigger infinite loops if componentWillReceiveProps calls setState.
10725
10726
10727 var instance = workInProgress.stateNode;
10728
10729 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
10730 return instance.__reactInternalMemoizedMaskedChildContext;
10731 }
10732
10733 var context = {};
10734
10735 for (var key in contextTypes) {
10736 context[key] = unmaskedContext[key];
10737 }
10738
10739 {
10740 var name = getComponentName(type) || 'Unknown';
10741 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
10742 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
10743 // Context is created before the class component is instantiated so check for instance.
10744
10745
10746 if (instance) {
10747 cacheContext(workInProgress, unmaskedContext, context);
10748 }
10749
10750 return context;
10751 }
10752}
10753
10754function hasContextChanged() {
10755 {
10756 return didPerformWorkStackCursor.current;
10757 }
10758}
10759
10760function isContextProvider(type) {
10761 {
10762 var childContextTypes = type.childContextTypes;
10763 return childContextTypes !== null && childContextTypes !== undefined;
10764 }
10765}
10766
10767function popContext(fiber) {
10768 {
10769 pop(didPerformWorkStackCursor, fiber);
10770 pop(contextStackCursor, fiber);
10771 }
10772}
10773
10774function popTopLevelContextObject(fiber) {
10775 {
10776 pop(didPerformWorkStackCursor, fiber);
10777 pop(contextStackCursor, fiber);
10778 }
10779}
10780
10781function pushTopLevelContextObject(fiber, context, didChange) {
10782 {
10783 if (!(contextStackCursor.current === emptyContextObject)) {
10784 {
10785 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
10786 }
10787 }
10788
10789 push(contextStackCursor, context, fiber);
10790 push(didPerformWorkStackCursor, didChange, fiber);
10791 }
10792}
10793
10794function processChildContext(fiber, type, parentContext) {
10795 {
10796 var instance = fiber.stateNode;
10797 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
10798 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
10799
10800 if (typeof instance.getChildContext !== 'function') {
10801 {
10802 var componentName = getComponentName(type) || 'Unknown';
10803
10804 if (!warnedAboutMissingGetChildContext[componentName]) {
10805 warnedAboutMissingGetChildContext[componentName] = true;
10806
10807 error('%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
10808 }
10809 }
10810
10811 return parentContext;
10812 }
10813
10814 var childContext;
10815 startPhaseTimer(fiber, 'getChildContext');
10816 childContext = instance.getChildContext();
10817 stopPhaseTimer();
10818
10819 for (var contextKey in childContext) {
10820 if (!(contextKey in childContextTypes)) {
10821 {
10822 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
10823 }
10824 }
10825 }
10826
10827 {
10828 var name = getComponentName(type) || 'Unknown';
10829 checkPropTypes(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
10830 // somebody calls unstable_renderSubtreeIntoContainer() and we process
10831 // context from the parent component instance. The stack will be missing
10832 // because it's outside of the reconciliation, and so the pointer has not
10833 // been set. This is rare and doesn't matter. We'll also remove that API.
10834 getCurrentFiberStackInDev);
10835 }
10836
10837 return _assign({}, parentContext, {}, childContext);
10838 }
10839}
10840
10841function pushContextProvider(workInProgress) {
10842 {
10843 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
10844 // If the instance does not exist yet, we will push null at first,
10845 // and replace it on the stack later when invalidating the context.
10846
10847 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
10848 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
10849
10850 previousContext = contextStackCursor.current;
10851 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
10852 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
10853 return true;
10854 }
10855}
10856
10857function invalidateContextProvider(workInProgress, type, didChange) {
10858 {
10859 var instance = workInProgress.stateNode;
10860
10861 if (!instance) {
10862 {
10863 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
10864 }
10865 }
10866
10867 if (didChange) {
10868 // Merge parent and own context.
10869 // Skip this if we're not updating due to sCU.
10870 // This avoids unnecessarily recomputing memoized values.
10871 var mergedContext = processChildContext(workInProgress, type, previousContext);
10872 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
10873 // It is important to unwind the context in the reverse order.
10874
10875 pop(didPerformWorkStackCursor, workInProgress);
10876 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
10877
10878 push(contextStackCursor, mergedContext, workInProgress);
10879 push(didPerformWorkStackCursor, didChange, workInProgress);
10880 } else {
10881 pop(didPerformWorkStackCursor, workInProgress);
10882 push(didPerformWorkStackCursor, didChange, workInProgress);
10883 }
10884 }
10885}
10886
10887function findCurrentUnmaskedContext(fiber) {
10888 {
10889 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
10890 // makes sense elsewhere
10891 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
10892 {
10893 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." );
10894 }
10895 }
10896
10897 var node = fiber;
10898
10899 do {
10900 switch (node.tag) {
10901 case HostRoot:
10902 return node.stateNode.context;
10903
10904 case ClassComponent:
10905 {
10906 var Component = node.type;
10907
10908 if (isContextProvider(Component)) {
10909 return node.stateNode.__reactInternalMemoizedMergedChildContext;
10910 }
10911
10912 break;
10913 }
10914 }
10915
10916 node = node.return;
10917 } while (node !== null);
10918
10919 {
10920 {
10921 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
10922 }
10923 }
10924 }
10925}
10926
10927var LegacyRoot = 0;
10928var BlockingRoot = 1;
10929var ConcurrentRoot = 2;
10930
10931var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority,
10932 Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback,
10933 Scheduler_cancelCallback = Scheduler.unstable_cancelCallback,
10934 Scheduler_shouldYield = Scheduler.unstable_shouldYield,
10935 Scheduler_requestPaint = Scheduler.unstable_requestPaint,
10936 Scheduler_now = Scheduler.unstable_now,
10937 Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,
10938 Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority,
10939 Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,
10940 Scheduler_NormalPriority = Scheduler.unstable_NormalPriority,
10941 Scheduler_LowPriority = Scheduler.unstable_LowPriority,
10942 Scheduler_IdlePriority = Scheduler.unstable_IdlePriority;
10943
10944{
10945 // Provide explicit error message when production+profiling bundle of e.g.
10946 // react-dom is used with production (non-profiling) bundle of
10947 // scheduler/tracing
10948 if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {
10949 {
10950 throw Error( "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" );
10951 }
10952 }
10953}
10954
10955var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
10956// ascending numbers so we can compare them like numbers. They start at 90 to
10957// avoid clashing with Scheduler's priorities.
10958
10959var ImmediatePriority = 99;
10960var UserBlockingPriority$1 = 98;
10961var NormalPriority = 97;
10962var LowPriority = 96;
10963var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
10964
10965var NoPriority = 90;
10966var shouldYield = Scheduler_shouldYield;
10967var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
10968Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
10969var syncQueue = null;
10970var immediateQueueCallbackNode = null;
10971var isFlushingSyncQueue = false;
10972var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
10973// This will be the case for modern browsers that support `performance.now`. In
10974// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
10975// timestamp. In that case, subtract the module initialization time to simulate
10976// the behavior of performance.now and keep our times small enough to fit
10977// within 32 bits.
10978// TODO: Consider lifting this into Scheduler.
10979
10980var now = initialTimeMs < 10000 ? Scheduler_now : function () {
10981 return Scheduler_now() - initialTimeMs;
10982};
10983function getCurrentPriorityLevel() {
10984 switch (Scheduler_getCurrentPriorityLevel()) {
10985 case Scheduler_ImmediatePriority:
10986 return ImmediatePriority;
10987
10988 case Scheduler_UserBlockingPriority:
10989 return UserBlockingPriority$1;
10990
10991 case Scheduler_NormalPriority:
10992 return NormalPriority;
10993
10994 case Scheduler_LowPriority:
10995 return LowPriority;
10996
10997 case Scheduler_IdlePriority:
10998 return IdlePriority;
10999
11000 default:
11001 {
11002 {
11003 throw Error( "Unknown priority level." );
11004 }
11005 }
11006
11007 }
11008}
11009
11010function reactPriorityToSchedulerPriority(reactPriorityLevel) {
11011 switch (reactPriorityLevel) {
11012 case ImmediatePriority:
11013 return Scheduler_ImmediatePriority;
11014
11015 case UserBlockingPriority$1:
11016 return Scheduler_UserBlockingPriority;
11017
11018 case NormalPriority:
11019 return Scheduler_NormalPriority;
11020
11021 case LowPriority:
11022 return Scheduler_LowPriority;
11023
11024 case IdlePriority:
11025 return Scheduler_IdlePriority;
11026
11027 default:
11028 {
11029 {
11030 throw Error( "Unknown priority level." );
11031 }
11032 }
11033
11034 }
11035}
11036
11037function runWithPriority$1(reactPriorityLevel, fn) {
11038 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11039 return Scheduler_runWithPriority(priorityLevel, fn);
11040}
11041function scheduleCallback(reactPriorityLevel, callback, options) {
11042 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11043 return Scheduler_scheduleCallback(priorityLevel, callback, options);
11044}
11045function scheduleSyncCallback(callback) {
11046 // Push this callback into an internal queue. We'll flush these either in
11047 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
11048 if (syncQueue === null) {
11049 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
11050
11051 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
11052 } else {
11053 // Push onto existing queue. Don't need to schedule a callback because
11054 // we already scheduled one when we created the queue.
11055 syncQueue.push(callback);
11056 }
11057
11058 return fakeCallbackNode;
11059}
11060function cancelCallback(callbackNode) {
11061 if (callbackNode !== fakeCallbackNode) {
11062 Scheduler_cancelCallback(callbackNode);
11063 }
11064}
11065function flushSyncCallbackQueue() {
11066 if (immediateQueueCallbackNode !== null) {
11067 var node = immediateQueueCallbackNode;
11068 immediateQueueCallbackNode = null;
11069 Scheduler_cancelCallback(node);
11070 }
11071
11072 flushSyncCallbackQueueImpl();
11073}
11074
11075function flushSyncCallbackQueueImpl() {
11076 if (!isFlushingSyncQueue && syncQueue !== null) {
11077 // Prevent re-entrancy.
11078 isFlushingSyncQueue = true;
11079 var i = 0;
11080
11081 try {
11082 var _isSync = true;
11083 var queue = syncQueue;
11084 runWithPriority$1(ImmediatePriority, function () {
11085 for (; i < queue.length; i++) {
11086 var callback = queue[i];
11087
11088 do {
11089 callback = callback(_isSync);
11090 } while (callback !== null);
11091 }
11092 });
11093 syncQueue = null;
11094 } catch (error) {
11095 // If something throws, leave the remaining callbacks on the queue.
11096 if (syncQueue !== null) {
11097 syncQueue = syncQueue.slice(i + 1);
11098 } // Resume flushing in the next tick
11099
11100
11101 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
11102 throw error;
11103 } finally {
11104 isFlushingSyncQueue = false;
11105 }
11106 }
11107}
11108
11109var NoMode = 0;
11110var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
11111// tag instead
11112
11113var BlockingMode = 2;
11114var ConcurrentMode = 4;
11115var ProfileMode = 8;
11116
11117// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
11118// Math.pow(2, 30) - 1
11119// 0b111111111111111111111111111111
11120var MAX_SIGNED_31_BIT_INT = 1073741823;
11121
11122var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
11123// Never work can be committed in an inconsistent state without tearing the UI.
11124// The main example is offscreen content, like a hidden subtree. So one possible
11125// name is Offscreen. However, it also includes dehydrated Suspense boundaries,
11126// which are inconsistent in the sense that they haven't finished yet, but
11127// aren't visibly inconsistent because the server rendered HTML matches what the
11128// hydrated tree would look like.
11129
11130var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
11131// order to be consistent.
11132
11133var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase
11134// priority of hover targets.
11135
11136var ContinuousHydration = 3;
11137var Sync = MAX_SIGNED_31_BIT_INT;
11138var Batched = Sync - 1;
11139var UNIT_SIZE = 10;
11140var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
11141
11142function msToExpirationTime(ms) {
11143 // Always subtract from the offset so that we don't clash with the magic number for NoWork.
11144 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
11145}
11146function expirationTimeToMs(expirationTime) {
11147 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
11148}
11149
11150function ceiling(num, precision) {
11151 return ((num / precision | 0) + 1) * precision;
11152}
11153
11154function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
11155 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
11156} // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
11157// the names to reflect.
11158
11159
11160var LOW_PRIORITY_EXPIRATION = 5000;
11161var LOW_PRIORITY_BATCH_SIZE = 250;
11162function computeAsyncExpiration(currentTime) {
11163 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
11164}
11165function computeSuspenseExpiration(currentTime, timeoutMs) {
11166 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
11167 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
11168} // We intentionally set a higher expiration time for interactive updates in
11169// dev than in production.
11170//
11171// If the main thread is being blocked so long that you hit the expiration,
11172// it's a problem that could be solved with better scheduling.
11173//
11174// People will be more likely to notice this and fix it with the long
11175// expiration time in development.
11176//
11177// In production we opt for better UX at the risk of masking scheduling
11178// problems, by expiring fast.
11179
11180var HIGH_PRIORITY_EXPIRATION = 500 ;
11181var HIGH_PRIORITY_BATCH_SIZE = 100;
11182function computeInteractiveExpiration(currentTime) {
11183 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
11184}
11185function inferPriorityFromExpirationTime(currentTime, expirationTime) {
11186 if (expirationTime === Sync) {
11187 return ImmediatePriority;
11188 }
11189
11190 if (expirationTime === Never || expirationTime === Idle) {
11191 return IdlePriority;
11192 }
11193
11194 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
11195
11196 if (msUntil <= 0) {
11197 return ImmediatePriority;
11198 }
11199
11200 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
11201 return UserBlockingPriority$1;
11202 }
11203
11204 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
11205 return NormalPriority;
11206 } // TODO: Handle LowPriority
11207 // Assume anything lower has idle priority
11208
11209
11210 return IdlePriority;
11211}
11212
11213var ReactStrictModeWarnings = {
11214 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
11215 flushPendingUnsafeLifecycleWarnings: function () {},
11216 recordLegacyContextWarning: function (fiber, instance) {},
11217 flushLegacyContextWarning: function () {},
11218 discardPendingWarnings: function () {}
11219};
11220
11221{
11222 var findStrictRoot = function (fiber) {
11223 var maybeStrictRoot = null;
11224 var node = fiber;
11225
11226 while (node !== null) {
11227 if (node.mode & StrictMode) {
11228 maybeStrictRoot = node;
11229 }
11230
11231 node = node.return;
11232 }
11233
11234 return maybeStrictRoot;
11235 };
11236
11237 var setToSortedString = function (set) {
11238 var array = [];
11239 set.forEach(function (value) {
11240 array.push(value);
11241 });
11242 return array.sort().join(', ');
11243 };
11244
11245 var pendingComponentWillMountWarnings = [];
11246 var pendingUNSAFE_ComponentWillMountWarnings = [];
11247 var pendingComponentWillReceivePropsWarnings = [];
11248 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11249 var pendingComponentWillUpdateWarnings = [];
11250 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
11251
11252 var didWarnAboutUnsafeLifecycles = new Set();
11253
11254 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
11255 // Dedup strategy: Warn once per component.
11256 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
11257 return;
11258 }
11259
11260 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
11261 instance.componentWillMount.__suppressDeprecationWarning !== true) {
11262 pendingComponentWillMountWarnings.push(fiber);
11263 }
11264
11265 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
11266 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
11267 }
11268
11269 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11270 pendingComponentWillReceivePropsWarnings.push(fiber);
11271 }
11272
11273 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11274 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
11275 }
11276
11277 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11278 pendingComponentWillUpdateWarnings.push(fiber);
11279 }
11280
11281 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
11282 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
11283 }
11284 };
11285
11286 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
11287 // We do an initial pass to gather component names
11288 var componentWillMountUniqueNames = new Set();
11289
11290 if (pendingComponentWillMountWarnings.length > 0) {
11291 pendingComponentWillMountWarnings.forEach(function (fiber) {
11292 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11293 didWarnAboutUnsafeLifecycles.add(fiber.type);
11294 });
11295 pendingComponentWillMountWarnings = [];
11296 }
11297
11298 var UNSAFE_componentWillMountUniqueNames = new Set();
11299
11300 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
11301 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
11302 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11303 didWarnAboutUnsafeLifecycles.add(fiber.type);
11304 });
11305 pendingUNSAFE_ComponentWillMountWarnings = [];
11306 }
11307
11308 var componentWillReceivePropsUniqueNames = new Set();
11309
11310 if (pendingComponentWillReceivePropsWarnings.length > 0) {
11311 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
11312 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11313 didWarnAboutUnsafeLifecycles.add(fiber.type);
11314 });
11315 pendingComponentWillReceivePropsWarnings = [];
11316 }
11317
11318 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
11319
11320 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
11321 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
11322 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11323 didWarnAboutUnsafeLifecycles.add(fiber.type);
11324 });
11325 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11326 }
11327
11328 var componentWillUpdateUniqueNames = new Set();
11329
11330 if (pendingComponentWillUpdateWarnings.length > 0) {
11331 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
11332 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11333 didWarnAboutUnsafeLifecycles.add(fiber.type);
11334 });
11335 pendingComponentWillUpdateWarnings = [];
11336 }
11337
11338 var UNSAFE_componentWillUpdateUniqueNames = new Set();
11339
11340 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
11341 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
11342 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11343 didWarnAboutUnsafeLifecycles.add(fiber.type);
11344 });
11345 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11346 } // Finally, we flush all the warnings
11347 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
11348
11349
11350 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
11351 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
11352
11353 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
11354 }
11355
11356 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
11357 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
11358
11359 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
11360 }
11361
11362 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
11363 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
11364
11365 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
11366 }
11367
11368 if (componentWillMountUniqueNames.size > 0) {
11369 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
11370
11371 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
11372 }
11373
11374 if (componentWillReceivePropsUniqueNames.size > 0) {
11375 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
11376
11377 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
11378 }
11379
11380 if (componentWillUpdateUniqueNames.size > 0) {
11381 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
11382
11383 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
11384 }
11385 };
11386
11387 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
11388
11389 var didWarnAboutLegacyContext = new Set();
11390
11391 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
11392 var strictRoot = findStrictRoot(fiber);
11393
11394 if (strictRoot === null) {
11395 error('Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11396
11397 return;
11398 } // Dedup strategy: Warn once per component.
11399
11400
11401 if (didWarnAboutLegacyContext.has(fiber.type)) {
11402 return;
11403 }
11404
11405 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
11406
11407 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
11408 if (warningsForRoot === undefined) {
11409 warningsForRoot = [];
11410 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
11411 }
11412
11413 warningsForRoot.push(fiber);
11414 }
11415 };
11416
11417 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
11418 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
11419 if (fiberArray.length === 0) {
11420 return;
11421 }
11422
11423 var firstFiber = fiberArray[0];
11424 var uniqueNames = new Set();
11425 fiberArray.forEach(function (fiber) {
11426 uniqueNames.add(getComponentName(fiber.type) || 'Component');
11427 didWarnAboutLegacyContext.add(fiber.type);
11428 });
11429 var sortedNames = setToSortedString(uniqueNames);
11430 var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
11431
11432 error('Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' + '%s', sortedNames, firstComponentStack);
11433 });
11434 };
11435
11436 ReactStrictModeWarnings.discardPendingWarnings = function () {
11437 pendingComponentWillMountWarnings = [];
11438 pendingUNSAFE_ComponentWillMountWarnings = [];
11439 pendingComponentWillReceivePropsWarnings = [];
11440 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11441 pendingComponentWillUpdateWarnings = [];
11442 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11443 pendingLegacyContextWarning = new Map();
11444 };
11445}
11446
11447var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
11448
11449var failedBoundaries = null;
11450var setRefreshHandler = function (handler) {
11451 {
11452 resolveFamily = handler;
11453 }
11454};
11455function resolveFunctionForHotReloading(type) {
11456 {
11457 if (resolveFamily === null) {
11458 // Hot reloading is disabled.
11459 return type;
11460 }
11461
11462 var family = resolveFamily(type);
11463
11464 if (family === undefined) {
11465 return type;
11466 } // Use the latest known implementation.
11467
11468
11469 return family.current;
11470 }
11471}
11472function resolveClassForHotReloading(type) {
11473 // No implementation differences.
11474 return resolveFunctionForHotReloading(type);
11475}
11476function resolveForwardRefForHotReloading(type) {
11477 {
11478 if (resolveFamily === null) {
11479 // Hot reloading is disabled.
11480 return type;
11481 }
11482
11483 var family = resolveFamily(type);
11484
11485 if (family === undefined) {
11486 // Check if we're dealing with a real forwardRef. Don't want to crash early.
11487 if (type !== null && type !== undefined && typeof type.render === 'function') {
11488 // ForwardRef is special because its resolved .type is an object,
11489 // but it's possible that we only have its inner render function in the map.
11490 // If that inner render function is different, we'll build a new forwardRef type.
11491 var currentRender = resolveFunctionForHotReloading(type.render);
11492
11493 if (type.render !== currentRender) {
11494 var syntheticType = {
11495 $$typeof: REACT_FORWARD_REF_TYPE,
11496 render: currentRender
11497 };
11498
11499 if (type.displayName !== undefined) {
11500 syntheticType.displayName = type.displayName;
11501 }
11502
11503 return syntheticType;
11504 }
11505 }
11506
11507 return type;
11508 } // Use the latest known implementation.
11509
11510
11511 return family.current;
11512 }
11513}
11514function isCompatibleFamilyForHotReloading(fiber, element) {
11515 {
11516 if (resolveFamily === null) {
11517 // Hot reloading is disabled.
11518 return false;
11519 }
11520
11521 var prevType = fiber.elementType;
11522 var nextType = element.type; // If we got here, we know types aren't === equal.
11523
11524 var needsCompareFamilies = false;
11525 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
11526
11527 switch (fiber.tag) {
11528 case ClassComponent:
11529 {
11530 if (typeof nextType === 'function') {
11531 needsCompareFamilies = true;
11532 }
11533
11534 break;
11535 }
11536
11537 case FunctionComponent:
11538 {
11539 if (typeof nextType === 'function') {
11540 needsCompareFamilies = true;
11541 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11542 // We don't know the inner type yet.
11543 // We're going to assume that the lazy inner type is stable,
11544 // and so it is sufficient to avoid reconciling it away.
11545 // We're not going to unwrap or actually use the new lazy type.
11546 needsCompareFamilies = true;
11547 }
11548
11549 break;
11550 }
11551
11552 case ForwardRef:
11553 {
11554 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
11555 needsCompareFamilies = true;
11556 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11557 needsCompareFamilies = true;
11558 }
11559
11560 break;
11561 }
11562
11563 case MemoComponent:
11564 case SimpleMemoComponent:
11565 {
11566 if ($$typeofNextType === REACT_MEMO_TYPE) {
11567 // TODO: if it was but can no longer be simple,
11568 // we shouldn't set this.
11569 needsCompareFamilies = true;
11570 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11571 needsCompareFamilies = true;
11572 }
11573
11574 break;
11575 }
11576
11577 default:
11578 return false;
11579 } // Check if both types have a family and it's the same one.
11580
11581
11582 if (needsCompareFamilies) {
11583 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
11584 // This means both of them need to be registered to preserve state.
11585 // If we unwrapped and compared the inner types for wrappers instead,
11586 // then we would risk falsely saying two separate memo(Foo)
11587 // calls are equivalent because they wrap the same Foo function.
11588 var prevFamily = resolveFamily(prevType);
11589
11590 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
11591 return true;
11592 }
11593 }
11594
11595 return false;
11596 }
11597}
11598function markFailedErrorBoundaryForHotReloading(fiber) {
11599 {
11600 if (resolveFamily === null) {
11601 // Hot reloading is disabled.
11602 return;
11603 }
11604
11605 if (typeof WeakSet !== 'function') {
11606 return;
11607 }
11608
11609 if (failedBoundaries === null) {
11610 failedBoundaries = new WeakSet();
11611 }
11612
11613 failedBoundaries.add(fiber);
11614 }
11615}
11616var scheduleRefresh = function (root, update) {
11617 {
11618 if (resolveFamily === null) {
11619 // Hot reloading is disabled.
11620 return;
11621 }
11622
11623 var staleFamilies = update.staleFamilies,
11624 updatedFamilies = update.updatedFamilies;
11625 flushPassiveEffects();
11626 flushSync(function () {
11627 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
11628 });
11629 }
11630};
11631var scheduleRoot = function (root, element) {
11632 {
11633 if (root.context !== emptyContextObject) {
11634 // Super edge case: root has a legacy _renderSubtree context
11635 // but we don't know the parentComponent so we can't pass it.
11636 // Just ignore. We'll delete this with _renderSubtree code path later.
11637 return;
11638 }
11639
11640 flushPassiveEffects();
11641 syncUpdates(function () {
11642 updateContainer(element, root, null, null);
11643 });
11644 }
11645};
11646
11647function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
11648 {
11649 var alternate = fiber.alternate,
11650 child = fiber.child,
11651 sibling = fiber.sibling,
11652 tag = fiber.tag,
11653 type = fiber.type;
11654 var candidateType = null;
11655
11656 switch (tag) {
11657 case FunctionComponent:
11658 case SimpleMemoComponent:
11659 case ClassComponent:
11660 candidateType = type;
11661 break;
11662
11663 case ForwardRef:
11664 candidateType = type.render;
11665 break;
11666 }
11667
11668 if (resolveFamily === null) {
11669 throw new Error('Expected resolveFamily to be set during hot reload.');
11670 }
11671
11672 var needsRender = false;
11673 var needsRemount = false;
11674
11675 if (candidateType !== null) {
11676 var family = resolveFamily(candidateType);
11677
11678 if (family !== undefined) {
11679 if (staleFamilies.has(family)) {
11680 needsRemount = true;
11681 } else if (updatedFamilies.has(family)) {
11682 if (tag === ClassComponent) {
11683 needsRemount = true;
11684 } else {
11685 needsRender = true;
11686 }
11687 }
11688 }
11689 }
11690
11691 if (failedBoundaries !== null) {
11692 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
11693 needsRemount = true;
11694 }
11695 }
11696
11697 if (needsRemount) {
11698 fiber._debugNeedsRemount = true;
11699 }
11700
11701 if (needsRemount || needsRender) {
11702 scheduleWork(fiber, Sync);
11703 }
11704
11705 if (child !== null && !needsRemount) {
11706 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
11707 }
11708
11709 if (sibling !== null) {
11710 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
11711 }
11712 }
11713}
11714
11715var findHostInstancesForRefresh = function (root, families) {
11716 {
11717 var hostInstances = new Set();
11718 var types = new Set(families.map(function (family) {
11719 return family.current;
11720 }));
11721 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
11722 return hostInstances;
11723 }
11724};
11725
11726function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
11727 {
11728 var child = fiber.child,
11729 sibling = fiber.sibling,
11730 tag = fiber.tag,
11731 type = fiber.type;
11732 var candidateType = null;
11733
11734 switch (tag) {
11735 case FunctionComponent:
11736 case SimpleMemoComponent:
11737 case ClassComponent:
11738 candidateType = type;
11739 break;
11740
11741 case ForwardRef:
11742 candidateType = type.render;
11743 break;
11744 }
11745
11746 var didMatch = false;
11747
11748 if (candidateType !== null) {
11749 if (types.has(candidateType)) {
11750 didMatch = true;
11751 }
11752 }
11753
11754 if (didMatch) {
11755 // We have a match. This only drills down to the closest host components.
11756 // There's no need to search deeper because for the purpose of giving
11757 // visual feedback, "flashing" outermost parent rectangles is sufficient.
11758 findHostInstancesForFiberShallowly(fiber, hostInstances);
11759 } else {
11760 // If there's no match, maybe there will be one further down in the child tree.
11761 if (child !== null) {
11762 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
11763 }
11764 }
11765
11766 if (sibling !== null) {
11767 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
11768 }
11769 }
11770}
11771
11772function findHostInstancesForFiberShallowly(fiber, hostInstances) {
11773 {
11774 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
11775
11776 if (foundHostInstances) {
11777 return;
11778 } // If we didn't find any host children, fallback to closest host parent.
11779
11780
11781 var node = fiber;
11782
11783 while (true) {
11784 switch (node.tag) {
11785 case HostComponent:
11786 hostInstances.add(node.stateNode);
11787 return;
11788
11789 case HostPortal:
11790 hostInstances.add(node.stateNode.containerInfo);
11791 return;
11792
11793 case HostRoot:
11794 hostInstances.add(node.stateNode.containerInfo);
11795 return;
11796 }
11797
11798 if (node.return === null) {
11799 throw new Error('Expected to reach root first.');
11800 }
11801
11802 node = node.return;
11803 }
11804 }
11805}
11806
11807function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
11808 {
11809 var node = fiber;
11810 var foundHostInstances = false;
11811
11812 while (true) {
11813 if (node.tag === HostComponent) {
11814 // We got a match.
11815 foundHostInstances = true;
11816 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
11817 } else if (node.child !== null) {
11818 node.child.return = node;
11819 node = node.child;
11820 continue;
11821 }
11822
11823 if (node === fiber) {
11824 return foundHostInstances;
11825 }
11826
11827 while (node.sibling === null) {
11828 if (node.return === null || node.return === fiber) {
11829 return foundHostInstances;
11830 }
11831
11832 node = node.return;
11833 }
11834
11835 node.sibling.return = node.return;
11836 node = node.sibling;
11837 }
11838 }
11839
11840 return false;
11841}
11842
11843function resolveDefaultProps(Component, baseProps) {
11844 if (Component && Component.defaultProps) {
11845 // Resolve default props. Taken from ReactElement
11846 var props = _assign({}, baseProps);
11847
11848 var defaultProps = Component.defaultProps;
11849
11850 for (var propName in defaultProps) {
11851 if (props[propName] === undefined) {
11852 props[propName] = defaultProps[propName];
11853 }
11854 }
11855
11856 return props;
11857 }
11858
11859 return baseProps;
11860}
11861function readLazyComponentType(lazyComponent) {
11862 initializeLazyComponentType(lazyComponent);
11863
11864 if (lazyComponent._status !== Resolved) {
11865 throw lazyComponent._result;
11866 }
11867
11868 return lazyComponent._result;
11869}
11870
11871var valueCursor = createCursor(null);
11872var rendererSigil;
11873
11874{
11875 // Use this to detect multiple renderers using the same context
11876 rendererSigil = {};
11877}
11878
11879var currentlyRenderingFiber = null;
11880var lastContextDependency = null;
11881var lastContextWithAllBitsObserved = null;
11882var isDisallowedContextReadInDEV = false;
11883function resetContextDependencies() {
11884 // This is called right before React yields execution, to ensure `readContext`
11885 // cannot be called outside the render phase.
11886 currentlyRenderingFiber = null;
11887 lastContextDependency = null;
11888 lastContextWithAllBitsObserved = null;
11889
11890 {
11891 isDisallowedContextReadInDEV = false;
11892 }
11893}
11894function enterDisallowedContextReadInDEV() {
11895 {
11896 isDisallowedContextReadInDEV = true;
11897 }
11898}
11899function exitDisallowedContextReadInDEV() {
11900 {
11901 isDisallowedContextReadInDEV = false;
11902 }
11903}
11904function pushProvider(providerFiber, nextValue) {
11905 var context = providerFiber.type._context;
11906
11907 {
11908 push(valueCursor, context._currentValue, providerFiber);
11909 context._currentValue = nextValue;
11910
11911 {
11912 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
11913 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
11914 }
11915
11916 context._currentRenderer = rendererSigil;
11917 }
11918 }
11919}
11920function popProvider(providerFiber) {
11921 var currentValue = valueCursor.current;
11922 pop(valueCursor, providerFiber);
11923 var context = providerFiber.type._context;
11924
11925 {
11926 context._currentValue = currentValue;
11927 }
11928}
11929function calculateChangedBits(context, newValue, oldValue) {
11930 if (objectIs(oldValue, newValue)) {
11931 // No change
11932 return 0;
11933 } else {
11934 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
11935
11936 {
11937 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
11938 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
11939 }
11940 }
11941
11942 return changedBits | 0;
11943 }
11944}
11945function scheduleWorkOnParentPath(parent, renderExpirationTime) {
11946 // Update the child expiration time of all the ancestors, including
11947 // the alternates.
11948 var node = parent;
11949
11950 while (node !== null) {
11951 var alternate = node.alternate;
11952
11953 if (node.childExpirationTime < renderExpirationTime) {
11954 node.childExpirationTime = renderExpirationTime;
11955
11956 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
11957 alternate.childExpirationTime = renderExpirationTime;
11958 }
11959 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
11960 alternate.childExpirationTime = renderExpirationTime;
11961 } else {
11962 // Neither alternate was updated, which means the rest of the
11963 // ancestor path already has sufficient priority.
11964 break;
11965 }
11966
11967 node = node.return;
11968 }
11969}
11970function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
11971 var fiber = workInProgress.child;
11972
11973 if (fiber !== null) {
11974 // Set the return pointer of the child to the work-in-progress fiber.
11975 fiber.return = workInProgress;
11976 }
11977
11978 while (fiber !== null) {
11979 var nextFiber = void 0; // Visit this fiber.
11980
11981 var list = fiber.dependencies;
11982
11983 if (list !== null) {
11984 nextFiber = fiber.child;
11985 var dependency = list.firstContext;
11986
11987 while (dependency !== null) {
11988 // Check if the context matches.
11989 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
11990 // Match! Schedule an update on this fiber.
11991 if (fiber.tag === ClassComponent) {
11992 // Schedule a force update on the work-in-progress.
11993 var update = createUpdate(renderExpirationTime, null);
11994 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
11995 // update to the current fiber, too, which means it will persist even if
11996 // this render is thrown away. Since it's a race condition, not sure it's
11997 // worth fixing.
11998
11999 enqueueUpdate(fiber, update);
12000 }
12001
12002 if (fiber.expirationTime < renderExpirationTime) {
12003 fiber.expirationTime = renderExpirationTime;
12004 }
12005
12006 var alternate = fiber.alternate;
12007
12008 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
12009 alternate.expirationTime = renderExpirationTime;
12010 }
12011
12012 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
12013
12014 if (list.expirationTime < renderExpirationTime) {
12015 list.expirationTime = renderExpirationTime;
12016 } // Since we already found a match, we can stop traversing the
12017 // dependency list.
12018
12019
12020 break;
12021 }
12022
12023 dependency = dependency.next;
12024 }
12025 } else if (fiber.tag === ContextProvider) {
12026 // Don't scan deeper if this is a matching provider
12027 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
12028 } else {
12029 // Traverse down.
12030 nextFiber = fiber.child;
12031 }
12032
12033 if (nextFiber !== null) {
12034 // Set the return pointer of the child to the work-in-progress fiber.
12035 nextFiber.return = fiber;
12036 } else {
12037 // No child. Traverse to next sibling.
12038 nextFiber = fiber;
12039
12040 while (nextFiber !== null) {
12041 if (nextFiber === workInProgress) {
12042 // We're back to the root of this subtree. Exit.
12043 nextFiber = null;
12044 break;
12045 }
12046
12047 var sibling = nextFiber.sibling;
12048
12049 if (sibling !== null) {
12050 // Set the return pointer of the sibling to the work-in-progress fiber.
12051 sibling.return = nextFiber.return;
12052 nextFiber = sibling;
12053 break;
12054 } // No more siblings. Traverse up.
12055
12056
12057 nextFiber = nextFiber.return;
12058 }
12059 }
12060
12061 fiber = nextFiber;
12062 }
12063}
12064function prepareToReadContext(workInProgress, renderExpirationTime) {
12065 currentlyRenderingFiber = workInProgress;
12066 lastContextDependency = null;
12067 lastContextWithAllBitsObserved = null;
12068 var dependencies = workInProgress.dependencies;
12069
12070 if (dependencies !== null) {
12071 var firstContext = dependencies.firstContext;
12072
12073 if (firstContext !== null) {
12074 if (dependencies.expirationTime >= renderExpirationTime) {
12075 // Context list has a pending update. Mark that this fiber performed work.
12076 markWorkInProgressReceivedUpdate();
12077 } // Reset the work-in-progress list
12078
12079
12080 dependencies.firstContext = null;
12081 }
12082 }
12083}
12084function readContext(context, observedBits) {
12085 {
12086 // This warning would fire if you read context inside a Hook like useMemo.
12087 // Unlike the class check below, it's not enforced in production for perf.
12088 if (isDisallowedContextReadInDEV) {
12089 error('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().');
12090 }
12091 }
12092
12093 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
12094 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
12095
12096 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
12097 // Observe all updates.
12098 lastContextWithAllBitsObserved = context;
12099 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
12100 } else {
12101 resolvedObservedBits = observedBits;
12102 }
12103
12104 var contextItem = {
12105 context: context,
12106 observedBits: resolvedObservedBits,
12107 next: null
12108 };
12109
12110 if (lastContextDependency === null) {
12111 if (!(currentlyRenderingFiber !== null)) {
12112 {
12113 throw Error( "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()." );
12114 }
12115 } // This is the first dependency for this component. Create a new list.
12116
12117
12118 lastContextDependency = contextItem;
12119 currentlyRenderingFiber.dependencies = {
12120 expirationTime: NoWork,
12121 firstContext: contextItem,
12122 responders: null
12123 };
12124 } else {
12125 // Append a new context item.
12126 lastContextDependency = lastContextDependency.next = contextItem;
12127 }
12128 }
12129
12130 return context._currentValue ;
12131}
12132
12133var UpdateState = 0;
12134var ReplaceState = 1;
12135var ForceUpdate = 2;
12136var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
12137// It should only be read right after calling `processUpdateQueue`, via
12138// `checkHasForceUpdateAfterProcessing`.
12139
12140var hasForceUpdate = false;
12141var didWarnUpdateInsideUpdate;
12142var currentlyProcessingQueue;
12143
12144{
12145 didWarnUpdateInsideUpdate = false;
12146 currentlyProcessingQueue = null;
12147}
12148
12149function initializeUpdateQueue(fiber) {
12150 var queue = {
12151 baseState: fiber.memoizedState,
12152 baseQueue: null,
12153 shared: {
12154 pending: null
12155 },
12156 effects: null
12157 };
12158 fiber.updateQueue = queue;
12159}
12160function cloneUpdateQueue(current, workInProgress) {
12161 // Clone the update queue from current. Unless it's already a clone.
12162 var queue = workInProgress.updateQueue;
12163 var currentQueue = current.updateQueue;
12164
12165 if (queue === currentQueue) {
12166 var clone = {
12167 baseState: currentQueue.baseState,
12168 baseQueue: currentQueue.baseQueue,
12169 shared: currentQueue.shared,
12170 effects: currentQueue.effects
12171 };
12172 workInProgress.updateQueue = clone;
12173 }
12174}
12175function createUpdate(expirationTime, suspenseConfig) {
12176 var update = {
12177 expirationTime: expirationTime,
12178 suspenseConfig: suspenseConfig,
12179 tag: UpdateState,
12180 payload: null,
12181 callback: null,
12182 next: null
12183 };
12184 update.next = update;
12185
12186 {
12187 update.priority = getCurrentPriorityLevel();
12188 }
12189
12190 return update;
12191}
12192function enqueueUpdate(fiber, update) {
12193 var updateQueue = fiber.updateQueue;
12194
12195 if (updateQueue === null) {
12196 // Only occurs if the fiber has been unmounted.
12197 return;
12198 }
12199
12200 var sharedQueue = updateQueue.shared;
12201 var pending = sharedQueue.pending;
12202
12203 if (pending === null) {
12204 // This is the first update. Create a circular list.
12205 update.next = update;
12206 } else {
12207 update.next = pending.next;
12208 pending.next = update;
12209 }
12210
12211 sharedQueue.pending = update;
12212
12213 {
12214 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
12215 error('An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
12216
12217 didWarnUpdateInsideUpdate = true;
12218 }
12219 }
12220}
12221function enqueueCapturedUpdate(workInProgress, update) {
12222 var current = workInProgress.alternate;
12223
12224 if (current !== null) {
12225 // Ensure the work-in-progress queue is a clone
12226 cloneUpdateQueue(current, workInProgress);
12227 } // Captured updates go only on the work-in-progress queue.
12228
12229
12230 var queue = workInProgress.updateQueue; // Append the update to the end of the list.
12231
12232 var last = queue.baseQueue;
12233
12234 if (last === null) {
12235 queue.baseQueue = update.next = update;
12236 update.next = update;
12237 } else {
12238 update.next = last.next;
12239 last.next = update;
12240 }
12241}
12242
12243function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
12244 switch (update.tag) {
12245 case ReplaceState:
12246 {
12247 var payload = update.payload;
12248
12249 if (typeof payload === 'function') {
12250 // Updater function
12251 {
12252 enterDisallowedContextReadInDEV();
12253
12254 if ( workInProgress.mode & StrictMode) {
12255 payload.call(instance, prevState, nextProps);
12256 }
12257 }
12258
12259 var nextState = payload.call(instance, prevState, nextProps);
12260
12261 {
12262 exitDisallowedContextReadInDEV();
12263 }
12264
12265 return nextState;
12266 } // State object
12267
12268
12269 return payload;
12270 }
12271
12272 case CaptureUpdate:
12273 {
12274 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
12275 }
12276 // Intentional fallthrough
12277
12278 case UpdateState:
12279 {
12280 var _payload = update.payload;
12281 var partialState;
12282
12283 if (typeof _payload === 'function') {
12284 // Updater function
12285 {
12286 enterDisallowedContextReadInDEV();
12287
12288 if ( workInProgress.mode & StrictMode) {
12289 _payload.call(instance, prevState, nextProps);
12290 }
12291 }
12292
12293 partialState = _payload.call(instance, prevState, nextProps);
12294
12295 {
12296 exitDisallowedContextReadInDEV();
12297 }
12298 } else {
12299 // Partial state object
12300 partialState = _payload;
12301 }
12302
12303 if (partialState === null || partialState === undefined) {
12304 // Null and undefined are treated as no-ops.
12305 return prevState;
12306 } // Merge the partial state and the previous state.
12307
12308
12309 return _assign({}, prevState, partialState);
12310 }
12311
12312 case ForceUpdate:
12313 {
12314 hasForceUpdate = true;
12315 return prevState;
12316 }
12317 }
12318
12319 return prevState;
12320}
12321
12322function processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {
12323 // This is always non-null on a ClassComponent or HostRoot
12324 var queue = workInProgress.updateQueue;
12325 hasForceUpdate = false;
12326
12327 {
12328 currentlyProcessingQueue = queue.shared;
12329 } // The last rebase update that is NOT part of the base state.
12330
12331
12332 var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.
12333
12334 var pendingQueue = queue.shared.pending;
12335
12336 if (pendingQueue !== null) {
12337 // We have new updates that haven't been processed yet.
12338 // We'll add them to the base queue.
12339 if (baseQueue !== null) {
12340 // Merge the pending queue and the base queue.
12341 var baseFirst = baseQueue.next;
12342 var pendingFirst = pendingQueue.next;
12343 baseQueue.next = pendingFirst;
12344 pendingQueue.next = baseFirst;
12345 }
12346
12347 baseQueue = pendingQueue;
12348 queue.shared.pending = null; // TODO: Pass `current` as argument
12349
12350 var current = workInProgress.alternate;
12351
12352 if (current !== null) {
12353 var currentQueue = current.updateQueue;
12354
12355 if (currentQueue !== null) {
12356 currentQueue.baseQueue = pendingQueue;
12357 }
12358 }
12359 } // These values may change as we process the queue.
12360
12361
12362 if (baseQueue !== null) {
12363 var first = baseQueue.next; // Iterate through the list of updates to compute the result.
12364
12365 var newState = queue.baseState;
12366 var newExpirationTime = NoWork;
12367 var newBaseState = null;
12368 var newBaseQueueFirst = null;
12369 var newBaseQueueLast = null;
12370
12371 if (first !== null) {
12372 var update = first;
12373
12374 do {
12375 var updateExpirationTime = update.expirationTime;
12376
12377 if (updateExpirationTime < renderExpirationTime) {
12378 // Priority is insufficient. Skip this update. If this is the first
12379 // skipped update, the previous update/state is the new base
12380 // update/state.
12381 var clone = {
12382 expirationTime: update.expirationTime,
12383 suspenseConfig: update.suspenseConfig,
12384 tag: update.tag,
12385 payload: update.payload,
12386 callback: update.callback,
12387 next: null
12388 };
12389
12390 if (newBaseQueueLast === null) {
12391 newBaseQueueFirst = newBaseQueueLast = clone;
12392 newBaseState = newState;
12393 } else {
12394 newBaseQueueLast = newBaseQueueLast.next = clone;
12395 } // Update the remaining priority in the queue.
12396
12397
12398 if (updateExpirationTime > newExpirationTime) {
12399 newExpirationTime = updateExpirationTime;
12400 }
12401 } else {
12402 // This update does have sufficient priority.
12403 if (newBaseQueueLast !== null) {
12404 var _clone = {
12405 expirationTime: Sync,
12406 // This update is going to be committed so we never want uncommit it.
12407 suspenseConfig: update.suspenseConfig,
12408 tag: update.tag,
12409 payload: update.payload,
12410 callback: update.callback,
12411 next: null
12412 };
12413 newBaseQueueLast = newBaseQueueLast.next = _clone;
12414 } // Mark the event time of this update as relevant to this render pass.
12415 // TODO: This should ideally use the true event time of this update rather than
12416 // its priority which is a derived and not reverseable value.
12417 // TODO: We should skip this update if it was already committed but currently
12418 // we have no way of detecting the difference between a committed and suspended
12419 // update here.
12420
12421
12422 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
12423
12424 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
12425 var callback = update.callback;
12426
12427 if (callback !== null) {
12428 workInProgress.effectTag |= Callback;
12429 var effects = queue.effects;
12430
12431 if (effects === null) {
12432 queue.effects = [update];
12433 } else {
12434 effects.push(update);
12435 }
12436 }
12437 }
12438
12439 update = update.next;
12440
12441 if (update === null || update === first) {
12442 pendingQueue = queue.shared.pending;
12443
12444 if (pendingQueue === null) {
12445 break;
12446 } else {
12447 // An update was scheduled from inside a reducer. Add the new
12448 // pending updates to the end of the list and keep processing.
12449 update = baseQueue.next = pendingQueue.next;
12450 pendingQueue.next = first;
12451 queue.baseQueue = baseQueue = pendingQueue;
12452 queue.shared.pending = null;
12453 }
12454 }
12455 } while (true);
12456 }
12457
12458 if (newBaseQueueLast === null) {
12459 newBaseState = newState;
12460 } else {
12461 newBaseQueueLast.next = newBaseQueueFirst;
12462 }
12463
12464 queue.baseState = newBaseState;
12465 queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.
12466 // This should be fine because the only two other things that contribute to
12467 // expiration time are props and context. We're already in the middle of the
12468 // begin phase by the time we start processing the queue, so we've already
12469 // dealt with the props. Context in components that specify
12470 // shouldComponentUpdate is tricky; but we'll have to account for
12471 // that regardless.
12472
12473 markUnprocessedUpdateTime(newExpirationTime);
12474 workInProgress.expirationTime = newExpirationTime;
12475 workInProgress.memoizedState = newState;
12476 }
12477
12478 {
12479 currentlyProcessingQueue = null;
12480 }
12481}
12482
12483function callCallback(callback, context) {
12484 if (!(typeof callback === 'function')) {
12485 {
12486 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
12487 }
12488 }
12489
12490 callback.call(context);
12491}
12492
12493function resetHasForceUpdateBeforeProcessing() {
12494 hasForceUpdate = false;
12495}
12496function checkHasForceUpdateAfterProcessing() {
12497 return hasForceUpdate;
12498}
12499function commitUpdateQueue(finishedWork, finishedQueue, instance) {
12500 // Commit the effects
12501 var effects = finishedQueue.effects;
12502 finishedQueue.effects = null;
12503
12504 if (effects !== null) {
12505 for (var i = 0; i < effects.length; i++) {
12506 var effect = effects[i];
12507 var callback = effect.callback;
12508
12509 if (callback !== null) {
12510 effect.callback = null;
12511 callCallback(callback, instance);
12512 }
12513 }
12514 }
12515}
12516
12517var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
12518function requestCurrentSuspenseConfig() {
12519 return ReactCurrentBatchConfig.suspense;
12520}
12521
12522var fakeInternalInstance = {};
12523var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
12524// We'll use it to determine whether we need to initialize legacy refs.
12525
12526var emptyRefsObject = new React.Component().refs;
12527var didWarnAboutStateAssignmentForComponent;
12528var didWarnAboutUninitializedState;
12529var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
12530var didWarnAboutLegacyLifecyclesAndDerivedState;
12531var didWarnAboutUndefinedDerivedState;
12532var warnOnUndefinedDerivedState;
12533var warnOnInvalidCallback;
12534var didWarnAboutDirectlyAssigningPropsToState;
12535var didWarnAboutContextTypeAndContextTypes;
12536var didWarnAboutInvalidateContextType;
12537
12538{
12539 didWarnAboutStateAssignmentForComponent = new Set();
12540 didWarnAboutUninitializedState = new Set();
12541 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
12542 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
12543 didWarnAboutDirectlyAssigningPropsToState = new Set();
12544 didWarnAboutUndefinedDerivedState = new Set();
12545 didWarnAboutContextTypeAndContextTypes = new Set();
12546 didWarnAboutInvalidateContextType = new Set();
12547 var didWarnOnInvalidCallback = new Set();
12548
12549 warnOnInvalidCallback = function (callback, callerName) {
12550 if (callback === null || typeof callback === 'function') {
12551 return;
12552 }
12553
12554 var key = callerName + "_" + callback;
12555
12556 if (!didWarnOnInvalidCallback.has(key)) {
12557 didWarnOnInvalidCallback.add(key);
12558
12559 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
12560 }
12561 };
12562
12563 warnOnUndefinedDerivedState = function (type, partialState) {
12564 if (partialState === undefined) {
12565 var componentName = getComponentName(type) || 'Component';
12566
12567 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
12568 didWarnAboutUndefinedDerivedState.add(componentName);
12569
12570 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
12571 }
12572 }
12573 }; // This is so gross but it's at least non-critical and can be removed if
12574 // it causes problems. This is meant to give a nicer error message for
12575 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
12576 // ...)) which otherwise throws a "_processChildContext is not a function"
12577 // exception.
12578
12579
12580 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
12581 enumerable: false,
12582 value: function () {
12583 {
12584 {
12585 throw Error( "_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)." );
12586 }
12587 }
12588 }
12589 });
12590 Object.freeze(fakeInternalInstance);
12591}
12592
12593function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
12594 var prevState = workInProgress.memoizedState;
12595
12596 {
12597 if ( workInProgress.mode & StrictMode) {
12598 // Invoke the function an extra time to help detect side-effects.
12599 getDerivedStateFromProps(nextProps, prevState);
12600 }
12601 }
12602
12603 var partialState = getDerivedStateFromProps(nextProps, prevState);
12604
12605 {
12606 warnOnUndefinedDerivedState(ctor, partialState);
12607 } // Merge the partial state and the previous state.
12608
12609
12610 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
12611 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
12612 // base state.
12613
12614 if (workInProgress.expirationTime === NoWork) {
12615 // Queue is always non-null for classes
12616 var updateQueue = workInProgress.updateQueue;
12617 updateQueue.baseState = memoizedState;
12618 }
12619}
12620var classComponentUpdater = {
12621 isMounted: isMounted,
12622 enqueueSetState: function (inst, payload, callback) {
12623 var fiber = get(inst);
12624 var currentTime = requestCurrentTimeForUpdate();
12625 var suspenseConfig = requestCurrentSuspenseConfig();
12626 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12627 var update = createUpdate(expirationTime, suspenseConfig);
12628 update.payload = payload;
12629
12630 if (callback !== undefined && callback !== null) {
12631 {
12632 warnOnInvalidCallback(callback, 'setState');
12633 }
12634
12635 update.callback = callback;
12636 }
12637
12638 enqueueUpdate(fiber, update);
12639 scheduleWork(fiber, expirationTime);
12640 },
12641 enqueueReplaceState: function (inst, payload, callback) {
12642 var fiber = get(inst);
12643 var currentTime = requestCurrentTimeForUpdate();
12644 var suspenseConfig = requestCurrentSuspenseConfig();
12645 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12646 var update = createUpdate(expirationTime, suspenseConfig);
12647 update.tag = ReplaceState;
12648 update.payload = payload;
12649
12650 if (callback !== undefined && callback !== null) {
12651 {
12652 warnOnInvalidCallback(callback, 'replaceState');
12653 }
12654
12655 update.callback = callback;
12656 }
12657
12658 enqueueUpdate(fiber, update);
12659 scheduleWork(fiber, expirationTime);
12660 },
12661 enqueueForceUpdate: function (inst, callback) {
12662 var fiber = get(inst);
12663 var currentTime = requestCurrentTimeForUpdate();
12664 var suspenseConfig = requestCurrentSuspenseConfig();
12665 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12666 var update = createUpdate(expirationTime, suspenseConfig);
12667 update.tag = ForceUpdate;
12668
12669 if (callback !== undefined && callback !== null) {
12670 {
12671 warnOnInvalidCallback(callback, 'forceUpdate');
12672 }
12673
12674 update.callback = callback;
12675 }
12676
12677 enqueueUpdate(fiber, update);
12678 scheduleWork(fiber, expirationTime);
12679 }
12680};
12681
12682function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
12683 var instance = workInProgress.stateNode;
12684
12685 if (typeof instance.shouldComponentUpdate === 'function') {
12686 {
12687 if ( workInProgress.mode & StrictMode) {
12688 // Invoke the function an extra time to help detect side-effects.
12689 instance.shouldComponentUpdate(newProps, newState, nextContext);
12690 }
12691 }
12692
12693 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
12694 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
12695 stopPhaseTimer();
12696
12697 {
12698 if (shouldUpdate === undefined) {
12699 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
12700 }
12701 }
12702
12703 return shouldUpdate;
12704 }
12705
12706 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
12707 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
12708 }
12709
12710 return true;
12711}
12712
12713function checkClassInstance(workInProgress, ctor, newProps) {
12714 var instance = workInProgress.stateNode;
12715
12716 {
12717 var name = getComponentName(ctor) || 'Component';
12718 var renderPresent = instance.render;
12719
12720 if (!renderPresent) {
12721 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
12722 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
12723 } else {
12724 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
12725 }
12726 }
12727
12728 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
12729 error('getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name);
12730 }
12731
12732 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
12733 error('getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name);
12734 }
12735
12736 if (instance.propTypes) {
12737 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
12738 }
12739
12740 if (instance.contextType) {
12741 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
12742 }
12743
12744 {
12745 if (instance.contextTypes) {
12746 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
12747 }
12748
12749 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
12750 didWarnAboutContextTypeAndContextTypes.add(ctor);
12751
12752 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
12753 }
12754 }
12755
12756 if (typeof instance.componentShouldUpdate === 'function') {
12757 error('%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name);
12758 }
12759
12760 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
12761 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
12762 }
12763
12764 if (typeof instance.componentDidUnmount === 'function') {
12765 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
12766 }
12767
12768 if (typeof instance.componentDidReceiveProps === 'function') {
12769 error('%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name);
12770 }
12771
12772 if (typeof instance.componentWillRecieveProps === 'function') {
12773 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
12774 }
12775
12776 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
12777 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
12778 }
12779
12780 var hasMutatedProps = instance.props !== newProps;
12781
12782 if (instance.props !== undefined && hasMutatedProps) {
12783 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
12784 }
12785
12786 if (instance.defaultProps) {
12787 error('Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name);
12788 }
12789
12790 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
12791 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
12792
12793 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
12794 }
12795
12796 if (typeof instance.getDerivedStateFromProps === 'function') {
12797 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12798 }
12799
12800 if (typeof instance.getDerivedStateFromError === 'function') {
12801 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12802 }
12803
12804 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
12805 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
12806 }
12807
12808 var _state = instance.state;
12809
12810 if (_state && (typeof _state !== 'object' || isArray(_state))) {
12811 error('%s.state: must be set to an object or null', name);
12812 }
12813
12814 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
12815 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
12816 }
12817 }
12818}
12819
12820function adoptClassInstance(workInProgress, instance) {
12821 instance.updater = classComponentUpdater;
12822 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
12823
12824 set(instance, workInProgress);
12825
12826 {
12827 instance._reactInternalInstance = fakeInternalInstance;
12828 }
12829}
12830
12831function constructClassInstance(workInProgress, ctor, props) {
12832 var isLegacyContextConsumer = false;
12833 var unmaskedContext = emptyContextObject;
12834 var context = emptyContextObject;
12835 var contextType = ctor.contextType;
12836
12837 {
12838 if ('contextType' in ctor) {
12839 var isValid = // Allow null for conditional declaration
12840 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
12841
12842 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
12843 didWarnAboutInvalidateContextType.add(ctor);
12844 var addendum = '';
12845
12846 if (contextType === undefined) {
12847 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';
12848 } else if (typeof contextType !== 'object') {
12849 addendum = ' However, it is set to a ' + typeof contextType + '.';
12850 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
12851 addendum = ' Did you accidentally pass the Context.Provider instead?';
12852 } else if (contextType._context !== undefined) {
12853 // <Context.Consumer>
12854 addendum = ' Did you accidentally pass the Context.Consumer instead?';
12855 } else {
12856 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
12857 }
12858
12859 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
12860 }
12861 }
12862 }
12863
12864 if (typeof contextType === 'object' && contextType !== null) {
12865 context = readContext(contextType);
12866 } else {
12867 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
12868 var contextTypes = ctor.contextTypes;
12869 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
12870 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
12871 } // Instantiate twice to help detect side-effects.
12872
12873
12874 {
12875 if ( workInProgress.mode & StrictMode) {
12876 new ctor(props, context); // eslint-disable-line no-new
12877 }
12878 }
12879
12880 var instance = new ctor(props, context);
12881 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
12882 adoptClassInstance(workInProgress, instance);
12883
12884 {
12885 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
12886 var componentName = getComponentName(ctor) || 'Component';
12887
12888 if (!didWarnAboutUninitializedState.has(componentName)) {
12889 didWarnAboutUninitializedState.add(componentName);
12890
12891 error('`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
12892 }
12893 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
12894 // Warn about these lifecycles if they are present.
12895 // Don't warn about react-lifecycles-compat polyfilled methods though.
12896
12897
12898 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
12899 var foundWillMountName = null;
12900 var foundWillReceivePropsName = null;
12901 var foundWillUpdateName = null;
12902
12903 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
12904 foundWillMountName = 'componentWillMount';
12905 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
12906 foundWillMountName = 'UNSAFE_componentWillMount';
12907 }
12908
12909 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12910 foundWillReceivePropsName = 'componentWillReceiveProps';
12911 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12912 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
12913 }
12914
12915 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12916 foundWillUpdateName = 'componentWillUpdate';
12917 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
12918 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
12919 }
12920
12921 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
12922 var _componentName = getComponentName(ctor) || 'Component';
12923
12924 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
12925
12926 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
12927 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
12928
12929 error('Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
12930 }
12931 }
12932 }
12933 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
12934 // ReactFiberContext usually updates this cache but can't for newly-created instances.
12935
12936
12937 if (isLegacyContextConsumer) {
12938 cacheContext(workInProgress, unmaskedContext, context);
12939 }
12940
12941 return instance;
12942}
12943
12944function callComponentWillMount(workInProgress, instance) {
12945 startPhaseTimer(workInProgress, 'componentWillMount');
12946 var oldState = instance.state;
12947
12948 if (typeof instance.componentWillMount === 'function') {
12949 instance.componentWillMount();
12950 }
12951
12952 if (typeof instance.UNSAFE_componentWillMount === 'function') {
12953 instance.UNSAFE_componentWillMount();
12954 }
12955
12956 stopPhaseTimer();
12957
12958 if (oldState !== instance.state) {
12959 {
12960 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
12961 }
12962
12963 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12964 }
12965}
12966
12967function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
12968 var oldState = instance.state;
12969 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
12970
12971 if (typeof instance.componentWillReceiveProps === 'function') {
12972 instance.componentWillReceiveProps(newProps, nextContext);
12973 }
12974
12975 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12976 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
12977 }
12978
12979 stopPhaseTimer();
12980
12981 if (instance.state !== oldState) {
12982 {
12983 var componentName = getComponentName(workInProgress.type) || 'Component';
12984
12985 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
12986 didWarnAboutStateAssignmentForComponent.add(componentName);
12987
12988 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
12989 }
12990 }
12991
12992 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
12993 }
12994} // Invokes the mount life-cycles on a previously never rendered instance.
12995
12996
12997function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
12998 {
12999 checkClassInstance(workInProgress, ctor, newProps);
13000 }
13001
13002 var instance = workInProgress.stateNode;
13003 instance.props = newProps;
13004 instance.state = workInProgress.memoizedState;
13005 instance.refs = emptyRefsObject;
13006 initializeUpdateQueue(workInProgress);
13007 var contextType = ctor.contextType;
13008
13009 if (typeof contextType === 'object' && contextType !== null) {
13010 instance.context = readContext(contextType);
13011 } else {
13012 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13013 instance.context = getMaskedContext(workInProgress, unmaskedContext);
13014 }
13015
13016 {
13017 if (instance.state === newProps) {
13018 var componentName = getComponentName(ctor) || 'Component';
13019
13020 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
13021 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
13022
13023 error('%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
13024 }
13025 }
13026
13027 if (workInProgress.mode & StrictMode) {
13028 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
13029 }
13030
13031 {
13032 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
13033 }
13034 }
13035
13036 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13037 instance.state = workInProgress.memoizedState;
13038 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13039
13040 if (typeof getDerivedStateFromProps === 'function') {
13041 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13042 instance.state = workInProgress.memoizedState;
13043 } // In order to support react-lifecycles-compat polyfilled components,
13044 // Unsafe lifecycles should not be invoked for components using the new APIs.
13045
13046
13047 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13048 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
13049 // process them now.
13050
13051 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13052 instance.state = workInProgress.memoizedState;
13053 }
13054
13055 if (typeof instance.componentDidMount === 'function') {
13056 workInProgress.effectTag |= Update;
13057 }
13058}
13059
13060function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13061 var instance = workInProgress.stateNode;
13062 var oldProps = workInProgress.memoizedProps;
13063 instance.props = oldProps;
13064 var oldContext = instance.context;
13065 var contextType = ctor.contextType;
13066 var nextContext = emptyContextObject;
13067
13068 if (typeof contextType === 'object' && contextType !== null) {
13069 nextContext = readContext(contextType);
13070 } else {
13071 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13072 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
13073 }
13074
13075 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13076 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13077 // ever the previously attempted to render - not the "current". However,
13078 // during componentDidUpdate we pass the "current" props.
13079 // In order to support react-lifecycles-compat polyfilled components,
13080 // Unsafe lifecycles should not be invoked for components using the new APIs.
13081
13082 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13083 if (oldProps !== newProps || oldContext !== nextContext) {
13084 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13085 }
13086 }
13087
13088 resetHasForceUpdateBeforeProcessing();
13089 var oldState = workInProgress.memoizedState;
13090 var newState = instance.state = oldState;
13091 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13092 newState = workInProgress.memoizedState;
13093
13094 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13095 // If an update was already in progress, we should schedule an Update
13096 // effect even though we're bailing out, so that cWU/cDU are called.
13097 if (typeof instance.componentDidMount === 'function') {
13098 workInProgress.effectTag |= Update;
13099 }
13100
13101 return false;
13102 }
13103
13104 if (typeof getDerivedStateFromProps === 'function') {
13105 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13106 newState = workInProgress.memoizedState;
13107 }
13108
13109 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13110
13111 if (shouldUpdate) {
13112 // In order to support react-lifecycles-compat polyfilled components,
13113 // Unsafe lifecycles should not be invoked for components using the new APIs.
13114 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13115 startPhaseTimer(workInProgress, 'componentWillMount');
13116
13117 if (typeof instance.componentWillMount === 'function') {
13118 instance.componentWillMount();
13119 }
13120
13121 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13122 instance.UNSAFE_componentWillMount();
13123 }
13124
13125 stopPhaseTimer();
13126 }
13127
13128 if (typeof instance.componentDidMount === 'function') {
13129 workInProgress.effectTag |= Update;
13130 }
13131 } else {
13132 // If an update was already in progress, we should schedule an Update
13133 // effect even though we're bailing out, so that cWU/cDU are called.
13134 if (typeof instance.componentDidMount === 'function') {
13135 workInProgress.effectTag |= Update;
13136 } // If shouldComponentUpdate returned false, we should still update the
13137 // memoized state to indicate that this work can be reused.
13138
13139
13140 workInProgress.memoizedProps = newProps;
13141 workInProgress.memoizedState = newState;
13142 } // Update the existing instance's state, props, and context pointers even
13143 // if shouldComponentUpdate returns false.
13144
13145
13146 instance.props = newProps;
13147 instance.state = newState;
13148 instance.context = nextContext;
13149 return shouldUpdate;
13150} // Invokes the update life-cycles and returns false if it shouldn't rerender.
13151
13152
13153function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
13154 var instance = workInProgress.stateNode;
13155 cloneUpdateQueue(current, workInProgress);
13156 var oldProps = workInProgress.memoizedProps;
13157 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
13158 var oldContext = instance.context;
13159 var contextType = ctor.contextType;
13160 var nextContext = emptyContextObject;
13161
13162 if (typeof contextType === 'object' && contextType !== null) {
13163 nextContext = readContext(contextType);
13164 } else {
13165 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13166 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13167 }
13168
13169 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13170 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13171 // ever the previously attempted to render - not the "current". However,
13172 // during componentDidUpdate we pass the "current" props.
13173 // In order to support react-lifecycles-compat polyfilled components,
13174 // Unsafe lifecycles should not be invoked for components using the new APIs.
13175
13176 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13177 if (oldProps !== newProps || oldContext !== nextContext) {
13178 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13179 }
13180 }
13181
13182 resetHasForceUpdateBeforeProcessing();
13183 var oldState = workInProgress.memoizedState;
13184 var newState = instance.state = oldState;
13185 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13186 newState = workInProgress.memoizedState;
13187
13188 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13189 // If an update was already in progress, we should schedule an Update
13190 // effect even though we're bailing out, so that cWU/cDU are called.
13191 if (typeof instance.componentDidUpdate === 'function') {
13192 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13193 workInProgress.effectTag |= Update;
13194 }
13195 }
13196
13197 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13198 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13199 workInProgress.effectTag |= Snapshot;
13200 }
13201 }
13202
13203 return false;
13204 }
13205
13206 if (typeof getDerivedStateFromProps === 'function') {
13207 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13208 newState = workInProgress.memoizedState;
13209 }
13210
13211 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13212
13213 if (shouldUpdate) {
13214 // In order to support react-lifecycles-compat polyfilled components,
13215 // Unsafe lifecycles should not be invoked for components using the new APIs.
13216 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13217 startPhaseTimer(workInProgress, 'componentWillUpdate');
13218
13219 if (typeof instance.componentWillUpdate === 'function') {
13220 instance.componentWillUpdate(newProps, newState, nextContext);
13221 }
13222
13223 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13224 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13225 }
13226
13227 stopPhaseTimer();
13228 }
13229
13230 if (typeof instance.componentDidUpdate === 'function') {
13231 workInProgress.effectTag |= Update;
13232 }
13233
13234 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13235 workInProgress.effectTag |= Snapshot;
13236 }
13237 } else {
13238 // If an update was already in progress, we should schedule an Update
13239 // effect even though we're bailing out, so that cWU/cDU are called.
13240 if (typeof instance.componentDidUpdate === 'function') {
13241 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13242 workInProgress.effectTag |= Update;
13243 }
13244 }
13245
13246 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13247 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13248 workInProgress.effectTag |= Snapshot;
13249 }
13250 } // If shouldComponentUpdate returned false, we should still update the
13251 // memoized props/state to indicate that this work can be reused.
13252
13253
13254 workInProgress.memoizedProps = newProps;
13255 workInProgress.memoizedState = newState;
13256 } // Update the existing instance's state, props, and context pointers even
13257 // if shouldComponentUpdate returns false.
13258
13259
13260 instance.props = newProps;
13261 instance.state = newState;
13262 instance.context = nextContext;
13263 return shouldUpdate;
13264}
13265
13266var didWarnAboutMaps;
13267var didWarnAboutGenerators;
13268var didWarnAboutStringRefs;
13269var ownerHasKeyUseWarning;
13270var ownerHasFunctionTypeWarning;
13271
13272var warnForMissingKey = function (child) {};
13273
13274{
13275 didWarnAboutMaps = false;
13276 didWarnAboutGenerators = false;
13277 didWarnAboutStringRefs = {};
13278 /**
13279 * Warn if there's no key explicitly set on dynamic arrays of children or
13280 * object keys are not valid. This allows us to keep track of children between
13281 * updates.
13282 */
13283
13284 ownerHasKeyUseWarning = {};
13285 ownerHasFunctionTypeWarning = {};
13286
13287 warnForMissingKey = function (child) {
13288 if (child === null || typeof child !== 'object') {
13289 return;
13290 }
13291
13292 if (!child._store || child._store.validated || child.key != null) {
13293 return;
13294 }
13295
13296 if (!(typeof child._store === 'object')) {
13297 {
13298 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
13299 }
13300 }
13301
13302 child._store.validated = true;
13303 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
13304
13305 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
13306 return;
13307 }
13308
13309 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
13310
13311 error('Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
13312 };
13313}
13314
13315var isArray$1 = Array.isArray;
13316
13317function coerceRef(returnFiber, current, element) {
13318 var mixedRef = element.ref;
13319
13320 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13321 {
13322 // TODO: Clean this up once we turn on the string ref warning for
13323 // everyone, because the strict mode case will no longer be relevant
13324 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
13325 // because these cannot be automatically converted to an arrow function
13326 // using a codemod. Therefore, we don't have to warn about string refs again.
13327 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
13328 var componentName = getComponentName(returnFiber.type) || 'Component';
13329
13330 if (!didWarnAboutStringRefs[componentName]) {
13331 {
13332 error('A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));
13333 }
13334
13335 didWarnAboutStringRefs[componentName] = true;
13336 }
13337 }
13338 }
13339
13340 if (element._owner) {
13341 var owner = element._owner;
13342 var inst;
13343
13344 if (owner) {
13345 var ownerFiber = owner;
13346
13347 if (!(ownerFiber.tag === ClassComponent)) {
13348 {
13349 throw Error( "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" );
13350 }
13351 }
13352
13353 inst = ownerFiber.stateNode;
13354 }
13355
13356 if (!inst) {
13357 {
13358 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
13359 }
13360 }
13361
13362 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
13363
13364 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
13365 return current.ref;
13366 }
13367
13368 var ref = function (value) {
13369 var refs = inst.refs;
13370
13371 if (refs === emptyRefsObject) {
13372 // This is a lazy pooled frozen object, so we need to initialize.
13373 refs = inst.refs = {};
13374 }
13375
13376 if (value === null) {
13377 delete refs[stringRef];
13378 } else {
13379 refs[stringRef] = value;
13380 }
13381 };
13382
13383 ref._stringRef = stringRef;
13384 return ref;
13385 } else {
13386 if (!(typeof mixedRef === 'string')) {
13387 {
13388 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
13389 }
13390 }
13391
13392 if (!element._owner) {
13393 {
13394 throw Error( "Element ref was specified as a string (" + mixedRef + ") 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." );
13395 }
13396 }
13397 }
13398 }
13399
13400 return mixedRef;
13401}
13402
13403function throwOnInvalidObjectType(returnFiber, newChild) {
13404 if (returnFiber.type !== 'textarea') {
13405 var addendum = '';
13406
13407 {
13408 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
13409 }
13410
13411 {
13412 {
13413 throw Error( "Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ")." + addendum );
13414 }
13415 }
13416 }
13417}
13418
13419function warnOnFunctionType() {
13420 {
13421 var currentComponentErrorInfo = 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.' + getCurrentFiberStackInDev();
13422
13423 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
13424 return;
13425 }
13426
13427 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
13428
13429 error('Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
13430 }
13431} // This wrapper function exists because I expect to clone the code in each path
13432// to be able to optimize each path individually by branching early. This needs
13433// a compiler or we can do it manually. Helpers that don't need this branching
13434// live outside of this function.
13435
13436
13437function ChildReconciler(shouldTrackSideEffects) {
13438 function deleteChild(returnFiber, childToDelete) {
13439 if (!shouldTrackSideEffects) {
13440 // Noop.
13441 return;
13442 } // Deletions are added in reversed order so we add it to the front.
13443 // At this point, the return fiber's effect list is empty except for
13444 // deletions, so we can just append the deletion to the list. The remaining
13445 // effects aren't added until the complete phase. Once we implement
13446 // resuming, this may not be true.
13447
13448
13449 var last = returnFiber.lastEffect;
13450
13451 if (last !== null) {
13452 last.nextEffect = childToDelete;
13453 returnFiber.lastEffect = childToDelete;
13454 } else {
13455 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13456 }
13457
13458 childToDelete.nextEffect = null;
13459 childToDelete.effectTag = Deletion;
13460 }
13461
13462 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13463 if (!shouldTrackSideEffects) {
13464 // Noop.
13465 return null;
13466 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
13467 // assuming that after the first child we've already added everything.
13468
13469
13470 var childToDelete = currentFirstChild;
13471
13472 while (childToDelete !== null) {
13473 deleteChild(returnFiber, childToDelete);
13474 childToDelete = childToDelete.sibling;
13475 }
13476
13477 return null;
13478 }
13479
13480 function mapRemainingChildren(returnFiber, currentFirstChild) {
13481 // Add the remaining children to a temporary map so that we can find them by
13482 // keys quickly. Implicit (null) keys get added to this set with their index
13483 // instead.
13484 var existingChildren = new Map();
13485 var existingChild = currentFirstChild;
13486
13487 while (existingChild !== null) {
13488 if (existingChild.key !== null) {
13489 existingChildren.set(existingChild.key, existingChild);
13490 } else {
13491 existingChildren.set(existingChild.index, existingChild);
13492 }
13493
13494 existingChild = existingChild.sibling;
13495 }
13496
13497 return existingChildren;
13498 }
13499
13500 function useFiber(fiber, pendingProps) {
13501 // We currently set sibling to null and index to 0 here because it is easy
13502 // to forget to do before returning it. E.g. for the single child case.
13503 var clone = createWorkInProgress(fiber, pendingProps);
13504 clone.index = 0;
13505 clone.sibling = null;
13506 return clone;
13507 }
13508
13509 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13510 newFiber.index = newIndex;
13511
13512 if (!shouldTrackSideEffects) {
13513 // Noop.
13514 return lastPlacedIndex;
13515 }
13516
13517 var current = newFiber.alternate;
13518
13519 if (current !== null) {
13520 var oldIndex = current.index;
13521
13522 if (oldIndex < lastPlacedIndex) {
13523 // This is a move.
13524 newFiber.effectTag = Placement;
13525 return lastPlacedIndex;
13526 } else {
13527 // This item can stay in place.
13528 return oldIndex;
13529 }
13530 } else {
13531 // This is an insertion.
13532 newFiber.effectTag = Placement;
13533 return lastPlacedIndex;
13534 }
13535 }
13536
13537 function placeSingleChild(newFiber) {
13538 // This is simpler for the single child case. We only need to do a
13539 // placement for inserting new children.
13540 if (shouldTrackSideEffects && newFiber.alternate === null) {
13541 newFiber.effectTag = Placement;
13542 }
13543
13544 return newFiber;
13545 }
13546
13547 function updateTextNode(returnFiber, current, textContent, expirationTime) {
13548 if (current === null || current.tag !== HostText) {
13549 // Insert
13550 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
13551 created.return = returnFiber;
13552 return created;
13553 } else {
13554 // Update
13555 var existing = useFiber(current, textContent);
13556 existing.return = returnFiber;
13557 return existing;
13558 }
13559 }
13560
13561 function updateElement(returnFiber, current, element, expirationTime) {
13562 if (current !== null) {
13563 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
13564 isCompatibleFamilyForHotReloading(current, element) )) {
13565 // Move based on index
13566 var existing = useFiber(current, element.props);
13567 existing.ref = coerceRef(returnFiber, current, element);
13568 existing.return = returnFiber;
13569
13570 {
13571 existing._debugSource = element._source;
13572 existing._debugOwner = element._owner;
13573 }
13574
13575 return existing;
13576 }
13577 } // Insert
13578
13579
13580 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
13581 created.ref = coerceRef(returnFiber, current, element);
13582 created.return = returnFiber;
13583 return created;
13584 }
13585
13586 function updatePortal(returnFiber, current, portal, expirationTime) {
13587 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
13588 // Insert
13589 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
13590 created.return = returnFiber;
13591 return created;
13592 } else {
13593 // Update
13594 var existing = useFiber(current, portal.children || []);
13595 existing.return = returnFiber;
13596 return existing;
13597 }
13598 }
13599
13600 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
13601 if (current === null || current.tag !== Fragment) {
13602 // Insert
13603 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
13604 created.return = returnFiber;
13605 return created;
13606 } else {
13607 // Update
13608 var existing = useFiber(current, fragment);
13609 existing.return = returnFiber;
13610 return existing;
13611 }
13612 }
13613
13614 function createChild(returnFiber, newChild, expirationTime) {
13615 if (typeof newChild === 'string' || typeof newChild === 'number') {
13616 // Text nodes don't have keys. If the previous node is implicitly keyed
13617 // we can continue to replace it without aborting even if it is not a text
13618 // node.
13619 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
13620 created.return = returnFiber;
13621 return created;
13622 }
13623
13624 if (typeof newChild === 'object' && newChild !== null) {
13625 switch (newChild.$$typeof) {
13626 case REACT_ELEMENT_TYPE:
13627 {
13628 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
13629
13630 _created.ref = coerceRef(returnFiber, null, newChild);
13631 _created.return = returnFiber;
13632 return _created;
13633 }
13634
13635 case REACT_PORTAL_TYPE:
13636 {
13637 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
13638
13639 _created2.return = returnFiber;
13640 return _created2;
13641 }
13642 }
13643
13644 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13645 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
13646
13647 _created3.return = returnFiber;
13648 return _created3;
13649 }
13650
13651 throwOnInvalidObjectType(returnFiber, newChild);
13652 }
13653
13654 {
13655 if (typeof newChild === 'function') {
13656 warnOnFunctionType();
13657 }
13658 }
13659
13660 return null;
13661 }
13662
13663 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
13664 // Update the fiber if the keys match, otherwise return null.
13665 var key = oldFiber !== null ? oldFiber.key : null;
13666
13667 if (typeof newChild === 'string' || typeof newChild === 'number') {
13668 // Text nodes don't have keys. If the previous node is implicitly keyed
13669 // we can continue to replace it without aborting even if it is not a text
13670 // node.
13671 if (key !== null) {
13672 return null;
13673 }
13674
13675 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
13676 }
13677
13678 if (typeof newChild === 'object' && newChild !== null) {
13679 switch (newChild.$$typeof) {
13680 case REACT_ELEMENT_TYPE:
13681 {
13682 if (newChild.key === key) {
13683 if (newChild.type === REACT_FRAGMENT_TYPE) {
13684 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
13685 }
13686
13687 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
13688 } else {
13689 return null;
13690 }
13691 }
13692
13693 case REACT_PORTAL_TYPE:
13694 {
13695 if (newChild.key === key) {
13696 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
13697 } else {
13698 return null;
13699 }
13700 }
13701 }
13702
13703 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13704 if (key !== null) {
13705 return null;
13706 }
13707
13708 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
13709 }
13710
13711 throwOnInvalidObjectType(returnFiber, newChild);
13712 }
13713
13714 {
13715 if (typeof newChild === 'function') {
13716 warnOnFunctionType();
13717 }
13718 }
13719
13720 return null;
13721 }
13722
13723 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
13724 if (typeof newChild === 'string' || typeof newChild === 'number') {
13725 // Text nodes don't have keys, so we neither have to check the old nor
13726 // new node for the key. If both are text nodes, they match.
13727 var matchedFiber = existingChildren.get(newIdx) || null;
13728 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
13729 }
13730
13731 if (typeof newChild === 'object' && newChild !== null) {
13732 switch (newChild.$$typeof) {
13733 case REACT_ELEMENT_TYPE:
13734 {
13735 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13736
13737 if (newChild.type === REACT_FRAGMENT_TYPE) {
13738 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
13739 }
13740
13741 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
13742 }
13743
13744 case REACT_PORTAL_TYPE:
13745 {
13746 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13747
13748 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
13749 }
13750 }
13751
13752 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13753 var _matchedFiber3 = existingChildren.get(newIdx) || null;
13754
13755 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
13756 }
13757
13758 throwOnInvalidObjectType(returnFiber, newChild);
13759 }
13760
13761 {
13762 if (typeof newChild === 'function') {
13763 warnOnFunctionType();
13764 }
13765 }
13766
13767 return null;
13768 }
13769 /**
13770 * Warns if there is a duplicate or missing key
13771 */
13772
13773
13774 function warnOnInvalidKey(child, knownKeys) {
13775 {
13776 if (typeof child !== 'object' || child === null) {
13777 return knownKeys;
13778 }
13779
13780 switch (child.$$typeof) {
13781 case REACT_ELEMENT_TYPE:
13782 case REACT_PORTAL_TYPE:
13783 warnForMissingKey(child);
13784 var key = child.key;
13785
13786 if (typeof key !== 'string') {
13787 break;
13788 }
13789
13790 if (knownKeys === null) {
13791 knownKeys = new Set();
13792 knownKeys.add(key);
13793 break;
13794 }
13795
13796 if (!knownKeys.has(key)) {
13797 knownKeys.add(key);
13798 break;
13799 }
13800
13801 error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
13802
13803 break;
13804 }
13805 }
13806
13807 return knownKeys;
13808 }
13809
13810 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
13811 // This algorithm can't optimize by searching from both ends since we
13812 // don't have backpointers on fibers. I'm trying to see how far we can get
13813 // with that model. If it ends up not being worth the tradeoffs, we can
13814 // add it later.
13815 // Even with a two ended optimization, we'd want to optimize for the case
13816 // where there are few changes and brute force the comparison instead of
13817 // going for the Map. It'd like to explore hitting that path first in
13818 // forward-only mode and only go for the Map once we notice that we need
13819 // lots of look ahead. This doesn't handle reversal as well as two ended
13820 // search but that's unusual. Besides, for the two ended optimization to
13821 // work on Iterables, we'd need to copy the whole set.
13822 // In this first iteration, we'll just live with hitting the bad case
13823 // (adding everything to a Map) in for every insert/move.
13824 // If you change this code, also update reconcileChildrenIterator() which
13825 // uses the same algorithm.
13826 {
13827 // First, validate keys.
13828 var knownKeys = null;
13829
13830 for (var i = 0; i < newChildren.length; i++) {
13831 var child = newChildren[i];
13832 knownKeys = warnOnInvalidKey(child, knownKeys);
13833 }
13834 }
13835
13836 var resultingFirstChild = null;
13837 var previousNewFiber = null;
13838 var oldFiber = currentFirstChild;
13839 var lastPlacedIndex = 0;
13840 var newIdx = 0;
13841 var nextOldFiber = null;
13842
13843 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
13844 if (oldFiber.index > newIdx) {
13845 nextOldFiber = oldFiber;
13846 oldFiber = null;
13847 } else {
13848 nextOldFiber = oldFiber.sibling;
13849 }
13850
13851 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
13852
13853 if (newFiber === null) {
13854 // TODO: This breaks on empty slots like null children. That's
13855 // unfortunate because it triggers the slow path all the time. We need
13856 // a better way to communicate whether this was a miss or null,
13857 // boolean, undefined, etc.
13858 if (oldFiber === null) {
13859 oldFiber = nextOldFiber;
13860 }
13861
13862 break;
13863 }
13864
13865 if (shouldTrackSideEffects) {
13866 if (oldFiber && newFiber.alternate === null) {
13867 // We matched the slot, but we didn't reuse the existing fiber, so we
13868 // need to delete the existing child.
13869 deleteChild(returnFiber, oldFiber);
13870 }
13871 }
13872
13873 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
13874
13875 if (previousNewFiber === null) {
13876 // TODO: Move out of the loop. This only happens for the first run.
13877 resultingFirstChild = newFiber;
13878 } else {
13879 // TODO: Defer siblings if we're not at the right index for this slot.
13880 // I.e. if we had null values before, then we want to defer this
13881 // for each null value. However, we also don't want to call updateSlot
13882 // with the previous one.
13883 previousNewFiber.sibling = newFiber;
13884 }
13885
13886 previousNewFiber = newFiber;
13887 oldFiber = nextOldFiber;
13888 }
13889
13890 if (newIdx === newChildren.length) {
13891 // We've reached the end of the new children. We can delete the rest.
13892 deleteRemainingChildren(returnFiber, oldFiber);
13893 return resultingFirstChild;
13894 }
13895
13896 if (oldFiber === null) {
13897 // If we don't have any more existing children we can choose a fast path
13898 // since the rest will all be insertions.
13899 for (; newIdx < newChildren.length; newIdx++) {
13900 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
13901
13902 if (_newFiber === null) {
13903 continue;
13904 }
13905
13906 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
13907
13908 if (previousNewFiber === null) {
13909 // TODO: Move out of the loop. This only happens for the first run.
13910 resultingFirstChild = _newFiber;
13911 } else {
13912 previousNewFiber.sibling = _newFiber;
13913 }
13914
13915 previousNewFiber = _newFiber;
13916 }
13917
13918 return resultingFirstChild;
13919 } // Add all children to a key map for quick lookups.
13920
13921
13922 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
13923
13924 for (; newIdx < newChildren.length; newIdx++) {
13925 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
13926
13927 if (_newFiber2 !== null) {
13928 if (shouldTrackSideEffects) {
13929 if (_newFiber2.alternate !== null) {
13930 // The new fiber is a work in progress, but if there exists a
13931 // current, that means that we reused the fiber. We need to delete
13932 // it from the child list so that we don't add it to the deletion
13933 // list.
13934 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
13935 }
13936 }
13937
13938 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
13939
13940 if (previousNewFiber === null) {
13941 resultingFirstChild = _newFiber2;
13942 } else {
13943 previousNewFiber.sibling = _newFiber2;
13944 }
13945
13946 previousNewFiber = _newFiber2;
13947 }
13948 }
13949
13950 if (shouldTrackSideEffects) {
13951 // Any existing children that weren't consumed above were deleted. We need
13952 // to add them to the deletion list.
13953 existingChildren.forEach(function (child) {
13954 return deleteChild(returnFiber, child);
13955 });
13956 }
13957
13958 return resultingFirstChild;
13959 }
13960
13961 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
13962 // This is the same implementation as reconcileChildrenArray(),
13963 // but using the iterator instead.
13964 var iteratorFn = getIteratorFn(newChildrenIterable);
13965
13966 if (!(typeof iteratorFn === 'function')) {
13967 {
13968 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
13969 }
13970 }
13971
13972 {
13973 // We don't support rendering Generators because it's a mutation.
13974 // See https://github.com/facebook/react/issues/12995
13975 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
13976 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
13977 if (!didWarnAboutGenerators) {
13978 error('Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.');
13979 }
13980
13981 didWarnAboutGenerators = true;
13982 } // Warn about using Maps as children
13983
13984
13985 if (newChildrenIterable.entries === iteratorFn) {
13986 if (!didWarnAboutMaps) {
13987 error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');
13988 }
13989
13990 didWarnAboutMaps = true;
13991 } // First, validate keys.
13992 // We'll get a different iterator later for the main pass.
13993
13994
13995 var _newChildren = iteratorFn.call(newChildrenIterable);
13996
13997 if (_newChildren) {
13998 var knownKeys = null;
13999
14000 var _step = _newChildren.next();
14001
14002 for (; !_step.done; _step = _newChildren.next()) {
14003 var child = _step.value;
14004 knownKeys = warnOnInvalidKey(child, knownKeys);
14005 }
14006 }
14007 }
14008
14009 var newChildren = iteratorFn.call(newChildrenIterable);
14010
14011 if (!(newChildren != null)) {
14012 {
14013 throw Error( "An iterable object provided no iterator." );
14014 }
14015 }
14016
14017 var resultingFirstChild = null;
14018 var previousNewFiber = null;
14019 var oldFiber = currentFirstChild;
14020 var lastPlacedIndex = 0;
14021 var newIdx = 0;
14022 var nextOldFiber = null;
14023 var step = newChildren.next();
14024
14025 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
14026 if (oldFiber.index > newIdx) {
14027 nextOldFiber = oldFiber;
14028 oldFiber = null;
14029 } else {
14030 nextOldFiber = oldFiber.sibling;
14031 }
14032
14033 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
14034
14035 if (newFiber === null) {
14036 // TODO: This breaks on empty slots like null children. That's
14037 // unfortunate because it triggers the slow path all the time. We need
14038 // a better way to communicate whether this was a miss or null,
14039 // boolean, undefined, etc.
14040 if (oldFiber === null) {
14041 oldFiber = nextOldFiber;
14042 }
14043
14044 break;
14045 }
14046
14047 if (shouldTrackSideEffects) {
14048 if (oldFiber && newFiber.alternate === null) {
14049 // We matched the slot, but we didn't reuse the existing fiber, so we
14050 // need to delete the existing child.
14051 deleteChild(returnFiber, oldFiber);
14052 }
14053 }
14054
14055 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14056
14057 if (previousNewFiber === null) {
14058 // TODO: Move out of the loop. This only happens for the first run.
14059 resultingFirstChild = newFiber;
14060 } else {
14061 // TODO: Defer siblings if we're not at the right index for this slot.
14062 // I.e. if we had null values before, then we want to defer this
14063 // for each null value. However, we also don't want to call updateSlot
14064 // with the previous one.
14065 previousNewFiber.sibling = newFiber;
14066 }
14067
14068 previousNewFiber = newFiber;
14069 oldFiber = nextOldFiber;
14070 }
14071
14072 if (step.done) {
14073 // We've reached the end of the new children. We can delete the rest.
14074 deleteRemainingChildren(returnFiber, oldFiber);
14075 return resultingFirstChild;
14076 }
14077
14078 if (oldFiber === null) {
14079 // If we don't have any more existing children we can choose a fast path
14080 // since the rest will all be insertions.
14081 for (; !step.done; newIdx++, step = newChildren.next()) {
14082 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
14083
14084 if (_newFiber3 === null) {
14085 continue;
14086 }
14087
14088 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
14089
14090 if (previousNewFiber === null) {
14091 // TODO: Move out of the loop. This only happens for the first run.
14092 resultingFirstChild = _newFiber3;
14093 } else {
14094 previousNewFiber.sibling = _newFiber3;
14095 }
14096
14097 previousNewFiber = _newFiber3;
14098 }
14099
14100 return resultingFirstChild;
14101 } // Add all children to a key map for quick lookups.
14102
14103
14104 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
14105
14106 for (; !step.done; newIdx++, step = newChildren.next()) {
14107 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
14108
14109 if (_newFiber4 !== null) {
14110 if (shouldTrackSideEffects) {
14111 if (_newFiber4.alternate !== null) {
14112 // The new fiber is a work in progress, but if there exists a
14113 // current, that means that we reused the fiber. We need to delete
14114 // it from the child list so that we don't add it to the deletion
14115 // list.
14116 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
14117 }
14118 }
14119
14120 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
14121
14122 if (previousNewFiber === null) {
14123 resultingFirstChild = _newFiber4;
14124 } else {
14125 previousNewFiber.sibling = _newFiber4;
14126 }
14127
14128 previousNewFiber = _newFiber4;
14129 }
14130 }
14131
14132 if (shouldTrackSideEffects) {
14133 // Any existing children that weren't consumed above were deleted. We need
14134 // to add them to the deletion list.
14135 existingChildren.forEach(function (child) {
14136 return deleteChild(returnFiber, child);
14137 });
14138 }
14139
14140 return resultingFirstChild;
14141 }
14142
14143 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
14144 // There's no need to check for keys on text nodes since we don't have a
14145 // way to define them.
14146 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
14147 // We already have an existing node so let's just update it and delete
14148 // the rest.
14149 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
14150 var existing = useFiber(currentFirstChild, textContent);
14151 existing.return = returnFiber;
14152 return existing;
14153 } // The existing first child is not a text node so we need to create one
14154 // and delete the existing ones.
14155
14156
14157 deleteRemainingChildren(returnFiber, currentFirstChild);
14158 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
14159 created.return = returnFiber;
14160 return created;
14161 }
14162
14163 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
14164 var key = element.key;
14165 var child = currentFirstChild;
14166
14167 while (child !== null) {
14168 // TODO: If key === null and child.key === null, then this only applies to
14169 // the first item in the list.
14170 if (child.key === key) {
14171 switch (child.tag) {
14172 case Fragment:
14173 {
14174 if (element.type === REACT_FRAGMENT_TYPE) {
14175 deleteRemainingChildren(returnFiber, child.sibling);
14176 var existing = useFiber(child, element.props.children);
14177 existing.return = returnFiber;
14178
14179 {
14180 existing._debugSource = element._source;
14181 existing._debugOwner = element._owner;
14182 }
14183
14184 return existing;
14185 }
14186
14187 break;
14188 }
14189
14190 case Block:
14191
14192 // We intentionally fallthrough here if enableBlocksAPI is not on.
14193 // eslint-disable-next-lined no-fallthrough
14194
14195 default:
14196 {
14197 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
14198 isCompatibleFamilyForHotReloading(child, element) )) {
14199 deleteRemainingChildren(returnFiber, child.sibling);
14200
14201 var _existing3 = useFiber(child, element.props);
14202
14203 _existing3.ref = coerceRef(returnFiber, child, element);
14204 _existing3.return = returnFiber;
14205
14206 {
14207 _existing3._debugSource = element._source;
14208 _existing3._debugOwner = element._owner;
14209 }
14210
14211 return _existing3;
14212 }
14213
14214 break;
14215 }
14216 } // Didn't match.
14217
14218
14219 deleteRemainingChildren(returnFiber, child);
14220 break;
14221 } else {
14222 deleteChild(returnFiber, child);
14223 }
14224
14225 child = child.sibling;
14226 }
14227
14228 if (element.type === REACT_FRAGMENT_TYPE) {
14229 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
14230 created.return = returnFiber;
14231 return created;
14232 } else {
14233 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
14234
14235 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
14236 _created4.return = returnFiber;
14237 return _created4;
14238 }
14239 }
14240
14241 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
14242 var key = portal.key;
14243 var child = currentFirstChild;
14244
14245 while (child !== null) {
14246 // TODO: If key === null and child.key === null, then this only applies to
14247 // the first item in the list.
14248 if (child.key === key) {
14249 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
14250 deleteRemainingChildren(returnFiber, child.sibling);
14251 var existing = useFiber(child, portal.children || []);
14252 existing.return = returnFiber;
14253 return existing;
14254 } else {
14255 deleteRemainingChildren(returnFiber, child);
14256 break;
14257 }
14258 } else {
14259 deleteChild(returnFiber, child);
14260 }
14261
14262 child = child.sibling;
14263 }
14264
14265 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
14266 created.return = returnFiber;
14267 return created;
14268 } // This API will tag the children with the side-effect of the reconciliation
14269 // itself. They will be added to the side-effect list as we pass through the
14270 // children and the parent.
14271
14272
14273 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
14274 // This function is not recursive.
14275 // If the top level item is an array, we treat it as a set of children,
14276 // not as a fragment. Nested arrays on the other hand will be treated as
14277 // fragment nodes. Recursion happens at the normal flow.
14278 // Handle top level unkeyed fragments as if they were arrays.
14279 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14280 // We treat the ambiguous cases above the same.
14281 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
14282
14283 if (isUnkeyedTopLevelFragment) {
14284 newChild = newChild.props.children;
14285 } // Handle object types
14286
14287
14288 var isObject = typeof newChild === 'object' && newChild !== null;
14289
14290 if (isObject) {
14291 switch (newChild.$$typeof) {
14292 case REACT_ELEMENT_TYPE:
14293 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
14294
14295 case REACT_PORTAL_TYPE:
14296 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
14297 }
14298 }
14299
14300 if (typeof newChild === 'string' || typeof newChild === 'number') {
14301 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
14302 }
14303
14304 if (isArray$1(newChild)) {
14305 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
14306 }
14307
14308 if (getIteratorFn(newChild)) {
14309 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
14310 }
14311
14312 if (isObject) {
14313 throwOnInvalidObjectType(returnFiber, newChild);
14314 }
14315
14316 {
14317 if (typeof newChild === 'function') {
14318 warnOnFunctionType();
14319 }
14320 }
14321
14322 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14323 // If the new child is undefined, and the return fiber is a composite
14324 // component, throw an error. If Fiber return types are disabled,
14325 // we already threw above.
14326 switch (returnFiber.tag) {
14327 case ClassComponent:
14328 {
14329 {
14330 var instance = returnFiber.stateNode;
14331
14332 if (instance.render._isMockFunction) {
14333 // We allow auto-mocks to proceed as if they're returning null.
14334 break;
14335 }
14336 }
14337 }
14338 // Intentionally fall through to the next case, which handles both
14339 // functions and classes
14340 // eslint-disable-next-lined no-fallthrough
14341
14342 case FunctionComponent:
14343 {
14344 var Component = returnFiber.type;
14345
14346 {
14347 {
14348 throw Error( (Component.displayName || Component.name || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." );
14349 }
14350 }
14351 }
14352 }
14353 } // Remaining cases are all treated as empty.
14354
14355
14356 return deleteRemainingChildren(returnFiber, currentFirstChild);
14357 }
14358
14359 return reconcileChildFibers;
14360}
14361
14362var reconcileChildFibers = ChildReconciler(true);
14363var mountChildFibers = ChildReconciler(false);
14364function cloneChildFibers(current, workInProgress) {
14365 if (!(current === null || workInProgress.child === current.child)) {
14366 {
14367 throw Error( "Resuming work not yet implemented." );
14368 }
14369 }
14370
14371 if (workInProgress.child === null) {
14372 return;
14373 }
14374
14375 var currentChild = workInProgress.child;
14376 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
14377 workInProgress.child = newChild;
14378 newChild.return = workInProgress;
14379
14380 while (currentChild.sibling !== null) {
14381 currentChild = currentChild.sibling;
14382 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
14383 newChild.return = workInProgress;
14384 }
14385
14386 newChild.sibling = null;
14387} // Reset a workInProgress child set to prepare it for a second pass.
14388
14389function resetChildFibers(workInProgress, renderExpirationTime) {
14390 var child = workInProgress.child;
14391
14392 while (child !== null) {
14393 resetWorkInProgress(child, renderExpirationTime);
14394 child = child.sibling;
14395 }
14396}
14397
14398var NO_CONTEXT = {};
14399var contextStackCursor$1 = createCursor(NO_CONTEXT);
14400var contextFiberStackCursor = createCursor(NO_CONTEXT);
14401var rootInstanceStackCursor = createCursor(NO_CONTEXT);
14402
14403function requiredContext(c) {
14404 if (!(c !== NO_CONTEXT)) {
14405 {
14406 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
14407 }
14408 }
14409
14410 return c;
14411}
14412
14413function getRootHostContainer() {
14414 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14415 return rootInstance;
14416}
14417
14418function pushHostContainer(fiber, nextRootInstance) {
14419 // Push current root instance onto the stack;
14420 // This allows us to reset root when portals are popped.
14421 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
14422 // This enables us to pop only Fibers that provide unique contexts.
14423
14424 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
14425 // However, we can't just call getRootHostContext() and push it because
14426 // we'd have a different number of entries on the stack depending on
14427 // whether getRootHostContext() throws somewhere in renderer code or not.
14428 // So we push an empty value first. This lets us safely unwind on errors.
14429
14430 push(contextStackCursor$1, NO_CONTEXT, fiber);
14431 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
14432
14433 pop(contextStackCursor$1, fiber);
14434 push(contextStackCursor$1, nextRootContext, fiber);
14435}
14436
14437function popHostContainer(fiber) {
14438 pop(contextStackCursor$1, fiber);
14439 pop(contextFiberStackCursor, fiber);
14440 pop(rootInstanceStackCursor, fiber);
14441}
14442
14443function getHostContext() {
14444 var context = requiredContext(contextStackCursor$1.current);
14445 return context;
14446}
14447
14448function pushHostContext(fiber) {
14449 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14450 var context = requiredContext(contextStackCursor$1.current);
14451 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
14452
14453 if (context === nextContext) {
14454 return;
14455 } // Track the context and the Fiber that provided it.
14456 // This enables us to pop only Fibers that provide unique contexts.
14457
14458
14459 push(contextFiberStackCursor, fiber, fiber);
14460 push(contextStackCursor$1, nextContext, fiber);
14461}
14462
14463function popHostContext(fiber) {
14464 // Do not pop unless this Fiber provided the current context.
14465 // pushHostContext() only pushes Fibers that provide unique contexts.
14466 if (contextFiberStackCursor.current !== fiber) {
14467 return;
14468 }
14469
14470 pop(contextStackCursor$1, fiber);
14471 pop(contextFiberStackCursor, fiber);
14472}
14473
14474var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
14475// inherited deeply down the subtree. The upper bits only affect
14476// this immediate suspense boundary and gets reset each new
14477// boundary or suspense list.
14478
14479var SubtreeSuspenseContextMask = 1; // Subtree Flags:
14480// InvisibleParentSuspenseContext indicates that one of our parent Suspense
14481// boundaries is not currently showing visible main content.
14482// Either because it is already showing a fallback or is not mounted at all.
14483// We can use this to determine if it is desirable to trigger a fallback at
14484// the parent. If not, then we might need to trigger undesirable boundaries
14485// and/or suspend the commit to avoid hiding the parent content.
14486
14487var InvisibleParentSuspenseContext = 1; // Shallow Flags:
14488// ForceSuspenseFallback can be used by SuspenseList to force newly added
14489// items into their fallback state during one of the render passes.
14490
14491var ForceSuspenseFallback = 2;
14492var suspenseStackCursor = createCursor(DefaultSuspenseContext);
14493function hasSuspenseContext(parentContext, flag) {
14494 return (parentContext & flag) !== 0;
14495}
14496function setDefaultShallowSuspenseContext(parentContext) {
14497 return parentContext & SubtreeSuspenseContextMask;
14498}
14499function setShallowSuspenseContext(parentContext, shallowContext) {
14500 return parentContext & SubtreeSuspenseContextMask | shallowContext;
14501}
14502function addSubtreeSuspenseContext(parentContext, subtreeContext) {
14503 return parentContext | subtreeContext;
14504}
14505function pushSuspenseContext(fiber, newContext) {
14506 push(suspenseStackCursor, newContext, fiber);
14507}
14508function popSuspenseContext(fiber) {
14509 pop(suspenseStackCursor, fiber);
14510}
14511
14512function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
14513 // If it was the primary children that just suspended, capture and render the
14514 // fallback. Otherwise, don't capture and bubble to the next boundary.
14515 var nextState = workInProgress.memoizedState;
14516
14517 if (nextState !== null) {
14518 if (nextState.dehydrated !== null) {
14519 // A dehydrated boundary always captures.
14520 return true;
14521 }
14522
14523 return false;
14524 }
14525
14526 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
14527
14528 if (props.fallback === undefined) {
14529 return false;
14530 } // Regular boundaries always capture.
14531
14532
14533 if (props.unstable_avoidThisFallback !== true) {
14534 return true;
14535 } // If it's a boundary we should avoid, then we prefer to bubble up to the
14536 // parent boundary if it is currently invisible.
14537
14538
14539 if (hasInvisibleParent) {
14540 return false;
14541 } // If the parent is not able to handle it, we must handle it.
14542
14543
14544 return true;
14545}
14546function findFirstSuspended(row) {
14547 var node = row;
14548
14549 while (node !== null) {
14550 if (node.tag === SuspenseComponent) {
14551 var state = node.memoizedState;
14552
14553 if (state !== null) {
14554 var dehydrated = state.dehydrated;
14555
14556 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
14557 return node;
14558 }
14559 }
14560 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
14561 // keep track of whether it suspended or not.
14562 node.memoizedProps.revealOrder !== undefined) {
14563 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
14564
14565 if (didSuspend) {
14566 return node;
14567 }
14568 } else if (node.child !== null) {
14569 node.child.return = node;
14570 node = node.child;
14571 continue;
14572 }
14573
14574 if (node === row) {
14575 return null;
14576 }
14577
14578 while (node.sibling === null) {
14579 if (node.return === null || node.return === row) {
14580 return null;
14581 }
14582
14583 node = node.return;
14584 }
14585
14586 node.sibling.return = node.return;
14587 node = node.sibling;
14588 }
14589
14590 return null;
14591}
14592
14593function createDeprecatedResponderListener(responder, props) {
14594 var eventResponderListener = {
14595 responder: responder,
14596 props: props
14597 };
14598
14599 {
14600 Object.freeze(eventResponderListener);
14601 }
14602
14603 return eventResponderListener;
14604}
14605
14606var HasEffect =
14607/* */
146081; // Represents the phase in which the effect (not the clean-up) fires.
14609
14610var Layout =
14611/* */
146122;
14613var Passive$1 =
14614/* */
146154;
14616
14617var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
14618 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
14619var didWarnAboutMismatchedHooksForComponent;
14620
14621{
14622 didWarnAboutMismatchedHooksForComponent = new Set();
14623}
14624
14625// These are set right before calling the component.
14626var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
14627// the work-in-progress hook.
14628
14629var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
14630// current hook list is the list that belongs to the current fiber. The
14631// work-in-progress hook list is a new list that will be added to the
14632// work-in-progress fiber.
14633
14634var currentHook = null;
14635var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
14636// does not get reset if we do another render pass; only when we're completely
14637// finished evaluating this component. This is an optimization so we know
14638// whether we need to clear render phase updates after a throw.
14639
14640var didScheduleRenderPhaseUpdate = false;
14641var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
14642
14643var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
14644// The list stores the order of hooks used during the initial render (mount).
14645// Subsequent renders (updates) reference this list.
14646
14647var hookTypesDev = null;
14648var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
14649// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
14650// When true, such Hooks will always be "remounted". Only used during hot reload.
14651
14652var ignorePreviousDependencies = false;
14653
14654function mountHookTypesDev() {
14655 {
14656 var hookName = currentHookNameInDev;
14657
14658 if (hookTypesDev === null) {
14659 hookTypesDev = [hookName];
14660 } else {
14661 hookTypesDev.push(hookName);
14662 }
14663 }
14664}
14665
14666function updateHookTypesDev() {
14667 {
14668 var hookName = currentHookNameInDev;
14669
14670 if (hookTypesDev !== null) {
14671 hookTypesUpdateIndexDev++;
14672
14673 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
14674 warnOnHookMismatchInDev(hookName);
14675 }
14676 }
14677 }
14678}
14679
14680function checkDepsAreArrayDev(deps) {
14681 {
14682 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
14683 // Verify deps, but only on mount to avoid extra checks.
14684 // It's unlikely their type would change as usually you define them inline.
14685 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
14686 }
14687 }
14688}
14689
14690function warnOnHookMismatchInDev(currentHookName) {
14691 {
14692 var componentName = getComponentName(currentlyRenderingFiber$1.type);
14693
14694 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
14695 didWarnAboutMismatchedHooksForComponent.add(componentName);
14696
14697 if (hookTypesDev !== null) {
14698 var table = '';
14699 var secondColumnStart = 30;
14700
14701 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
14702 var oldHookName = hookTypesDev[i];
14703 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
14704 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
14705 // lol @ IE not supporting String#repeat
14706
14707 while (row.length < secondColumnStart) {
14708 row += ' ';
14709 }
14710
14711 row += newHookName + '\n';
14712 table += row;
14713 }
14714
14715 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
14716 }
14717 }
14718 }
14719}
14720
14721function throwInvalidHookError() {
14722 {
14723 {
14724 throw Error( "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." );
14725 }
14726 }
14727}
14728
14729function areHookInputsEqual(nextDeps, prevDeps) {
14730 {
14731 if (ignorePreviousDependencies) {
14732 // Only true when this component is being hot reloaded.
14733 return false;
14734 }
14735 }
14736
14737 if (prevDeps === null) {
14738 {
14739 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
14740 }
14741
14742 return false;
14743 }
14744
14745 {
14746 // Don't bother comparing lengths in prod because these arrays should be
14747 // passed inline.
14748 if (nextDeps.length !== prevDeps.length) {
14749 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
14750 }
14751 }
14752
14753 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
14754 if (objectIs(nextDeps[i], prevDeps[i])) {
14755 continue;
14756 }
14757
14758 return false;
14759 }
14760
14761 return true;
14762}
14763
14764function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {
14765 renderExpirationTime = nextRenderExpirationTime;
14766 currentlyRenderingFiber$1 = workInProgress;
14767
14768 {
14769 hookTypesDev = current !== null ? current._debugHookTypes : null;
14770 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
14771
14772 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
14773 }
14774
14775 workInProgress.memoizedState = null;
14776 workInProgress.updateQueue = null;
14777 workInProgress.expirationTime = NoWork; // The following should have already been reset
14778 // currentHook = null;
14779 // workInProgressHook = null;
14780 // didScheduleRenderPhaseUpdate = false;
14781 // TODO Warn if no hooks are used at all during mount, then some are used during update.
14782 // Currently we will identify the update render as a mount because memoizedState === null.
14783 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
14784 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
14785 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
14786 // so memoizedState would be null during updates and mounts.
14787
14788 {
14789 if (current !== null && current.memoizedState !== null) {
14790 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
14791 } else if (hookTypesDev !== null) {
14792 // This dispatcher handles an edge case where a component is updating,
14793 // but no stateful hooks have been used.
14794 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
14795 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
14796 // This dispatcher does that.
14797 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
14798 } else {
14799 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
14800 }
14801 }
14802
14803 var children = Component(props, secondArg); // Check if there was a render phase update
14804
14805 if (workInProgress.expirationTime === renderExpirationTime) {
14806 // Keep rendering in a loop for as long as render phase updates continue to
14807 // be scheduled. Use a counter to prevent infinite loops.
14808 var numberOfReRenders = 0;
14809
14810 do {
14811 workInProgress.expirationTime = NoWork;
14812
14813 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
14814 {
14815 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
14816 }
14817 }
14818
14819 numberOfReRenders += 1;
14820
14821 {
14822 // Even when hot reloading, allow dependencies to stabilize
14823 // after first render to prevent infinite render phase updates.
14824 ignorePreviousDependencies = false;
14825 } // Start over from the beginning of the list
14826
14827
14828 currentHook = null;
14829 workInProgressHook = null;
14830 workInProgress.updateQueue = null;
14831
14832 {
14833 // Also validate hook order for cascading updates.
14834 hookTypesUpdateIndexDev = -1;
14835 }
14836
14837 ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV ;
14838 children = Component(props, secondArg);
14839 } while (workInProgress.expirationTime === renderExpirationTime);
14840 } // We can assume the previous dispatcher is always this one, since we set it
14841 // at the beginning of the render phase and there's no re-entrancy.
14842
14843
14844 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
14845
14846 {
14847 workInProgress._debugHookTypes = hookTypesDev;
14848 } // This check uses currentHook so that it works the same in DEV and prod bundles.
14849 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
14850
14851
14852 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
14853 renderExpirationTime = NoWork;
14854 currentlyRenderingFiber$1 = null;
14855 currentHook = null;
14856 workInProgressHook = null;
14857
14858 {
14859 currentHookNameInDev = null;
14860 hookTypesDev = null;
14861 hookTypesUpdateIndexDev = -1;
14862 }
14863
14864 didScheduleRenderPhaseUpdate = false;
14865
14866 if (!!didRenderTooFewHooks) {
14867 {
14868 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
14869 }
14870 }
14871
14872 return children;
14873}
14874function bailoutHooks(current, workInProgress, expirationTime) {
14875 workInProgress.updateQueue = current.updateQueue;
14876 workInProgress.effectTag &= ~(Passive | Update);
14877
14878 if (current.expirationTime <= expirationTime) {
14879 current.expirationTime = NoWork;
14880 }
14881}
14882function resetHooksAfterThrow() {
14883 // We can assume the previous dispatcher is always this one, since we set it
14884 // at the beginning of the render phase and there's no re-entrancy.
14885 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
14886
14887 if (didScheduleRenderPhaseUpdate) {
14888 // There were render phase updates. These are only valid for this render
14889 // phase, which we are now aborting. Remove the updates from the queues so
14890 // they do not persist to the next render. Do not remove updates from hooks
14891 // that weren't processed.
14892 //
14893 // Only reset the updates from the queue if it has a clone. If it does
14894 // not have a clone, that means it wasn't processed, and the updates were
14895 // scheduled before we entered the render phase.
14896 var hook = currentlyRenderingFiber$1.memoizedState;
14897
14898 while (hook !== null) {
14899 var queue = hook.queue;
14900
14901 if (queue !== null) {
14902 queue.pending = null;
14903 }
14904
14905 hook = hook.next;
14906 }
14907 }
14908
14909 renderExpirationTime = NoWork;
14910 currentlyRenderingFiber$1 = null;
14911 currentHook = null;
14912 workInProgressHook = null;
14913
14914 {
14915 hookTypesDev = null;
14916 hookTypesUpdateIndexDev = -1;
14917 currentHookNameInDev = null;
14918 }
14919
14920 didScheduleRenderPhaseUpdate = false;
14921}
14922
14923function mountWorkInProgressHook() {
14924 var hook = {
14925 memoizedState: null,
14926 baseState: null,
14927 baseQueue: null,
14928 queue: null,
14929 next: null
14930 };
14931
14932 if (workInProgressHook === null) {
14933 // This is the first hook in the list
14934 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
14935 } else {
14936 // Append to the end of the list
14937 workInProgressHook = workInProgressHook.next = hook;
14938 }
14939
14940 return workInProgressHook;
14941}
14942
14943function updateWorkInProgressHook() {
14944 // This function is used both for updates and for re-renders triggered by a
14945 // render phase update. It assumes there is either a current hook we can
14946 // clone, or a work-in-progress hook from a previous render pass that we can
14947 // use as a base. When we reach the end of the base list, we must switch to
14948 // the dispatcher used for mounts.
14949 var nextCurrentHook;
14950
14951 if (currentHook === null) {
14952 var current = currentlyRenderingFiber$1.alternate;
14953
14954 if (current !== null) {
14955 nextCurrentHook = current.memoizedState;
14956 } else {
14957 nextCurrentHook = null;
14958 }
14959 } else {
14960 nextCurrentHook = currentHook.next;
14961 }
14962
14963 var nextWorkInProgressHook;
14964
14965 if (workInProgressHook === null) {
14966 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
14967 } else {
14968 nextWorkInProgressHook = workInProgressHook.next;
14969 }
14970
14971 if (nextWorkInProgressHook !== null) {
14972 // There's already a work-in-progress. Reuse it.
14973 workInProgressHook = nextWorkInProgressHook;
14974 nextWorkInProgressHook = workInProgressHook.next;
14975 currentHook = nextCurrentHook;
14976 } else {
14977 // Clone from the current hook.
14978 if (!(nextCurrentHook !== null)) {
14979 {
14980 throw Error( "Rendered more hooks than during the previous render." );
14981 }
14982 }
14983
14984 currentHook = nextCurrentHook;
14985 var newHook = {
14986 memoizedState: currentHook.memoizedState,
14987 baseState: currentHook.baseState,
14988 baseQueue: currentHook.baseQueue,
14989 queue: currentHook.queue,
14990 next: null
14991 };
14992
14993 if (workInProgressHook === null) {
14994 // This is the first hook in the list.
14995 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
14996 } else {
14997 // Append to the end of the list.
14998 workInProgressHook = workInProgressHook.next = newHook;
14999 }
15000 }
15001
15002 return workInProgressHook;
15003}
15004
15005function createFunctionComponentUpdateQueue() {
15006 return {
15007 lastEffect: null
15008 };
15009}
15010
15011function basicStateReducer(state, action) {
15012 // $FlowFixMe: Flow doesn't like mixed types
15013 return typeof action === 'function' ? action(state) : action;
15014}
15015
15016function mountReducer(reducer, initialArg, init) {
15017 var hook = mountWorkInProgressHook();
15018 var initialState;
15019
15020 if (init !== undefined) {
15021 initialState = init(initialArg);
15022 } else {
15023 initialState = initialArg;
15024 }
15025
15026 hook.memoizedState = hook.baseState = initialState;
15027 var queue = hook.queue = {
15028 pending: null,
15029 dispatch: null,
15030 lastRenderedReducer: reducer,
15031 lastRenderedState: initialState
15032 };
15033 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15034 return [hook.memoizedState, dispatch];
15035}
15036
15037function updateReducer(reducer, initialArg, init) {
15038 var hook = updateWorkInProgressHook();
15039 var queue = hook.queue;
15040
15041 if (!(queue !== null)) {
15042 {
15043 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15044 }
15045 }
15046
15047 queue.lastRenderedReducer = reducer;
15048 var current = currentHook; // The last rebase update that is NOT part of the base state.
15049
15050 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
15051
15052 var pendingQueue = queue.pending;
15053
15054 if (pendingQueue !== null) {
15055 // We have new updates that haven't been processed yet.
15056 // We'll add them to the base queue.
15057 if (baseQueue !== null) {
15058 // Merge the pending queue and the base queue.
15059 var baseFirst = baseQueue.next;
15060 var pendingFirst = pendingQueue.next;
15061 baseQueue.next = pendingFirst;
15062 pendingQueue.next = baseFirst;
15063 }
15064
15065 current.baseQueue = baseQueue = pendingQueue;
15066 queue.pending = null;
15067 }
15068
15069 if (baseQueue !== null) {
15070 // We have a queue to process.
15071 var first = baseQueue.next;
15072 var newState = current.baseState;
15073 var newBaseState = null;
15074 var newBaseQueueFirst = null;
15075 var newBaseQueueLast = null;
15076 var update = first;
15077
15078 do {
15079 var updateExpirationTime = update.expirationTime;
15080
15081 if (updateExpirationTime < renderExpirationTime) {
15082 // Priority is insufficient. Skip this update. If this is the first
15083 // skipped update, the previous update/state is the new base
15084 // update/state.
15085 var clone = {
15086 expirationTime: update.expirationTime,
15087 suspenseConfig: update.suspenseConfig,
15088 action: update.action,
15089 eagerReducer: update.eagerReducer,
15090 eagerState: update.eagerState,
15091 next: null
15092 };
15093
15094 if (newBaseQueueLast === null) {
15095 newBaseQueueFirst = newBaseQueueLast = clone;
15096 newBaseState = newState;
15097 } else {
15098 newBaseQueueLast = newBaseQueueLast.next = clone;
15099 } // Update the remaining priority in the queue.
15100
15101
15102 if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {
15103 currentlyRenderingFiber$1.expirationTime = updateExpirationTime;
15104 markUnprocessedUpdateTime(updateExpirationTime);
15105 }
15106 } else {
15107 // This update does have sufficient priority.
15108 if (newBaseQueueLast !== null) {
15109 var _clone = {
15110 expirationTime: Sync,
15111 // This update is going to be committed so we never want uncommit it.
15112 suspenseConfig: update.suspenseConfig,
15113 action: update.action,
15114 eagerReducer: update.eagerReducer,
15115 eagerState: update.eagerState,
15116 next: null
15117 };
15118 newBaseQueueLast = newBaseQueueLast.next = _clone;
15119 } // Mark the event time of this update as relevant to this render pass.
15120 // TODO: This should ideally use the true event time of this update rather than
15121 // its priority which is a derived and not reverseable value.
15122 // TODO: We should skip this update if it was already committed but currently
15123 // we have no way of detecting the difference between a committed and suspended
15124 // update here.
15125
15126
15127 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
15128
15129 if (update.eagerReducer === reducer) {
15130 // If this update was processed eagerly, and its reducer matches the
15131 // current reducer, we can use the eagerly computed state.
15132 newState = update.eagerState;
15133 } else {
15134 var action = update.action;
15135 newState = reducer(newState, action);
15136 }
15137 }
15138
15139 update = update.next;
15140 } while (update !== null && update !== first);
15141
15142 if (newBaseQueueLast === null) {
15143 newBaseState = newState;
15144 } else {
15145 newBaseQueueLast.next = newBaseQueueFirst;
15146 } // Mark that the fiber performed work, but only if the new state is
15147 // different from the current state.
15148
15149
15150 if (!objectIs(newState, hook.memoizedState)) {
15151 markWorkInProgressReceivedUpdate();
15152 }
15153
15154 hook.memoizedState = newState;
15155 hook.baseState = newBaseState;
15156 hook.baseQueue = newBaseQueueLast;
15157 queue.lastRenderedState = newState;
15158 }
15159
15160 var dispatch = queue.dispatch;
15161 return [hook.memoizedState, dispatch];
15162}
15163
15164function rerenderReducer(reducer, initialArg, init) {
15165 var hook = updateWorkInProgressHook();
15166 var queue = hook.queue;
15167
15168 if (!(queue !== null)) {
15169 {
15170 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15171 }
15172 }
15173
15174 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
15175 // work-in-progress hook.
15176
15177 var dispatch = queue.dispatch;
15178 var lastRenderPhaseUpdate = queue.pending;
15179 var newState = hook.memoizedState;
15180
15181 if (lastRenderPhaseUpdate !== null) {
15182 // The queue doesn't persist past this render pass.
15183 queue.pending = null;
15184 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
15185 var update = firstRenderPhaseUpdate;
15186
15187 do {
15188 // Process this render phase update. We don't have to check the
15189 // priority because it will always be the same as the current
15190 // render's.
15191 var action = update.action;
15192 newState = reducer(newState, action);
15193 update = update.next;
15194 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
15195 // different from the current state.
15196
15197
15198 if (!objectIs(newState, hook.memoizedState)) {
15199 markWorkInProgressReceivedUpdate();
15200 }
15201
15202 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
15203 // the base state unless the queue is empty.
15204 // TODO: Not sure if this is the desired semantics, but it's what we
15205 // do for gDSFP. I can't remember why.
15206
15207 if (hook.baseQueue === null) {
15208 hook.baseState = newState;
15209 }
15210
15211 queue.lastRenderedState = newState;
15212 }
15213
15214 return [newState, dispatch];
15215}
15216
15217function mountState(initialState) {
15218 var hook = mountWorkInProgressHook();
15219
15220 if (typeof initialState === 'function') {
15221 // $FlowFixMe: Flow doesn't like mixed types
15222 initialState = initialState();
15223 }
15224
15225 hook.memoizedState = hook.baseState = initialState;
15226 var queue = hook.queue = {
15227 pending: null,
15228 dispatch: null,
15229 lastRenderedReducer: basicStateReducer,
15230 lastRenderedState: initialState
15231 };
15232 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15233 return [hook.memoizedState, dispatch];
15234}
15235
15236function updateState(initialState) {
15237 return updateReducer(basicStateReducer);
15238}
15239
15240function rerenderState(initialState) {
15241 return rerenderReducer(basicStateReducer);
15242}
15243
15244function pushEffect(tag, create, destroy, deps) {
15245 var effect = {
15246 tag: tag,
15247 create: create,
15248 destroy: destroy,
15249 deps: deps,
15250 // Circular
15251 next: null
15252 };
15253 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
15254
15255 if (componentUpdateQueue === null) {
15256 componentUpdateQueue = createFunctionComponentUpdateQueue();
15257 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
15258 componentUpdateQueue.lastEffect = effect.next = effect;
15259 } else {
15260 var lastEffect = componentUpdateQueue.lastEffect;
15261
15262 if (lastEffect === null) {
15263 componentUpdateQueue.lastEffect = effect.next = effect;
15264 } else {
15265 var firstEffect = lastEffect.next;
15266 lastEffect.next = effect;
15267 effect.next = firstEffect;
15268 componentUpdateQueue.lastEffect = effect;
15269 }
15270 }
15271
15272 return effect;
15273}
15274
15275function mountRef(initialValue) {
15276 var hook = mountWorkInProgressHook();
15277 var ref = {
15278 current: initialValue
15279 };
15280
15281 {
15282 Object.seal(ref);
15283 }
15284
15285 hook.memoizedState = ref;
15286 return ref;
15287}
15288
15289function updateRef(initialValue) {
15290 var hook = updateWorkInProgressHook();
15291 return hook.memoizedState;
15292}
15293
15294function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15295 var hook = mountWorkInProgressHook();
15296 var nextDeps = deps === undefined ? null : deps;
15297 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
15298 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);
15299}
15300
15301function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15302 var hook = updateWorkInProgressHook();
15303 var nextDeps = deps === undefined ? null : deps;
15304 var destroy = undefined;
15305
15306 if (currentHook !== null) {
15307 var prevEffect = currentHook.memoizedState;
15308 destroy = prevEffect.destroy;
15309
15310 if (nextDeps !== null) {
15311 var prevDeps = prevEffect.deps;
15312
15313 if (areHookInputsEqual(nextDeps, prevDeps)) {
15314 pushEffect(hookEffectTag, create, destroy, nextDeps);
15315 return;
15316 }
15317 }
15318 }
15319
15320 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
15321 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);
15322}
15323
15324function mountEffect(create, deps) {
15325 {
15326 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15327 if ('undefined' !== typeof jest) {
15328 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15329 }
15330 }
15331
15332 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
15333}
15334
15335function updateEffect(create, deps) {
15336 {
15337 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15338 if ('undefined' !== typeof jest) {
15339 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15340 }
15341 }
15342
15343 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
15344}
15345
15346function mountLayoutEffect(create, deps) {
15347 return mountEffectImpl(Update, Layout, create, deps);
15348}
15349
15350function updateLayoutEffect(create, deps) {
15351 return updateEffectImpl(Update, Layout, create, deps);
15352}
15353
15354function imperativeHandleEffect(create, ref) {
15355 if (typeof ref === 'function') {
15356 var refCallback = ref;
15357
15358 var _inst = create();
15359
15360 refCallback(_inst);
15361 return function () {
15362 refCallback(null);
15363 };
15364 } else if (ref !== null && ref !== undefined) {
15365 var refObject = ref;
15366
15367 {
15368 if (!refObject.hasOwnProperty('current')) {
15369 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');
15370 }
15371 }
15372
15373 var _inst2 = create();
15374
15375 refObject.current = _inst2;
15376 return function () {
15377 refObject.current = null;
15378 };
15379 }
15380}
15381
15382function mountImperativeHandle(ref, create, deps) {
15383 {
15384 if (typeof create !== 'function') {
15385 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15386 }
15387 } // TODO: If deps are provided, should we skip comparing the ref itself?
15388
15389
15390 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15391 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15392}
15393
15394function updateImperativeHandle(ref, create, deps) {
15395 {
15396 if (typeof create !== 'function') {
15397 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15398 }
15399 } // TODO: If deps are provided, should we skip comparing the ref itself?
15400
15401
15402 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15403 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15404}
15405
15406function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
15407 // The react-debug-hooks package injects its own implementation
15408 // so that e.g. DevTools can display custom hook values.
15409}
15410
15411var updateDebugValue = mountDebugValue;
15412
15413function mountCallback(callback, deps) {
15414 var hook = mountWorkInProgressHook();
15415 var nextDeps = deps === undefined ? null : deps;
15416 hook.memoizedState = [callback, nextDeps];
15417 return callback;
15418}
15419
15420function updateCallback(callback, deps) {
15421 var hook = updateWorkInProgressHook();
15422 var nextDeps = deps === undefined ? null : deps;
15423 var prevState = hook.memoizedState;
15424
15425 if (prevState !== null) {
15426 if (nextDeps !== null) {
15427 var prevDeps = prevState[1];
15428
15429 if (areHookInputsEqual(nextDeps, prevDeps)) {
15430 return prevState[0];
15431 }
15432 }
15433 }
15434
15435 hook.memoizedState = [callback, nextDeps];
15436 return callback;
15437}
15438
15439function mountMemo(nextCreate, deps) {
15440 var hook = mountWorkInProgressHook();
15441 var nextDeps = deps === undefined ? null : deps;
15442 var nextValue = nextCreate();
15443 hook.memoizedState = [nextValue, nextDeps];
15444 return nextValue;
15445}
15446
15447function updateMemo(nextCreate, deps) {
15448 var hook = updateWorkInProgressHook();
15449 var nextDeps = deps === undefined ? null : deps;
15450 var prevState = hook.memoizedState;
15451
15452 if (prevState !== null) {
15453 // Assume these are defined. If they're not, areHookInputsEqual will warn.
15454 if (nextDeps !== null) {
15455 var prevDeps = prevState[1];
15456
15457 if (areHookInputsEqual(nextDeps, prevDeps)) {
15458 return prevState[0];
15459 }
15460 }
15461 }
15462
15463 var nextValue = nextCreate();
15464 hook.memoizedState = [nextValue, nextDeps];
15465 return nextValue;
15466}
15467
15468function mountDeferredValue(value, config) {
15469 var _mountState = mountState(value),
15470 prevValue = _mountState[0],
15471 setValue = _mountState[1];
15472
15473 mountEffect(function () {
15474 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15475 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15476
15477 try {
15478 setValue(value);
15479 } finally {
15480 ReactCurrentBatchConfig$1.suspense = previousConfig;
15481 }
15482 }, [value, config]);
15483 return prevValue;
15484}
15485
15486function updateDeferredValue(value, config) {
15487 var _updateState = updateState(),
15488 prevValue = _updateState[0],
15489 setValue = _updateState[1];
15490
15491 updateEffect(function () {
15492 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15493 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15494
15495 try {
15496 setValue(value);
15497 } finally {
15498 ReactCurrentBatchConfig$1.suspense = previousConfig;
15499 }
15500 }, [value, config]);
15501 return prevValue;
15502}
15503
15504function rerenderDeferredValue(value, config) {
15505 var _rerenderState = rerenderState(),
15506 prevValue = _rerenderState[0],
15507 setValue = _rerenderState[1];
15508
15509 updateEffect(function () {
15510 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15511 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15512
15513 try {
15514 setValue(value);
15515 } finally {
15516 ReactCurrentBatchConfig$1.suspense = previousConfig;
15517 }
15518 }, [value, config]);
15519 return prevValue;
15520}
15521
15522function startTransition(setPending, config, callback) {
15523 var priorityLevel = getCurrentPriorityLevel();
15524 runWithPriority$1(priorityLevel < UserBlockingPriority$1 ? UserBlockingPriority$1 : priorityLevel, function () {
15525 setPending(true);
15526 });
15527 runWithPriority$1(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {
15528 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15529 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15530
15531 try {
15532 setPending(false);
15533 callback();
15534 } finally {
15535 ReactCurrentBatchConfig$1.suspense = previousConfig;
15536 }
15537 });
15538}
15539
15540function mountTransition(config) {
15541 var _mountState2 = mountState(false),
15542 isPending = _mountState2[0],
15543 setPending = _mountState2[1];
15544
15545 var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15546 return [start, isPending];
15547}
15548
15549function updateTransition(config) {
15550 var _updateState2 = updateState(),
15551 isPending = _updateState2[0],
15552 setPending = _updateState2[1];
15553
15554 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15555 return [start, isPending];
15556}
15557
15558function rerenderTransition(config) {
15559 var _rerenderState2 = rerenderState(),
15560 isPending = _rerenderState2[0],
15561 setPending = _rerenderState2[1];
15562
15563 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15564 return [start, isPending];
15565}
15566
15567function dispatchAction(fiber, queue, action) {
15568 {
15569 if (typeof arguments[3] === 'function') {
15570 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
15571 }
15572 }
15573
15574 var currentTime = requestCurrentTimeForUpdate();
15575 var suspenseConfig = requestCurrentSuspenseConfig();
15576 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
15577 var update = {
15578 expirationTime: expirationTime,
15579 suspenseConfig: suspenseConfig,
15580 action: action,
15581 eagerReducer: null,
15582 eagerState: null,
15583 next: null
15584 };
15585
15586 {
15587 update.priority = getCurrentPriorityLevel();
15588 } // Append the update to the end of the list.
15589
15590
15591 var pending = queue.pending;
15592
15593 if (pending === null) {
15594 // This is the first update. Create a circular list.
15595 update.next = update;
15596 } else {
15597 update.next = pending.next;
15598 pending.next = update;
15599 }
15600
15601 queue.pending = update;
15602 var alternate = fiber.alternate;
15603
15604 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
15605 // This is a render phase update. Stash it in a lazily-created map of
15606 // queue -> linked list of updates. After this render pass, we'll restart
15607 // and apply the stashed updates on top of the work-in-progress hook.
15608 didScheduleRenderPhaseUpdate = true;
15609 update.expirationTime = renderExpirationTime;
15610 currentlyRenderingFiber$1.expirationTime = renderExpirationTime;
15611 } else {
15612 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
15613 // The queue is currently empty, which means we can eagerly compute the
15614 // next state before entering the render phase. If the new state is the
15615 // same as the current state, we may be able to bail out entirely.
15616 var lastRenderedReducer = queue.lastRenderedReducer;
15617
15618 if (lastRenderedReducer !== null) {
15619 var prevDispatcher;
15620
15621 {
15622 prevDispatcher = ReactCurrentDispatcher.current;
15623 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
15624 }
15625
15626 try {
15627 var currentState = queue.lastRenderedState;
15628 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
15629 // it, on the update object. If the reducer hasn't changed by the
15630 // time we enter the render phase, then the eager state can be used
15631 // without calling the reducer again.
15632
15633 update.eagerReducer = lastRenderedReducer;
15634 update.eagerState = eagerState;
15635
15636 if (objectIs(eagerState, currentState)) {
15637 // Fast path. We can bail out without scheduling React to re-render.
15638 // It's still possible that we'll need to rebase this update later,
15639 // if the component re-renders for a different reason and by that
15640 // time the reducer has changed.
15641 return;
15642 }
15643 } catch (error) {// Suppress the error. It will throw again in the render phase.
15644 } finally {
15645 {
15646 ReactCurrentDispatcher.current = prevDispatcher;
15647 }
15648 }
15649 }
15650 }
15651
15652 {
15653 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15654 if ('undefined' !== typeof jest) {
15655 warnIfNotScopedWithMatchingAct(fiber);
15656 warnIfNotCurrentlyActingUpdatesInDev(fiber);
15657 }
15658 }
15659
15660 scheduleWork(fiber, expirationTime);
15661 }
15662}
15663
15664var ContextOnlyDispatcher = {
15665 readContext: readContext,
15666 useCallback: throwInvalidHookError,
15667 useContext: throwInvalidHookError,
15668 useEffect: throwInvalidHookError,
15669 useImperativeHandle: throwInvalidHookError,
15670 useLayoutEffect: throwInvalidHookError,
15671 useMemo: throwInvalidHookError,
15672 useReducer: throwInvalidHookError,
15673 useRef: throwInvalidHookError,
15674 useState: throwInvalidHookError,
15675 useDebugValue: throwInvalidHookError,
15676 useResponder: throwInvalidHookError,
15677 useDeferredValue: throwInvalidHookError,
15678 useTransition: throwInvalidHookError
15679};
15680var HooksDispatcherOnMountInDEV = null;
15681var HooksDispatcherOnMountWithHookTypesInDEV = null;
15682var HooksDispatcherOnUpdateInDEV = null;
15683var HooksDispatcherOnRerenderInDEV = null;
15684var InvalidNestedHooksDispatcherOnMountInDEV = null;
15685var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
15686var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
15687
15688{
15689 var warnInvalidContextAccess = function () {
15690 error('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().');
15691 };
15692
15693 var warnInvalidHookAccess = function () {
15694 error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
15695 };
15696
15697 HooksDispatcherOnMountInDEV = {
15698 readContext: function (context, observedBits) {
15699 return readContext(context, observedBits);
15700 },
15701 useCallback: function (callback, deps) {
15702 currentHookNameInDev = 'useCallback';
15703 mountHookTypesDev();
15704 checkDepsAreArrayDev(deps);
15705 return mountCallback(callback, deps);
15706 },
15707 useContext: function (context, observedBits) {
15708 currentHookNameInDev = 'useContext';
15709 mountHookTypesDev();
15710 return readContext(context, observedBits);
15711 },
15712 useEffect: function (create, deps) {
15713 currentHookNameInDev = 'useEffect';
15714 mountHookTypesDev();
15715 checkDepsAreArrayDev(deps);
15716 return mountEffect(create, deps);
15717 },
15718 useImperativeHandle: function (ref, create, deps) {
15719 currentHookNameInDev = 'useImperativeHandle';
15720 mountHookTypesDev();
15721 checkDepsAreArrayDev(deps);
15722 return mountImperativeHandle(ref, create, deps);
15723 },
15724 useLayoutEffect: function (create, deps) {
15725 currentHookNameInDev = 'useLayoutEffect';
15726 mountHookTypesDev();
15727 checkDepsAreArrayDev(deps);
15728 return mountLayoutEffect(create, deps);
15729 },
15730 useMemo: function (create, deps) {
15731 currentHookNameInDev = 'useMemo';
15732 mountHookTypesDev();
15733 checkDepsAreArrayDev(deps);
15734 var prevDispatcher = ReactCurrentDispatcher.current;
15735 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15736
15737 try {
15738 return mountMemo(create, deps);
15739 } finally {
15740 ReactCurrentDispatcher.current = prevDispatcher;
15741 }
15742 },
15743 useReducer: function (reducer, initialArg, init) {
15744 currentHookNameInDev = 'useReducer';
15745 mountHookTypesDev();
15746 var prevDispatcher = ReactCurrentDispatcher.current;
15747 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15748
15749 try {
15750 return mountReducer(reducer, initialArg, init);
15751 } finally {
15752 ReactCurrentDispatcher.current = prevDispatcher;
15753 }
15754 },
15755 useRef: function (initialValue) {
15756 currentHookNameInDev = 'useRef';
15757 mountHookTypesDev();
15758 return mountRef(initialValue);
15759 },
15760 useState: function (initialState) {
15761 currentHookNameInDev = 'useState';
15762 mountHookTypesDev();
15763 var prevDispatcher = ReactCurrentDispatcher.current;
15764 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15765
15766 try {
15767 return mountState(initialState);
15768 } finally {
15769 ReactCurrentDispatcher.current = prevDispatcher;
15770 }
15771 },
15772 useDebugValue: function (value, formatterFn) {
15773 currentHookNameInDev = 'useDebugValue';
15774 mountHookTypesDev();
15775 return mountDebugValue();
15776 },
15777 useResponder: function (responder, props) {
15778 currentHookNameInDev = 'useResponder';
15779 mountHookTypesDev();
15780 return createDeprecatedResponderListener(responder, props);
15781 },
15782 useDeferredValue: function (value, config) {
15783 currentHookNameInDev = 'useDeferredValue';
15784 mountHookTypesDev();
15785 return mountDeferredValue(value, config);
15786 },
15787 useTransition: function (config) {
15788 currentHookNameInDev = 'useTransition';
15789 mountHookTypesDev();
15790 return mountTransition(config);
15791 }
15792 };
15793 HooksDispatcherOnMountWithHookTypesInDEV = {
15794 readContext: function (context, observedBits) {
15795 return readContext(context, observedBits);
15796 },
15797 useCallback: function (callback, deps) {
15798 currentHookNameInDev = 'useCallback';
15799 updateHookTypesDev();
15800 return mountCallback(callback, deps);
15801 },
15802 useContext: function (context, observedBits) {
15803 currentHookNameInDev = 'useContext';
15804 updateHookTypesDev();
15805 return readContext(context, observedBits);
15806 },
15807 useEffect: function (create, deps) {
15808 currentHookNameInDev = 'useEffect';
15809 updateHookTypesDev();
15810 return mountEffect(create, deps);
15811 },
15812 useImperativeHandle: function (ref, create, deps) {
15813 currentHookNameInDev = 'useImperativeHandle';
15814 updateHookTypesDev();
15815 return mountImperativeHandle(ref, create, deps);
15816 },
15817 useLayoutEffect: function (create, deps) {
15818 currentHookNameInDev = 'useLayoutEffect';
15819 updateHookTypesDev();
15820 return mountLayoutEffect(create, deps);
15821 },
15822 useMemo: function (create, deps) {
15823 currentHookNameInDev = 'useMemo';
15824 updateHookTypesDev();
15825 var prevDispatcher = ReactCurrentDispatcher.current;
15826 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15827
15828 try {
15829 return mountMemo(create, deps);
15830 } finally {
15831 ReactCurrentDispatcher.current = prevDispatcher;
15832 }
15833 },
15834 useReducer: function (reducer, initialArg, init) {
15835 currentHookNameInDev = 'useReducer';
15836 updateHookTypesDev();
15837 var prevDispatcher = ReactCurrentDispatcher.current;
15838 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15839
15840 try {
15841 return mountReducer(reducer, initialArg, init);
15842 } finally {
15843 ReactCurrentDispatcher.current = prevDispatcher;
15844 }
15845 },
15846 useRef: function (initialValue) {
15847 currentHookNameInDev = 'useRef';
15848 updateHookTypesDev();
15849 return mountRef(initialValue);
15850 },
15851 useState: function (initialState) {
15852 currentHookNameInDev = 'useState';
15853 updateHookTypesDev();
15854 var prevDispatcher = ReactCurrentDispatcher.current;
15855 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15856
15857 try {
15858 return mountState(initialState);
15859 } finally {
15860 ReactCurrentDispatcher.current = prevDispatcher;
15861 }
15862 },
15863 useDebugValue: function (value, formatterFn) {
15864 currentHookNameInDev = 'useDebugValue';
15865 updateHookTypesDev();
15866 return mountDebugValue();
15867 },
15868 useResponder: function (responder, props) {
15869 currentHookNameInDev = 'useResponder';
15870 updateHookTypesDev();
15871 return createDeprecatedResponderListener(responder, props);
15872 },
15873 useDeferredValue: function (value, config) {
15874 currentHookNameInDev = 'useDeferredValue';
15875 updateHookTypesDev();
15876 return mountDeferredValue(value, config);
15877 },
15878 useTransition: function (config) {
15879 currentHookNameInDev = 'useTransition';
15880 updateHookTypesDev();
15881 return mountTransition(config);
15882 }
15883 };
15884 HooksDispatcherOnUpdateInDEV = {
15885 readContext: function (context, observedBits) {
15886 return readContext(context, observedBits);
15887 },
15888 useCallback: function (callback, deps) {
15889 currentHookNameInDev = 'useCallback';
15890 updateHookTypesDev();
15891 return updateCallback(callback, deps);
15892 },
15893 useContext: function (context, observedBits) {
15894 currentHookNameInDev = 'useContext';
15895 updateHookTypesDev();
15896 return readContext(context, observedBits);
15897 },
15898 useEffect: function (create, deps) {
15899 currentHookNameInDev = 'useEffect';
15900 updateHookTypesDev();
15901 return updateEffect(create, deps);
15902 },
15903 useImperativeHandle: function (ref, create, deps) {
15904 currentHookNameInDev = 'useImperativeHandle';
15905 updateHookTypesDev();
15906 return updateImperativeHandle(ref, create, deps);
15907 },
15908 useLayoutEffect: function (create, deps) {
15909 currentHookNameInDev = 'useLayoutEffect';
15910 updateHookTypesDev();
15911 return updateLayoutEffect(create, deps);
15912 },
15913 useMemo: function (create, deps) {
15914 currentHookNameInDev = 'useMemo';
15915 updateHookTypesDev();
15916 var prevDispatcher = ReactCurrentDispatcher.current;
15917 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
15918
15919 try {
15920 return updateMemo(create, deps);
15921 } finally {
15922 ReactCurrentDispatcher.current = prevDispatcher;
15923 }
15924 },
15925 useReducer: function (reducer, initialArg, init) {
15926 currentHookNameInDev = 'useReducer';
15927 updateHookTypesDev();
15928 var prevDispatcher = ReactCurrentDispatcher.current;
15929 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
15930
15931 try {
15932 return updateReducer(reducer, initialArg, init);
15933 } finally {
15934 ReactCurrentDispatcher.current = prevDispatcher;
15935 }
15936 },
15937 useRef: function (initialValue) {
15938 currentHookNameInDev = 'useRef';
15939 updateHookTypesDev();
15940 return updateRef();
15941 },
15942 useState: function (initialState) {
15943 currentHookNameInDev = 'useState';
15944 updateHookTypesDev();
15945 var prevDispatcher = ReactCurrentDispatcher.current;
15946 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
15947
15948 try {
15949 return updateState(initialState);
15950 } finally {
15951 ReactCurrentDispatcher.current = prevDispatcher;
15952 }
15953 },
15954 useDebugValue: function (value, formatterFn) {
15955 currentHookNameInDev = 'useDebugValue';
15956 updateHookTypesDev();
15957 return updateDebugValue();
15958 },
15959 useResponder: function (responder, props) {
15960 currentHookNameInDev = 'useResponder';
15961 updateHookTypesDev();
15962 return createDeprecatedResponderListener(responder, props);
15963 },
15964 useDeferredValue: function (value, config) {
15965 currentHookNameInDev = 'useDeferredValue';
15966 updateHookTypesDev();
15967 return updateDeferredValue(value, config);
15968 },
15969 useTransition: function (config) {
15970 currentHookNameInDev = 'useTransition';
15971 updateHookTypesDev();
15972 return updateTransition(config);
15973 }
15974 };
15975 HooksDispatcherOnRerenderInDEV = {
15976 readContext: function (context, observedBits) {
15977 return readContext(context, observedBits);
15978 },
15979 useCallback: function (callback, deps) {
15980 currentHookNameInDev = 'useCallback';
15981 updateHookTypesDev();
15982 return updateCallback(callback, deps);
15983 },
15984 useContext: function (context, observedBits) {
15985 currentHookNameInDev = 'useContext';
15986 updateHookTypesDev();
15987 return readContext(context, observedBits);
15988 },
15989 useEffect: function (create, deps) {
15990 currentHookNameInDev = 'useEffect';
15991 updateHookTypesDev();
15992 return updateEffect(create, deps);
15993 },
15994 useImperativeHandle: function (ref, create, deps) {
15995 currentHookNameInDev = 'useImperativeHandle';
15996 updateHookTypesDev();
15997 return updateImperativeHandle(ref, create, deps);
15998 },
15999 useLayoutEffect: function (create, deps) {
16000 currentHookNameInDev = 'useLayoutEffect';
16001 updateHookTypesDev();
16002 return updateLayoutEffect(create, deps);
16003 },
16004 useMemo: function (create, deps) {
16005 currentHookNameInDev = 'useMemo';
16006 updateHookTypesDev();
16007 var prevDispatcher = ReactCurrentDispatcher.current;
16008 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16009
16010 try {
16011 return updateMemo(create, deps);
16012 } finally {
16013 ReactCurrentDispatcher.current = prevDispatcher;
16014 }
16015 },
16016 useReducer: function (reducer, initialArg, init) {
16017 currentHookNameInDev = 'useReducer';
16018 updateHookTypesDev();
16019 var prevDispatcher = ReactCurrentDispatcher.current;
16020 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16021
16022 try {
16023 return rerenderReducer(reducer, initialArg, init);
16024 } finally {
16025 ReactCurrentDispatcher.current = prevDispatcher;
16026 }
16027 },
16028 useRef: function (initialValue) {
16029 currentHookNameInDev = 'useRef';
16030 updateHookTypesDev();
16031 return updateRef();
16032 },
16033 useState: function (initialState) {
16034 currentHookNameInDev = 'useState';
16035 updateHookTypesDev();
16036 var prevDispatcher = ReactCurrentDispatcher.current;
16037 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16038
16039 try {
16040 return rerenderState(initialState);
16041 } finally {
16042 ReactCurrentDispatcher.current = prevDispatcher;
16043 }
16044 },
16045 useDebugValue: function (value, formatterFn) {
16046 currentHookNameInDev = 'useDebugValue';
16047 updateHookTypesDev();
16048 return updateDebugValue();
16049 },
16050 useResponder: function (responder, props) {
16051 currentHookNameInDev = 'useResponder';
16052 updateHookTypesDev();
16053 return createDeprecatedResponderListener(responder, props);
16054 },
16055 useDeferredValue: function (value, config) {
16056 currentHookNameInDev = 'useDeferredValue';
16057 updateHookTypesDev();
16058 return rerenderDeferredValue(value, config);
16059 },
16060 useTransition: function (config) {
16061 currentHookNameInDev = 'useTransition';
16062 updateHookTypesDev();
16063 return rerenderTransition(config);
16064 }
16065 };
16066 InvalidNestedHooksDispatcherOnMountInDEV = {
16067 readContext: function (context, observedBits) {
16068 warnInvalidContextAccess();
16069 return readContext(context, observedBits);
16070 },
16071 useCallback: function (callback, deps) {
16072 currentHookNameInDev = 'useCallback';
16073 warnInvalidHookAccess();
16074 mountHookTypesDev();
16075 return mountCallback(callback, deps);
16076 },
16077 useContext: function (context, observedBits) {
16078 currentHookNameInDev = 'useContext';
16079 warnInvalidHookAccess();
16080 mountHookTypesDev();
16081 return readContext(context, observedBits);
16082 },
16083 useEffect: function (create, deps) {
16084 currentHookNameInDev = 'useEffect';
16085 warnInvalidHookAccess();
16086 mountHookTypesDev();
16087 return mountEffect(create, deps);
16088 },
16089 useImperativeHandle: function (ref, create, deps) {
16090 currentHookNameInDev = 'useImperativeHandle';
16091 warnInvalidHookAccess();
16092 mountHookTypesDev();
16093 return mountImperativeHandle(ref, create, deps);
16094 },
16095 useLayoutEffect: function (create, deps) {
16096 currentHookNameInDev = 'useLayoutEffect';
16097 warnInvalidHookAccess();
16098 mountHookTypesDev();
16099 return mountLayoutEffect(create, deps);
16100 },
16101 useMemo: function (create, deps) {
16102 currentHookNameInDev = 'useMemo';
16103 warnInvalidHookAccess();
16104 mountHookTypesDev();
16105 var prevDispatcher = ReactCurrentDispatcher.current;
16106 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16107
16108 try {
16109 return mountMemo(create, deps);
16110 } finally {
16111 ReactCurrentDispatcher.current = prevDispatcher;
16112 }
16113 },
16114 useReducer: function (reducer, initialArg, init) {
16115 currentHookNameInDev = 'useReducer';
16116 warnInvalidHookAccess();
16117 mountHookTypesDev();
16118 var prevDispatcher = ReactCurrentDispatcher.current;
16119 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16120
16121 try {
16122 return mountReducer(reducer, initialArg, init);
16123 } finally {
16124 ReactCurrentDispatcher.current = prevDispatcher;
16125 }
16126 },
16127 useRef: function (initialValue) {
16128 currentHookNameInDev = 'useRef';
16129 warnInvalidHookAccess();
16130 mountHookTypesDev();
16131 return mountRef(initialValue);
16132 },
16133 useState: function (initialState) {
16134 currentHookNameInDev = 'useState';
16135 warnInvalidHookAccess();
16136 mountHookTypesDev();
16137 var prevDispatcher = ReactCurrentDispatcher.current;
16138 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16139
16140 try {
16141 return mountState(initialState);
16142 } finally {
16143 ReactCurrentDispatcher.current = prevDispatcher;
16144 }
16145 },
16146 useDebugValue: function (value, formatterFn) {
16147 currentHookNameInDev = 'useDebugValue';
16148 warnInvalidHookAccess();
16149 mountHookTypesDev();
16150 return mountDebugValue();
16151 },
16152 useResponder: function (responder, props) {
16153 currentHookNameInDev = 'useResponder';
16154 warnInvalidHookAccess();
16155 mountHookTypesDev();
16156 return createDeprecatedResponderListener(responder, props);
16157 },
16158 useDeferredValue: function (value, config) {
16159 currentHookNameInDev = 'useDeferredValue';
16160 warnInvalidHookAccess();
16161 mountHookTypesDev();
16162 return mountDeferredValue(value, config);
16163 },
16164 useTransition: function (config) {
16165 currentHookNameInDev = 'useTransition';
16166 warnInvalidHookAccess();
16167 mountHookTypesDev();
16168 return mountTransition(config);
16169 }
16170 };
16171 InvalidNestedHooksDispatcherOnUpdateInDEV = {
16172 readContext: function (context, observedBits) {
16173 warnInvalidContextAccess();
16174 return readContext(context, observedBits);
16175 },
16176 useCallback: function (callback, deps) {
16177 currentHookNameInDev = 'useCallback';
16178 warnInvalidHookAccess();
16179 updateHookTypesDev();
16180 return updateCallback(callback, deps);
16181 },
16182 useContext: function (context, observedBits) {
16183 currentHookNameInDev = 'useContext';
16184 warnInvalidHookAccess();
16185 updateHookTypesDev();
16186 return readContext(context, observedBits);
16187 },
16188 useEffect: function (create, deps) {
16189 currentHookNameInDev = 'useEffect';
16190 warnInvalidHookAccess();
16191 updateHookTypesDev();
16192 return updateEffect(create, deps);
16193 },
16194 useImperativeHandle: function (ref, create, deps) {
16195 currentHookNameInDev = 'useImperativeHandle';
16196 warnInvalidHookAccess();
16197 updateHookTypesDev();
16198 return updateImperativeHandle(ref, create, deps);
16199 },
16200 useLayoutEffect: function (create, deps) {
16201 currentHookNameInDev = 'useLayoutEffect';
16202 warnInvalidHookAccess();
16203 updateHookTypesDev();
16204 return updateLayoutEffect(create, deps);
16205 },
16206 useMemo: function (create, deps) {
16207 currentHookNameInDev = 'useMemo';
16208 warnInvalidHookAccess();
16209 updateHookTypesDev();
16210 var prevDispatcher = ReactCurrentDispatcher.current;
16211 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16212
16213 try {
16214 return updateMemo(create, deps);
16215 } finally {
16216 ReactCurrentDispatcher.current = prevDispatcher;
16217 }
16218 },
16219 useReducer: function (reducer, initialArg, init) {
16220 currentHookNameInDev = 'useReducer';
16221 warnInvalidHookAccess();
16222 updateHookTypesDev();
16223 var prevDispatcher = ReactCurrentDispatcher.current;
16224 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16225
16226 try {
16227 return updateReducer(reducer, initialArg, init);
16228 } finally {
16229 ReactCurrentDispatcher.current = prevDispatcher;
16230 }
16231 },
16232 useRef: function (initialValue) {
16233 currentHookNameInDev = 'useRef';
16234 warnInvalidHookAccess();
16235 updateHookTypesDev();
16236 return updateRef();
16237 },
16238 useState: function (initialState) {
16239 currentHookNameInDev = 'useState';
16240 warnInvalidHookAccess();
16241 updateHookTypesDev();
16242 var prevDispatcher = ReactCurrentDispatcher.current;
16243 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16244
16245 try {
16246 return updateState(initialState);
16247 } finally {
16248 ReactCurrentDispatcher.current = prevDispatcher;
16249 }
16250 },
16251 useDebugValue: function (value, formatterFn) {
16252 currentHookNameInDev = 'useDebugValue';
16253 warnInvalidHookAccess();
16254 updateHookTypesDev();
16255 return updateDebugValue();
16256 },
16257 useResponder: function (responder, props) {
16258 currentHookNameInDev = 'useResponder';
16259 warnInvalidHookAccess();
16260 updateHookTypesDev();
16261 return createDeprecatedResponderListener(responder, props);
16262 },
16263 useDeferredValue: function (value, config) {
16264 currentHookNameInDev = 'useDeferredValue';
16265 warnInvalidHookAccess();
16266 updateHookTypesDev();
16267 return updateDeferredValue(value, config);
16268 },
16269 useTransition: function (config) {
16270 currentHookNameInDev = 'useTransition';
16271 warnInvalidHookAccess();
16272 updateHookTypesDev();
16273 return updateTransition(config);
16274 }
16275 };
16276 InvalidNestedHooksDispatcherOnRerenderInDEV = {
16277 readContext: function (context, observedBits) {
16278 warnInvalidContextAccess();
16279 return readContext(context, observedBits);
16280 },
16281 useCallback: function (callback, deps) {
16282 currentHookNameInDev = 'useCallback';
16283 warnInvalidHookAccess();
16284 updateHookTypesDev();
16285 return updateCallback(callback, deps);
16286 },
16287 useContext: function (context, observedBits) {
16288 currentHookNameInDev = 'useContext';
16289 warnInvalidHookAccess();
16290 updateHookTypesDev();
16291 return readContext(context, observedBits);
16292 },
16293 useEffect: function (create, deps) {
16294 currentHookNameInDev = 'useEffect';
16295 warnInvalidHookAccess();
16296 updateHookTypesDev();
16297 return updateEffect(create, deps);
16298 },
16299 useImperativeHandle: function (ref, create, deps) {
16300 currentHookNameInDev = 'useImperativeHandle';
16301 warnInvalidHookAccess();
16302 updateHookTypesDev();
16303 return updateImperativeHandle(ref, create, deps);
16304 },
16305 useLayoutEffect: function (create, deps) {
16306 currentHookNameInDev = 'useLayoutEffect';
16307 warnInvalidHookAccess();
16308 updateHookTypesDev();
16309 return updateLayoutEffect(create, deps);
16310 },
16311 useMemo: function (create, deps) {
16312 currentHookNameInDev = 'useMemo';
16313 warnInvalidHookAccess();
16314 updateHookTypesDev();
16315 var prevDispatcher = ReactCurrentDispatcher.current;
16316 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16317
16318 try {
16319 return updateMemo(create, deps);
16320 } finally {
16321 ReactCurrentDispatcher.current = prevDispatcher;
16322 }
16323 },
16324 useReducer: function (reducer, initialArg, init) {
16325 currentHookNameInDev = 'useReducer';
16326 warnInvalidHookAccess();
16327 updateHookTypesDev();
16328 var prevDispatcher = ReactCurrentDispatcher.current;
16329 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16330
16331 try {
16332 return rerenderReducer(reducer, initialArg, init);
16333 } finally {
16334 ReactCurrentDispatcher.current = prevDispatcher;
16335 }
16336 },
16337 useRef: function (initialValue) {
16338 currentHookNameInDev = 'useRef';
16339 warnInvalidHookAccess();
16340 updateHookTypesDev();
16341 return updateRef();
16342 },
16343 useState: function (initialState) {
16344 currentHookNameInDev = 'useState';
16345 warnInvalidHookAccess();
16346 updateHookTypesDev();
16347 var prevDispatcher = ReactCurrentDispatcher.current;
16348 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16349
16350 try {
16351 return rerenderState(initialState);
16352 } finally {
16353 ReactCurrentDispatcher.current = prevDispatcher;
16354 }
16355 },
16356 useDebugValue: function (value, formatterFn) {
16357 currentHookNameInDev = 'useDebugValue';
16358 warnInvalidHookAccess();
16359 updateHookTypesDev();
16360 return updateDebugValue();
16361 },
16362 useResponder: function (responder, props) {
16363 currentHookNameInDev = 'useResponder';
16364 warnInvalidHookAccess();
16365 updateHookTypesDev();
16366 return createDeprecatedResponderListener(responder, props);
16367 },
16368 useDeferredValue: function (value, config) {
16369 currentHookNameInDev = 'useDeferredValue';
16370 warnInvalidHookAccess();
16371 updateHookTypesDev();
16372 return rerenderDeferredValue(value, config);
16373 },
16374 useTransition: function (config) {
16375 currentHookNameInDev = 'useTransition';
16376 warnInvalidHookAccess();
16377 updateHookTypesDev();
16378 return rerenderTransition(config);
16379 }
16380 };
16381}
16382
16383var now$1 = Scheduler.unstable_now;
16384var commitTime = 0;
16385var profilerStartTime = -1;
16386
16387function getCommitTime() {
16388 return commitTime;
16389}
16390
16391function recordCommitTime() {
16392
16393 commitTime = now$1();
16394}
16395
16396function startProfilerTimer(fiber) {
16397
16398 profilerStartTime = now$1();
16399
16400 if (fiber.actualStartTime < 0) {
16401 fiber.actualStartTime = now$1();
16402 }
16403}
16404
16405function stopProfilerTimerIfRunning(fiber) {
16406
16407 profilerStartTime = -1;
16408}
16409
16410function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
16411
16412 if (profilerStartTime >= 0) {
16413 var elapsedTime = now$1() - profilerStartTime;
16414 fiber.actualDuration += elapsedTime;
16415
16416 if (overrideBaseTime) {
16417 fiber.selfBaseDuration = elapsedTime;
16418 }
16419
16420 profilerStartTime = -1;
16421 }
16422}
16423
16424// This may have been an insertion or a hydration.
16425
16426var hydrationParentFiber = null;
16427var nextHydratableInstance = null;
16428var isHydrating = false;
16429
16430function enterHydrationState(fiber) {
16431
16432 var parentInstance = fiber.stateNode.containerInfo;
16433 nextHydratableInstance = getFirstHydratableChild(parentInstance);
16434 hydrationParentFiber = fiber;
16435 isHydrating = true;
16436 return true;
16437}
16438
16439function deleteHydratableInstance(returnFiber, instance) {
16440 {
16441 switch (returnFiber.tag) {
16442 case HostRoot:
16443 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
16444 break;
16445
16446 case HostComponent:
16447 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
16448 break;
16449 }
16450 }
16451
16452 var childToDelete = createFiberFromHostInstanceForDeletion();
16453 childToDelete.stateNode = instance;
16454 childToDelete.return = returnFiber;
16455 childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
16456 // these children are not part of the reconciliation list of children.
16457 // Even if we abort and rereconcile the children, that will try to hydrate
16458 // again and the nodes are still in the host tree so these will be
16459 // recreated.
16460
16461 if (returnFiber.lastEffect !== null) {
16462 returnFiber.lastEffect.nextEffect = childToDelete;
16463 returnFiber.lastEffect = childToDelete;
16464 } else {
16465 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
16466 }
16467}
16468
16469function insertNonHydratedInstance(returnFiber, fiber) {
16470 fiber.effectTag = fiber.effectTag & ~Hydrating | Placement;
16471
16472 {
16473 switch (returnFiber.tag) {
16474 case HostRoot:
16475 {
16476 var parentContainer = returnFiber.stateNode.containerInfo;
16477
16478 switch (fiber.tag) {
16479 case HostComponent:
16480 var type = fiber.type;
16481 var props = fiber.pendingProps;
16482 didNotFindHydratableContainerInstance(parentContainer, type);
16483 break;
16484
16485 case HostText:
16486 var text = fiber.pendingProps;
16487 didNotFindHydratableContainerTextInstance(parentContainer, text);
16488 break;
16489 }
16490
16491 break;
16492 }
16493
16494 case HostComponent:
16495 {
16496 var parentType = returnFiber.type;
16497 var parentProps = returnFiber.memoizedProps;
16498 var parentInstance = returnFiber.stateNode;
16499
16500 switch (fiber.tag) {
16501 case HostComponent:
16502 var _type = fiber.type;
16503 var _props = fiber.pendingProps;
16504 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type);
16505 break;
16506
16507 case HostText:
16508 var _text = fiber.pendingProps;
16509 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
16510 break;
16511
16512 case SuspenseComponent:
16513 didNotFindHydratableSuspenseInstance(parentType, parentProps);
16514 break;
16515 }
16516
16517 break;
16518 }
16519
16520 default:
16521 return;
16522 }
16523 }
16524}
16525
16526function tryHydrate(fiber, nextInstance) {
16527 switch (fiber.tag) {
16528 case HostComponent:
16529 {
16530 var type = fiber.type;
16531 var props = fiber.pendingProps;
16532 var instance = canHydrateInstance(nextInstance, type);
16533
16534 if (instance !== null) {
16535 fiber.stateNode = instance;
16536 return true;
16537 }
16538
16539 return false;
16540 }
16541
16542 case HostText:
16543 {
16544 var text = fiber.pendingProps;
16545 var textInstance = canHydrateTextInstance(nextInstance, text);
16546
16547 if (textInstance !== null) {
16548 fiber.stateNode = textInstance;
16549 return true;
16550 }
16551
16552 return false;
16553 }
16554
16555 case SuspenseComponent:
16556 {
16557
16558 return false;
16559 }
16560
16561 default:
16562 return false;
16563 }
16564}
16565
16566function tryToClaimNextHydratableInstance(fiber) {
16567 if (!isHydrating) {
16568 return;
16569 }
16570
16571 var nextInstance = nextHydratableInstance;
16572
16573 if (!nextInstance) {
16574 // Nothing to hydrate. Make it an insertion.
16575 insertNonHydratedInstance(hydrationParentFiber, fiber);
16576 isHydrating = false;
16577 hydrationParentFiber = fiber;
16578 return;
16579 }
16580
16581 var firstAttemptedInstance = nextInstance;
16582
16583 if (!tryHydrate(fiber, nextInstance)) {
16584 // If we can't hydrate this instance let's try the next one.
16585 // We use this as a heuristic. It's based on intuition and not data so it
16586 // might be flawed or unnecessary.
16587 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
16588
16589 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
16590 // Nothing to hydrate. Make it an insertion.
16591 insertNonHydratedInstance(hydrationParentFiber, fiber);
16592 isHydrating = false;
16593 hydrationParentFiber = fiber;
16594 return;
16595 } // We matched the next one, we'll now assume that the first one was
16596 // superfluous and we'll delete it. Since we can't eagerly delete it
16597 // we'll have to schedule a deletion. To do that, this node needs a dummy
16598 // fiber associated with it.
16599
16600
16601 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
16602 }
16603
16604 hydrationParentFiber = fiber;
16605 nextHydratableInstance = getFirstHydratableChild(nextInstance);
16606}
16607
16608function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
16609
16610 var instance = fiber.stateNode;
16611 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.
16612
16613 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
16614 // is a new ref we mark this as an update.
16615
16616 if (updatePayload !== null) {
16617 return true;
16618 }
16619
16620 return false;
16621}
16622
16623function prepareToHydrateHostTextInstance(fiber) {
16624
16625 var textInstance = fiber.stateNode;
16626 var textContent = fiber.memoizedProps;
16627 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
16628
16629 {
16630 if (shouldUpdate) {
16631 // We assume that prepareToHydrateHostTextInstance is called in a context where the
16632 // hydration parent is the parent host component of this host text.
16633 var returnFiber = hydrationParentFiber;
16634
16635 if (returnFiber !== null) {
16636 switch (returnFiber.tag) {
16637 case HostRoot:
16638 {
16639 var parentContainer = returnFiber.stateNode.containerInfo;
16640 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
16641 break;
16642 }
16643
16644 case HostComponent:
16645 {
16646 var parentType = returnFiber.type;
16647 var parentProps = returnFiber.memoizedProps;
16648 var parentInstance = returnFiber.stateNode;
16649 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
16650 break;
16651 }
16652 }
16653 }
16654 }
16655 }
16656
16657 return shouldUpdate;
16658}
16659
16660function skipPastDehydratedSuspenseInstance(fiber) {
16661
16662 var suspenseState = fiber.memoizedState;
16663 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
16664
16665 if (!suspenseInstance) {
16666 {
16667 throw Error( "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." );
16668 }
16669 }
16670
16671 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
16672}
16673
16674function popToNextHostParent(fiber) {
16675 var parent = fiber.return;
16676
16677 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
16678 parent = parent.return;
16679 }
16680
16681 hydrationParentFiber = parent;
16682}
16683
16684function popHydrationState(fiber) {
16685
16686 if (fiber !== hydrationParentFiber) {
16687 // We're deeper than the current hydration context, inside an inserted
16688 // tree.
16689 return false;
16690 }
16691
16692 if (!isHydrating) {
16693 // If we're not currently hydrating but we're in a hydration context, then
16694 // we were an insertion and now need to pop up reenter hydration of our
16695 // siblings.
16696 popToNextHostParent(fiber);
16697 isHydrating = true;
16698 return false;
16699 }
16700
16701 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.
16702 // We only do this deeper than head and body since they tend to have random
16703 // other nodes in them. We also ignore components with pure text content in
16704 // side of them.
16705 // TODO: Better heuristic.
16706
16707 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
16708 var nextInstance = nextHydratableInstance;
16709
16710 while (nextInstance) {
16711 deleteHydratableInstance(fiber, nextInstance);
16712 nextInstance = getNextHydratableSibling(nextInstance);
16713 }
16714 }
16715
16716 popToNextHostParent(fiber);
16717
16718 if (fiber.tag === SuspenseComponent) {
16719 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
16720 } else {
16721 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
16722 }
16723
16724 return true;
16725}
16726
16727function resetHydrationState() {
16728
16729 hydrationParentFiber = null;
16730 nextHydratableInstance = null;
16731 isHydrating = false;
16732}
16733
16734var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
16735var didReceiveUpdate = false;
16736var didWarnAboutBadClass;
16737var didWarnAboutModulePatternComponent;
16738var didWarnAboutContextTypeOnFunctionComponent;
16739var didWarnAboutGetDerivedStateOnFunctionComponent;
16740var didWarnAboutFunctionRefs;
16741var didWarnAboutReassigningProps;
16742var didWarnAboutRevealOrder;
16743var didWarnAboutTailOptions;
16744
16745{
16746 didWarnAboutBadClass = {};
16747 didWarnAboutModulePatternComponent = {};
16748 didWarnAboutContextTypeOnFunctionComponent = {};
16749 didWarnAboutGetDerivedStateOnFunctionComponent = {};
16750 didWarnAboutFunctionRefs = {};
16751 didWarnAboutReassigningProps = false;
16752 didWarnAboutRevealOrder = {};
16753 didWarnAboutTailOptions = {};
16754}
16755
16756function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
16757 if (current === null) {
16758 // If this is a fresh new component that hasn't been rendered yet, we
16759 // won't update its child set by applying minimal side-effects. Instead,
16760 // we will add them all to the child before it gets rendered. That means
16761 // we can optimize this reconciliation pass by not tracking side-effects.
16762 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16763 } else {
16764 // If the current child is the same as the work in progress, it means that
16765 // we haven't yet started any work on these children. Therefore, we use
16766 // the clone algorithm to create a copy of all the current children.
16767 // If we had any progressed work already, that is invalid at this point so
16768 // let's throw it out.
16769 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
16770 }
16771}
16772
16773function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
16774 // This function is fork of reconcileChildren. It's used in cases where we
16775 // want to reconcile without matching against the existing set. This has the
16776 // effect of all current children being unmounted; even if the type and key
16777 // are the same, the old child is unmounted and a new child is created.
16778 //
16779 // To do this, we're going to go through the reconcile algorithm twice. In
16780 // the first pass, we schedule a deletion for all the current children by
16781 // passing null.
16782 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
16783 // pass null in place of where we usually pass the current child set. This has
16784 // the effect of remounting all children regardless of whether their
16785 // identities match.
16786
16787 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16788}
16789
16790function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
16791 // TODO: current can be non-null here even if the component
16792 // hasn't yet mounted. This happens after the first render suspends.
16793 // We'll need to figure out if this is fine or can cause issues.
16794 {
16795 if (workInProgress.type !== workInProgress.elementType) {
16796 // Lazy component props can't be validated in createElement
16797 // because they're only guaranteed to be resolved here.
16798 var innerPropTypes = Component.propTypes;
16799
16800 if (innerPropTypes) {
16801 checkPropTypes(innerPropTypes, nextProps, // Resolved props
16802 'prop', getComponentName(Component), getCurrentFiberStackInDev);
16803 }
16804 }
16805 }
16806
16807 var render = Component.render;
16808 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
16809
16810 var nextChildren;
16811 prepareToReadContext(workInProgress, renderExpirationTime);
16812
16813 {
16814 ReactCurrentOwner$1.current = workInProgress;
16815 setIsRendering(true);
16816 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
16817
16818 if ( workInProgress.mode & StrictMode) {
16819 // Only double-render components with Hooks
16820 if (workInProgress.memoizedState !== null) {
16821 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
16822 }
16823 }
16824
16825 setIsRendering(false);
16826 }
16827
16828 if (current !== null && !didReceiveUpdate) {
16829 bailoutHooks(current, workInProgress, renderExpirationTime);
16830 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
16831 } // React DevTools reads this flag.
16832
16833
16834 workInProgress.effectTag |= PerformedWork;
16835 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
16836 return workInProgress.child;
16837}
16838
16839function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
16840 if (current === null) {
16841 var type = Component.type;
16842
16843 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
16844 Component.defaultProps === undefined) {
16845 var resolvedType = type;
16846
16847 {
16848 resolvedType = resolveFunctionForHotReloading(type);
16849 } // If this is a plain function component without default props,
16850 // and with only the default shallow comparison, we upgrade it
16851 // to a SimpleMemoComponent to allow fast path updates.
16852
16853
16854 workInProgress.tag = SimpleMemoComponent;
16855 workInProgress.type = resolvedType;
16856
16857 {
16858 validateFunctionComponentInDev(workInProgress, type);
16859 }
16860
16861 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
16862 }
16863
16864 {
16865 var innerPropTypes = type.propTypes;
16866
16867 if (innerPropTypes) {
16868 // Inner memo component props aren't currently validated in createElement.
16869 // We could move it there, but we'd still need this for lazy code path.
16870 checkPropTypes(innerPropTypes, nextProps, // Resolved props
16871 'prop', getComponentName(type), getCurrentFiberStackInDev);
16872 }
16873 }
16874
16875 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
16876 child.ref = workInProgress.ref;
16877 child.return = workInProgress;
16878 workInProgress.child = child;
16879 return child;
16880 }
16881
16882 {
16883 var _type = Component.type;
16884 var _innerPropTypes = _type.propTypes;
16885
16886 if (_innerPropTypes) {
16887 // Inner memo component props aren't currently validated in createElement.
16888 // We could move it there, but we'd still need this for lazy code path.
16889 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
16890 'prop', getComponentName(_type), getCurrentFiberStackInDev);
16891 }
16892 }
16893
16894 var currentChild = current.child; // This is always exactly one child
16895
16896 if (updateExpirationTime < renderExpirationTime) {
16897 // This will be the props with resolved defaultProps,
16898 // unlike current.memoizedProps which will be the unresolved ones.
16899 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
16900
16901 var compare = Component.compare;
16902 compare = compare !== null ? compare : shallowEqual;
16903
16904 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
16905 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
16906 }
16907 } // React DevTools reads this flag.
16908
16909
16910 workInProgress.effectTag |= PerformedWork;
16911 var newChild = createWorkInProgress(currentChild, nextProps);
16912 newChild.ref = workInProgress.ref;
16913 newChild.return = workInProgress;
16914 workInProgress.child = newChild;
16915 return newChild;
16916}
16917
16918function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
16919 // TODO: current can be non-null here even if the component
16920 // hasn't yet mounted. This happens when the inner render suspends.
16921 // We'll need to figure out if this is fine or can cause issues.
16922 {
16923 if (workInProgress.type !== workInProgress.elementType) {
16924 // Lazy component props can't be validated in createElement
16925 // because they're only guaranteed to be resolved here.
16926 var outerMemoType = workInProgress.elementType;
16927
16928 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
16929 // We warn when you define propTypes on lazy()
16930 // so let's just skip over it to find memo() outer wrapper.
16931 // Inner props for memo are validated later.
16932 outerMemoType = refineResolvedLazyComponent(outerMemoType);
16933 }
16934
16935 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
16936
16937 if (outerPropTypes) {
16938 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
16939 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
16940 } // Inner propTypes will be validated in the function component path.
16941
16942 }
16943 }
16944
16945 if (current !== null) {
16946 var prevProps = current.memoizedProps;
16947
16948 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
16949 workInProgress.type === current.type )) {
16950 didReceiveUpdate = false;
16951
16952 if (updateExpirationTime < renderExpirationTime) {
16953 // The pending update priority was cleared at the beginning of
16954 // beginWork. We're about to bail out, but there might be additional
16955 // updates at a lower priority. Usually, the priority level of the
16956 // remaining updates is accumlated during the evaluation of the
16957 // component (i.e. when processing the update queue). But since since
16958 // we're bailing out early *without* evaluating the component, we need
16959 // to account for it here, too. Reset to the value of the current fiber.
16960 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
16961 // because a MemoComponent fiber does not have hooks or an update queue;
16962 // rather, it wraps around an inner component, which may or may not
16963 // contains hooks.
16964 // TODO: Move the reset at in beginWork out of the common path so that
16965 // this is no longer necessary.
16966 workInProgress.expirationTime = current.expirationTime;
16967 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
16968 }
16969 }
16970 }
16971
16972 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
16973}
16974
16975function updateFragment(current, workInProgress, renderExpirationTime) {
16976 var nextChildren = workInProgress.pendingProps;
16977 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
16978 return workInProgress.child;
16979}
16980
16981function updateMode(current, workInProgress, renderExpirationTime) {
16982 var nextChildren = workInProgress.pendingProps.children;
16983 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
16984 return workInProgress.child;
16985}
16986
16987function updateProfiler(current, workInProgress, renderExpirationTime) {
16988 {
16989 workInProgress.effectTag |= Update;
16990 }
16991
16992 var nextProps = workInProgress.pendingProps;
16993 var nextChildren = nextProps.children;
16994 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
16995 return workInProgress.child;
16996}
16997
16998function markRef(current, workInProgress) {
16999 var ref = workInProgress.ref;
17000
17001 if (current === null && ref !== null || current !== null && current.ref !== ref) {
17002 // Schedule a Ref effect
17003 workInProgress.effectTag |= Ref;
17004 }
17005}
17006
17007function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
17008 {
17009 if (workInProgress.type !== workInProgress.elementType) {
17010 // Lazy component props can't be validated in createElement
17011 // because they're only guaranteed to be resolved here.
17012 var innerPropTypes = Component.propTypes;
17013
17014 if (innerPropTypes) {
17015 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17016 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17017 }
17018 }
17019 }
17020
17021 var context;
17022
17023 {
17024 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
17025 context = getMaskedContext(workInProgress, unmaskedContext);
17026 }
17027
17028 var nextChildren;
17029 prepareToReadContext(workInProgress, renderExpirationTime);
17030
17031 {
17032 ReactCurrentOwner$1.current = workInProgress;
17033 setIsRendering(true);
17034 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
17035
17036 if ( workInProgress.mode & StrictMode) {
17037 // Only double-render components with Hooks
17038 if (workInProgress.memoizedState !== null) {
17039 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
17040 }
17041 }
17042
17043 setIsRendering(false);
17044 }
17045
17046 if (current !== null && !didReceiveUpdate) {
17047 bailoutHooks(current, workInProgress, renderExpirationTime);
17048 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17049 } // React DevTools reads this flag.
17050
17051
17052 workInProgress.effectTag |= PerformedWork;
17053 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17054 return workInProgress.child;
17055}
17056
17057function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
17058 {
17059 if (workInProgress.type !== workInProgress.elementType) {
17060 // Lazy component props can't be validated in createElement
17061 // because they're only guaranteed to be resolved here.
17062 var innerPropTypes = Component.propTypes;
17063
17064 if (innerPropTypes) {
17065 checkPropTypes(innerPropTypes, nextProps, // Resolved props
17066 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17067 }
17068 }
17069 } // Push context providers early to prevent context stack mismatches.
17070 // During mounting we don't know the child context yet as the instance doesn't exist.
17071 // We will invalidate the child context in finishClassComponent() right after rendering.
17072
17073
17074 var hasContext;
17075
17076 if (isContextProvider(Component)) {
17077 hasContext = true;
17078 pushContextProvider(workInProgress);
17079 } else {
17080 hasContext = false;
17081 }
17082
17083 prepareToReadContext(workInProgress, renderExpirationTime);
17084 var instance = workInProgress.stateNode;
17085 var shouldUpdate;
17086
17087 if (instance === null) {
17088 if (current !== null) {
17089 // A class component without an instance only mounts if it suspended
17090 // inside a non-concurrent tree, in an inconsistent state. We want to
17091 // treat it like a new mount, even though an empty version of it already
17092 // committed. Disconnect the alternate pointers.
17093 current.alternate = null;
17094 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17095
17096 workInProgress.effectTag |= Placement;
17097 } // In the initial pass we might need to construct the instance.
17098
17099
17100 constructClassInstance(workInProgress, Component, nextProps);
17101 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17102 shouldUpdate = true;
17103 } else if (current === null) {
17104 // In a resume, we'll already have an instance we can reuse.
17105 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17106 } else {
17107 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
17108 }
17109
17110 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
17111
17112 {
17113 var inst = workInProgress.stateNode;
17114
17115 if (inst.props !== nextProps) {
17116 if (!didWarnAboutReassigningProps) {
17117 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component');
17118 }
17119
17120 didWarnAboutReassigningProps = true;
17121 }
17122 }
17123
17124 return nextUnitOfWork;
17125}
17126
17127function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
17128 // Refs should update even if shouldComponentUpdate returns false
17129 markRef(current, workInProgress);
17130 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
17131
17132 if (!shouldUpdate && !didCaptureError) {
17133 // Context providers should defer to sCU for rendering
17134 if (hasContext) {
17135 invalidateContextProvider(workInProgress, Component, false);
17136 }
17137
17138 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17139 }
17140
17141 var instance = workInProgress.stateNode; // Rerender
17142
17143 ReactCurrentOwner$1.current = workInProgress;
17144 var nextChildren;
17145
17146 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
17147 // If we captured an error, but getDerivedStateFromError is not defined,
17148 // unmount all the children. componentDidCatch will schedule an update to
17149 // re-render a fallback. This is temporary until we migrate everyone to
17150 // the new API.
17151 // TODO: Warn in a future release.
17152 nextChildren = null;
17153
17154 {
17155 stopProfilerTimerIfRunning();
17156 }
17157 } else {
17158 {
17159 setIsRendering(true);
17160 nextChildren = instance.render();
17161
17162 if ( workInProgress.mode & StrictMode) {
17163 instance.render();
17164 }
17165
17166 setIsRendering(false);
17167 }
17168 } // React DevTools reads this flag.
17169
17170
17171 workInProgress.effectTag |= PerformedWork;
17172
17173 if (current !== null && didCaptureError) {
17174 // If we're recovering from an error, reconcile without reusing any of
17175 // the existing children. Conceptually, the normal children and the children
17176 // that are shown on error are two different sets, so we shouldn't reuse
17177 // normal children even if their identities match.
17178 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
17179 } else {
17180 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17181 } // Memoize state using the values we just used to render.
17182 // TODO: Restructure so we never read values from the instance.
17183
17184
17185 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
17186
17187 if (hasContext) {
17188 invalidateContextProvider(workInProgress, Component, true);
17189 }
17190
17191 return workInProgress.child;
17192}
17193
17194function pushHostRootContext(workInProgress) {
17195 var root = workInProgress.stateNode;
17196
17197 if (root.pendingContext) {
17198 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
17199 } else if (root.context) {
17200 // Should always be set
17201 pushTopLevelContextObject(workInProgress, root.context, false);
17202 }
17203
17204 pushHostContainer(workInProgress, root.containerInfo);
17205}
17206
17207function updateHostRoot(current, workInProgress, renderExpirationTime) {
17208 pushHostRootContext(workInProgress);
17209 var updateQueue = workInProgress.updateQueue;
17210
17211 if (!(current !== null && updateQueue !== null)) {
17212 {
17213 throw Error( "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." );
17214 }
17215 }
17216
17217 var nextProps = workInProgress.pendingProps;
17218 var prevState = workInProgress.memoizedState;
17219 var prevChildren = prevState !== null ? prevState.element : null;
17220 cloneUpdateQueue(current, workInProgress);
17221 processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);
17222 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
17223 // being called "element".
17224
17225 var nextChildren = nextState.element;
17226
17227 if (nextChildren === prevChildren) {
17228 // If the state is the same as before, that's a bailout because we had
17229 // no work that expires at this time.
17230 resetHydrationState();
17231 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17232 }
17233
17234 var root = workInProgress.stateNode;
17235
17236 if (root.hydrate && enterHydrationState(workInProgress)) {
17237 // If we don't have any current children this might be the first pass.
17238 // We always try to hydrate. If this isn't a hydration pass there won't
17239 // be any children to hydrate which is effectively the same thing as
17240 // not hydrating.
17241 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
17242 workInProgress.child = child;
17243 var node = child;
17244
17245 while (node) {
17246 // Mark each child as hydrating. This is a fast path to know whether this
17247 // tree is part of a hydrating tree. This is used to determine if a child
17248 // node has fully mounted yet, and for scheduling event replaying.
17249 // Conceptually this is similar to Placement in that a new subtree is
17250 // inserted into the React tree here. It just happens to not need DOM
17251 // mutations because it already exists.
17252 node.effectTag = node.effectTag & ~Placement | Hydrating;
17253 node = node.sibling;
17254 }
17255 } else {
17256 // Otherwise reset hydration state in case we aborted and resumed another
17257 // root.
17258 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17259 resetHydrationState();
17260 }
17261
17262 return workInProgress.child;
17263}
17264
17265function updateHostComponent(current, workInProgress, renderExpirationTime) {
17266 pushHostContext(workInProgress);
17267
17268 if (current === null) {
17269 tryToClaimNextHydratableInstance(workInProgress);
17270 }
17271
17272 var type = workInProgress.type;
17273 var nextProps = workInProgress.pendingProps;
17274 var prevProps = current !== null ? current.memoizedProps : null;
17275 var nextChildren = nextProps.children;
17276 var isDirectTextChild = shouldSetTextContent(type, nextProps);
17277
17278 if (isDirectTextChild) {
17279 // We special case a direct text child of a host node. This is a common
17280 // case. We won't handle it as a reified child. We will instead handle
17281 // this in the host environment that also has access to this prop. That
17282 // avoids allocating another HostText fiber and traversing it.
17283 nextChildren = null;
17284 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
17285 // If we're switching from a direct text child to a normal child, or to
17286 // empty, we need to schedule the text content to be reset.
17287 workInProgress.effectTag |= ContentReset;
17288 }
17289
17290 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
17291
17292 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
17293 {
17294 markSpawnedWork(Never);
17295 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
17296
17297
17298 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
17299 return null;
17300 }
17301
17302 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17303 return workInProgress.child;
17304}
17305
17306function updateHostText(current, workInProgress) {
17307 if (current === null) {
17308 tryToClaimNextHydratableInstance(workInProgress);
17309 } // Nothing to do here. This is terminal. We'll do the completion step
17310 // immediately after.
17311
17312
17313 return null;
17314}
17315
17316function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
17317 if (_current !== null) {
17318 // A lazy component only mounts if it suspended inside a non-
17319 // concurrent tree, in an inconsistent state. We want to treat it like
17320 // a new mount, even though an empty version of it already committed.
17321 // Disconnect the alternate pointers.
17322 _current.alternate = null;
17323 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17324
17325 workInProgress.effectTag |= Placement;
17326 }
17327
17328 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
17329 // Cancel and resume right after we know the tag.
17330
17331 cancelWorkTimer(workInProgress);
17332 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
17333
17334 workInProgress.type = Component;
17335 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
17336 startWorkTimer(workInProgress);
17337 var resolvedProps = resolveDefaultProps(Component, props);
17338 var child;
17339
17340 switch (resolvedTag) {
17341 case FunctionComponent:
17342 {
17343 {
17344 validateFunctionComponentInDev(workInProgress, Component);
17345 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
17346 }
17347
17348 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17349 return child;
17350 }
17351
17352 case ClassComponent:
17353 {
17354 {
17355 workInProgress.type = Component = resolveClassForHotReloading(Component);
17356 }
17357
17358 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17359 return child;
17360 }
17361
17362 case ForwardRef:
17363 {
17364 {
17365 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
17366 }
17367
17368 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17369 return child;
17370 }
17371
17372 case MemoComponent:
17373 {
17374 {
17375 if (workInProgress.type !== workInProgress.elementType) {
17376 var outerPropTypes = Component.propTypes;
17377
17378 if (outerPropTypes) {
17379 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
17380 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17381 }
17382 }
17383 }
17384
17385 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
17386 updateExpirationTime, renderExpirationTime);
17387 return child;
17388 }
17389 }
17390
17391 var hint = '';
17392
17393 {
17394 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
17395 hint = ' Did you wrap a component in React.lazy() more than once?';
17396 }
17397 } // This message intentionally doesn't mention ForwardRef or MemoComponent
17398 // because the fact that it's a separate type of work is an
17399 // implementation detail.
17400
17401
17402 {
17403 {
17404 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
17405 }
17406 }
17407}
17408
17409function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
17410 if (_current !== null) {
17411 // An incomplete component only mounts if it suspended inside a non-
17412 // concurrent tree, in an inconsistent state. We want to treat it like
17413 // a new mount, even though an empty version of it already committed.
17414 // Disconnect the alternate pointers.
17415 _current.alternate = null;
17416 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17417
17418 workInProgress.effectTag |= Placement;
17419 } // Promote the fiber to a class and try rendering again.
17420
17421
17422 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
17423 // Push context providers early to prevent context stack mismatches.
17424 // During mounting we don't know the child context yet as the instance doesn't exist.
17425 // We will invalidate the child context in finishClassComponent() right after rendering.
17426
17427 var hasContext;
17428
17429 if (isContextProvider(Component)) {
17430 hasContext = true;
17431 pushContextProvider(workInProgress);
17432 } else {
17433 hasContext = false;
17434 }
17435
17436 prepareToReadContext(workInProgress, renderExpirationTime);
17437 constructClassInstance(workInProgress, Component, nextProps);
17438 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17439 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17440}
17441
17442function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
17443 if (_current !== null) {
17444 // An indeterminate component only mounts if it suspended inside a non-
17445 // concurrent tree, in an inconsistent state. We want to treat it like
17446 // a new mount, even though an empty version of it already committed.
17447 // Disconnect the alternate pointers.
17448 _current.alternate = null;
17449 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17450
17451 workInProgress.effectTag |= Placement;
17452 }
17453
17454 var props = workInProgress.pendingProps;
17455 var context;
17456
17457 {
17458 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
17459 context = getMaskedContext(workInProgress, unmaskedContext);
17460 }
17461
17462 prepareToReadContext(workInProgress, renderExpirationTime);
17463 var value;
17464
17465 {
17466 if (Component.prototype && typeof Component.prototype.render === 'function') {
17467 var componentName = getComponentName(Component) || 'Unknown';
17468
17469 if (!didWarnAboutBadClass[componentName]) {
17470 error("The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
17471
17472 didWarnAboutBadClass[componentName] = true;
17473 }
17474 }
17475
17476 if (workInProgress.mode & StrictMode) {
17477 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
17478 }
17479
17480 setIsRendering(true);
17481 ReactCurrentOwner$1.current = workInProgress;
17482 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17483 setIsRendering(false);
17484 } // React DevTools reads this flag.
17485
17486
17487 workInProgress.effectTag |= PerformedWork;
17488
17489 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17490 {
17491 var _componentName = getComponentName(Component) || 'Unknown';
17492
17493 if (!didWarnAboutModulePatternComponent[_componentName]) {
17494 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
17495
17496 didWarnAboutModulePatternComponent[_componentName] = true;
17497 }
17498 } // Proceed under the assumption that this is a class instance
17499
17500
17501 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
17502
17503 workInProgress.memoizedState = null;
17504 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
17505 // During mounting we don't know the child context yet as the instance doesn't exist.
17506 // We will invalidate the child context in finishClassComponent() right after rendering.
17507
17508 var hasContext = false;
17509
17510 if (isContextProvider(Component)) {
17511 hasContext = true;
17512 pushContextProvider(workInProgress);
17513 } else {
17514 hasContext = false;
17515 }
17516
17517 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
17518 initializeUpdateQueue(workInProgress);
17519 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
17520
17521 if (typeof getDerivedStateFromProps === 'function') {
17522 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
17523 }
17524
17525 adoptClassInstance(workInProgress, value);
17526 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
17527 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17528 } else {
17529 // Proceed under the assumption that this is a function component
17530 workInProgress.tag = FunctionComponent;
17531
17532 {
17533
17534 if ( workInProgress.mode & StrictMode) {
17535 // Only double-render components with Hooks
17536 if (workInProgress.memoizedState !== null) {
17537 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17538 }
17539 }
17540 }
17541
17542 reconcileChildren(null, workInProgress, value, renderExpirationTime);
17543
17544 {
17545 validateFunctionComponentInDev(workInProgress, Component);
17546 }
17547
17548 return workInProgress.child;
17549 }
17550}
17551
17552function validateFunctionComponentInDev(workInProgress, Component) {
17553 {
17554 if (Component) {
17555 if (Component.childContextTypes) {
17556 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
17557 }
17558 }
17559
17560 if (workInProgress.ref !== null) {
17561 var info = '';
17562 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
17563
17564 if (ownerName) {
17565 info += '\n\nCheck the render method of `' + ownerName + '`.';
17566 }
17567
17568 var warningKey = ownerName || workInProgress._debugID || '';
17569 var debugSource = workInProgress._debugSource;
17570
17571 if (debugSource) {
17572 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
17573 }
17574
17575 if (!didWarnAboutFunctionRefs[warningKey]) {
17576 didWarnAboutFunctionRefs[warningKey] = true;
17577
17578 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
17579 }
17580 }
17581
17582 if (typeof Component.getDerivedStateFromProps === 'function') {
17583 var _componentName2 = getComponentName(Component) || 'Unknown';
17584
17585 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
17586 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
17587
17588 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
17589 }
17590 }
17591
17592 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
17593 var _componentName3 = getComponentName(Component) || 'Unknown';
17594
17595 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
17596 error('%s: Function components do not support contextType.', _componentName3);
17597
17598 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
17599 }
17600 }
17601 }
17602}
17603
17604var SUSPENDED_MARKER = {
17605 dehydrated: null,
17606 retryTime: NoWork
17607};
17608
17609function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
17610 // If the context is telling us that we should show a fallback, and we're not
17611 // already showing content, then we should show the fallback instead.
17612 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
17613}
17614
17615function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
17616 var mode = workInProgress.mode;
17617 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
17618
17619 {
17620 if (shouldSuspend(workInProgress)) {
17621 workInProgress.effectTag |= DidCapture;
17622 }
17623 }
17624
17625 var suspenseContext = suspenseStackCursor.current;
17626 var nextDidTimeout = false;
17627 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
17628
17629 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
17630 // Something in this boundary's subtree already suspended. Switch to
17631 // rendering the fallback children.
17632 nextDidTimeout = true;
17633 workInProgress.effectTag &= ~DidCapture;
17634 } else {
17635 // Attempting the main content
17636 if (current === null || current.memoizedState !== null) {
17637 // This is a new mount or this boundary is already showing a fallback state.
17638 // Mark this subtree context as having at least one invisible parent that could
17639 // handle the fallback state.
17640 // Boundaries without fallbacks or should be avoided are not considered since
17641 // they cannot handle preferred fallback states.
17642 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
17643 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
17644 }
17645 }
17646 }
17647
17648 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
17649 pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to
17650 // showing the fallback children in place of the "primary" children.
17651 // However, we don't want to delete the primary children because then their
17652 // state will be lost (both the React state and the host state, e.g.
17653 // uncontrolled form inputs). Instead we keep them mounted and hide them.
17654 // Both the fallback children AND the primary children are rendered at the
17655 // same time. Once the primary children are un-suspended, we can delete
17656 // the fallback children — don't need to preserve their state.
17657 //
17658 // The two sets of children are siblings in the host environment, but
17659 // semantically, for purposes of reconciliation, they are two separate sets.
17660 // So we store them using two fragment fibers.
17661 //
17662 // However, we want to avoid allocating extra fibers for every placeholder.
17663 // They're only necessary when the children time out, because that's the
17664 // only time when both sets are mounted.
17665 //
17666 // So, the extra fragment fibers are only used if the children time out.
17667 // Otherwise, we render the primary children directly. This requires some
17668 // custom reconciliation logic to preserve the state of the primary
17669 // children. It's essentially a very basic form of re-parenting.
17670
17671 if (current === null) {
17672 // If we're currently hydrating, try to hydrate this boundary.
17673 // But only if this has a fallback.
17674 if (nextProps.fallback !== undefined) {
17675 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
17676 } // This is the initial mount. This branch is pretty simple because there's
17677 // no previous state that needs to be preserved.
17678
17679
17680 if (nextDidTimeout) {
17681 // Mount separate fragments for primary and fallback children.
17682 var nextFallbackChildren = nextProps.fallback;
17683 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
17684 primaryChildFragment.return = workInProgress;
17685
17686 if ((workInProgress.mode & BlockingMode) === NoMode) {
17687 // Outside of blocking mode, we commit the effects from the
17688 // partially completed, timed-out tree, too.
17689 var progressedState = workInProgress.memoizedState;
17690 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
17691 primaryChildFragment.child = progressedPrimaryChild;
17692 var progressedChild = progressedPrimaryChild;
17693
17694 while (progressedChild !== null) {
17695 progressedChild.return = primaryChildFragment;
17696 progressedChild = progressedChild.sibling;
17697 }
17698 }
17699
17700 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
17701 fallbackChildFragment.return = workInProgress;
17702 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
17703 // fallback children.
17704
17705 workInProgress.memoizedState = SUSPENDED_MARKER;
17706 workInProgress.child = primaryChildFragment;
17707 return fallbackChildFragment;
17708 } else {
17709 // Mount the primary children without an intermediate fragment fiber.
17710 var nextPrimaryChildren = nextProps.children;
17711 workInProgress.memoizedState = null;
17712 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
17713 }
17714 } else {
17715 // This is an update. This branch is more complicated because we need to
17716 // ensure the state of the primary children is preserved.
17717 var prevState = current.memoizedState;
17718
17719 if (prevState !== null) {
17720 // wrapped in a fragment fiber.
17721
17722
17723 var currentPrimaryChildFragment = current.child;
17724 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
17725
17726 if (nextDidTimeout) {
17727 // Still timed out. Reuse the current primary children by cloning
17728 // its fragment. We're going to skip over these entirely.
17729 var _nextFallbackChildren2 = nextProps.fallback;
17730
17731 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);
17732
17733 _primaryChildFragment2.return = workInProgress;
17734
17735 if ((workInProgress.mode & BlockingMode) === NoMode) {
17736 // Outside of blocking mode, we commit the effects from the
17737 // partially completed, timed-out tree, too.
17738 var _progressedState = workInProgress.memoizedState;
17739
17740 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
17741
17742 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
17743 _primaryChildFragment2.child = _progressedPrimaryChild;
17744 var _progressedChild2 = _progressedPrimaryChild;
17745
17746 while (_progressedChild2 !== null) {
17747 _progressedChild2.return = _primaryChildFragment2;
17748 _progressedChild2 = _progressedChild2.sibling;
17749 }
17750 }
17751 } // Because primaryChildFragment is a new fiber that we're inserting as the
17752 // parent of a new tree, we need to set its treeBaseDuration.
17753
17754
17755 if ( workInProgress.mode & ProfileMode) {
17756 // treeBaseDuration is the sum of all the child tree base durations.
17757 var _treeBaseDuration = 0;
17758 var _hiddenChild = _primaryChildFragment2.child;
17759
17760 while (_hiddenChild !== null) {
17761 _treeBaseDuration += _hiddenChild.treeBaseDuration;
17762 _hiddenChild = _hiddenChild.sibling;
17763 }
17764
17765 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
17766 } // Clone the fallback child fragment, too. These we'll continue
17767 // working on.
17768
17769
17770 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);
17771
17772 _fallbackChildFragment2.return = workInProgress;
17773 _primaryChildFragment2.sibling = _fallbackChildFragment2;
17774 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
17775 // fallback children.
17776
17777 workInProgress.memoizedState = SUSPENDED_MARKER;
17778 workInProgress.child = _primaryChildFragment2;
17779 return _fallbackChildFragment2;
17780 } else {
17781 // No longer suspended. Switch back to showing the primary children,
17782 // and remove the intermediate fragment fiber.
17783 var _nextPrimaryChildren = nextProps.children;
17784 var currentPrimaryChild = currentPrimaryChildFragment.child;
17785 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
17786 // children. Wait until the complete phase, after we've confirmed the
17787 // fallback is no longer needed.
17788 // TODO: Would it be better to store the fallback fragment on
17789 // the stateNode?
17790 // Continue rendering the children, like we normally do.
17791
17792 workInProgress.memoizedState = null;
17793 return workInProgress.child = primaryChild;
17794 }
17795 } else {
17796 // The current tree has not already timed out. That means the primary
17797 // children are not wrapped in a fragment fiber.
17798 var _currentPrimaryChild = current.child;
17799
17800 if (nextDidTimeout) {
17801 // Timed out. Wrap the children in a fragment fiber to keep them
17802 // separate from the fallback children.
17803 var _nextFallbackChildren3 = nextProps.fallback;
17804
17805 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
17806 // going to render this fragment.
17807 null, mode, NoWork, null);
17808
17809 _primaryChildFragment3.return = workInProgress;
17810 _primaryChildFragment3.child = _currentPrimaryChild;
17811
17812 if (_currentPrimaryChild !== null) {
17813 _currentPrimaryChild.return = _primaryChildFragment3;
17814 } // Even though we're creating a new fiber, there are no new children,
17815 // because we're reusing an already mounted tree. So we don't need to
17816 // schedule a placement.
17817 // primaryChildFragment.effectTag |= Placement;
17818
17819
17820 if ((workInProgress.mode & BlockingMode) === NoMode) {
17821 // Outside of blocking mode, we commit the effects from the
17822 // partially completed, timed-out tree, too.
17823 var _progressedState2 = workInProgress.memoizedState;
17824
17825 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
17826
17827 _primaryChildFragment3.child = _progressedPrimaryChild2;
17828 var _progressedChild3 = _progressedPrimaryChild2;
17829
17830 while (_progressedChild3 !== null) {
17831 _progressedChild3.return = _primaryChildFragment3;
17832 _progressedChild3 = _progressedChild3.sibling;
17833 }
17834 } // Because primaryChildFragment is a new fiber that we're inserting as the
17835 // parent of a new tree, we need to set its treeBaseDuration.
17836
17837
17838 if ( workInProgress.mode & ProfileMode) {
17839 // treeBaseDuration is the sum of all the child tree base durations.
17840 var _treeBaseDuration2 = 0;
17841 var _hiddenChild2 = _primaryChildFragment3.child;
17842
17843 while (_hiddenChild2 !== null) {
17844 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
17845 _hiddenChild2 = _hiddenChild2.sibling;
17846 }
17847
17848 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
17849 } // Create a fragment from the fallback children, too.
17850
17851
17852 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
17853
17854 _fallbackChildFragment3.return = workInProgress;
17855 _primaryChildFragment3.sibling = _fallbackChildFragment3;
17856 _fallbackChildFragment3.effectTag |= Placement;
17857 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
17858 // fallback children.
17859
17860 workInProgress.memoizedState = SUSPENDED_MARKER;
17861 workInProgress.child = _primaryChildFragment3;
17862 return _fallbackChildFragment3;
17863 } else {
17864 // Still haven't timed out. Continue rendering the children, like we
17865 // normally do.
17866 workInProgress.memoizedState = null;
17867 var _nextPrimaryChildren2 = nextProps.children;
17868 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
17869 }
17870 }
17871 }
17872}
17873
17874function scheduleWorkOnFiber(fiber, renderExpirationTime) {
17875 if (fiber.expirationTime < renderExpirationTime) {
17876 fiber.expirationTime = renderExpirationTime;
17877 }
17878
17879 var alternate = fiber.alternate;
17880
17881 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
17882 alternate.expirationTime = renderExpirationTime;
17883 }
17884
17885 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
17886}
17887
17888function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
17889 // Mark any Suspense boundaries with fallbacks as having work to do.
17890 // If they were previously forced into fallbacks, they may now be able
17891 // to unblock.
17892 var node = firstChild;
17893
17894 while (node !== null) {
17895 if (node.tag === SuspenseComponent) {
17896 var state = node.memoizedState;
17897
17898 if (state !== null) {
17899 scheduleWorkOnFiber(node, renderExpirationTime);
17900 }
17901 } else if (node.tag === SuspenseListComponent) {
17902 // If the tail is hidden there might not be an Suspense boundaries
17903 // to schedule work on. In this case we have to schedule it on the
17904 // list itself.
17905 // We don't have to traverse to the children of the list since
17906 // the list will propagate the change when it rerenders.
17907 scheduleWorkOnFiber(node, renderExpirationTime);
17908 } else if (node.child !== null) {
17909 node.child.return = node;
17910 node = node.child;
17911 continue;
17912 }
17913
17914 if (node === workInProgress) {
17915 return;
17916 }
17917
17918 while (node.sibling === null) {
17919 if (node.return === null || node.return === workInProgress) {
17920 return;
17921 }
17922
17923 node = node.return;
17924 }
17925
17926 node.sibling.return = node.return;
17927 node = node.sibling;
17928 }
17929}
17930
17931function findLastContentRow(firstChild) {
17932 // This is going to find the last row among these children that is already
17933 // showing content on the screen, as opposed to being in fallback state or
17934 // new. If a row has multiple Suspense boundaries, any of them being in the
17935 // fallback state, counts as the whole row being in a fallback state.
17936 // Note that the "rows" will be workInProgress, but any nested children
17937 // will still be current since we haven't rendered them yet. The mounted
17938 // order may not be the same as the new order. We use the new order.
17939 var row = firstChild;
17940 var lastContentRow = null;
17941
17942 while (row !== null) {
17943 var currentRow = row.alternate; // New rows can't be content rows.
17944
17945 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
17946 lastContentRow = row;
17947 }
17948
17949 row = row.sibling;
17950 }
17951
17952 return lastContentRow;
17953}
17954
17955function validateRevealOrder(revealOrder) {
17956 {
17957 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
17958 didWarnAboutRevealOrder[revealOrder] = true;
17959
17960 if (typeof revealOrder === 'string') {
17961 switch (revealOrder.toLowerCase()) {
17962 case 'together':
17963 case 'forwards':
17964 case 'backwards':
17965 {
17966 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
17967
17968 break;
17969 }
17970
17971 case 'forward':
17972 case 'backward':
17973 {
17974 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
17975
17976 break;
17977 }
17978
17979 default:
17980 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
17981
17982 break;
17983 }
17984 } else {
17985 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
17986 }
17987 }
17988 }
17989}
17990
17991function validateTailOptions(tailMode, revealOrder) {
17992 {
17993 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
17994 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
17995 didWarnAboutTailOptions[tailMode] = true;
17996
17997 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
17998 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
17999 didWarnAboutTailOptions[tailMode] = true;
18000
18001 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
18002 }
18003 }
18004 }
18005}
18006
18007function validateSuspenseListNestedChild(childSlot, index) {
18008 {
18009 var isArray = Array.isArray(childSlot);
18010 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
18011
18012 if (isArray || isIterable) {
18013 var type = isArray ? 'array' : 'iterable';
18014
18015 error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
18016
18017 return false;
18018 }
18019 }
18020
18021 return true;
18022}
18023
18024function validateSuspenseListChildren(children, revealOrder) {
18025 {
18026 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
18027 if (Array.isArray(children)) {
18028 for (var i = 0; i < children.length; i++) {
18029 if (!validateSuspenseListNestedChild(children[i], i)) {
18030 return;
18031 }
18032 }
18033 } else {
18034 var iteratorFn = getIteratorFn(children);
18035
18036 if (typeof iteratorFn === 'function') {
18037 var childrenIterator = iteratorFn.call(children);
18038
18039 if (childrenIterator) {
18040 var step = childrenIterator.next();
18041 var _i = 0;
18042
18043 for (; !step.done; step = childrenIterator.next()) {
18044 if (!validateSuspenseListNestedChild(step.value, _i)) {
18045 return;
18046 }
18047
18048 _i++;
18049 }
18050 }
18051 } else {
18052 error('A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
18053 }
18054 }
18055 }
18056 }
18057}
18058
18059function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
18060 var renderState = workInProgress.memoizedState;
18061
18062 if (renderState === null) {
18063 workInProgress.memoizedState = {
18064 isBackwards: isBackwards,
18065 rendering: null,
18066 renderingStartTime: 0,
18067 last: lastContentRow,
18068 tail: tail,
18069 tailExpiration: 0,
18070 tailMode: tailMode,
18071 lastEffect: lastEffectBeforeRendering
18072 };
18073 } else {
18074 // We can reuse the existing object from previous renders.
18075 renderState.isBackwards = isBackwards;
18076 renderState.rendering = null;
18077 renderState.renderingStartTime = 0;
18078 renderState.last = lastContentRow;
18079 renderState.tail = tail;
18080 renderState.tailExpiration = 0;
18081 renderState.tailMode = tailMode;
18082 renderState.lastEffect = lastEffectBeforeRendering;
18083 }
18084} // This can end up rendering this component multiple passes.
18085// The first pass splits the children fibers into two sets. A head and tail.
18086// We first render the head. If anything is in fallback state, we do another
18087// pass through beginWork to rerender all children (including the tail) with
18088// the force suspend context. If the first render didn't have anything in
18089// in fallback state. Then we render each row in the tail one-by-one.
18090// That happens in the completeWork phase without going back to beginWork.
18091
18092
18093function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
18094 var nextProps = workInProgress.pendingProps;
18095 var revealOrder = nextProps.revealOrder;
18096 var tailMode = nextProps.tail;
18097 var newChildren = nextProps.children;
18098 validateRevealOrder(revealOrder);
18099 validateTailOptions(tailMode, revealOrder);
18100 validateSuspenseListChildren(newChildren, revealOrder);
18101 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18102 var suspenseContext = suspenseStackCursor.current;
18103 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
18104
18105 if (shouldForceFallback) {
18106 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
18107 workInProgress.effectTag |= DidCapture;
18108 } else {
18109 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
18110
18111 if (didSuspendBefore) {
18112 // If we previously forced a fallback, we need to schedule work
18113 // on any nested boundaries to let them know to try to render
18114 // again. This is the same as context updating.
18115 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
18116 }
18117
18118 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18119 }
18120
18121 pushSuspenseContext(workInProgress, suspenseContext);
18122
18123 if ((workInProgress.mode & BlockingMode) === NoMode) {
18124 // Outside of blocking mode, SuspenseList doesn't work so we just
18125 // use make it a noop by treating it as the default revealOrder.
18126 workInProgress.memoizedState = null;
18127 } else {
18128 switch (revealOrder) {
18129 case 'forwards':
18130 {
18131 var lastContentRow = findLastContentRow(workInProgress.child);
18132 var tail;
18133
18134 if (lastContentRow === null) {
18135 // The whole list is part of the tail.
18136 // TODO: We could fast path by just rendering the tail now.
18137 tail = workInProgress.child;
18138 workInProgress.child = null;
18139 } else {
18140 // Disconnect the tail rows after the content row.
18141 // We're going to render them separately later.
18142 tail = lastContentRow.sibling;
18143 lastContentRow.sibling = null;
18144 }
18145
18146 initSuspenseListRenderState(workInProgress, false, // isBackwards
18147 tail, lastContentRow, tailMode, workInProgress.lastEffect);
18148 break;
18149 }
18150
18151 case 'backwards':
18152 {
18153 // We're going to find the first row that has existing content.
18154 // At the same time we're going to reverse the list of everything
18155 // we pass in the meantime. That's going to be our tail in reverse
18156 // order.
18157 var _tail = null;
18158 var row = workInProgress.child;
18159 workInProgress.child = null;
18160
18161 while (row !== null) {
18162 var currentRow = row.alternate; // New rows can't be content rows.
18163
18164 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18165 // This is the beginning of the main content.
18166 workInProgress.child = row;
18167 break;
18168 }
18169
18170 var nextRow = row.sibling;
18171 row.sibling = _tail;
18172 _tail = row;
18173 row = nextRow;
18174 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
18175
18176
18177 initSuspenseListRenderState(workInProgress, true, // isBackwards
18178 _tail, null, // last
18179 tailMode, workInProgress.lastEffect);
18180 break;
18181 }
18182
18183 case 'together':
18184 {
18185 initSuspenseListRenderState(workInProgress, false, // isBackwards
18186 null, // tail
18187 null, // last
18188 undefined, workInProgress.lastEffect);
18189 break;
18190 }
18191
18192 default:
18193 {
18194 // The default reveal order is the same as not having
18195 // a boundary.
18196 workInProgress.memoizedState = null;
18197 }
18198 }
18199 }
18200
18201 return workInProgress.child;
18202}
18203
18204function updatePortalComponent(current, workInProgress, renderExpirationTime) {
18205 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18206 var nextChildren = workInProgress.pendingProps;
18207
18208 if (current === null) {
18209 // Portals are special because we don't append the children during mount
18210 // but at commit. Therefore we need to track insertions which the normal
18211 // flow doesn't do during mount. This doesn't happen at the root because
18212 // the root always starts with a "current" with a null child.
18213 // TODO: Consider unifying this with how the root works.
18214 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
18215 } else {
18216 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
18217 }
18218
18219 return workInProgress.child;
18220}
18221
18222function updateContextProvider(current, workInProgress, renderExpirationTime) {
18223 var providerType = workInProgress.type;
18224 var context = providerType._context;
18225 var newProps = workInProgress.pendingProps;
18226 var oldProps = workInProgress.memoizedProps;
18227 var newValue = newProps.value;
18228
18229 {
18230 var providerPropTypes = workInProgress.type.propTypes;
18231
18232 if (providerPropTypes) {
18233 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
18234 }
18235 }
18236
18237 pushProvider(workInProgress, newValue);
18238
18239 if (oldProps !== null) {
18240 var oldValue = oldProps.value;
18241 var changedBits = calculateChangedBits(context, newValue, oldValue);
18242
18243 if (changedBits === 0) {
18244 // No change. Bailout early if children are the same.
18245 if (oldProps.children === newProps.children && !hasContextChanged()) {
18246 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18247 }
18248 } else {
18249 // The context value changed. Search for matching consumers and schedule
18250 // them to update.
18251 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
18252 }
18253 }
18254
18255 var newChildren = newProps.children;
18256 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18257 return workInProgress.child;
18258}
18259
18260var hasWarnedAboutUsingContextAsConsumer = false;
18261
18262function updateContextConsumer(current, workInProgress, renderExpirationTime) {
18263 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
18264 // DEV mode, we create a separate object for Context.Consumer that acts
18265 // like a proxy to Context. This proxy object adds unnecessary code in PROD
18266 // so we use the old behaviour (Context.Consumer references Context) to
18267 // reduce size and overhead. The separate object references context via
18268 // a property called "_context", which also gives us the ability to check
18269 // in DEV mode if this property exists or not and warn if it does not.
18270
18271 {
18272 if (context._context === undefined) {
18273 // This may be because it's a Context (rather than a Consumer).
18274 // Or it may be because it's older React where they're the same thing.
18275 // We only want to warn if we're sure it's a new React.
18276 if (context !== context.Consumer) {
18277 if (!hasWarnedAboutUsingContextAsConsumer) {
18278 hasWarnedAboutUsingContextAsConsumer = true;
18279
18280 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
18281 }
18282 }
18283 } else {
18284 context = context._context;
18285 }
18286 }
18287
18288 var newProps = workInProgress.pendingProps;
18289 var render = newProps.children;
18290
18291 {
18292 if (typeof render !== 'function') {
18293 error('A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.');
18294 }
18295 }
18296
18297 prepareToReadContext(workInProgress, renderExpirationTime);
18298 var newValue = readContext(context, newProps.unstable_observedBits);
18299 var newChildren;
18300
18301 {
18302 ReactCurrentOwner$1.current = workInProgress;
18303 setIsRendering(true);
18304 newChildren = render(newValue);
18305 setIsRendering(false);
18306 } // React DevTools reads this flag.
18307
18308
18309 workInProgress.effectTag |= PerformedWork;
18310 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18311 return workInProgress.child;
18312}
18313
18314function markWorkInProgressReceivedUpdate() {
18315 didReceiveUpdate = true;
18316}
18317
18318function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
18319 cancelWorkTimer(workInProgress);
18320
18321 if (current !== null) {
18322 // Reuse previous dependencies
18323 workInProgress.dependencies = current.dependencies;
18324 }
18325
18326 {
18327 // Don't update "base" render times for bailouts.
18328 stopProfilerTimerIfRunning();
18329 }
18330
18331 var updateExpirationTime = workInProgress.expirationTime;
18332
18333 if (updateExpirationTime !== NoWork) {
18334 markUnprocessedUpdateTime(updateExpirationTime);
18335 } // Check if the children have any pending work.
18336
18337
18338 var childExpirationTime = workInProgress.childExpirationTime;
18339
18340 if (childExpirationTime < renderExpirationTime) {
18341 // The children don't have any work either. We can skip them.
18342 // TODO: Once we add back resuming, we should check if the children are
18343 // a work-in-progress set. If so, we need to transfer their effects.
18344 return null;
18345 } else {
18346 // This fiber doesn't have work, but its subtree does. Clone the child
18347 // fibers and continue.
18348 cloneChildFibers(current, workInProgress);
18349 return workInProgress.child;
18350 }
18351}
18352
18353function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
18354 {
18355 var returnFiber = oldWorkInProgress.return;
18356
18357 if (returnFiber === null) {
18358 throw new Error('Cannot swap the root fiber.');
18359 } // Disconnect from the old current.
18360 // It will get deleted.
18361
18362
18363 current.alternate = null;
18364 oldWorkInProgress.alternate = null; // Connect to the new tree.
18365
18366 newWorkInProgress.index = oldWorkInProgress.index;
18367 newWorkInProgress.sibling = oldWorkInProgress.sibling;
18368 newWorkInProgress.return = oldWorkInProgress.return;
18369 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
18370
18371 if (oldWorkInProgress === returnFiber.child) {
18372 returnFiber.child = newWorkInProgress;
18373 } else {
18374 var prevSibling = returnFiber.child;
18375
18376 if (prevSibling === null) {
18377 throw new Error('Expected parent to have a child.');
18378 }
18379
18380 while (prevSibling.sibling !== oldWorkInProgress) {
18381 prevSibling = prevSibling.sibling;
18382
18383 if (prevSibling === null) {
18384 throw new Error('Expected to find the previous sibling.');
18385 }
18386 }
18387
18388 prevSibling.sibling = newWorkInProgress;
18389 } // Delete the old fiber and place the new one.
18390 // Since the old fiber is disconnected, we have to schedule it manually.
18391
18392
18393 var last = returnFiber.lastEffect;
18394
18395 if (last !== null) {
18396 last.nextEffect = current;
18397 returnFiber.lastEffect = current;
18398 } else {
18399 returnFiber.firstEffect = returnFiber.lastEffect = current;
18400 }
18401
18402 current.nextEffect = null;
18403 current.effectTag = Deletion;
18404 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
18405
18406 return newWorkInProgress;
18407 }
18408}
18409
18410function beginWork(current, workInProgress, renderExpirationTime) {
18411 var updateExpirationTime = workInProgress.expirationTime;
18412
18413 {
18414 if (workInProgress._debugNeedsRemount && current !== null) {
18415 // This will restart the begin phase with a new fiber.
18416 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
18417 }
18418 }
18419
18420 if (current !== null) {
18421 var oldProps = current.memoizedProps;
18422 var newProps = workInProgress.pendingProps;
18423
18424 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
18425 workInProgress.type !== current.type )) {
18426 // If props or context changed, mark the fiber as having performed work.
18427 // This may be unset if the props are determined to be equal later (memo).
18428 didReceiveUpdate = true;
18429 } else if (updateExpirationTime < renderExpirationTime) {
18430 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
18431 // the begin phase. There's still some bookkeeping we that needs to be done
18432 // in this optimized path, mostly pushing stuff onto the stack.
18433
18434 switch (workInProgress.tag) {
18435 case HostRoot:
18436 pushHostRootContext(workInProgress);
18437 resetHydrationState();
18438 break;
18439
18440 case HostComponent:
18441 pushHostContext(workInProgress);
18442
18443 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
18444 {
18445 markSpawnedWork(Never);
18446 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
18447
18448
18449 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
18450 return null;
18451 }
18452
18453 break;
18454
18455 case ClassComponent:
18456 {
18457 var Component = workInProgress.type;
18458
18459 if (isContextProvider(Component)) {
18460 pushContextProvider(workInProgress);
18461 }
18462
18463 break;
18464 }
18465
18466 case HostPortal:
18467 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18468 break;
18469
18470 case ContextProvider:
18471 {
18472 var newValue = workInProgress.memoizedProps.value;
18473 pushProvider(workInProgress, newValue);
18474 break;
18475 }
18476
18477 case Profiler:
18478 {
18479 // Profiler should only call onRender when one of its descendants actually rendered.
18480 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
18481
18482 if (hasChildWork) {
18483 workInProgress.effectTag |= Update;
18484 }
18485 }
18486
18487 break;
18488
18489 case SuspenseComponent:
18490 {
18491 var state = workInProgress.memoizedState;
18492
18493 if (state !== null) {
18494 // whether to retry the primary children, or to skip over it and
18495 // go straight to the fallback. Check the priority of the primary
18496 // child fragment.
18497
18498
18499 var primaryChildFragment = workInProgress.child;
18500 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
18501
18502 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
18503 // The primary children have pending work. Use the normal path
18504 // to attempt to render the primary children again.
18505 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
18506 } else {
18507 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
18508 // priority. Bailout.
18509
18510 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18511
18512 if (child !== null) {
18513 // The fallback children have pending work. Skip over the
18514 // primary children and work on the fallback.
18515 return child.sibling;
18516 } else {
18517 return null;
18518 }
18519 }
18520 } else {
18521 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18522 }
18523
18524 break;
18525 }
18526
18527 case SuspenseListComponent:
18528 {
18529 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
18530
18531 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
18532
18533 if (didSuspendBefore) {
18534 if (_hasChildWork) {
18535 // If something was in fallback state last time, and we have all the
18536 // same children then we're still in progressive loading state.
18537 // Something might get unblocked by state updates or retries in the
18538 // tree which will affect the tail. So we need to use the normal
18539 // path to compute the correct tail.
18540 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
18541 } // If none of the children had any work, that means that none of
18542 // them got retried so they'll still be blocked in the same way
18543 // as before. We can fast bail out.
18544
18545
18546 workInProgress.effectTag |= DidCapture;
18547 } // If nothing suspended before and we're rendering the same children,
18548 // then the tail doesn't matter. Anything new that suspends will work
18549 // in the "together" mode, so we can continue from the state we had.
18550
18551
18552 var renderState = workInProgress.memoizedState;
18553
18554 if (renderState !== null) {
18555 // Reset to the "together" mode in case we've started a different
18556 // update in the past but didn't complete it.
18557 renderState.rendering = null;
18558 renderState.tail = null;
18559 }
18560
18561 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
18562
18563 if (_hasChildWork) {
18564 break;
18565 } else {
18566 // If none of the children had any work, that means that none of
18567 // them got retried so they'll still be blocked in the same way
18568 // as before. We can fast bail out.
18569 return null;
18570 }
18571 }
18572 }
18573
18574 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18575 } else {
18576 // An update was scheduled on this fiber, but there are no new props
18577 // nor legacy context. Set this to false. If an update queue or context
18578 // consumer produces a changed value, it will set this to true. Otherwise,
18579 // the component will assume the children have not changed and bail out.
18580 didReceiveUpdate = false;
18581 }
18582 } else {
18583 didReceiveUpdate = false;
18584 } // Before entering the begin phase, clear pending update priority.
18585 // TODO: This assumes that we're about to evaluate the component and process
18586 // the update queue. However, there's an exception: SimpleMemoComponent
18587 // sometimes bails out later in the begin phase. This indicates that we should
18588 // move this assignment out of the common path and into each branch.
18589
18590
18591 workInProgress.expirationTime = NoWork;
18592
18593 switch (workInProgress.tag) {
18594 case IndeterminateComponent:
18595 {
18596 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
18597 }
18598
18599 case LazyComponent:
18600 {
18601 var elementType = workInProgress.elementType;
18602 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
18603 }
18604
18605 case FunctionComponent:
18606 {
18607 var _Component = workInProgress.type;
18608 var unresolvedProps = workInProgress.pendingProps;
18609 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
18610 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
18611 }
18612
18613 case ClassComponent:
18614 {
18615 var _Component2 = workInProgress.type;
18616 var _unresolvedProps = workInProgress.pendingProps;
18617
18618 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
18619
18620 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
18621 }
18622
18623 case HostRoot:
18624 return updateHostRoot(current, workInProgress, renderExpirationTime);
18625
18626 case HostComponent:
18627 return updateHostComponent(current, workInProgress, renderExpirationTime);
18628
18629 case HostText:
18630 return updateHostText(current, workInProgress);
18631
18632 case SuspenseComponent:
18633 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
18634
18635 case HostPortal:
18636 return updatePortalComponent(current, workInProgress, renderExpirationTime);
18637
18638 case ForwardRef:
18639 {
18640 var type = workInProgress.type;
18641 var _unresolvedProps2 = workInProgress.pendingProps;
18642
18643 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
18644
18645 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
18646 }
18647
18648 case Fragment:
18649 return updateFragment(current, workInProgress, renderExpirationTime);
18650
18651 case Mode:
18652 return updateMode(current, workInProgress, renderExpirationTime);
18653
18654 case Profiler:
18655 return updateProfiler(current, workInProgress, renderExpirationTime);
18656
18657 case ContextProvider:
18658 return updateContextProvider(current, workInProgress, renderExpirationTime);
18659
18660 case ContextConsumer:
18661 return updateContextConsumer(current, workInProgress, renderExpirationTime);
18662
18663 case MemoComponent:
18664 {
18665 var _type2 = workInProgress.type;
18666 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
18667
18668 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
18669
18670 {
18671 if (workInProgress.type !== workInProgress.elementType) {
18672 var outerPropTypes = _type2.propTypes;
18673
18674 if (outerPropTypes) {
18675 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
18676 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
18677 }
18678 }
18679 }
18680
18681 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
18682 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
18683 }
18684
18685 case SimpleMemoComponent:
18686 {
18687 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
18688 }
18689
18690 case IncompleteClassComponent:
18691 {
18692 var _Component3 = workInProgress.type;
18693 var _unresolvedProps4 = workInProgress.pendingProps;
18694
18695 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
18696
18697 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
18698 }
18699
18700 case SuspenseListComponent:
18701 {
18702 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
18703 }
18704 }
18705
18706 {
18707 {
18708 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
18709 }
18710 }
18711}
18712
18713function markUpdate(workInProgress) {
18714 // Tag the fiber with an update effect. This turns a Placement into
18715 // a PlacementAndUpdate.
18716 workInProgress.effectTag |= Update;
18717}
18718
18719function markRef$1(workInProgress) {
18720 workInProgress.effectTag |= Ref;
18721}
18722
18723var appendAllChildren;
18724var updateHostContainer;
18725var updateHostComponent$1;
18726var updateHostText$1;
18727
18728{
18729 // Mutation mode
18730 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
18731 // We only have the top Fiber that was created but we need recurse down its
18732 // children to find all the terminal nodes.
18733 var node = workInProgress.child;
18734
18735 while (node !== null) {
18736 if (node.tag === HostComponent || node.tag === HostText) {
18737 appendInitialChild(parent, node.stateNode);
18738 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
18739 node.child.return = node;
18740 node = node.child;
18741 continue;
18742 }
18743
18744 if (node === workInProgress) {
18745 return;
18746 }
18747
18748 while (node.sibling === null) {
18749 if (node.return === null || node.return === workInProgress) {
18750 return;
18751 }
18752
18753 node = node.return;
18754 }
18755
18756 node.sibling.return = node.return;
18757 node = node.sibling;
18758 }
18759 };
18760
18761 updateHostContainer = function (workInProgress) {// Noop
18762 };
18763
18764 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
18765 // If we have an alternate, that means this is an update and we need to
18766 // schedule a side-effect to do the updates.
18767 var oldProps = current.memoizedProps;
18768
18769 if (oldProps === newProps) {
18770 // In mutation mode, this is sufficient for a bailout because
18771 // we won't touch this node even if children changed.
18772 return;
18773 } // If we get updated because one of our children updated, we don't
18774 // have newProps so we'll have to reuse them.
18775 // TODO: Split the update API as separate for the props vs. children.
18776 // Even better would be if children weren't special cased at all tho.
18777
18778
18779 var instance = workInProgress.stateNode;
18780 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
18781 // component is hitting the resume path. Figure out why. Possibly
18782 // related to `hidden`.
18783
18784 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
18785
18786 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
18787 // is a new ref we mark this as an update. All the work is done in commitWork.
18788
18789 if (updatePayload) {
18790 markUpdate(workInProgress);
18791 }
18792 };
18793
18794 updateHostText$1 = function (current, workInProgress, oldText, newText) {
18795 // If the text differs, mark it as an update. All the work in done in commitWork.
18796 if (oldText !== newText) {
18797 markUpdate(workInProgress);
18798 }
18799 };
18800}
18801
18802function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
18803 switch (renderState.tailMode) {
18804 case 'hidden':
18805 {
18806 // Any insertions at the end of the tail list after this point
18807 // should be invisible. If there are already mounted boundaries
18808 // anything before them are not considered for collapsing.
18809 // Therefore we need to go through the whole tail to find if
18810 // there are any.
18811 var tailNode = renderState.tail;
18812 var lastTailNode = null;
18813
18814 while (tailNode !== null) {
18815 if (tailNode.alternate !== null) {
18816 lastTailNode = tailNode;
18817 }
18818
18819 tailNode = tailNode.sibling;
18820 } // Next we're simply going to delete all insertions after the
18821 // last rendered item.
18822
18823
18824 if (lastTailNode === null) {
18825 // All remaining items in the tail are insertions.
18826 renderState.tail = null;
18827 } else {
18828 // Detach the insertion after the last node that was already
18829 // inserted.
18830 lastTailNode.sibling = null;
18831 }
18832
18833 break;
18834 }
18835
18836 case 'collapsed':
18837 {
18838 // Any insertions at the end of the tail list after this point
18839 // should be invisible. If there are already mounted boundaries
18840 // anything before them are not considered for collapsing.
18841 // Therefore we need to go through the whole tail to find if
18842 // there are any.
18843 var _tailNode = renderState.tail;
18844 var _lastTailNode = null;
18845
18846 while (_tailNode !== null) {
18847 if (_tailNode.alternate !== null) {
18848 _lastTailNode = _tailNode;
18849 }
18850
18851 _tailNode = _tailNode.sibling;
18852 } // Next we're simply going to delete all insertions after the
18853 // last rendered item.
18854
18855
18856 if (_lastTailNode === null) {
18857 // All remaining items in the tail are insertions.
18858 if (!hasRenderedATailFallback && renderState.tail !== null) {
18859 // We suspended during the head. We want to show at least one
18860 // row at the tail. So we'll keep on and cut off the rest.
18861 renderState.tail.sibling = null;
18862 } else {
18863 renderState.tail = null;
18864 }
18865 } else {
18866 // Detach the insertion after the last node that was already
18867 // inserted.
18868 _lastTailNode.sibling = null;
18869 }
18870
18871 break;
18872 }
18873 }
18874}
18875
18876function completeWork(current, workInProgress, renderExpirationTime) {
18877 var newProps = workInProgress.pendingProps;
18878
18879 switch (workInProgress.tag) {
18880 case IndeterminateComponent:
18881 case LazyComponent:
18882 case SimpleMemoComponent:
18883 case FunctionComponent:
18884 case ForwardRef:
18885 case Fragment:
18886 case Mode:
18887 case Profiler:
18888 case ContextConsumer:
18889 case MemoComponent:
18890 return null;
18891
18892 case ClassComponent:
18893 {
18894 var Component = workInProgress.type;
18895
18896 if (isContextProvider(Component)) {
18897 popContext(workInProgress);
18898 }
18899
18900 return null;
18901 }
18902
18903 case HostRoot:
18904 {
18905 popHostContainer(workInProgress);
18906 popTopLevelContextObject(workInProgress);
18907 var fiberRoot = workInProgress.stateNode;
18908
18909 if (fiberRoot.pendingContext) {
18910 fiberRoot.context = fiberRoot.pendingContext;
18911 fiberRoot.pendingContext = null;
18912 }
18913
18914 if (current === null || current.child === null) {
18915 // If we hydrated, pop so that we can delete any remaining children
18916 // that weren't hydrated.
18917 var wasHydrated = popHydrationState(workInProgress);
18918
18919 if (wasHydrated) {
18920 // If we hydrated, then we'll need to schedule an update for
18921 // the commit side-effects on the root.
18922 markUpdate(workInProgress);
18923 }
18924 }
18925
18926 updateHostContainer(workInProgress);
18927 return null;
18928 }
18929
18930 case HostComponent:
18931 {
18932 popHostContext(workInProgress);
18933 var rootContainerInstance = getRootHostContainer();
18934 var type = workInProgress.type;
18935
18936 if (current !== null && workInProgress.stateNode != null) {
18937 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
18938
18939 if (current.ref !== workInProgress.ref) {
18940 markRef$1(workInProgress);
18941 }
18942 } else {
18943 if (!newProps) {
18944 if (!(workInProgress.stateNode !== null)) {
18945 {
18946 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
18947 }
18948 } // This can happen when we abort work.
18949
18950
18951 return null;
18952 }
18953
18954 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
18955 // "stack" as the parent. Then append children as we go in beginWork
18956 // or completeWork depending on whether we want to add them top->down or
18957 // bottom->up. Top->down is faster in IE11.
18958
18959 var _wasHydrated = popHydrationState(workInProgress);
18960
18961 if (_wasHydrated) {
18962 // TODO: Move this and createInstance step into the beginPhase
18963 // to consolidate.
18964 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
18965 // If changes to the hydrated node need to be applied at the
18966 // commit-phase we mark this as such.
18967 markUpdate(workInProgress);
18968 }
18969 } else {
18970 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
18971 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
18972
18973 workInProgress.stateNode = instance;
18974 // (eg DOM renderer supports auto-focus for certain elements).
18975 // Make sure such renderers get scheduled for later work.
18976
18977
18978 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
18979 markUpdate(workInProgress);
18980 }
18981 }
18982
18983 if (workInProgress.ref !== null) {
18984 // If there is a ref on a host node we need to schedule a callback
18985 markRef$1(workInProgress);
18986 }
18987 }
18988
18989 return null;
18990 }
18991
18992 case HostText:
18993 {
18994 var newText = newProps;
18995
18996 if (current && workInProgress.stateNode != null) {
18997 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
18998 // to schedule a side-effect to do the updates.
18999
19000 updateHostText$1(current, workInProgress, oldText, newText);
19001 } else {
19002 if (typeof newText !== 'string') {
19003 if (!(workInProgress.stateNode !== null)) {
19004 {
19005 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19006 }
19007 } // This can happen when we abort work.
19008
19009 }
19010
19011 var _rootContainerInstance = getRootHostContainer();
19012
19013 var _currentHostContext = getHostContext();
19014
19015 var _wasHydrated2 = popHydrationState(workInProgress);
19016
19017 if (_wasHydrated2) {
19018 if (prepareToHydrateHostTextInstance(workInProgress)) {
19019 markUpdate(workInProgress);
19020 }
19021 } else {
19022 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
19023 }
19024 }
19025
19026 return null;
19027 }
19028
19029 case SuspenseComponent:
19030 {
19031 popSuspenseContext(workInProgress);
19032 var nextState = workInProgress.memoizedState;
19033
19034 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
19035 // Something suspended. Re-render with the fallback children.
19036 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
19037
19038 return workInProgress;
19039 }
19040
19041 var nextDidTimeout = nextState !== null;
19042 var prevDidTimeout = false;
19043
19044 if (current === null) {
19045 if (workInProgress.memoizedProps.fallback !== undefined) {
19046 popHydrationState(workInProgress);
19047 }
19048 } else {
19049 var prevState = current.memoizedState;
19050 prevDidTimeout = prevState !== null;
19051
19052 if (!nextDidTimeout && prevState !== null) {
19053 // We just switched from the fallback to the normal children.
19054 // Delete the fallback.
19055 // TODO: Would it be better to store the fallback fragment on
19056 // the stateNode during the begin phase?
19057 var currentFallbackChild = current.child.sibling;
19058
19059 if (currentFallbackChild !== null) {
19060 // Deletions go at the beginning of the return fiber's effect list
19061 var first = workInProgress.firstEffect;
19062
19063 if (first !== null) {
19064 workInProgress.firstEffect = currentFallbackChild;
19065 currentFallbackChild.nextEffect = first;
19066 } else {
19067 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
19068 currentFallbackChild.nextEffect = null;
19069 }
19070
19071 currentFallbackChild.effectTag = Deletion;
19072 }
19073 }
19074 }
19075
19076 if (nextDidTimeout && !prevDidTimeout) {
19077 // If this subtreee is running in blocking mode we can suspend,
19078 // otherwise we won't suspend.
19079 // TODO: This will still suspend a synchronous tree if anything
19080 // in the concurrent tree already suspended during this render.
19081 // This is a known bug.
19082 if ((workInProgress.mode & BlockingMode) !== NoMode) {
19083 // TODO: Move this back to throwException because this is too late
19084 // if this is a large tree which is common for initial loads. We
19085 // don't know if we should restart a render or not until we get
19086 // this marker, and this is too late.
19087 // If this render already had a ping or lower pri updates,
19088 // and this is the first time we know we're going to suspend we
19089 // should be able to immediately restart from within throwException.
19090 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
19091
19092 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
19093 // If this was in an invisible tree or a new render, then showing
19094 // this boundary is ok.
19095 renderDidSuspend();
19096 } else {
19097 // Otherwise, we're going to have to hide content so we should
19098 // suspend for longer if possible.
19099 renderDidSuspendDelayIfPossible();
19100 }
19101 }
19102 }
19103
19104 {
19105 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
19106 if (nextDidTimeout || prevDidTimeout) {
19107 // If this boundary just timed out, schedule an effect to attach a
19108 // retry listener to the promise. This flag is also used to hide the
19109 // primary children. In mutation mode, we also need the flag to
19110 // *unhide* children that were previously hidden, so check if this
19111 // is currently timed out, too.
19112 workInProgress.effectTag |= Update;
19113 }
19114 }
19115
19116 return null;
19117 }
19118
19119 case HostPortal:
19120 popHostContainer(workInProgress);
19121 updateHostContainer(workInProgress);
19122 return null;
19123
19124 case ContextProvider:
19125 // Pop provider fiber
19126 popProvider(workInProgress);
19127 return null;
19128
19129 case IncompleteClassComponent:
19130 {
19131 // Same as class component case. I put it down here so that the tags are
19132 // sequential to ensure this switch is compiled to a jump table.
19133 var _Component = workInProgress.type;
19134
19135 if (isContextProvider(_Component)) {
19136 popContext(workInProgress);
19137 }
19138
19139 return null;
19140 }
19141
19142 case SuspenseListComponent:
19143 {
19144 popSuspenseContext(workInProgress);
19145 var renderState = workInProgress.memoizedState;
19146
19147 if (renderState === null) {
19148 // We're running in the default, "independent" mode.
19149 // We don't do anything in this mode.
19150 return null;
19151 }
19152
19153 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
19154 var renderedTail = renderState.rendering;
19155
19156 if (renderedTail === null) {
19157 // We just rendered the head.
19158 if (!didSuspendAlready) {
19159 // This is the first pass. We need to figure out if anything is still
19160 // suspended in the rendered set.
19161 // If new content unsuspended, but there's still some content that
19162 // didn't. Then we need to do a second pass that forces everything
19163 // to keep showing their fallbacks.
19164 // We might be suspended if something in this render pass suspended, or
19165 // something in the previous committed pass suspended. Otherwise,
19166 // there's no chance so we can skip the expensive call to
19167 // findFirstSuspended.
19168 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
19169
19170 if (!cannotBeSuspended) {
19171 var row = workInProgress.child;
19172
19173 while (row !== null) {
19174 var suspended = findFirstSuspended(row);
19175
19176 if (suspended !== null) {
19177 didSuspendAlready = true;
19178 workInProgress.effectTag |= DidCapture;
19179 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
19180 // part of the second pass. In that case nothing will subscribe to
19181 // its thennables. Instead, we'll transfer its thennables to the
19182 // SuspenseList so that it can retry if they resolve.
19183 // There might be multiple of these in the list but since we're
19184 // going to wait for all of them anyway, it doesn't really matter
19185 // which ones gets to ping. In theory we could get clever and keep
19186 // track of how many dependencies remain but it gets tricky because
19187 // in the meantime, we can add/remove/change items and dependencies.
19188 // We might bail out of the loop before finding any but that
19189 // doesn't matter since that means that the other boundaries that
19190 // we did find already has their listeners attached.
19191
19192 var newThennables = suspended.updateQueue;
19193
19194 if (newThennables !== null) {
19195 workInProgress.updateQueue = newThennables;
19196 workInProgress.effectTag |= Update;
19197 } // Rerender the whole list, but this time, we'll force fallbacks
19198 // to stay in place.
19199 // Reset the effect list before doing the second pass since that's now invalid.
19200
19201
19202 if (renderState.lastEffect === null) {
19203 workInProgress.firstEffect = null;
19204 }
19205
19206 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
19207
19208 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
19209 // rerender the children.
19210
19211 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
19212 return workInProgress.child;
19213 }
19214
19215 row = row.sibling;
19216 }
19217 }
19218 } else {
19219 cutOffTailIfNeeded(renderState, false);
19220 } // Next we're going to render the tail.
19221
19222 } else {
19223 // Append the rendered row to the child list.
19224 if (!didSuspendAlready) {
19225 var _suspended = findFirstSuspended(renderedTail);
19226
19227 if (_suspended !== null) {
19228 workInProgress.effectTag |= DidCapture;
19229 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
19230 // get lost if this row ends up dropped during a second pass.
19231
19232 var _newThennables = _suspended.updateQueue;
19233
19234 if (_newThennables !== null) {
19235 workInProgress.updateQueue = _newThennables;
19236 workInProgress.effectTag |= Update;
19237 }
19238
19239 cutOffTailIfNeeded(renderState, true); // This might have been modified.
19240
19241 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
19242 // We need to delete the row we just rendered.
19243 // Reset the effect list to what it was before we rendered this
19244 // child. The nested children have already appended themselves.
19245 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
19246
19247 if (lastEffect !== null) {
19248 lastEffect.nextEffect = null;
19249 } // We're done.
19250
19251
19252 return null;
19253 }
19254 } else if ( // The time it took to render last row is greater than time until
19255 // the expiration.
19256 now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {
19257 // We have now passed our CPU deadline and we'll just give up further
19258 // attempts to render the main content and only render fallbacks.
19259 // The assumption is that this is usually faster.
19260 workInProgress.effectTag |= DidCapture;
19261 didSuspendAlready = true;
19262 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19263 // to get it started back up to attempt the next item. If we can show
19264 // them, then they really have the same priority as this render.
19265 // So we'll pick it back up the very next render pass once we've had
19266 // an opportunity to yield for paint.
19267
19268 var nextPriority = renderExpirationTime - 1;
19269 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
19270
19271 {
19272 markSpawnedWork(nextPriority);
19273 }
19274 }
19275 }
19276
19277 if (renderState.isBackwards) {
19278 // The effect list of the backwards tail will have been added
19279 // to the end. This breaks the guarantee that life-cycles fire in
19280 // sibling order but that isn't a strong guarantee promised by React.
19281 // Especially since these might also just pop in during future commits.
19282 // Append to the beginning of the list.
19283 renderedTail.sibling = workInProgress.child;
19284 workInProgress.child = renderedTail;
19285 } else {
19286 var previousSibling = renderState.last;
19287
19288 if (previousSibling !== null) {
19289 previousSibling.sibling = renderedTail;
19290 } else {
19291 workInProgress.child = renderedTail;
19292 }
19293
19294 renderState.last = renderedTail;
19295 }
19296 }
19297
19298 if (renderState.tail !== null) {
19299 // We still have tail rows to render.
19300 if (renderState.tailExpiration === 0) {
19301 // Heuristic for how long we're willing to spend rendering rows
19302 // until we just give up and show what we have so far.
19303 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
19304 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this
19305 // is a per component value. It should really be since the start
19306 // of the total render or last commit. Consider using something like
19307 // globalMostRecentFallbackTime. That doesn't account for being
19308 // suspended for part of the time or when it's a new render.
19309 // It should probably use a global start time value instead.
19310 } // Pop a row.
19311
19312
19313 var next = renderState.tail;
19314 renderState.rendering = next;
19315 renderState.tail = next.sibling;
19316 renderState.lastEffect = workInProgress.lastEffect;
19317 renderState.renderingStartTime = now();
19318 next.sibling = null; // Restore the context.
19319 // TODO: We can probably just avoid popping it instead and only
19320 // setting it the first time we go from not suspended to suspended.
19321
19322 var suspenseContext = suspenseStackCursor.current;
19323
19324 if (didSuspendAlready) {
19325 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19326 } else {
19327 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19328 }
19329
19330 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
19331
19332 return next;
19333 }
19334
19335 return null;
19336 }
19337 }
19338
19339 {
19340 {
19341 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
19342 }
19343 }
19344}
19345
19346function unwindWork(workInProgress, renderExpirationTime) {
19347 switch (workInProgress.tag) {
19348 case ClassComponent:
19349 {
19350 var Component = workInProgress.type;
19351
19352 if (isContextProvider(Component)) {
19353 popContext(workInProgress);
19354 }
19355
19356 var effectTag = workInProgress.effectTag;
19357
19358 if (effectTag & ShouldCapture) {
19359 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
19360 return workInProgress;
19361 }
19362
19363 return null;
19364 }
19365
19366 case HostRoot:
19367 {
19368 popHostContainer(workInProgress);
19369 popTopLevelContextObject(workInProgress);
19370 var _effectTag = workInProgress.effectTag;
19371
19372 if (!((_effectTag & DidCapture) === NoEffect)) {
19373 {
19374 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
19375 }
19376 }
19377
19378 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
19379 return workInProgress;
19380 }
19381
19382 case HostComponent:
19383 {
19384 // TODO: popHydrationState
19385 popHostContext(workInProgress);
19386 return null;
19387 }
19388
19389 case SuspenseComponent:
19390 {
19391 popSuspenseContext(workInProgress);
19392
19393 var _effectTag2 = workInProgress.effectTag;
19394
19395 if (_effectTag2 & ShouldCapture) {
19396 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
19397
19398 return workInProgress;
19399 }
19400
19401 return null;
19402 }
19403
19404 case SuspenseListComponent:
19405 {
19406 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
19407 // caught by a nested boundary. If not, it should bubble through.
19408
19409 return null;
19410 }
19411
19412 case HostPortal:
19413 popHostContainer(workInProgress);
19414 return null;
19415
19416 case ContextProvider:
19417 popProvider(workInProgress);
19418 return null;
19419
19420 default:
19421 return null;
19422 }
19423}
19424
19425function unwindInterruptedWork(interruptedWork) {
19426 switch (interruptedWork.tag) {
19427 case ClassComponent:
19428 {
19429 var childContextTypes = interruptedWork.type.childContextTypes;
19430
19431 if (childContextTypes !== null && childContextTypes !== undefined) {
19432 popContext(interruptedWork);
19433 }
19434
19435 break;
19436 }
19437
19438 case HostRoot:
19439 {
19440 popHostContainer(interruptedWork);
19441 popTopLevelContextObject(interruptedWork);
19442 break;
19443 }
19444
19445 case HostComponent:
19446 {
19447 popHostContext(interruptedWork);
19448 break;
19449 }
19450
19451 case HostPortal:
19452 popHostContainer(interruptedWork);
19453 break;
19454
19455 case SuspenseComponent:
19456 popSuspenseContext(interruptedWork);
19457 break;
19458
19459 case SuspenseListComponent:
19460 popSuspenseContext(interruptedWork);
19461 break;
19462
19463 case ContextProvider:
19464 popProvider(interruptedWork);
19465 break;
19466 }
19467}
19468
19469function createCapturedValue(value, source) {
19470 // If the value is an error, call this function immediately after it is thrown
19471 // so the stack is accurate.
19472 return {
19473 value: value,
19474 source: source,
19475 stack: getStackByFiberInDevAndProd(source)
19476 };
19477}
19478
19479function logCapturedError(capturedError) {
19480
19481 var error = capturedError.error;
19482
19483 {
19484 var componentName = capturedError.componentName,
19485 componentStack = capturedError.componentStack,
19486 errorBoundaryName = capturedError.errorBoundaryName,
19487 errorBoundaryFound = capturedError.errorBoundaryFound,
19488 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
19489 // `preventDefault()` in window `error` handler.
19490 // We record this information as an expando on the error.
19491
19492 if (error != null && error._suppressLogging) {
19493 if (errorBoundaryFound && willRetry) {
19494 // The error is recoverable and was silenced.
19495 // Ignore it and don't print the stack addendum.
19496 // This is handy for testing error boundaries without noise.
19497 return;
19498 } // The error is fatal. Since the silencing might have
19499 // been accidental, we'll surface it anyway.
19500 // However, the browser would have silenced the original error
19501 // so we'll print it first, and then print the stack addendum.
19502
19503
19504 console['error'](error); // Don't transform to our wrapper
19505 // For a more detailed description of this block, see:
19506 // https://github.com/facebook/react/pull/13384
19507 }
19508
19509 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
19510 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
19511
19512 if (errorBoundaryFound && errorBoundaryName) {
19513 if (willRetry) {
19514 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
19515 } else {
19516 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
19517 }
19518 } else {
19519 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://fb.me/react-error-boundaries to learn more about error boundaries.';
19520 }
19521
19522 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
19523 // We don't include the original error message and JS stack because the browser
19524 // has already printed it. Even if the application swallows the error, it is still
19525 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
19526
19527 console['error'](combinedMessage); // Don't transform to our wrapper
19528 }
19529}
19530
19531var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
19532
19533{
19534 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
19535}
19536
19537var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
19538function logError(boundary, errorInfo) {
19539 var source = errorInfo.source;
19540 var stack = errorInfo.stack;
19541
19542 if (stack === null && source !== null) {
19543 stack = getStackByFiberInDevAndProd(source);
19544 }
19545
19546 var capturedError = {
19547 componentName: source !== null ? getComponentName(source.type) : null,
19548 componentStack: stack !== null ? stack : '',
19549 error: errorInfo.value,
19550 errorBoundary: null,
19551 errorBoundaryName: null,
19552 errorBoundaryFound: false,
19553 willRetry: false
19554 };
19555
19556 if (boundary !== null && boundary.tag === ClassComponent) {
19557 capturedError.errorBoundary = boundary.stateNode;
19558 capturedError.errorBoundaryName = getComponentName(boundary.type);
19559 capturedError.errorBoundaryFound = true;
19560 capturedError.willRetry = true;
19561 }
19562
19563 try {
19564 logCapturedError(capturedError);
19565 } catch (e) {
19566 // This method must not throw, or React internal state will get messed up.
19567 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
19568 // we want to report this error outside of the normal stack as a last resort.
19569 // https://github.com/facebook/react/issues/13188
19570 setTimeout(function () {
19571 throw e;
19572 });
19573 }
19574}
19575
19576var callComponentWillUnmountWithTimer = function (current, instance) {
19577 startPhaseTimer(current, 'componentWillUnmount');
19578 instance.props = current.memoizedProps;
19579 instance.state = current.memoizedState;
19580 instance.componentWillUnmount();
19581 stopPhaseTimer();
19582}; // Capture errors so they don't interrupt unmounting.
19583
19584
19585function safelyCallComponentWillUnmount(current, instance) {
19586 {
19587 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
19588
19589 if (hasCaughtError()) {
19590 var unmountError = clearCaughtError();
19591 captureCommitPhaseError(current, unmountError);
19592 }
19593 }
19594}
19595
19596function safelyDetachRef(current) {
19597 var ref = current.ref;
19598
19599 if (ref !== null) {
19600 if (typeof ref === 'function') {
19601 {
19602 invokeGuardedCallback(null, ref, null, null);
19603
19604 if (hasCaughtError()) {
19605 var refError = clearCaughtError();
19606 captureCommitPhaseError(current, refError);
19607 }
19608 }
19609 } else {
19610 ref.current = null;
19611 }
19612 }
19613}
19614
19615function safelyCallDestroy(current, destroy) {
19616 {
19617 invokeGuardedCallback(null, destroy, null);
19618
19619 if (hasCaughtError()) {
19620 var error = clearCaughtError();
19621 captureCommitPhaseError(current, error);
19622 }
19623 }
19624}
19625
19626function commitBeforeMutationLifeCycles(current, finishedWork) {
19627 switch (finishedWork.tag) {
19628 case FunctionComponent:
19629 case ForwardRef:
19630 case SimpleMemoComponent:
19631 case Block:
19632 {
19633 return;
19634 }
19635
19636 case ClassComponent:
19637 {
19638 if (finishedWork.effectTag & Snapshot) {
19639 if (current !== null) {
19640 var prevProps = current.memoizedProps;
19641 var prevState = current.memoizedState;
19642 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
19643 var instance = finishedWork.stateNode; // We could update instance props and state here,
19644 // but instead we rely on them being set during last render.
19645 // TODO: revisit this when we implement resuming.
19646
19647 {
19648 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19649 if (instance.props !== finishedWork.memoizedProps) {
19650 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
19651 }
19652
19653 if (instance.state !== finishedWork.memoizedState) {
19654 error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
19655 }
19656 }
19657 }
19658
19659 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
19660
19661 {
19662 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
19663
19664 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
19665 didWarnSet.add(finishedWork.type);
19666
19667 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
19668 }
19669 }
19670
19671 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
19672 stopPhaseTimer();
19673 }
19674 }
19675
19676 return;
19677 }
19678
19679 case HostRoot:
19680 case HostComponent:
19681 case HostText:
19682 case HostPortal:
19683 case IncompleteClassComponent:
19684 // Nothing to do for these component types
19685 return;
19686 }
19687
19688 {
19689 {
19690 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
19691 }
19692 }
19693}
19694
19695function commitHookEffectListUnmount(tag, finishedWork) {
19696 var updateQueue = finishedWork.updateQueue;
19697 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
19698
19699 if (lastEffect !== null) {
19700 var firstEffect = lastEffect.next;
19701 var effect = firstEffect;
19702
19703 do {
19704 if ((effect.tag & tag) === tag) {
19705 // Unmount
19706 var destroy = effect.destroy;
19707 effect.destroy = undefined;
19708
19709 if (destroy !== undefined) {
19710 destroy();
19711 }
19712 }
19713
19714 effect = effect.next;
19715 } while (effect !== firstEffect);
19716 }
19717}
19718
19719function commitHookEffectListMount(tag, finishedWork) {
19720 var updateQueue = finishedWork.updateQueue;
19721 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
19722
19723 if (lastEffect !== null) {
19724 var firstEffect = lastEffect.next;
19725 var effect = firstEffect;
19726
19727 do {
19728 if ((effect.tag & tag) === tag) {
19729 // Mount
19730 var create = effect.create;
19731 effect.destroy = create();
19732
19733 {
19734 var destroy = effect.destroy;
19735
19736 if (destroy !== undefined && typeof destroy !== 'function') {
19737 var addendum = void 0;
19738
19739 if (destroy === null) {
19740 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
19741 } else if (typeof destroy.then === 'function') {
19742 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching';
19743 } else {
19744 addendum = ' You returned: ' + destroy;
19745 }
19746
19747 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
19748 }
19749 }
19750 }
19751
19752 effect = effect.next;
19753 } while (effect !== firstEffect);
19754 }
19755}
19756
19757function commitPassiveHookEffects(finishedWork) {
19758 if ((finishedWork.effectTag & Passive) !== NoEffect) {
19759 switch (finishedWork.tag) {
19760 case FunctionComponent:
19761 case ForwardRef:
19762 case SimpleMemoComponent:
19763 case Block:
19764 {
19765 // TODO (#17945) We should call all passive destroy functions (for all fibers)
19766 // before calling any create functions. The current approach only serializes
19767 // these for a single fiber.
19768 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
19769 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
19770 break;
19771 }
19772 }
19773 }
19774}
19775
19776function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
19777 switch (finishedWork.tag) {
19778 case FunctionComponent:
19779 case ForwardRef:
19780 case SimpleMemoComponent:
19781 case Block:
19782 {
19783 // At this point layout effects have already been destroyed (during mutation phase).
19784 // This is done to prevent sibling component effects from interfering with each other,
19785 // e.g. a destroy function in one component should never override a ref set
19786 // by a create function in another component during the same commit.
19787 commitHookEffectListMount(Layout | HasEffect, finishedWork);
19788
19789 return;
19790 }
19791
19792 case ClassComponent:
19793 {
19794 var instance = finishedWork.stateNode;
19795
19796 if (finishedWork.effectTag & Update) {
19797 if (current === null) {
19798 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
19799 // but instead we rely on them being set during last render.
19800 // TODO: revisit this when we implement resuming.
19801
19802 {
19803 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19804 if (instance.props !== finishedWork.memoizedProps) {
19805 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
19806 }
19807
19808 if (instance.state !== finishedWork.memoizedState) {
19809 error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
19810 }
19811 }
19812 }
19813
19814 instance.componentDidMount();
19815 stopPhaseTimer();
19816 } else {
19817 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
19818 var prevState = current.memoizedState;
19819 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
19820 // but instead we rely on them being set during last render.
19821 // TODO: revisit this when we implement resuming.
19822
19823 {
19824 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19825 if (instance.props !== finishedWork.memoizedProps) {
19826 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
19827 }
19828
19829 if (instance.state !== finishedWork.memoizedState) {
19830 error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
19831 }
19832 }
19833 }
19834
19835 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
19836 stopPhaseTimer();
19837 }
19838 }
19839
19840 var updateQueue = finishedWork.updateQueue;
19841
19842 if (updateQueue !== null) {
19843 {
19844 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19845 if (instance.props !== finishedWork.memoizedProps) {
19846 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
19847 }
19848
19849 if (instance.state !== finishedWork.memoizedState) {
19850 error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
19851 }
19852 }
19853 } // We could update instance props and state here,
19854 // but instead we rely on them being set during last render.
19855 // TODO: revisit this when we implement resuming.
19856
19857
19858 commitUpdateQueue(finishedWork, updateQueue, instance);
19859 }
19860
19861 return;
19862 }
19863
19864 case HostRoot:
19865 {
19866 var _updateQueue = finishedWork.updateQueue;
19867
19868 if (_updateQueue !== null) {
19869 var _instance = null;
19870
19871 if (finishedWork.child !== null) {
19872 switch (finishedWork.child.tag) {
19873 case HostComponent:
19874 _instance = getPublicInstance(finishedWork.child.stateNode);
19875 break;
19876
19877 case ClassComponent:
19878 _instance = finishedWork.child.stateNode;
19879 break;
19880 }
19881 }
19882
19883 commitUpdateQueue(finishedWork, _updateQueue, _instance);
19884 }
19885
19886 return;
19887 }
19888
19889 case HostComponent:
19890 {
19891 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
19892 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
19893 // These effects should only be committed when components are first mounted,
19894 // aka when there is no current/alternate.
19895
19896 if (current === null && finishedWork.effectTag & Update) {
19897 var type = finishedWork.type;
19898 var props = finishedWork.memoizedProps;
19899 commitMount(_instance2, type, props);
19900 }
19901
19902 return;
19903 }
19904
19905 case HostText:
19906 {
19907 // We have no life-cycles associated with text.
19908 return;
19909 }
19910
19911 case HostPortal:
19912 {
19913 // We have no life-cycles associated with portals.
19914 return;
19915 }
19916
19917 case Profiler:
19918 {
19919 {
19920 var onRender = finishedWork.memoizedProps.onRender;
19921
19922 if (typeof onRender === 'function') {
19923 {
19924 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
19925 }
19926 }
19927 }
19928
19929 return;
19930 }
19931
19932 case SuspenseComponent:
19933 {
19934 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
19935 return;
19936 }
19937
19938 case SuspenseListComponent:
19939 case IncompleteClassComponent:
19940 case FundamentalComponent:
19941 case ScopeComponent:
19942 return;
19943 }
19944
19945 {
19946 {
19947 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
19948 }
19949 }
19950}
19951
19952function hideOrUnhideAllChildren(finishedWork, isHidden) {
19953 {
19954 // We only have the top Fiber that was inserted but we need to recurse down its
19955 // children to find all the terminal nodes.
19956 var node = finishedWork;
19957
19958 while (true) {
19959 if (node.tag === HostComponent) {
19960 var instance = node.stateNode;
19961
19962 if (isHidden) {
19963 hideInstance(instance);
19964 } else {
19965 unhideInstance(node.stateNode, node.memoizedProps);
19966 }
19967 } else if (node.tag === HostText) {
19968 var _instance3 = node.stateNode;
19969
19970 if (isHidden) {
19971 hideTextInstance(_instance3);
19972 } else {
19973 unhideTextInstance(_instance3, node.memoizedProps);
19974 }
19975 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
19976 // Found a nested Suspense component that timed out. Skip over the
19977 // primary child fragment, which should remain hidden.
19978 var fallbackChildFragment = node.child.sibling;
19979 fallbackChildFragment.return = node;
19980 node = fallbackChildFragment;
19981 continue;
19982 } else if (node.child !== null) {
19983 node.child.return = node;
19984 node = node.child;
19985 continue;
19986 }
19987
19988 if (node === finishedWork) {
19989 return;
19990 }
19991
19992 while (node.sibling === null) {
19993 if (node.return === null || node.return === finishedWork) {
19994 return;
19995 }
19996
19997 node = node.return;
19998 }
19999
20000 node.sibling.return = node.return;
20001 node = node.sibling;
20002 }
20003 }
20004}
20005
20006function commitAttachRef(finishedWork) {
20007 var ref = finishedWork.ref;
20008
20009 if (ref !== null) {
20010 var instance = finishedWork.stateNode;
20011 var instanceToUse;
20012
20013 switch (finishedWork.tag) {
20014 case HostComponent:
20015 instanceToUse = getPublicInstance(instance);
20016 break;
20017
20018 default:
20019 instanceToUse = instance;
20020 } // Moved outside to ensure DCE works with this flag
20021
20022 if (typeof ref === 'function') {
20023 ref(instanceToUse);
20024 } else {
20025 {
20026 if (!ref.hasOwnProperty('current')) {
20027 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
20028 }
20029 }
20030
20031 ref.current = instanceToUse;
20032 }
20033 }
20034}
20035
20036function commitDetachRef(current) {
20037 var currentRef = current.ref;
20038
20039 if (currentRef !== null) {
20040 if (typeof currentRef === 'function') {
20041 currentRef(null);
20042 } else {
20043 currentRef.current = null;
20044 }
20045 }
20046} // User-originating errors (lifecycles and refs) should not interrupt
20047// deletion, so don't let them throw. Host-originating errors should
20048// interrupt deletion, so it's okay
20049
20050
20051function commitUnmount(finishedRoot, current, renderPriorityLevel) {
20052 onCommitUnmount(current);
20053
20054 switch (current.tag) {
20055 case FunctionComponent:
20056 case ForwardRef:
20057 case MemoComponent:
20058 case SimpleMemoComponent:
20059 case Block:
20060 {
20061 var updateQueue = current.updateQueue;
20062
20063 if (updateQueue !== null) {
20064 var lastEffect = updateQueue.lastEffect;
20065
20066 if (lastEffect !== null) {
20067 var firstEffect = lastEffect.next;
20068
20069 {
20070 // When the owner fiber is deleted, the destroy function of a passive
20071 // effect hook is called during the synchronous commit phase. This is
20072 // a concession to implementation complexity. Calling it in the
20073 // passive effect phase (like they usually are, when dependencies
20074 // change during an update) would require either traversing the
20075 // children of the deleted fiber again, or including unmount effects
20076 // as part of the fiber effect list.
20077 //
20078 // Because this is during the sync commit phase, we need to change
20079 // the priority.
20080 //
20081 // TODO: Reconsider this implementation trade off.
20082 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
20083 runWithPriority$1(priorityLevel, function () {
20084 var effect = firstEffect;
20085
20086 do {
20087 var _destroy = effect.destroy;
20088
20089 if (_destroy !== undefined) {
20090 safelyCallDestroy(current, _destroy);
20091 }
20092
20093 effect = effect.next;
20094 } while (effect !== firstEffect);
20095 });
20096 }
20097 }
20098 }
20099
20100 return;
20101 }
20102
20103 case ClassComponent:
20104 {
20105 safelyDetachRef(current);
20106 var instance = current.stateNode;
20107
20108 if (typeof instance.componentWillUnmount === 'function') {
20109 safelyCallComponentWillUnmount(current, instance);
20110 }
20111
20112 return;
20113 }
20114
20115 case HostComponent:
20116 {
20117
20118 safelyDetachRef(current);
20119 return;
20120 }
20121
20122 case HostPortal:
20123 {
20124 // TODO: this is recursive.
20125 // We are also not using this parent because
20126 // the portal will get pushed immediately.
20127 {
20128 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
20129 }
20130
20131 return;
20132 }
20133
20134 case FundamentalComponent:
20135 {
20136
20137 return;
20138 }
20139
20140 case DehydratedFragment:
20141 {
20142
20143 return;
20144 }
20145
20146 case ScopeComponent:
20147 {
20148
20149 return;
20150 }
20151 }
20152}
20153
20154function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
20155 // While we're inside a removed host node we don't want to call
20156 // removeChild on the inner nodes because they're removed by the top
20157 // call anyway. We also want to call componentWillUnmount on all
20158 // composites before this host node is removed from the tree. Therefore
20159 // we do an inner loop while we're still inside the host node.
20160 var node = root;
20161
20162 while (true) {
20163 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
20164 // Skip portals because commitUnmount() currently visits them recursively.
20165
20166 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
20167 // If we don't use mutation we drill down into portals here instead.
20168 node.tag !== HostPortal)) {
20169 node.child.return = node;
20170 node = node.child;
20171 continue;
20172 }
20173
20174 if (node === root) {
20175 return;
20176 }
20177
20178 while (node.sibling === null) {
20179 if (node.return === null || node.return === root) {
20180 return;
20181 }
20182
20183 node = node.return;
20184 }
20185
20186 node.sibling.return = node.return;
20187 node = node.sibling;
20188 }
20189}
20190
20191function detachFiber(current) {
20192 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
20193 // should clear the child pointer of the parent alternate to let this
20194 // get GC:ed but we don't know which for sure which parent is the current
20195 // one so we'll settle for GC:ing the subtree of this child. This child
20196 // itself will be GC:ed when the parent updates the next time.
20197
20198 current.return = null;
20199 current.child = null;
20200 current.memoizedState = null;
20201 current.updateQueue = null;
20202 current.dependencies = null;
20203 current.alternate = null;
20204 current.firstEffect = null;
20205 current.lastEffect = null;
20206 current.pendingProps = null;
20207 current.memoizedProps = null;
20208 current.stateNode = null;
20209
20210 if (alternate !== null) {
20211 detachFiber(alternate);
20212 }
20213}
20214
20215function getHostParentFiber(fiber) {
20216 var parent = fiber.return;
20217
20218 while (parent !== null) {
20219 if (isHostParent(parent)) {
20220 return parent;
20221 }
20222
20223 parent = parent.return;
20224 }
20225
20226 {
20227 {
20228 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
20229 }
20230 }
20231}
20232
20233function isHostParent(fiber) {
20234 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
20235}
20236
20237function getHostSibling(fiber) {
20238 // We're going to search forward into the tree until we find a sibling host
20239 // node. Unfortunately, if multiple insertions are done in a row we have to
20240 // search past them. This leads to exponential search for the next sibling.
20241 // TODO: Find a more efficient way to do this.
20242 var node = fiber;
20243
20244 siblings: while (true) {
20245 // If we didn't find anything, let's try the next sibling.
20246 while (node.sibling === null) {
20247 if (node.return === null || isHostParent(node.return)) {
20248 // If we pop out of the root or hit the parent the fiber we are the
20249 // last sibling.
20250 return null;
20251 }
20252
20253 node = node.return;
20254 }
20255
20256 node.sibling.return = node.return;
20257 node = node.sibling;
20258
20259 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
20260 // If it is not host node and, we might have a host node inside it.
20261 // Try to search down until we find one.
20262 if (node.effectTag & Placement) {
20263 // If we don't have a child, try the siblings instead.
20264 continue siblings;
20265 } // If we don't have a child, try the siblings instead.
20266 // We also skip portals because they are not part of this host tree.
20267
20268
20269 if (node.child === null || node.tag === HostPortal) {
20270 continue siblings;
20271 } else {
20272 node.child.return = node;
20273 node = node.child;
20274 }
20275 } // Check if this host node is stable or about to be placed.
20276
20277
20278 if (!(node.effectTag & Placement)) {
20279 // Found it!
20280 return node.stateNode;
20281 }
20282 }
20283}
20284
20285function commitPlacement(finishedWork) {
20286
20287
20288 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
20289
20290 var parent;
20291 var isContainer;
20292 var parentStateNode = parentFiber.stateNode;
20293
20294 switch (parentFiber.tag) {
20295 case HostComponent:
20296 parent = parentStateNode;
20297 isContainer = false;
20298 break;
20299
20300 case HostRoot:
20301 parent = parentStateNode.containerInfo;
20302 isContainer = true;
20303 break;
20304
20305 case HostPortal:
20306 parent = parentStateNode.containerInfo;
20307 isContainer = true;
20308 break;
20309
20310 case FundamentalComponent:
20311
20312 // eslint-disable-next-line-no-fallthrough
20313
20314 default:
20315 {
20316 {
20317 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
20318 }
20319 }
20320
20321 }
20322
20323 if (parentFiber.effectTag & ContentReset) {
20324 // Reset the text content of the parent before doing any insertions
20325 resetTextContent(parent); // Clear ContentReset from the effect tag
20326
20327 parentFiber.effectTag &= ~ContentReset;
20328 }
20329
20330 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
20331 // children to find all the terminal nodes.
20332
20333 if (isContainer) {
20334 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
20335 } else {
20336 insertOrAppendPlacementNode(finishedWork, before, parent);
20337 }
20338}
20339
20340function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
20341 var tag = node.tag;
20342 var isHost = tag === HostComponent || tag === HostText;
20343
20344 if (isHost || enableFundamentalAPI ) {
20345 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
20346
20347 if (before) {
20348 insertInContainerBefore(parent, stateNode, before);
20349 } else {
20350 appendChildToContainer(parent, stateNode);
20351 }
20352 } else if (tag === HostPortal) ; else {
20353 var child = node.child;
20354
20355 if (child !== null) {
20356 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
20357 var sibling = child.sibling;
20358
20359 while (sibling !== null) {
20360 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
20361 sibling = sibling.sibling;
20362 }
20363 }
20364 }
20365}
20366
20367function insertOrAppendPlacementNode(node, before, parent) {
20368 var tag = node.tag;
20369 var isHost = tag === HostComponent || tag === HostText;
20370
20371 if (isHost || enableFundamentalAPI ) {
20372 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
20373
20374 if (before) {
20375 insertBefore(parent, stateNode, before);
20376 } else {
20377 appendChild(parent, stateNode);
20378 }
20379 } else if (tag === HostPortal) ; else {
20380 var child = node.child;
20381
20382 if (child !== null) {
20383 insertOrAppendPlacementNode(child, before, parent);
20384 var sibling = child.sibling;
20385
20386 while (sibling !== null) {
20387 insertOrAppendPlacementNode(sibling, before, parent);
20388 sibling = sibling.sibling;
20389 }
20390 }
20391 }
20392}
20393
20394function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
20395 // We only have the top Fiber that was deleted but we need to recurse down its
20396 // children to find all the terminal nodes.
20397 var node = current; // Each iteration, currentParent is populated with node's host parent if not
20398 // currentParentIsValid.
20399
20400 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
20401
20402 var currentParent;
20403 var currentParentIsContainer;
20404
20405 while (true) {
20406 if (!currentParentIsValid) {
20407 var parent = node.return;
20408
20409 findParent: while (true) {
20410 if (!(parent !== null)) {
20411 {
20412 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
20413 }
20414 }
20415
20416 var parentStateNode = parent.stateNode;
20417
20418 switch (parent.tag) {
20419 case HostComponent:
20420 currentParent = parentStateNode;
20421 currentParentIsContainer = false;
20422 break findParent;
20423
20424 case HostRoot:
20425 currentParent = parentStateNode.containerInfo;
20426 currentParentIsContainer = true;
20427 break findParent;
20428
20429 case HostPortal:
20430 currentParent = parentStateNode.containerInfo;
20431 currentParentIsContainer = true;
20432 break findParent;
20433
20434 }
20435
20436 parent = parent.return;
20437 }
20438
20439 currentParentIsValid = true;
20440 }
20441
20442 if (node.tag === HostComponent || node.tag === HostText) {
20443 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
20444 // node from the tree.
20445
20446 if (currentParentIsContainer) {
20447 removeChildFromContainer(currentParent, node.stateNode);
20448 } else {
20449 removeChild(currentParent, node.stateNode);
20450 } // Don't visit children because we already visited them.
20451
20452 } else if (node.tag === HostPortal) {
20453 if (node.child !== null) {
20454 // When we go into a portal, it becomes the parent to remove from.
20455 // We will reassign it back when we pop the portal on the way up.
20456 currentParent = node.stateNode.containerInfo;
20457 currentParentIsContainer = true; // Visit children because portals might contain host components.
20458
20459 node.child.return = node;
20460 node = node.child;
20461 continue;
20462 }
20463 } else {
20464 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
20465
20466 if (node.child !== null) {
20467 node.child.return = node;
20468 node = node.child;
20469 continue;
20470 }
20471 }
20472
20473 if (node === current) {
20474 return;
20475 }
20476
20477 while (node.sibling === null) {
20478 if (node.return === null || node.return === current) {
20479 return;
20480 }
20481
20482 node = node.return;
20483
20484 if (node.tag === HostPortal) {
20485 // When we go out of the portal, we need to restore the parent.
20486 // Since we don't keep a stack of them, we will search for it.
20487 currentParentIsValid = false;
20488 }
20489 }
20490
20491 node.sibling.return = node.return;
20492 node = node.sibling;
20493 }
20494}
20495
20496function commitDeletion(finishedRoot, current, renderPriorityLevel) {
20497 {
20498 // Recursively delete all host nodes from the parent.
20499 // Detach refs and call componentWillUnmount() on the whole subtree.
20500 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
20501 }
20502
20503 detachFiber(current);
20504}
20505
20506function commitWork(current, finishedWork) {
20507
20508 switch (finishedWork.tag) {
20509 case FunctionComponent:
20510 case ForwardRef:
20511 case MemoComponent:
20512 case SimpleMemoComponent:
20513 case Block:
20514 {
20515 // Layout effects are destroyed during the mutation phase so that all
20516 // destroy functions for all fibers are called before any create functions.
20517 // This prevents sibling component effects from interfering with each other,
20518 // e.g. a destroy function in one component should never override a ref set
20519 // by a create function in another component during the same commit.
20520 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
20521 return;
20522 }
20523
20524 case ClassComponent:
20525 {
20526 return;
20527 }
20528
20529 case HostComponent:
20530 {
20531 var instance = finishedWork.stateNode;
20532
20533 if (instance != null) {
20534 // Commit the work prepared earlier.
20535 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
20536 // as the newProps. The updatePayload will contain the real change in
20537 // this case.
20538
20539 var oldProps = current !== null ? current.memoizedProps : newProps;
20540 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
20541
20542 var updatePayload = finishedWork.updateQueue;
20543 finishedWork.updateQueue = null;
20544
20545 if (updatePayload !== null) {
20546 commitUpdate(instance, updatePayload, type, oldProps, newProps);
20547 }
20548 }
20549
20550 return;
20551 }
20552
20553 case HostText:
20554 {
20555 if (!(finishedWork.stateNode !== null)) {
20556 {
20557 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
20558 }
20559 }
20560
20561 var textInstance = finishedWork.stateNode;
20562 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
20563 // as the newProps. The updatePayload will contain the real change in
20564 // this case.
20565
20566 var oldText = current !== null ? current.memoizedProps : newText;
20567 commitTextUpdate(textInstance, oldText, newText);
20568 return;
20569 }
20570
20571 case HostRoot:
20572 {
20573 {
20574 var _root = finishedWork.stateNode;
20575
20576 if (_root.hydrate) {
20577 // We've just hydrated. No need to hydrate again.
20578 _root.hydrate = false;
20579 commitHydratedContainer(_root.containerInfo);
20580 }
20581 }
20582
20583 return;
20584 }
20585
20586 case Profiler:
20587 {
20588 return;
20589 }
20590
20591 case SuspenseComponent:
20592 {
20593 commitSuspenseComponent(finishedWork);
20594 attachSuspenseRetryListeners(finishedWork);
20595 return;
20596 }
20597
20598 case SuspenseListComponent:
20599 {
20600 attachSuspenseRetryListeners(finishedWork);
20601 return;
20602 }
20603
20604 case IncompleteClassComponent:
20605 {
20606 return;
20607 }
20608 }
20609
20610 {
20611 {
20612 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
20613 }
20614 }
20615}
20616
20617function commitSuspenseComponent(finishedWork) {
20618 var newState = finishedWork.memoizedState;
20619 var newDidTimeout;
20620 var primaryChildParent = finishedWork;
20621
20622 if (newState === null) {
20623 newDidTimeout = false;
20624 } else {
20625 newDidTimeout = true;
20626 primaryChildParent = finishedWork.child;
20627 markCommitTimeOfFallback();
20628 }
20629
20630 if ( primaryChildParent !== null) {
20631 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
20632 }
20633}
20634
20635function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
20636
20637 var newState = finishedWork.memoizedState;
20638
20639 if (newState === null) {
20640 var current = finishedWork.alternate;
20641
20642 if (current !== null) {
20643 var prevState = current.memoizedState;
20644
20645 if (prevState !== null) {
20646 var suspenseInstance = prevState.dehydrated;
20647
20648 if (suspenseInstance !== null) {
20649 commitHydratedSuspenseInstance(suspenseInstance);
20650 }
20651 }
20652 }
20653 }
20654}
20655
20656function attachSuspenseRetryListeners(finishedWork) {
20657 // If this boundary just timed out, then it will have a set of thenables.
20658 // For each thenable, attach a listener so that when it resolves, React
20659 // attempts to re-render the boundary in the primary (pre-timeout) state.
20660 var thenables = finishedWork.updateQueue;
20661
20662 if (thenables !== null) {
20663 finishedWork.updateQueue = null;
20664 var retryCache = finishedWork.stateNode;
20665
20666 if (retryCache === null) {
20667 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
20668 }
20669
20670 thenables.forEach(function (thenable) {
20671 // Memoize using the boundary fiber to prevent redundant listeners.
20672 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
20673
20674 if (!retryCache.has(thenable)) {
20675 {
20676 if (thenable.__reactDoNotTraceInteractions !== true) {
20677 retry = tracing.unstable_wrap(retry);
20678 }
20679 }
20680
20681 retryCache.add(thenable);
20682 thenable.then(retry, retry);
20683 }
20684 });
20685 }
20686}
20687
20688function commitResetTextContent(current) {
20689
20690 resetTextContent(current.stateNode);
20691}
20692
20693var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
20694
20695function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
20696 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
20697
20698 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
20699 // being called "element".
20700
20701 update.payload = {
20702 element: null
20703 };
20704 var error = errorInfo.value;
20705
20706 update.callback = function () {
20707 onUncaughtError(error);
20708 logError(fiber, errorInfo);
20709 };
20710
20711 return update;
20712}
20713
20714function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
20715 var update = createUpdate(expirationTime, null);
20716 update.tag = CaptureUpdate;
20717 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
20718
20719 if (typeof getDerivedStateFromError === 'function') {
20720 var error$1 = errorInfo.value;
20721
20722 update.payload = function () {
20723 logError(fiber, errorInfo);
20724 return getDerivedStateFromError(error$1);
20725 };
20726 }
20727
20728 var inst = fiber.stateNode;
20729
20730 if (inst !== null && typeof inst.componentDidCatch === 'function') {
20731 update.callback = function callback() {
20732 {
20733 markFailedErrorBoundaryForHotReloading(fiber);
20734 }
20735
20736 if (typeof getDerivedStateFromError !== 'function') {
20737 // To preserve the preexisting retry behavior of error boundaries,
20738 // we keep track of which ones already failed during this batch.
20739 // This gets reset before we yield back to the browser.
20740 // TODO: Warn in strict mode if getDerivedStateFromError is
20741 // not defined.
20742 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
20743
20744 logError(fiber, errorInfo);
20745 }
20746
20747 var error$1 = errorInfo.value;
20748 var stack = errorInfo.stack;
20749 this.componentDidCatch(error$1, {
20750 componentStack: stack !== null ? stack : ''
20751 });
20752
20753 {
20754 if (typeof getDerivedStateFromError !== 'function') {
20755 // If componentDidCatch is the only error boundary method defined,
20756 // then it needs to call setState to recover from errors.
20757 // If no state update is scheduled then the boundary will swallow the error.
20758 if (fiber.expirationTime !== Sync) {
20759 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown');
20760 }
20761 }
20762 }
20763 };
20764 } else {
20765 update.callback = function () {
20766 markFailedErrorBoundaryForHotReloading(fiber);
20767 };
20768 }
20769
20770 return update;
20771}
20772
20773function attachPingListener(root, renderExpirationTime, thenable) {
20774 // Attach a listener to the promise to "ping" the root and retry. But
20775 // only if one does not already exist for the current render expiration
20776 // time (which acts like a "thread ID" here).
20777 var pingCache = root.pingCache;
20778 var threadIDs;
20779
20780 if (pingCache === null) {
20781 pingCache = root.pingCache = new PossiblyWeakMap$1();
20782 threadIDs = new Set();
20783 pingCache.set(thenable, threadIDs);
20784 } else {
20785 threadIDs = pingCache.get(thenable);
20786
20787 if (threadIDs === undefined) {
20788 threadIDs = new Set();
20789 pingCache.set(thenable, threadIDs);
20790 }
20791 }
20792
20793 if (!threadIDs.has(renderExpirationTime)) {
20794 // Memoize using the thread ID to prevent redundant listeners.
20795 threadIDs.add(renderExpirationTime);
20796 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
20797 thenable.then(ping, ping);
20798 }
20799}
20800
20801function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
20802 // The source fiber did not complete.
20803 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
20804
20805 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
20806
20807 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
20808 // This is a thenable.
20809 var thenable = value;
20810
20811 if ((sourceFiber.mode & BlockingMode) === NoMode) {
20812 // Reset the memoizedState to what it was before we attempted
20813 // to render it.
20814 var currentSource = sourceFiber.alternate;
20815
20816 if (currentSource) {
20817 sourceFiber.updateQueue = currentSource.updateQueue;
20818 sourceFiber.memoizedState = currentSource.memoizedState;
20819 sourceFiber.expirationTime = currentSource.expirationTime;
20820 } else {
20821 sourceFiber.updateQueue = null;
20822 sourceFiber.memoizedState = null;
20823 }
20824 }
20825
20826 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
20827
20828 var _workInProgress = returnFiber;
20829
20830 do {
20831 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
20832 // Found the nearest boundary.
20833 // Stash the promise on the boundary fiber. If the boundary times out, we'll
20834 // attach another listener to flip the boundary back to its normal state.
20835 var thenables = _workInProgress.updateQueue;
20836
20837 if (thenables === null) {
20838 var updateQueue = new Set();
20839 updateQueue.add(thenable);
20840 _workInProgress.updateQueue = updateQueue;
20841 } else {
20842 thenables.add(thenable);
20843 } // If the boundary is outside of blocking mode, we should *not*
20844 // suspend the commit. Pretend as if the suspended component rendered
20845 // null and keep rendering. In the commit phase, we'll schedule a
20846 // subsequent synchronous update to re-render the Suspense.
20847 //
20848 // Note: It doesn't matter whether the component that suspended was
20849 // inside a blocking mode tree. If the Suspense is outside of it, we
20850 // should *not* suspend the commit.
20851
20852
20853 if ((_workInProgress.mode & BlockingMode) === NoMode) {
20854 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
20855 // But we shouldn't call any lifecycle methods or callbacks. Remove
20856 // all lifecycle effect tags.
20857
20858 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
20859
20860 if (sourceFiber.tag === ClassComponent) {
20861 var currentSourceFiber = sourceFiber.alternate;
20862
20863 if (currentSourceFiber === null) {
20864 // This is a new mount. Change the tag so it's not mistaken for a
20865 // completed class component. For example, we should not call
20866 // componentWillUnmount if it is deleted.
20867 sourceFiber.tag = IncompleteClassComponent;
20868 } else {
20869 // When we try rendering again, we should not reuse the current fiber,
20870 // since it's known to be in an inconsistent state. Use a force update to
20871 // prevent a bail out.
20872 var update = createUpdate(Sync, null);
20873 update.tag = ForceUpdate;
20874 enqueueUpdate(sourceFiber, update);
20875 }
20876 } // The source fiber did not complete. Mark it with Sync priority to
20877 // indicate that it still has pending work.
20878
20879
20880 sourceFiber.expirationTime = Sync; // Exit without suspending.
20881
20882 return;
20883 } // Confirmed that the boundary is in a concurrent mode tree. Continue
20884 // with the normal suspend path.
20885 //
20886 // After this we'll use a set of heuristics to determine whether this
20887 // render pass will run to completion or restart or "suspend" the commit.
20888 // The actual logic for this is spread out in different places.
20889 //
20890 // This first principle is that if we're going to suspend when we complete
20891 // a root, then we should also restart if we get an update or ping that
20892 // might unsuspend it, and vice versa. The only reason to suspend is
20893 // because you think you might want to restart before committing. However,
20894 // it doesn't make sense to restart only while in the period we're suspended.
20895 //
20896 // Restarting too aggressively is also not good because it starves out any
20897 // intermediate loading state. So we use heuristics to determine when.
20898 // Suspense Heuristics
20899 //
20900 // If nothing threw a Promise or all the same fallbacks are already showing,
20901 // then don't suspend/restart.
20902 //
20903 // If this is an initial render of a new tree of Suspense boundaries and
20904 // those trigger a fallback, then don't suspend/restart. We want to ensure
20905 // that we can show the initial loading state as quickly as possible.
20906 //
20907 // If we hit a "Delayed" case, such as when we'd switch from content back into
20908 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
20909 // this case. If none is defined, JND is used instead.
20910 //
20911 // If we're already showing a fallback and it gets "retried", allowing us to show
20912 // another level, but there's still an inner boundary that would show a fallback,
20913 // then we suspend/restart for 500ms since the last time we showed a fallback
20914 // anywhere in the tree. This effectively throttles progressive loading into a
20915 // consistent train of commits. This also gives us an opportunity to restart to
20916 // get to the completed state slightly earlier.
20917 //
20918 // If there's ambiguity due to batching it's resolved in preference of:
20919 // 1) "delayed", 2) "initial render", 3) "retry".
20920 //
20921 // We want to ensure that a "busy" state doesn't get force committed. We want to
20922 // ensure that new initial loading states can commit as soon as possible.
20923
20924
20925 attachPingListener(root, renderExpirationTime, thenable);
20926 _workInProgress.effectTag |= ShouldCapture;
20927 _workInProgress.expirationTime = renderExpirationTime;
20928 return;
20929 } // This boundary already captured during this render. Continue to the next
20930 // boundary.
20931
20932
20933 _workInProgress = _workInProgress.return;
20934 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
20935 // TODO: Use invariant so the message is stripped in prod?
20936
20937
20938 value = new Error((getComponentName(sourceFiber.type) || 'A React component') + ' suspended while rendering, but no fallback UI was specified.\n' + '\n' + 'Add a <Suspense fallback=...> component higher in the tree to ' + 'provide a loading indicator or placeholder to display.' + getStackByFiberInDevAndProd(sourceFiber));
20939 } // We didn't find a boundary that could handle this type of exception. Start
20940 // over and traverse parent path again, this time treating the exception
20941 // as an error.
20942
20943
20944 renderDidError();
20945 value = createCapturedValue(value, sourceFiber);
20946 var workInProgress = returnFiber;
20947
20948 do {
20949 switch (workInProgress.tag) {
20950 case HostRoot:
20951 {
20952 var _errorInfo = value;
20953 workInProgress.effectTag |= ShouldCapture;
20954 workInProgress.expirationTime = renderExpirationTime;
20955
20956 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
20957
20958 enqueueCapturedUpdate(workInProgress, _update);
20959 return;
20960 }
20961
20962 case ClassComponent:
20963 // Capture and retry
20964 var errorInfo = value;
20965 var ctor = workInProgress.type;
20966 var instance = workInProgress.stateNode;
20967
20968 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
20969 workInProgress.effectTag |= ShouldCapture;
20970 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
20971
20972 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
20973
20974 enqueueCapturedUpdate(workInProgress, _update2);
20975 return;
20976 }
20977
20978 break;
20979 }
20980
20981 workInProgress = workInProgress.return;
20982 } while (workInProgress !== null);
20983}
20984
20985var ceil = Math.ceil;
20986var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
20987 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
20988 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
20989var NoContext =
20990/* */
209910;
20992var BatchedContext =
20993/* */
209941;
20995var EventContext =
20996/* */
209972;
20998var DiscreteEventContext =
20999/* */
210004;
21001var LegacyUnbatchedContext =
21002/* */
210038;
21004var RenderContext =
21005/* */
2100616;
21007var CommitContext =
21008/* */
2100932;
21010var RootIncomplete = 0;
21011var RootFatalErrored = 1;
21012var RootErrored = 2;
21013var RootSuspended = 3;
21014var RootSuspendedWithDelay = 4;
21015var RootCompleted = 5;
21016// Describes where we are in the React execution stack
21017var executionContext = NoContext; // The root we're working on
21018
21019var workInProgressRoot = null; // The fiber we're working on
21020
21021var workInProgress = null; // The expiration time we're rendering
21022
21023var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.
21024
21025var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
21026
21027var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
21028// This is conceptually a time stamp but expressed in terms of an ExpirationTime
21029// because we deal mostly with expiration times in the hot path, so this avoids
21030// the conversion happening in the hot path.
21031
21032var workInProgressRootLatestProcessedExpirationTime = Sync;
21033var workInProgressRootLatestSuspenseTimeout = Sync;
21034var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
21035// includes unprocessed updates, not work in bailed out children.
21036
21037var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
21038// This flag determines if it might be worthwhile to restart if an opportunity
21039// happens latere.
21040
21041var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
21042// model where we don't commit new loading states in too quick succession.
21043
21044var globalMostRecentFallbackTime = 0;
21045var FALLBACK_THROTTLE_MS = 500;
21046var nextEffect = null;
21047var hasUncaughtError = false;
21048var firstUncaughtError = null;
21049var legacyErrorBoundariesThatAlreadyFailed = null;
21050var rootDoesHavePassiveEffects = false;
21051var rootWithPendingPassiveEffects = null;
21052var pendingPassiveEffectsRenderPriority = NoPriority;
21053var pendingPassiveEffectsExpirationTime = NoWork;
21054var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
21055
21056var NESTED_UPDATE_LIMIT = 50;
21057var nestedUpdateCount = 0;
21058var rootWithNestedUpdates = null;
21059var NESTED_PASSIVE_UPDATE_LIMIT = 50;
21060var nestedPassiveUpdateCount = 0;
21061var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
21062// during the commit phase. This enables them to be traced across components
21063// that spawn new work during render. E.g. hidden boundaries, suspended SSR
21064// hydration or SuspenseList.
21065
21066var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
21067// time). However, if two updates are scheduled within the same event, we
21068// should treat their start times as simultaneous, even if the actual clock
21069// time has advanced between the first and second call.
21070// In other words, because expiration times determine how updates are batched,
21071// we want all updates of like priority that occur within the same event to
21072// receive the same expiration time. Otherwise we get tearing.
21073
21074var currentEventTime = NoWork;
21075function requestCurrentTimeForUpdate() {
21076 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21077 // We're inside React, so it's fine to read the actual time.
21078 return msToExpirationTime(now());
21079 } // We're not inside React, so we may be in the middle of a browser event.
21080
21081
21082 if (currentEventTime !== NoWork) {
21083 // Use the same start time for all updates until we enter React again.
21084 return currentEventTime;
21085 } // This is the first update since React yielded. Compute a new start time.
21086
21087
21088 currentEventTime = msToExpirationTime(now());
21089 return currentEventTime;
21090}
21091function getCurrentTime() {
21092 return msToExpirationTime(now());
21093}
21094function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
21095 var mode = fiber.mode;
21096
21097 if ((mode & BlockingMode) === NoMode) {
21098 return Sync;
21099 }
21100
21101 var priorityLevel = getCurrentPriorityLevel();
21102
21103 if ((mode & ConcurrentMode) === NoMode) {
21104 return priorityLevel === ImmediatePriority ? Sync : Batched;
21105 }
21106
21107 if ((executionContext & RenderContext) !== NoContext) {
21108 // Use whatever time we're already rendering
21109 // TODO: Should there be a way to opt out, like with `runWithPriority`?
21110 return renderExpirationTime$1;
21111 }
21112
21113 var expirationTime;
21114
21115 if (suspenseConfig !== null) {
21116 // Compute an expiration time based on the Suspense timeout.
21117 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
21118 } else {
21119 // Compute an expiration time based on the Scheduler priority.
21120 switch (priorityLevel) {
21121 case ImmediatePriority:
21122 expirationTime = Sync;
21123 break;
21124
21125 case UserBlockingPriority$1:
21126 // TODO: Rename this to computeUserBlockingExpiration
21127 expirationTime = computeInteractiveExpiration(currentTime);
21128 break;
21129
21130 case NormalPriority:
21131 case LowPriority:
21132 // TODO: Handle LowPriority
21133 // TODO: Rename this to... something better.
21134 expirationTime = computeAsyncExpiration(currentTime);
21135 break;
21136
21137 case IdlePriority:
21138 expirationTime = Idle;
21139 break;
21140
21141 default:
21142 {
21143 {
21144 throw Error( "Expected a valid priority level" );
21145 }
21146 }
21147
21148 }
21149 } // If we're in the middle of rendering a tree, do not update at the same
21150 // expiration time that is already rendering.
21151 // TODO: We shouldn't have to do this if the update is on a different root.
21152 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
21153 // the root when we check for this condition.
21154
21155
21156 if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {
21157 // This is a trick to move this update into a separate batch
21158 expirationTime -= 1;
21159 }
21160
21161 return expirationTime;
21162}
21163function scheduleUpdateOnFiber(fiber, expirationTime) {
21164 checkForNestedUpdates();
21165 warnAboutRenderPhaseUpdatesInDEV(fiber);
21166 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
21167
21168 if (root === null) {
21169 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
21170 return;
21171 }
21172
21173 checkForInterruption(fiber, expirationTime);
21174 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
21175 // priority as an argument to that function and this one.
21176
21177 var priorityLevel = getCurrentPriorityLevel();
21178
21179 if (expirationTime === Sync) {
21180 if ( // Check if we're inside unbatchedUpdates
21181 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
21182 (executionContext & (RenderContext | CommitContext)) === NoContext) {
21183 // Register pending interactions on the root to avoid losing traced interaction data.
21184 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
21185 // root inside of batchedUpdates should be synchronous, but layout updates
21186 // should be deferred until the end of the batch.
21187
21188 performSyncWorkOnRoot(root);
21189 } else {
21190 ensureRootIsScheduled(root);
21191 schedulePendingInteractions(root, expirationTime);
21192
21193 if (executionContext === NoContext) {
21194 // Flush the synchronous work now, unless we're already working or inside
21195 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
21196 // scheduleCallbackForFiber to preserve the ability to schedule a callback
21197 // without immediately flushing it. We only do this for user-initiated
21198 // updates, to preserve historical behavior of legacy mode.
21199 flushSyncCallbackQueue();
21200 }
21201 }
21202 } else {
21203 ensureRootIsScheduled(root);
21204 schedulePendingInteractions(root, expirationTime);
21205 }
21206
21207 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
21208 // discrete, even inside a discrete event.
21209 priorityLevel === UserBlockingPriority$1 || priorityLevel === ImmediatePriority)) {
21210 // This is the result of a discrete event. Track the lowest priority
21211 // discrete update per root so we can flush them early, if needed.
21212 if (rootsWithPendingDiscreteUpdates === null) {
21213 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
21214 } else {
21215 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
21216
21217 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
21218 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
21219 }
21220 }
21221 }
21222}
21223var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
21224// work without treating it as a typical update that originates from an event;
21225// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
21226// on a fiber.
21227
21228function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
21229 // Update the source fiber's expiration time
21230 if (fiber.expirationTime < expirationTime) {
21231 fiber.expirationTime = expirationTime;
21232 }
21233
21234 var alternate = fiber.alternate;
21235
21236 if (alternate !== null && alternate.expirationTime < expirationTime) {
21237 alternate.expirationTime = expirationTime;
21238 } // Walk the parent path to the root and update the child expiration time.
21239
21240
21241 var node = fiber.return;
21242 var root = null;
21243
21244 if (node === null && fiber.tag === HostRoot) {
21245 root = fiber.stateNode;
21246 } else {
21247 while (node !== null) {
21248 alternate = node.alternate;
21249
21250 if (node.childExpirationTime < expirationTime) {
21251 node.childExpirationTime = expirationTime;
21252
21253 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21254 alternate.childExpirationTime = expirationTime;
21255 }
21256 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21257 alternate.childExpirationTime = expirationTime;
21258 }
21259
21260 if (node.return === null && node.tag === HostRoot) {
21261 root = node.stateNode;
21262 break;
21263 }
21264
21265 node = node.return;
21266 }
21267 }
21268
21269 if (root !== null) {
21270 if (workInProgressRoot === root) {
21271 // Received an update to a tree that's in the middle of rendering. Mark
21272 // that's unprocessed work on this root.
21273 markUnprocessedUpdateTime(expirationTime);
21274
21275 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
21276 // The root already suspended with a delay, which means this render
21277 // definitely won't finish. Since we have a new update, let's mark it as
21278 // suspended now, right before marking the incoming update. This has the
21279 // effect of interrupting the current render and switching to the update.
21280 // TODO: This happens to work when receiving an update during the render
21281 // phase, because of the trick inside computeExpirationForFiber to
21282 // subtract 1 from `renderExpirationTime` to move it into a
21283 // separate bucket. But we should probably model it with an exception,
21284 // using the same mechanism we use to force hydration of a subtree.
21285 // TODO: This does not account for low pri updates that were already
21286 // scheduled before the root started rendering. Need to track the next
21287 // pending expiration time (perhaps by backtracking the return path) and
21288 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
21289 markRootSuspendedAtTime(root, renderExpirationTime$1);
21290 }
21291 } // Mark that the root has a pending update.
21292
21293
21294 markRootUpdatedAtTime(root, expirationTime);
21295 }
21296
21297 return root;
21298}
21299
21300function getNextRootExpirationTimeToWorkOn(root) {
21301 // Determines the next expiration time that the root should render, taking
21302 // into account levels that may be suspended, or levels that may have
21303 // received a ping.
21304 var lastExpiredTime = root.lastExpiredTime;
21305
21306 if (lastExpiredTime !== NoWork) {
21307 return lastExpiredTime;
21308 } // "Pending" refers to any update that hasn't committed yet, including if it
21309 // suspended. The "suspended" range is therefore a subset.
21310
21311
21312 var firstPendingTime = root.firstPendingTime;
21313
21314 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
21315 // The highest priority pending time is not suspended. Let's work on that.
21316 return firstPendingTime;
21317 } // If the first pending time is suspended, check if there's a lower priority
21318 // pending level that we know about. Or check if we received a ping. Work
21319 // on whichever is higher priority.
21320
21321
21322 var lastPingedTime = root.lastPingedTime;
21323 var nextKnownPendingLevel = root.nextKnownPendingLevel;
21324 var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
21325
21326 if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {
21327 // Don't work on Idle/Never priority unless everything else is committed.
21328 return NoWork;
21329 }
21330
21331 return nextLevel;
21332} // Use this function to schedule a task for a root. There's only one task per
21333// root; if a task was already scheduled, we'll check to make sure the
21334// expiration time of the existing task is the same as the expiration time of
21335// the next level that the root has work on. This function is called on every
21336// update, and right before exiting a task.
21337
21338
21339function ensureRootIsScheduled(root) {
21340 var lastExpiredTime = root.lastExpiredTime;
21341
21342 if (lastExpiredTime !== NoWork) {
21343 // Special case: Expired work should flush synchronously.
21344 root.callbackExpirationTime = Sync;
21345 root.callbackPriority = ImmediatePriority;
21346 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
21347 return;
21348 }
21349
21350 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
21351 var existingCallbackNode = root.callbackNode;
21352
21353 if (expirationTime === NoWork) {
21354 // There's nothing to work on.
21355 if (existingCallbackNode !== null) {
21356 root.callbackNode = null;
21357 root.callbackExpirationTime = NoWork;
21358 root.callbackPriority = NoPriority;
21359 }
21360
21361 return;
21362 } // TODO: If this is an update, we already read the current time. Pass the
21363 // time as an argument.
21364
21365
21366 var currentTime = requestCurrentTimeForUpdate();
21367 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
21368 // expiration time. Otherwise, we'll cancel it and schedule a new one.
21369
21370 if (existingCallbackNode !== null) {
21371 var existingCallbackPriority = root.callbackPriority;
21372 var existingCallbackExpirationTime = root.callbackExpirationTime;
21373
21374 if ( // Callback must have the exact same expiration time.
21375 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
21376 existingCallbackPriority >= priorityLevel) {
21377 // Existing callback is sufficient.
21378 return;
21379 } // Need to schedule a new task.
21380 // TODO: Instead of scheduling a new task, we should be able to change the
21381 // priority of the existing one.
21382
21383
21384 cancelCallback(existingCallbackNode);
21385 }
21386
21387 root.callbackExpirationTime = expirationTime;
21388 root.callbackPriority = priorityLevel;
21389 var callbackNode;
21390
21391 if (expirationTime === Sync) {
21392 // Sync React callbacks are scheduled on a special internal queue
21393 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
21394 } else {
21395 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
21396 // ordering because tasks are processed in timeout order.
21397 {
21398 timeout: expirationTimeToMs(expirationTime) - now()
21399 });
21400 }
21401
21402 root.callbackNode = callbackNode;
21403} // This is the entry point for every concurrent task, i.e. anything that
21404// goes through Scheduler.
21405
21406
21407function performConcurrentWorkOnRoot(root, didTimeout) {
21408 // Since we know we're in a React event, we can clear the current
21409 // event time. The next update will compute a new event time.
21410 currentEventTime = NoWork;
21411
21412 if (didTimeout) {
21413 // The render task took too long to complete. Mark the current time as
21414 // expired to synchronously render all expired work in a single batch.
21415 var currentTime = requestCurrentTimeForUpdate();
21416 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
21417
21418 ensureRootIsScheduled(root);
21419 return null;
21420 } // Determine the next expiration time to work on, using the fields stored
21421 // on the root.
21422
21423
21424 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
21425
21426 if (expirationTime !== NoWork) {
21427 var originalCallbackNode = root.callbackNode;
21428
21429 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
21430 {
21431 throw Error( "Should not already be working." );
21432 }
21433 }
21434
21435 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
21436 // and prepare a fresh one. Otherwise we'll continue where we left off.
21437
21438 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
21439 prepareFreshStack(root, expirationTime);
21440 startWorkOnPendingInteractions(root, expirationTime);
21441 } // If we have a work-in-progress fiber, it means there's still work to do
21442 // in this root.
21443
21444
21445 if (workInProgress !== null) {
21446 var prevExecutionContext = executionContext;
21447 executionContext |= RenderContext;
21448 var prevDispatcher = pushDispatcher();
21449 var prevInteractions = pushInteractions(root);
21450 startWorkLoopTimer(workInProgress);
21451
21452 do {
21453 try {
21454 workLoopConcurrent();
21455 break;
21456 } catch (thrownValue) {
21457 handleError(root, thrownValue);
21458 }
21459 } while (true);
21460
21461 resetContextDependencies();
21462 executionContext = prevExecutionContext;
21463 popDispatcher(prevDispatcher);
21464
21465 {
21466 popInteractions(prevInteractions);
21467 }
21468
21469 if (workInProgressRootExitStatus === RootFatalErrored) {
21470 var fatalError = workInProgressRootFatalError;
21471 stopInterruptedWorkLoopTimer();
21472 prepareFreshStack(root, expirationTime);
21473 markRootSuspendedAtTime(root, expirationTime);
21474 ensureRootIsScheduled(root);
21475 throw fatalError;
21476 }
21477
21478 if (workInProgress !== null) {
21479 // There's still work left over. Exit without committing.
21480 stopInterruptedWorkLoopTimer();
21481 } else {
21482 // We now have a consistent tree. The next step is either to commit it,
21483 // or, if something suspended, wait to commit it after a timeout.
21484 stopFinishedWorkLoopTimer();
21485 var finishedWork = root.finishedWork = root.current.alternate;
21486 root.finishedExpirationTime = expirationTime;
21487 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
21488 }
21489
21490 ensureRootIsScheduled(root);
21491
21492 if (root.callbackNode === originalCallbackNode) {
21493 // The task node scheduled for this root is the same one that's
21494 // currently executed. Need to return a continuation.
21495 return performConcurrentWorkOnRoot.bind(null, root);
21496 }
21497 }
21498 }
21499
21500 return null;
21501}
21502
21503function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
21504 // Set this to null to indicate there's no in-progress render.
21505 workInProgressRoot = null;
21506
21507 switch (exitStatus) {
21508 case RootIncomplete:
21509 case RootFatalErrored:
21510 {
21511 {
21512 {
21513 throw Error( "Root did not complete. This is a bug in React." );
21514 }
21515 }
21516 }
21517 // Flow knows about invariant, so it complains if I add a break
21518 // statement, but eslint doesn't know about invariant, so it complains
21519 // if I do. eslint-disable-next-line no-fallthrough
21520
21521 case RootErrored:
21522 {
21523 // If this was an async render, the error may have happened due to
21524 // a mutation in a concurrent event. Try rendering one more time,
21525 // synchronously, to see if the error goes away. If there are
21526 // lower priority updates, let's include those, too, in case they
21527 // fix the inconsistency. Render at Idle to include all updates.
21528 // If it was Idle or Never or some not-yet-invented time, render
21529 // at that time.
21530 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
21531 // and therefore not hit this path again.
21532
21533 break;
21534 }
21535
21536 case RootSuspended:
21537 {
21538 markRootSuspendedAtTime(root, expirationTime);
21539 var lastSuspendedTime = root.lastSuspendedTime;
21540
21541 if (expirationTime === lastSuspendedTime) {
21542 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
21543 } // We have an acceptable loading state. We need to figure out if we
21544 // should immediately commit it or wait a bit.
21545 // If we have processed new updates during this render, we may now
21546 // have a new loading state ready. We want to ensure that we commit
21547 // that as soon as possible.
21548
21549
21550 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
21551
21552 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
21553 !( IsThisRendererActing.current)) {
21554 // If we have not processed any new updates during this pass, then
21555 // this is either a retry of an existing fallback state or a
21556 // hidden tree. Hidden trees shouldn't be batched with other work
21557 // and after that's fixed it can only be a retry. We're going to
21558 // throttle committing retries so that we don't show too many
21559 // loading states too quickly.
21560 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
21561
21562 if (msUntilTimeout > 10) {
21563 if (workInProgressRootHasPendingPing) {
21564 var lastPingedTime = root.lastPingedTime;
21565
21566 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
21567 // This render was pinged but we didn't get to restart
21568 // earlier so try restarting now instead.
21569 root.lastPingedTime = expirationTime;
21570 prepareFreshStack(root, expirationTime);
21571 break;
21572 }
21573 }
21574
21575 var nextTime = getNextRootExpirationTimeToWorkOn(root);
21576
21577 if (nextTime !== NoWork && nextTime !== expirationTime) {
21578 // There's additional work on this root.
21579 break;
21580 }
21581
21582 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
21583 // We should prefer to render the fallback of at the last
21584 // suspended level. Ping the last suspended level to try
21585 // rendering it again.
21586 root.lastPingedTime = lastSuspendedTime;
21587 break;
21588 } // The render is suspended, it hasn't timed out, and there's no
21589 // lower priority work to do. Instead of committing the fallback
21590 // immediately, wait for more data to arrive.
21591
21592
21593 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
21594 break;
21595 }
21596 } // The work expired. Commit immediately.
21597
21598
21599 commitRoot(root);
21600 break;
21601 }
21602
21603 case RootSuspendedWithDelay:
21604 {
21605 markRootSuspendedAtTime(root, expirationTime);
21606 var _lastSuspendedTime = root.lastSuspendedTime;
21607
21608 if (expirationTime === _lastSuspendedTime) {
21609 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
21610 }
21611
21612 if ( // do not delay if we're inside an act() scope
21613 !( IsThisRendererActing.current)) {
21614 // We're suspended in a state that should be avoided. We'll try to
21615 // avoid committing it for as long as the timeouts let us.
21616 if (workInProgressRootHasPendingPing) {
21617 var _lastPingedTime = root.lastPingedTime;
21618
21619 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
21620 // This render was pinged but we didn't get to restart earlier
21621 // so try restarting now instead.
21622 root.lastPingedTime = expirationTime;
21623 prepareFreshStack(root, expirationTime);
21624 break;
21625 }
21626 }
21627
21628 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
21629
21630 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
21631 // There's additional work on this root.
21632 break;
21633 }
21634
21635 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
21636 // We should prefer to render the fallback of at the last
21637 // suspended level. Ping the last suspended level to try
21638 // rendering it again.
21639 root.lastPingedTime = _lastSuspendedTime;
21640 break;
21641 }
21642
21643 var _msUntilTimeout;
21644
21645 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
21646 // We have processed a suspense config whose expiration time we
21647 // can use as the timeout.
21648 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
21649 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
21650 // This should never normally happen because only new updates
21651 // cause delayed states, so we should have processed something.
21652 // However, this could also happen in an offscreen tree.
21653 _msUntilTimeout = 0;
21654 } else {
21655 // If we don't have a suspense config, we're going to use a
21656 // heuristic to determine how long we can suspend.
21657 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
21658 var currentTimeMs = now();
21659 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
21660 var timeElapsed = currentTimeMs - eventTimeMs;
21661
21662 if (timeElapsed < 0) {
21663 // We get this wrong some time since we estimate the time.
21664 timeElapsed = 0;
21665 }
21666
21667 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
21668 // event time is exact instead of inferred from expiration time
21669 // we don't need this.
21670
21671 if (timeUntilExpirationMs < _msUntilTimeout) {
21672 _msUntilTimeout = timeUntilExpirationMs;
21673 }
21674 } // Don't bother with a very short suspense time.
21675
21676
21677 if (_msUntilTimeout > 10) {
21678 // The render is suspended, it hasn't timed out, and there's no
21679 // lower priority work to do. Instead of committing the fallback
21680 // immediately, wait for more data to arrive.
21681 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
21682 break;
21683 }
21684 } // The work expired. Commit immediately.
21685
21686
21687 commitRoot(root);
21688 break;
21689 }
21690
21691 case RootCompleted:
21692 {
21693 // The work completed. Ready to commit.
21694 if ( // do not delay if we're inside an act() scope
21695 !( IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
21696 // If we have exceeded the minimum loading delay, which probably
21697 // means we have shown a spinner already, we might have to suspend
21698 // a bit longer to ensure that the spinner is shown for
21699 // enough time.
21700 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
21701
21702 if (_msUntilTimeout2 > 10) {
21703 markRootSuspendedAtTime(root, expirationTime);
21704 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
21705 break;
21706 }
21707 }
21708
21709 commitRoot(root);
21710 break;
21711 }
21712
21713 default:
21714 {
21715 {
21716 {
21717 throw Error( "Unknown root exit status." );
21718 }
21719 }
21720 }
21721 }
21722} // This is the entry point for synchronous tasks that don't go
21723// through Scheduler
21724
21725
21726function performSyncWorkOnRoot(root) {
21727 // Check if there's expired work on this root. Otherwise, render at Sync.
21728 var lastExpiredTime = root.lastExpiredTime;
21729 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
21730
21731 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
21732 {
21733 throw Error( "Should not already be working." );
21734 }
21735 }
21736
21737 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
21738 // and prepare a fresh one. Otherwise we'll continue where we left off.
21739
21740 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
21741 prepareFreshStack(root, expirationTime);
21742 startWorkOnPendingInteractions(root, expirationTime);
21743 } // If we have a work-in-progress fiber, it means there's still work to do
21744 // in this root.
21745
21746
21747 if (workInProgress !== null) {
21748 var prevExecutionContext = executionContext;
21749 executionContext |= RenderContext;
21750 var prevDispatcher = pushDispatcher();
21751 var prevInteractions = pushInteractions(root);
21752 startWorkLoopTimer(workInProgress);
21753
21754 do {
21755 try {
21756 workLoopSync();
21757 break;
21758 } catch (thrownValue) {
21759 handleError(root, thrownValue);
21760 }
21761 } while (true);
21762
21763 resetContextDependencies();
21764 executionContext = prevExecutionContext;
21765 popDispatcher(prevDispatcher);
21766
21767 {
21768 popInteractions(prevInteractions);
21769 }
21770
21771 if (workInProgressRootExitStatus === RootFatalErrored) {
21772 var fatalError = workInProgressRootFatalError;
21773 stopInterruptedWorkLoopTimer();
21774 prepareFreshStack(root, expirationTime);
21775 markRootSuspendedAtTime(root, expirationTime);
21776 ensureRootIsScheduled(root);
21777 throw fatalError;
21778 }
21779
21780 if (workInProgress !== null) {
21781 // This is a sync render, so we should have finished the whole tree.
21782 {
21783 {
21784 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
21785 }
21786 }
21787 } else {
21788 // We now have a consistent tree. Because this is a sync render, we
21789 // will commit it even if something suspended.
21790 stopFinishedWorkLoopTimer();
21791 root.finishedWork = root.current.alternate;
21792 root.finishedExpirationTime = expirationTime;
21793 finishSyncRender(root);
21794 } // Before exiting, make sure there's a callback scheduled for the next
21795 // pending level.
21796
21797
21798 ensureRootIsScheduled(root);
21799 }
21800
21801 return null;
21802}
21803
21804function finishSyncRender(root) {
21805 // Set this to null to indicate there's no in-progress render.
21806 workInProgressRoot = null;
21807 commitRoot(root);
21808}
21809function flushDiscreteUpdates() {
21810 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
21811 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
21812 // those two cases. Need to fix this before exposing flushDiscreteUpdates
21813 // as a public API.
21814 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {
21815 {
21816 if ((executionContext & RenderContext) !== NoContext) {
21817 error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');
21818 }
21819 } // We're already rendering, so we can't synchronously flush pending work.
21820 // This is probably a nested event dispatch triggered by a lifecycle/effect,
21821 // like `el.focus()`. Exit.
21822
21823
21824 return;
21825 }
21826
21827 flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that
21828 // they fire before the next serial event.
21829
21830 flushPassiveEffects();
21831}
21832function syncUpdates(fn, a, b, c) {
21833 return runWithPriority$1(ImmediatePriority, fn.bind(null, a, b, c));
21834}
21835
21836function flushPendingDiscreteUpdates() {
21837 if (rootsWithPendingDiscreteUpdates !== null) {
21838 // For each root with pending discrete updates, schedule a callback to
21839 // immediately flush them.
21840 var roots = rootsWithPendingDiscreteUpdates;
21841 rootsWithPendingDiscreteUpdates = null;
21842 roots.forEach(function (expirationTime, root) {
21843 markRootExpiredAtTime(root, expirationTime);
21844 ensureRootIsScheduled(root);
21845 }); // Now flush the immediate queue.
21846
21847 flushSyncCallbackQueue();
21848 }
21849}
21850
21851function batchedUpdates$1(fn, a) {
21852 var prevExecutionContext = executionContext;
21853 executionContext |= BatchedContext;
21854
21855 try {
21856 return fn(a);
21857 } finally {
21858 executionContext = prevExecutionContext;
21859
21860 if (executionContext === NoContext) {
21861 // Flush the immediate callbacks that were scheduled during this batch
21862 flushSyncCallbackQueue();
21863 }
21864 }
21865}
21866function batchedEventUpdates$1(fn, a) {
21867 var prevExecutionContext = executionContext;
21868 executionContext |= EventContext;
21869
21870 try {
21871 return fn(a);
21872 } finally {
21873 executionContext = prevExecutionContext;
21874
21875 if (executionContext === NoContext) {
21876 // Flush the immediate callbacks that were scheduled during this batch
21877 flushSyncCallbackQueue();
21878 }
21879 }
21880}
21881function discreteUpdates$1(fn, a, b, c, d) {
21882 var prevExecutionContext = executionContext;
21883 executionContext |= DiscreteEventContext;
21884
21885 try {
21886 // Should this
21887 return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c, d));
21888 } finally {
21889 executionContext = prevExecutionContext;
21890
21891 if (executionContext === NoContext) {
21892 // Flush the immediate callbacks that were scheduled during this batch
21893 flushSyncCallbackQueue();
21894 }
21895 }
21896}
21897function unbatchedUpdates(fn, a) {
21898 var prevExecutionContext = executionContext;
21899 executionContext &= ~BatchedContext;
21900 executionContext |= LegacyUnbatchedContext;
21901
21902 try {
21903 return fn(a);
21904 } finally {
21905 executionContext = prevExecutionContext;
21906
21907 if (executionContext === NoContext) {
21908 // Flush the immediate callbacks that were scheduled during this batch
21909 flushSyncCallbackQueue();
21910 }
21911 }
21912}
21913function flushSync(fn, a) {
21914 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21915 {
21916 {
21917 throw Error( "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." );
21918 }
21919 }
21920 }
21921
21922 var prevExecutionContext = executionContext;
21923 executionContext |= BatchedContext;
21924
21925 try {
21926 return runWithPriority$1(ImmediatePriority, fn.bind(null, a));
21927 } finally {
21928 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
21929 // Note that this will happen even if batchedUpdates is higher up
21930 // the stack.
21931
21932 flushSyncCallbackQueue();
21933 }
21934}
21935
21936function prepareFreshStack(root, expirationTime) {
21937 root.finishedWork = null;
21938 root.finishedExpirationTime = NoWork;
21939 var timeoutHandle = root.timeoutHandle;
21940
21941 if (timeoutHandle !== noTimeout) {
21942 // The root previous suspended and scheduled a timeout to commit a fallback
21943 // state. Now that we have additional work, cancel the timeout.
21944 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
21945
21946 cancelTimeout(timeoutHandle);
21947 }
21948
21949 if (workInProgress !== null) {
21950 var interruptedWork = workInProgress.return;
21951
21952 while (interruptedWork !== null) {
21953 unwindInterruptedWork(interruptedWork);
21954 interruptedWork = interruptedWork.return;
21955 }
21956 }
21957
21958 workInProgressRoot = root;
21959 workInProgress = createWorkInProgress(root.current, null);
21960 renderExpirationTime$1 = expirationTime;
21961 workInProgressRootExitStatus = RootIncomplete;
21962 workInProgressRootFatalError = null;
21963 workInProgressRootLatestProcessedExpirationTime = Sync;
21964 workInProgressRootLatestSuspenseTimeout = Sync;
21965 workInProgressRootCanSuspendUsingConfig = null;
21966 workInProgressRootNextUnprocessedUpdateTime = NoWork;
21967 workInProgressRootHasPendingPing = false;
21968
21969 {
21970 spawnedWorkDuringRender = null;
21971 }
21972
21973 {
21974 ReactStrictModeWarnings.discardPendingWarnings();
21975 }
21976}
21977
21978function handleError(root, thrownValue) {
21979 do {
21980 try {
21981 // Reset module-level state that was set during the render phase.
21982 resetContextDependencies();
21983 resetHooksAfterThrow();
21984 resetCurrentFiber();
21985
21986 if (workInProgress === null || workInProgress.return === null) {
21987 // Expected to be working on a non-root fiber. This is a fatal error
21988 // because there's no ancestor that can handle it; the root is
21989 // supposed to capture all errors that weren't caught by an error
21990 // boundary.
21991 workInProgressRootExitStatus = RootFatalErrored;
21992 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
21993 // sibling, or the parent if there are no siblings. But since the root
21994 // has no siblings nor a parent, we set it to null. Usually this is
21995 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
21996 // interntionally not calling those, we need set it here.
21997 // TODO: Consider calling `unwindWork` to pop the contexts.
21998
21999 workInProgress = null;
22000 return null;
22001 }
22002
22003 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
22004 // Record the time spent rendering before an error was thrown. This
22005 // avoids inaccurate Profiler durations in the case of a
22006 // suspended render.
22007 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
22008 }
22009
22010 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);
22011 workInProgress = completeUnitOfWork(workInProgress);
22012 } catch (yetAnotherThrownValue) {
22013 // Something in the return path also threw.
22014 thrownValue = yetAnotherThrownValue;
22015 continue;
22016 } // Return to the normal work loop.
22017
22018
22019 return;
22020 } while (true);
22021}
22022
22023function pushDispatcher(root) {
22024 var prevDispatcher = ReactCurrentDispatcher$1.current;
22025 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
22026
22027 if (prevDispatcher === null) {
22028 // The React isomorphic package does not include a default dispatcher.
22029 // Instead the first renderer will lazily attach one, in order to give
22030 // nicer error messages.
22031 return ContextOnlyDispatcher;
22032 } else {
22033 return prevDispatcher;
22034 }
22035}
22036
22037function popDispatcher(prevDispatcher) {
22038 ReactCurrentDispatcher$1.current = prevDispatcher;
22039}
22040
22041function pushInteractions(root) {
22042 {
22043 var prevInteractions = tracing.__interactionsRef.current;
22044 tracing.__interactionsRef.current = root.memoizedInteractions;
22045 return prevInteractions;
22046 }
22047}
22048
22049function popInteractions(prevInteractions) {
22050 {
22051 tracing.__interactionsRef.current = prevInteractions;
22052 }
22053}
22054
22055function markCommitTimeOfFallback() {
22056 globalMostRecentFallbackTime = now();
22057}
22058function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
22059 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
22060 workInProgressRootLatestProcessedExpirationTime = expirationTime;
22061 }
22062
22063 if (suspenseConfig !== null) {
22064 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
22065 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
22066
22067 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
22068 }
22069 }
22070}
22071function markUnprocessedUpdateTime(expirationTime) {
22072 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
22073 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
22074 }
22075}
22076function renderDidSuspend() {
22077 if (workInProgressRootExitStatus === RootIncomplete) {
22078 workInProgressRootExitStatus = RootSuspended;
22079 }
22080}
22081function renderDidSuspendDelayIfPossible() {
22082 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
22083 workInProgressRootExitStatus = RootSuspendedWithDelay;
22084 } // Check if there's a lower priority update somewhere else in the tree.
22085
22086
22087 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
22088 // Mark the current render as suspended, and then mark that there's a
22089 // pending update.
22090 // TODO: This should immediately interrupt the current render, instead
22091 // of waiting until the next time we yield.
22092 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);
22093 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
22094 }
22095}
22096function renderDidError() {
22097 if (workInProgressRootExitStatus !== RootCompleted) {
22098 workInProgressRootExitStatus = RootErrored;
22099 }
22100} // Called during render to determine if anything has suspended.
22101// Returns false if we're not sure.
22102
22103function renderHasNotSuspendedYet() {
22104 // If something errored or completed, we can't really be sure,
22105 // so those are false.
22106 return workInProgressRootExitStatus === RootIncomplete;
22107}
22108
22109function inferTimeFromExpirationTime(expirationTime) {
22110 // We don't know exactly when the update was scheduled, but we can infer an
22111 // approximate start time from the expiration time.
22112 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22113 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
22114}
22115
22116function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
22117 // We don't know exactly when the update was scheduled, but we can infer an
22118 // approximate start time from the expiration time by subtracting the timeout
22119 // that was added to the event time.
22120 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22121 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
22122} // The work loop is an extremely hot path. Tell Closure not to inline it.
22123
22124/** @noinline */
22125
22126
22127function workLoopSync() {
22128 // Already timed out, so perform work without checking if we need to yield.
22129 while (workInProgress !== null) {
22130 workInProgress = performUnitOfWork(workInProgress);
22131 }
22132}
22133/** @noinline */
22134
22135
22136function workLoopConcurrent() {
22137 // Perform work until Scheduler asks us to yield
22138 while (workInProgress !== null && !shouldYield()) {
22139 workInProgress = performUnitOfWork(workInProgress);
22140 }
22141}
22142
22143function performUnitOfWork(unitOfWork) {
22144 // The current, flushed, state of this fiber is the alternate. Ideally
22145 // nothing should rely on this, but relying on it here means that we don't
22146 // need an additional field on the work in progress.
22147 var current = unitOfWork.alternate;
22148 startWorkTimer(unitOfWork);
22149 setCurrentFiber(unitOfWork);
22150 var next;
22151
22152 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
22153 startProfilerTimer(unitOfWork);
22154 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
22155 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
22156 } else {
22157 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
22158 }
22159
22160 resetCurrentFiber();
22161 unitOfWork.memoizedProps = unitOfWork.pendingProps;
22162
22163 if (next === null) {
22164 // If this doesn't spawn new work, complete the current work.
22165 next = completeUnitOfWork(unitOfWork);
22166 }
22167
22168 ReactCurrentOwner$2.current = null;
22169 return next;
22170}
22171
22172function completeUnitOfWork(unitOfWork) {
22173 // Attempt to complete the current unit of work, then move to the next
22174 // sibling. If there are no more siblings, return to the parent fiber.
22175 workInProgress = unitOfWork;
22176
22177 do {
22178 // The current, flushed, state of this fiber is the alternate. Ideally
22179 // nothing should rely on this, but relying on it here means that we don't
22180 // need an additional field on the work in progress.
22181 var current = workInProgress.alternate;
22182 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
22183
22184 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
22185 setCurrentFiber(workInProgress);
22186 var next = void 0;
22187
22188 if ( (workInProgress.mode & ProfileMode) === NoMode) {
22189 next = completeWork(current, workInProgress, renderExpirationTime$1);
22190 } else {
22191 startProfilerTimer(workInProgress);
22192 next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
22193
22194 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
22195 }
22196
22197 stopWorkTimer(workInProgress);
22198 resetCurrentFiber();
22199 resetChildExpirationTime(workInProgress);
22200
22201 if (next !== null) {
22202 // Completing this fiber spawned new work. Work on that next.
22203 return next;
22204 }
22205
22206 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
22207 (returnFiber.effectTag & Incomplete) === NoEffect) {
22208 // Append all the effects of the subtree and this fiber onto the effect
22209 // list of the parent. The completion order of the children affects the
22210 // side-effect order.
22211 if (returnFiber.firstEffect === null) {
22212 returnFiber.firstEffect = workInProgress.firstEffect;
22213 }
22214
22215 if (workInProgress.lastEffect !== null) {
22216 if (returnFiber.lastEffect !== null) {
22217 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
22218 }
22219
22220 returnFiber.lastEffect = workInProgress.lastEffect;
22221 } // If this fiber had side-effects, we append it AFTER the children's
22222 // side-effects. We can perform certain side-effects earlier if needed,
22223 // by doing multiple passes over the effect list. We don't want to
22224 // schedule our own side-effect on our own list because if end up
22225 // reusing children we'll schedule this effect onto itself since we're
22226 // at the end.
22227
22228
22229 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
22230 // list. PerformedWork effect is read by React DevTools but shouldn't be
22231 // committed.
22232
22233 if (effectTag > PerformedWork) {
22234 if (returnFiber.lastEffect !== null) {
22235 returnFiber.lastEffect.nextEffect = workInProgress;
22236 } else {
22237 returnFiber.firstEffect = workInProgress;
22238 }
22239
22240 returnFiber.lastEffect = workInProgress;
22241 }
22242 }
22243 } else {
22244 // This fiber did not complete because something threw. Pop values off
22245 // the stack without entering the complete phase. If this is a boundary,
22246 // capture values if possible.
22247 var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.
22248
22249
22250 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22251 // Record the render duration for the fiber that errored.
22252 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
22253
22254 var actualDuration = workInProgress.actualDuration;
22255 var child = workInProgress.child;
22256
22257 while (child !== null) {
22258 actualDuration += child.actualDuration;
22259 child = child.sibling;
22260 }
22261
22262 workInProgress.actualDuration = actualDuration;
22263 }
22264
22265 if (_next !== null) {
22266 // If completing this work spawned new work, do that next. We'll come
22267 // back here again.
22268 // Since we're restarting, remove anything that is not a host effect
22269 // from the effect tag.
22270 // TODO: The name stopFailedWorkTimer is misleading because Suspense
22271 // also captures and restarts.
22272 stopFailedWorkTimer(workInProgress);
22273 _next.effectTag &= HostEffectMask;
22274 return _next;
22275 }
22276
22277 stopWorkTimer(workInProgress);
22278
22279 if (returnFiber !== null) {
22280 // Mark the parent fiber as incomplete and clear its effect list.
22281 returnFiber.firstEffect = returnFiber.lastEffect = null;
22282 returnFiber.effectTag |= Incomplete;
22283 }
22284 }
22285
22286 var siblingFiber = workInProgress.sibling;
22287
22288 if (siblingFiber !== null) {
22289 // If there is more work to do in this returnFiber, do that next.
22290 return siblingFiber;
22291 } // Otherwise, return to the parent
22292
22293
22294 workInProgress = returnFiber;
22295 } while (workInProgress !== null); // We've reached the root.
22296
22297
22298 if (workInProgressRootExitStatus === RootIncomplete) {
22299 workInProgressRootExitStatus = RootCompleted;
22300 }
22301
22302 return null;
22303}
22304
22305function getRemainingExpirationTime(fiber) {
22306 var updateExpirationTime = fiber.expirationTime;
22307 var childExpirationTime = fiber.childExpirationTime;
22308 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
22309}
22310
22311function resetChildExpirationTime(completedWork) {
22312 if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {
22313 // The children of this component are hidden. Don't bubble their
22314 // expiration times.
22315 return;
22316 }
22317
22318 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
22319
22320 if ( (completedWork.mode & ProfileMode) !== NoMode) {
22321 // In profiling mode, resetChildExpirationTime is also used to reset
22322 // profiler durations.
22323 var actualDuration = completedWork.actualDuration;
22324 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
22325 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
22326 // When work is done, it should bubble to the parent's actualDuration. If
22327 // the fiber has not been cloned though, (meaning no work was done), then
22328 // this value will reflect the amount of time spent working on a previous
22329 // render. In that case it should not bubble. We determine whether it was
22330 // cloned by comparing the child pointer.
22331
22332 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
22333 var child = completedWork.child;
22334
22335 while (child !== null) {
22336 var childUpdateExpirationTime = child.expirationTime;
22337 var childChildExpirationTime = child.childExpirationTime;
22338
22339 if (childUpdateExpirationTime > newChildExpirationTime) {
22340 newChildExpirationTime = childUpdateExpirationTime;
22341 }
22342
22343 if (childChildExpirationTime > newChildExpirationTime) {
22344 newChildExpirationTime = childChildExpirationTime;
22345 }
22346
22347 if (shouldBubbleActualDurations) {
22348 actualDuration += child.actualDuration;
22349 }
22350
22351 treeBaseDuration += child.treeBaseDuration;
22352 child = child.sibling;
22353 }
22354
22355 completedWork.actualDuration = actualDuration;
22356 completedWork.treeBaseDuration = treeBaseDuration;
22357 } else {
22358 var _child = completedWork.child;
22359
22360 while (_child !== null) {
22361 var _childUpdateExpirationTime = _child.expirationTime;
22362 var _childChildExpirationTime = _child.childExpirationTime;
22363
22364 if (_childUpdateExpirationTime > newChildExpirationTime) {
22365 newChildExpirationTime = _childUpdateExpirationTime;
22366 }
22367
22368 if (_childChildExpirationTime > newChildExpirationTime) {
22369 newChildExpirationTime = _childChildExpirationTime;
22370 }
22371
22372 _child = _child.sibling;
22373 }
22374 }
22375
22376 completedWork.childExpirationTime = newChildExpirationTime;
22377}
22378
22379function commitRoot(root) {
22380 var renderPriorityLevel = getCurrentPriorityLevel();
22381 runWithPriority$1(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
22382 return null;
22383}
22384
22385function commitRootImpl(root, renderPriorityLevel) {
22386 do {
22387 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
22388 // means `flushPassiveEffects` will sometimes result in additional
22389 // passive effects. So we need to keep flushing in a loop until there are
22390 // no more pending effects.
22391 // TODO: Might be better if `flushPassiveEffects` did not automatically
22392 // flush synchronous work at the end, to avoid factoring hazards like this.
22393 flushPassiveEffects();
22394 } while (rootWithPendingPassiveEffects !== null);
22395
22396 flushRenderPhaseStrictModeWarningsInDEV();
22397
22398 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22399 {
22400 throw Error( "Should not already be working." );
22401 }
22402 }
22403
22404 var finishedWork = root.finishedWork;
22405 var expirationTime = root.finishedExpirationTime;
22406
22407 if (finishedWork === null) {
22408 return null;
22409 }
22410
22411 root.finishedWork = null;
22412 root.finishedExpirationTime = NoWork;
22413
22414 if (!(finishedWork !== root.current)) {
22415 {
22416 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
22417 }
22418 } // commitRoot never returns a continuation; it always finishes synchronously.
22419 // So we can clear these now to allow a new callback to be scheduled.
22420
22421
22422 root.callbackNode = null;
22423 root.callbackExpirationTime = NoWork;
22424 root.callbackPriority = NoPriority;
22425 root.nextKnownPendingLevel = NoWork;
22426 startCommitTimer(); // Update the first and last pending times on this root. The new first
22427 // pending time is whatever is left on the root fiber.
22428
22429 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
22430 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
22431
22432 if (root === workInProgressRoot) {
22433 // We can reset these now that they are finished.
22434 workInProgressRoot = null;
22435 workInProgress = null;
22436 renderExpirationTime$1 = NoWork;
22437 } // This indicates that the last root we worked on is not the same one that
22438 // we're committing now. This most commonly happens when a suspended root
22439 // times out.
22440 // Get the list of effects.
22441
22442
22443 var firstEffect;
22444
22445 if (finishedWork.effectTag > PerformedWork) {
22446 // A fiber's effect list consists only of its children, not itself. So if
22447 // the root has an effect, we need to add it to the end of the list. The
22448 // resulting list is the set that would belong to the root's parent, if it
22449 // had one; that is, all the effects in the tree including the root.
22450 if (finishedWork.lastEffect !== null) {
22451 finishedWork.lastEffect.nextEffect = finishedWork;
22452 firstEffect = finishedWork.firstEffect;
22453 } else {
22454 firstEffect = finishedWork;
22455 }
22456 } else {
22457 // There is no effect on the root.
22458 firstEffect = finishedWork.firstEffect;
22459 }
22460
22461 if (firstEffect !== null) {
22462 var prevExecutionContext = executionContext;
22463 executionContext |= CommitContext;
22464 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
22465
22466 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
22467 // of the effect list for each phase: all mutation effects come before all
22468 // layout effects, and so on.
22469 // The first phase a "before mutation" phase. We use this phase to read the
22470 // state of the host tree right before we mutate it. This is where
22471 // getSnapshotBeforeUpdate is called.
22472
22473 startCommitSnapshotEffectsTimer();
22474 prepareForCommit(root.containerInfo);
22475 nextEffect = firstEffect;
22476
22477 do {
22478 {
22479 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
22480
22481 if (hasCaughtError()) {
22482 if (!(nextEffect !== null)) {
22483 {
22484 throw Error( "Should be working on an effect." );
22485 }
22486 }
22487
22488 var error = clearCaughtError();
22489 captureCommitPhaseError(nextEffect, error);
22490 nextEffect = nextEffect.nextEffect;
22491 }
22492 }
22493 } while (nextEffect !== null);
22494
22495 stopCommitSnapshotEffectsTimer();
22496
22497 {
22498 // Mark the current commit time to be shared by all Profilers in this
22499 // batch. This enables them to be grouped later.
22500 recordCommitTime();
22501 } // The next phase is the mutation phase, where we mutate the host tree.
22502
22503
22504 startCommitHostEffectsTimer();
22505 nextEffect = firstEffect;
22506
22507 do {
22508 {
22509 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
22510
22511 if (hasCaughtError()) {
22512 if (!(nextEffect !== null)) {
22513 {
22514 throw Error( "Should be working on an effect." );
22515 }
22516 }
22517
22518 var _error = clearCaughtError();
22519
22520 captureCommitPhaseError(nextEffect, _error);
22521 nextEffect = nextEffect.nextEffect;
22522 }
22523 }
22524 } while (nextEffect !== null);
22525
22526 stopCommitHostEffectsTimer();
22527 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
22528 // the mutation phase, so that the previous tree is still current during
22529 // componentWillUnmount, but before the layout phase, so that the finished
22530 // work is current during componentDidMount/Update.
22531
22532 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
22533 // the host tree after it's been mutated. The idiomatic use case for this is
22534 // layout, but class component lifecycles also fire here for legacy reasons.
22535
22536 startCommitLifeCyclesTimer();
22537 nextEffect = firstEffect;
22538
22539 do {
22540 {
22541 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
22542
22543 if (hasCaughtError()) {
22544 if (!(nextEffect !== null)) {
22545 {
22546 throw Error( "Should be working on an effect." );
22547 }
22548 }
22549
22550 var _error2 = clearCaughtError();
22551
22552 captureCommitPhaseError(nextEffect, _error2);
22553 nextEffect = nextEffect.nextEffect;
22554 }
22555 }
22556 } while (nextEffect !== null);
22557
22558 stopCommitLifeCyclesTimer();
22559 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
22560 // opportunity to paint.
22561
22562 requestPaint();
22563
22564 {
22565 popInteractions(prevInteractions);
22566 }
22567
22568 executionContext = prevExecutionContext;
22569 } else {
22570 // No effects.
22571 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
22572 // no effects.
22573 // TODO: Maybe there's a better way to report this.
22574
22575 startCommitSnapshotEffectsTimer();
22576 stopCommitSnapshotEffectsTimer();
22577
22578 {
22579 recordCommitTime();
22580 }
22581
22582 startCommitHostEffectsTimer();
22583 stopCommitHostEffectsTimer();
22584 startCommitLifeCyclesTimer();
22585 stopCommitLifeCyclesTimer();
22586 }
22587
22588 stopCommitTimer();
22589 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
22590
22591 if (rootDoesHavePassiveEffects) {
22592 // This commit has passive effects. Stash a reference to them. But don't
22593 // schedule a callback until after flushing layout work.
22594 rootDoesHavePassiveEffects = false;
22595 rootWithPendingPassiveEffects = root;
22596 pendingPassiveEffectsExpirationTime = expirationTime;
22597 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
22598 } else {
22599 // We are done with the effect chain at this point so let's clear the
22600 // nextEffect pointers to assist with GC. If we have passive effects, we'll
22601 // clear this in flushPassiveEffects.
22602 nextEffect = firstEffect;
22603
22604 while (nextEffect !== null) {
22605 var nextNextEffect = nextEffect.nextEffect;
22606 nextEffect.nextEffect = null;
22607 nextEffect = nextNextEffect;
22608 }
22609 } // Check if there's remaining work on this root
22610
22611
22612 var remainingExpirationTime = root.firstPendingTime;
22613
22614 if (remainingExpirationTime !== NoWork) {
22615 {
22616 if (spawnedWorkDuringRender !== null) {
22617 var expirationTimes = spawnedWorkDuringRender;
22618 spawnedWorkDuringRender = null;
22619
22620 for (var i = 0; i < expirationTimes.length; i++) {
22621 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
22622 }
22623 }
22624
22625 schedulePendingInteractions(root, remainingExpirationTime);
22626 }
22627 } else {
22628 // If there's no remaining work, we can clear the set of already failed
22629 // error boundaries.
22630 legacyErrorBoundariesThatAlreadyFailed = null;
22631 }
22632
22633 {
22634 if (!rootDidHavePassiveEffects) {
22635 // If there are no passive effects, then we can complete the pending interactions.
22636 // Otherwise, we'll wait until after the passive effects are flushed.
22637 // Wait to do this until after remaining work has been scheduled,
22638 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
22639 finishPendingInteractions(root, expirationTime);
22640 }
22641 }
22642
22643 if (remainingExpirationTime === Sync) {
22644 // Count the number of times the root synchronously re-renders without
22645 // finishing. If there are too many, it indicates an infinite update loop.
22646 if (root === rootWithNestedUpdates) {
22647 nestedUpdateCount++;
22648 } else {
22649 nestedUpdateCount = 0;
22650 rootWithNestedUpdates = root;
22651 }
22652 } else {
22653 nestedUpdateCount = 0;
22654 }
22655
22656 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
22657 // additional work on this root is scheduled.
22658
22659 ensureRootIsScheduled(root);
22660
22661 if (hasUncaughtError) {
22662 hasUncaughtError = false;
22663 var _error3 = firstUncaughtError;
22664 firstUncaughtError = null;
22665 throw _error3;
22666 }
22667
22668 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
22669 // This is a legacy edge case. We just committed the initial mount of
22670 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
22671 // synchronously, but layout updates should be deferred until the end
22672 // of the batch.
22673 return null;
22674 } // If layout work was scheduled, flush it now.
22675
22676
22677 flushSyncCallbackQueue();
22678 return null;
22679}
22680
22681function commitBeforeMutationEffects() {
22682 while (nextEffect !== null) {
22683 var effectTag = nextEffect.effectTag;
22684
22685 if ((effectTag & Snapshot) !== NoEffect) {
22686 setCurrentFiber(nextEffect);
22687 recordEffect();
22688 var current = nextEffect.alternate;
22689 commitBeforeMutationLifeCycles(current, nextEffect);
22690 resetCurrentFiber();
22691 }
22692
22693 if ((effectTag & Passive) !== NoEffect) {
22694 // If there are passive effects, schedule a callback to flush at
22695 // the earliest opportunity.
22696 if (!rootDoesHavePassiveEffects) {
22697 rootDoesHavePassiveEffects = true;
22698 scheduleCallback(NormalPriority, function () {
22699 flushPassiveEffects();
22700 return null;
22701 });
22702 }
22703 }
22704
22705 nextEffect = nextEffect.nextEffect;
22706 }
22707}
22708
22709function commitMutationEffects(root, renderPriorityLevel) {
22710 // TODO: Should probably move the bulk of this function to commitWork.
22711 while (nextEffect !== null) {
22712 setCurrentFiber(nextEffect);
22713 var effectTag = nextEffect.effectTag;
22714
22715 if (effectTag & ContentReset) {
22716 commitResetTextContent(nextEffect);
22717 }
22718
22719 if (effectTag & Ref) {
22720 var current = nextEffect.alternate;
22721
22722 if (current !== null) {
22723 commitDetachRef(current);
22724 }
22725 } // The following switch statement is only concerned about placement,
22726 // updates, and deletions. To avoid needing to add a case for every possible
22727 // bitmap value, we remove the secondary effects from the effect tag and
22728 // switch on that value.
22729
22730
22731 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
22732
22733 switch (primaryEffectTag) {
22734 case Placement:
22735 {
22736 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
22737 // inserted, before any life-cycles like componentDidMount gets called.
22738 // TODO: findDOMNode doesn't rely on this any more but isMounted does
22739 // and isMounted is deprecated anyway so we should be able to kill this.
22740
22741 nextEffect.effectTag &= ~Placement;
22742 break;
22743 }
22744
22745 case PlacementAndUpdate:
22746 {
22747 // Placement
22748 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
22749 // inserted, before any life-cycles like componentDidMount gets called.
22750
22751 nextEffect.effectTag &= ~Placement; // Update
22752
22753 var _current = nextEffect.alternate;
22754 commitWork(_current, nextEffect);
22755 break;
22756 }
22757
22758 case Hydrating:
22759 {
22760 nextEffect.effectTag &= ~Hydrating;
22761 break;
22762 }
22763
22764 case HydratingAndUpdate:
22765 {
22766 nextEffect.effectTag &= ~Hydrating; // Update
22767
22768 var _current2 = nextEffect.alternate;
22769 commitWork(_current2, nextEffect);
22770 break;
22771 }
22772
22773 case Update:
22774 {
22775 var _current3 = nextEffect.alternate;
22776 commitWork(_current3, nextEffect);
22777 break;
22778 }
22779
22780 case Deletion:
22781 {
22782 commitDeletion(root, nextEffect, renderPriorityLevel);
22783 break;
22784 }
22785 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
22786
22787
22788 recordEffect();
22789 resetCurrentFiber();
22790 nextEffect = nextEffect.nextEffect;
22791 }
22792}
22793
22794function commitLayoutEffects(root, committedExpirationTime) {
22795 // TODO: Should probably move the bulk of this function to commitWork.
22796 while (nextEffect !== null) {
22797 setCurrentFiber(nextEffect);
22798 var effectTag = nextEffect.effectTag;
22799
22800 if (effectTag & (Update | Callback)) {
22801 recordEffect();
22802 var current = nextEffect.alternate;
22803 commitLifeCycles(root, current, nextEffect);
22804 }
22805
22806 if (effectTag & Ref) {
22807 recordEffect();
22808 commitAttachRef(nextEffect);
22809 }
22810
22811 resetCurrentFiber();
22812 nextEffect = nextEffect.nextEffect;
22813 }
22814}
22815
22816function flushPassiveEffects() {
22817 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
22818 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
22819 pendingPassiveEffectsRenderPriority = NoPriority;
22820 return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);
22821 }
22822}
22823
22824function flushPassiveEffectsImpl() {
22825 if (rootWithPendingPassiveEffects === null) {
22826 return false;
22827 }
22828
22829 var root = rootWithPendingPassiveEffects;
22830 var expirationTime = pendingPassiveEffectsExpirationTime;
22831 rootWithPendingPassiveEffects = null;
22832 pendingPassiveEffectsExpirationTime = NoWork;
22833
22834 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22835 {
22836 throw Error( "Cannot flush passive effects while already rendering." );
22837 }
22838 }
22839
22840 var prevExecutionContext = executionContext;
22841 executionContext |= CommitContext;
22842 var prevInteractions = pushInteractions(root);
22843
22844 {
22845 // Note: This currently assumes there are no passive effects on the root fiber
22846 // because the root is not part of its own effect list.
22847 // This could change in the future.
22848 var _effect2 = root.current.firstEffect;
22849
22850 while (_effect2 !== null) {
22851 {
22852 setCurrentFiber(_effect2);
22853 invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
22854
22855 if (hasCaughtError()) {
22856 if (!(_effect2 !== null)) {
22857 {
22858 throw Error( "Should be working on an effect." );
22859 }
22860 }
22861
22862 var _error5 = clearCaughtError();
22863
22864 captureCommitPhaseError(_effect2, _error5);
22865 }
22866
22867 resetCurrentFiber();
22868 }
22869
22870 var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC
22871
22872 _effect2.nextEffect = null;
22873 _effect2 = nextNextEffect;
22874 }
22875 }
22876
22877 {
22878 popInteractions(prevInteractions);
22879 finishPendingInteractions(root, expirationTime);
22880 }
22881
22882 executionContext = prevExecutionContext;
22883 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
22884 // exceeds the limit, we'll fire a warning.
22885
22886 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
22887 return true;
22888}
22889
22890function isAlreadyFailedLegacyErrorBoundary(instance) {
22891 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
22892}
22893function markLegacyErrorBoundaryAsFailed(instance) {
22894 if (legacyErrorBoundariesThatAlreadyFailed === null) {
22895 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
22896 } else {
22897 legacyErrorBoundariesThatAlreadyFailed.add(instance);
22898 }
22899}
22900
22901function prepareToThrowUncaughtError(error) {
22902 if (!hasUncaughtError) {
22903 hasUncaughtError = true;
22904 firstUncaughtError = error;
22905 }
22906}
22907
22908var onUncaughtError = prepareToThrowUncaughtError;
22909
22910function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
22911 var errorInfo = createCapturedValue(error, sourceFiber);
22912 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
22913 enqueueUpdate(rootFiber, update);
22914 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
22915
22916 if (root !== null) {
22917 ensureRootIsScheduled(root);
22918 schedulePendingInteractions(root, Sync);
22919 }
22920}
22921
22922function captureCommitPhaseError(sourceFiber, error) {
22923 if (sourceFiber.tag === HostRoot) {
22924 // Error was thrown at the root. There is no parent, so the root
22925 // itself should capture it.
22926 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
22927 return;
22928 }
22929
22930 var fiber = sourceFiber.return;
22931
22932 while (fiber !== null) {
22933 if (fiber.tag === HostRoot) {
22934 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
22935 return;
22936 } else if (fiber.tag === ClassComponent) {
22937 var ctor = fiber.type;
22938 var instance = fiber.stateNode;
22939
22940 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
22941 var errorInfo = createCapturedValue(error, sourceFiber);
22942 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
22943 Sync);
22944 enqueueUpdate(fiber, update);
22945 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
22946
22947 if (root !== null) {
22948 ensureRootIsScheduled(root);
22949 schedulePendingInteractions(root, Sync);
22950 }
22951
22952 return;
22953 }
22954 }
22955
22956 fiber = fiber.return;
22957 }
22958}
22959function pingSuspendedRoot(root, thenable, suspendedTime) {
22960 var pingCache = root.pingCache;
22961
22962 if (pingCache !== null) {
22963 // The thenable resolved, so we no longer need to memoize, because it will
22964 // never be thrown again.
22965 pingCache.delete(thenable);
22966 }
22967
22968 if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {
22969 // Received a ping at the same priority level at which we're currently
22970 // rendering. We might want to restart this render. This should mirror
22971 // the logic of whether or not a root suspends once it completes.
22972 // TODO: If we're rendering sync either due to Sync, Batched or expired,
22973 // we should probably never restart.
22974 // If we're suspended with delay, we'll always suspend so we can always
22975 // restart. If we're suspended without any updates, it might be a retry.
22976 // If it's early in the retry we can restart. We can't know for sure
22977 // whether we'll eventually process an update during this render pass,
22978 // but it's somewhat unlikely that we get to a ping before that, since
22979 // getting to the root most update is usually very fast.
22980 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
22981 // Restart from the root. Don't need to schedule a ping because
22982 // we're already working on this tree.
22983 prepareFreshStack(root, renderExpirationTime$1);
22984 } else {
22985 // Even though we can't restart right now, we might get an
22986 // opportunity later. So we mark this render as having a ping.
22987 workInProgressRootHasPendingPing = true;
22988 }
22989
22990 return;
22991 }
22992
22993 if (!isRootSuspendedAtTime(root, suspendedTime)) {
22994 // The root is no longer suspended at this time.
22995 return;
22996 }
22997
22998 var lastPingedTime = root.lastPingedTime;
22999
23000 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
23001 // There's already a lower priority ping scheduled.
23002 return;
23003 } // Mark the time at which this ping was scheduled.
23004
23005
23006 root.lastPingedTime = suspendedTime;
23007
23008 ensureRootIsScheduled(root);
23009 schedulePendingInteractions(root, suspendedTime);
23010}
23011
23012function retryTimedOutBoundary(boundaryFiber, retryTime) {
23013 // The boundary fiber (a Suspense component or SuspenseList component)
23014 // previously was rendered in its fallback state. One of the promises that
23015 // suspended it has resolved, which means at least part of the tree was
23016 // likely unblocked. Try rendering again, at a new expiration time.
23017 if (retryTime === NoWork) {
23018 var suspenseConfig = null; // Retries don't carry over the already committed update.
23019
23020 var currentTime = requestCurrentTimeForUpdate();
23021 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
23022 } // TODO: Special case idle priority?
23023
23024
23025 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
23026
23027 if (root !== null) {
23028 ensureRootIsScheduled(root);
23029 schedulePendingInteractions(root, retryTime);
23030 }
23031}
23032function resolveRetryThenable(boundaryFiber, thenable) {
23033 var retryTime = NoWork; // Default
23034
23035 var retryCache;
23036
23037 {
23038 retryCache = boundaryFiber.stateNode;
23039 }
23040
23041 if (retryCache !== null) {
23042 // The thenable resolved, so we no longer need to memoize, because it will
23043 // never be thrown again.
23044 retryCache.delete(thenable);
23045 }
23046
23047 retryTimedOutBoundary(boundaryFiber, retryTime);
23048} // Computes the next Just Noticeable Difference (JND) boundary.
23049// The theory is that a person can't tell the difference between small differences in time.
23050// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
23051// difference in the experience. However, waiting for longer might mean that we can avoid
23052// showing an intermediate loading state. The longer we have already waited, the harder it
23053// is to tell small differences in time. Therefore, the longer we've already waited,
23054// the longer we can wait additionally. At some point we have to give up though.
23055// We pick a train model where the next boundary commits at a consistent schedule.
23056// These particular numbers are vague estimates. We expect to adjust them based on research.
23057
23058function jnd(timeElapsed) {
23059 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
23060}
23061
23062function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
23063 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
23064
23065 if (busyMinDurationMs <= 0) {
23066 return 0;
23067 }
23068
23069 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
23070
23071 var currentTimeMs = now();
23072 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
23073 var timeElapsed = currentTimeMs - eventTimeMs;
23074
23075 if (timeElapsed <= busyDelayMs) {
23076 // If we haven't yet waited longer than the initial delay, we don't
23077 // have to wait any additional time.
23078 return 0;
23079 }
23080
23081 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
23082
23083 return msUntilTimeout;
23084}
23085
23086function checkForNestedUpdates() {
23087 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
23088 nestedUpdateCount = 0;
23089 rootWithNestedUpdates = null;
23090
23091 {
23092 {
23093 throw Error( "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." );
23094 }
23095 }
23096 }
23097
23098 {
23099 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
23100 nestedPassiveUpdateCount = 0;
23101
23102 error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
23103 }
23104 }
23105}
23106
23107function flushRenderPhaseStrictModeWarningsInDEV() {
23108 {
23109 ReactStrictModeWarnings.flushLegacyContextWarning();
23110
23111 {
23112 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
23113 }
23114 }
23115}
23116
23117function stopFinishedWorkLoopTimer() {
23118 var didCompleteRoot = true;
23119 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23120 interruptedBy = null;
23121}
23122
23123function stopInterruptedWorkLoopTimer() {
23124 // TODO: Track which fiber caused the interruption.
23125 var didCompleteRoot = false;
23126 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23127 interruptedBy = null;
23128}
23129
23130function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
23131 if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {
23132 interruptedBy = fiberThatReceivedUpdate;
23133 }
23134}
23135
23136var didWarnStateUpdateForUnmountedComponent = null;
23137
23138function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
23139 {
23140 var tag = fiber.tag;
23141
23142 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
23143 // Only warn for user-defined components, not internal ones like Suspense.
23144 return;
23145 }
23146 // the problematic code almost always lies inside that component.
23147
23148
23149 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23150
23151 if (didWarnStateUpdateForUnmountedComponent !== null) {
23152 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
23153 return;
23154 }
23155
23156 didWarnStateUpdateForUnmountedComponent.add(componentName);
23157 } else {
23158 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
23159 }
23160
23161 error("Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
23162 }
23163}
23164
23165var beginWork$1;
23166
23167{
23168 var dummyFiber = null;
23169
23170 beginWork$1 = function (current, unitOfWork, expirationTime) {
23171 // If a component throws an error, we replay it again in a synchronously
23172 // dispatched event, so that the debugger will treat it as an uncaught
23173 // error See ReactErrorUtils for more information.
23174 // Before entering the begin phase, copy the work-in-progress onto a dummy
23175 // fiber. If beginWork throws, we'll use this to reset the state.
23176 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
23177
23178 try {
23179 return beginWork(current, unitOfWork, expirationTime);
23180 } catch (originalError) {
23181 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
23182 // Don't replay promises. Treat everything else like an error.
23183 throw originalError;
23184 } // Keep this code in sync with handleError; any changes here must have
23185 // corresponding changes there.
23186
23187
23188 resetContextDependencies();
23189 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
23190 // same fiber again.
23191 // Unwind the failed stack frame
23192
23193 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
23194
23195 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
23196
23197 if ( unitOfWork.mode & ProfileMode) {
23198 // Reset the profiler timer.
23199 startProfilerTimer(unitOfWork);
23200 } // Run beginWork again.
23201
23202
23203 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, expirationTime);
23204
23205 if (hasCaughtError()) {
23206 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
23207 // Rethrow this error instead of the original one.
23208
23209 throw replayError;
23210 } else {
23211 // This branch is reachable if the render phase is impure.
23212 throw originalError;
23213 }
23214 }
23215 };
23216}
23217
23218var didWarnAboutUpdateInRender = false;
23219var didWarnAboutUpdateInRenderForAnotherComponent;
23220
23221{
23222 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
23223}
23224
23225function warnAboutRenderPhaseUpdatesInDEV(fiber) {
23226 {
23227 if (isRendering && (executionContext & RenderContext) !== NoContext) {
23228 switch (fiber.tag) {
23229 case FunctionComponent:
23230 case ForwardRef:
23231 case SimpleMemoComponent:
23232 {
23233 var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
23234
23235 var dedupeKey = renderingComponentName;
23236
23237 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
23238 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
23239 var setStateComponentName = getComponentName(fiber.type) || 'Unknown';
23240
23241 error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://fb.me/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
23242 }
23243
23244 break;
23245 }
23246
23247 case ClassComponent:
23248 {
23249 if (!didWarnAboutUpdateInRender) {
23250 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
23251
23252 didWarnAboutUpdateInRender = true;
23253 }
23254
23255 break;
23256 }
23257 }
23258 }
23259 }
23260} // a 'shared' variable that changes when act() opens/closes in tests.
23261
23262
23263var IsThisRendererActing = {
23264 current: false
23265};
23266function warnIfNotScopedWithMatchingAct(fiber) {
23267 {
23268 if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
23269 error("It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + "import {act} from 'react-dom/test-utils';\n" + '// ...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + "import TestRenderer from 'react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '// ...\n' + 'act(() => ...);' + '%s', getStackByFiberInDevAndProd(fiber));
23270 }
23271 }
23272}
23273function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
23274 {
23275 if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23276 error('An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
23277 }
23278 }
23279}
23280
23281function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
23282 {
23283 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23284 error('An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
23285 }
23286 }
23287}
23288
23289var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
23290
23291var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
23292// scheduler is the actual recommendation. The alternative could be a testing build,
23293// a new lib, or whatever; we dunno just yet. This message is for early adopters
23294// to get their tests right.
23295
23296function warnIfUnmockedScheduler(fiber) {
23297 {
23298 if (didWarnAboutUnmockedScheduler === false && Scheduler.unstable_flushAllWithoutAsserting === undefined) {
23299 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
23300 didWarnAboutUnmockedScheduler = true;
23301
23302 error('In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
23303 }
23304 }
23305 }
23306}
23307
23308function computeThreadID(root, expirationTime) {
23309 // Interaction threads are unique per root and expiration time.
23310 return expirationTime * 1000 + root.interactionThreadID;
23311}
23312
23313function markSpawnedWork(expirationTime) {
23314
23315 if (spawnedWorkDuringRender === null) {
23316 spawnedWorkDuringRender = [expirationTime];
23317 } else {
23318 spawnedWorkDuringRender.push(expirationTime);
23319 }
23320}
23321
23322function scheduleInteractions(root, expirationTime, interactions) {
23323
23324 if (interactions.size > 0) {
23325 var pendingInteractionMap = root.pendingInteractionMap;
23326 var pendingInteractions = pendingInteractionMap.get(expirationTime);
23327
23328 if (pendingInteractions != null) {
23329 interactions.forEach(function (interaction) {
23330 if (!pendingInteractions.has(interaction)) {
23331 // Update the pending async work count for previously unscheduled interaction.
23332 interaction.__count++;
23333 }
23334
23335 pendingInteractions.add(interaction);
23336 });
23337 } else {
23338 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
23339
23340 interactions.forEach(function (interaction) {
23341 interaction.__count++;
23342 });
23343 }
23344
23345 var subscriber = tracing.__subscriberRef.current;
23346
23347 if (subscriber !== null) {
23348 var threadID = computeThreadID(root, expirationTime);
23349 subscriber.onWorkScheduled(interactions, threadID);
23350 }
23351 }
23352}
23353
23354function schedulePendingInteractions(root, expirationTime) {
23355
23356 scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current);
23357}
23358
23359function startWorkOnPendingInteractions(root, expirationTime) {
23360 // we can accurately attribute time spent working on it, And so that cascading
23361 // work triggered during the render phase will be associated with it.
23362
23363
23364 var interactions = new Set();
23365 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23366 if (scheduledExpirationTime >= expirationTime) {
23367 scheduledInteractions.forEach(function (interaction) {
23368 return interactions.add(interaction);
23369 });
23370 }
23371 }); // Store the current set of interactions on the FiberRoot for a few reasons:
23372 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
23373 // without having to recalculate it. We will also use it in commitWork() to
23374 // pass to any Profiler onRender() hooks. This also provides DevTools with a
23375 // way to access it when the onCommitRoot() hook is called.
23376
23377 root.memoizedInteractions = interactions;
23378
23379 if (interactions.size > 0) {
23380 var subscriber = tracing.__subscriberRef.current;
23381
23382 if (subscriber !== null) {
23383 var threadID = computeThreadID(root, expirationTime);
23384
23385 try {
23386 subscriber.onWorkStarted(interactions, threadID);
23387 } catch (error) {
23388 // If the subscriber throws, rethrow it in a separate task
23389 scheduleCallback(ImmediatePriority, function () {
23390 throw error;
23391 });
23392 }
23393 }
23394 }
23395}
23396
23397function finishPendingInteractions(root, committedExpirationTime) {
23398
23399 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
23400 var subscriber;
23401
23402 try {
23403 subscriber = tracing.__subscriberRef.current;
23404
23405 if (subscriber !== null && root.memoizedInteractions.size > 0) {
23406 var threadID = computeThreadID(root, committedExpirationTime);
23407 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
23408 }
23409 } catch (error) {
23410 // If the subscriber throws, rethrow it in a separate task
23411 scheduleCallback(ImmediatePriority, function () {
23412 throw error;
23413 });
23414 } finally {
23415 // Clear completed interactions from the pending Map.
23416 // Unless the render was suspended or cascading work was scheduled,
23417 // In which case– leave pending interactions until the subsequent render.
23418 var pendingInteractionMap = root.pendingInteractionMap;
23419 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23420 // Only decrement the pending interaction count if we're done.
23421 // If there's still work at the current priority,
23422 // That indicates that we are waiting for suspense data.
23423 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
23424 pendingInteractionMap.delete(scheduledExpirationTime);
23425 scheduledInteractions.forEach(function (interaction) {
23426 interaction.__count--;
23427
23428 if (subscriber !== null && interaction.__count === 0) {
23429 try {
23430 subscriber.onInteractionScheduledWorkCompleted(interaction);
23431 } catch (error) {
23432 // If the subscriber throws, rethrow it in a separate task
23433 scheduleCallback(ImmediatePriority, function () {
23434 throw error;
23435 });
23436 }
23437 }
23438 });
23439 }
23440 });
23441 }
23442}
23443
23444var onScheduleFiberRoot = null;
23445var onCommitFiberRoot = null;
23446var onCommitFiberUnmount = null;
23447var hasLoggedError = false;
23448var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
23449function injectInternals(internals) {
23450 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
23451 // No DevTools
23452 return false;
23453 }
23454
23455 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
23456
23457 if (hook.isDisabled) {
23458 // This isn't a real property on the hook, but it can be set to opt out
23459 // of DevTools integration and associated warnings and logs.
23460 // https://github.com/facebook/react/issues/3877
23461 return true;
23462 }
23463
23464 if (!hook.supportsFiber) {
23465 {
23466 error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');
23467 } // DevTools exists, even though it doesn't support Fiber.
23468
23469
23470 return true;
23471 }
23472
23473 try {
23474 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
23475
23476 if (true) {
23477 // Only used by Fast Refresh
23478 if (typeof hook.onScheduleFiberRoot === 'function') {
23479 onScheduleFiberRoot = function (root, children) {
23480 try {
23481 hook.onScheduleFiberRoot(rendererID, root, children);
23482 } catch (err) {
23483 if (true && !hasLoggedError) {
23484 hasLoggedError = true;
23485
23486 error('React instrumentation encountered an error: %s', err);
23487 }
23488 }
23489 };
23490 }
23491 }
23492
23493 onCommitFiberRoot = function (root, expirationTime) {
23494 try {
23495 var didError = (root.current.effectTag & DidCapture) === DidCapture;
23496
23497 if (enableProfilerTimer) {
23498 var currentTime = getCurrentTime();
23499 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
23500 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
23501 } else {
23502 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
23503 }
23504 } catch (err) {
23505 if (true) {
23506 if (!hasLoggedError) {
23507 hasLoggedError = true;
23508
23509 error('React instrumentation encountered an error: %s', err);
23510 }
23511 }
23512 }
23513 };
23514
23515 onCommitFiberUnmount = function (fiber) {
23516 try {
23517 hook.onCommitFiberUnmount(rendererID, fiber);
23518 } catch (err) {
23519 if (true) {
23520 if (!hasLoggedError) {
23521 hasLoggedError = true;
23522
23523 error('React instrumentation encountered an error: %s', err);
23524 }
23525 }
23526 }
23527 };
23528 } catch (err) {
23529 // Catch all errors because it is unsafe to throw during initialization.
23530 {
23531 error('React instrumentation encountered an error: %s.', err);
23532 }
23533 } // DevTools exists
23534
23535
23536 return true;
23537}
23538function onScheduleRoot(root, children) {
23539 if (typeof onScheduleFiberRoot === 'function') {
23540 onScheduleFiberRoot(root, children);
23541 }
23542}
23543function onCommitRoot(root, expirationTime) {
23544 if (typeof onCommitFiberRoot === 'function') {
23545 onCommitFiberRoot(root, expirationTime);
23546 }
23547}
23548function onCommitUnmount(fiber) {
23549 if (typeof onCommitFiberUnmount === 'function') {
23550 onCommitFiberUnmount(fiber);
23551 }
23552}
23553
23554var hasBadMapPolyfill;
23555
23556{
23557 hasBadMapPolyfill = false;
23558
23559 try {
23560 var nonExtensibleObject = Object.preventExtensions({});
23561 var testMap = new Map([[nonExtensibleObject, null]]);
23562 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
23563 // https://github.com/rollup/rollup/issues/1771
23564 // TODO: we can remove these if Rollup fixes the bug.
23565
23566 testMap.set(0, 0);
23567 testSet.add(0);
23568 } catch (e) {
23569 // TODO: Consider warning about bad polyfills
23570 hasBadMapPolyfill = true;
23571 }
23572}
23573
23574var debugCounter = 1;
23575
23576function FiberNode(tag, pendingProps, key, mode) {
23577 // Instance
23578 this.tag = tag;
23579 this.key = key;
23580 this.elementType = null;
23581 this.type = null;
23582 this.stateNode = null; // Fiber
23583
23584 this.return = null;
23585 this.child = null;
23586 this.sibling = null;
23587 this.index = 0;
23588 this.ref = null;
23589 this.pendingProps = pendingProps;
23590 this.memoizedProps = null;
23591 this.updateQueue = null;
23592 this.memoizedState = null;
23593 this.dependencies = null;
23594 this.mode = mode; // Effects
23595
23596 this.effectTag = NoEffect;
23597 this.nextEffect = null;
23598 this.firstEffect = null;
23599 this.lastEffect = null;
23600 this.expirationTime = NoWork;
23601 this.childExpirationTime = NoWork;
23602 this.alternate = null;
23603
23604 {
23605 // Note: The following is done to avoid a v8 performance cliff.
23606 //
23607 // Initializing the fields below to smis and later updating them with
23608 // double values will cause Fibers to end up having separate shapes.
23609 // This behavior/bug has something to do with Object.preventExtension().
23610 // Fortunately this only impacts DEV builds.
23611 // Unfortunately it makes React unusably slow for some applications.
23612 // To work around this, initialize the fields below with doubles.
23613 //
23614 // Learn more about this here:
23615 // https://github.com/facebook/react/issues/14365
23616 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
23617 this.actualDuration = Number.NaN;
23618 this.actualStartTime = Number.NaN;
23619 this.selfBaseDuration = Number.NaN;
23620 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
23621 // This won't trigger the performance cliff mentioned above,
23622 // and it simplifies other profiler code (including DevTools).
23623
23624 this.actualDuration = 0;
23625 this.actualStartTime = -1;
23626 this.selfBaseDuration = 0;
23627 this.treeBaseDuration = 0;
23628 } // This is normally DEV-only except www when it adds listeners.
23629 // TODO: remove the User Timing integration in favor of Root Events.
23630
23631
23632 {
23633 this._debugID = debugCounter++;
23634 this._debugIsCurrentlyTiming = false;
23635 }
23636
23637 {
23638 this._debugSource = null;
23639 this._debugOwner = null;
23640 this._debugNeedsRemount = false;
23641 this._debugHookTypes = null;
23642
23643 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
23644 Object.preventExtensions(this);
23645 }
23646 }
23647} // This is a constructor function, rather than a POJO constructor, still
23648// please ensure we do the following:
23649// 1) Nobody should add any instance methods on this. Instance methods can be
23650// more difficult to predict when they get optimized and they are almost
23651// never inlined properly in static compilers.
23652// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
23653// always know when it is a fiber.
23654// 3) We might want to experiment with using numeric keys since they are easier
23655// to optimize in a non-JIT environment.
23656// 4) We can easily go from a constructor to a createFiber object literal if that
23657// is faster.
23658// 5) It should be easy to port this to a C struct and keep a C implementation
23659// compatible.
23660
23661
23662var createFiber = function (tag, pendingProps, key, mode) {
23663 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
23664 return new FiberNode(tag, pendingProps, key, mode);
23665};
23666
23667function shouldConstruct(Component) {
23668 var prototype = Component.prototype;
23669 return !!(prototype && prototype.isReactComponent);
23670}
23671
23672function isSimpleFunctionComponent(type) {
23673 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
23674}
23675function resolveLazyComponentTag(Component) {
23676 if (typeof Component === 'function') {
23677 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
23678 } else if (Component !== undefined && Component !== null) {
23679 var $$typeof = Component.$$typeof;
23680
23681 if ($$typeof === REACT_FORWARD_REF_TYPE) {
23682 return ForwardRef;
23683 }
23684
23685 if ($$typeof === REACT_MEMO_TYPE) {
23686 return MemoComponent;
23687 }
23688 }
23689
23690 return IndeterminateComponent;
23691} // This is used to create an alternate fiber to do work on.
23692
23693function createWorkInProgress(current, pendingProps) {
23694 var workInProgress = current.alternate;
23695
23696 if (workInProgress === null) {
23697 // We use a double buffering pooling technique because we know that we'll
23698 // only ever need at most two versions of a tree. We pool the "other" unused
23699 // node that we're free to reuse. This is lazily created to avoid allocating
23700 // extra objects for things that are never updated. It also allow us to
23701 // reclaim the extra memory if needed.
23702 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
23703 workInProgress.elementType = current.elementType;
23704 workInProgress.type = current.type;
23705 workInProgress.stateNode = current.stateNode;
23706
23707 {
23708 // DEV-only fields
23709 {
23710 workInProgress._debugID = current._debugID;
23711 }
23712
23713 workInProgress._debugSource = current._debugSource;
23714 workInProgress._debugOwner = current._debugOwner;
23715 workInProgress._debugHookTypes = current._debugHookTypes;
23716 }
23717
23718 workInProgress.alternate = current;
23719 current.alternate = workInProgress;
23720 } else {
23721 workInProgress.pendingProps = pendingProps; // We already have an alternate.
23722 // Reset the effect tag.
23723
23724 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
23725
23726 workInProgress.nextEffect = null;
23727 workInProgress.firstEffect = null;
23728 workInProgress.lastEffect = null;
23729
23730 {
23731 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
23732 // This prevents time from endlessly accumulating in new commits.
23733 // This has the downside of resetting values for different priority renders,
23734 // But works for yielding (the common case) and should support resuming.
23735 workInProgress.actualDuration = 0;
23736 workInProgress.actualStartTime = -1;
23737 }
23738 }
23739
23740 workInProgress.childExpirationTime = current.childExpirationTime;
23741 workInProgress.expirationTime = current.expirationTime;
23742 workInProgress.child = current.child;
23743 workInProgress.memoizedProps = current.memoizedProps;
23744 workInProgress.memoizedState = current.memoizedState;
23745 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
23746 // it cannot be shared with the current fiber.
23747
23748 var currentDependencies = current.dependencies;
23749 workInProgress.dependencies = currentDependencies === null ? null : {
23750 expirationTime: currentDependencies.expirationTime,
23751 firstContext: currentDependencies.firstContext,
23752 responders: currentDependencies.responders
23753 }; // These will be overridden during the parent's reconciliation
23754
23755 workInProgress.sibling = current.sibling;
23756 workInProgress.index = current.index;
23757 workInProgress.ref = current.ref;
23758
23759 {
23760 workInProgress.selfBaseDuration = current.selfBaseDuration;
23761 workInProgress.treeBaseDuration = current.treeBaseDuration;
23762 }
23763
23764 {
23765 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
23766
23767 switch (workInProgress.tag) {
23768 case IndeterminateComponent:
23769 case FunctionComponent:
23770 case SimpleMemoComponent:
23771 workInProgress.type = resolveFunctionForHotReloading(current.type);
23772 break;
23773
23774 case ClassComponent:
23775 workInProgress.type = resolveClassForHotReloading(current.type);
23776 break;
23777
23778 case ForwardRef:
23779 workInProgress.type = resolveForwardRefForHotReloading(current.type);
23780 break;
23781 }
23782 }
23783
23784 return workInProgress;
23785} // Used to reuse a Fiber for a second pass.
23786
23787function resetWorkInProgress(workInProgress, renderExpirationTime) {
23788 // This resets the Fiber to what createFiber or createWorkInProgress would
23789 // have set the values to before during the first pass. Ideally this wouldn't
23790 // be necessary but unfortunately many code paths reads from the workInProgress
23791 // when they should be reading from current and writing to workInProgress.
23792 // We assume pendingProps, index, key, ref, return are still untouched to
23793 // avoid doing another reconciliation.
23794 // Reset the effect tag but keep any Placement tags, since that's something
23795 // that child fiber is setting, not the reconciliation.
23796 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
23797
23798 workInProgress.nextEffect = null;
23799 workInProgress.firstEffect = null;
23800 workInProgress.lastEffect = null;
23801 var current = workInProgress.alternate;
23802
23803 if (current === null) {
23804 // Reset to createFiber's initial values.
23805 workInProgress.childExpirationTime = NoWork;
23806 workInProgress.expirationTime = renderExpirationTime;
23807 workInProgress.child = null;
23808 workInProgress.memoizedProps = null;
23809 workInProgress.memoizedState = null;
23810 workInProgress.updateQueue = null;
23811 workInProgress.dependencies = null;
23812
23813 {
23814 // Note: We don't reset the actualTime counts. It's useful to accumulate
23815 // actual time across multiple render passes.
23816 workInProgress.selfBaseDuration = 0;
23817 workInProgress.treeBaseDuration = 0;
23818 }
23819 } else {
23820 // Reset to the cloned values that createWorkInProgress would've.
23821 workInProgress.childExpirationTime = current.childExpirationTime;
23822 workInProgress.expirationTime = current.expirationTime;
23823 workInProgress.child = current.child;
23824 workInProgress.memoizedProps = current.memoizedProps;
23825 workInProgress.memoizedState = current.memoizedState;
23826 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
23827 // it cannot be shared with the current fiber.
23828
23829 var currentDependencies = current.dependencies;
23830 workInProgress.dependencies = currentDependencies === null ? null : {
23831 expirationTime: currentDependencies.expirationTime,
23832 firstContext: currentDependencies.firstContext,
23833 responders: currentDependencies.responders
23834 };
23835
23836 {
23837 // Note: We don't reset the actualTime counts. It's useful to accumulate
23838 // actual time across multiple render passes.
23839 workInProgress.selfBaseDuration = current.selfBaseDuration;
23840 workInProgress.treeBaseDuration = current.treeBaseDuration;
23841 }
23842 }
23843
23844 return workInProgress;
23845}
23846function createHostRootFiber(tag) {
23847 var mode;
23848
23849 if (tag === ConcurrentRoot) {
23850 mode = ConcurrentMode | BlockingMode | StrictMode;
23851 } else if (tag === BlockingRoot) {
23852 mode = BlockingMode | StrictMode;
23853 } else {
23854 mode = NoMode;
23855 }
23856
23857 if ( isDevToolsPresent) {
23858 // Always collect profile timings when DevTools are present.
23859 // This enables DevTools to start capturing timing at any point–
23860 // Without some nodes in the tree having empty base times.
23861 mode |= ProfileMode;
23862 }
23863
23864 return createFiber(HostRoot, null, null, mode);
23865}
23866function createFiberFromTypeAndProps(type, // React$ElementType
23867key, pendingProps, owner, mode, expirationTime) {
23868 var fiber;
23869 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
23870
23871 var resolvedType = type;
23872
23873 if (typeof type === 'function') {
23874 if (shouldConstruct(type)) {
23875 fiberTag = ClassComponent;
23876
23877 {
23878 resolvedType = resolveClassForHotReloading(resolvedType);
23879 }
23880 } else {
23881 {
23882 resolvedType = resolveFunctionForHotReloading(resolvedType);
23883 }
23884 }
23885 } else if (typeof type === 'string') {
23886 fiberTag = HostComponent;
23887 } else {
23888 getTag: switch (type) {
23889 case REACT_FRAGMENT_TYPE:
23890 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
23891
23892 case REACT_CONCURRENT_MODE_TYPE:
23893 fiberTag = Mode;
23894 mode |= ConcurrentMode | BlockingMode | StrictMode;
23895 break;
23896
23897 case REACT_STRICT_MODE_TYPE:
23898 fiberTag = Mode;
23899 mode |= StrictMode;
23900 break;
23901
23902 case REACT_PROFILER_TYPE:
23903 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
23904
23905 case REACT_SUSPENSE_TYPE:
23906 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
23907
23908 case REACT_SUSPENSE_LIST_TYPE:
23909 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
23910
23911 default:
23912 {
23913 if (typeof type === 'object' && type !== null) {
23914 switch (type.$$typeof) {
23915 case REACT_PROVIDER_TYPE:
23916 fiberTag = ContextProvider;
23917 break getTag;
23918
23919 case REACT_CONTEXT_TYPE:
23920 // This is a consumer
23921 fiberTag = ContextConsumer;
23922 break getTag;
23923
23924 case REACT_FORWARD_REF_TYPE:
23925 fiberTag = ForwardRef;
23926
23927 {
23928 resolvedType = resolveForwardRefForHotReloading(resolvedType);
23929 }
23930
23931 break getTag;
23932
23933 case REACT_MEMO_TYPE:
23934 fiberTag = MemoComponent;
23935 break getTag;
23936
23937 case REACT_LAZY_TYPE:
23938 fiberTag = LazyComponent;
23939 resolvedType = null;
23940 break getTag;
23941
23942 case REACT_BLOCK_TYPE:
23943 fiberTag = Block;
23944 break getTag;
23945
23946 }
23947 }
23948
23949 var info = '';
23950
23951 {
23952 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
23953 info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and " + 'named imports.';
23954 }
23955
23956 var ownerName = owner ? getComponentName(owner.type) : null;
23957
23958 if (ownerName) {
23959 info += '\n\nCheck the render method of `' + ownerName + '`.';
23960 }
23961 }
23962
23963 {
23964 {
23965 throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + (type == null ? type : typeof type) + "." + info );
23966 }
23967 }
23968 }
23969 }
23970 }
23971
23972 fiber = createFiber(fiberTag, pendingProps, key, mode);
23973 fiber.elementType = type;
23974 fiber.type = resolvedType;
23975 fiber.expirationTime = expirationTime;
23976 return fiber;
23977}
23978function createFiberFromElement(element, mode, expirationTime) {
23979 var owner = null;
23980
23981 {
23982 owner = element._owner;
23983 }
23984
23985 var type = element.type;
23986 var key = element.key;
23987 var pendingProps = element.props;
23988 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
23989
23990 {
23991 fiber._debugSource = element._source;
23992 fiber._debugOwner = element._owner;
23993 }
23994
23995 return fiber;
23996}
23997function createFiberFromFragment(elements, mode, expirationTime, key) {
23998 var fiber = createFiber(Fragment, elements, key, mode);
23999 fiber.expirationTime = expirationTime;
24000 return fiber;
24001}
24002
24003function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
24004 {
24005 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
24006 error('Profiler must specify an "id" string and "onRender" function as props');
24007 }
24008 }
24009
24010 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
24011
24012 fiber.elementType = REACT_PROFILER_TYPE;
24013 fiber.type = REACT_PROFILER_TYPE;
24014 fiber.expirationTime = expirationTime;
24015 return fiber;
24016}
24017
24018function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
24019 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
24020 // This needs to be fixed in getComponentName so that it relies on the tag
24021 // instead.
24022
24023 fiber.type = REACT_SUSPENSE_TYPE;
24024 fiber.elementType = REACT_SUSPENSE_TYPE;
24025 fiber.expirationTime = expirationTime;
24026 return fiber;
24027}
24028function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
24029 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
24030
24031 {
24032 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
24033 // This needs to be fixed in getComponentName so that it relies on the tag
24034 // instead.
24035 fiber.type = REACT_SUSPENSE_LIST_TYPE;
24036 }
24037
24038 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
24039 fiber.expirationTime = expirationTime;
24040 return fiber;
24041}
24042function createFiberFromText(content, mode, expirationTime) {
24043 var fiber = createFiber(HostText, content, null, mode);
24044 fiber.expirationTime = expirationTime;
24045 return fiber;
24046}
24047function createFiberFromHostInstanceForDeletion() {
24048 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.
24049
24050 fiber.elementType = 'DELETED';
24051 fiber.type = 'DELETED';
24052 return fiber;
24053}
24054function createFiberFromPortal(portal, mode, expirationTime) {
24055 var pendingProps = portal.children !== null ? portal.children : [];
24056 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
24057 fiber.expirationTime = expirationTime;
24058 fiber.stateNode = {
24059 containerInfo: portal.containerInfo,
24060 pendingChildren: null,
24061 // Used by persistent updates
24062 implementation: portal.implementation
24063 };
24064 return fiber;
24065} // Used for stashing WIP properties to replay failed work in DEV.
24066
24067function assignFiberPropertiesInDEV(target, source) {
24068 if (target === null) {
24069 // This Fiber's initial properties will always be overwritten.
24070 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
24071 target = createFiber(IndeterminateComponent, null, null, NoMode);
24072 } // This is intentionally written as a list of all properties.
24073 // We tried to use Object.assign() instead but this is called in
24074 // the hottest path, and Object.assign() was too slow:
24075 // https://github.com/facebook/react/issues/12502
24076 // This code is DEV-only so size is not a concern.
24077
24078
24079 target.tag = source.tag;
24080 target.key = source.key;
24081 target.elementType = source.elementType;
24082 target.type = source.type;
24083 target.stateNode = source.stateNode;
24084 target.return = source.return;
24085 target.child = source.child;
24086 target.sibling = source.sibling;
24087 target.index = source.index;
24088 target.ref = source.ref;
24089 target.pendingProps = source.pendingProps;
24090 target.memoizedProps = source.memoizedProps;
24091 target.updateQueue = source.updateQueue;
24092 target.memoizedState = source.memoizedState;
24093 target.dependencies = source.dependencies;
24094 target.mode = source.mode;
24095 target.effectTag = source.effectTag;
24096 target.nextEffect = source.nextEffect;
24097 target.firstEffect = source.firstEffect;
24098 target.lastEffect = source.lastEffect;
24099 target.expirationTime = source.expirationTime;
24100 target.childExpirationTime = source.childExpirationTime;
24101 target.alternate = source.alternate;
24102
24103 {
24104 target.actualDuration = source.actualDuration;
24105 target.actualStartTime = source.actualStartTime;
24106 target.selfBaseDuration = source.selfBaseDuration;
24107 target.treeBaseDuration = source.treeBaseDuration;
24108 }
24109
24110 {
24111 target._debugID = source._debugID;
24112 }
24113
24114 target._debugSource = source._debugSource;
24115 target._debugOwner = source._debugOwner;
24116 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
24117 target._debugNeedsRemount = source._debugNeedsRemount;
24118 target._debugHookTypes = source._debugHookTypes;
24119 return target;
24120}
24121
24122function FiberRootNode(containerInfo, tag, hydrate) {
24123 this.tag = tag;
24124 this.current = null;
24125 this.containerInfo = containerInfo;
24126 this.pendingChildren = null;
24127 this.pingCache = null;
24128 this.finishedExpirationTime = NoWork;
24129 this.finishedWork = null;
24130 this.timeoutHandle = noTimeout;
24131 this.context = null;
24132 this.pendingContext = null;
24133 this.hydrate = hydrate;
24134 this.callbackNode = null;
24135 this.callbackPriority = NoPriority;
24136 this.firstPendingTime = NoWork;
24137 this.firstSuspendedTime = NoWork;
24138 this.lastSuspendedTime = NoWork;
24139 this.nextKnownPendingLevel = NoWork;
24140 this.lastPingedTime = NoWork;
24141 this.lastExpiredTime = NoWork;
24142
24143 {
24144 this.interactionThreadID = tracing.unstable_getThreadID();
24145 this.memoizedInteractions = new Set();
24146 this.pendingInteractionMap = new Map();
24147 }
24148}
24149
24150function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
24151 var root = new FiberRootNode(containerInfo, tag, hydrate);
24152 // stateNode is any.
24153
24154
24155 var uninitializedFiber = createHostRootFiber(tag);
24156 root.current = uninitializedFiber;
24157 uninitializedFiber.stateNode = root;
24158 initializeUpdateQueue(uninitializedFiber);
24159 return root;
24160}
24161function isRootSuspendedAtTime(root, expirationTime) {
24162 var firstSuspendedTime = root.firstSuspendedTime;
24163 var lastSuspendedTime = root.lastSuspendedTime;
24164 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
24165}
24166function markRootSuspendedAtTime(root, expirationTime) {
24167 var firstSuspendedTime = root.firstSuspendedTime;
24168 var lastSuspendedTime = root.lastSuspendedTime;
24169
24170 if (firstSuspendedTime < expirationTime) {
24171 root.firstSuspendedTime = expirationTime;
24172 }
24173
24174 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
24175 root.lastSuspendedTime = expirationTime;
24176 }
24177
24178 if (expirationTime <= root.lastPingedTime) {
24179 root.lastPingedTime = NoWork;
24180 }
24181
24182 if (expirationTime <= root.lastExpiredTime) {
24183 root.lastExpiredTime = NoWork;
24184 }
24185}
24186function markRootUpdatedAtTime(root, expirationTime) {
24187 // Update the range of pending times
24188 var firstPendingTime = root.firstPendingTime;
24189
24190 if (expirationTime > firstPendingTime) {
24191 root.firstPendingTime = expirationTime;
24192 } // Update the range of suspended times. Treat everything lower priority or
24193 // equal to this update as unsuspended.
24194
24195
24196 var firstSuspendedTime = root.firstSuspendedTime;
24197
24198 if (firstSuspendedTime !== NoWork) {
24199 if (expirationTime >= firstSuspendedTime) {
24200 // The entire suspended range is now unsuspended.
24201 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
24202 } else if (expirationTime >= root.lastSuspendedTime) {
24203 root.lastSuspendedTime = expirationTime + 1;
24204 } // This is a pending level. Check if it's higher priority than the next
24205 // known pending level.
24206
24207
24208 if (expirationTime > root.nextKnownPendingLevel) {
24209 root.nextKnownPendingLevel = expirationTime;
24210 }
24211 }
24212}
24213function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
24214 // Update the range of pending times
24215 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
24216 // equal to this update as unsuspended.
24217
24218 if (finishedExpirationTime <= root.lastSuspendedTime) {
24219 // The entire suspended range is now unsuspended.
24220 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
24221 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
24222 // Part of the suspended range is now unsuspended. Narrow the range to
24223 // include everything between the unsuspended time (non-inclusive) and the
24224 // last suspended time.
24225 root.firstSuspendedTime = finishedExpirationTime - 1;
24226 }
24227
24228 if (finishedExpirationTime <= root.lastPingedTime) {
24229 // Clear the pinged time
24230 root.lastPingedTime = NoWork;
24231 }
24232
24233 if (finishedExpirationTime <= root.lastExpiredTime) {
24234 // Clear the expired time
24235 root.lastExpiredTime = NoWork;
24236 }
24237}
24238function markRootExpiredAtTime(root, expirationTime) {
24239 var lastExpiredTime = root.lastExpiredTime;
24240
24241 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
24242 root.lastExpiredTime = expirationTime;
24243 }
24244}
24245
24246var didWarnAboutNestedUpdates;
24247var didWarnAboutFindNodeInStrictMode;
24248
24249{
24250 didWarnAboutNestedUpdates = false;
24251 didWarnAboutFindNodeInStrictMode = {};
24252}
24253
24254function getContextForSubtree(parentComponent) {
24255 if (!parentComponent) {
24256 return emptyContextObject;
24257 }
24258
24259 var fiber = get(parentComponent);
24260 var parentContext = findCurrentUnmaskedContext(fiber);
24261
24262 if (fiber.tag === ClassComponent) {
24263 var Component = fiber.type;
24264
24265 if (isContextProvider(Component)) {
24266 return processChildContext(fiber, Component, parentContext);
24267 }
24268 }
24269
24270 return parentContext;
24271}
24272
24273function findHostInstanceWithWarning(component, methodName) {
24274 {
24275 var fiber = get(component);
24276
24277 if (fiber === undefined) {
24278 if (typeof component.render === 'function') {
24279 {
24280 {
24281 throw Error( "Unable to find node on an unmounted component." );
24282 }
24283 }
24284 } else {
24285 {
24286 {
24287 throw Error( "Argument appears to not be a ReactComponent. Keys: " + Object.keys(component) );
24288 }
24289 }
24290 }
24291 }
24292
24293 var hostFiber = findCurrentHostFiber(fiber);
24294
24295 if (hostFiber === null) {
24296 return null;
24297 }
24298
24299 if (hostFiber.mode & StrictMode) {
24300 var componentName = getComponentName(fiber.type) || 'Component';
24301
24302 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
24303 didWarnAboutFindNodeInStrictMode[componentName] = true;
24304
24305 if (fiber.mode & StrictMode) {
24306 error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-find-node%s', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));
24307 } else {
24308 error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-find-node%s', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));
24309 }
24310 }
24311 }
24312
24313 return hostFiber.stateNode;
24314 }
24315}
24316
24317function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
24318 return createFiberRoot(containerInfo, tag, hydrate);
24319}
24320function updateContainer(element, container, parentComponent, callback) {
24321 {
24322 onScheduleRoot(container, element);
24323 }
24324
24325 var current$1 = container.current;
24326 var currentTime = requestCurrentTimeForUpdate();
24327
24328 {
24329 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
24330 if ('undefined' !== typeof jest) {
24331 warnIfUnmockedScheduler(current$1);
24332 warnIfNotScopedWithMatchingAct(current$1);
24333 }
24334 }
24335
24336 var suspenseConfig = requestCurrentSuspenseConfig();
24337 var expirationTime = computeExpirationForFiber(currentTime, current$1, suspenseConfig);
24338 var context = getContextForSubtree(parentComponent);
24339
24340 if (container.context === null) {
24341 container.context = context;
24342 } else {
24343 container.pendingContext = context;
24344 }
24345
24346 {
24347 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
24348 didWarnAboutNestedUpdates = true;
24349
24350 error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current.type) || 'Unknown');
24351 }
24352 }
24353
24354 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
24355 // being called "element".
24356
24357 update.payload = {
24358 element: element
24359 };
24360 callback = callback === undefined ? null : callback;
24361
24362 if (callback !== null) {
24363 {
24364 if (typeof callback !== 'function') {
24365 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
24366 }
24367 }
24368
24369 update.callback = callback;
24370 }
24371
24372 enqueueUpdate(current$1, update);
24373 scheduleWork(current$1, expirationTime);
24374 return expirationTime;
24375}
24376function getPublicRootInstance(container) {
24377 var containerFiber = container.current;
24378
24379 if (!containerFiber.child) {
24380 return null;
24381 }
24382
24383 switch (containerFiber.child.tag) {
24384 case HostComponent:
24385 return getPublicInstance(containerFiber.child.stateNode);
24386
24387 default:
24388 return containerFiber.child.stateNode;
24389 }
24390}
24391
24392function markRetryTimeImpl(fiber, retryTime) {
24393 var suspenseState = fiber.memoizedState;
24394
24395 if (suspenseState !== null && suspenseState.dehydrated !== null) {
24396 if (suspenseState.retryTime < retryTime) {
24397 suspenseState.retryTime = retryTime;
24398 }
24399 }
24400} // Increases the priority of thennables when they resolve within this boundary.
24401
24402
24403function markRetryTimeIfNotHydrated(fiber, retryTime) {
24404 markRetryTimeImpl(fiber, retryTime);
24405 var alternate = fiber.alternate;
24406
24407 if (alternate) {
24408 markRetryTimeImpl(alternate, retryTime);
24409 }
24410}
24411
24412function attemptUserBlockingHydration$1(fiber) {
24413 if (fiber.tag !== SuspenseComponent) {
24414 // We ignore HostRoots here because we can't increase
24415 // their priority and they should not suspend on I/O,
24416 // since you have to wrap anything that might suspend in
24417 // Suspense.
24418 return;
24419 }
24420
24421 var expTime = computeInteractiveExpiration(requestCurrentTimeForUpdate());
24422 scheduleWork(fiber, expTime);
24423 markRetryTimeIfNotHydrated(fiber, expTime);
24424}
24425function attemptContinuousHydration$1(fiber) {
24426 if (fiber.tag !== SuspenseComponent) {
24427 // We ignore HostRoots here because we can't increase
24428 // their priority and they should not suspend on I/O,
24429 // since you have to wrap anything that might suspend in
24430 // Suspense.
24431 return;
24432 }
24433
24434 scheduleWork(fiber, ContinuousHydration);
24435 markRetryTimeIfNotHydrated(fiber, ContinuousHydration);
24436}
24437function attemptHydrationAtCurrentPriority$1(fiber) {
24438 if (fiber.tag !== SuspenseComponent) {
24439 // We ignore HostRoots here because we can't increase
24440 // their priority other than synchronously flush it.
24441 return;
24442 }
24443
24444 var currentTime = requestCurrentTimeForUpdate();
24445 var expTime = computeExpirationForFiber(currentTime, fiber, null);
24446 scheduleWork(fiber, expTime);
24447 markRetryTimeIfNotHydrated(fiber, expTime);
24448}
24449function findHostInstanceWithNoPortals(fiber) {
24450 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
24451
24452 if (hostFiber === null) {
24453 return null;
24454 }
24455
24456 if (hostFiber.tag === FundamentalComponent) {
24457 return hostFiber.stateNode.instance;
24458 }
24459
24460 return hostFiber.stateNode;
24461}
24462
24463var shouldSuspendImpl = function (fiber) {
24464 return false;
24465};
24466
24467function shouldSuspend(fiber) {
24468 return shouldSuspendImpl(fiber);
24469}
24470var overrideHookState = null;
24471var overrideProps = null;
24472var scheduleUpdate = null;
24473var setSuspenseHandler = null;
24474
24475{
24476 var copyWithSetImpl = function (obj, path, idx, value) {
24477 if (idx >= path.length) {
24478 return value;
24479 }
24480
24481 var key = path[idx];
24482 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
24483
24484 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
24485 return updated;
24486 };
24487
24488 var copyWithSet = function (obj, path, value) {
24489 return copyWithSetImpl(obj, path, 0, value);
24490 }; // Support DevTools editable values for useState and useReducer.
24491
24492
24493 overrideHookState = function (fiber, id, path, value) {
24494 // For now, the "id" of stateful hooks is just the stateful hook index.
24495 // This may change in the future with e.g. nested hooks.
24496 var currentHook = fiber.memoizedState;
24497
24498 while (currentHook !== null && id > 0) {
24499 currentHook = currentHook.next;
24500 id--;
24501 }
24502
24503 if (currentHook !== null) {
24504 var newState = copyWithSet(currentHook.memoizedState, path, value);
24505 currentHook.memoizedState = newState;
24506 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
24507 // because there is no update we can add for useReducer hooks that won't trigger an error.
24508 // (There's no appropriate action type for DevTools overrides.)
24509 // As a result though, React will see the scheduled update as a noop and bailout.
24510 // Shallow cloning props works as a workaround for now to bypass the bailout check.
24511
24512 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
24513 scheduleWork(fiber, Sync);
24514 }
24515 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
24516
24517
24518 overrideProps = function (fiber, path, value) {
24519 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
24520
24521 if (fiber.alternate) {
24522 fiber.alternate.pendingProps = fiber.pendingProps;
24523 }
24524
24525 scheduleWork(fiber, Sync);
24526 };
24527
24528 scheduleUpdate = function (fiber) {
24529 scheduleWork(fiber, Sync);
24530 };
24531
24532 setSuspenseHandler = function (newShouldSuspendImpl) {
24533 shouldSuspendImpl = newShouldSuspendImpl;
24534 };
24535}
24536
24537function injectIntoDevTools(devToolsConfig) {
24538 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
24539 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
24540 return injectInternals(_assign({}, devToolsConfig, {
24541 overrideHookState: overrideHookState,
24542 overrideProps: overrideProps,
24543 setSuspenseHandler: setSuspenseHandler,
24544 scheduleUpdate: scheduleUpdate,
24545 currentDispatcherRef: ReactCurrentDispatcher,
24546 findHostInstanceByFiber: function (fiber) {
24547 var hostFiber = findCurrentHostFiber(fiber);
24548
24549 if (hostFiber === null) {
24550 return null;
24551 }
24552
24553 return hostFiber.stateNode;
24554 },
24555 findFiberByHostInstance: function (instance) {
24556 if (!findFiberByHostInstance) {
24557 // Might not be implemented by the renderer.
24558 return null;
24559 }
24560
24561 return findFiberByHostInstance(instance);
24562 },
24563 // React Refresh
24564 findHostInstancesForRefresh: findHostInstancesForRefresh ,
24565 scheduleRefresh: scheduleRefresh ,
24566 scheduleRoot: scheduleRoot ,
24567 setRefreshHandler: setRefreshHandler ,
24568 // Enables DevTools to append owner stacks to error messages in DEV mode.
24569 getCurrentFiber: function () {
24570 return current;
24571 }
24572 }));
24573}
24574var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
24575
24576function ReactDOMRoot(container, options) {
24577 this._internalRoot = createRootImpl(container, ConcurrentRoot, options);
24578}
24579
24580function ReactDOMBlockingRoot(container, tag, options) {
24581 this._internalRoot = createRootImpl(container, tag, options);
24582}
24583
24584ReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children) {
24585 var root = this._internalRoot;
24586
24587 {
24588 if (typeof arguments[1] === 'function') {
24589 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
24590 }
24591
24592 var container = root.containerInfo;
24593
24594 if (container.nodeType !== COMMENT_NODE) {
24595 var hostInstance = findHostInstanceWithNoPortals(root.current);
24596
24597 if (hostInstance) {
24598 if (hostInstance.parentNode !== container) {
24599 error('render(...): It looks like the React-rendered content of the ' + 'root container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + "root.unmount() to empty a root's container.");
24600 }
24601 }
24602 }
24603 }
24604
24605 updateContainer(children, root, null, null);
24606};
24607
24608ReactDOMRoot.prototype.unmount = ReactDOMBlockingRoot.prototype.unmount = function () {
24609 {
24610 if (typeof arguments[0] === 'function') {
24611 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
24612 }
24613 }
24614
24615 var root = this._internalRoot;
24616 var container = root.containerInfo;
24617 updateContainer(null, root, null, function () {
24618 unmarkContainerAsRoot(container);
24619 });
24620};
24621
24622function createRootImpl(container, tag, options) {
24623 // Tag is either LegacyRoot or Concurrent Root
24624 var hydrate = options != null && options.hydrate === true;
24625 var hydrationCallbacks = options != null && options.hydrationOptions || null;
24626 var root = createContainer(container, tag, hydrate);
24627 markContainerAsRoot(root.current, container);
24628
24629 if (hydrate && tag !== LegacyRoot) {
24630 var doc = container.nodeType === DOCUMENT_NODE ? container : container.ownerDocument;
24631 eagerlyTrapReplayableEvents(container, doc);
24632 }
24633
24634 return root;
24635}
24636function createLegacyRoot(container, options) {
24637 return new ReactDOMBlockingRoot(container, LegacyRoot, options);
24638}
24639function isValidContainer(node) {
24640 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === ' react-mount-point-unstable '));
24641}
24642
24643var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
24644var topLevelUpdateWarnings;
24645var warnedAboutHydrateAPI = false;
24646
24647{
24648 topLevelUpdateWarnings = function (container) {
24649 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
24650 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
24651
24652 if (hostInstance) {
24653 if (hostInstance.parentNode !== container) {
24654 error('render(...): It looks like the React-rendered content of this ' + 'container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + 'ReactDOM.unmountComponentAtNode to empty a container.');
24655 }
24656 }
24657 }
24658
24659 var isRootRenderedBySomeReact = !!container._reactRootContainer;
24660 var rootEl = getReactRootElementInContainer(container);
24661 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
24662
24663 if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
24664 error('render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.');
24665 }
24666
24667 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
24668 error('render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.');
24669 }
24670 };
24671}
24672
24673function getReactRootElementInContainer(container) {
24674 if (!container) {
24675 return null;
24676 }
24677
24678 if (container.nodeType === DOCUMENT_NODE) {
24679 return container.documentElement;
24680 } else {
24681 return container.firstChild;
24682 }
24683}
24684
24685function shouldHydrateDueToLegacyHeuristic(container) {
24686 var rootElement = getReactRootElementInContainer(container);
24687 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
24688}
24689
24690function legacyCreateRootFromDOMContainer(container, forceHydrate) {
24691 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content.
24692
24693 if (!shouldHydrate) {
24694 var warned = false;
24695 var rootSibling;
24696
24697 while (rootSibling = container.lastChild) {
24698 {
24699 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
24700 warned = true;
24701
24702 error('render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.');
24703 }
24704 }
24705
24706 container.removeChild(rootSibling);
24707 }
24708 }
24709
24710 {
24711 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
24712 warnedAboutHydrateAPI = true;
24713
24714 warn('render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v17. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.');
24715 }
24716 }
24717
24718 return createLegacyRoot(container, shouldHydrate ? {
24719 hydrate: true
24720 } : undefined);
24721}
24722
24723function warnOnInvalidCallback$1(callback, callerName) {
24724 {
24725 if (callback !== null && typeof callback !== 'function') {
24726 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
24727 }
24728 }
24729}
24730
24731function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
24732 {
24733 topLevelUpdateWarnings(container);
24734 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');
24735 } // TODO: Without `any` type, Flow says "Property cannot be accessed on any
24736 // member of intersection type." Whyyyyyy.
24737
24738
24739 var root = container._reactRootContainer;
24740 var fiberRoot;
24741
24742 if (!root) {
24743 // Initial mount
24744 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
24745 fiberRoot = root._internalRoot;
24746
24747 if (typeof callback === 'function') {
24748 var originalCallback = callback;
24749
24750 callback = function () {
24751 var instance = getPublicRootInstance(fiberRoot);
24752 originalCallback.call(instance);
24753 };
24754 } // Initial mount should not be batched.
24755
24756
24757 unbatchedUpdates(function () {
24758 updateContainer(children, fiberRoot, parentComponent, callback);
24759 });
24760 } else {
24761 fiberRoot = root._internalRoot;
24762
24763 if (typeof callback === 'function') {
24764 var _originalCallback = callback;
24765
24766 callback = function () {
24767 var instance = getPublicRootInstance(fiberRoot);
24768
24769 _originalCallback.call(instance);
24770 };
24771 } // Update
24772
24773
24774 updateContainer(children, fiberRoot, parentComponent, callback);
24775 }
24776
24777 return getPublicRootInstance(fiberRoot);
24778}
24779
24780function findDOMNode(componentOrElement) {
24781 {
24782 var owner = ReactCurrentOwner$3.current;
24783
24784 if (owner !== null && owner.stateNode !== null) {
24785 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
24786
24787 if (!warnedAboutRefsInRender) {
24788 error('%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(owner.type) || 'A component');
24789 }
24790
24791 owner.stateNode._warnedAboutRefsInRender = true;
24792 }
24793 }
24794
24795 if (componentOrElement == null) {
24796 return null;
24797 }
24798
24799 if (componentOrElement.nodeType === ELEMENT_NODE) {
24800 return componentOrElement;
24801 }
24802
24803 {
24804 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
24805 }
24806}
24807function hydrate(element, container, callback) {
24808 if (!isValidContainer(container)) {
24809 {
24810 throw Error( "Target container is not a DOM element." );
24811 }
24812 }
24813
24814 {
24815 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
24816
24817 if (isModernRoot) {
24818 error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?');
24819 }
24820 } // TODO: throw or warn if we couldn't hydrate?
24821
24822
24823 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
24824}
24825function render(element, container, callback) {
24826 if (!isValidContainer(container)) {
24827 {
24828 throw Error( "Target container is not a DOM element." );
24829 }
24830 }
24831
24832 {
24833 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
24834
24835 if (isModernRoot) {
24836 error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?');
24837 }
24838 }
24839
24840 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
24841}
24842function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
24843 if (!isValidContainer(containerNode)) {
24844 {
24845 throw Error( "Target container is not a DOM element." );
24846 }
24847 }
24848
24849 if (!(parentComponent != null && has(parentComponent))) {
24850 {
24851 throw Error( "parentComponent must be a valid React Component" );
24852 }
24853 }
24854
24855 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
24856}
24857function unmountComponentAtNode(container) {
24858 if (!isValidContainer(container)) {
24859 {
24860 throw Error( "unmountComponentAtNode(...): Target container is not a DOM element." );
24861 }
24862 }
24863
24864 {
24865 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
24866
24867 if (isModernRoot) {
24868 error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.unmount()?');
24869 }
24870 }
24871
24872 if (container._reactRootContainer) {
24873 {
24874 var rootEl = getReactRootElementInContainer(container);
24875 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
24876
24877 if (renderedByDifferentReact) {
24878 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
24879 }
24880 } // Unmount should not be batched.
24881
24882
24883 unbatchedUpdates(function () {
24884 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
24885 // $FlowFixMe This should probably use `delete container._reactRootContainer`
24886 container._reactRootContainer = null;
24887 unmarkContainerAsRoot(container);
24888 });
24889 }); // If you call unmountComponentAtNode twice in quick succession, you'll
24890 // get `true` twice. That's probably fine?
24891
24892 return true;
24893 } else {
24894 {
24895 var _rootEl = getReactRootElementInContainer(container);
24896
24897 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl)); // Check if the container itself is a React root node.
24898
24899 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
24900
24901 if (hasNonRootReactChild) {
24902 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.');
24903 }
24904 }
24905
24906 return false;
24907 }
24908}
24909
24910function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
24911implementation) {
24912 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
24913 return {
24914 // This tag allow us to uniquely identify this as a React Portal
24915 $$typeof: REACT_PORTAL_TYPE,
24916 key: key == null ? null : '' + key,
24917 children: children,
24918 containerInfo: containerInfo,
24919 implementation: implementation
24920 };
24921}
24922
24923var ReactVersion = '16.13.1';
24924
24925setAttemptUserBlockingHydration(attemptUserBlockingHydration$1);
24926setAttemptContinuousHydration(attemptContinuousHydration$1);
24927setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
24928var didWarnAboutUnstableCreatePortal = false;
24929
24930{
24931 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
24932 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
24933 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
24934 error('React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
24935 }
24936}
24937
24938setRestoreImplementation(restoreControlledState$3);
24939setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);
24940
24941function createPortal$1(children, container) {
24942 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
24943
24944 if (!isValidContainer(container)) {
24945 {
24946 throw Error( "Target container is not a DOM element." );
24947 }
24948 } // TODO: pass ReactDOM portal implementation as third argument
24949 // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
24950
24951
24952 return createPortal(children, container, null, key);
24953}
24954
24955function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
24956
24957 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
24958}
24959
24960function unstable_createPortal(children, container) {
24961 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
24962
24963 {
24964 if (!didWarnAboutUnstableCreatePortal) {
24965 didWarnAboutUnstableCreatePortal = true;
24966
24967 warn('The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + 'but without the "unstable_" prefix.');
24968 }
24969 }
24970
24971 return createPortal$1(children, container, key);
24972}
24973
24974var Internals = {
24975 // Keep in sync with ReactDOMUnstableNativeDependencies.js
24976 // ReactTestUtils.js, and ReactTestUtilsAct.js. This is an array for better minification.
24977 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch, flushPassiveEffects, IsThisRendererActing]
24978};
24979var foundDevTools = injectIntoDevTools({
24980 findFiberByHostInstance: getClosestInstanceFromNode,
24981 bundleType: 1 ,
24982 version: ReactVersion,
24983 rendererPackageName: 'react-dom'
24984});
24985
24986{
24987 if (!foundDevTools && canUseDOM && window.top === window.self) {
24988 // If we're in Chrome or Firefox, provide a download link if not installed.
24989 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
24990 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
24991
24992 if (/^(https?|file):$/.test(protocol)) {
24993 // eslint-disable-next-line react-internal/no-production-logging
24994 console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://fb.me/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://fb.me/react-devtools-faq' : ''), 'font-weight:bold');
24995 }
24996 }
24997 }
24998}
24999
25000exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
25001exports.createPortal = createPortal$1;
25002exports.findDOMNode = findDOMNode;
25003exports.flushSync = flushSync;
25004exports.hydrate = hydrate;
25005exports.render = render;
25006exports.unmountComponentAtNode = unmountComponentAtNode;
25007exports.unstable_batchedUpdates = batchedUpdates$1;
25008exports.unstable_createPortal = unstable_createPortal;
25009exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
25010exports.version = ReactVersion;
25011 })();
25012}