UNPKG

906 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(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
14 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
15 (global = global || self, factory(global.ReactDOM = {}, global.React));
16}(this, (function (exports, React) { 'use strict';
17
18 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
19 // Current owner and dispatcher used to share the same ref,
20 // but PR #14548 split them out to better support the react-debug-tools package.
21
22 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
23 ReactSharedInternals.ReactCurrentDispatcher = {
24 current: null
25 };
26 }
27
28 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
29 ReactSharedInternals.ReactCurrentBatchConfig = {
30 suspense: null
31 };
32 }
33
34 // by calls to these methods by a Babel plugin.
35 //
36 // In PROD (or in packages without access to React internals),
37 // they are left as they are instead.
38
39 function warn(format) {
40 {
41 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
42 args[_key - 1] = arguments[_key];
43 }
44
45 printWarning('warn', format, args);
46 }
47 }
48 function error(format) {
49 {
50 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
51 args[_key2 - 1] = arguments[_key2];
52 }
53
54 printWarning('error', format, args);
55 }
56 }
57
58 function printWarning(level, format, args) {
59 // When changing this logic, you might want to also
60 // update consoleWithStackDev.www.js as well.
61 {
62 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
63
64 if (!hasExistingStack) {
65 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
66 var stack = ReactDebugCurrentFrame.getStackAddendum();
67
68 if (stack !== '') {
69 format += '%s';
70 args = args.concat([stack]);
71 }
72 }
73
74 var argsWithFormat = args.map(function (item) {
75 return '' + item;
76 }); // Careful: RN currently depends on this prefix
77
78 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
79 // breaks IE9: https://github.com/facebook/react/issues/13610
80 // eslint-disable-next-line react-internal/no-production-logging
81
82 Function.prototype.apply.call(console[level], console, argsWithFormat);
83
84 try {
85 // --- Welcome to debugging React ---
86 // This error was thrown as a convenience so that you can use this stack
87 // to find the callsite that caused this warning to fire.
88 var argIndex = 0;
89 var message = 'Warning: ' + format.replace(/%s/g, function () {
90 return args[argIndex++];
91 });
92 throw new Error(message);
93 } catch (x) {}
94 }
95 }
96
97 if (!React) {
98 {
99 throw Error( "ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM." );
100 }
101 }
102
103 var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
104 var funcArgs = Array.prototype.slice.call(arguments, 3);
105
106 try {
107 func.apply(context, funcArgs);
108 } catch (error) {
109 this.onError(error);
110 }
111 };
112
113 {
114 // In DEV mode, we swap out invokeGuardedCallback for a special version
115 // that plays more nicely with the browser's DevTools. The idea is to preserve
116 // "Pause on exceptions" behavior. Because React wraps all user-provided
117 // functions in invokeGuardedCallback, and the production version of
118 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
119 // like caught exceptions, and the DevTools won't pause unless the developer
120 // takes the extra step of enabling pause on caught exceptions. This is
121 // unintuitive, though, because even though React has caught the error, from
122 // the developer's perspective, the error is uncaught.
123 //
124 // To preserve the expected "Pause on exceptions" behavior, we don't use a
125 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
126 // DOM node, and call the user-provided callback from inside an event handler
127 // for that fake event. If the callback throws, the error is "captured" using
128 // a global event handler. But because the error happens in a different
129 // event loop context, it does not interrupt the normal program flow.
130 // Effectively, this gives us try-catch behavior without actually using
131 // try-catch. Neat!
132 // Check that the browser supports the APIs we need to implement our special
133 // DEV version of invokeGuardedCallback
134 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
135 var fakeNode = document.createElement('react');
136
137 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
138 // If document doesn't exist we know for sure we will crash in this method
139 // when we call document.createEvent(). However this can cause confusing
140 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
141 // So we preemptively throw with a better message instead.
142 if (!(typeof document !== 'undefined')) {
143 {
144 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." );
145 }
146 }
147
148 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
149 // set this to true at the beginning, then set it to false right after
150 // calling the function. If the function errors, `didError` will never be
151 // set to false. This strategy works even if the browser is flaky and
152 // fails to call our global error handler, because it doesn't rely on
153 // the error event at all.
154
155 var didError = true; // Keeps track of the value of window.event so that we can reset it
156 // during the callback to let user code access window.event in the
157 // browsers that support it.
158
159 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
160 // dispatching: https://github.com/facebook/react/issues/13688
161
162 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
163 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
164 // call the user-provided callback.
165
166 var funcArgs = Array.prototype.slice.call(arguments, 3);
167
168 function callCallback() {
169 // We immediately remove the callback from event listeners so that
170 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
171 // nested call would trigger the fake event handlers of any call higher
172 // in the stack.
173 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
174 // window.event assignment in both IE <= 10 as they throw an error
175 // "Member not found" in strict mode, and in Firefox which does not
176 // support window.event.
177
178 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
179 window.event = windowEvent;
180 }
181
182 func.apply(context, funcArgs);
183 didError = false;
184 } // Create a global error event handler. We use this to capture the value
185 // that was thrown. It's possible that this error handler will fire more
186 // than once; for example, if non-React code also calls `dispatchEvent`
187 // and a handler for that event throws. We should be resilient to most of
188 // those cases. Even if our error event handler fires more than once, the
189 // last error event is always used. If the callback actually does error,
190 // we know that the last error event is the correct one, because it's not
191 // possible for anything else to have happened in between our callback
192 // erroring and the code that follows the `dispatchEvent` call below. If
193 // the callback doesn't error, but the error event was fired, we know to
194 // ignore it because `didError` will be false, as described above.
195
196
197 var error; // Use this to track whether the error event is ever called.
198
199 var didSetError = false;
200 var isCrossOriginError = false;
201
202 function handleWindowError(event) {
203 error = event.error;
204 didSetError = true;
205
206 if (error === null && event.colno === 0 && event.lineno === 0) {
207 isCrossOriginError = true;
208 }
209
210 if (event.defaultPrevented) {
211 // Some other error handler has prevented default.
212 // Browsers silence the error report if this happens.
213 // We'll remember this to later decide whether to log it or not.
214 if (error != null && typeof error === 'object') {
215 try {
216 error._suppressLogging = true;
217 } catch (inner) {// Ignore.
218 }
219 }
220 }
221 } // Create a fake event type.
222
223
224 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
225
226 window.addEventListener('error', handleWindowError);
227 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
228 // errors, it will trigger our global error handler.
229
230 evt.initEvent(evtType, false, false);
231 fakeNode.dispatchEvent(evt);
232
233 if (windowEventDescriptor) {
234 Object.defineProperty(window, 'event', windowEventDescriptor);
235 }
236
237 if (didError) {
238 if (!didSetError) {
239 // The callback errored, but the error event never fired.
240 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.');
241 } else if (isCrossOriginError) {
242 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.');
243 }
244
245 this.onError(error);
246 } // Remove our event listeners
247
248
249 window.removeEventListener('error', handleWindowError);
250 };
251
252 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
253 }
254 }
255
256 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
257
258 var hasError = false;
259 var caughtError = null; // Used by event system to capture/rethrow the first error.
260
261 var hasRethrowError = false;
262 var rethrowError = null;
263 var reporter = {
264 onError: function (error) {
265 hasError = true;
266 caughtError = error;
267 }
268 };
269 /**
270 * Call a function while guarding against errors that happens within it.
271 * Returns an error if it throws, otherwise null.
272 *
273 * In production, this is implemented using a try-catch. The reason we don't
274 * use a try-catch directly is so that we can swap out a different
275 * implementation in DEV mode.
276 *
277 * @param {String} name of the guard to use for logging or debugging
278 * @param {Function} func The function to invoke
279 * @param {*} context The context to use when calling the function
280 * @param {...*} args Arguments for function
281 */
282
283 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
284 hasError = false;
285 caughtError = null;
286 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
287 }
288 /**
289 * Same as invokeGuardedCallback, but instead of returning an error, it stores
290 * it in a global so it can be rethrown by `rethrowCaughtError` later.
291 * TODO: See if caughtError and rethrowError can be unified.
292 *
293 * @param {String} name of the guard to use for logging or debugging
294 * @param {Function} func The function to invoke
295 * @param {*} context The context to use when calling the function
296 * @param {...*} args Arguments for function
297 */
298
299 function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
300 invokeGuardedCallback.apply(this, arguments);
301
302 if (hasError) {
303 var error = clearCaughtError();
304
305 if (!hasRethrowError) {
306 hasRethrowError = true;
307 rethrowError = error;
308 }
309 }
310 }
311 /**
312 * During execution of guarded functions we will capture the first error which
313 * we will rethrow to be handled by the top level error handler.
314 */
315
316 function rethrowCaughtError() {
317 if (hasRethrowError) {
318 var error = rethrowError;
319 hasRethrowError = false;
320 rethrowError = null;
321 throw error;
322 }
323 }
324 function hasCaughtError() {
325 return hasError;
326 }
327 function clearCaughtError() {
328 if (hasError) {
329 var error = caughtError;
330 hasError = false;
331 caughtError = null;
332 return error;
333 } else {
334 {
335 {
336 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
337 }
338 }
339 }
340 }
341
342 var getFiberCurrentPropsFromNode = null;
343 var getInstanceFromNode = null;
344 var getNodeFromInstance = null;
345 function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
346 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
347 getInstanceFromNode = getInstanceFromNodeImpl;
348 getNodeFromInstance = getNodeFromInstanceImpl;
349
350 {
351 if (!getNodeFromInstance || !getInstanceFromNode) {
352 error('EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.');
353 }
354 }
355 }
356 var validateEventDispatches;
357
358 {
359 validateEventDispatches = function (event) {
360 var dispatchListeners = event._dispatchListeners;
361 var dispatchInstances = event._dispatchInstances;
362 var listenersIsArr = Array.isArray(dispatchListeners);
363 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
364 var instancesIsArr = Array.isArray(dispatchInstances);
365 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
366
367 if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
368 error('EventPluginUtils: Invalid `event`.');
369 }
370 };
371 }
372 /**
373 * Dispatch the event to the listener.
374 * @param {SyntheticEvent} event SyntheticEvent to handle
375 * @param {function} listener Application-level callback
376 * @param {*} inst Internal component instance
377 */
378
379
380 function executeDispatch(event, listener, inst) {
381 var type = event.type || 'unknown-event';
382 event.currentTarget = getNodeFromInstance(inst);
383 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
384 event.currentTarget = null;
385 }
386 /**
387 * Standard/simple iteration through an event's collected dispatches.
388 */
389
390 function executeDispatchesInOrder(event) {
391 var dispatchListeners = event._dispatchListeners;
392 var dispatchInstances = event._dispatchInstances;
393
394 {
395 validateEventDispatches(event);
396 }
397
398 if (Array.isArray(dispatchListeners)) {
399 for (var i = 0; i < dispatchListeners.length; i++) {
400 if (event.isPropagationStopped()) {
401 break;
402 } // Listeners and Instances are two parallel arrays that are always in sync.
403
404
405 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
406 }
407 } else if (dispatchListeners) {
408 executeDispatch(event, dispatchListeners, dispatchInstances);
409 }
410
411 event._dispatchListeners = null;
412 event._dispatchInstances = null;
413 }
414
415 var FunctionComponent = 0;
416 var ClassComponent = 1;
417 var IndeterminateComponent = 2; // Before we know whether it is function or class
418
419 var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
420
421 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
422
423 var HostComponent = 5;
424 var HostText = 6;
425 var Fragment = 7;
426 var Mode = 8;
427 var ContextConsumer = 9;
428 var ContextProvider = 10;
429 var ForwardRef = 11;
430 var Profiler = 12;
431 var SuspenseComponent = 13;
432 var MemoComponent = 14;
433 var SimpleMemoComponent = 15;
434 var LazyComponent = 16;
435 var IncompleteClassComponent = 17;
436 var DehydratedFragment = 18;
437 var SuspenseListComponent = 19;
438 var FundamentalComponent = 20;
439 var ScopeComponent = 21;
440 var Block = 22;
441
442 /**
443 * Injectable ordering of event plugins.
444 */
445 var eventPluginOrder = null;
446 /**
447 * Injectable mapping from names to event plugin modules.
448 */
449
450 var namesToPlugins = {};
451 /**
452 * Recomputes the plugin list using the injected plugins and plugin ordering.
453 *
454 * @private
455 */
456
457 function recomputePluginOrdering() {
458 if (!eventPluginOrder) {
459 // Wait until an `eventPluginOrder` is injected.
460 return;
461 }
462
463 for (var pluginName in namesToPlugins) {
464 var pluginModule = namesToPlugins[pluginName];
465 var pluginIndex = eventPluginOrder.indexOf(pluginName);
466
467 if (!(pluginIndex > -1)) {
468 {
469 throw Error( "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + pluginName + "`." );
470 }
471 }
472
473 if (plugins[pluginIndex]) {
474 continue;
475 }
476
477 if (!pluginModule.extractEvents) {
478 {
479 throw Error( "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + pluginName + "` does not." );
480 }
481 }
482
483 plugins[pluginIndex] = pluginModule;
484 var publishedEvents = pluginModule.eventTypes;
485
486 for (var eventName in publishedEvents) {
487 if (!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName)) {
488 {
489 throw Error( "EventPluginRegistry: Failed to publish event `" + eventName + "` for plugin `" + pluginName + "`." );
490 }
491 }
492 }
493 }
494 }
495 /**
496 * Publishes an event so that it can be dispatched by the supplied plugin.
497 *
498 * @param {object} dispatchConfig Dispatch configuration for the event.
499 * @param {object} PluginModule Plugin publishing the event.
500 * @return {boolean} True if the event was successfully published.
501 * @private
502 */
503
504
505 function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
506 if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) {
507 {
508 throw Error( "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + eventName + "`." );
509 }
510 }
511
512 eventNameDispatchConfigs[eventName] = dispatchConfig;
513 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
514
515 if (phasedRegistrationNames) {
516 for (var phaseName in phasedRegistrationNames) {
517 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
518 var phasedRegistrationName = phasedRegistrationNames[phaseName];
519 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
520 }
521 }
522
523 return true;
524 } else if (dispatchConfig.registrationName) {
525 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
526 return true;
527 }
528
529 return false;
530 }
531 /**
532 * Publishes a registration name that is used to identify dispatched events.
533 *
534 * @param {string} registrationName Registration name to add.
535 * @param {object} PluginModule Plugin publishing the event.
536 * @private
537 */
538
539
540 function publishRegistrationName(registrationName, pluginModule, eventName) {
541 if (!!registrationNameModules[registrationName]) {
542 {
543 throw Error( "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + registrationName + "`." );
544 }
545 }
546
547 registrationNameModules[registrationName] = pluginModule;
548 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
549
550 {
551 var lowerCasedName = registrationName.toLowerCase();
552 possibleRegistrationNames[lowerCasedName] = registrationName;
553
554 if (registrationName === 'onDoubleClick') {
555 possibleRegistrationNames.ondblclick = registrationName;
556 }
557 }
558 }
559 /**
560 * Registers plugins so that they can extract and dispatch events.
561 */
562
563 /**
564 * Ordered list of injected plugins.
565 */
566
567
568 var plugins = [];
569 /**
570 * Mapping from event name to dispatch config
571 */
572
573 var eventNameDispatchConfigs = {};
574 /**
575 * Mapping from registration name to plugin module
576 */
577
578 var registrationNameModules = {};
579 /**
580 * Mapping from registration name to event name
581 */
582
583 var registrationNameDependencies = {};
584 /**
585 * Mapping from lowercase registration names to the properly cased version,
586 * used to warn in the case of missing event handlers. Available
587 * only in true.
588 * @type {Object}
589 */
590
591 var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
592
593 /**
594 * Injects an ordering of plugins (by plugin name). This allows the ordering
595 * to be decoupled from injection of the actual plugins so that ordering is
596 * always deterministic regardless of packaging, on-the-fly injection, etc.
597 *
598 * @param {array} InjectedEventPluginOrder
599 * @internal
600 */
601
602 function injectEventPluginOrder(injectedEventPluginOrder) {
603 if (!!eventPluginOrder) {
604 {
605 throw Error( "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." );
606 }
607 } // Clone the ordering so it cannot be dynamically mutated.
608
609
610 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
611 recomputePluginOrdering();
612 }
613 /**
614 * Injects plugins to be used by plugin event system. The plugin names must be
615 * in the ordering injected by `injectEventPluginOrder`.
616 *
617 * Plugins can be injected as part of page initialization or on-the-fly.
618 *
619 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
620 * @internal
621 */
622
623 function injectEventPluginsByName(injectedNamesToPlugins) {
624 var isOrderingDirty = false;
625
626 for (var pluginName in injectedNamesToPlugins) {
627 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
628 continue;
629 }
630
631 var pluginModule = injectedNamesToPlugins[pluginName];
632
633 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
634 if (!!namesToPlugins[pluginName]) {
635 {
636 throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + pluginName + "`." );
637 }
638 }
639
640 namesToPlugins[pluginName] = pluginModule;
641 isOrderingDirty = true;
642 }
643 }
644
645 if (isOrderingDirty) {
646 recomputePluginOrdering();
647 }
648 }
649
650 var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
651
652 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
653 var _assign = ReactInternals.assign;
654
655 var PLUGIN_EVENT_SYSTEM = 1;
656 var IS_REPLAYED = 1 << 5;
657 var IS_FIRST_ANCESTOR = 1 << 6;
658
659 var restoreImpl = null;
660 var restoreTarget = null;
661 var restoreQueue = null;
662
663 function restoreStateOfTarget(target) {
664 // We perform this translation at the end of the event loop so that we
665 // always receive the correct fiber here
666 var internalInstance = getInstanceFromNode(target);
667
668 if (!internalInstance) {
669 // Unmounted
670 return;
671 }
672
673 if (!(typeof restoreImpl === 'function')) {
674 {
675 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." );
676 }
677 }
678
679 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
680
681 if (stateNode) {
682 var _props = getFiberCurrentPropsFromNode(stateNode);
683
684 restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
685 }
686 }
687
688 function setRestoreImplementation(impl) {
689 restoreImpl = impl;
690 }
691 function enqueueStateRestore(target) {
692 if (restoreTarget) {
693 if (restoreQueue) {
694 restoreQueue.push(target);
695 } else {
696 restoreQueue = [target];
697 }
698 } else {
699 restoreTarget = target;
700 }
701 }
702 function needsStateRestore() {
703 return restoreTarget !== null || restoreQueue !== null;
704 }
705 function restoreStateIfNeeded() {
706 if (!restoreTarget) {
707 return;
708 }
709
710 var target = restoreTarget;
711 var queuedTargets = restoreQueue;
712 restoreTarget = null;
713 restoreQueue = null;
714 restoreStateOfTarget(target);
715
716 if (queuedTargets) {
717 for (var i = 0; i < queuedTargets.length; i++) {
718 restoreStateOfTarget(queuedTargets[i]);
719 }
720 }
721 }
722
723 var enableProfilerTimer = true; // Trace which interactions trigger each commit.
724
725 var enableDeprecatedFlareAPI = false; // Experimental Host Component support.
726
727 var enableFundamentalAPI = false; // Experimental Scope support.
728 var warnAboutStringRefs = false;
729
730 // the renderer. Such as when we're dispatching events or if third party
731 // libraries need to call batchedUpdates. Eventually, this API will go away when
732 // everything is batched by default. We'll then have a similar API to opt-out of
733 // scheduled work and instead do synchronous work.
734 // Defaults
735
736 var batchedUpdatesImpl = function (fn, bookkeeping) {
737 return fn(bookkeeping);
738 };
739
740 var discreteUpdatesImpl = function (fn, a, b, c, d) {
741 return fn(a, b, c, d);
742 };
743
744 var flushDiscreteUpdatesImpl = function () {};
745
746 var batchedEventUpdatesImpl = batchedUpdatesImpl;
747 var isInsideEventHandler = false;
748 var isBatchingEventUpdates = false;
749
750 function finishEventHandler() {
751 // Here we wait until all updates have propagated, which is important
752 // when using controlled components within layers:
753 // https://github.com/facebook/react/issues/1698
754 // Then we restore state of any controlled component.
755 var controlledComponentsHavePendingUpdates = needsStateRestore();
756
757 if (controlledComponentsHavePendingUpdates) {
758 // If a controlled event was fired, we may need to restore the state of
759 // the DOM node back to the controlled value. This is necessary when React
760 // bails out of the update without touching the DOM.
761 flushDiscreteUpdatesImpl();
762 restoreStateIfNeeded();
763 }
764 }
765
766 function batchedUpdates(fn, bookkeeping) {
767 if (isInsideEventHandler) {
768 // If we are currently inside another batch, we need to wait until it
769 // fully completes before restoring state.
770 return fn(bookkeeping);
771 }
772
773 isInsideEventHandler = true;
774
775 try {
776 return batchedUpdatesImpl(fn, bookkeeping);
777 } finally {
778 isInsideEventHandler = false;
779 finishEventHandler();
780 }
781 }
782 function batchedEventUpdates(fn, a, b) {
783 if (isBatchingEventUpdates) {
784 // If we are currently inside another batch, we need to wait until it
785 // fully completes before restoring state.
786 return fn(a, b);
787 }
788
789 isBatchingEventUpdates = true;
790
791 try {
792 return batchedEventUpdatesImpl(fn, a, b);
793 } finally {
794 isBatchingEventUpdates = false;
795 finishEventHandler();
796 }
797 } // This is for the React Flare event system
798 function discreteUpdates(fn, a, b, c, d) {
799 var prevIsInsideEventHandler = isInsideEventHandler;
800 isInsideEventHandler = true;
801
802 try {
803 return discreteUpdatesImpl(fn, a, b, c, d);
804 } finally {
805 isInsideEventHandler = prevIsInsideEventHandler;
806
807 if (!isInsideEventHandler) {
808 finishEventHandler();
809 }
810 }
811 }
812 function flushDiscreteUpdatesIfNeeded(timeStamp) {
813 // event.timeStamp isn't overly reliable due to inconsistencies in
814 // how different browsers have historically provided the time stamp.
815 // Some browsers provide high-resolution time stamps for all events,
816 // some provide low-resolution time stamps for all events. FF < 52
817 // even mixes both time stamps together. Some browsers even report
818 // negative time stamps or time stamps that are 0 (iOS9) in some cases.
819 // Given we are only comparing two time stamps with equality (!==),
820 // we are safe from the resolution differences. If the time stamp is 0
821 // we bail-out of preventing the flush, which can affect semantics,
822 // such as if an earlier flush removes or adds event listeners that
823 // are fired in the subsequent flush. However, this is the same
824 // behaviour as we had before this change, so the risks are low.
825 if (!isInsideEventHandler && (!enableDeprecatedFlareAPI )) {
826 flushDiscreteUpdatesImpl();
827 }
828 }
829 function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {
830 batchedUpdatesImpl = _batchedUpdatesImpl;
831 discreteUpdatesImpl = _discreteUpdatesImpl;
832 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
833 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
834 }
835
836 var DiscreteEvent = 0;
837 var UserBlockingEvent = 1;
838 var ContinuousEvent = 2;
839
840 var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
841 var _ReactInternals$Sched = ReactInternals$1.Scheduler,
842 unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback,
843 unstable_now = _ReactInternals$Sched.unstable_now,
844 unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback,
845 unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield,
846 unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint,
847 unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode,
848 unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority,
849 unstable_next = _ReactInternals$Sched.unstable_next,
850 unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution,
851 unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution,
852 unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel,
853 unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority,
854 unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority,
855 unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority,
856 unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority,
857 unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority,
858 unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate,
859 unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
860
861 // A reserved attribute.
862 // It is handled by React separately and shouldn't be written to the DOM.
863 var RESERVED = 0; // A simple string attribute.
864 // Attributes that aren't in the whitelist are presumed to have this type.
865
866 var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
867 // "enumerated" attributes with "true" and "false" as possible values.
868 // When true, it should be set to a "true" string.
869 // When false, it should be set to a "false" string.
870
871 var BOOLEANISH_STRING = 2; // A real boolean attribute.
872 // When true, it should be present (set either to an empty string or its name).
873 // When false, it should be omitted.
874
875 var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
876 // When true, it should be present (set either to an empty string or its name).
877 // When false, it should be omitted.
878 // For any other value, should be present with that value.
879
880 var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
881 // When falsy, it should be removed.
882
883 var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
884 // When falsy, it should be removed.
885
886 var POSITIVE_NUMERIC = 6;
887
888 /* eslint-disable max-len */
889 var 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";
890 /* eslint-enable max-len */
891
892 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
893 var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
894 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
895 var hasOwnProperty = Object.prototype.hasOwnProperty;
896 var illegalAttributeNameCache = {};
897 var validatedAttributeNameCache = {};
898 function isAttributeNameSafe(attributeName) {
899 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
900 return true;
901 }
902
903 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
904 return false;
905 }
906
907 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
908 validatedAttributeNameCache[attributeName] = true;
909 return true;
910 }
911
912 illegalAttributeNameCache[attributeName] = true;
913
914 {
915 error('Invalid attribute name: `%s`', attributeName);
916 }
917
918 return false;
919 }
920 function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
921 if (propertyInfo !== null) {
922 return propertyInfo.type === RESERVED;
923 }
924
925 if (isCustomComponentTag) {
926 return false;
927 }
928
929 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
930 return true;
931 }
932
933 return false;
934 }
935 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
936 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
937 return false;
938 }
939
940 switch (typeof value) {
941 case 'function': // $FlowIssue symbol is perfectly valid here
942
943 case 'symbol':
944 // eslint-disable-line
945 return true;
946
947 case 'boolean':
948 {
949 if (isCustomComponentTag) {
950 return false;
951 }
952
953 if (propertyInfo !== null) {
954 return !propertyInfo.acceptsBooleans;
955 } else {
956 var prefix = name.toLowerCase().slice(0, 5);
957 return prefix !== 'data-' && prefix !== 'aria-';
958 }
959 }
960
961 default:
962 return false;
963 }
964 }
965 function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
966 if (value === null || typeof value === 'undefined') {
967 return true;
968 }
969
970 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
971 return true;
972 }
973
974 if (isCustomComponentTag) {
975 return false;
976 }
977
978 if (propertyInfo !== null) {
979 switch (propertyInfo.type) {
980 case BOOLEAN:
981 return !value;
982
983 case OVERLOADED_BOOLEAN:
984 return value === false;
985
986 case NUMERIC:
987 return isNaN(value);
988
989 case POSITIVE_NUMERIC:
990 return isNaN(value) || value < 1;
991 }
992 }
993
994 return false;
995 }
996 function getPropertyInfo(name) {
997 return properties.hasOwnProperty(name) ? properties[name] : null;
998 }
999
1000 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL) {
1001 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
1002 this.attributeName = attributeName;
1003 this.attributeNamespace = attributeNamespace;
1004 this.mustUseProperty = mustUseProperty;
1005 this.propertyName = name;
1006 this.type = type;
1007 this.sanitizeURL = sanitizeURL;
1008 } // When adding attributes to this list, be sure to also add them to
1009 // the `possibleStandardNames` module to ensure casing and incorrect
1010 // name warnings.
1011
1012
1013 var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
1014
1015 var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
1016 // elements (not just inputs). Now that ReactDOMInput assigns to the
1017 // defaultValue property -- do we need this?
1018 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];
1019
1020 reservedProps.forEach(function (name) {
1021 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
1022 name, // attributeName
1023 null, // attributeNamespace
1024 false);
1025 }); // A few React string attributes have a different name.
1026 // This is a mapping from React prop names to the attribute names.
1027
1028 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
1029 var name = _ref[0],
1030 attributeName = _ref[1];
1031 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1032 attributeName, // attributeName
1033 null, // attributeNamespace
1034 false);
1035 }); // These are "enumerated" HTML attributes that accept "true" and "false".
1036 // In React, we let users pass `true` and `false` even though technically
1037 // these aren't boolean attributes (they are coerced to strings).
1038
1039 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
1040 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
1041 name.toLowerCase(), // attributeName
1042 null, // attributeNamespace
1043 false);
1044 }); // These are "enumerated" SVG attributes that accept "true" and "false".
1045 // In React, we let users pass `true` and `false` even though technically
1046 // these aren't boolean attributes (they are coerced to strings).
1047 // Since these are SVG attributes, their attribute names are case-sensitive.
1048
1049 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
1050 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
1051 name, // attributeName
1052 null, // attributeNamespace
1053 false);
1054 }); // These are HTML boolean attributes.
1055
1056 ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
1057 // on the client side because the browsers are inconsistent. Instead we call focus().
1058 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
1059 'itemScope'].forEach(function (name) {
1060 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
1061 name.toLowerCase(), // attributeName
1062 null, // attributeNamespace
1063 false);
1064 }); // These are the few React props that we set as DOM properties
1065 // rather than attributes. These are all booleans.
1066
1067 ['checked', // Note: `option.selected` is not updated if `select.multiple` is
1068 // disabled with `removeAttribute`. We have special logic for handling this.
1069 'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,
1070 // you'll need to set attributeName to name.toLowerCase()
1071 // instead in the assignment below.
1072 ].forEach(function (name) {
1073 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
1074 name, // attributeName
1075 null, // attributeNamespace
1076 false);
1077 }); // These are HTML attributes that are "overloaded booleans": they behave like
1078 // booleans, but can also accept a string value.
1079
1080 ['capture', 'download' // NOTE: if you add a camelCased prop to this list,
1081 // you'll need to set attributeName to name.toLowerCase()
1082 // instead in the assignment below.
1083 ].forEach(function (name) {
1084 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
1085 name, // attributeName
1086 null, // attributeNamespace
1087 false);
1088 }); // These are HTML attributes that must be positive numbers.
1089
1090 ['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
1091 // you'll need to set attributeName to name.toLowerCase()
1092 // instead in the assignment below.
1093 ].forEach(function (name) {
1094 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
1095 name, // attributeName
1096 null, // attributeNamespace
1097 false);
1098 }); // These are HTML attributes that must be numbers.
1099
1100 ['rowSpan', 'start'].forEach(function (name) {
1101 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
1102 name.toLowerCase(), // attributeName
1103 null, // attributeNamespace
1104 false);
1105 });
1106 var CAMELIZE = /[\-\:]([a-z])/g;
1107
1108 var capitalize = function (token) {
1109 return token[1].toUpperCase();
1110 }; // This is a list of all SVG attributes that need special casing, namespacing,
1111 // or boolean value assignment. Regular attributes that just accept strings
1112 // and have the same names are omitted, just like in the HTML whitelist.
1113 // Some of these attributes can be hard to find. This list was created by
1114 // scraping the MDN documentation.
1115
1116
1117 ['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,
1118 // you'll need to set attributeName to name.toLowerCase()
1119 // instead in the assignment below.
1120 ].forEach(function (attributeName) {
1121 var name = attributeName.replace(CAMELIZE, capitalize);
1122 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1123 attributeName, null, // attributeNamespace
1124 false);
1125 }); // String SVG attributes with the xlink namespace.
1126
1127 ['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
1128 // you'll need to set attributeName to name.toLowerCase()
1129 // instead in the assignment below.
1130 ].forEach(function (attributeName) {
1131 var name = attributeName.replace(CAMELIZE, capitalize);
1132 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1133 attributeName, 'http://www.w3.org/1999/xlink', false);
1134 }); // String SVG attributes with the xml namespace.
1135
1136 ['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
1137 // you'll need to set attributeName to name.toLowerCase()
1138 // instead in the assignment below.
1139 ].forEach(function (attributeName) {
1140 var name = attributeName.replace(CAMELIZE, capitalize);
1141 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
1142 attributeName, 'http://www.w3.org/XML/1998/namespace', false);
1143 }); // These attribute exists both in HTML and SVG.
1144 // The attribute name is case-sensitive in SVG so we can't just use
1145 // the React name like we do for attributes that exist only in HTML.
1146
1147 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
1148 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
1149 attributeName.toLowerCase(), // attributeName
1150 null, // attributeNamespace
1151 false);
1152 }); // These attributes accept URLs. These must not allow javascript: URLS.
1153 // These will also need to accept Trusted Types object in the future.
1154
1155 var xlinkHref = 'xlinkHref';
1156 properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
1157 'xlink:href', 'http://www.w3.org/1999/xlink', true);
1158 ['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
1159 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
1160 attributeName.toLowerCase(), // attributeName
1161 null, // attributeNamespace
1162 true);
1163 });
1164
1165 var ReactDebugCurrentFrame = null;
1166
1167 {
1168 ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1169 } // A javascript: URL can contain leading C0 control or \u0020 SPACE,
1170 // and any newline or tab are filtered out as if they're not part of the URL.
1171 // https://url.spec.whatwg.org/#url-parsing
1172 // Tab or newline are defined as \r\n\t:
1173 // https://infra.spec.whatwg.org/#ascii-tab-or-newline
1174 // A C0 control is a code point in the range \u0000 NULL to \u001F
1175 // INFORMATION SEPARATOR ONE, inclusive:
1176 // https://infra.spec.whatwg.org/#c0-control-or-space
1177
1178 /* eslint-disable max-len */
1179
1180
1181 var 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;
1182 var didWarn = false;
1183
1184 function sanitizeURL(url) {
1185 {
1186 if (!didWarn && isJavaScriptProtocol.test(url)) {
1187 didWarn = true;
1188
1189 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));
1190 }
1191 }
1192 }
1193
1194 /**
1195 * Get the value for a property on a node. Only used in DEV for SSR validation.
1196 * The "expected" argument is used as a hint of what the expected value is.
1197 * Some properties have multiple equivalent values.
1198 */
1199 function getValueForProperty(node, name, expected, propertyInfo) {
1200 {
1201 if (propertyInfo.mustUseProperty) {
1202 var propertyName = propertyInfo.propertyName;
1203 return node[propertyName];
1204 } else {
1205 if ( propertyInfo.sanitizeURL) {
1206 // If we haven't fully disabled javascript: URLs, and if
1207 // the hydration is successful of a javascript: URL, we
1208 // still want to warn on the client.
1209 sanitizeURL('' + expected);
1210 }
1211
1212 var attributeName = propertyInfo.attributeName;
1213 var stringValue = null;
1214
1215 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
1216 if (node.hasAttribute(attributeName)) {
1217 var value = node.getAttribute(attributeName);
1218
1219 if (value === '') {
1220 return true;
1221 }
1222
1223 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1224 return value;
1225 }
1226
1227 if (value === '' + expected) {
1228 return expected;
1229 }
1230
1231 return value;
1232 }
1233 } else if (node.hasAttribute(attributeName)) {
1234 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1235 // We had an attribute but shouldn't have had one, so read it
1236 // for the error message.
1237 return node.getAttribute(attributeName);
1238 }
1239
1240 if (propertyInfo.type === BOOLEAN) {
1241 // If this was a boolean, it doesn't matter what the value is
1242 // the fact that we have it is the same as the expected.
1243 return expected;
1244 } // Even if this property uses a namespace we use getAttribute
1245 // because we assume its namespaced name is the same as our config.
1246 // To use getAttributeNS we need the local name which we don't have
1247 // in our config atm.
1248
1249
1250 stringValue = node.getAttribute(attributeName);
1251 }
1252
1253 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
1254 return stringValue === null ? expected : stringValue;
1255 } else if (stringValue === '' + expected) {
1256 return expected;
1257 } else {
1258 return stringValue;
1259 }
1260 }
1261 }
1262 }
1263 /**
1264 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
1265 * The third argument is used as a hint of what the expected value is. Some
1266 * attributes have multiple equivalent values.
1267 */
1268
1269 function getValueForAttribute(node, name, expected) {
1270 {
1271 if (!isAttributeNameSafe(name)) {
1272 return;
1273 }
1274
1275 if (!node.hasAttribute(name)) {
1276 return expected === undefined ? undefined : null;
1277 }
1278
1279 var value = node.getAttribute(name);
1280
1281 if (value === '' + expected) {
1282 return expected;
1283 }
1284
1285 return value;
1286 }
1287 }
1288 /**
1289 * Sets the value for a property on a node.
1290 *
1291 * @param {DOMElement} node
1292 * @param {string} name
1293 * @param {*} value
1294 */
1295
1296 function setValueForProperty(node, name, value, isCustomComponentTag) {
1297 var propertyInfo = getPropertyInfo(name);
1298
1299 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
1300 return;
1301 }
1302
1303 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
1304 value = null;
1305 } // If the prop isn't in the special list, treat it as a simple attribute.
1306
1307
1308 if (isCustomComponentTag || propertyInfo === null) {
1309 if (isAttributeNameSafe(name)) {
1310 var _attributeName = name;
1311
1312 if (value === null) {
1313 node.removeAttribute(_attributeName);
1314 } else {
1315 node.setAttribute(_attributeName, '' + value);
1316 }
1317 }
1318
1319 return;
1320 }
1321
1322 var mustUseProperty = propertyInfo.mustUseProperty;
1323
1324 if (mustUseProperty) {
1325 var propertyName = propertyInfo.propertyName;
1326
1327 if (value === null) {
1328 var type = propertyInfo.type;
1329 node[propertyName] = type === BOOLEAN ? false : '';
1330 } else {
1331 // Contrary to `setAttribute`, object properties are properly
1332 // `toString`ed by IE8/9.
1333 node[propertyName] = value;
1334 }
1335
1336 return;
1337 } // The rest are treated as attributes with special cases.
1338
1339
1340 var attributeName = propertyInfo.attributeName,
1341 attributeNamespace = propertyInfo.attributeNamespace;
1342
1343 if (value === null) {
1344 node.removeAttribute(attributeName);
1345 } else {
1346 var _type = propertyInfo.type;
1347 var attributeValue;
1348
1349 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
1350 // If attribute type is boolean, we know for sure it won't be an execution sink
1351 // and we won't require Trusted Type here.
1352 attributeValue = '';
1353 } else {
1354 // `setAttribute` with objects becomes only `[object]` in IE8/9,
1355 // ('' + value) makes it output the correct toString()-value.
1356 {
1357 attributeValue = '' + value;
1358 }
1359
1360 if (propertyInfo.sanitizeURL) {
1361 sanitizeURL(attributeValue.toString());
1362 }
1363 }
1364
1365 if (attributeNamespace) {
1366 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
1367 } else {
1368 node.setAttribute(attributeName, attributeValue);
1369 }
1370 }
1371 }
1372
1373 var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1374 function describeComponentFrame (name, source, ownerName) {
1375 var sourceInfo = '';
1376
1377 if (source) {
1378 var path = source.fileName;
1379 var fileName = path.replace(BEFORE_SLASH_RE, '');
1380
1381 {
1382 // In DEV, include code for a common special case:
1383 // prefer "folder/index.js" instead of just "index.js".
1384 if (/^index\./.test(fileName)) {
1385 var match = path.match(BEFORE_SLASH_RE);
1386
1387 if (match) {
1388 var pathBeforeSlash = match[1];
1389
1390 if (pathBeforeSlash) {
1391 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1392 fileName = folderName + '/' + fileName;
1393 }
1394 }
1395 }
1396 }
1397
1398 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1399 } else if (ownerName) {
1400 sourceInfo = ' (created by ' + ownerName + ')';
1401 }
1402
1403 return '\n in ' + (name || 'Unknown') + sourceInfo;
1404 }
1405
1406 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
1407 // nor polyfill, then a plain number is used for performance.
1408 var hasSymbol = typeof Symbol === 'function' && Symbol.for;
1409 var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
1410 var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
1411 var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
1412 var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
1413 var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
1414 var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
1415 var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
1416 var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
1417 var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
1418 var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
1419 var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
1420 var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
1421 var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
1422 var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
1423 var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
1424 var FAUX_ITERATOR_SYMBOL = '@@iterator';
1425 function getIteratorFn(maybeIterable) {
1426 if (maybeIterable === null || typeof maybeIterable !== 'object') {
1427 return null;
1428 }
1429
1430 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
1431
1432 if (typeof maybeIterator === 'function') {
1433 return maybeIterator;
1434 }
1435
1436 return null;
1437 }
1438
1439 var Uninitialized = -1;
1440 var Pending = 0;
1441 var Resolved = 1;
1442 var Rejected = 2;
1443 function refineResolvedLazyComponent(lazyComponent) {
1444 return lazyComponent._status === Resolved ? lazyComponent._result : null;
1445 }
1446 function initializeLazyComponentType(lazyComponent) {
1447 if (lazyComponent._status === Uninitialized) {
1448 lazyComponent._status = Pending;
1449 var ctor = lazyComponent._ctor;
1450 var thenable = ctor();
1451 lazyComponent._result = thenable;
1452 thenable.then(function (moduleObject) {
1453 if (lazyComponent._status === Pending) {
1454 var defaultExport = moduleObject.default;
1455
1456 {
1457 if (defaultExport === undefined) {
1458 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);
1459 }
1460 }
1461
1462 lazyComponent._status = Resolved;
1463 lazyComponent._result = defaultExport;
1464 }
1465 }, function (error) {
1466 if (lazyComponent._status === Pending) {
1467 lazyComponent._status = Rejected;
1468 lazyComponent._result = error;
1469 }
1470 });
1471 }
1472 }
1473
1474 function getWrappedName(outerType, innerType, wrapperName) {
1475 var functionName = innerType.displayName || innerType.name || '';
1476 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
1477 }
1478
1479 function getComponentName(type) {
1480 if (type == null) {
1481 // Host root, text node or just invalid type.
1482 return null;
1483 }
1484
1485 {
1486 if (typeof type.tag === 'number') {
1487 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
1488 }
1489 }
1490
1491 if (typeof type === 'function') {
1492 return type.displayName || type.name || null;
1493 }
1494
1495 if (typeof type === 'string') {
1496 return type;
1497 }
1498
1499 switch (type) {
1500 case REACT_FRAGMENT_TYPE:
1501 return 'Fragment';
1502
1503 case REACT_PORTAL_TYPE:
1504 return 'Portal';
1505
1506 case REACT_PROFILER_TYPE:
1507 return "Profiler";
1508
1509 case REACT_STRICT_MODE_TYPE:
1510 return 'StrictMode';
1511
1512 case REACT_SUSPENSE_TYPE:
1513 return 'Suspense';
1514
1515 case REACT_SUSPENSE_LIST_TYPE:
1516 return 'SuspenseList';
1517 }
1518
1519 if (typeof type === 'object') {
1520 switch (type.$$typeof) {
1521 case REACT_CONTEXT_TYPE:
1522 return 'Context.Consumer';
1523
1524 case REACT_PROVIDER_TYPE:
1525 return 'Context.Provider';
1526
1527 case REACT_FORWARD_REF_TYPE:
1528 return getWrappedName(type, type.render, 'ForwardRef');
1529
1530 case REACT_MEMO_TYPE:
1531 return getComponentName(type.type);
1532
1533 case REACT_BLOCK_TYPE:
1534 return getComponentName(type.render);
1535
1536 case REACT_LAZY_TYPE:
1537 {
1538 var thenable = type;
1539 var resolvedThenable = refineResolvedLazyComponent(thenable);
1540
1541 if (resolvedThenable) {
1542 return getComponentName(resolvedThenable);
1543 }
1544
1545 break;
1546 }
1547 }
1548 }
1549
1550 return null;
1551 }
1552
1553 var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
1554
1555 function describeFiber(fiber) {
1556 switch (fiber.tag) {
1557 case HostRoot:
1558 case HostPortal:
1559 case HostText:
1560 case Fragment:
1561 case ContextProvider:
1562 case ContextConsumer:
1563 return '';
1564
1565 default:
1566 var owner = fiber._debugOwner;
1567 var source = fiber._debugSource;
1568 var name = getComponentName(fiber.type);
1569 var ownerName = null;
1570
1571 if (owner) {
1572 ownerName = getComponentName(owner.type);
1573 }
1574
1575 return describeComponentFrame(name, source, ownerName);
1576 }
1577 }
1578
1579 function getStackByFiberInDevAndProd(workInProgress) {
1580 var info = '';
1581 var node = workInProgress;
1582
1583 do {
1584 info += describeFiber(node);
1585 node = node.return;
1586 } while (node);
1587
1588 return info;
1589 }
1590 var current = null;
1591 var isRendering = false;
1592 function getCurrentFiberOwnerNameInDevOrNull() {
1593 {
1594 if (current === null) {
1595 return null;
1596 }
1597
1598 var owner = current._debugOwner;
1599
1600 if (owner !== null && typeof owner !== 'undefined') {
1601 return getComponentName(owner.type);
1602 }
1603 }
1604
1605 return null;
1606 }
1607 function getCurrentFiberStackInDev() {
1608 {
1609 if (current === null) {
1610 return '';
1611 } // Safe because if current fiber exists, we are reconciling,
1612 // and it is guaranteed to be the work-in-progress version.
1613
1614
1615 return getStackByFiberInDevAndProd(current);
1616 }
1617 }
1618 function resetCurrentFiber() {
1619 {
1620 ReactDebugCurrentFrame$1.getCurrentStack = null;
1621 current = null;
1622 isRendering = false;
1623 }
1624 }
1625 function setCurrentFiber(fiber) {
1626 {
1627 ReactDebugCurrentFrame$1.getCurrentStack = getCurrentFiberStackInDev;
1628 current = fiber;
1629 isRendering = false;
1630 }
1631 }
1632 function setIsRendering(rendering) {
1633 {
1634 isRendering = rendering;
1635 }
1636 }
1637
1638 // Flow does not allow string concatenation of most non-string types. To work
1639 // around this limitation, we use an opaque type that can only be obtained by
1640 // passing the value through getToStringValue first.
1641 function toString(value) {
1642 return '' + value;
1643 }
1644 function getToStringValue(value) {
1645 switch (typeof value) {
1646 case 'boolean':
1647 case 'number':
1648 case 'object':
1649 case 'string':
1650 case 'undefined':
1651 return value;
1652
1653 default:
1654 // function, symbol are assigned as empty strings
1655 return '';
1656 }
1657 }
1658
1659 /**
1660 * Copyright (c) 2013-present, Facebook, Inc.
1661 *
1662 * This source code is licensed under the MIT license found in the
1663 * LICENSE file in the root directory of this source tree.
1664 */
1665
1666 var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1667
1668 var ReactPropTypesSecret_1 = ReactPropTypesSecret;
1669
1670 var printWarning$1 = function() {};
1671
1672 {
1673 var ReactPropTypesSecret$1 = ReactPropTypesSecret_1;
1674 var loggedTypeFailures = {};
1675 var has = Function.call.bind(Object.prototype.hasOwnProperty);
1676
1677 printWarning$1 = function(text) {
1678 var message = 'Warning: ' + text;
1679 if (typeof console !== 'undefined') {
1680 console.error(message);
1681 }
1682 try {
1683 // --- Welcome to debugging React ---
1684 // This error was thrown as a convenience so that you can use this stack
1685 // to find the callsite that caused this warning to fire.
1686 throw new Error(message);
1687 } catch (x) {}
1688 };
1689 }
1690
1691 /**
1692 * Assert that the values match with the type specs.
1693 * Error messages are memorized and will only be shown once.
1694 *
1695 * @param {object} typeSpecs Map of name to a ReactPropType
1696 * @param {object} values Runtime values that need to be type-checked
1697 * @param {string} location e.g. "prop", "context", "child context"
1698 * @param {string} componentName Name of the component for error messages.
1699 * @param {?Function} getStack Returns the component stack.
1700 * @private
1701 */
1702 function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1703 {
1704 for (var typeSpecName in typeSpecs) {
1705 if (has(typeSpecs, typeSpecName)) {
1706 var error;
1707 // Prop type validation may throw. In case they do, we don't want to
1708 // fail the render phase where it didn't fail before. So we log it.
1709 // After these have been cleaned up, we'll let them throw.
1710 try {
1711 // This is intentionally an invariant that gets caught. It's the same
1712 // behavior as without this statement except with a better message.
1713 if (typeof typeSpecs[typeSpecName] !== 'function') {
1714 var err = Error(
1715 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1716 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1717 );
1718 err.name = 'Invariant Violation';
1719 throw err;
1720 }
1721 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret$1);
1722 } catch (ex) {
1723 error = ex;
1724 }
1725 if (error && !(error instanceof Error)) {
1726 printWarning$1(
1727 (componentName || 'React class') + ': type specification of ' +
1728 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1729 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1730 'You may have forgotten to pass an argument to the type checker ' +
1731 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1732 'shape all require an argument).'
1733 );
1734 }
1735 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1736 // Only monitor this failure once because there tends to be a lot of the
1737 // same error.
1738 loggedTypeFailures[error.message] = true;
1739
1740 var stack = getStack ? getStack() : '';
1741
1742 printWarning$1(
1743 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1744 );
1745 }
1746 }
1747 }
1748 }
1749 }
1750
1751 /**
1752 * Resets warning cache when testing.
1753 *
1754 * @private
1755 */
1756 checkPropTypes.resetWarningCache = function() {
1757 {
1758 loggedTypeFailures = {};
1759 }
1760 };
1761
1762 var checkPropTypes_1 = checkPropTypes;
1763
1764 var ReactDebugCurrentFrame$2 = null;
1765 var ReactControlledValuePropTypes = {
1766 checkPropTypes: null
1767 };
1768
1769 {
1770 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
1771 var hasReadOnlyValue = {
1772 button: true,
1773 checkbox: true,
1774 image: true,
1775 hidden: true,
1776 radio: true,
1777 reset: true,
1778 submit: true
1779 };
1780 var propTypes = {
1781 value: function (props, propName, componentName) {
1782 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null || enableDeprecatedFlareAPI ) {
1783 return null;
1784 }
1785
1786 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`.');
1787 },
1788 checked: function (props, propName, componentName) {
1789 if (props.onChange || props.readOnly || props.disabled || props[propName] == null || enableDeprecatedFlareAPI ) {
1790 return null;
1791 }
1792
1793 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`.');
1794 }
1795 };
1796 /**
1797 * Provide a linked `value` attribute for controlled forms. You should not use
1798 * this outside of the ReactDOM controlled form components.
1799 */
1800
1801 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
1802 checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$2.getStackAddendum);
1803 };
1804 }
1805
1806 function isCheckable(elem) {
1807 var type = elem.type;
1808 var nodeName = elem.nodeName;
1809 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
1810 }
1811
1812 function getTracker(node) {
1813 return node._valueTracker;
1814 }
1815
1816 function detachTracker(node) {
1817 node._valueTracker = null;
1818 }
1819
1820 function getValueFromNode(node) {
1821 var value = '';
1822
1823 if (!node) {
1824 return value;
1825 }
1826
1827 if (isCheckable(node)) {
1828 value = node.checked ? 'true' : 'false';
1829 } else {
1830 value = node.value;
1831 }
1832
1833 return value;
1834 }
1835
1836 function trackValueOnNode(node) {
1837 var valueField = isCheckable(node) ? 'checked' : 'value';
1838 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
1839 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
1840 // and don't track value will cause over reporting of changes,
1841 // but it's better then a hard failure
1842 // (needed for certain tests that spyOn input values and Safari)
1843
1844 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
1845 return;
1846 }
1847
1848 var get = descriptor.get,
1849 set = descriptor.set;
1850 Object.defineProperty(node, valueField, {
1851 configurable: true,
1852 get: function () {
1853 return get.call(this);
1854 },
1855 set: function (value) {
1856 currentValue = '' + value;
1857 set.call(this, value);
1858 }
1859 }); // We could've passed this the first time
1860 // but it triggers a bug in IE11 and Edge 14/15.
1861 // Calling defineProperty() again should be equivalent.
1862 // https://github.com/facebook/react/issues/11768
1863
1864 Object.defineProperty(node, valueField, {
1865 enumerable: descriptor.enumerable
1866 });
1867 var tracker = {
1868 getValue: function () {
1869 return currentValue;
1870 },
1871 setValue: function (value) {
1872 currentValue = '' + value;
1873 },
1874 stopTracking: function () {
1875 detachTracker(node);
1876 delete node[valueField];
1877 }
1878 };
1879 return tracker;
1880 }
1881
1882 function track(node) {
1883 if (getTracker(node)) {
1884 return;
1885 } // TODO: Once it's just Fiber we can move this to node._wrapperState
1886
1887
1888 node._valueTracker = trackValueOnNode(node);
1889 }
1890 function updateValueIfChanged(node) {
1891 if (!node) {
1892 return false;
1893 }
1894
1895 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
1896 // that trying again will succeed
1897
1898 if (!tracker) {
1899 return true;
1900 }
1901
1902 var lastValue = tracker.getValue();
1903 var nextValue = getValueFromNode(node);
1904
1905 if (nextValue !== lastValue) {
1906 tracker.setValue(nextValue);
1907 return true;
1908 }
1909
1910 return false;
1911 }
1912
1913 var didWarnValueDefaultValue = false;
1914 var didWarnCheckedDefaultChecked = false;
1915 var didWarnControlledToUncontrolled = false;
1916 var didWarnUncontrolledToControlled = false;
1917
1918 function isControlled(props) {
1919 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
1920 return usesChecked ? props.checked != null : props.value != null;
1921 }
1922 /**
1923 * Implements an <input> host component that allows setting these optional
1924 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
1925 *
1926 * If `checked` or `value` are not supplied (or null/undefined), user actions
1927 * that affect the checked state or value will trigger updates to the element.
1928 *
1929 * If they are supplied (and not null/undefined), the rendered element will not
1930 * trigger updates to the element. Instead, the props must change in order for
1931 * the rendered element to be updated.
1932 *
1933 * The rendered element will be initialized as unchecked (or `defaultChecked`)
1934 * with an empty value (or `defaultValue`).
1935 *
1936 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
1937 */
1938
1939
1940 function getHostProps(element, props) {
1941 var node = element;
1942 var checked = props.checked;
1943
1944 var hostProps = _assign({}, props, {
1945 defaultChecked: undefined,
1946 defaultValue: undefined,
1947 value: undefined,
1948 checked: checked != null ? checked : node._wrapperState.initialChecked
1949 });
1950
1951 return hostProps;
1952 }
1953 function initWrapperState(element, props) {
1954 {
1955 ReactControlledValuePropTypes.checkPropTypes('input', props);
1956
1957 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
1958 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);
1959
1960 didWarnCheckedDefaultChecked = true;
1961 }
1962
1963 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
1964 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);
1965
1966 didWarnValueDefaultValue = true;
1967 }
1968 }
1969
1970 var node = element;
1971 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
1972 node._wrapperState = {
1973 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
1974 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
1975 controlled: isControlled(props)
1976 };
1977 }
1978 function updateChecked(element, props) {
1979 var node = element;
1980 var checked = props.checked;
1981
1982 if (checked != null) {
1983 setValueForProperty(node, 'checked', checked, false);
1984 }
1985 }
1986 function updateWrapper(element, props) {
1987 var node = element;
1988
1989 {
1990 var controlled = isControlled(props);
1991
1992 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
1993 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);
1994
1995 didWarnUncontrolledToControlled = true;
1996 }
1997
1998 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
1999 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);
2000
2001 didWarnControlledToUncontrolled = true;
2002 }
2003 }
2004
2005 updateChecked(element, props);
2006 var value = getToStringValue(props.value);
2007 var type = props.type;
2008
2009 if (value != null) {
2010 if (type === 'number') {
2011 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
2012 // eslint-disable-next-line
2013 node.value != value) {
2014 node.value = toString(value);
2015 }
2016 } else if (node.value !== toString(value)) {
2017 node.value = toString(value);
2018 }
2019 } else if (type === 'submit' || type === 'reset') {
2020 // Submit/reset inputs need the attribute removed completely to avoid
2021 // blank-text buttons.
2022 node.removeAttribute('value');
2023 return;
2024 }
2025
2026 {
2027 // When syncing the value attribute, the value comes from a cascade of
2028 // properties:
2029 // 1. The value React property
2030 // 2. The defaultValue React property
2031 // 3. Otherwise there should be no change
2032 if (props.hasOwnProperty('value')) {
2033 setDefaultValue(node, props.type, value);
2034 } else if (props.hasOwnProperty('defaultValue')) {
2035 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
2036 }
2037 }
2038
2039 {
2040 // When syncing the checked attribute, it only changes when it needs
2041 // to be removed, such as transitioning from a checkbox into a text input
2042 if (props.checked == null && props.defaultChecked != null) {
2043 node.defaultChecked = !!props.defaultChecked;
2044 }
2045 }
2046 }
2047 function postMountWrapper(element, props, isHydrating) {
2048 var node = element; // Do not assign value if it is already set. This prevents user text input
2049 // from being lost during SSR hydration.
2050
2051 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
2052 var type = props.type;
2053 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
2054 // default value provided by the browser. See: #12872
2055
2056 if (isButton && (props.value === undefined || props.value === null)) {
2057 return;
2058 }
2059
2060 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
2061 // from being lost during SSR hydration.
2062
2063 if (!isHydrating) {
2064 {
2065 // When syncing the value attribute, the value property should use
2066 // the wrapperState._initialValue property. This uses:
2067 //
2068 // 1. The value React property when present
2069 // 2. The defaultValue React property when present
2070 // 3. An empty string
2071 if (initialValue !== node.value) {
2072 node.value = initialValue;
2073 }
2074 }
2075 }
2076
2077 {
2078 // Otherwise, the value attribute is synchronized to the property,
2079 // so we assign defaultValue to the same thing as the value property
2080 // assignment step above.
2081 node.defaultValue = initialValue;
2082 }
2083 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
2084 // this is needed to work around a chrome bug where setting defaultChecked
2085 // will sometimes influence the value of checked (even after detachment).
2086 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
2087 // We need to temporarily unset name to avoid disrupting radio button groups.
2088
2089
2090 var name = node.name;
2091
2092 if (name !== '') {
2093 node.name = '';
2094 }
2095
2096 {
2097 // When syncing the checked attribute, both the checked property and
2098 // attribute are assigned at the same time using defaultChecked. This uses:
2099 //
2100 // 1. The checked React property when present
2101 // 2. The defaultChecked React property when present
2102 // 3. Otherwise, false
2103 node.defaultChecked = !node.defaultChecked;
2104 node.defaultChecked = !!node._wrapperState.initialChecked;
2105 }
2106
2107 if (name !== '') {
2108 node.name = name;
2109 }
2110 }
2111 function restoreControlledState(element, props) {
2112 var node = element;
2113 updateWrapper(node, props);
2114 updateNamedCousins(node, props);
2115 }
2116
2117 function updateNamedCousins(rootNode, props) {
2118 var name = props.name;
2119
2120 if (props.type === 'radio' && name != null) {
2121 var queryRoot = rootNode;
2122
2123 while (queryRoot.parentNode) {
2124 queryRoot = queryRoot.parentNode;
2125 } // If `rootNode.form` was non-null, then we could try `form.elements`,
2126 // but that sometimes behaves strangely in IE8. We could also try using
2127 // `form.getElementsByName`, but that will only return direct children
2128 // and won't include inputs that use the HTML5 `form=` attribute. Since
2129 // the input might not even be in a form. It might not even be in the
2130 // document. Let's just use the local `querySelectorAll` to ensure we don't
2131 // miss anything.
2132
2133
2134 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
2135
2136 for (var i = 0; i < group.length; i++) {
2137 var otherNode = group[i];
2138
2139 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
2140 continue;
2141 } // This will throw if radio buttons rendered by different copies of React
2142 // and the same name are rendered into the same form (same as #1939).
2143 // That's probably okay; we don't support it just as we don't support
2144 // mixing React radio buttons with non-React ones.
2145
2146
2147 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
2148
2149 if (!otherProps) {
2150 {
2151 throw Error( "ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported." );
2152 }
2153 } // We need update the tracked value on the named cousin since the value
2154 // was changed but the input saw no event or value set
2155
2156
2157 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
2158 // was previously checked to update will cause it to be come re-checked
2159 // as appropriate.
2160
2161 updateWrapper(otherNode, otherProps);
2162 }
2163 }
2164 } // In Chrome, assigning defaultValue to certain input types triggers input validation.
2165 // For number inputs, the display value loses trailing decimal points. For email inputs,
2166 // Chrome raises "The specified value <x> is not a valid email address".
2167 //
2168 // Here we check to see if the defaultValue has actually changed, avoiding these problems
2169 // when the user is inputting text
2170 //
2171 // https://github.com/facebook/react/issues/7253
2172
2173
2174 function setDefaultValue(node, type, value) {
2175 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
2176 type !== 'number' || node.ownerDocument.activeElement !== node) {
2177 if (value == null) {
2178 node.defaultValue = toString(node._wrapperState.initialValue);
2179 } else if (node.defaultValue !== toString(value)) {
2180 node.defaultValue = toString(value);
2181 }
2182 }
2183 }
2184
2185 var didWarnSelectedSetOnOption = false;
2186 var didWarnInvalidChild = false;
2187
2188 function flattenChildren(children) {
2189 var content = ''; // Flatten children. We'll warn if they are invalid
2190 // during validateProps() which runs for hydration too.
2191 // Note that this would throw on non-element objects.
2192 // Elements are stringified (which is normally irrelevant
2193 // but matters for <fbt>).
2194
2195 React.Children.forEach(children, function (child) {
2196 if (child == null) {
2197 return;
2198 }
2199
2200 content += child; // Note: we don't warn about invalid children here.
2201 // Instead, this is done separately below so that
2202 // it happens during the hydration codepath too.
2203 });
2204 return content;
2205 }
2206 /**
2207 * Implements an <option> host component that warns when `selected` is set.
2208 */
2209
2210
2211 function validateProps(element, props) {
2212 {
2213 // This mirrors the codepath above, but runs for hydration too.
2214 // Warn about invalid children here so that client and hydration are consistent.
2215 // TODO: this seems like it could cause a DEV-only throw for hydration
2216 // if children contains a non-element object. We should try to avoid that.
2217 if (typeof props.children === 'object' && props.children !== null) {
2218 React.Children.forEach(props.children, function (child) {
2219 if (child == null) {
2220 return;
2221 }
2222
2223 if (typeof child === 'string' || typeof child === 'number') {
2224 return;
2225 }
2226
2227 if (typeof child.type !== 'string') {
2228 return;
2229 }
2230
2231 if (!didWarnInvalidChild) {
2232 didWarnInvalidChild = true;
2233
2234 error('Only strings and numbers are supported as <option> children.');
2235 }
2236 });
2237 } // TODO: Remove support for `selected` in <option>.
2238
2239
2240 if (props.selected != null && !didWarnSelectedSetOnOption) {
2241 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
2242
2243 didWarnSelectedSetOnOption = true;
2244 }
2245 }
2246 }
2247 function postMountWrapper$1(element, props) {
2248 // value="" should make a value attribute (#6219)
2249 if (props.value != null) {
2250 element.setAttribute('value', toString(getToStringValue(props.value)));
2251 }
2252 }
2253 function getHostProps$1(element, props) {
2254 var hostProps = _assign({
2255 children: undefined
2256 }, props);
2257
2258 var content = flattenChildren(props.children);
2259
2260 if (content) {
2261 hostProps.children = content;
2262 }
2263
2264 return hostProps;
2265 }
2266
2267 var didWarnValueDefaultValue$1;
2268
2269 {
2270 didWarnValueDefaultValue$1 = false;
2271 }
2272
2273 function getDeclarationErrorAddendum() {
2274 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
2275
2276 if (ownerName) {
2277 return '\n\nCheck the render method of `' + ownerName + '`.';
2278 }
2279
2280 return '';
2281 }
2282
2283 var valuePropNames = ['value', 'defaultValue'];
2284 /**
2285 * Validation function for `value` and `defaultValue`.
2286 */
2287
2288 function checkSelectPropTypes(props) {
2289 {
2290 ReactControlledValuePropTypes.checkPropTypes('select', props);
2291
2292 for (var i = 0; i < valuePropNames.length; i++) {
2293 var propName = valuePropNames[i];
2294
2295 if (props[propName] == null) {
2296 continue;
2297 }
2298
2299 var isArray = Array.isArray(props[propName]);
2300
2301 if (props.multiple && !isArray) {
2302 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
2303 } else if (!props.multiple && isArray) {
2304 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
2305 }
2306 }
2307 }
2308 }
2309
2310 function updateOptions(node, multiple, propValue, setDefaultSelected) {
2311 var options = node.options;
2312
2313 if (multiple) {
2314 var selectedValues = propValue;
2315 var selectedValue = {};
2316
2317 for (var i = 0; i < selectedValues.length; i++) {
2318 // Prefix to avoid chaos with special keys.
2319 selectedValue['$' + selectedValues[i]] = true;
2320 }
2321
2322 for (var _i = 0; _i < options.length; _i++) {
2323 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
2324
2325 if (options[_i].selected !== selected) {
2326 options[_i].selected = selected;
2327 }
2328
2329 if (selected && setDefaultSelected) {
2330 options[_i].defaultSelected = true;
2331 }
2332 }
2333 } else {
2334 // Do not set `select.value` as exact behavior isn't consistent across all
2335 // browsers for all cases.
2336 var _selectedValue = toString(getToStringValue(propValue));
2337
2338 var defaultSelected = null;
2339
2340 for (var _i2 = 0; _i2 < options.length; _i2++) {
2341 if (options[_i2].value === _selectedValue) {
2342 options[_i2].selected = true;
2343
2344 if (setDefaultSelected) {
2345 options[_i2].defaultSelected = true;
2346 }
2347
2348 return;
2349 }
2350
2351 if (defaultSelected === null && !options[_i2].disabled) {
2352 defaultSelected = options[_i2];
2353 }
2354 }
2355
2356 if (defaultSelected !== null) {
2357 defaultSelected.selected = true;
2358 }
2359 }
2360 }
2361 /**
2362 * Implements a <select> host component that allows optionally setting the
2363 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
2364 * stringable. If `multiple` is true, the prop must be an array of stringables.
2365 *
2366 * If `value` is not supplied (or null/undefined), user actions that change the
2367 * selected option will trigger updates to the rendered options.
2368 *
2369 * If it is supplied (and not null/undefined), the rendered options will not
2370 * update in response to user actions. Instead, the `value` prop must change in
2371 * order for the rendered options to update.
2372 *
2373 * If `defaultValue` is provided, any options with the supplied values will be
2374 * selected.
2375 */
2376
2377
2378 function getHostProps$2(element, props) {
2379 return _assign({}, props, {
2380 value: undefined
2381 });
2382 }
2383 function initWrapperState$1(element, props) {
2384 var node = element;
2385
2386 {
2387 checkSelectPropTypes(props);
2388 }
2389
2390 node._wrapperState = {
2391 wasMultiple: !!props.multiple
2392 };
2393
2394 {
2395 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
2396 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');
2397
2398 didWarnValueDefaultValue$1 = true;
2399 }
2400 }
2401 }
2402 function postMountWrapper$2(element, props) {
2403 var node = element;
2404 node.multiple = !!props.multiple;
2405 var value = props.value;
2406
2407 if (value != null) {
2408 updateOptions(node, !!props.multiple, value, false);
2409 } else if (props.defaultValue != null) {
2410 updateOptions(node, !!props.multiple, props.defaultValue, true);
2411 }
2412 }
2413 function postUpdateWrapper(element, props) {
2414 var node = element;
2415 var wasMultiple = node._wrapperState.wasMultiple;
2416 node._wrapperState.wasMultiple = !!props.multiple;
2417 var value = props.value;
2418
2419 if (value != null) {
2420 updateOptions(node, !!props.multiple, value, false);
2421 } else if (wasMultiple !== !!props.multiple) {
2422 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
2423 if (props.defaultValue != null) {
2424 updateOptions(node, !!props.multiple, props.defaultValue, true);
2425 } else {
2426 // Revert the select back to its default unselected state.
2427 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
2428 }
2429 }
2430 }
2431 function restoreControlledState$1(element, props) {
2432 var node = element;
2433 var value = props.value;
2434
2435 if (value != null) {
2436 updateOptions(node, !!props.multiple, value, false);
2437 }
2438 }
2439
2440 var didWarnValDefaultVal = false;
2441
2442 /**
2443 * Implements a <textarea> host component that allows setting `value`, and
2444 * `defaultValue`. This differs from the traditional DOM API because value is
2445 * usually set as PCDATA children.
2446 *
2447 * If `value` is not supplied (or null/undefined), user actions that affect the
2448 * value will trigger updates to the element.
2449 *
2450 * If `value` is supplied (and not null/undefined), the rendered element will
2451 * not trigger updates to the element. Instead, the `value` prop must change in
2452 * order for the rendered element to be updated.
2453 *
2454 * The rendered element will be initialized with an empty value, the prop
2455 * `defaultValue` if specified, or the children content (deprecated).
2456 */
2457 function getHostProps$3(element, props) {
2458 var node = element;
2459
2460 if (!(props.dangerouslySetInnerHTML == null)) {
2461 {
2462 throw Error( "`dangerouslySetInnerHTML` does not make sense on <textarea>." );
2463 }
2464 } // Always set children to the same thing. In IE9, the selection range will
2465 // get reset if `textContent` is mutated. We could add a check in setTextContent
2466 // to only set the value if/when the value differs from the node value (which would
2467 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
2468 // solution. The value can be a boolean or object so that's why it's forced
2469 // to be a string.
2470
2471
2472 var hostProps = _assign({}, props, {
2473 value: undefined,
2474 defaultValue: undefined,
2475 children: toString(node._wrapperState.initialValue)
2476 });
2477
2478 return hostProps;
2479 }
2480 function initWrapperState$2(element, props) {
2481 var node = element;
2482
2483 {
2484 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
2485
2486 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
2487 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');
2488
2489 didWarnValDefaultVal = true;
2490 }
2491 }
2492
2493 var initialValue = props.value; // Only bother fetching default value if we're going to use it
2494
2495 if (initialValue == null) {
2496 var children = props.children,
2497 defaultValue = props.defaultValue;
2498
2499 if (children != null) {
2500 {
2501 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
2502 }
2503
2504 {
2505 if (!(defaultValue == null)) {
2506 {
2507 throw Error( "If you supply `defaultValue` on a <textarea>, do not pass children." );
2508 }
2509 }
2510
2511 if (Array.isArray(children)) {
2512 if (!(children.length <= 1)) {
2513 {
2514 throw Error( "<textarea> can only have at most one child." );
2515 }
2516 }
2517
2518 children = children[0];
2519 }
2520
2521 defaultValue = children;
2522 }
2523 }
2524
2525 if (defaultValue == null) {
2526 defaultValue = '';
2527 }
2528
2529 initialValue = defaultValue;
2530 }
2531
2532 node._wrapperState = {
2533 initialValue: getToStringValue(initialValue)
2534 };
2535 }
2536 function updateWrapper$1(element, props) {
2537 var node = element;
2538 var value = getToStringValue(props.value);
2539 var defaultValue = getToStringValue(props.defaultValue);
2540
2541 if (value != null) {
2542 // Cast `value` to a string to ensure the value is set correctly. While
2543 // browsers typically do this as necessary, jsdom doesn't.
2544 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
2545
2546 if (newValue !== node.value) {
2547 node.value = newValue;
2548 }
2549
2550 if (props.defaultValue == null && node.defaultValue !== newValue) {
2551 node.defaultValue = newValue;
2552 }
2553 }
2554
2555 if (defaultValue != null) {
2556 node.defaultValue = toString(defaultValue);
2557 }
2558 }
2559 function postMountWrapper$3(element, props) {
2560 var node = element; // This is in postMount because we need access to the DOM node, which is not
2561 // available until after the component has mounted.
2562
2563 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
2564 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
2565 // will populate textContent as well.
2566 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
2567
2568 if (textContent === node._wrapperState.initialValue) {
2569 if (textContent !== '' && textContent !== null) {
2570 node.value = textContent;
2571 }
2572 }
2573 }
2574 function restoreControlledState$2(element, props) {
2575 // DOM component is still mounted; update
2576 updateWrapper$1(element, props);
2577 }
2578
2579 var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2580 var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2581 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
2582 var Namespaces = {
2583 html: HTML_NAMESPACE,
2584 mathml: MATH_NAMESPACE,
2585 svg: SVG_NAMESPACE
2586 }; // Assumes there is no parent namespace.
2587
2588 function getIntrinsicNamespace(type) {
2589 switch (type) {
2590 case 'svg':
2591 return SVG_NAMESPACE;
2592
2593 case 'math':
2594 return MATH_NAMESPACE;
2595
2596 default:
2597 return HTML_NAMESPACE;
2598 }
2599 }
2600 function getChildNamespace(parentNamespace, type) {
2601 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
2602 // No (or default) parent namespace: potential entry point.
2603 return getIntrinsicNamespace(type);
2604 }
2605
2606 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
2607 // We're leaving SVG.
2608 return HTML_NAMESPACE;
2609 } // By default, pass namespace below.
2610
2611
2612 return parentNamespace;
2613 }
2614
2615 /* globals MSApp */
2616
2617 /**
2618 * Create a function which has 'unsafe' privileges (required by windows8 apps)
2619 */
2620 var createMicrosoftUnsafeLocalFunction = function (func) {
2621 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
2622 return function (arg0, arg1, arg2, arg3) {
2623 MSApp.execUnsafeLocalFunction(function () {
2624 return func(arg0, arg1, arg2, arg3);
2625 });
2626 };
2627 } else {
2628 return func;
2629 }
2630 };
2631
2632 var reusableSVGContainer;
2633 /**
2634 * Set the innerHTML property of a node
2635 *
2636 * @param {DOMElement} node
2637 * @param {string} html
2638 * @internal
2639 */
2640
2641 var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
2642 if (node.namespaceURI === Namespaces.svg) {
2643
2644 if (!('innerHTML' in node)) {
2645 // IE does not have innerHTML for SVG nodes, so instead we inject the
2646 // new markup in a temp node and then move the child nodes across into
2647 // the target node
2648 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
2649 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
2650 var svgNode = reusableSVGContainer.firstChild;
2651
2652 while (node.firstChild) {
2653 node.removeChild(node.firstChild);
2654 }
2655
2656 while (svgNode.firstChild) {
2657 node.appendChild(svgNode.firstChild);
2658 }
2659
2660 return;
2661 }
2662 }
2663
2664 node.innerHTML = html;
2665 });
2666
2667 /**
2668 * HTML nodeType values that represent the type of the node
2669 */
2670 var ELEMENT_NODE = 1;
2671 var TEXT_NODE = 3;
2672 var COMMENT_NODE = 8;
2673 var DOCUMENT_NODE = 9;
2674 var DOCUMENT_FRAGMENT_NODE = 11;
2675
2676 /**
2677 * Set the textContent property of a node. For text updates, it's faster
2678 * to set the `nodeValue` of the Text node directly instead of using
2679 * `.textContent` which will remove the existing node and create a new one.
2680 *
2681 * @param {DOMElement} node
2682 * @param {string} text
2683 * @internal
2684 */
2685
2686 var setTextContent = function (node, text) {
2687 if (text) {
2688 var firstChild = node.firstChild;
2689
2690 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
2691 firstChild.nodeValue = text;
2692 return;
2693 }
2694 }
2695
2696 node.textContent = text;
2697 };
2698
2699 // Do not use the below two methods directly!
2700 // Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
2701 // (It is the only module that is allowed to access these methods.)
2702 function unsafeCastStringToDOMTopLevelType(topLevelType) {
2703 return topLevelType;
2704 }
2705 function unsafeCastDOMTopLevelTypeToString(topLevelType) {
2706 return topLevelType;
2707 }
2708
2709 /**
2710 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
2711 *
2712 * @param {string} styleProp
2713 * @param {string} eventName
2714 * @returns {object}
2715 */
2716
2717 function makePrefixMap(styleProp, eventName) {
2718 var prefixes = {};
2719 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
2720 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
2721 prefixes['Moz' + styleProp] = 'moz' + eventName;
2722 return prefixes;
2723 }
2724 /**
2725 * A list of event names to a configurable list of vendor prefixes.
2726 */
2727
2728
2729 var vendorPrefixes = {
2730 animationend: makePrefixMap('Animation', 'AnimationEnd'),
2731 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
2732 animationstart: makePrefixMap('Animation', 'AnimationStart'),
2733 transitionend: makePrefixMap('Transition', 'TransitionEnd')
2734 };
2735 /**
2736 * Event names that have already been detected and prefixed (if applicable).
2737 */
2738
2739 var prefixedEventNames = {};
2740 /**
2741 * Element to check for prefixes on.
2742 */
2743
2744 var style = {};
2745 /**
2746 * Bootstrap if a DOM exists.
2747 */
2748
2749 if (canUseDOM) {
2750 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
2751 // the un-prefixed "animation" and "transition" properties are defined on the
2752 // style object but the events that fire will still be prefixed, so we need
2753 // to check if the un-prefixed events are usable, and if not remove them from the map.
2754
2755 if (!('AnimationEvent' in window)) {
2756 delete vendorPrefixes.animationend.animation;
2757 delete vendorPrefixes.animationiteration.animation;
2758 delete vendorPrefixes.animationstart.animation;
2759 } // Same as above
2760
2761
2762 if (!('TransitionEvent' in window)) {
2763 delete vendorPrefixes.transitionend.transition;
2764 }
2765 }
2766 /**
2767 * Attempts to determine the correct vendor prefixed event name.
2768 *
2769 * @param {string} eventName
2770 * @returns {string}
2771 */
2772
2773
2774 function getVendorPrefixedEventName(eventName) {
2775 if (prefixedEventNames[eventName]) {
2776 return prefixedEventNames[eventName];
2777 } else if (!vendorPrefixes[eventName]) {
2778 return eventName;
2779 }
2780
2781 var prefixMap = vendorPrefixes[eventName];
2782
2783 for (var styleProp in prefixMap) {
2784 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
2785 return prefixedEventNames[eventName] = prefixMap[styleProp];
2786 }
2787 }
2788
2789 return eventName;
2790 }
2791
2792 /**
2793 * To identify top level events in ReactDOM, we use constants defined by this
2794 * module. This is the only module that uses the unsafe* methods to express
2795 * that the constants actually correspond to the browser event names. This lets
2796 * us save some bundle size by avoiding a top level type -> event name map.
2797 * The rest of ReactDOM code should import top level types from this file.
2798 */
2799
2800 var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
2801 var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
2802 var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
2803 var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
2804 var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
2805 var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
2806 var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
2807 var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
2808 var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
2809 var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
2810 var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
2811 var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
2812 var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
2813 var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
2814 var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
2815 var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
2816 var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
2817 var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
2818 var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
2819 var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
2820 var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
2821 var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
2822 var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
2823 var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
2824 var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
2825 var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
2826 var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
2827 var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
2828 var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
2829 var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
2830 var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
2831 var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
2832 var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
2833 var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
2834 var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
2835 var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
2836 var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
2837 var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
2838 var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
2839 var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
2840 var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
2841 var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
2842 var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
2843 var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
2844 var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
2845 var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
2846 var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
2847 var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
2848 var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
2849 var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
2850 var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
2851 var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
2852 var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
2853 var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
2854 var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
2855 var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
2856 var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
2857 var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
2858 var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
2859 var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
2860 var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
2861 var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
2862 var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
2863 var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
2864 var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
2865 var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
2866 var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
2867 var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
2868 var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
2869 var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
2870 var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
2871 var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
2872 var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
2873 var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
2874 var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
2875 var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
2876 var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
2877 var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
2878 var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
2879 var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel'); // List of events that need to be individually attached to media elements.
2880 // Note that events in this list will *not* be listened to at the top level
2881 // unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
2882
2883 var 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];
2884 function getRawEventName(topLevelType) {
2885 return unsafeCastDOMTopLevelTypeToString(topLevelType);
2886 }
2887
2888 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; // prettier-ignore
2889
2890 var elementListenerMap = new PossiblyWeakMap();
2891 function getListenerMapForElement(element) {
2892 var listenerMap = elementListenerMap.get(element);
2893
2894 if (listenerMap === undefined) {
2895 listenerMap = new Map();
2896 elementListenerMap.set(element, listenerMap);
2897 }
2898
2899 return listenerMap;
2900 }
2901
2902 /**
2903 * `ReactInstanceMap` maintains a mapping from a public facing stateful
2904 * instance (key) and the internal representation (value). This allows public
2905 * methods to accept the user facing instance as an argument and map them back
2906 * to internal methods.
2907 *
2908 * Note that this module is currently shared and assumed to be stateless.
2909 * If this becomes an actual Map, that will break.
2910 */
2911 function get(key) {
2912 return key._reactInternalFiber;
2913 }
2914 function has$1(key) {
2915 return key._reactInternalFiber !== undefined;
2916 }
2917 function set(key, value) {
2918 key._reactInternalFiber = value;
2919 }
2920
2921 // Don't change these two values. They're used by React Dev Tools.
2922 var NoEffect =
2923 /* */
2924 0;
2925 var PerformedWork =
2926 /* */
2927 1; // You can change the rest (and add more).
2928
2929 var Placement =
2930 /* */
2931 2;
2932 var Update =
2933 /* */
2934 4;
2935 var PlacementAndUpdate =
2936 /* */
2937 6;
2938 var Deletion =
2939 /* */
2940 8;
2941 var ContentReset =
2942 /* */
2943 16;
2944 var Callback =
2945 /* */
2946 32;
2947 var DidCapture =
2948 /* */
2949 64;
2950 var Ref =
2951 /* */
2952 128;
2953 var Snapshot =
2954 /* */
2955 256;
2956 var Passive =
2957 /* */
2958 512;
2959 var Hydrating =
2960 /* */
2961 1024;
2962 var HydratingAndUpdate =
2963 /* */
2964 1028; // Passive & Update & Callback & Ref & Snapshot
2965
2966 var LifecycleEffectMask =
2967 /* */
2968 932; // Union of all host effects
2969
2970 var HostEffectMask =
2971 /* */
2972 2047;
2973 var Incomplete =
2974 /* */
2975 2048;
2976 var ShouldCapture =
2977 /* */
2978 4096;
2979
2980 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
2981 function getNearestMountedFiber(fiber) {
2982 var node = fiber;
2983 var nearestMounted = fiber;
2984
2985 if (!fiber.alternate) {
2986 // If there is no alternate, this might be a new tree that isn't inserted
2987 // yet. If it is, then it will have a pending insertion effect on it.
2988 var nextNode = node;
2989
2990 do {
2991 node = nextNode;
2992
2993 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
2994 // This is an insertion or in-progress hydration. The nearest possible
2995 // mounted fiber is the parent but we need to continue to figure out
2996 // if that one is still mounted.
2997 nearestMounted = node.return;
2998 }
2999
3000 nextNode = node.return;
3001 } while (nextNode);
3002 } else {
3003 while (node.return) {
3004 node = node.return;
3005 }
3006 }
3007
3008 if (node.tag === HostRoot) {
3009 // TODO: Check if this was a nested HostRoot when used with
3010 // renderContainerIntoSubtree.
3011 return nearestMounted;
3012 } // If we didn't hit the root, that means that we're in an disconnected tree
3013 // that has been unmounted.
3014
3015
3016 return null;
3017 }
3018 function getSuspenseInstanceFromFiber(fiber) {
3019 if (fiber.tag === SuspenseComponent) {
3020 var suspenseState = fiber.memoizedState;
3021
3022 if (suspenseState === null) {
3023 var current = fiber.alternate;
3024
3025 if (current !== null) {
3026 suspenseState = current.memoizedState;
3027 }
3028 }
3029
3030 if (suspenseState !== null) {
3031 return suspenseState.dehydrated;
3032 }
3033 }
3034
3035 return null;
3036 }
3037 function getContainerFromFiber(fiber) {
3038 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
3039 }
3040 function isFiberMounted(fiber) {
3041 return getNearestMountedFiber(fiber) === fiber;
3042 }
3043 function isMounted(component) {
3044 {
3045 var owner = ReactCurrentOwner.current;
3046
3047 if (owner !== null && owner.tag === ClassComponent) {
3048 var ownerFiber = owner;
3049 var instance = ownerFiber.stateNode;
3050
3051 if (!instance._warnedAboutRefsInRender) {
3052 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');
3053 }
3054
3055 instance._warnedAboutRefsInRender = true;
3056 }
3057 }
3058
3059 var fiber = get(component);
3060
3061 if (!fiber) {
3062 return false;
3063 }
3064
3065 return getNearestMountedFiber(fiber) === fiber;
3066 }
3067
3068 function assertIsMounted(fiber) {
3069 if (!(getNearestMountedFiber(fiber) === fiber)) {
3070 {
3071 throw Error( "Unable to find node on an unmounted component." );
3072 }
3073 }
3074 }
3075
3076 function findCurrentFiberUsingSlowPath(fiber) {
3077 var alternate = fiber.alternate;
3078
3079 if (!alternate) {
3080 // If there is no alternate, then we only need to check if it is mounted.
3081 var nearestMounted = getNearestMountedFiber(fiber);
3082
3083 if (!(nearestMounted !== null)) {
3084 {
3085 throw Error( "Unable to find node on an unmounted component." );
3086 }
3087 }
3088
3089 if (nearestMounted !== fiber) {
3090 return null;
3091 }
3092
3093 return fiber;
3094 } // If we have two possible branches, we'll walk backwards up to the root
3095 // to see what path the root points to. On the way we may hit one of the
3096 // special cases and we'll deal with them.
3097
3098
3099 var a = fiber;
3100 var b = alternate;
3101
3102 while (true) {
3103 var parentA = a.return;
3104
3105 if (parentA === null) {
3106 // We're at the root.
3107 break;
3108 }
3109
3110 var parentB = parentA.alternate;
3111
3112 if (parentB === null) {
3113 // There is no alternate. This is an unusual case. Currently, it only
3114 // happens when a Suspense component is hidden. An extra fragment fiber
3115 // is inserted in between the Suspense fiber and its children. Skip
3116 // over this extra fragment fiber and proceed to the next parent.
3117 var nextParent = parentA.return;
3118
3119 if (nextParent !== null) {
3120 a = b = nextParent;
3121 continue;
3122 } // If there's no parent, we're at the root.
3123
3124
3125 break;
3126 } // If both copies of the parent fiber point to the same child, we can
3127 // assume that the child is current. This happens when we bailout on low
3128 // priority: the bailed out fiber's child reuses the current child.
3129
3130
3131 if (parentA.child === parentB.child) {
3132 var child = parentA.child;
3133
3134 while (child) {
3135 if (child === a) {
3136 // We've determined that A is the current branch.
3137 assertIsMounted(parentA);
3138 return fiber;
3139 }
3140
3141 if (child === b) {
3142 // We've determined that B is the current branch.
3143 assertIsMounted(parentA);
3144 return alternate;
3145 }
3146
3147 child = child.sibling;
3148 } // We should never have an alternate for any mounting node. So the only
3149 // way this could possibly happen is if this was unmounted, if at all.
3150
3151
3152 {
3153 {
3154 throw Error( "Unable to find node on an unmounted component." );
3155 }
3156 }
3157 }
3158
3159 if (a.return !== b.return) {
3160 // The return pointer of A and the return pointer of B point to different
3161 // fibers. We assume that return pointers never criss-cross, so A must
3162 // belong to the child set of A.return, and B must belong to the child
3163 // set of B.return.
3164 a = parentA;
3165 b = parentB;
3166 } else {
3167 // The return pointers point to the same fiber. We'll have to use the
3168 // default, slow path: scan the child sets of each parent alternate to see
3169 // which child belongs to which set.
3170 //
3171 // Search parent A's child set
3172 var didFindChild = false;
3173 var _child = parentA.child;
3174
3175 while (_child) {
3176 if (_child === a) {
3177 didFindChild = true;
3178 a = parentA;
3179 b = parentB;
3180 break;
3181 }
3182
3183 if (_child === b) {
3184 didFindChild = true;
3185 b = parentA;
3186 a = parentB;
3187 break;
3188 }
3189
3190 _child = _child.sibling;
3191 }
3192
3193 if (!didFindChild) {
3194 // Search parent B's child set
3195 _child = parentB.child;
3196
3197 while (_child) {
3198 if (_child === a) {
3199 didFindChild = true;
3200 a = parentB;
3201 b = parentA;
3202 break;
3203 }
3204
3205 if (_child === b) {
3206 didFindChild = true;
3207 b = parentB;
3208 a = parentA;
3209 break;
3210 }
3211
3212 _child = _child.sibling;
3213 }
3214
3215 if (!didFindChild) {
3216 {
3217 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." );
3218 }
3219 }
3220 }
3221 }
3222
3223 if (!(a.alternate === b)) {
3224 {
3225 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
3226 }
3227 }
3228 } // If the root is not a host container, we're in a disconnected tree. I.e.
3229 // unmounted.
3230
3231
3232 if (!(a.tag === HostRoot)) {
3233 {
3234 throw Error( "Unable to find node on an unmounted component." );
3235 }
3236 }
3237
3238 if (a.stateNode.current === a) {
3239 // We've determined that A is the current branch.
3240 return fiber;
3241 } // Otherwise B has to be current branch.
3242
3243
3244 return alternate;
3245 }
3246 function findCurrentHostFiber(parent) {
3247 var currentParent = findCurrentFiberUsingSlowPath(parent);
3248
3249 if (!currentParent) {
3250 return null;
3251 } // Next we'll drill down this component to find the first HostComponent/Text.
3252
3253
3254 var node = currentParent;
3255
3256 while (true) {
3257 if (node.tag === HostComponent || node.tag === HostText) {
3258 return node;
3259 } else if (node.child) {
3260 node.child.return = node;
3261 node = node.child;
3262 continue;
3263 }
3264
3265 if (node === currentParent) {
3266 return null;
3267 }
3268
3269 while (!node.sibling) {
3270 if (!node.return || node.return === currentParent) {
3271 return null;
3272 }
3273
3274 node = node.return;
3275 }
3276
3277 node.sibling.return = node.return;
3278 node = node.sibling;
3279 } // Flow needs the return null here, but ESLint complains about it.
3280 // eslint-disable-next-line no-unreachable
3281
3282
3283 return null;
3284 }
3285 function findCurrentHostFiberWithNoPortals(parent) {
3286 var currentParent = findCurrentFiberUsingSlowPath(parent);
3287
3288 if (!currentParent) {
3289 return null;
3290 } // Next we'll drill down this component to find the first HostComponent/Text.
3291
3292
3293 var node = currentParent;
3294
3295 while (true) {
3296 if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI ) {
3297 return node;
3298 } else if (node.child && node.tag !== HostPortal) {
3299 node.child.return = node;
3300 node = node.child;
3301 continue;
3302 }
3303
3304 if (node === currentParent) {
3305 return null;
3306 }
3307
3308 while (!node.sibling) {
3309 if (!node.return || node.return === currentParent) {
3310 return null;
3311 }
3312
3313 node = node.return;
3314 }
3315
3316 node.sibling.return = node.return;
3317 node = node.sibling;
3318 } // Flow needs the return null here, but ESLint complains about it.
3319 // eslint-disable-next-line no-unreachable
3320
3321
3322 return null;
3323 }
3324
3325 /**
3326 * Accumulates items that must not be null or undefined into the first one. This
3327 * is used to conserve memory by avoiding array allocations, and thus sacrifices
3328 * API cleanness. Since `current` can be null before being passed in and not
3329 * null after this function, make sure to assign it back to `current`:
3330 *
3331 * `a = accumulateInto(a, b);`
3332 *
3333 * This API should be sparingly used. Try `accumulate` for something cleaner.
3334 *
3335 * @return {*|array<*>} An accumulation of items.
3336 */
3337
3338 function accumulateInto(current, next) {
3339 if (!(next != null)) {
3340 {
3341 throw Error( "accumulateInto(...): Accumulated items must not be null or undefined." );
3342 }
3343 }
3344
3345 if (current == null) {
3346 return next;
3347 } // Both are not empty. Warning: Never call x.concat(y) when you are not
3348 // certain that x is an Array (x could be a string with concat method).
3349
3350
3351 if (Array.isArray(current)) {
3352 if (Array.isArray(next)) {
3353 current.push.apply(current, next);
3354 return current;
3355 }
3356
3357 current.push(next);
3358 return current;
3359 }
3360
3361 if (Array.isArray(next)) {
3362 // A bit too dangerous to mutate `next`.
3363 return [current].concat(next);
3364 }
3365
3366 return [current, next];
3367 }
3368
3369 /**
3370 * @param {array} arr an "accumulation" of items which is either an Array or
3371 * a single item. Useful when paired with the `accumulate` module. This is a
3372 * simple utility that allows us to reason about a collection of items, but
3373 * handling the case when there is exactly one item (and we do not need to
3374 * allocate an array).
3375 * @param {function} cb Callback invoked with each element or a collection.
3376 * @param {?} [scope] Scope used as `this` in a callback.
3377 */
3378 function forEachAccumulated(arr, cb, scope) {
3379 if (Array.isArray(arr)) {
3380 arr.forEach(cb, scope);
3381 } else if (arr) {
3382 cb.call(scope, arr);
3383 }
3384 }
3385
3386 /**
3387 * Internal queue of events that have accumulated their dispatches and are
3388 * waiting to have their dispatches executed.
3389 */
3390
3391 var eventQueue = null;
3392 /**
3393 * Dispatches an event and releases it back into the pool, unless persistent.
3394 *
3395 * @param {?object} event Synthetic event to be dispatched.
3396 * @private
3397 */
3398
3399 var executeDispatchesAndRelease = function (event) {
3400 if (event) {
3401 executeDispatchesInOrder(event);
3402
3403 if (!event.isPersistent()) {
3404 event.constructor.release(event);
3405 }
3406 }
3407 };
3408
3409 var executeDispatchesAndReleaseTopLevel = function (e) {
3410 return executeDispatchesAndRelease(e);
3411 };
3412
3413 function runEventsInBatch(events) {
3414 if (events !== null) {
3415 eventQueue = accumulateInto(eventQueue, events);
3416 } // Set `eventQueue` to null before processing it so that we can tell if more
3417 // events get enqueued while processing.
3418
3419
3420 var processingEventQueue = eventQueue;
3421 eventQueue = null;
3422
3423 if (!processingEventQueue) {
3424 return;
3425 }
3426
3427 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
3428
3429 if (!!eventQueue) {
3430 {
3431 throw Error( "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." );
3432 }
3433 } // This would be a good time to rethrow if any of the event handlers threw.
3434
3435
3436 rethrowCaughtError();
3437 }
3438
3439 /**
3440 * Gets the target node from a native browser event by accounting for
3441 * inconsistencies in browser DOM APIs.
3442 *
3443 * @param {object} nativeEvent Native browser event.
3444 * @return {DOMEventTarget} Target node.
3445 */
3446
3447 function getEventTarget(nativeEvent) {
3448 // Fallback to nativeEvent.srcElement for IE9
3449 // https://github.com/facebook/react/issues/12506
3450 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
3451
3452 if (target.correspondingUseElement) {
3453 target = target.correspondingUseElement;
3454 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
3455 // @see http://www.quirksmode.org/js/events_properties.html
3456
3457
3458 return target.nodeType === TEXT_NODE ? target.parentNode : target;
3459 }
3460
3461 /**
3462 * Checks if an event is supported in the current execution environment.
3463 *
3464 * NOTE: This will not work correctly for non-generic events such as `change`,
3465 * `reset`, `load`, `error`, and `select`.
3466 *
3467 * Borrows from Modernizr.
3468 *
3469 * @param {string} eventNameSuffix Event name, e.g. "click".
3470 * @return {boolean} True if the event is supported.
3471 * @internal
3472 * @license Modernizr 3.0.0pre (Custom Build) | MIT
3473 */
3474
3475 function isEventSupported(eventNameSuffix) {
3476 if (!canUseDOM) {
3477 return false;
3478 }
3479
3480 var eventName = 'on' + eventNameSuffix;
3481 var isSupported = eventName in document;
3482
3483 if (!isSupported) {
3484 var element = document.createElement('div');
3485 element.setAttribute(eventName, 'return;');
3486 isSupported = typeof element[eventName] === 'function';
3487 }
3488
3489 return isSupported;
3490 }
3491
3492 /**
3493 * Summary of `DOMEventPluginSystem` event handling:
3494 *
3495 * - Top-level delegation is used to trap most native browser events. This
3496 * may only occur in the main thread and is the responsibility of
3497 * ReactDOMEventListener, which is injected and can therefore support
3498 * pluggable event sources. This is the only work that occurs in the main
3499 * thread.
3500 *
3501 * - We normalize and de-duplicate events to account for browser quirks. This
3502 * may be done in the worker thread.
3503 *
3504 * - Forward these native events (with the associated top-level type used to
3505 * trap it) to `EventPluginRegistry`, which in turn will ask plugins if they want
3506 * to extract any synthetic events.
3507 *
3508 * - The `EventPluginRegistry` will then process each event by annotating them with
3509 * "dispatches", a sequence of listeners and IDs that care about that event.
3510 *
3511 * - The `EventPluginRegistry` then dispatches the events.
3512 *
3513 * Overview of React and the event system:
3514 *
3515 * +------------+ .
3516 * | DOM | .
3517 * +------------+ .
3518 * | .
3519 * v .
3520 * +------------+ .
3521 * | ReactEvent | .
3522 * | Listener | .
3523 * +------------+ . +-----------+
3524 * | . +--------+|SimpleEvent|
3525 * | . | |Plugin |
3526 * +-----|------+ . v +-----------+
3527 * | | | . +--------------+ +------------+
3528 * | +-----------.--->|PluginRegistry| | Event |
3529 * | | . | | +-----------+ | Propagators|
3530 * | ReactEvent | . | | |TapEvent | |------------|
3531 * | Emitter | . | |<---+|Plugin | |other plugin|
3532 * | | . | | +-----------+ | utilities |
3533 * | +-----------.--->| | +------------+
3534 * | | | . +--------------+
3535 * +-----|------+ . ^ +-----------+
3536 * | . | |Enter/Leave|
3537 * + . +-------+|Plugin |
3538 * +-------------+ . +-----------+
3539 * | application | .
3540 * |-------------| .
3541 * | | .
3542 * | | .
3543 * +-------------+ .
3544 * .
3545 * React Core . General Purpose Event Plugin System
3546 */
3547
3548 var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
3549 var callbackBookkeepingPool = [];
3550
3551 function releaseTopLevelCallbackBookKeeping(instance) {
3552 instance.topLevelType = null;
3553 instance.nativeEvent = null;
3554 instance.targetInst = null;
3555 instance.ancestors.length = 0;
3556
3557 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
3558 callbackBookkeepingPool.push(instance);
3559 }
3560 } // Used to store ancestor hierarchy in top level callback
3561
3562
3563 function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags) {
3564 if (callbackBookkeepingPool.length) {
3565 var instance = callbackBookkeepingPool.pop();
3566 instance.topLevelType = topLevelType;
3567 instance.eventSystemFlags = eventSystemFlags;
3568 instance.nativeEvent = nativeEvent;
3569 instance.targetInst = targetInst;
3570 return instance;
3571 }
3572
3573 return {
3574 topLevelType: topLevelType,
3575 eventSystemFlags: eventSystemFlags,
3576 nativeEvent: nativeEvent,
3577 targetInst: targetInst,
3578 ancestors: []
3579 };
3580 }
3581 /**
3582 * Find the deepest React component completely containing the root of the
3583 * passed-in instance (for use when entire React trees are nested within each
3584 * other). If React trees are not nested, returns null.
3585 */
3586
3587
3588 function findRootContainerNode(inst) {
3589 if (inst.tag === HostRoot) {
3590 return inst.stateNode.containerInfo;
3591 } // TODO: It may be a good idea to cache this to prevent unnecessary DOM
3592 // traversal, but caching is difficult to do correctly without using a
3593 // mutation observer to listen for all DOM changes.
3594
3595
3596 while (inst.return) {
3597 inst = inst.return;
3598 }
3599
3600 if (inst.tag !== HostRoot) {
3601 // This can happen if we're in a detached tree.
3602 return null;
3603 }
3604
3605 return inst.stateNode.containerInfo;
3606 }
3607 /**
3608 * Allows registered plugins an opportunity to extract events from top-level
3609 * native browser events.
3610 *
3611 * @return {*} An accumulation of synthetic events.
3612 * @internal
3613 */
3614
3615
3616 function extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
3617 var events = null;
3618
3619 for (var i = 0; i < plugins.length; i++) {
3620 // Not every plugin in the ordering may be loaded at runtime.
3621 var possiblePlugin = plugins[i];
3622
3623 if (possiblePlugin) {
3624 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
3625
3626 if (extractedEvents) {
3627 events = accumulateInto(events, extractedEvents);
3628 }
3629 }
3630 }
3631
3632 return events;
3633 }
3634
3635 function runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
3636 var events = extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
3637 runEventsInBatch(events);
3638 }
3639
3640 function handleTopLevel(bookKeeping) {
3641 var targetInst = bookKeeping.targetInst; // Loop through the hierarchy, in case there's any nested components.
3642 // It's important that we build the array of ancestors before calling any
3643 // event handlers, because event handlers can modify the DOM, leading to
3644 // inconsistencies with ReactMount's node cache. See #1105.
3645
3646 var ancestor = targetInst;
3647
3648 do {
3649 if (!ancestor) {
3650 var ancestors = bookKeeping.ancestors;
3651 ancestors.push(ancestor);
3652 break;
3653 }
3654
3655 var root = findRootContainerNode(ancestor);
3656
3657 if (!root) {
3658 break;
3659 }
3660
3661 var tag = ancestor.tag;
3662
3663 if (tag === HostComponent || tag === HostText) {
3664 bookKeeping.ancestors.push(ancestor);
3665 }
3666
3667 ancestor = getClosestInstanceFromNode(root);
3668 } while (ancestor);
3669
3670 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
3671 targetInst = bookKeeping.ancestors[i];
3672 var eventTarget = getEventTarget(bookKeeping.nativeEvent);
3673 var topLevelType = bookKeeping.topLevelType;
3674 var nativeEvent = bookKeeping.nativeEvent;
3675 var eventSystemFlags = bookKeeping.eventSystemFlags; // If this is the first ancestor, we mark it on the system flags
3676
3677 if (i === 0) {
3678 eventSystemFlags |= IS_FIRST_ANCESTOR;
3679 }
3680
3681 runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, eventTarget, eventSystemFlags);
3682 }
3683 }
3684
3685 function dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst) {
3686 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags);
3687
3688 try {
3689 // Event queue being processed in the same cycle allows
3690 // `preventDefault`.
3691 batchedEventUpdates(handleTopLevel, bookKeeping);
3692 } finally {
3693 releaseTopLevelCallbackBookKeeping(bookKeeping);
3694 }
3695 }
3696 /**
3697 * We listen for bubbled touch events on the document object.
3698 *
3699 * Firefox v8.01 (and possibly others) exhibited strange behavior when
3700 * mounting `onmousemove` events at some node that was not the document
3701 * element. The symptoms were that if your mouse is not moving over something
3702 * contained within that mount point (for example on the background) the
3703 * top-level listeners for `onmousemove` won't be called. However, if you
3704 * register the `mousemove` on the document object, then it will of course
3705 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
3706 * top-level listeners to the document object only, at least for these
3707 * movement types of events and possibly all events.
3708 *
3709 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
3710 *
3711 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
3712 * they bubble to document.
3713 *
3714 * @param {string} registrationName Name of listener (e.g. `onClick`).
3715 * @param {object} mountAt Container where to mount the listener
3716 */
3717
3718 function legacyListenToEvent(registrationName, mountAt) {
3719 var listenerMap = getListenerMapForElement(mountAt);
3720 var dependencies = registrationNameDependencies[registrationName];
3721
3722 for (var i = 0; i < dependencies.length; i++) {
3723 var dependency = dependencies[i];
3724 legacyListenToTopLevelEvent(dependency, mountAt, listenerMap);
3725 }
3726 }
3727 function legacyListenToTopLevelEvent(topLevelType, mountAt, listenerMap) {
3728 if (!listenerMap.has(topLevelType)) {
3729 switch (topLevelType) {
3730 case TOP_SCROLL:
3731 trapCapturedEvent(TOP_SCROLL, mountAt);
3732 break;
3733
3734 case TOP_FOCUS:
3735 case TOP_BLUR:
3736 trapCapturedEvent(TOP_FOCUS, mountAt);
3737 trapCapturedEvent(TOP_BLUR, mountAt); // We set the flag for a single dependency later in this function,
3738 // but this ensures we mark both as attached rather than just one.
3739
3740 listenerMap.set(TOP_BLUR, null);
3741 listenerMap.set(TOP_FOCUS, null);
3742 break;
3743
3744 case TOP_CANCEL:
3745 case TOP_CLOSE:
3746 if (isEventSupported(getRawEventName(topLevelType))) {
3747 trapCapturedEvent(topLevelType, mountAt);
3748 }
3749
3750 break;
3751
3752 case TOP_INVALID:
3753 case TOP_SUBMIT:
3754 case TOP_RESET:
3755 // We listen to them on the target DOM elements.
3756 // Some of them bubble so we don't want them to fire twice.
3757 break;
3758
3759 default:
3760 // By default, listen on the top level to all non-media events.
3761 // Media events don't bubble so adding the listener wouldn't do anything.
3762 var isMediaEvent = mediaEventTypes.indexOf(topLevelType) !== -1;
3763
3764 if (!isMediaEvent) {
3765 trapBubbledEvent(topLevelType, mountAt);
3766 }
3767
3768 break;
3769 }
3770
3771 listenerMap.set(topLevelType, null);
3772 }
3773 }
3774 function isListeningToAllDependencies(registrationName, mountAt) {
3775 var listenerMap = getListenerMapForElement(mountAt);
3776 var dependencies = registrationNameDependencies[registrationName];
3777
3778 for (var i = 0; i < dependencies.length; i++) {
3779 var dependency = dependencies[i];
3780
3781 if (!listenerMap.has(dependency)) {
3782 return false;
3783 }
3784 }
3785
3786 return true;
3787 }
3788
3789 var attemptUserBlockingHydration;
3790 function setAttemptUserBlockingHydration(fn) {
3791 attemptUserBlockingHydration = fn;
3792 }
3793 var attemptContinuousHydration;
3794 function setAttemptContinuousHydration(fn) {
3795 attemptContinuousHydration = fn;
3796 }
3797 var attemptHydrationAtCurrentPriority;
3798 function setAttemptHydrationAtCurrentPriority(fn) {
3799 attemptHydrationAtCurrentPriority = fn;
3800 } // TODO: Upgrade this definition once we're on a newer version of Flow that
3801 var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
3802
3803 var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
3804 // if the last target was dehydrated.
3805
3806 var queuedFocus = null;
3807 var queuedDrag = null;
3808 var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
3809
3810 var queuedPointers = new Map();
3811 var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
3812
3813 var queuedExplicitHydrationTargets = [];
3814 function hasQueuedDiscreteEvents() {
3815 return queuedDiscreteEvents.length > 0;
3816 }
3817 var 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];
3818 var 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];
3819 function isReplayableDiscreteEvent(eventType) {
3820 return discreteReplayableEvents.indexOf(eventType) > -1;
3821 }
3822
3823 function trapReplayableEventForDocument(topLevelType, document, listenerMap) {
3824 legacyListenToTopLevelEvent(topLevelType, document, listenerMap);
3825 }
3826
3827 function eagerlyTrapReplayableEvents(container, document) {
3828 var listenerMapForDoc = getListenerMapForElement(document); // Discrete
3829
3830 discreteReplayableEvents.forEach(function (topLevelType) {
3831 trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);
3832 }); // Continuous
3833
3834 continuousReplayableEvents.forEach(function (topLevelType) {
3835 trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc);
3836 });
3837 }
3838
3839 function createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3840 return {
3841 blockedOn: blockedOn,
3842 topLevelType: topLevelType,
3843 eventSystemFlags: eventSystemFlags | IS_REPLAYED,
3844 nativeEvent: nativeEvent,
3845 container: container
3846 };
3847 }
3848
3849 function queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3850 var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
3851 queuedDiscreteEvents.push(queuedEvent);
3852 } // Resets the replaying for this type of continuous event to no event.
3853
3854 function clearIfContinuousEvent(topLevelType, nativeEvent) {
3855 switch (topLevelType) {
3856 case TOP_FOCUS:
3857 case TOP_BLUR:
3858 queuedFocus = null;
3859 break;
3860
3861 case TOP_DRAG_ENTER:
3862 case TOP_DRAG_LEAVE:
3863 queuedDrag = null;
3864 break;
3865
3866 case TOP_MOUSE_OVER:
3867 case TOP_MOUSE_OUT:
3868 queuedMouse = null;
3869 break;
3870
3871 case TOP_POINTER_OVER:
3872 case TOP_POINTER_OUT:
3873 {
3874 var pointerId = nativeEvent.pointerId;
3875 queuedPointers.delete(pointerId);
3876 break;
3877 }
3878
3879 case TOP_GOT_POINTER_CAPTURE:
3880 case TOP_LOST_POINTER_CAPTURE:
3881 {
3882 var _pointerId = nativeEvent.pointerId;
3883 queuedPointerCaptures.delete(_pointerId);
3884 break;
3885 }
3886 }
3887 }
3888
3889 function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3890 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
3891 var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
3892
3893 if (blockedOn !== null) {
3894 var _fiber2 = getInstanceFromNode$1(blockedOn);
3895
3896 if (_fiber2 !== null) {
3897 // Attempt to increase the priority of this target.
3898 attemptContinuousHydration(_fiber2);
3899 }
3900 }
3901
3902 return queuedEvent;
3903 } // If we have already queued this exact event, then it's because
3904 // the different event systems have different DOM event listeners.
3905 // We can accumulate the flags and store a single event to be
3906 // replayed.
3907
3908
3909 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
3910 return existingQueuedEvent;
3911 }
3912
3913 function queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent) {
3914 // These set relatedTarget to null because the replayed event will be treated as if we
3915 // moved from outside the window (no target) onto the target once it hydrates.
3916 // Instead of mutating we could clone the event.
3917 switch (topLevelType) {
3918 case TOP_FOCUS:
3919 {
3920 var focusEvent = nativeEvent;
3921 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, topLevelType, eventSystemFlags, container, focusEvent);
3922 return true;
3923 }
3924
3925 case TOP_DRAG_ENTER:
3926 {
3927 var dragEvent = nativeEvent;
3928 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, topLevelType, eventSystemFlags, container, dragEvent);
3929 return true;
3930 }
3931
3932 case TOP_MOUSE_OVER:
3933 {
3934 var mouseEvent = nativeEvent;
3935 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, topLevelType, eventSystemFlags, container, mouseEvent);
3936 return true;
3937 }
3938
3939 case TOP_POINTER_OVER:
3940 {
3941 var pointerEvent = nativeEvent;
3942 var pointerId = pointerEvent.pointerId;
3943 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, topLevelType, eventSystemFlags, container, pointerEvent));
3944 return true;
3945 }
3946
3947 case TOP_GOT_POINTER_CAPTURE:
3948 {
3949 var _pointerEvent = nativeEvent;
3950 var _pointerId2 = _pointerEvent.pointerId;
3951 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, topLevelType, eventSystemFlags, container, _pointerEvent));
3952 return true;
3953 }
3954 }
3955
3956 return false;
3957 } // Check if this target is unblocked. Returns true if it's unblocked.
3958
3959 function attemptExplicitHydrationTarget(queuedTarget) {
3960 // TODO: This function shares a lot of logic with attemptToDispatchEvent.
3961 // Try to unify them. It's a bit tricky since it would require two return
3962 // values.
3963 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
3964
3965 if (targetInst !== null) {
3966 var nearestMounted = getNearestMountedFiber(targetInst);
3967
3968 if (nearestMounted !== null) {
3969 var tag = nearestMounted.tag;
3970
3971 if (tag === SuspenseComponent) {
3972 var instance = getSuspenseInstanceFromFiber(nearestMounted);
3973
3974 if (instance !== null) {
3975 // We're blocked on hydrating this boundary.
3976 // Increase its priority.
3977 queuedTarget.blockedOn = instance;
3978 unstable_runWithPriority(queuedTarget.priority, function () {
3979 attemptHydrationAtCurrentPriority(nearestMounted);
3980 });
3981 return;
3982 }
3983 } else if (tag === HostRoot) {
3984 var root = nearestMounted.stateNode;
3985
3986 if (root.hydrate) {
3987 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
3988 // a root other than sync.
3989
3990 return;
3991 }
3992 }
3993 }
3994 }
3995
3996 queuedTarget.blockedOn = null;
3997 }
3998
3999 function attemptReplayContinuousQueuedEvent(queuedEvent) {
4000 if (queuedEvent.blockedOn !== null) {
4001 return false;
4002 }
4003
4004 var nextBlockedOn = attemptToDispatchEvent(queuedEvent.topLevelType, queuedEvent.eventSystemFlags, queuedEvent.container, queuedEvent.nativeEvent);
4005
4006 if (nextBlockedOn !== null) {
4007 // We're still blocked. Try again later.
4008 var _fiber3 = getInstanceFromNode$1(nextBlockedOn);
4009
4010 if (_fiber3 !== null) {
4011 attemptContinuousHydration(_fiber3);
4012 }
4013
4014 queuedEvent.blockedOn = nextBlockedOn;
4015 return false;
4016 }
4017
4018 return true;
4019 }
4020
4021 function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
4022 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
4023 map.delete(key);
4024 }
4025 }
4026
4027 function replayUnblockedEvents() {
4028 hasScheduledReplayAttempt = false; // First replay discrete events.
4029
4030 while (queuedDiscreteEvents.length > 0) {
4031 var nextDiscreteEvent = queuedDiscreteEvents[0];
4032
4033 if (nextDiscreteEvent.blockedOn !== null) {
4034 // We're still blocked.
4035 // Increase the priority of this boundary to unblock
4036 // the next discrete event.
4037 var _fiber4 = getInstanceFromNode$1(nextDiscreteEvent.blockedOn);
4038
4039 if (_fiber4 !== null) {
4040 attemptUserBlockingHydration(_fiber4);
4041 }
4042
4043 break;
4044 }
4045
4046 var nextBlockedOn = attemptToDispatchEvent(nextDiscreteEvent.topLevelType, nextDiscreteEvent.eventSystemFlags, nextDiscreteEvent.container, nextDiscreteEvent.nativeEvent);
4047
4048 if (nextBlockedOn !== null) {
4049 // We're still blocked. Try again later.
4050 nextDiscreteEvent.blockedOn = nextBlockedOn;
4051 } else {
4052 // We've successfully replayed the first event. Let's try the next one.
4053 queuedDiscreteEvents.shift();
4054 }
4055 } // Next replay any continuous events.
4056
4057
4058 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
4059 queuedFocus = null;
4060 }
4061
4062 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
4063 queuedDrag = null;
4064 }
4065
4066 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
4067 queuedMouse = null;
4068 }
4069
4070 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
4071 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
4072 }
4073
4074 function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
4075 if (queuedEvent.blockedOn === unblocked) {
4076 queuedEvent.blockedOn = null;
4077
4078 if (!hasScheduledReplayAttempt) {
4079 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
4080 // now unblocked. This first might not actually be unblocked yet.
4081 // We could check it early to avoid scheduling an unnecessary callback.
4082
4083 unstable_scheduleCallback(unstable_NormalPriority, replayUnblockedEvents);
4084 }
4085 }
4086 }
4087
4088 function retryIfBlockedOn(unblocked) {
4089 // Mark anything that was blocked on this as no longer blocked
4090 // and eligible for a replay.
4091 if (queuedDiscreteEvents.length > 0) {
4092 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's
4093 // worth it because we expect very few discrete events to queue up and once
4094 // we are actually fully unblocked it will be fast to replay them.
4095
4096 for (var i = 1; i < queuedDiscreteEvents.length; i++) {
4097 var queuedEvent = queuedDiscreteEvents[i];
4098
4099 if (queuedEvent.blockedOn === unblocked) {
4100 queuedEvent.blockedOn = null;
4101 }
4102 }
4103 }
4104
4105 if (queuedFocus !== null) {
4106 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
4107 }
4108
4109 if (queuedDrag !== null) {
4110 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
4111 }
4112
4113 if (queuedMouse !== null) {
4114 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
4115 }
4116
4117 var unblock = function (queuedEvent) {
4118 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
4119 };
4120
4121 queuedPointers.forEach(unblock);
4122 queuedPointerCaptures.forEach(unblock);
4123
4124 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
4125 var queuedTarget = queuedExplicitHydrationTargets[_i];
4126
4127 if (queuedTarget.blockedOn === unblocked) {
4128 queuedTarget.blockedOn = null;
4129 }
4130 }
4131
4132 while (queuedExplicitHydrationTargets.length > 0) {
4133 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
4134
4135 if (nextExplicitTarget.blockedOn !== null) {
4136 // We're still blocked.
4137 break;
4138 } else {
4139 attemptExplicitHydrationTarget(nextExplicitTarget);
4140
4141 if (nextExplicitTarget.blockedOn === null) {
4142 // We're unblocked.
4143 queuedExplicitHydrationTargets.shift();
4144 }
4145 }
4146 }
4147 }
4148
4149 function addEventBubbleListener(element, eventType, listener) {
4150 element.addEventListener(eventType, listener, false);
4151 }
4152 function addEventCaptureListener(element, eventType, listener) {
4153 element.addEventListener(eventType, listener, true);
4154 }
4155
4156 // do it in two places, which duplicates logic
4157 // and increases the bundle size, we do it all
4158 // here once. If we remove or refactor the
4159 // SimpleEventPlugin, we should also remove or
4160 // update the below line.
4161
4162 var simpleEventPluginEventTypes = {};
4163 var topLevelEventsToDispatchConfig = new Map();
4164 var eventPriorities = new Map(); // We store most of the events in this module in pairs of two strings so we can re-use
4165 // the code required to apply the same logic for event prioritization and that of the
4166 // SimpleEventPlugin. This complicates things slightly, but the aim is to reduce code
4167 // duplication (for which there would be quite a bit). For the events that are not needed
4168 // for the SimpleEventPlugin (otherDiscreteEvents) we process them separately as an
4169 // array of top level events.
4170 // Lastly, we ignore prettier so we can keep the formatting sane.
4171 // prettier-ignore
4172
4173 var 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'];
4174 var otherDiscreteEvents = [TOP_CHANGE, TOP_SELECTION_CHANGE, TOP_TEXT_INPUT, TOP_COMPOSITION_START, TOP_COMPOSITION_END, TOP_COMPOSITION_UPDATE]; // prettier-ignore
4175
4176 var 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
4177
4178 var 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'];
4179 /**
4180 * Turns
4181 * ['abort', ...]
4182 * into
4183 * eventTypes = {
4184 * 'abort': {
4185 * phasedRegistrationNames: {
4186 * bubbled: 'onAbort',
4187 * captured: 'onAbortCapture',
4188 * },
4189 * dependencies: [TOP_ABORT],
4190 * },
4191 * ...
4192 * };
4193 * topLevelEventsToDispatchConfig = new Map([
4194 * [TOP_ABORT, { sameConfig }],
4195 * ]);
4196 */
4197
4198 function processSimpleEventPluginPairsByPriority(eventTypes, priority) {
4199 // As the event types are in pairs of two, we need to iterate
4200 // through in twos. The events are in pairs of two to save code
4201 // and improve init perf of processing this array, as it will
4202 // result in far fewer object allocations and property accesses
4203 // if we only use three arrays to process all the categories of
4204 // instead of tuples.
4205 for (var i = 0; i < eventTypes.length; i += 2) {
4206 var topEvent = eventTypes[i];
4207 var event = eventTypes[i + 1];
4208 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4209 var onEvent = 'on' + capitalizedEvent;
4210 var config = {
4211 phasedRegistrationNames: {
4212 bubbled: onEvent,
4213 captured: onEvent + 'Capture'
4214 },
4215 dependencies: [topEvent],
4216 eventPriority: priority
4217 };
4218 eventPriorities.set(topEvent, priority);
4219 topLevelEventsToDispatchConfig.set(topEvent, config);
4220 simpleEventPluginEventTypes[event] = config;
4221 }
4222 }
4223
4224 function processTopEventPairsByPriority(eventTypes, priority) {
4225 for (var i = 0; i < eventTypes.length; i++) {
4226 eventPriorities.set(eventTypes[i], priority);
4227 }
4228 } // SimpleEventPlugin
4229
4230
4231 processSimpleEventPluginPairsByPriority(discreteEventPairsForSimpleEventPlugin, DiscreteEvent);
4232 processSimpleEventPluginPairsByPriority(userBlockingPairsForSimpleEventPlugin, UserBlockingEvent);
4233 processSimpleEventPluginPairsByPriority(continuousPairsForSimpleEventPlugin, ContinuousEvent); // Not used by SimpleEventPlugin
4234
4235 processTopEventPairsByPriority(otherDiscreteEvents, DiscreteEvent);
4236 function getEventPriorityForPluginSystem(topLevelType) {
4237 var priority = eventPriorities.get(topLevelType); // Default to a ContinuousEvent. Note: we might
4238 // want to warn if we can't detect the priority
4239 // for the event.
4240
4241 return priority === undefined ? ContinuousEvent : priority;
4242 }
4243
4244 // Intentionally not named imports because Rollup would use dynamic dispatch for
4245 var UserBlockingPriority = unstable_UserBlockingPriority,
4246 runWithPriority = unstable_runWithPriority; // TODO: can we stop exporting these?
4247
4248 var _enabled = true;
4249 function setEnabled(enabled) {
4250 _enabled = !!enabled;
4251 }
4252 function isEnabled() {
4253 return _enabled;
4254 }
4255 function trapBubbledEvent(topLevelType, element) {
4256 trapEventForPluginEventSystem(element, topLevelType, false);
4257 }
4258 function trapCapturedEvent(topLevelType, element) {
4259 trapEventForPluginEventSystem(element, topLevelType, true);
4260 }
4261
4262 function trapEventForPluginEventSystem(container, topLevelType, capture) {
4263 var listener;
4264
4265 switch (getEventPriorityForPluginSystem(topLevelType)) {
4266 case DiscreteEvent:
4267 listener = dispatchDiscreteEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4268 break;
4269
4270 case UserBlockingEvent:
4271 listener = dispatchUserBlockingUpdate.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4272 break;
4273
4274 case ContinuousEvent:
4275 default:
4276 listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM, container);
4277 break;
4278 }
4279
4280 var rawEventName = getRawEventName(topLevelType);
4281
4282 if (capture) {
4283 addEventCaptureListener(container, rawEventName, listener);
4284 } else {
4285 addEventBubbleListener(container, rawEventName, listener);
4286 }
4287 }
4288
4289 function dispatchDiscreteEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4290 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
4291 discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, container, nativeEvent);
4292 }
4293
4294 function dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, container, nativeEvent) {
4295 runWithPriority(UserBlockingPriority, dispatchEvent.bind(null, topLevelType, eventSystemFlags, container, nativeEvent));
4296 }
4297
4298 function dispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4299 if (!_enabled) {
4300 return;
4301 }
4302
4303 if (hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(topLevelType)) {
4304 // If we already have a queue of discrete events, and this is another discrete
4305 // event, then we can't dispatch it regardless of its target, since they
4306 // need to dispatch in order.
4307 queueDiscreteEvent(null, // Flags that we're not actually blocked on anything as far as we know.
4308 topLevelType, eventSystemFlags, container, nativeEvent);
4309 return;
4310 }
4311
4312 var blockedOn = attemptToDispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent);
4313
4314 if (blockedOn === null) {
4315 // We successfully dispatched this event.
4316 clearIfContinuousEvent(topLevelType, nativeEvent);
4317 return;
4318 }
4319
4320 if (isReplayableDiscreteEvent(topLevelType)) {
4321 // This this to be replayed later once the target is available.
4322 queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent);
4323 return;
4324 }
4325
4326 if (queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, container, nativeEvent)) {
4327 return;
4328 } // We need to clear only if we didn't queue because
4329 // queueing is accummulative.
4330
4331
4332 clearIfContinuousEvent(topLevelType, nativeEvent); // This is not replayable so we'll invoke it but without a target,
4333 // in case the event system needs to trace it.
4334
4335 {
4336 dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, null);
4337 }
4338 } // Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
4339
4340 function attemptToDispatchEvent(topLevelType, eventSystemFlags, container, nativeEvent) {
4341 // TODO: Warn if _enabled is false.
4342 var nativeEventTarget = getEventTarget(nativeEvent);
4343 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4344
4345 if (targetInst !== null) {
4346 var nearestMounted = getNearestMountedFiber(targetInst);
4347
4348 if (nearestMounted === null) {
4349 // This tree has been unmounted already. Dispatch without a target.
4350 targetInst = null;
4351 } else {
4352 var tag = nearestMounted.tag;
4353
4354 if (tag === SuspenseComponent) {
4355 var instance = getSuspenseInstanceFromFiber(nearestMounted);
4356
4357 if (instance !== null) {
4358 // Queue the event to be replayed later. Abort dispatching since we
4359 // don't want this event dispatched twice through the event system.
4360 // TODO: If this is the first discrete event in the queue. Schedule an increased
4361 // priority for this boundary.
4362 return instance;
4363 } // This shouldn't happen, something went wrong but to avoid blocking
4364 // the whole system, dispatch the event without a target.
4365 // TODO: Warn.
4366
4367
4368 targetInst = null;
4369 } else if (tag === HostRoot) {
4370 var root = nearestMounted.stateNode;
4371
4372 if (root.hydrate) {
4373 // If this happens during a replay something went wrong and it might block
4374 // the whole system.
4375 return getContainerFromFiber(nearestMounted);
4376 }
4377
4378 targetInst = null;
4379 } else if (nearestMounted !== targetInst) {
4380 // If we get an event (ex: img onload) before committing that
4381 // component's mount, ignore it for now (that is, treat it as if it was an
4382 // event on a non-React tree). We might also consider queueing events and
4383 // dispatching them after the mount.
4384 targetInst = null;
4385 }
4386 }
4387 }
4388
4389 {
4390 dispatchEventForLegacyPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
4391 } // We're not blocked on anything.
4392
4393
4394 return null;
4395 }
4396
4397 // List derived from Gecko source code:
4398 // https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
4399 var shorthandToLonghand = {
4400 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
4401 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
4402 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
4403 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
4404 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
4405 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
4406 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
4407 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
4408 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
4409 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
4410 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
4411 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
4412 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
4413 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
4414 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
4415 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
4416 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
4417 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
4418 columns: ['columnCount', 'columnWidth'],
4419 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
4420 flexFlow: ['flexDirection', 'flexWrap'],
4421 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
4422 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
4423 gap: ['columnGap', 'rowGap'],
4424 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
4425 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
4426 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
4427 gridColumnGap: ['columnGap'],
4428 gridGap: ['columnGap', 'rowGap'],
4429 gridRow: ['gridRowEnd', 'gridRowStart'],
4430 gridRowGap: ['rowGap'],
4431 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
4432 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
4433 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
4434 marker: ['markerEnd', 'markerMid', 'markerStart'],
4435 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
4436 maskPosition: ['maskPositionX', 'maskPositionY'],
4437 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
4438 overflow: ['overflowX', 'overflowY'],
4439 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
4440 placeContent: ['alignContent', 'justifyContent'],
4441 placeItems: ['alignItems', 'justifyItems'],
4442 placeSelf: ['alignSelf', 'justifySelf'],
4443 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
4444 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
4445 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
4446 wordWrap: ['overflowWrap']
4447 };
4448
4449 /**
4450 * CSS properties which accept numbers but are not in units of "px".
4451 */
4452 var isUnitlessNumber = {
4453 animationIterationCount: true,
4454 borderImageOutset: true,
4455 borderImageSlice: true,
4456 borderImageWidth: true,
4457 boxFlex: true,
4458 boxFlexGroup: true,
4459 boxOrdinalGroup: true,
4460 columnCount: true,
4461 columns: true,
4462 flex: true,
4463 flexGrow: true,
4464 flexPositive: true,
4465 flexShrink: true,
4466 flexNegative: true,
4467 flexOrder: true,
4468 gridArea: true,
4469 gridRow: true,
4470 gridRowEnd: true,
4471 gridRowSpan: true,
4472 gridRowStart: true,
4473 gridColumn: true,
4474 gridColumnEnd: true,
4475 gridColumnSpan: true,
4476 gridColumnStart: true,
4477 fontWeight: true,
4478 lineClamp: true,
4479 lineHeight: true,
4480 opacity: true,
4481 order: true,
4482 orphans: true,
4483 tabSize: true,
4484 widows: true,
4485 zIndex: true,
4486 zoom: true,
4487 // SVG-related properties
4488 fillOpacity: true,
4489 floodOpacity: true,
4490 stopOpacity: true,
4491 strokeDasharray: true,
4492 strokeDashoffset: true,
4493 strokeMiterlimit: true,
4494 strokeOpacity: true,
4495 strokeWidth: true
4496 };
4497 /**
4498 * @param {string} prefix vendor-specific prefix, eg: Webkit
4499 * @param {string} key style name, eg: transitionDuration
4500 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
4501 * WebkitTransitionDuration
4502 */
4503
4504 function prefixKey(prefix, key) {
4505 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
4506 }
4507 /**
4508 * Support style names that may come passed in prefixed by adding permutations
4509 * of vendor prefixes.
4510 */
4511
4512
4513 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
4514 // infinite loop, because it iterates over the newly added props too.
4515
4516 Object.keys(isUnitlessNumber).forEach(function (prop) {
4517 prefixes.forEach(function (prefix) {
4518 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
4519 });
4520 });
4521
4522 /**
4523 * Convert a value into the proper css writable value. The style name `name`
4524 * should be logical (no hyphens), as specified
4525 * in `CSSProperty.isUnitlessNumber`.
4526 *
4527 * @param {string} name CSS property name such as `topMargin`.
4528 * @param {*} value CSS property value such as `10px`.
4529 * @return {string} Normalized style value with dimensions applied.
4530 */
4531
4532 function dangerousStyleValue(name, value, isCustomProperty) {
4533 // Note that we've removed escapeTextForBrowser() calls here since the
4534 // whole string will be escaped when the attribute is injected into
4535 // the markup. If you provide unsafe user data here they can inject
4536 // arbitrary CSS which may be problematic (I couldn't repro this):
4537 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
4538 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
4539 // This is not an XSS hole but instead a potential CSS injection issue
4540 // which has lead to a greater discussion about how we're going to
4541 // trust URLs moving forward. See #2115901
4542 var isEmpty = value == null || typeof value === 'boolean' || value === '';
4543
4544 if (isEmpty) {
4545 return '';
4546 }
4547
4548 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
4549 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
4550 }
4551
4552 return ('' + value).trim();
4553 }
4554
4555 var uppercasePattern = /([A-Z])/g;
4556 var msPattern = /^ms-/;
4557 /**
4558 * Hyphenates a camelcased CSS property name, for example:
4559 *
4560 * > hyphenateStyleName('backgroundColor')
4561 * < "background-color"
4562 * > hyphenateStyleName('MozTransition')
4563 * < "-moz-transition"
4564 * > hyphenateStyleName('msTransition')
4565 * < "-ms-transition"
4566 *
4567 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
4568 * is converted to `-ms-`.
4569 */
4570
4571 function hyphenateStyleName(name) {
4572 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
4573 }
4574
4575 var warnValidStyle = function () {};
4576
4577 {
4578 // 'msTransform' is correct, but the other prefixes should be capitalized
4579 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
4580 var msPattern$1 = /^-ms-/;
4581 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
4582
4583 var badStyleValueWithSemicolonPattern = /;\s*$/;
4584 var warnedStyleNames = {};
4585 var warnedStyleValues = {};
4586 var warnedForNaNValue = false;
4587 var warnedForInfinityValue = false;
4588
4589 var camelize = function (string) {
4590 return string.replace(hyphenPattern, function (_, character) {
4591 return character.toUpperCase();
4592 });
4593 };
4594
4595 var warnHyphenatedStyleName = function (name) {
4596 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
4597 return;
4598 }
4599
4600 warnedStyleNames[name] = true;
4601
4602 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
4603 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
4604 // is converted to lowercase `ms`.
4605 camelize(name.replace(msPattern$1, 'ms-')));
4606 };
4607
4608 var warnBadVendoredStyleName = function (name) {
4609 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
4610 return;
4611 }
4612
4613 warnedStyleNames[name] = true;
4614
4615 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
4616 };
4617
4618 var warnStyleValueWithSemicolon = function (name, value) {
4619 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
4620 return;
4621 }
4622
4623 warnedStyleValues[value] = true;
4624
4625 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
4626 };
4627
4628 var warnStyleValueIsNaN = function (name, value) {
4629 if (warnedForNaNValue) {
4630 return;
4631 }
4632
4633 warnedForNaNValue = true;
4634
4635 error('`NaN` is an invalid value for the `%s` css style property.', name);
4636 };
4637
4638 var warnStyleValueIsInfinity = function (name, value) {
4639 if (warnedForInfinityValue) {
4640 return;
4641 }
4642
4643 warnedForInfinityValue = true;
4644
4645 error('`Infinity` is an invalid value for the `%s` css style property.', name);
4646 };
4647
4648 warnValidStyle = function (name, value) {
4649 if (name.indexOf('-') > -1) {
4650 warnHyphenatedStyleName(name);
4651 } else if (badVendoredStyleNamePattern.test(name)) {
4652 warnBadVendoredStyleName(name);
4653 } else if (badStyleValueWithSemicolonPattern.test(value)) {
4654 warnStyleValueWithSemicolon(name, value);
4655 }
4656
4657 if (typeof value === 'number') {
4658 if (isNaN(value)) {
4659 warnStyleValueIsNaN(name, value);
4660 } else if (!isFinite(value)) {
4661 warnStyleValueIsInfinity(name, value);
4662 }
4663 }
4664 };
4665 }
4666
4667 var warnValidStyle$1 = warnValidStyle;
4668
4669 /**
4670 * Operations for dealing with CSS properties.
4671 */
4672
4673 /**
4674 * This creates a string that is expected to be equivalent to the style
4675 * attribute generated by server-side rendering. It by-passes warnings and
4676 * security checks so it's not safe to use this value for anything other than
4677 * comparison. It is only used in DEV for SSR validation.
4678 */
4679
4680 function createDangerousStringForStyles(styles) {
4681 {
4682 var serialized = '';
4683 var delimiter = '';
4684
4685 for (var styleName in styles) {
4686 if (!styles.hasOwnProperty(styleName)) {
4687 continue;
4688 }
4689
4690 var styleValue = styles[styleName];
4691
4692 if (styleValue != null) {
4693 var isCustomProperty = styleName.indexOf('--') === 0;
4694 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
4695 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
4696 delimiter = ';';
4697 }
4698 }
4699
4700 return serialized || null;
4701 }
4702 }
4703 /**
4704 * Sets the value for multiple styles on a node. If a value is specified as
4705 * '' (empty string), the corresponding style property will be unset.
4706 *
4707 * @param {DOMElement} node
4708 * @param {object} styles
4709 */
4710
4711 function setValueForStyles(node, styles) {
4712 var style = node.style;
4713
4714 for (var styleName in styles) {
4715 if (!styles.hasOwnProperty(styleName)) {
4716 continue;
4717 }
4718
4719 var isCustomProperty = styleName.indexOf('--') === 0;
4720
4721 {
4722 if (!isCustomProperty) {
4723 warnValidStyle$1(styleName, styles[styleName]);
4724 }
4725 }
4726
4727 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
4728
4729 if (styleName === 'float') {
4730 styleName = 'cssFloat';
4731 }
4732
4733 if (isCustomProperty) {
4734 style.setProperty(styleName, styleValue);
4735 } else {
4736 style[styleName] = styleValue;
4737 }
4738 }
4739 }
4740
4741 function isValueEmpty(value) {
4742 return value == null || typeof value === 'boolean' || value === '';
4743 }
4744 /**
4745 * Given {color: 'red', overflow: 'hidden'} returns {
4746 * color: 'color',
4747 * overflowX: 'overflow',
4748 * overflowY: 'overflow',
4749 * }. This can be read as "the overflowY property was set by the overflow
4750 * shorthand". That is, the values are the property that each was derived from.
4751 */
4752
4753
4754 function expandShorthandMap(styles) {
4755 var expanded = {};
4756
4757 for (var key in styles) {
4758 var longhands = shorthandToLonghand[key] || [key];
4759
4760 for (var i = 0; i < longhands.length; i++) {
4761 expanded[longhands[i]] = key;
4762 }
4763 }
4764
4765 return expanded;
4766 }
4767 /**
4768 * When mixing shorthand and longhand property names, we warn during updates if
4769 * we expect an incorrect result to occur. In particular, we warn for:
4770 *
4771 * Updating a shorthand property (longhand gets overwritten):
4772 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
4773 * becomes .style.font = 'baz'
4774 * Removing a shorthand property (longhand gets lost too):
4775 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
4776 * becomes .style.font = ''
4777 * Removing a longhand property (should revert to shorthand; doesn't):
4778 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
4779 * becomes .style.fontVariant = ''
4780 */
4781
4782
4783 function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
4784 {
4785
4786 if (!nextStyles) {
4787 return;
4788 }
4789
4790 var expandedUpdates = expandShorthandMap(styleUpdates);
4791 var expandedStyles = expandShorthandMap(nextStyles);
4792 var warnedAbout = {};
4793
4794 for (var key in expandedUpdates) {
4795 var originalKey = expandedUpdates[key];
4796 var correctOriginalKey = expandedStyles[key];
4797
4798 if (correctOriginalKey && originalKey !== correctOriginalKey) {
4799 var warningKey = originalKey + ',' + correctOriginalKey;
4800
4801 if (warnedAbout[warningKey]) {
4802 continue;
4803 }
4804
4805 warnedAbout[warningKey] = true;
4806
4807 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);
4808 }
4809 }
4810 }
4811 }
4812
4813 // For HTML, certain tags should omit their close tag. We keep a whitelist for
4814 // those special-case tags.
4815 var omittedCloseTags = {
4816 area: true,
4817 base: true,
4818 br: true,
4819 col: true,
4820 embed: true,
4821 hr: true,
4822 img: true,
4823 input: true,
4824 keygen: true,
4825 link: true,
4826 meta: true,
4827 param: true,
4828 source: true,
4829 track: true,
4830 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
4831
4832 };
4833
4834 // `omittedCloseTags` except that `menuitem` should still have its closing tag.
4835
4836 var voidElementTags = _assign({
4837 menuitem: true
4838 }, omittedCloseTags);
4839
4840 var HTML = '__html';
4841 var ReactDebugCurrentFrame$3 = null;
4842
4843 {
4844 ReactDebugCurrentFrame$3 = ReactSharedInternals.ReactDebugCurrentFrame;
4845 }
4846
4847 function assertValidProps(tag, props) {
4848 if (!props) {
4849 return;
4850 } // Note the use of `==` which checks for null or undefined.
4851
4852
4853 if (voidElementTags[tag]) {
4854 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {
4855 {
4856 throw Error( tag + " is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`." + ( ReactDebugCurrentFrame$3.getStackAddendum() ) );
4857 }
4858 }
4859 }
4860
4861 if (props.dangerouslySetInnerHTML != null) {
4862 if (!(props.children == null)) {
4863 {
4864 throw Error( "Can only set one of `children` or `props.dangerouslySetInnerHTML`." );
4865 }
4866 }
4867
4868 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML)) {
4869 {
4870 throw Error( "`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information." );
4871 }
4872 }
4873 }
4874
4875 {
4876 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
4877 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.');
4878 }
4879 }
4880
4881 if (!(props.style == null || typeof props.style === 'object')) {
4882 {
4883 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() ) );
4884 }
4885 }
4886 }
4887
4888 function isCustomComponent(tagName, props) {
4889 if (tagName.indexOf('-') === -1) {
4890 return typeof props.is === 'string';
4891 }
4892
4893 switch (tagName) {
4894 // These are reserved SVG and MathML elements.
4895 // We don't mind this whitelist too much because we expect it to never grow.
4896 // The alternative is to track the namespace in a few places which is convoluted.
4897 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
4898 case 'annotation-xml':
4899 case 'color-profile':
4900 case 'font-face':
4901 case 'font-face-src':
4902 case 'font-face-uri':
4903 case 'font-face-format':
4904 case 'font-face-name':
4905 case 'missing-glyph':
4906 return false;
4907
4908 default:
4909 return true;
4910 }
4911 }
4912
4913 // When adding attributes to the HTML or SVG whitelist, be sure to
4914 // also add them to this module to ensure casing and incorrect name
4915 // warnings.
4916 var possibleStandardNames = {
4917 // HTML
4918 accept: 'accept',
4919 acceptcharset: 'acceptCharset',
4920 'accept-charset': 'acceptCharset',
4921 accesskey: 'accessKey',
4922 action: 'action',
4923 allowfullscreen: 'allowFullScreen',
4924 alt: 'alt',
4925 as: 'as',
4926 async: 'async',
4927 autocapitalize: 'autoCapitalize',
4928 autocomplete: 'autoComplete',
4929 autocorrect: 'autoCorrect',
4930 autofocus: 'autoFocus',
4931 autoplay: 'autoPlay',
4932 autosave: 'autoSave',
4933 capture: 'capture',
4934 cellpadding: 'cellPadding',
4935 cellspacing: 'cellSpacing',
4936 challenge: 'challenge',
4937 charset: 'charSet',
4938 checked: 'checked',
4939 children: 'children',
4940 cite: 'cite',
4941 class: 'className',
4942 classid: 'classID',
4943 classname: 'className',
4944 cols: 'cols',
4945 colspan: 'colSpan',
4946 content: 'content',
4947 contenteditable: 'contentEditable',
4948 contextmenu: 'contextMenu',
4949 controls: 'controls',
4950 controlslist: 'controlsList',
4951 coords: 'coords',
4952 crossorigin: 'crossOrigin',
4953 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
4954 data: 'data',
4955 datetime: 'dateTime',
4956 default: 'default',
4957 defaultchecked: 'defaultChecked',
4958 defaultvalue: 'defaultValue',
4959 defer: 'defer',
4960 dir: 'dir',
4961 disabled: 'disabled',
4962 disablepictureinpicture: 'disablePictureInPicture',
4963 download: 'download',
4964 draggable: 'draggable',
4965 enctype: 'encType',
4966 for: 'htmlFor',
4967 form: 'form',
4968 formmethod: 'formMethod',
4969 formaction: 'formAction',
4970 formenctype: 'formEncType',
4971 formnovalidate: 'formNoValidate',
4972 formtarget: 'formTarget',
4973 frameborder: 'frameBorder',
4974 headers: 'headers',
4975 height: 'height',
4976 hidden: 'hidden',
4977 high: 'high',
4978 href: 'href',
4979 hreflang: 'hrefLang',
4980 htmlfor: 'htmlFor',
4981 httpequiv: 'httpEquiv',
4982 'http-equiv': 'httpEquiv',
4983 icon: 'icon',
4984 id: 'id',
4985 innerhtml: 'innerHTML',
4986 inputmode: 'inputMode',
4987 integrity: 'integrity',
4988 is: 'is',
4989 itemid: 'itemID',
4990 itemprop: 'itemProp',
4991 itemref: 'itemRef',
4992 itemscope: 'itemScope',
4993 itemtype: 'itemType',
4994 keyparams: 'keyParams',
4995 keytype: 'keyType',
4996 kind: 'kind',
4997 label: 'label',
4998 lang: 'lang',
4999 list: 'list',
5000 loop: 'loop',
5001 low: 'low',
5002 manifest: 'manifest',
5003 marginwidth: 'marginWidth',
5004 marginheight: 'marginHeight',
5005 max: 'max',
5006 maxlength: 'maxLength',
5007 media: 'media',
5008 mediagroup: 'mediaGroup',
5009 method: 'method',
5010 min: 'min',
5011 minlength: 'minLength',
5012 multiple: 'multiple',
5013 muted: 'muted',
5014 name: 'name',
5015 nomodule: 'noModule',
5016 nonce: 'nonce',
5017 novalidate: 'noValidate',
5018 open: 'open',
5019 optimum: 'optimum',
5020 pattern: 'pattern',
5021 placeholder: 'placeholder',
5022 playsinline: 'playsInline',
5023 poster: 'poster',
5024 preload: 'preload',
5025 profile: 'profile',
5026 radiogroup: 'radioGroup',
5027 readonly: 'readOnly',
5028 referrerpolicy: 'referrerPolicy',
5029 rel: 'rel',
5030 required: 'required',
5031 reversed: 'reversed',
5032 role: 'role',
5033 rows: 'rows',
5034 rowspan: 'rowSpan',
5035 sandbox: 'sandbox',
5036 scope: 'scope',
5037 scoped: 'scoped',
5038 scrolling: 'scrolling',
5039 seamless: 'seamless',
5040 selected: 'selected',
5041 shape: 'shape',
5042 size: 'size',
5043 sizes: 'sizes',
5044 span: 'span',
5045 spellcheck: 'spellCheck',
5046 src: 'src',
5047 srcdoc: 'srcDoc',
5048 srclang: 'srcLang',
5049 srcset: 'srcSet',
5050 start: 'start',
5051 step: 'step',
5052 style: 'style',
5053 summary: 'summary',
5054 tabindex: 'tabIndex',
5055 target: 'target',
5056 title: 'title',
5057 type: 'type',
5058 usemap: 'useMap',
5059 value: 'value',
5060 width: 'width',
5061 wmode: 'wmode',
5062 wrap: 'wrap',
5063 // SVG
5064 about: 'about',
5065 accentheight: 'accentHeight',
5066 'accent-height': 'accentHeight',
5067 accumulate: 'accumulate',
5068 additive: 'additive',
5069 alignmentbaseline: 'alignmentBaseline',
5070 'alignment-baseline': 'alignmentBaseline',
5071 allowreorder: 'allowReorder',
5072 alphabetic: 'alphabetic',
5073 amplitude: 'amplitude',
5074 arabicform: 'arabicForm',
5075 'arabic-form': 'arabicForm',
5076 ascent: 'ascent',
5077 attributename: 'attributeName',
5078 attributetype: 'attributeType',
5079 autoreverse: 'autoReverse',
5080 azimuth: 'azimuth',
5081 basefrequency: 'baseFrequency',
5082 baselineshift: 'baselineShift',
5083 'baseline-shift': 'baselineShift',
5084 baseprofile: 'baseProfile',
5085 bbox: 'bbox',
5086 begin: 'begin',
5087 bias: 'bias',
5088 by: 'by',
5089 calcmode: 'calcMode',
5090 capheight: 'capHeight',
5091 'cap-height': 'capHeight',
5092 clip: 'clip',
5093 clippath: 'clipPath',
5094 'clip-path': 'clipPath',
5095 clippathunits: 'clipPathUnits',
5096 cliprule: 'clipRule',
5097 'clip-rule': 'clipRule',
5098 color: 'color',
5099 colorinterpolation: 'colorInterpolation',
5100 'color-interpolation': 'colorInterpolation',
5101 colorinterpolationfilters: 'colorInterpolationFilters',
5102 'color-interpolation-filters': 'colorInterpolationFilters',
5103 colorprofile: 'colorProfile',
5104 'color-profile': 'colorProfile',
5105 colorrendering: 'colorRendering',
5106 'color-rendering': 'colorRendering',
5107 contentscripttype: 'contentScriptType',
5108 contentstyletype: 'contentStyleType',
5109 cursor: 'cursor',
5110 cx: 'cx',
5111 cy: 'cy',
5112 d: 'd',
5113 datatype: 'datatype',
5114 decelerate: 'decelerate',
5115 descent: 'descent',
5116 diffuseconstant: 'diffuseConstant',
5117 direction: 'direction',
5118 display: 'display',
5119 divisor: 'divisor',
5120 dominantbaseline: 'dominantBaseline',
5121 'dominant-baseline': 'dominantBaseline',
5122 dur: 'dur',
5123 dx: 'dx',
5124 dy: 'dy',
5125 edgemode: 'edgeMode',
5126 elevation: 'elevation',
5127 enablebackground: 'enableBackground',
5128 'enable-background': 'enableBackground',
5129 end: 'end',
5130 exponent: 'exponent',
5131 externalresourcesrequired: 'externalResourcesRequired',
5132 fill: 'fill',
5133 fillopacity: 'fillOpacity',
5134 'fill-opacity': 'fillOpacity',
5135 fillrule: 'fillRule',
5136 'fill-rule': 'fillRule',
5137 filter: 'filter',
5138 filterres: 'filterRes',
5139 filterunits: 'filterUnits',
5140 floodopacity: 'floodOpacity',
5141 'flood-opacity': 'floodOpacity',
5142 floodcolor: 'floodColor',
5143 'flood-color': 'floodColor',
5144 focusable: 'focusable',
5145 fontfamily: 'fontFamily',
5146 'font-family': 'fontFamily',
5147 fontsize: 'fontSize',
5148 'font-size': 'fontSize',
5149 fontsizeadjust: 'fontSizeAdjust',
5150 'font-size-adjust': 'fontSizeAdjust',
5151 fontstretch: 'fontStretch',
5152 'font-stretch': 'fontStretch',
5153 fontstyle: 'fontStyle',
5154 'font-style': 'fontStyle',
5155 fontvariant: 'fontVariant',
5156 'font-variant': 'fontVariant',
5157 fontweight: 'fontWeight',
5158 'font-weight': 'fontWeight',
5159 format: 'format',
5160 from: 'from',
5161 fx: 'fx',
5162 fy: 'fy',
5163 g1: 'g1',
5164 g2: 'g2',
5165 glyphname: 'glyphName',
5166 'glyph-name': 'glyphName',
5167 glyphorientationhorizontal: 'glyphOrientationHorizontal',
5168 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
5169 glyphorientationvertical: 'glyphOrientationVertical',
5170 'glyph-orientation-vertical': 'glyphOrientationVertical',
5171 glyphref: 'glyphRef',
5172 gradienttransform: 'gradientTransform',
5173 gradientunits: 'gradientUnits',
5174 hanging: 'hanging',
5175 horizadvx: 'horizAdvX',
5176 'horiz-adv-x': 'horizAdvX',
5177 horizoriginx: 'horizOriginX',
5178 'horiz-origin-x': 'horizOriginX',
5179 ideographic: 'ideographic',
5180 imagerendering: 'imageRendering',
5181 'image-rendering': 'imageRendering',
5182 in2: 'in2',
5183 in: 'in',
5184 inlist: 'inlist',
5185 intercept: 'intercept',
5186 k1: 'k1',
5187 k2: 'k2',
5188 k3: 'k3',
5189 k4: 'k4',
5190 k: 'k',
5191 kernelmatrix: 'kernelMatrix',
5192 kernelunitlength: 'kernelUnitLength',
5193 kerning: 'kerning',
5194 keypoints: 'keyPoints',
5195 keysplines: 'keySplines',
5196 keytimes: 'keyTimes',
5197 lengthadjust: 'lengthAdjust',
5198 letterspacing: 'letterSpacing',
5199 'letter-spacing': 'letterSpacing',
5200 lightingcolor: 'lightingColor',
5201 'lighting-color': 'lightingColor',
5202 limitingconeangle: 'limitingConeAngle',
5203 local: 'local',
5204 markerend: 'markerEnd',
5205 'marker-end': 'markerEnd',
5206 markerheight: 'markerHeight',
5207 markermid: 'markerMid',
5208 'marker-mid': 'markerMid',
5209 markerstart: 'markerStart',
5210 'marker-start': 'markerStart',
5211 markerunits: 'markerUnits',
5212 markerwidth: 'markerWidth',
5213 mask: 'mask',
5214 maskcontentunits: 'maskContentUnits',
5215 maskunits: 'maskUnits',
5216 mathematical: 'mathematical',
5217 mode: 'mode',
5218 numoctaves: 'numOctaves',
5219 offset: 'offset',
5220 opacity: 'opacity',
5221 operator: 'operator',
5222 order: 'order',
5223 orient: 'orient',
5224 orientation: 'orientation',
5225 origin: 'origin',
5226 overflow: 'overflow',
5227 overlineposition: 'overlinePosition',
5228 'overline-position': 'overlinePosition',
5229 overlinethickness: 'overlineThickness',
5230 'overline-thickness': 'overlineThickness',
5231 paintorder: 'paintOrder',
5232 'paint-order': 'paintOrder',
5233 panose1: 'panose1',
5234 'panose-1': 'panose1',
5235 pathlength: 'pathLength',
5236 patterncontentunits: 'patternContentUnits',
5237 patterntransform: 'patternTransform',
5238 patternunits: 'patternUnits',
5239 pointerevents: 'pointerEvents',
5240 'pointer-events': 'pointerEvents',
5241 points: 'points',
5242 pointsatx: 'pointsAtX',
5243 pointsaty: 'pointsAtY',
5244 pointsatz: 'pointsAtZ',
5245 prefix: 'prefix',
5246 preservealpha: 'preserveAlpha',
5247 preserveaspectratio: 'preserveAspectRatio',
5248 primitiveunits: 'primitiveUnits',
5249 property: 'property',
5250 r: 'r',
5251 radius: 'radius',
5252 refx: 'refX',
5253 refy: 'refY',
5254 renderingintent: 'renderingIntent',
5255 'rendering-intent': 'renderingIntent',
5256 repeatcount: 'repeatCount',
5257 repeatdur: 'repeatDur',
5258 requiredextensions: 'requiredExtensions',
5259 requiredfeatures: 'requiredFeatures',
5260 resource: 'resource',
5261 restart: 'restart',
5262 result: 'result',
5263 results: 'results',
5264 rotate: 'rotate',
5265 rx: 'rx',
5266 ry: 'ry',
5267 scale: 'scale',
5268 security: 'security',
5269 seed: 'seed',
5270 shaperendering: 'shapeRendering',
5271 'shape-rendering': 'shapeRendering',
5272 slope: 'slope',
5273 spacing: 'spacing',
5274 specularconstant: 'specularConstant',
5275 specularexponent: 'specularExponent',
5276 speed: 'speed',
5277 spreadmethod: 'spreadMethod',
5278 startoffset: 'startOffset',
5279 stddeviation: 'stdDeviation',
5280 stemh: 'stemh',
5281 stemv: 'stemv',
5282 stitchtiles: 'stitchTiles',
5283 stopcolor: 'stopColor',
5284 'stop-color': 'stopColor',
5285 stopopacity: 'stopOpacity',
5286 'stop-opacity': 'stopOpacity',
5287 strikethroughposition: 'strikethroughPosition',
5288 'strikethrough-position': 'strikethroughPosition',
5289 strikethroughthickness: 'strikethroughThickness',
5290 'strikethrough-thickness': 'strikethroughThickness',
5291 string: 'string',
5292 stroke: 'stroke',
5293 strokedasharray: 'strokeDasharray',
5294 'stroke-dasharray': 'strokeDasharray',
5295 strokedashoffset: 'strokeDashoffset',
5296 'stroke-dashoffset': 'strokeDashoffset',
5297 strokelinecap: 'strokeLinecap',
5298 'stroke-linecap': 'strokeLinecap',
5299 strokelinejoin: 'strokeLinejoin',
5300 'stroke-linejoin': 'strokeLinejoin',
5301 strokemiterlimit: 'strokeMiterlimit',
5302 'stroke-miterlimit': 'strokeMiterlimit',
5303 strokewidth: 'strokeWidth',
5304 'stroke-width': 'strokeWidth',
5305 strokeopacity: 'strokeOpacity',
5306 'stroke-opacity': 'strokeOpacity',
5307 suppresscontenteditablewarning: 'suppressContentEditableWarning',
5308 suppresshydrationwarning: 'suppressHydrationWarning',
5309 surfacescale: 'surfaceScale',
5310 systemlanguage: 'systemLanguage',
5311 tablevalues: 'tableValues',
5312 targetx: 'targetX',
5313 targety: 'targetY',
5314 textanchor: 'textAnchor',
5315 'text-anchor': 'textAnchor',
5316 textdecoration: 'textDecoration',
5317 'text-decoration': 'textDecoration',
5318 textlength: 'textLength',
5319 textrendering: 'textRendering',
5320 'text-rendering': 'textRendering',
5321 to: 'to',
5322 transform: 'transform',
5323 typeof: 'typeof',
5324 u1: 'u1',
5325 u2: 'u2',
5326 underlineposition: 'underlinePosition',
5327 'underline-position': 'underlinePosition',
5328 underlinethickness: 'underlineThickness',
5329 'underline-thickness': 'underlineThickness',
5330 unicode: 'unicode',
5331 unicodebidi: 'unicodeBidi',
5332 'unicode-bidi': 'unicodeBidi',
5333 unicoderange: 'unicodeRange',
5334 'unicode-range': 'unicodeRange',
5335 unitsperem: 'unitsPerEm',
5336 'units-per-em': 'unitsPerEm',
5337 unselectable: 'unselectable',
5338 valphabetic: 'vAlphabetic',
5339 'v-alphabetic': 'vAlphabetic',
5340 values: 'values',
5341 vectoreffect: 'vectorEffect',
5342 'vector-effect': 'vectorEffect',
5343 version: 'version',
5344 vertadvy: 'vertAdvY',
5345 'vert-adv-y': 'vertAdvY',
5346 vertoriginx: 'vertOriginX',
5347 'vert-origin-x': 'vertOriginX',
5348 vertoriginy: 'vertOriginY',
5349 'vert-origin-y': 'vertOriginY',
5350 vhanging: 'vHanging',
5351 'v-hanging': 'vHanging',
5352 videographic: 'vIdeographic',
5353 'v-ideographic': 'vIdeographic',
5354 viewbox: 'viewBox',
5355 viewtarget: 'viewTarget',
5356 visibility: 'visibility',
5357 vmathematical: 'vMathematical',
5358 'v-mathematical': 'vMathematical',
5359 vocab: 'vocab',
5360 widths: 'widths',
5361 wordspacing: 'wordSpacing',
5362 'word-spacing': 'wordSpacing',
5363 writingmode: 'writingMode',
5364 'writing-mode': 'writingMode',
5365 x1: 'x1',
5366 x2: 'x2',
5367 x: 'x',
5368 xchannelselector: 'xChannelSelector',
5369 xheight: 'xHeight',
5370 'x-height': 'xHeight',
5371 xlinkactuate: 'xlinkActuate',
5372 'xlink:actuate': 'xlinkActuate',
5373 xlinkarcrole: 'xlinkArcrole',
5374 'xlink:arcrole': 'xlinkArcrole',
5375 xlinkhref: 'xlinkHref',
5376 'xlink:href': 'xlinkHref',
5377 xlinkrole: 'xlinkRole',
5378 'xlink:role': 'xlinkRole',
5379 xlinkshow: 'xlinkShow',
5380 'xlink:show': 'xlinkShow',
5381 xlinktitle: 'xlinkTitle',
5382 'xlink:title': 'xlinkTitle',
5383 xlinktype: 'xlinkType',
5384 'xlink:type': 'xlinkType',
5385 xmlbase: 'xmlBase',
5386 'xml:base': 'xmlBase',
5387 xmllang: 'xmlLang',
5388 'xml:lang': 'xmlLang',
5389 xmlns: 'xmlns',
5390 'xml:space': 'xmlSpace',
5391 xmlnsxlink: 'xmlnsXlink',
5392 'xmlns:xlink': 'xmlnsXlink',
5393 xmlspace: 'xmlSpace',
5394 y1: 'y1',
5395 y2: 'y2',
5396 y: 'y',
5397 ychannelselector: 'yChannelSelector',
5398 z: 'z',
5399 zoomandpan: 'zoomAndPan'
5400 };
5401
5402 var ariaProperties = {
5403 'aria-current': 0,
5404 // state
5405 'aria-details': 0,
5406 'aria-disabled': 0,
5407 // state
5408 'aria-hidden': 0,
5409 // state
5410 'aria-invalid': 0,
5411 // state
5412 'aria-keyshortcuts': 0,
5413 'aria-label': 0,
5414 'aria-roledescription': 0,
5415 // Widget Attributes
5416 'aria-autocomplete': 0,
5417 'aria-checked': 0,
5418 'aria-expanded': 0,
5419 'aria-haspopup': 0,
5420 'aria-level': 0,
5421 'aria-modal': 0,
5422 'aria-multiline': 0,
5423 'aria-multiselectable': 0,
5424 'aria-orientation': 0,
5425 'aria-placeholder': 0,
5426 'aria-pressed': 0,
5427 'aria-readonly': 0,
5428 'aria-required': 0,
5429 'aria-selected': 0,
5430 'aria-sort': 0,
5431 'aria-valuemax': 0,
5432 'aria-valuemin': 0,
5433 'aria-valuenow': 0,
5434 'aria-valuetext': 0,
5435 // Live Region Attributes
5436 'aria-atomic': 0,
5437 'aria-busy': 0,
5438 'aria-live': 0,
5439 'aria-relevant': 0,
5440 // Drag-and-Drop Attributes
5441 'aria-dropeffect': 0,
5442 'aria-grabbed': 0,
5443 // Relationship Attributes
5444 'aria-activedescendant': 0,
5445 'aria-colcount': 0,
5446 'aria-colindex': 0,
5447 'aria-colspan': 0,
5448 'aria-controls': 0,
5449 'aria-describedby': 0,
5450 'aria-errormessage': 0,
5451 'aria-flowto': 0,
5452 'aria-labelledby': 0,
5453 'aria-owns': 0,
5454 'aria-posinset': 0,
5455 'aria-rowcount': 0,
5456 'aria-rowindex': 0,
5457 'aria-rowspan': 0,
5458 'aria-setsize': 0
5459 };
5460
5461 var warnedProperties = {};
5462 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
5463 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
5464 var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
5465
5466 function validateProperty(tagName, name) {
5467 {
5468 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
5469 return true;
5470 }
5471
5472 if (rARIACamel.test(name)) {
5473 var ariaName = 'aria-' + name.slice(4).toLowerCase();
5474 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
5475 // DOM properties, then it is an invalid aria-* attribute.
5476
5477 if (correctName == null) {
5478 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
5479
5480 warnedProperties[name] = true;
5481 return true;
5482 } // aria-* attributes should be lowercase; suggest the lowercase version.
5483
5484
5485 if (name !== correctName) {
5486 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
5487
5488 warnedProperties[name] = true;
5489 return true;
5490 }
5491 }
5492
5493 if (rARIA.test(name)) {
5494 var lowerCasedName = name.toLowerCase();
5495 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
5496 // DOM properties, then it is an invalid aria-* attribute.
5497
5498 if (standardName == null) {
5499 warnedProperties[name] = true;
5500 return false;
5501 } // aria-* attributes should be lowercase; suggest the lowercase version.
5502
5503
5504 if (name !== standardName) {
5505 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
5506
5507 warnedProperties[name] = true;
5508 return true;
5509 }
5510 }
5511 }
5512
5513 return true;
5514 }
5515
5516 function warnInvalidARIAProps(type, props) {
5517 {
5518 var invalidProps = [];
5519
5520 for (var key in props) {
5521 var isValid = validateProperty(type, key);
5522
5523 if (!isValid) {
5524 invalidProps.push(key);
5525 }
5526 }
5527
5528 var unknownPropString = invalidProps.map(function (prop) {
5529 return '`' + prop + '`';
5530 }).join(', ');
5531
5532 if (invalidProps.length === 1) {
5533 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
5534 } else if (invalidProps.length > 1) {
5535 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
5536 }
5537 }
5538 }
5539
5540 function validateProperties(type, props) {
5541 if (isCustomComponent(type, props)) {
5542 return;
5543 }
5544
5545 warnInvalidARIAProps(type, props);
5546 }
5547
5548 var didWarnValueNull = false;
5549 function validateProperties$1(type, props) {
5550 {
5551 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
5552 return;
5553 }
5554
5555 if (props != null && props.value === null && !didWarnValueNull) {
5556 didWarnValueNull = true;
5557
5558 if (type === 'select' && props.multiple) {
5559 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);
5560 } else {
5561 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
5562 }
5563 }
5564 }
5565 }
5566
5567 var validateProperty$1 = function () {};
5568
5569 {
5570 var warnedProperties$1 = {};
5571 var _hasOwnProperty = Object.prototype.hasOwnProperty;
5572 var EVENT_NAME_REGEX = /^on./;
5573 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
5574 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
5575 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
5576
5577 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
5578 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
5579 return true;
5580 }
5581
5582 var lowerCasedName = name.toLowerCase();
5583
5584 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
5585 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.');
5586
5587 warnedProperties$1[name] = true;
5588 return true;
5589 } // We can't rely on the event system being injected on the server.
5590
5591
5592 if (canUseEventSystem) {
5593 if (registrationNameModules.hasOwnProperty(name)) {
5594 return true;
5595 }
5596
5597 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
5598
5599 if (registrationName != null) {
5600 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
5601
5602 warnedProperties$1[name] = true;
5603 return true;
5604 }
5605
5606 if (EVENT_NAME_REGEX.test(name)) {
5607 error('Unknown event handler property `%s`. It will be ignored.', name);
5608
5609 warnedProperties$1[name] = true;
5610 return true;
5611 }
5612 } else if (EVENT_NAME_REGEX.test(name)) {
5613 // If no event plugins have been injected, we are in a server environment.
5614 // So we can't tell if the event name is correct for sure, but we can filter
5615 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
5616 if (INVALID_EVENT_NAME_REGEX.test(name)) {
5617 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
5618 }
5619
5620 warnedProperties$1[name] = true;
5621 return true;
5622 } // Let the ARIA attribute hook validate ARIA attributes
5623
5624
5625 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
5626 return true;
5627 }
5628
5629 if (lowerCasedName === 'innerhtml') {
5630 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
5631
5632 warnedProperties$1[name] = true;
5633 return true;
5634 }
5635
5636 if (lowerCasedName === 'aria') {
5637 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
5638
5639 warnedProperties$1[name] = true;
5640 return true;
5641 }
5642
5643 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
5644 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
5645
5646 warnedProperties$1[name] = true;
5647 return true;
5648 }
5649
5650 if (typeof value === 'number' && isNaN(value)) {
5651 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
5652
5653 warnedProperties$1[name] = true;
5654 return true;
5655 }
5656
5657 var propertyInfo = getPropertyInfo(name);
5658 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
5659
5660 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
5661 var standardName = possibleStandardNames[lowerCasedName];
5662
5663 if (standardName !== name) {
5664 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
5665
5666 warnedProperties$1[name] = true;
5667 return true;
5668 }
5669 } else if (!isReserved && name !== lowerCasedName) {
5670 // Unknown attributes should have lowercase casing since that's how they
5671 // will be cased anyway with server rendering.
5672 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);
5673
5674 warnedProperties$1[name] = true;
5675 return true;
5676 }
5677
5678 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
5679 if (value) {
5680 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);
5681 } else {
5682 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);
5683 }
5684
5685 warnedProperties$1[name] = true;
5686 return true;
5687 } // Now that we've validated casing, do not validate
5688 // data types for reserved props
5689
5690
5691 if (isReserved) {
5692 return true;
5693 } // Warn when a known attribute is a bad type
5694
5695
5696 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
5697 warnedProperties$1[name] = true;
5698 return false;
5699 } // Warn when passing the strings 'false' or 'true' into a boolean prop
5700
5701
5702 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
5703 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);
5704
5705 warnedProperties$1[name] = true;
5706 return true;
5707 }
5708
5709 return true;
5710 };
5711 }
5712
5713 var warnUnknownProperties = function (type, props, canUseEventSystem) {
5714 {
5715 var unknownProps = [];
5716
5717 for (var key in props) {
5718 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
5719
5720 if (!isValid) {
5721 unknownProps.push(key);
5722 }
5723 }
5724
5725 var unknownPropString = unknownProps.map(function (prop) {
5726 return '`' + prop + '`';
5727 }).join(', ');
5728
5729 if (unknownProps.length === 1) {
5730 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);
5731 } else if (unknownProps.length > 1) {
5732 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);
5733 }
5734 }
5735 };
5736
5737 function validateProperties$2(type, props, canUseEventSystem) {
5738 if (isCustomComponent(type, props)) {
5739 return;
5740 }
5741
5742 warnUnknownProperties(type, props, canUseEventSystem);
5743 }
5744
5745 var didWarnInvalidHydration = false;
5746 var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
5747 var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
5748 var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
5749 var AUTOFOCUS = 'autoFocus';
5750 var CHILDREN = 'children';
5751 var STYLE = 'style';
5752 var HTML$1 = '__html';
5753 var HTML_NAMESPACE$1 = Namespaces.html;
5754 var warnedUnknownTags;
5755 var suppressHydrationWarning;
5756 var validatePropertiesInDevelopment;
5757 var warnForTextDifference;
5758 var warnForPropDifference;
5759 var warnForExtraAttributes;
5760 var warnForInvalidEventListener;
5761 var canDiffStyleForHydrationWarning;
5762 var normalizeMarkupForTextOrAttribute;
5763 var normalizeHTML;
5764
5765 {
5766 warnedUnknownTags = {
5767 // Chrome is the only major browser not shipping <time>. But as of July
5768 // 2017 it intends to ship it due to widespread usage. We intentionally
5769 // *don't* warn for <time> even if it's unrecognized by Chrome because
5770 // it soon will be, and many apps have been using it anyway.
5771 time: true,
5772 // There are working polyfills for <dialog>. Let people use it.
5773 dialog: true,
5774 // Electron ships a custom <webview> tag to display external web content in
5775 // an isolated frame and process.
5776 // This tag is not present in non Electron environments such as JSDom which
5777 // is often used for testing purposes.
5778 // @see https://electronjs.org/docs/api/webview-tag
5779 webview: true
5780 };
5781
5782 validatePropertiesInDevelopment = function (type, props) {
5783 validateProperties(type, props);
5784 validateProperties$1(type, props);
5785 validateProperties$2(type, props,
5786 /* canUseEventSystem */
5787 true);
5788 }; // IE 11 parses & normalizes the style attribute as opposed to other
5789 // browsers. It adds spaces and sorts the properties in some
5790 // non-alphabetical order. Handling that would require sorting CSS
5791 // properties in the client & server versions or applying
5792 // `expectedStyle` to a temporary DOM node to read its `style` attribute
5793 // normalized. Since it only affects IE, we're skipping style warnings
5794 // in that browser completely in favor of doing all that work.
5795 // See https://github.com/facebook/react/issues/11807
5796
5797
5798 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; // HTML parsing normalizes CR and CRLF to LF.
5799 // It also can turn \u0000 into \uFFFD inside attributes.
5800 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
5801 // If we have a mismatch, it might be caused by that.
5802 // We will still patch up in this case but not fire the warning.
5803
5804 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
5805 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
5806
5807 normalizeMarkupForTextOrAttribute = function (markup) {
5808 var markupString = typeof markup === 'string' ? markup : '' + markup;
5809 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
5810 };
5811
5812 warnForTextDifference = function (serverText, clientText) {
5813 if (didWarnInvalidHydration) {
5814 return;
5815 }
5816
5817 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
5818 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
5819
5820 if (normalizedServerText === normalizedClientText) {
5821 return;
5822 }
5823
5824 didWarnInvalidHydration = true;
5825
5826 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
5827 };
5828
5829 warnForPropDifference = function (propName, serverValue, clientValue) {
5830 if (didWarnInvalidHydration) {
5831 return;
5832 }
5833
5834 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
5835 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
5836
5837 if (normalizedServerValue === normalizedClientValue) {
5838 return;
5839 }
5840
5841 didWarnInvalidHydration = true;
5842
5843 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
5844 };
5845
5846 warnForExtraAttributes = function (attributeNames) {
5847 if (didWarnInvalidHydration) {
5848 return;
5849 }
5850
5851 didWarnInvalidHydration = true;
5852 var names = [];
5853 attributeNames.forEach(function (name) {
5854 names.push(name);
5855 });
5856
5857 error('Extra attributes from the server: %s', names);
5858 };
5859
5860 warnForInvalidEventListener = function (registrationName, listener) {
5861 if (listener === false) {
5862 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);
5863 } else {
5864 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
5865 }
5866 }; // Parse the HTML and read it back to normalize the HTML string so that it
5867 // can be used for comparison.
5868
5869
5870 normalizeHTML = function (parent, html) {
5871 // We could have created a separate document here to avoid
5872 // re-initializing custom elements if they exist. But this breaks
5873 // how <noscript> is being handled. So we use the same document.
5874 // See the discussion in https://github.com/facebook/react/pull/11157.
5875 var testElement = parent.namespaceURI === HTML_NAMESPACE$1 ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
5876 testElement.innerHTML = html;
5877 return testElement.innerHTML;
5878 };
5879 }
5880
5881 function ensureListeningTo(rootContainerElement, registrationName) {
5882 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
5883 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
5884 legacyListenToEvent(registrationName, doc);
5885 }
5886
5887 function getOwnerDocumentFromRootContainer(rootContainerElement) {
5888 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
5889 }
5890
5891 function noop() {}
5892
5893 function trapClickOnNonInteractiveElement(node) {
5894 // Mobile Safari does not fire properly bubble click events on
5895 // non-interactive elements, which means delegated click listeners do not
5896 // fire. The workaround for this bug involves attaching an empty click
5897 // listener on the target node.
5898 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
5899 // Just set it using the onclick property so that we don't have to manage any
5900 // bookkeeping for it. Not sure if we need to clear it when the listener is
5901 // removed.
5902 // TODO: Only do this for the relevant Safaris maybe?
5903 node.onclick = noop;
5904 }
5905
5906 function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
5907 for (var propKey in nextProps) {
5908 if (!nextProps.hasOwnProperty(propKey)) {
5909 continue;
5910 }
5911
5912 var nextProp = nextProps[propKey];
5913
5914 if (propKey === STYLE) {
5915 {
5916 if (nextProp) {
5917 // Freeze the next style object so that we can assume it won't be
5918 // mutated. We have already warned for this in the past.
5919 Object.freeze(nextProp);
5920 }
5921 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
5922
5923
5924 setValueForStyles(domElement, nextProp);
5925 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
5926 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
5927
5928 if (nextHtml != null) {
5929 setInnerHTML(domElement, nextHtml);
5930 }
5931 } else if (propKey === CHILDREN) {
5932 if (typeof nextProp === 'string') {
5933 // Avoid setting initial textContent when the text is empty. In IE11 setting
5934 // textContent on a <textarea> will cause the placeholder to not
5935 // show within the <textarea> until it has been focused and blurred again.
5936 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
5937 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
5938
5939 if (canSetTextContent) {
5940 setTextContent(domElement, nextProp);
5941 }
5942 } else if (typeof nextProp === 'number') {
5943 setTextContent(domElement, '' + nextProp);
5944 }
5945 } else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameModules.hasOwnProperty(propKey)) {
5946 if (nextProp != null) {
5947 if ( typeof nextProp !== 'function') {
5948 warnForInvalidEventListener(propKey, nextProp);
5949 }
5950
5951 ensureListeningTo(rootContainerElement, propKey);
5952 }
5953 } else if (nextProp != null) {
5954 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
5955 }
5956 }
5957 }
5958
5959 function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
5960 // TODO: Handle wasCustomComponentTag
5961 for (var i = 0; i < updatePayload.length; i += 2) {
5962 var propKey = updatePayload[i];
5963 var propValue = updatePayload[i + 1];
5964
5965 if (propKey === STYLE) {
5966 setValueForStyles(domElement, propValue);
5967 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
5968 setInnerHTML(domElement, propValue);
5969 } else if (propKey === CHILDREN) {
5970 setTextContent(domElement, propValue);
5971 } else {
5972 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
5973 }
5974 }
5975 }
5976
5977 function createElement(type, props, rootContainerElement, parentNamespace) {
5978 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
5979 // tags get no namespace.
5980
5981 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
5982 var domElement;
5983 var namespaceURI = parentNamespace;
5984
5985 if (namespaceURI === HTML_NAMESPACE$1) {
5986 namespaceURI = getIntrinsicNamespace(type);
5987 }
5988
5989 if (namespaceURI === HTML_NAMESPACE$1) {
5990 {
5991 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
5992 // allow <SVG> or <mATH>.
5993
5994 if (!isCustomComponentTag && type !== type.toLowerCase()) {
5995 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
5996 }
5997 }
5998
5999 if (type === 'script') {
6000 // Create the script via .innerHTML so its "parser-inserted" flag is
6001 // set to true and it does not execute
6002 var div = ownerDocument.createElement('div');
6003
6004 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
6005 // This is guaranteed to yield a script element.
6006
6007 var firstChild = div.firstChild;
6008 domElement = div.removeChild(firstChild);
6009 } else if (typeof props.is === 'string') {
6010 // $FlowIssue `createElement` should be updated for Web Components
6011 domElement = ownerDocument.createElement(type, {
6012 is: props.is
6013 });
6014 } else {
6015 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
6016 // See discussion in https://github.com/facebook/react/pull/6896
6017 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
6018 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
6019 // attributes on `select`s needs to be added before `option`s are inserted.
6020 // This prevents:
6021 // - a bug where the `select` does not scroll to the correct option because singular
6022 // `select` elements automatically pick the first item #13222
6023 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
6024 // See https://github.com/facebook/react/issues/13222
6025 // and https://github.com/facebook/react/issues/14239
6026
6027 if (type === 'select') {
6028 var node = domElement;
6029
6030 if (props.multiple) {
6031 node.multiple = true;
6032 } else if (props.size) {
6033 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
6034 // it is possible that no option is selected.
6035 //
6036 // This is only necessary when a select in "single selection mode".
6037 node.size = props.size;
6038 }
6039 }
6040 }
6041 } else {
6042 domElement = ownerDocument.createElementNS(namespaceURI, type);
6043 }
6044
6045 {
6046 if (namespaceURI === HTML_NAMESPACE$1) {
6047 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
6048 warnedUnknownTags[type] = true;
6049
6050 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);
6051 }
6052 }
6053 }
6054
6055 return domElement;
6056 }
6057 function createTextNode(text, rootContainerElement) {
6058 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
6059 }
6060 function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
6061 var isCustomComponentTag = isCustomComponent(tag, rawProps);
6062
6063 {
6064 validatePropertiesInDevelopment(tag, rawProps);
6065 } // TODO: Make sure that we check isMounted before firing any of these events.
6066
6067
6068 var props;
6069
6070 switch (tag) {
6071 case 'iframe':
6072 case 'object':
6073 case 'embed':
6074 trapBubbledEvent(TOP_LOAD, domElement);
6075 props = rawProps;
6076 break;
6077
6078 case 'video':
6079 case 'audio':
6080 // Create listener for each media event
6081 for (var i = 0; i < mediaEventTypes.length; i++) {
6082 trapBubbledEvent(mediaEventTypes[i], domElement);
6083 }
6084
6085 props = rawProps;
6086 break;
6087
6088 case 'source':
6089 trapBubbledEvent(TOP_ERROR, domElement);
6090 props = rawProps;
6091 break;
6092
6093 case 'img':
6094 case 'image':
6095 case 'link':
6096 trapBubbledEvent(TOP_ERROR, domElement);
6097 trapBubbledEvent(TOP_LOAD, domElement);
6098 props = rawProps;
6099 break;
6100
6101 case 'form':
6102 trapBubbledEvent(TOP_RESET, domElement);
6103 trapBubbledEvent(TOP_SUBMIT, domElement);
6104 props = rawProps;
6105 break;
6106
6107 case 'details':
6108 trapBubbledEvent(TOP_TOGGLE, domElement);
6109 props = rawProps;
6110 break;
6111
6112 case 'input':
6113 initWrapperState(domElement, rawProps);
6114 props = getHostProps(domElement, rawProps);
6115 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6116 // to onChange. Even if there is no listener.
6117
6118 ensureListeningTo(rootContainerElement, 'onChange');
6119 break;
6120
6121 case 'option':
6122 validateProps(domElement, rawProps);
6123 props = getHostProps$1(domElement, rawProps);
6124 break;
6125
6126 case 'select':
6127 initWrapperState$1(domElement, rawProps);
6128 props = getHostProps$2(domElement, rawProps);
6129 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6130 // to onChange. Even if there is no listener.
6131
6132 ensureListeningTo(rootContainerElement, 'onChange');
6133 break;
6134
6135 case 'textarea':
6136 initWrapperState$2(domElement, rawProps);
6137 props = getHostProps$3(domElement, rawProps);
6138 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6139 // to onChange. Even if there is no listener.
6140
6141 ensureListeningTo(rootContainerElement, 'onChange');
6142 break;
6143
6144 default:
6145 props = rawProps;
6146 }
6147
6148 assertValidProps(tag, props);
6149 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
6150
6151 switch (tag) {
6152 case 'input':
6153 // TODO: Make sure we check if this is still unmounted or do any clean
6154 // up necessary since we never stop tracking anymore.
6155 track(domElement);
6156 postMountWrapper(domElement, rawProps, false);
6157 break;
6158
6159 case 'textarea':
6160 // TODO: Make sure we check if this is still unmounted or do any clean
6161 // up necessary since we never stop tracking anymore.
6162 track(domElement);
6163 postMountWrapper$3(domElement);
6164 break;
6165
6166 case 'option':
6167 postMountWrapper$1(domElement, rawProps);
6168 break;
6169
6170 case 'select':
6171 postMountWrapper$2(domElement, rawProps);
6172 break;
6173
6174 default:
6175 if (typeof props.onClick === 'function') {
6176 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6177 trapClickOnNonInteractiveElement(domElement);
6178 }
6179
6180 break;
6181 }
6182 } // Calculate the diff between the two objects.
6183
6184 function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
6185 {
6186 validatePropertiesInDevelopment(tag, nextRawProps);
6187 }
6188
6189 var updatePayload = null;
6190 var lastProps;
6191 var nextProps;
6192
6193 switch (tag) {
6194 case 'input':
6195 lastProps = getHostProps(domElement, lastRawProps);
6196 nextProps = getHostProps(domElement, nextRawProps);
6197 updatePayload = [];
6198 break;
6199
6200 case 'option':
6201 lastProps = getHostProps$1(domElement, lastRawProps);
6202 nextProps = getHostProps$1(domElement, nextRawProps);
6203 updatePayload = [];
6204 break;
6205
6206 case 'select':
6207 lastProps = getHostProps$2(domElement, lastRawProps);
6208 nextProps = getHostProps$2(domElement, nextRawProps);
6209 updatePayload = [];
6210 break;
6211
6212 case 'textarea':
6213 lastProps = getHostProps$3(domElement, lastRawProps);
6214 nextProps = getHostProps$3(domElement, nextRawProps);
6215 updatePayload = [];
6216 break;
6217
6218 default:
6219 lastProps = lastRawProps;
6220 nextProps = nextRawProps;
6221
6222 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
6223 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6224 trapClickOnNonInteractiveElement(domElement);
6225 }
6226
6227 break;
6228 }
6229
6230 assertValidProps(tag, nextProps);
6231 var propKey;
6232 var styleName;
6233 var styleUpdates = null;
6234
6235 for (propKey in lastProps) {
6236 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
6237 continue;
6238 }
6239
6240 if (propKey === STYLE) {
6241 var lastStyle = lastProps[propKey];
6242
6243 for (styleName in lastStyle) {
6244 if (lastStyle.hasOwnProperty(styleName)) {
6245 if (!styleUpdates) {
6246 styleUpdates = {};
6247 }
6248
6249 styleUpdates[styleName] = '';
6250 }
6251 }
6252 } 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)) {
6253 // This is a special case. If any listener updates we need to ensure
6254 // that the "current" fiber pointer gets updated so we need a commit
6255 // to update this element.
6256 if (!updatePayload) {
6257 updatePayload = [];
6258 }
6259 } else {
6260 // For all other deleted properties we add it to the queue. We use
6261 // the whitelist in the commit phase instead.
6262 (updatePayload = updatePayload || []).push(propKey, null);
6263 }
6264 }
6265
6266 for (propKey in nextProps) {
6267 var nextProp = nextProps[propKey];
6268 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
6269
6270 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
6271 continue;
6272 }
6273
6274 if (propKey === STYLE) {
6275 {
6276 if (nextProp) {
6277 // Freeze the next style object so that we can assume it won't be
6278 // mutated. We have already warned for this in the past.
6279 Object.freeze(nextProp);
6280 }
6281 }
6282
6283 if (lastProp) {
6284 // Unset styles on `lastProp` but not on `nextProp`.
6285 for (styleName in lastProp) {
6286 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
6287 if (!styleUpdates) {
6288 styleUpdates = {};
6289 }
6290
6291 styleUpdates[styleName] = '';
6292 }
6293 } // Update styles that changed since `lastProp`.
6294
6295
6296 for (styleName in nextProp) {
6297 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
6298 if (!styleUpdates) {
6299 styleUpdates = {};
6300 }
6301
6302 styleUpdates[styleName] = nextProp[styleName];
6303 }
6304 }
6305 } else {
6306 // Relies on `updateStylesByID` not mutating `styleUpdates`.
6307 if (!styleUpdates) {
6308 if (!updatePayload) {
6309 updatePayload = [];
6310 }
6311
6312 updatePayload.push(propKey, styleUpdates);
6313 }
6314
6315 styleUpdates = nextProp;
6316 }
6317 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
6318 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
6319 var lastHtml = lastProp ? lastProp[HTML$1] : undefined;
6320
6321 if (nextHtml != null) {
6322 if (lastHtml !== nextHtml) {
6323 (updatePayload = updatePayload || []).push(propKey, nextHtml);
6324 }
6325 }
6326 } else if (propKey === CHILDREN) {
6327 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
6328 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
6329 }
6330 } else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameModules.hasOwnProperty(propKey)) {
6331 if (nextProp != null) {
6332 // We eagerly listen to this even though we haven't committed yet.
6333 if ( typeof nextProp !== 'function') {
6334 warnForInvalidEventListener(propKey, nextProp);
6335 }
6336
6337 ensureListeningTo(rootContainerElement, propKey);
6338 }
6339
6340 if (!updatePayload && lastProp !== nextProp) {
6341 // This is a special case. If any listener updates we need to ensure
6342 // that the "current" props pointer gets updated so we need a commit
6343 // to update this element.
6344 updatePayload = [];
6345 }
6346 } else {
6347 // For any other property we always add it to the queue and then we
6348 // filter it out using the whitelist during the commit.
6349 (updatePayload = updatePayload || []).push(propKey, nextProp);
6350 }
6351 }
6352
6353 if (styleUpdates) {
6354 {
6355 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
6356 }
6357
6358 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
6359 }
6360
6361 return updatePayload;
6362 } // Apply the diff.
6363
6364 function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
6365 // Update checked *before* name.
6366 // In the middle of an update, it is possible to have multiple checked.
6367 // When a checked radio tries to change name, browser makes another radio's checked false.
6368 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
6369 updateChecked(domElement, nextRawProps);
6370 }
6371
6372 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
6373 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
6374
6375 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
6376 // changed.
6377
6378 switch (tag) {
6379 case 'input':
6380 // Update the wrapper around inputs *after* updating props. This has to
6381 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
6382 // raise warnings and prevent the new value from being assigned.
6383 updateWrapper(domElement, nextRawProps);
6384 break;
6385
6386 case 'textarea':
6387 updateWrapper$1(domElement, nextRawProps);
6388 break;
6389
6390 case 'select':
6391 // <select> value update needs to occur after <option> children
6392 // reconciliation
6393 postUpdateWrapper(domElement, nextRawProps);
6394 break;
6395 }
6396 }
6397
6398 function getPossibleStandardName(propName) {
6399 {
6400 var lowerCasedName = propName.toLowerCase();
6401
6402 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
6403 return null;
6404 }
6405
6406 return possibleStandardNames[lowerCasedName] || null;
6407 }
6408 }
6409
6410 function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
6411 var isCustomComponentTag;
6412 var extraAttributeNames;
6413
6414 {
6415 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true;
6416 isCustomComponentTag = isCustomComponent(tag, rawProps);
6417 validatePropertiesInDevelopment(tag, rawProps);
6418 } // TODO: Make sure that we check isMounted before firing any of these events.
6419
6420
6421 switch (tag) {
6422 case 'iframe':
6423 case 'object':
6424 case 'embed':
6425 trapBubbledEvent(TOP_LOAD, domElement);
6426 break;
6427
6428 case 'video':
6429 case 'audio':
6430 // Create listener for each media event
6431 for (var i = 0; i < mediaEventTypes.length; i++) {
6432 trapBubbledEvent(mediaEventTypes[i], domElement);
6433 }
6434
6435 break;
6436
6437 case 'source':
6438 trapBubbledEvent(TOP_ERROR, domElement);
6439 break;
6440
6441 case 'img':
6442 case 'image':
6443 case 'link':
6444 trapBubbledEvent(TOP_ERROR, domElement);
6445 trapBubbledEvent(TOP_LOAD, domElement);
6446 break;
6447
6448 case 'form':
6449 trapBubbledEvent(TOP_RESET, domElement);
6450 trapBubbledEvent(TOP_SUBMIT, domElement);
6451 break;
6452
6453 case 'details':
6454 trapBubbledEvent(TOP_TOGGLE, domElement);
6455 break;
6456
6457 case 'input':
6458 initWrapperState(domElement, rawProps);
6459 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6460 // to onChange. Even if there is no listener.
6461
6462 ensureListeningTo(rootContainerElement, 'onChange');
6463 break;
6464
6465 case 'option':
6466 validateProps(domElement, rawProps);
6467 break;
6468
6469 case 'select':
6470 initWrapperState$1(domElement, rawProps);
6471 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6472 // to onChange. Even if there is no listener.
6473
6474 ensureListeningTo(rootContainerElement, 'onChange');
6475 break;
6476
6477 case 'textarea':
6478 initWrapperState$2(domElement, rawProps);
6479 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
6480 // to onChange. Even if there is no listener.
6481
6482 ensureListeningTo(rootContainerElement, 'onChange');
6483 break;
6484 }
6485
6486 assertValidProps(tag, rawProps);
6487
6488 {
6489 extraAttributeNames = new Set();
6490 var attributes = domElement.attributes;
6491
6492 for (var _i = 0; _i < attributes.length; _i++) {
6493 var name = attributes[_i].name.toLowerCase();
6494
6495 switch (name) {
6496 // Built-in SSR attribute is whitelisted
6497 case 'data-reactroot':
6498 break;
6499 // Controlled attributes are not validated
6500 // TODO: Only ignore them on controlled tags.
6501
6502 case 'value':
6503 break;
6504
6505 case 'checked':
6506 break;
6507
6508 case 'selected':
6509 break;
6510
6511 default:
6512 // Intentionally use the original name.
6513 // See discussion in https://github.com/facebook/react/pull/10676.
6514 extraAttributeNames.add(attributes[_i].name);
6515 }
6516 }
6517 }
6518
6519 var updatePayload = null;
6520
6521 for (var propKey in rawProps) {
6522 if (!rawProps.hasOwnProperty(propKey)) {
6523 continue;
6524 }
6525
6526 var nextProp = rawProps[propKey];
6527
6528 if (propKey === CHILDREN) {
6529 // For text content children we compare against textContent. This
6530 // might match additional HTML that is hidden when we read it using
6531 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
6532 // satisfies our requirement. Our requirement is not to produce perfect
6533 // HTML and attributes. Ideally we should preserve structure but it's
6534 // ok not to if the visible content is still enough to indicate what
6535 // even listeners these nodes might be wired up to.
6536 // TODO: Warn if there is more than a single textNode as a child.
6537 // TODO: Should we use domElement.firstChild.nodeValue to compare?
6538 if (typeof nextProp === 'string') {
6539 if (domElement.textContent !== nextProp) {
6540 if ( !suppressHydrationWarning) {
6541 warnForTextDifference(domElement.textContent, nextProp);
6542 }
6543
6544 updatePayload = [CHILDREN, nextProp];
6545 }
6546 } else if (typeof nextProp === 'number') {
6547 if (domElement.textContent !== '' + nextProp) {
6548 if ( !suppressHydrationWarning) {
6549 warnForTextDifference(domElement.textContent, nextProp);
6550 }
6551
6552 updatePayload = [CHILDREN, '' + nextProp];
6553 }
6554 }
6555 } else if (registrationNameModules.hasOwnProperty(propKey)) {
6556 if (nextProp != null) {
6557 if ( typeof nextProp !== 'function') {
6558 warnForInvalidEventListener(propKey, nextProp);
6559 }
6560
6561 ensureListeningTo(rootContainerElement, propKey);
6562 }
6563 } else if ( // Convince Flow we've calculated it (it's DEV-only in this method.)
6564 typeof isCustomComponentTag === 'boolean') {
6565 // Validate that the properties correspond to their expected values.
6566 var serverValue = void 0;
6567 var propertyInfo = getPropertyInfo(propKey);
6568
6569 if (suppressHydrationWarning) ; else if ( propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
6570 // TODO: Only ignore them on controlled tags.
6571 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
6572 var serverHTML = domElement.innerHTML;
6573 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
6574 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
6575
6576 if (expectedHTML !== serverHTML) {
6577 warnForPropDifference(propKey, serverHTML, expectedHTML);
6578 }
6579 } else if (propKey === STYLE) {
6580 // $FlowFixMe - Should be inferred as not undefined.
6581 extraAttributeNames.delete(propKey);
6582
6583 if (canDiffStyleForHydrationWarning) {
6584 var expectedStyle = createDangerousStringForStyles(nextProp);
6585 serverValue = domElement.getAttribute('style');
6586
6587 if (expectedStyle !== serverValue) {
6588 warnForPropDifference(propKey, serverValue, expectedStyle);
6589 }
6590 }
6591 } else if (isCustomComponentTag) {
6592 // $FlowFixMe - Should be inferred as not undefined.
6593 extraAttributeNames.delete(propKey.toLowerCase());
6594 serverValue = getValueForAttribute(domElement, propKey, nextProp);
6595
6596 if (nextProp !== serverValue) {
6597 warnForPropDifference(propKey, serverValue, nextProp);
6598 }
6599 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
6600 var isMismatchDueToBadCasing = false;
6601
6602 if (propertyInfo !== null) {
6603 // $FlowFixMe - Should be inferred as not undefined.
6604 extraAttributeNames.delete(propertyInfo.attributeName);
6605 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
6606 } else {
6607 var ownNamespace = parentNamespace;
6608
6609 if (ownNamespace === HTML_NAMESPACE$1) {
6610 ownNamespace = getIntrinsicNamespace(tag);
6611 }
6612
6613 if (ownNamespace === HTML_NAMESPACE$1) {
6614 // $FlowFixMe - Should be inferred as not undefined.
6615 extraAttributeNames.delete(propKey.toLowerCase());
6616 } else {
6617 var standardName = getPossibleStandardName(propKey);
6618
6619 if (standardName !== null && standardName !== propKey) {
6620 // If an SVG prop is supplied with bad casing, it will
6621 // be successfully parsed from HTML, but will produce a mismatch
6622 // (and would be incorrectly rendered on the client).
6623 // However, we already warn about bad casing elsewhere.
6624 // So we'll skip the misleading extra mismatch warning in this case.
6625 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
6626
6627 extraAttributeNames.delete(standardName);
6628 } // $FlowFixMe - Should be inferred as not undefined.
6629
6630
6631 extraAttributeNames.delete(propKey);
6632 }
6633
6634 serverValue = getValueForAttribute(domElement, propKey, nextProp);
6635 }
6636
6637 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
6638 warnForPropDifference(propKey, serverValue, nextProp);
6639 }
6640 }
6641 }
6642 }
6643
6644 {
6645 // $FlowFixMe - Should be inferred as not undefined.
6646 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
6647 // $FlowFixMe - Should be inferred as not undefined.
6648 warnForExtraAttributes(extraAttributeNames);
6649 }
6650 }
6651
6652 switch (tag) {
6653 case 'input':
6654 // TODO: Make sure we check if this is still unmounted or do any clean
6655 // up necessary since we never stop tracking anymore.
6656 track(domElement);
6657 postMountWrapper(domElement, rawProps, true);
6658 break;
6659
6660 case 'textarea':
6661 // TODO: Make sure we check if this is still unmounted or do any clean
6662 // up necessary since we never stop tracking anymore.
6663 track(domElement);
6664 postMountWrapper$3(domElement);
6665 break;
6666
6667 case 'select':
6668 case 'option':
6669 // For input and textarea we current always set the value property at
6670 // post mount to force it to diverge from attributes. However, for
6671 // option and select we don't quite do the same thing and select
6672 // is not resilient to the DOM state changing so we don't do that here.
6673 // TODO: Consider not doing this for input and textarea.
6674 break;
6675
6676 default:
6677 if (typeof rawProps.onClick === 'function') {
6678 // TODO: This cast may not be sound for SVG, MathML or custom elements.
6679 trapClickOnNonInteractiveElement(domElement);
6680 }
6681
6682 break;
6683 }
6684
6685 return updatePayload;
6686 }
6687 function diffHydratedText(textNode, text) {
6688 var isDifferent = textNode.nodeValue !== text;
6689 return isDifferent;
6690 }
6691 function warnForUnmatchedText(textNode, text) {
6692 {
6693 warnForTextDifference(textNode.nodeValue, text);
6694 }
6695 }
6696 function warnForDeletedHydratableElement(parentNode, child) {
6697 {
6698 if (didWarnInvalidHydration) {
6699 return;
6700 }
6701
6702 didWarnInvalidHydration = true;
6703
6704 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
6705 }
6706 }
6707 function warnForDeletedHydratableText(parentNode, child) {
6708 {
6709 if (didWarnInvalidHydration) {
6710 return;
6711 }
6712
6713 didWarnInvalidHydration = true;
6714
6715 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
6716 }
6717 }
6718 function warnForInsertedHydratedElement(parentNode, tag, props) {
6719 {
6720 if (didWarnInvalidHydration) {
6721 return;
6722 }
6723
6724 didWarnInvalidHydration = true;
6725
6726 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
6727 }
6728 }
6729 function warnForInsertedHydratedText(parentNode, text) {
6730 {
6731 if (text === '') {
6732 // We expect to insert empty text nodes since they're not represented in
6733 // the HTML.
6734 // TODO: Remove this special case if we can just avoid inserting empty
6735 // text nodes.
6736 return;
6737 }
6738
6739 if (didWarnInvalidHydration) {
6740 return;
6741 }
6742
6743 didWarnInvalidHydration = true;
6744
6745 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
6746 }
6747 }
6748 function restoreControlledState$3(domElement, tag, props) {
6749 switch (tag) {
6750 case 'input':
6751 restoreControlledState(domElement, props);
6752 return;
6753
6754 case 'textarea':
6755 restoreControlledState$2(domElement, props);
6756 return;
6757
6758 case 'select':
6759 restoreControlledState$1(domElement, props);
6760 return;
6761 }
6762 }
6763
6764 function getActiveElement(doc) {
6765 doc = doc || (typeof document !== 'undefined' ? document : undefined);
6766
6767 if (typeof doc === 'undefined') {
6768 return null;
6769 }
6770
6771 try {
6772 return doc.activeElement || doc.body;
6773 } catch (e) {
6774 return doc.body;
6775 }
6776 }
6777
6778 /**
6779 * Given any node return the first leaf node without children.
6780 *
6781 * @param {DOMElement|DOMTextNode} node
6782 * @return {DOMElement|DOMTextNode}
6783 */
6784
6785 function getLeafNode(node) {
6786 while (node && node.firstChild) {
6787 node = node.firstChild;
6788 }
6789
6790 return node;
6791 }
6792 /**
6793 * Get the next sibling within a container. This will walk up the
6794 * DOM if a node's siblings have been exhausted.
6795 *
6796 * @param {DOMElement|DOMTextNode} node
6797 * @return {?DOMElement|DOMTextNode}
6798 */
6799
6800
6801 function getSiblingNode(node) {
6802 while (node) {
6803 if (node.nextSibling) {
6804 return node.nextSibling;
6805 }
6806
6807 node = node.parentNode;
6808 }
6809 }
6810 /**
6811 * Get object describing the nodes which contain characters at offset.
6812 *
6813 * @param {DOMElement|DOMTextNode} root
6814 * @param {number} offset
6815 * @return {?object}
6816 */
6817
6818
6819 function getNodeForCharacterOffset(root, offset) {
6820 var node = getLeafNode(root);
6821 var nodeStart = 0;
6822 var nodeEnd = 0;
6823
6824 while (node) {
6825 if (node.nodeType === TEXT_NODE) {
6826 nodeEnd = nodeStart + node.textContent.length;
6827
6828 if (nodeStart <= offset && nodeEnd >= offset) {
6829 return {
6830 node: node,
6831 offset: offset - nodeStart
6832 };
6833 }
6834
6835 nodeStart = nodeEnd;
6836 }
6837
6838 node = getLeafNode(getSiblingNode(node));
6839 }
6840 }
6841
6842 /**
6843 * @param {DOMElement} outerNode
6844 * @return {?object}
6845 */
6846
6847 function getOffsets(outerNode) {
6848 var ownerDocument = outerNode.ownerDocument;
6849 var win = ownerDocument && ownerDocument.defaultView || window;
6850 var selection = win.getSelection && win.getSelection();
6851
6852 if (!selection || selection.rangeCount === 0) {
6853 return null;
6854 }
6855
6856 var anchorNode = selection.anchorNode,
6857 anchorOffset = selection.anchorOffset,
6858 focusNode = selection.focusNode,
6859 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
6860 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
6861 // expose properties, triggering a "Permission denied error" if any of its
6862 // properties are accessed. The only seemingly possible way to avoid erroring
6863 // is to access a property that typically works for non-anonymous divs and
6864 // catch any error that may otherwise arise. See
6865 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
6866
6867 try {
6868 /* eslint-disable no-unused-expressions */
6869 anchorNode.nodeType;
6870 focusNode.nodeType;
6871 /* eslint-enable no-unused-expressions */
6872 } catch (e) {
6873 return null;
6874 }
6875
6876 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
6877 }
6878 /**
6879 * Returns {start, end} where `start` is the character/codepoint index of
6880 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
6881 * `end` is the index of (focusNode, focusOffset).
6882 *
6883 * Returns null if you pass in garbage input but we should probably just crash.
6884 *
6885 * Exported only for testing.
6886 */
6887
6888 function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
6889 var length = 0;
6890 var start = -1;
6891 var end = -1;
6892 var indexWithinAnchor = 0;
6893 var indexWithinFocus = 0;
6894 var node = outerNode;
6895 var parentNode = null;
6896
6897 outer: while (true) {
6898 var next = null;
6899
6900 while (true) {
6901 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
6902 start = length + anchorOffset;
6903 }
6904
6905 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
6906 end = length + focusOffset;
6907 }
6908
6909 if (node.nodeType === TEXT_NODE) {
6910 length += node.nodeValue.length;
6911 }
6912
6913 if ((next = node.firstChild) === null) {
6914 break;
6915 } // Moving from `node` to its first child `next`.
6916
6917
6918 parentNode = node;
6919 node = next;
6920 }
6921
6922 while (true) {
6923 if (node === outerNode) {
6924 // If `outerNode` has children, this is always the second time visiting
6925 // it. If it has no children, this is still the first loop, and the only
6926 // valid selection is anchorNode and focusNode both equal to this node
6927 // and both offsets 0, in which case we will have handled above.
6928 break outer;
6929 }
6930
6931 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
6932 start = length;
6933 }
6934
6935 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
6936 end = length;
6937 }
6938
6939 if ((next = node.nextSibling) !== null) {
6940 break;
6941 }
6942
6943 node = parentNode;
6944 parentNode = node.parentNode;
6945 } // Moving from `node` to its next sibling `next`.
6946
6947
6948 node = next;
6949 }
6950
6951 if (start === -1 || end === -1) {
6952 // This should never happen. (Would happen if the anchor/focus nodes aren't
6953 // actually inside the passed-in node.)
6954 return null;
6955 }
6956
6957 return {
6958 start: start,
6959 end: end
6960 };
6961 }
6962 /**
6963 * In modern non-IE browsers, we can support both forward and backward
6964 * selections.
6965 *
6966 * Note: IE10+ supports the Selection object, but it does not support
6967 * the `extend` method, which means that even in modern IE, it's not possible
6968 * to programmatically create a backward selection. Thus, for all IE
6969 * versions, we use the old IE API to create our selections.
6970 *
6971 * @param {DOMElement|DOMTextNode} node
6972 * @param {object} offsets
6973 */
6974
6975 function setOffsets(node, offsets) {
6976 var doc = node.ownerDocument || document;
6977 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
6978 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
6979 // fails when pasting 100+ items)
6980
6981 if (!win.getSelection) {
6982 return;
6983 }
6984
6985 var selection = win.getSelection();
6986 var length = node.textContent.length;
6987 var start = Math.min(offsets.start, length);
6988 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
6989 // Flip backward selections, so we can set with a single range.
6990
6991 if (!selection.extend && start > end) {
6992 var temp = end;
6993 end = start;
6994 start = temp;
6995 }
6996
6997 var startMarker = getNodeForCharacterOffset(node, start);
6998 var endMarker = getNodeForCharacterOffset(node, end);
6999
7000 if (startMarker && endMarker) {
7001 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
7002 return;
7003 }
7004
7005 var range = doc.createRange();
7006 range.setStart(startMarker.node, startMarker.offset);
7007 selection.removeAllRanges();
7008
7009 if (start > end) {
7010 selection.addRange(range);
7011 selection.extend(endMarker.node, endMarker.offset);
7012 } else {
7013 range.setEnd(endMarker.node, endMarker.offset);
7014 selection.addRange(range);
7015 }
7016 }
7017 }
7018
7019 function isTextNode(node) {
7020 return node && node.nodeType === TEXT_NODE;
7021 }
7022
7023 function containsNode(outerNode, innerNode) {
7024 if (!outerNode || !innerNode) {
7025 return false;
7026 } else if (outerNode === innerNode) {
7027 return true;
7028 } else if (isTextNode(outerNode)) {
7029 return false;
7030 } else if (isTextNode(innerNode)) {
7031 return containsNode(outerNode, innerNode.parentNode);
7032 } else if ('contains' in outerNode) {
7033 return outerNode.contains(innerNode);
7034 } else if (outerNode.compareDocumentPosition) {
7035 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
7036 } else {
7037 return false;
7038 }
7039 }
7040
7041 function isInDocument(node) {
7042 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
7043 }
7044
7045 function isSameOriginFrame(iframe) {
7046 try {
7047 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
7048 // to throw, e.g. if it has a cross-origin src attribute.
7049 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
7050 // iframe.contentDocument.defaultView;
7051 // A safety way is to access one of the cross origin properties: Window or Location
7052 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
7053 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
7054 return typeof iframe.contentWindow.location.href === 'string';
7055 } catch (err) {
7056 return false;
7057 }
7058 }
7059
7060 function getActiveElementDeep() {
7061 var win = window;
7062 var element = getActiveElement();
7063
7064 while (element instanceof win.HTMLIFrameElement) {
7065 if (isSameOriginFrame(element)) {
7066 win = element.contentWindow;
7067 } else {
7068 return element;
7069 }
7070
7071 element = getActiveElement(win.document);
7072 }
7073
7074 return element;
7075 }
7076 /**
7077 * @ReactInputSelection: React input selection module. Based on Selection.js,
7078 * but modified to be suitable for react and has a couple of bug fixes (doesn't
7079 * assume buttons have range selections allowed).
7080 * Input selection module for React.
7081 */
7082
7083 /**
7084 * @hasSelectionCapabilities: we get the element types that support selection
7085 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
7086 * and `selectionEnd` rows.
7087 */
7088
7089
7090 function hasSelectionCapabilities(elem) {
7091 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7092 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
7093 }
7094 function getSelectionInformation() {
7095 var focusedElem = getActiveElementDeep();
7096 return {
7097 // Used by Flare
7098 activeElementDetached: null,
7099 focusedElem: focusedElem,
7100 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
7101 };
7102 }
7103 /**
7104 * @restoreSelection: If any selection information was potentially lost,
7105 * restore it. This is useful when performing operations that could remove dom
7106 * nodes and place them back in, resulting in focus being lost.
7107 */
7108
7109 function restoreSelection(priorSelectionInformation) {
7110 var curFocusedElem = getActiveElementDeep();
7111 var priorFocusedElem = priorSelectionInformation.focusedElem;
7112 var priorSelectionRange = priorSelectionInformation.selectionRange;
7113
7114 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
7115 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
7116 setSelection(priorFocusedElem, priorSelectionRange);
7117 } // Focusing a node can change the scroll position, which is undesirable
7118
7119
7120 var ancestors = [];
7121 var ancestor = priorFocusedElem;
7122
7123 while (ancestor = ancestor.parentNode) {
7124 if (ancestor.nodeType === ELEMENT_NODE) {
7125 ancestors.push({
7126 element: ancestor,
7127 left: ancestor.scrollLeft,
7128 top: ancestor.scrollTop
7129 });
7130 }
7131 }
7132
7133 if (typeof priorFocusedElem.focus === 'function') {
7134 priorFocusedElem.focus();
7135 }
7136
7137 for (var i = 0; i < ancestors.length; i++) {
7138 var info = ancestors[i];
7139 info.element.scrollLeft = info.left;
7140 info.element.scrollTop = info.top;
7141 }
7142 }
7143 }
7144 /**
7145 * @getSelection: Gets the selection bounds of a focused textarea, input or
7146 * contentEditable node.
7147 * -@input: Look up selection bounds of this input
7148 * -@return {start: selectionStart, end: selectionEnd}
7149 */
7150
7151 function getSelection(input) {
7152 var selection;
7153
7154 if ('selectionStart' in input) {
7155 // Modern browser with input or textarea.
7156 selection = {
7157 start: input.selectionStart,
7158 end: input.selectionEnd
7159 };
7160 } else {
7161 // Content editable or old IE textarea.
7162 selection = getOffsets(input);
7163 }
7164
7165 return selection || {
7166 start: 0,
7167 end: 0
7168 };
7169 }
7170 /**
7171 * @setSelection: Sets the selection bounds of a textarea or input and focuses
7172 * the input.
7173 * -@input Set selection bounds of this input or textarea
7174 * -@offsets Object of same form that is returned from get*
7175 */
7176
7177 function setSelection(input, offsets) {
7178 var start = offsets.start,
7179 end = offsets.end;
7180
7181 if (end === undefined) {
7182 end = start;
7183 }
7184
7185 if ('selectionStart' in input) {
7186 input.selectionStart = start;
7187 input.selectionEnd = Math.min(end, input.value.length);
7188 } else {
7189 setOffsets(input, offsets);
7190 }
7191 }
7192
7193 var validateDOMNesting = function () {};
7194
7195 var updatedAncestorInfo = function () {};
7196
7197 {
7198 // This validation code was written based on the HTML5 parsing spec:
7199 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
7200 //
7201 // Note: this does not catch all invalid nesting, nor does it try to (as it's
7202 // not clear what practical benefit doing so provides); instead, we warn only
7203 // for cases where the parser will give a parse tree differing from what React
7204 // intended. For example, <b><div></div></b> is invalid but we don't warn
7205 // because it still parses correctly; we do warn for other cases like nested
7206 // <p> tags where the beginning of the second element implicitly closes the
7207 // first, causing a confusing mess.
7208 // https://html.spec.whatwg.org/multipage/syntax.html#special
7209 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
7210
7211 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
7212 // TODO: Distinguish by namespace here -- for <title>, including it here
7213 // errs on the side of fewer warnings
7214 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
7215
7216 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
7217
7218 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
7219 var emptyAncestorInfo = {
7220 current: null,
7221 formTag: null,
7222 aTagInScope: null,
7223 buttonTagInScope: null,
7224 nobrTagInScope: null,
7225 pTagInButtonScope: null,
7226 listItemTagAutoclosing: null,
7227 dlItemTagAutoclosing: null
7228 };
7229
7230 updatedAncestorInfo = function (oldInfo, tag) {
7231 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
7232
7233 var info = {
7234 tag: tag
7235 };
7236
7237 if (inScopeTags.indexOf(tag) !== -1) {
7238 ancestorInfo.aTagInScope = null;
7239 ancestorInfo.buttonTagInScope = null;
7240 ancestorInfo.nobrTagInScope = null;
7241 }
7242
7243 if (buttonScopeTags.indexOf(tag) !== -1) {
7244 ancestorInfo.pTagInButtonScope = null;
7245 } // See rules for 'li', 'dd', 'dt' start tags in
7246 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
7247
7248
7249 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
7250 ancestorInfo.listItemTagAutoclosing = null;
7251 ancestorInfo.dlItemTagAutoclosing = null;
7252 }
7253
7254 ancestorInfo.current = info;
7255
7256 if (tag === 'form') {
7257 ancestorInfo.formTag = info;
7258 }
7259
7260 if (tag === 'a') {
7261 ancestorInfo.aTagInScope = info;
7262 }
7263
7264 if (tag === 'button') {
7265 ancestorInfo.buttonTagInScope = info;
7266 }
7267
7268 if (tag === 'nobr') {
7269 ancestorInfo.nobrTagInScope = info;
7270 }
7271
7272 if (tag === 'p') {
7273 ancestorInfo.pTagInButtonScope = info;
7274 }
7275
7276 if (tag === 'li') {
7277 ancestorInfo.listItemTagAutoclosing = info;
7278 }
7279
7280 if (tag === 'dd' || tag === 'dt') {
7281 ancestorInfo.dlItemTagAutoclosing = info;
7282 }
7283
7284 return ancestorInfo;
7285 };
7286 /**
7287 * Returns whether
7288 */
7289
7290
7291 var isTagValidWithParent = function (tag, parentTag) {
7292 // First, let's check if we're in an unusual parsing mode...
7293 switch (parentTag) {
7294 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
7295 case 'select':
7296 return tag === 'option' || tag === 'optgroup' || tag === '#text';
7297
7298 case 'optgroup':
7299 return tag === 'option' || tag === '#text';
7300 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
7301 // but
7302
7303 case 'option':
7304 return tag === '#text';
7305 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
7306 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
7307 // No special behavior since these rules fall back to "in body" mode for
7308 // all except special table nodes which cause bad parsing behavior anyway.
7309 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
7310
7311 case 'tr':
7312 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
7313 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
7314
7315 case 'tbody':
7316 case 'thead':
7317 case 'tfoot':
7318 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
7319 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
7320
7321 case 'colgroup':
7322 return tag === 'col' || tag === 'template';
7323 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
7324
7325 case 'table':
7326 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
7327 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
7328
7329 case 'head':
7330 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
7331 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
7332
7333 case 'html':
7334 return tag === 'head' || tag === 'body' || tag === 'frameset';
7335
7336 case 'frameset':
7337 return tag === 'frame';
7338
7339 case '#document':
7340 return tag === 'html';
7341 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
7342 // where the parsing rules cause implicit opens or closes to be added.
7343 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
7344
7345
7346 switch (tag) {
7347 case 'h1':
7348 case 'h2':
7349 case 'h3':
7350 case 'h4':
7351 case 'h5':
7352 case 'h6':
7353 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
7354
7355 case 'rp':
7356 case 'rt':
7357 return impliedEndTags.indexOf(parentTag) === -1;
7358
7359 case 'body':
7360 case 'caption':
7361 case 'col':
7362 case 'colgroup':
7363 case 'frameset':
7364 case 'frame':
7365 case 'head':
7366 case 'html':
7367 case 'tbody':
7368 case 'td':
7369 case 'tfoot':
7370 case 'th':
7371 case 'thead':
7372 case 'tr':
7373 // These tags are only valid with a few parents that have special child
7374 // parsing rules -- if we're down here, then none of those matched and
7375 // so we allow it only if we don't know what the parent is, as all other
7376 // cases are invalid.
7377 return parentTag == null;
7378 }
7379
7380 return true;
7381 };
7382 /**
7383 * Returns whether
7384 */
7385
7386
7387 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
7388 switch (tag) {
7389 case 'address':
7390 case 'article':
7391 case 'aside':
7392 case 'blockquote':
7393 case 'center':
7394 case 'details':
7395 case 'dialog':
7396 case 'dir':
7397 case 'div':
7398 case 'dl':
7399 case 'fieldset':
7400 case 'figcaption':
7401 case 'figure':
7402 case 'footer':
7403 case 'header':
7404 case 'hgroup':
7405 case 'main':
7406 case 'menu':
7407 case 'nav':
7408 case 'ol':
7409 case 'p':
7410 case 'section':
7411 case 'summary':
7412 case 'ul':
7413 case 'pre':
7414 case 'listing':
7415 case 'table':
7416 case 'hr':
7417 case 'xmp':
7418 case 'h1':
7419 case 'h2':
7420 case 'h3':
7421 case 'h4':
7422 case 'h5':
7423 case 'h6':
7424 return ancestorInfo.pTagInButtonScope;
7425
7426 case 'form':
7427 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
7428
7429 case 'li':
7430 return ancestorInfo.listItemTagAutoclosing;
7431
7432 case 'dd':
7433 case 'dt':
7434 return ancestorInfo.dlItemTagAutoclosing;
7435
7436 case 'button':
7437 return ancestorInfo.buttonTagInScope;
7438
7439 case 'a':
7440 // Spec says something about storing a list of markers, but it sounds
7441 // equivalent to this check.
7442 return ancestorInfo.aTagInScope;
7443
7444 case 'nobr':
7445 return ancestorInfo.nobrTagInScope;
7446 }
7447
7448 return null;
7449 };
7450
7451 var didWarn$1 = {};
7452
7453 validateDOMNesting = function (childTag, childText, ancestorInfo) {
7454 ancestorInfo = ancestorInfo || emptyAncestorInfo;
7455 var parentInfo = ancestorInfo.current;
7456 var parentTag = parentInfo && parentInfo.tag;
7457
7458 if (childText != null) {
7459 if (childTag != null) {
7460 error('validateDOMNesting: when childText is passed, childTag should be null');
7461 }
7462
7463 childTag = '#text';
7464 }
7465
7466 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
7467 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
7468 var invalidParentOrAncestor = invalidParent || invalidAncestor;
7469
7470 if (!invalidParentOrAncestor) {
7471 return;
7472 }
7473
7474 var ancestorTag = invalidParentOrAncestor.tag;
7475 var addendum = getCurrentFiberStackInDev();
7476 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
7477
7478 if (didWarn$1[warnKey]) {
7479 return;
7480 }
7481
7482 didWarn$1[warnKey] = true;
7483 var tagDisplayName = childTag;
7484 var whitespaceInfo = '';
7485
7486 if (childTag === '#text') {
7487 if (/\S/.test(childText)) {
7488 tagDisplayName = 'Text nodes';
7489 } else {
7490 tagDisplayName = 'Whitespace text nodes';
7491 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
7492 }
7493 } else {
7494 tagDisplayName = '<' + childTag + '>';
7495 }
7496
7497 if (invalidParent) {
7498 var info = '';
7499
7500 if (ancestorTag === 'table' && childTag === 'tr') {
7501 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
7502 }
7503
7504 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);
7505 } else {
7506 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);
7507 }
7508 };
7509 }
7510
7511 var SUPPRESS_HYDRATION_WARNING$1;
7512
7513 {
7514 SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7515 }
7516
7517 var SUSPENSE_START_DATA = '$';
7518 var SUSPENSE_END_DATA = '/$';
7519 var SUSPENSE_PENDING_START_DATA = '$?';
7520 var SUSPENSE_FALLBACK_START_DATA = '$!';
7521 var STYLE$1 = 'style';
7522 var eventsEnabled = null;
7523 var selectionInformation = null;
7524
7525 function shouldAutoFocusHostComponent(type, props) {
7526 switch (type) {
7527 case 'button':
7528 case 'input':
7529 case 'select':
7530 case 'textarea':
7531 return !!props.autoFocus;
7532 }
7533
7534 return false;
7535 }
7536 function getRootHostContext(rootContainerInstance) {
7537 var type;
7538 var namespace;
7539 var nodeType = rootContainerInstance.nodeType;
7540
7541 switch (nodeType) {
7542 case DOCUMENT_NODE:
7543 case DOCUMENT_FRAGMENT_NODE:
7544 {
7545 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
7546 var root = rootContainerInstance.documentElement;
7547 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
7548 break;
7549 }
7550
7551 default:
7552 {
7553 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
7554 var ownNamespace = container.namespaceURI || null;
7555 type = container.tagName;
7556 namespace = getChildNamespace(ownNamespace, type);
7557 break;
7558 }
7559 }
7560
7561 {
7562 var validatedTag = type.toLowerCase();
7563 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
7564 return {
7565 namespace: namespace,
7566 ancestorInfo: ancestorInfo
7567 };
7568 }
7569 }
7570 function getChildHostContext(parentHostContext, type, rootContainerInstance) {
7571 {
7572 var parentHostContextDev = parentHostContext;
7573 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
7574 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
7575 return {
7576 namespace: namespace,
7577 ancestorInfo: ancestorInfo
7578 };
7579 }
7580 }
7581 function getPublicInstance(instance) {
7582 return instance;
7583 }
7584 function prepareForCommit(containerInfo) {
7585 eventsEnabled = isEnabled();
7586 selectionInformation = getSelectionInformation();
7587 setEnabled(false);
7588 }
7589 function resetAfterCommit(containerInfo) {
7590 restoreSelection(selectionInformation);
7591 setEnabled(eventsEnabled);
7592 eventsEnabled = null;
7593
7594 selectionInformation = null;
7595 }
7596 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
7597 var parentNamespace;
7598
7599 {
7600 // TODO: take namespace into account when validating.
7601 var hostContextDev = hostContext;
7602 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
7603
7604 if (typeof props.children === 'string' || typeof props.children === 'number') {
7605 var string = '' + props.children;
7606 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
7607 validateDOMNesting(null, string, ownAncestorInfo);
7608 }
7609
7610 parentNamespace = hostContextDev.namespace;
7611 }
7612
7613 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
7614 precacheFiberNode(internalInstanceHandle, domElement);
7615 updateFiberProps(domElement, props);
7616 return domElement;
7617 }
7618 function appendInitialChild(parentInstance, child) {
7619 parentInstance.appendChild(child);
7620 }
7621 function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
7622 setInitialProperties(domElement, type, props, rootContainerInstance);
7623 return shouldAutoFocusHostComponent(type, props);
7624 }
7625 function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
7626 {
7627 var hostContextDev = hostContext;
7628
7629 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
7630 var string = '' + newProps.children;
7631 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
7632 validateDOMNesting(null, string, ownAncestorInfo);
7633 }
7634 }
7635
7636 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
7637 }
7638 function shouldSetTextContent(type, props) {
7639 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;
7640 }
7641 function shouldDeprioritizeSubtree(type, props) {
7642 return !!props.hidden;
7643 }
7644 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
7645 {
7646 var hostContextDev = hostContext;
7647 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
7648 }
7649
7650 var textNode = createTextNode(text, rootContainerInstance);
7651 precacheFiberNode(internalInstanceHandle, textNode);
7652 return textNode;
7653 }
7654 // if a component just imports ReactDOM (e.g. for findDOMNode).
7655 // Some environments might not have setTimeout or clearTimeout.
7656
7657 var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
7658 var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
7659 var noTimeout = -1; // -------------------
7660 function commitMount(domElement, type, newProps, internalInstanceHandle) {
7661 // Despite the naming that might imply otherwise, this method only
7662 // fires if there is an `Update` effect scheduled during mounting.
7663 // This happens if `finalizeInitialChildren` returns `true` (which it
7664 // does to implement the `autoFocus` attribute on the client). But
7665 // there are also other cases when this might happen (such as patching
7666 // up text content during hydration mismatch). So we'll check this again.
7667 if (shouldAutoFocusHostComponent(type, newProps)) {
7668 domElement.focus();
7669 }
7670 }
7671 function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
7672 // Update the props handle so that we know which props are the ones with
7673 // with current event handlers.
7674 updateFiberProps(domElement, newProps); // Apply the diff to the DOM node.
7675
7676 updateProperties(domElement, updatePayload, type, oldProps, newProps);
7677 }
7678 function resetTextContent(domElement) {
7679 setTextContent(domElement, '');
7680 }
7681 function commitTextUpdate(textInstance, oldText, newText) {
7682 textInstance.nodeValue = newText;
7683 }
7684 function appendChild(parentInstance, child) {
7685 parentInstance.appendChild(child);
7686 }
7687 function appendChildToContainer(container, child) {
7688 var parentNode;
7689
7690 if (container.nodeType === COMMENT_NODE) {
7691 parentNode = container.parentNode;
7692 parentNode.insertBefore(child, container);
7693 } else {
7694 parentNode = container;
7695 parentNode.appendChild(child);
7696 } // This container might be used for a portal.
7697 // If something inside a portal is clicked, that click should bubble
7698 // through the React tree. However, on Mobile Safari the click would
7699 // never bubble through the *DOM* tree unless an ancestor with onclick
7700 // event exists. So we wouldn't see it and dispatch it.
7701 // This is why we ensure that non React root containers have inline onclick
7702 // defined.
7703 // https://github.com/facebook/react/issues/11918
7704
7705
7706 var reactRootContainer = container._reactRootContainer;
7707
7708 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
7709 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7710 trapClickOnNonInteractiveElement(parentNode);
7711 }
7712 }
7713 function insertBefore(parentInstance, child, beforeChild) {
7714 parentInstance.insertBefore(child, beforeChild);
7715 }
7716 function insertInContainerBefore(container, child, beforeChild) {
7717 if (container.nodeType === COMMENT_NODE) {
7718 container.parentNode.insertBefore(child, beforeChild);
7719 } else {
7720 container.insertBefore(child, beforeChild);
7721 }
7722 }
7723 function removeChild(parentInstance, child) {
7724 parentInstance.removeChild(child);
7725 }
7726 function removeChildFromContainer(container, child) {
7727 if (container.nodeType === COMMENT_NODE) {
7728 container.parentNode.removeChild(child);
7729 } else {
7730 container.removeChild(child);
7731 }
7732 }
7733
7734 function hideInstance(instance) {
7735 // pass host context to this method?
7736
7737
7738 instance = instance;
7739 var style = instance.style;
7740
7741 if (typeof style.setProperty === 'function') {
7742 style.setProperty('display', 'none', 'important');
7743 } else {
7744 style.display = 'none';
7745 }
7746 }
7747 function hideTextInstance(textInstance) {
7748 textInstance.nodeValue = '';
7749 }
7750 function unhideInstance(instance, props) {
7751 instance = instance;
7752 var styleProp = props[STYLE$1];
7753 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
7754 instance.style.display = dangerousStyleValue('display', display);
7755 }
7756 function unhideTextInstance(textInstance, text) {
7757 textInstance.nodeValue = text;
7758 } // -------------------
7759 function canHydrateInstance(instance, type, props) {
7760 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
7761 return null;
7762 } // This has now been refined to an element node.
7763
7764
7765 return instance;
7766 }
7767 function canHydrateTextInstance(instance, text) {
7768 if (text === '' || instance.nodeType !== TEXT_NODE) {
7769 // Empty strings are not parsed by HTML so there won't be a correct match here.
7770 return null;
7771 } // This has now been refined to a text node.
7772
7773
7774 return instance;
7775 }
7776 function isSuspenseInstancePending(instance) {
7777 return instance.data === SUSPENSE_PENDING_START_DATA;
7778 }
7779 function isSuspenseInstanceFallback(instance) {
7780 return instance.data === SUSPENSE_FALLBACK_START_DATA;
7781 }
7782
7783 function getNextHydratable(node) {
7784 // Skip non-hydratable nodes.
7785 for (; node != null; node = node.nextSibling) {
7786 var nodeType = node.nodeType;
7787
7788 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
7789 break;
7790 }
7791 }
7792
7793 return node;
7794 }
7795
7796 function getNextHydratableSibling(instance) {
7797 return getNextHydratable(instance.nextSibling);
7798 }
7799 function getFirstHydratableChild(parentInstance) {
7800 return getNextHydratable(parentInstance.firstChild);
7801 }
7802 function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
7803 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
7804 // get attached.
7805
7806 updateFiberProps(instance, props);
7807 var parentNamespace;
7808
7809 {
7810 var hostContextDev = hostContext;
7811 parentNamespace = hostContextDev.namespace;
7812 }
7813
7814 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
7815 }
7816 function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
7817 precacheFiberNode(internalInstanceHandle, textInstance);
7818 return diffHydratedText(textInstance, text);
7819 }
7820 function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
7821 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
7822 // There might be nested nodes so we need to keep track of how
7823 // deep we are and only break out when we're back on top.
7824
7825 var depth = 0;
7826
7827 while (node) {
7828 if (node.nodeType === COMMENT_NODE) {
7829 var data = node.data;
7830
7831 if (data === SUSPENSE_END_DATA) {
7832 if (depth === 0) {
7833 return getNextHydratableSibling(node);
7834 } else {
7835 depth--;
7836 }
7837 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
7838 depth++;
7839 }
7840 }
7841
7842 node = node.nextSibling;
7843 } // TODO: Warn, we didn't find the end comment boundary.
7844
7845
7846 return null;
7847 } // Returns the SuspenseInstance if this node is a direct child of a
7848 // SuspenseInstance. I.e. if its previous sibling is a Comment with
7849 // SUSPENSE_x_START_DATA. Otherwise, null.
7850
7851 function getParentSuspenseInstance(targetInstance) {
7852 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
7853 // There might be nested nodes so we need to keep track of how
7854 // deep we are and only break out when we're back on top.
7855
7856 var depth = 0;
7857
7858 while (node) {
7859 if (node.nodeType === COMMENT_NODE) {
7860 var data = node.data;
7861
7862 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
7863 if (depth === 0) {
7864 return node;
7865 } else {
7866 depth--;
7867 }
7868 } else if (data === SUSPENSE_END_DATA) {
7869 depth++;
7870 }
7871 }
7872
7873 node = node.previousSibling;
7874 }
7875
7876 return null;
7877 }
7878 function commitHydratedContainer(container) {
7879 // Retry if any event replaying was blocked on this.
7880 retryIfBlockedOn(container);
7881 }
7882 function commitHydratedSuspenseInstance(suspenseInstance) {
7883 // Retry if any event replaying was blocked on this.
7884 retryIfBlockedOn(suspenseInstance);
7885 }
7886 function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
7887 {
7888 warnForUnmatchedText(textInstance, text);
7889 }
7890 }
7891 function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
7892 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7893 warnForUnmatchedText(textInstance, text);
7894 }
7895 }
7896 function didNotHydrateContainerInstance(parentContainer, instance) {
7897 {
7898 if (instance.nodeType === ELEMENT_NODE) {
7899 warnForDeletedHydratableElement(parentContainer, instance);
7900 } else if (instance.nodeType === COMMENT_NODE) ; else {
7901 warnForDeletedHydratableText(parentContainer, instance);
7902 }
7903 }
7904 }
7905 function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
7906 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7907 if (instance.nodeType === ELEMENT_NODE) {
7908 warnForDeletedHydratableElement(parentInstance, instance);
7909 } else if (instance.nodeType === COMMENT_NODE) ; else {
7910 warnForDeletedHydratableText(parentInstance, instance);
7911 }
7912 }
7913 }
7914 function didNotFindHydratableContainerInstance(parentContainer, type, props) {
7915 {
7916 warnForInsertedHydratedElement(parentContainer, type);
7917 }
7918 }
7919 function didNotFindHydratableContainerTextInstance(parentContainer, text) {
7920 {
7921 warnForInsertedHydratedText(parentContainer, text);
7922 }
7923 }
7924 function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
7925 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7926 warnForInsertedHydratedElement(parentInstance, type);
7927 }
7928 }
7929 function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
7930 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
7931 warnForInsertedHydratedText(parentInstance, text);
7932 }
7933 }
7934 function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
7935 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) ;
7936 }
7937
7938 var randomKey = Math.random().toString(36).slice(2);
7939 var internalInstanceKey = '__reactInternalInstance$' + randomKey;
7940 var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
7941 var internalContainerInstanceKey = '__reactContainere$' + randomKey;
7942 function precacheFiberNode(hostInst, node) {
7943 node[internalInstanceKey] = hostInst;
7944 }
7945 function markContainerAsRoot(hostRoot, node) {
7946 node[internalContainerInstanceKey] = hostRoot;
7947 }
7948 function unmarkContainerAsRoot(node) {
7949 node[internalContainerInstanceKey] = null;
7950 }
7951 function isContainerMarkedAsRoot(node) {
7952 return !!node[internalContainerInstanceKey];
7953 } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
7954 // If the target node is part of a hydrated or not yet rendered subtree, then
7955 // this may also return a SuspenseComponent or HostRoot to indicate that.
7956 // Conceptually the HostRoot fiber is a child of the Container node. So if you
7957 // pass the Container node as the targetNode, you will not actually get the
7958 // HostRoot back. To get to the HostRoot, you need to pass a child of it.
7959 // The same thing applies to Suspense boundaries.
7960
7961 function getClosestInstanceFromNode(targetNode) {
7962 var targetInst = targetNode[internalInstanceKey];
7963
7964 if (targetInst) {
7965 // Don't return HostRoot or SuspenseComponent here.
7966 return targetInst;
7967 } // If the direct event target isn't a React owned DOM node, we need to look
7968 // to see if one of its parents is a React owned DOM node.
7969
7970
7971 var parentNode = targetNode.parentNode;
7972
7973 while (parentNode) {
7974 // We'll check if this is a container root that could include
7975 // React nodes in the future. We need to check this first because
7976 // if we're a child of a dehydrated container, we need to first
7977 // find that inner container before moving on to finding the parent
7978 // instance. Note that we don't check this field on the targetNode
7979 // itself because the fibers are conceptually between the container
7980 // node and the first child. It isn't surrounding the container node.
7981 // If it's not a container, we check if it's an instance.
7982 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
7983
7984 if (targetInst) {
7985 // Since this wasn't the direct target of the event, we might have
7986 // stepped past dehydrated DOM nodes to get here. However they could
7987 // also have been non-React nodes. We need to answer which one.
7988 // If we the instance doesn't have any children, then there can't be
7989 // a nested suspense boundary within it. So we can use this as a fast
7990 // bailout. Most of the time, when people add non-React children to
7991 // the tree, it is using a ref to a child-less DOM node.
7992 // Normally we'd only need to check one of the fibers because if it
7993 // has ever gone from having children to deleting them or vice versa
7994 // it would have deleted the dehydrated boundary nested inside already.
7995 // However, since the HostRoot starts out with an alternate it might
7996 // have one on the alternate so we need to check in case this was a
7997 // root.
7998 var alternate = targetInst.alternate;
7999
8000 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
8001 // Next we need to figure out if the node that skipped past is
8002 // nested within a dehydrated boundary and if so, which one.
8003 var suspenseInstance = getParentSuspenseInstance(targetNode);
8004
8005 while (suspenseInstance !== null) {
8006 // We found a suspense instance. That means that we haven't
8007 // hydrated it yet. Even though we leave the comments in the
8008 // DOM after hydrating, and there are boundaries in the DOM
8009 // that could already be hydrated, we wouldn't have found them
8010 // through this pass since if the target is hydrated it would
8011 // have had an internalInstanceKey on it.
8012 // Let's get the fiber associated with the SuspenseComponent
8013 // as the deepest instance.
8014 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
8015
8016 if (targetSuspenseInst) {
8017 return targetSuspenseInst;
8018 } // If we don't find a Fiber on the comment, it might be because
8019 // we haven't gotten to hydrate it yet. There might still be a
8020 // parent boundary that hasn't above this one so we need to find
8021 // the outer most that is known.
8022
8023
8024 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
8025 // host component also hasn't hydrated yet. We can return it
8026 // below since it will bail out on the isMounted check later.
8027 }
8028 }
8029
8030 return targetInst;
8031 }
8032
8033 targetNode = parentNode;
8034 parentNode = targetNode.parentNode;
8035 }
8036
8037 return null;
8038 }
8039 /**
8040 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
8041 * instance, or null if the node was not rendered by this React.
8042 */
8043
8044 function getInstanceFromNode$1(node) {
8045 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
8046
8047 if (inst) {
8048 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
8049 return inst;
8050 } else {
8051 return null;
8052 }
8053 }
8054
8055 return null;
8056 }
8057 /**
8058 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
8059 * DOM node.
8060 */
8061
8062 function getNodeFromInstance$1(inst) {
8063 if (inst.tag === HostComponent || inst.tag === HostText) {
8064 // In Fiber this, is just the state node right now. We assume it will be
8065 // a host component or host text.
8066 return inst.stateNode;
8067 } // Without this first invariant, passing a non-DOM-component triggers the next
8068 // invariant for a missing parent, which is super confusing.
8069
8070
8071 {
8072 {
8073 throw Error( "getNodeFromInstance: Invalid argument." );
8074 }
8075 }
8076 }
8077 function getFiberCurrentPropsFromNode$1(node) {
8078 return node[internalEventHandlersKey] || null;
8079 }
8080 function updateFiberProps(node, props) {
8081 node[internalEventHandlersKey] = props;
8082 }
8083
8084 function getParent(inst) {
8085 do {
8086 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
8087 // That is depending on if we want nested subtrees (layers) to bubble
8088 // events to their parent. We could also go through parentNode on the
8089 // host node but that wouldn't work for React Native and doesn't let us
8090 // do the portal feature.
8091 } while (inst && inst.tag !== HostComponent);
8092
8093 if (inst) {
8094 return inst;
8095 }
8096
8097 return null;
8098 }
8099 /**
8100 * Return the lowest common ancestor of A and B, or null if they are in
8101 * different trees.
8102 */
8103
8104
8105 function getLowestCommonAncestor(instA, instB) {
8106 var depthA = 0;
8107
8108 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
8109 depthA++;
8110 }
8111
8112 var depthB = 0;
8113
8114 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
8115 depthB++;
8116 } // If A is deeper, crawl up.
8117
8118
8119 while (depthA - depthB > 0) {
8120 instA = getParent(instA);
8121 depthA--;
8122 } // If B is deeper, crawl up.
8123
8124
8125 while (depthB - depthA > 0) {
8126 instB = getParent(instB);
8127 depthB--;
8128 } // Walk in lockstep until we find a match.
8129
8130
8131 var depth = depthA;
8132
8133 while (depth--) {
8134 if (instA === instB || instA === instB.alternate) {
8135 return instA;
8136 }
8137
8138 instA = getParent(instA);
8139 instB = getParent(instB);
8140 }
8141
8142 return null;
8143 }
8144 /**
8145 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
8146 */
8147
8148 function traverseTwoPhase(inst, fn, arg) {
8149 var path = [];
8150
8151 while (inst) {
8152 path.push(inst);
8153 inst = getParent(inst);
8154 }
8155
8156 var i;
8157
8158 for (i = path.length; i-- > 0;) {
8159 fn(path[i], 'captured', arg);
8160 }
8161
8162 for (i = 0; i < path.length; i++) {
8163 fn(path[i], 'bubbled', arg);
8164 }
8165 }
8166 /**
8167 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
8168 * should would receive a `mouseEnter` or `mouseLeave` event.
8169 *
8170 * Does not invoke the callback on the nearest common ancestor because nothing
8171 * "entered" or "left" that element.
8172 */
8173
8174 function traverseEnterLeave(from, to, fn, argFrom, argTo) {
8175 var common = from && to ? getLowestCommonAncestor(from, to) : null;
8176 var pathFrom = [];
8177
8178 while (true) {
8179 if (!from) {
8180 break;
8181 }
8182
8183 if (from === common) {
8184 break;
8185 }
8186
8187 var alternate = from.alternate;
8188
8189 if (alternate !== null && alternate === common) {
8190 break;
8191 }
8192
8193 pathFrom.push(from);
8194 from = getParent(from);
8195 }
8196
8197 var pathTo = [];
8198
8199 while (true) {
8200 if (!to) {
8201 break;
8202 }
8203
8204 if (to === common) {
8205 break;
8206 }
8207
8208 var _alternate = to.alternate;
8209
8210 if (_alternate !== null && _alternate === common) {
8211 break;
8212 }
8213
8214 pathTo.push(to);
8215 to = getParent(to);
8216 }
8217
8218 for (var i = 0; i < pathFrom.length; i++) {
8219 fn(pathFrom[i], 'bubbled', argFrom);
8220 }
8221
8222 for (var _i = pathTo.length; _i-- > 0;) {
8223 fn(pathTo[_i], 'captured', argTo);
8224 }
8225 }
8226
8227 function isInteractive(tag) {
8228 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
8229 }
8230
8231 function shouldPreventMouseEvent(name, type, props) {
8232 switch (name) {
8233 case 'onClick':
8234 case 'onClickCapture':
8235 case 'onDoubleClick':
8236 case 'onDoubleClickCapture':
8237 case 'onMouseDown':
8238 case 'onMouseDownCapture':
8239 case 'onMouseMove':
8240 case 'onMouseMoveCapture':
8241 case 'onMouseUp':
8242 case 'onMouseUpCapture':
8243 case 'onMouseEnter':
8244 return !!(props.disabled && isInteractive(type));
8245
8246 default:
8247 return false;
8248 }
8249 }
8250 /**
8251 * @param {object} inst The instance, which is the source of events.
8252 * @param {string} registrationName Name of listener (e.g. `onClick`).
8253 * @return {?function} The stored callback.
8254 */
8255
8256
8257 function getListener(inst, registrationName) {
8258 var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
8259 // live here; needs to be moved to a better place soon
8260
8261 var stateNode = inst.stateNode;
8262
8263 if (!stateNode) {
8264 // Work in progress (ex: onload events in incremental mode).
8265 return null;
8266 }
8267
8268 var props = getFiberCurrentPropsFromNode(stateNode);
8269
8270 if (!props) {
8271 // Work in progress.
8272 return null;
8273 }
8274
8275 listener = props[registrationName];
8276
8277 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
8278 return null;
8279 }
8280
8281 if (!(!listener || typeof listener === 'function')) {
8282 {
8283 throw Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type." );
8284 }
8285 }
8286
8287 return listener;
8288 }
8289
8290 /**
8291 * Some event types have a notion of different registration names for different
8292 * "phases" of propagation. This finds listeners by a given phase.
8293 */
8294 function listenerAtPhase(inst, event, propagationPhase) {
8295 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
8296 return getListener(inst, registrationName);
8297 }
8298 /**
8299 * A small set of propagation patterns, each of which will accept a small amount
8300 * of information, and generate a set of "dispatch ready event objects" - which
8301 * are sets of events that have already been annotated with a set of dispatched
8302 * listener functions/ids. The API is designed this way to discourage these
8303 * propagation strategies from actually executing the dispatches, since we
8304 * always want to collect the entire set of dispatches before executing even a
8305 * single one.
8306 */
8307
8308 /**
8309 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
8310 * here, allows us to not have to bind or create functions for each event.
8311 * Mutating the event's members allows us to not have to create a wrapping
8312 * "dispatch" object that pairs the event with the listener.
8313 */
8314
8315
8316 function accumulateDirectionalDispatches(inst, phase, event) {
8317 {
8318 if (!inst) {
8319 error('Dispatching inst must not be null');
8320 }
8321 }
8322
8323 var listener = listenerAtPhase(inst, event, phase);
8324
8325 if (listener) {
8326 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
8327 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
8328 }
8329 }
8330 /**
8331 * Collect dispatches (must be entirely collected before dispatching - see unit
8332 * tests). Lazily allocate the array to conserve memory. We must loop through
8333 * each event and perform the traversal for each one. We cannot perform a
8334 * single traversal for the entire collection of events because each event may
8335 * have a different target.
8336 */
8337
8338
8339 function accumulateTwoPhaseDispatchesSingle(event) {
8340 if (event && event.dispatchConfig.phasedRegistrationNames) {
8341 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
8342 }
8343 }
8344 /**
8345 * Accumulates without regard to direction, does not look for phased
8346 * registration names. Same as `accumulateDirectDispatchesSingle` but without
8347 * requiring that the `dispatchMarker` be the same as the dispatched ID.
8348 */
8349
8350
8351 function accumulateDispatches(inst, ignoredDirection, event) {
8352 if (inst && event && event.dispatchConfig.registrationName) {
8353 var registrationName = event.dispatchConfig.registrationName;
8354 var listener = getListener(inst, registrationName);
8355
8356 if (listener) {
8357 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
8358 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
8359 }
8360 }
8361 }
8362 /**
8363 * Accumulates dispatches on an `SyntheticEvent`, but only for the
8364 * `dispatchMarker`.
8365 * @param {SyntheticEvent} event
8366 */
8367
8368
8369 function accumulateDirectDispatchesSingle(event) {
8370 if (event && event.dispatchConfig.registrationName) {
8371 accumulateDispatches(event._targetInst, null, event);
8372 }
8373 }
8374
8375 function accumulateTwoPhaseDispatches(events) {
8376 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
8377 }
8378 function accumulateEnterLeaveDispatches(leave, enter, from, to) {
8379 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
8380 }
8381 function accumulateDirectDispatches(events) {
8382 forEachAccumulated(events, accumulateDirectDispatchesSingle);
8383 }
8384
8385 /**
8386 * These variables store information about text content of a target node,
8387 * allowing comparison of content before and after a given event.
8388 *
8389 * Identify the node where selection currently begins, then observe
8390 * both its text content and its current position in the DOM. Since the
8391 * browser may natively replace the target node during composition, we can
8392 * use its position to find its replacement.
8393 *
8394 *
8395 */
8396 var root = null;
8397 var startText = null;
8398 var fallbackText = null;
8399 function initialize(nativeEventTarget) {
8400 root = nativeEventTarget;
8401 startText = getText();
8402 return true;
8403 }
8404 function reset() {
8405 root = null;
8406 startText = null;
8407 fallbackText = null;
8408 }
8409 function getData() {
8410 if (fallbackText) {
8411 return fallbackText;
8412 }
8413
8414 var start;
8415 var startValue = startText;
8416 var startLength = startValue.length;
8417 var end;
8418 var endValue = getText();
8419 var endLength = endValue.length;
8420
8421 for (start = 0; start < startLength; start++) {
8422 if (startValue[start] !== endValue[start]) {
8423 break;
8424 }
8425 }
8426
8427 var minEnd = startLength - start;
8428
8429 for (end = 1; end <= minEnd; end++) {
8430 if (startValue[startLength - end] !== endValue[endLength - end]) {
8431 break;
8432 }
8433 }
8434
8435 var sliceTail = end > 1 ? 1 - end : undefined;
8436 fallbackText = endValue.slice(start, sliceTail);
8437 return fallbackText;
8438 }
8439 function getText() {
8440 if ('value' in root) {
8441 return root.value;
8442 }
8443
8444 return root.textContent;
8445 }
8446
8447 var EVENT_POOL_SIZE = 10;
8448 /**
8449 * @interface Event
8450 * @see http://www.w3.org/TR/DOM-Level-3-Events/
8451 */
8452
8453 var EventInterface = {
8454 type: null,
8455 target: null,
8456 // currentTarget is set when dispatching; no use in copying it here
8457 currentTarget: function () {
8458 return null;
8459 },
8460 eventPhase: null,
8461 bubbles: null,
8462 cancelable: null,
8463 timeStamp: function (event) {
8464 return event.timeStamp || Date.now();
8465 },
8466 defaultPrevented: null,
8467 isTrusted: null
8468 };
8469
8470 function functionThatReturnsTrue() {
8471 return true;
8472 }
8473
8474 function functionThatReturnsFalse() {
8475 return false;
8476 }
8477 /**
8478 * Synthetic events are dispatched by event plugins, typically in response to a
8479 * top-level event delegation handler.
8480 *
8481 * These systems should generally use pooling to reduce the frequency of garbage
8482 * collection. The system should check `isPersistent` to determine whether the
8483 * event should be released into the pool after being dispatched. Users that
8484 * need a persisted event should invoke `persist`.
8485 *
8486 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
8487 * normalizing browser quirks. Subclasses do not necessarily have to implement a
8488 * DOM interface; custom application-specific events can also subclass this.
8489 *
8490 * @param {object} dispatchConfig Configuration used to dispatch this event.
8491 * @param {*} targetInst Marker identifying the event target.
8492 * @param {object} nativeEvent Native browser event.
8493 * @param {DOMEventTarget} nativeEventTarget Target node.
8494 */
8495
8496
8497 function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
8498 {
8499 // these have a getter/setter for warnings
8500 delete this.nativeEvent;
8501 delete this.preventDefault;
8502 delete this.stopPropagation;
8503 delete this.isDefaultPrevented;
8504 delete this.isPropagationStopped;
8505 }
8506
8507 this.dispatchConfig = dispatchConfig;
8508 this._targetInst = targetInst;
8509 this.nativeEvent = nativeEvent;
8510 var Interface = this.constructor.Interface;
8511
8512 for (var propName in Interface) {
8513 if (!Interface.hasOwnProperty(propName)) {
8514 continue;
8515 }
8516
8517 {
8518 delete this[propName]; // this has a getter/setter for warnings
8519 }
8520
8521 var normalize = Interface[propName];
8522
8523 if (normalize) {
8524 this[propName] = normalize(nativeEvent);
8525 } else {
8526 if (propName === 'target') {
8527 this.target = nativeEventTarget;
8528 } else {
8529 this[propName] = nativeEvent[propName];
8530 }
8531 }
8532 }
8533
8534 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
8535
8536 if (defaultPrevented) {
8537 this.isDefaultPrevented = functionThatReturnsTrue;
8538 } else {
8539 this.isDefaultPrevented = functionThatReturnsFalse;
8540 }
8541
8542 this.isPropagationStopped = functionThatReturnsFalse;
8543 return this;
8544 }
8545
8546 _assign(SyntheticEvent.prototype, {
8547 preventDefault: function () {
8548 this.defaultPrevented = true;
8549 var event = this.nativeEvent;
8550
8551 if (!event) {
8552 return;
8553 }
8554
8555 if (event.preventDefault) {
8556 event.preventDefault();
8557 } else if (typeof event.returnValue !== 'unknown') {
8558 event.returnValue = false;
8559 }
8560
8561 this.isDefaultPrevented = functionThatReturnsTrue;
8562 },
8563 stopPropagation: function () {
8564 var event = this.nativeEvent;
8565
8566 if (!event) {
8567 return;
8568 }
8569
8570 if (event.stopPropagation) {
8571 event.stopPropagation();
8572 } else if (typeof event.cancelBubble !== 'unknown') {
8573 // The ChangeEventPlugin registers a "propertychange" event for
8574 // IE. This event does not support bubbling or cancelling, and
8575 // any references to cancelBubble throw "Member not found". A
8576 // typeof check of "unknown" circumvents this issue (and is also
8577 // IE specific).
8578 event.cancelBubble = true;
8579 }
8580
8581 this.isPropagationStopped = functionThatReturnsTrue;
8582 },
8583
8584 /**
8585 * We release all dispatched `SyntheticEvent`s after each event loop, adding
8586 * them back into the pool. This allows a way to hold onto a reference that
8587 * won't be added back into the pool.
8588 */
8589 persist: function () {
8590 this.isPersistent = functionThatReturnsTrue;
8591 },
8592
8593 /**
8594 * Checks if this event should be released back into the pool.
8595 *
8596 * @return {boolean} True if this should not be released, false otherwise.
8597 */
8598 isPersistent: functionThatReturnsFalse,
8599
8600 /**
8601 * `PooledClass` looks for `destructor` on each instance it releases.
8602 */
8603 destructor: function () {
8604 var Interface = this.constructor.Interface;
8605
8606 for (var propName in Interface) {
8607 {
8608 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
8609 }
8610 }
8611
8612 this.dispatchConfig = null;
8613 this._targetInst = null;
8614 this.nativeEvent = null;
8615 this.isDefaultPrevented = functionThatReturnsFalse;
8616 this.isPropagationStopped = functionThatReturnsFalse;
8617 this._dispatchListeners = null;
8618 this._dispatchInstances = null;
8619
8620 {
8621 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
8622 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
8623 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
8624 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
8625 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
8626 }
8627 }
8628 });
8629
8630 SyntheticEvent.Interface = EventInterface;
8631 /**
8632 * Helper to reduce boilerplate when creating subclasses.
8633 */
8634
8635 SyntheticEvent.extend = function (Interface) {
8636 var Super = this;
8637
8638 var E = function () {};
8639
8640 E.prototype = Super.prototype;
8641 var prototype = new E();
8642
8643 function Class() {
8644 return Super.apply(this, arguments);
8645 }
8646
8647 _assign(prototype, Class.prototype);
8648
8649 Class.prototype = prototype;
8650 Class.prototype.constructor = Class;
8651 Class.Interface = _assign({}, Super.Interface, Interface);
8652 Class.extend = Super.extend;
8653 addEventPoolingTo(Class);
8654 return Class;
8655 };
8656
8657 addEventPoolingTo(SyntheticEvent);
8658 /**
8659 * Helper to nullify syntheticEvent instance properties when destructing
8660 *
8661 * @param {String} propName
8662 * @param {?object} getVal
8663 * @return {object} defineProperty object
8664 */
8665
8666 function getPooledWarningPropertyDefinition(propName, getVal) {
8667 var isFunction = typeof getVal === 'function';
8668 return {
8669 configurable: true,
8670 set: set,
8671 get: get
8672 };
8673
8674 function set(val) {
8675 var action = isFunction ? 'setting the method' : 'setting the property';
8676 warn(action, 'This is effectively a no-op');
8677 return val;
8678 }
8679
8680 function get() {
8681 var action = isFunction ? 'accessing the method' : 'accessing the property';
8682 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
8683 warn(action, result);
8684 return getVal;
8685 }
8686
8687 function warn(action, result) {
8688 {
8689 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);
8690 }
8691 }
8692 }
8693
8694 function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
8695 var EventConstructor = this;
8696
8697 if (EventConstructor.eventPool.length) {
8698 var instance = EventConstructor.eventPool.pop();
8699 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
8700 return instance;
8701 }
8702
8703 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
8704 }
8705
8706 function releasePooledEvent(event) {
8707 var EventConstructor = this;
8708
8709 if (!(event instanceof EventConstructor)) {
8710 {
8711 throw Error( "Trying to release an event instance into a pool of a different type." );
8712 }
8713 }
8714
8715 event.destructor();
8716
8717 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
8718 EventConstructor.eventPool.push(event);
8719 }
8720 }
8721
8722 function addEventPoolingTo(EventConstructor) {
8723 EventConstructor.eventPool = [];
8724 EventConstructor.getPooled = getPooledEvent;
8725 EventConstructor.release = releasePooledEvent;
8726 }
8727
8728 /**
8729 * @interface Event
8730 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
8731 */
8732
8733 var SyntheticCompositionEvent = SyntheticEvent.extend({
8734 data: null
8735 });
8736
8737 /**
8738 * @interface Event
8739 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
8740 * /#events-inputevents
8741 */
8742
8743 var SyntheticInputEvent = SyntheticEvent.extend({
8744 data: null
8745 });
8746
8747 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
8748
8749 var START_KEYCODE = 229;
8750 var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
8751 var documentMode = null;
8752
8753 if (canUseDOM && 'documentMode' in document) {
8754 documentMode = document.documentMode;
8755 } // Webkit offers a very useful `textInput` event that can be used to
8756 // directly represent `beforeInput`. The IE `textinput` event is not as
8757 // useful, so we don't use it.
8758
8759
8760 var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
8761 // by the native compositionend event may be incorrect. Japanese ideographic
8762 // spaces, for instance (\u3000) are not recorded correctly.
8763
8764 var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
8765 var SPACEBAR_CODE = 32;
8766 var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); // Events and their corresponding property names.
8767
8768 var eventTypes = {
8769 beforeInput: {
8770 phasedRegistrationNames: {
8771 bubbled: 'onBeforeInput',
8772 captured: 'onBeforeInputCapture'
8773 },
8774 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
8775 },
8776 compositionEnd: {
8777 phasedRegistrationNames: {
8778 bubbled: 'onCompositionEnd',
8779 captured: 'onCompositionEndCapture'
8780 },
8781 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8782 },
8783 compositionStart: {
8784 phasedRegistrationNames: {
8785 bubbled: 'onCompositionStart',
8786 captured: 'onCompositionStartCapture'
8787 },
8788 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8789 },
8790 compositionUpdate: {
8791 phasedRegistrationNames: {
8792 bubbled: 'onCompositionUpdate',
8793 captured: 'onCompositionUpdateCapture'
8794 },
8795 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
8796 }
8797 }; // Track whether we've ever handled a keypress on the space key.
8798
8799 var hasSpaceKeypress = false;
8800 /**
8801 * Return whether a native keypress event is assumed to be a command.
8802 * This is required because Firefox fires `keypress` events for key commands
8803 * (cut, copy, select-all, etc.) even though no character is inserted.
8804 */
8805
8806 function isKeypressCommand(nativeEvent) {
8807 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
8808 !(nativeEvent.ctrlKey && nativeEvent.altKey);
8809 }
8810 /**
8811 * Translate native top level events into event types.
8812 *
8813 * @param {string} topLevelType
8814 * @return {object}
8815 */
8816
8817
8818 function getCompositionEventType(topLevelType) {
8819 switch (topLevelType) {
8820 case TOP_COMPOSITION_START:
8821 return eventTypes.compositionStart;
8822
8823 case TOP_COMPOSITION_END:
8824 return eventTypes.compositionEnd;
8825
8826 case TOP_COMPOSITION_UPDATE:
8827 return eventTypes.compositionUpdate;
8828 }
8829 }
8830 /**
8831 * Does our fallback best-guess model think this event signifies that
8832 * composition has begun?
8833 *
8834 * @param {string} topLevelType
8835 * @param {object} nativeEvent
8836 * @return {boolean}
8837 */
8838
8839
8840 function isFallbackCompositionStart(topLevelType, nativeEvent) {
8841 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
8842 }
8843 /**
8844 * Does our fallback mode think that this event is the end of composition?
8845 *
8846 * @param {string} topLevelType
8847 * @param {object} nativeEvent
8848 * @return {boolean}
8849 */
8850
8851
8852 function isFallbackCompositionEnd(topLevelType, nativeEvent) {
8853 switch (topLevelType) {
8854 case TOP_KEY_UP:
8855 // Command keys insert or clear IME input.
8856 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
8857
8858 case TOP_KEY_DOWN:
8859 // Expect IME keyCode on each keydown. If we get any other
8860 // code we must have exited earlier.
8861 return nativeEvent.keyCode !== START_KEYCODE;
8862
8863 case TOP_KEY_PRESS:
8864 case TOP_MOUSE_DOWN:
8865 case TOP_BLUR:
8866 // Events are not possible without cancelling IME.
8867 return true;
8868
8869 default:
8870 return false;
8871 }
8872 }
8873 /**
8874 * Google Input Tools provides composition data via a CustomEvent,
8875 * with the `data` property populated in the `detail` object. If this
8876 * is available on the event object, use it. If not, this is a plain
8877 * composition event and we have nothing special to extract.
8878 *
8879 * @param {object} nativeEvent
8880 * @return {?string}
8881 */
8882
8883
8884 function getDataFromCustomEvent(nativeEvent) {
8885 var detail = nativeEvent.detail;
8886
8887 if (typeof detail === 'object' && 'data' in detail) {
8888 return detail.data;
8889 }
8890
8891 return null;
8892 }
8893 /**
8894 * Check if a composition event was triggered by Korean IME.
8895 * Our fallback mode does not work well with IE's Korean IME,
8896 * so just use native composition events when Korean IME is used.
8897 * Although CompositionEvent.locale property is deprecated,
8898 * it is available in IE, where our fallback mode is enabled.
8899 *
8900 * @param {object} nativeEvent
8901 * @return {boolean}
8902 */
8903
8904
8905 function isUsingKoreanIME(nativeEvent) {
8906 return nativeEvent.locale === 'ko';
8907 } // Track the current IME composition status, if any.
8908
8909
8910 var isComposing = false;
8911 /**
8912 * @return {?object} A SyntheticCompositionEvent.
8913 */
8914
8915 function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
8916 var eventType;
8917 var fallbackData;
8918
8919 if (canUseCompositionEvent) {
8920 eventType = getCompositionEventType(topLevelType);
8921 } else if (!isComposing) {
8922 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
8923 eventType = eventTypes.compositionStart;
8924 }
8925 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
8926 eventType = eventTypes.compositionEnd;
8927 }
8928
8929 if (!eventType) {
8930 return null;
8931 }
8932
8933 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
8934 // The current composition is stored statically and must not be
8935 // overwritten while composition continues.
8936 if (!isComposing && eventType === eventTypes.compositionStart) {
8937 isComposing = initialize(nativeEventTarget);
8938 } else if (eventType === eventTypes.compositionEnd) {
8939 if (isComposing) {
8940 fallbackData = getData();
8941 }
8942 }
8943 }
8944
8945 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
8946
8947 if (fallbackData) {
8948 // Inject data generated from fallback path into the synthetic event.
8949 // This matches the property of native CompositionEventInterface.
8950 event.data = fallbackData;
8951 } else {
8952 var customData = getDataFromCustomEvent(nativeEvent);
8953
8954 if (customData !== null) {
8955 event.data = customData;
8956 }
8957 }
8958
8959 accumulateTwoPhaseDispatches(event);
8960 return event;
8961 }
8962 /**
8963 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
8964 * @param {object} nativeEvent Native browser event.
8965 * @return {?string} The string corresponding to this `beforeInput` event.
8966 */
8967
8968
8969 function getNativeBeforeInputChars(topLevelType, nativeEvent) {
8970 switch (topLevelType) {
8971 case TOP_COMPOSITION_END:
8972 return getDataFromCustomEvent(nativeEvent);
8973
8974 case TOP_KEY_PRESS:
8975 /**
8976 * If native `textInput` events are available, our goal is to make
8977 * use of them. However, there is a special case: the spacebar key.
8978 * In Webkit, preventing default on a spacebar `textInput` event
8979 * cancels character insertion, but it *also* causes the browser
8980 * to fall back to its default spacebar behavior of scrolling the
8981 * page.
8982 *
8983 * Tracking at:
8984 * https://code.google.com/p/chromium/issues/detail?id=355103
8985 *
8986 * To avoid this issue, use the keypress event as if no `textInput`
8987 * event is available.
8988 */
8989 var which = nativeEvent.which;
8990
8991 if (which !== SPACEBAR_CODE) {
8992 return null;
8993 }
8994
8995 hasSpaceKeypress = true;
8996 return SPACEBAR_CHAR;
8997
8998 case TOP_TEXT_INPUT:
8999 // Record the characters to be added to the DOM.
9000 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
9001 // it at the keypress level and bail immediately. Android Chrome
9002 // doesn't give us keycodes, so we need to ignore it.
9003
9004 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
9005 return null;
9006 }
9007
9008 return chars;
9009
9010 default:
9011 // For other native event types, do nothing.
9012 return null;
9013 }
9014 }
9015 /**
9016 * For browsers that do not provide the `textInput` event, extract the
9017 * appropriate string to use for SyntheticInputEvent.
9018 *
9019 * @param {number} topLevelType Number from `TopLevelEventTypes`.
9020 * @param {object} nativeEvent Native browser event.
9021 * @return {?string} The fallback string for this `beforeInput` event.
9022 */
9023
9024
9025 function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
9026 // If we are currently composing (IME) and using a fallback to do so,
9027 // try to extract the composed characters from the fallback object.
9028 // If composition event is available, we extract a string only at
9029 // compositionevent, otherwise extract it at fallback events.
9030 if (isComposing) {
9031 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
9032 var chars = getData();
9033 reset();
9034 isComposing = false;
9035 return chars;
9036 }
9037
9038 return null;
9039 }
9040
9041 switch (topLevelType) {
9042 case TOP_PASTE:
9043 // If a paste event occurs after a keypress, throw out the input
9044 // chars. Paste events should not lead to BeforeInput events.
9045 return null;
9046
9047 case TOP_KEY_PRESS:
9048 /**
9049 * As of v27, Firefox may fire keypress events even when no character
9050 * will be inserted. A few possibilities:
9051 *
9052 * - `which` is `0`. Arrow keys, Esc key, etc.
9053 *
9054 * - `which` is the pressed key code, but no char is available.
9055 * Ex: 'AltGr + d` in Polish. There is no modified character for
9056 * this key combination and no character is inserted into the
9057 * document, but FF fires the keypress for char code `100` anyway.
9058 * No `input` event will occur.
9059 *
9060 * - `which` is the pressed key code, but a command combination is
9061 * being used. Ex: `Cmd+C`. No character is inserted, and no
9062 * `input` event will occur.
9063 */
9064 if (!isKeypressCommand(nativeEvent)) {
9065 // IE fires the `keypress` event when a user types an emoji via
9066 // Touch keyboard of Windows. In such a case, the `char` property
9067 // holds an emoji character like `\uD83D\uDE0A`. Because its length
9068 // is 2, the property `which` does not represent an emoji correctly.
9069 // In such a case, we directly return the `char` property instead of
9070 // using `which`.
9071 if (nativeEvent.char && nativeEvent.char.length > 1) {
9072 return nativeEvent.char;
9073 } else if (nativeEvent.which) {
9074 return String.fromCharCode(nativeEvent.which);
9075 }
9076 }
9077
9078 return null;
9079
9080 case TOP_COMPOSITION_END:
9081 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
9082
9083 default:
9084 return null;
9085 }
9086 }
9087 /**
9088 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
9089 * `textInput` or fallback behavior.
9090 *
9091 * @return {?object} A SyntheticInputEvent.
9092 */
9093
9094
9095 function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
9096 var chars;
9097
9098 if (canUseTextInputEvent) {
9099 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
9100 } else {
9101 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
9102 } // If no characters are being inserted, no BeforeInput event should
9103 // be fired.
9104
9105
9106 if (!chars) {
9107 return null;
9108 }
9109
9110 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
9111 event.data = chars;
9112 accumulateTwoPhaseDispatches(event);
9113 return event;
9114 }
9115 /**
9116 * Create an `onBeforeInput` event to match
9117 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
9118 *
9119 * This event plugin is based on the native `textInput` event
9120 * available in Chrome, Safari, Opera, and IE. This event fires after
9121 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
9122 *
9123 * `beforeInput` is spec'd but not implemented in any browsers, and
9124 * the `input` event does not provide any useful information about what has
9125 * actually been added, contrary to the spec. Thus, `textInput` is the best
9126 * available event to identify the characters that have actually been inserted
9127 * into the target node.
9128 *
9129 * This plugin is also responsible for emitting `composition` events, thus
9130 * allowing us to share composition fallback code for both `beforeInput` and
9131 * `composition` event types.
9132 */
9133
9134
9135 var BeforeInputEventPlugin = {
9136 eventTypes: eventTypes,
9137 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9138 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
9139 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
9140
9141 if (composition === null) {
9142 return beforeInput;
9143 }
9144
9145 if (beforeInput === null) {
9146 return composition;
9147 }
9148
9149 return [composition, beforeInput];
9150 }
9151 };
9152
9153 /**
9154 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
9155 */
9156 var supportedInputTypes = {
9157 color: true,
9158 date: true,
9159 datetime: true,
9160 'datetime-local': true,
9161 email: true,
9162 month: true,
9163 number: true,
9164 password: true,
9165 range: true,
9166 search: true,
9167 tel: true,
9168 text: true,
9169 time: true,
9170 url: true,
9171 week: true
9172 };
9173
9174 function isTextInputElement(elem) {
9175 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
9176
9177 if (nodeName === 'input') {
9178 return !!supportedInputTypes[elem.type];
9179 }
9180
9181 if (nodeName === 'textarea') {
9182 return true;
9183 }
9184
9185 return false;
9186 }
9187
9188 var eventTypes$1 = {
9189 change: {
9190 phasedRegistrationNames: {
9191 bubbled: 'onChange',
9192 captured: 'onChangeCapture'
9193 },
9194 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
9195 }
9196 };
9197
9198 function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
9199 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
9200 event.type = 'change'; // Flag this event loop as needing state restore.
9201
9202 enqueueStateRestore(target);
9203 accumulateTwoPhaseDispatches(event);
9204 return event;
9205 }
9206 /**
9207 * For IE shims
9208 */
9209
9210
9211 var activeElement = null;
9212 var activeElementInst = null;
9213 /**
9214 * SECTION: handle `change` event
9215 */
9216
9217 function shouldUseChangeEvent(elem) {
9218 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
9219 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
9220 }
9221
9222 function manualDispatchChangeEvent(nativeEvent) {
9223 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
9224 // other events and have it go through ReactBrowserEventEmitter. Since it
9225 // doesn't, we manually listen for the events and so we have to enqueue and
9226 // process the abstract event manually.
9227 //
9228 // Batching is necessary here in order to ensure that all event handlers run
9229 // before the next rerender (including event handlers attached to ancestor
9230 // elements instead of directly on the input). Without this, controlled
9231 // components don't work properly in conjunction with event bubbling because
9232 // the component is rerendered and the value reverted before all the event
9233 // handlers can run. See https://github.com/facebook/react/issues/708.
9234
9235 batchedUpdates(runEventInBatch, event);
9236 }
9237
9238 function runEventInBatch(event) {
9239 runEventsInBatch(event);
9240 }
9241
9242 function getInstIfValueChanged(targetInst) {
9243 var targetNode = getNodeFromInstance$1(targetInst);
9244
9245 if (updateValueIfChanged(targetNode)) {
9246 return targetInst;
9247 }
9248 }
9249
9250 function getTargetInstForChangeEvent(topLevelType, targetInst) {
9251 if (topLevelType === TOP_CHANGE) {
9252 return targetInst;
9253 }
9254 }
9255 /**
9256 * SECTION: handle `input` event
9257 */
9258
9259
9260 var isInputEventSupported = false;
9261
9262 if (canUseDOM) {
9263 // IE9 claims to support the input event but fails to trigger it when
9264 // deleting text, so we ignore its input events.
9265 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
9266 }
9267 /**
9268 * (For IE <=9) Starts tracking propertychange events on the passed-in element
9269 * and override the value property so that we can distinguish user events from
9270 * value changes in JS.
9271 */
9272
9273
9274 function startWatchingForValueChange(target, targetInst) {
9275 activeElement = target;
9276 activeElementInst = targetInst;
9277 activeElement.attachEvent('onpropertychange', handlePropertyChange);
9278 }
9279 /**
9280 * (For IE <=9) Removes the event listeners from the currently-tracked element,
9281 * if any exists.
9282 */
9283
9284
9285 function stopWatchingForValueChange() {
9286 if (!activeElement) {
9287 return;
9288 }
9289
9290 activeElement.detachEvent('onpropertychange', handlePropertyChange);
9291 activeElement = null;
9292 activeElementInst = null;
9293 }
9294 /**
9295 * (For IE <=9) Handles a propertychange event, sending a `change` event if
9296 * the value of the active element has changed.
9297 */
9298
9299
9300 function handlePropertyChange(nativeEvent) {
9301 if (nativeEvent.propertyName !== 'value') {
9302 return;
9303 }
9304
9305 if (getInstIfValueChanged(activeElementInst)) {
9306 manualDispatchChangeEvent(nativeEvent);
9307 }
9308 }
9309
9310 function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
9311 if (topLevelType === TOP_FOCUS) {
9312 // In IE9, propertychange fires for most input events but is buggy and
9313 // doesn't fire when text is deleted, but conveniently, selectionchange
9314 // appears to fire in all of the remaining cases so we catch those and
9315 // forward the event if the value has changed
9316 // In either case, we don't want to call the event handler if the value
9317 // is changed from JS so we redefine a setter for `.value` that updates
9318 // our activeElementValue variable, allowing us to ignore those changes
9319 //
9320 // stopWatching() should be a noop here but we call it just in case we
9321 // missed a blur event somehow.
9322 stopWatchingForValueChange();
9323 startWatchingForValueChange(target, targetInst);
9324 } else if (topLevelType === TOP_BLUR) {
9325 stopWatchingForValueChange();
9326 }
9327 } // For IE8 and IE9.
9328
9329
9330 function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
9331 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
9332 // On the selectionchange event, the target is just document which isn't
9333 // helpful for us so just check activeElement instead.
9334 //
9335 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
9336 // propertychange on the first input event after setting `value` from a
9337 // script and fires only keydown, keypress, keyup. Catching keyup usually
9338 // gets it and catching keydown lets us fire an event for the first
9339 // keystroke if user does a key repeat (it'll be a little delayed: right
9340 // before the second keystroke). Other input methods (e.g., paste) seem to
9341 // fire selectionchange normally.
9342 return getInstIfValueChanged(activeElementInst);
9343 }
9344 }
9345 /**
9346 * SECTION: handle `click` event
9347 */
9348
9349
9350 function shouldUseClickEvent(elem) {
9351 // Use the `click` event to detect changes to checkbox and radio inputs.
9352 // This approach works across all browsers, whereas `change` does not fire
9353 // until `blur` in IE8.
9354 var nodeName = elem.nodeName;
9355 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
9356 }
9357
9358 function getTargetInstForClickEvent(topLevelType, targetInst) {
9359 if (topLevelType === TOP_CLICK) {
9360 return getInstIfValueChanged(targetInst);
9361 }
9362 }
9363
9364 function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
9365 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
9366 return getInstIfValueChanged(targetInst);
9367 }
9368 }
9369
9370 function handleControlledInputBlur(node) {
9371 var state = node._wrapperState;
9372
9373 if (!state || !state.controlled || node.type !== 'number') {
9374 return;
9375 }
9376
9377 {
9378 // If controlled, assign the value attribute to the current value on blur
9379 setDefaultValue(node, 'number', node.value);
9380 }
9381 }
9382 /**
9383 * This plugin creates an `onChange` event that normalizes change events
9384 * across form elements. This event fires at a time when it's possible to
9385 * change the element's value without seeing a flicker.
9386 *
9387 * Supported elements are:
9388 * - input (see `isTextInputElement`)
9389 * - textarea
9390 * - select
9391 */
9392
9393
9394 var ChangeEventPlugin = {
9395 eventTypes: eventTypes$1,
9396 _isInputEventSupported: isInputEventSupported,
9397 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9398 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
9399 var getTargetInstFunc, handleEventFunc;
9400
9401 if (shouldUseChangeEvent(targetNode)) {
9402 getTargetInstFunc = getTargetInstForChangeEvent;
9403 } else if (isTextInputElement(targetNode)) {
9404 if (isInputEventSupported) {
9405 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
9406 } else {
9407 getTargetInstFunc = getTargetInstForInputEventPolyfill;
9408 handleEventFunc = handleEventsForInputEventPolyfill;
9409 }
9410 } else if (shouldUseClickEvent(targetNode)) {
9411 getTargetInstFunc = getTargetInstForClickEvent;
9412 }
9413
9414 if (getTargetInstFunc) {
9415 var inst = getTargetInstFunc(topLevelType, targetInst);
9416
9417 if (inst) {
9418 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
9419 return event;
9420 }
9421 }
9422
9423 if (handleEventFunc) {
9424 handleEventFunc(topLevelType, targetNode, targetInst);
9425 } // When blurring, set the value attribute for number inputs
9426
9427
9428 if (topLevelType === TOP_BLUR) {
9429 handleControlledInputBlur(targetNode);
9430 }
9431 }
9432 };
9433
9434 var SyntheticUIEvent = SyntheticEvent.extend({
9435 view: null,
9436 detail: null
9437 });
9438
9439 /**
9440 * Translation from modifier key to the associated property in the event.
9441 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
9442 */
9443 var modifierKeyToProp = {
9444 Alt: 'altKey',
9445 Control: 'ctrlKey',
9446 Meta: 'metaKey',
9447 Shift: 'shiftKey'
9448 }; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
9449 // getModifierState. If getModifierState is not supported, we map it to a set of
9450 // modifier keys exposed by the event. In this case, Lock-keys are not supported.
9451
9452 function modifierStateGetter(keyArg) {
9453 var syntheticEvent = this;
9454 var nativeEvent = syntheticEvent.nativeEvent;
9455
9456 if (nativeEvent.getModifierState) {
9457 return nativeEvent.getModifierState(keyArg);
9458 }
9459
9460 var keyProp = modifierKeyToProp[keyArg];
9461 return keyProp ? !!nativeEvent[keyProp] : false;
9462 }
9463
9464 function getEventModifierState(nativeEvent) {
9465 return modifierStateGetter;
9466 }
9467
9468 var previousScreenX = 0;
9469 var previousScreenY = 0; // Use flags to signal movementX/Y has already been set
9470
9471 var isMovementXSet = false;
9472 var isMovementYSet = false;
9473 /**
9474 * @interface MouseEvent
9475 * @see http://www.w3.org/TR/DOM-Level-3-Events/
9476 */
9477
9478 var SyntheticMouseEvent = SyntheticUIEvent.extend({
9479 screenX: null,
9480 screenY: null,
9481 clientX: null,
9482 clientY: null,
9483 pageX: null,
9484 pageY: null,
9485 ctrlKey: null,
9486 shiftKey: null,
9487 altKey: null,
9488 metaKey: null,
9489 getModifierState: getEventModifierState,
9490 button: null,
9491 buttons: null,
9492 relatedTarget: function (event) {
9493 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
9494 },
9495 movementX: function (event) {
9496 if ('movementX' in event) {
9497 return event.movementX;
9498 }
9499
9500 var screenX = previousScreenX;
9501 previousScreenX = event.screenX;
9502
9503 if (!isMovementXSet) {
9504 isMovementXSet = true;
9505 return 0;
9506 }
9507
9508 return event.type === 'mousemove' ? event.screenX - screenX : 0;
9509 },
9510 movementY: function (event) {
9511 if ('movementY' in event) {
9512 return event.movementY;
9513 }
9514
9515 var screenY = previousScreenY;
9516 previousScreenY = event.screenY;
9517
9518 if (!isMovementYSet) {
9519 isMovementYSet = true;
9520 return 0;
9521 }
9522
9523 return event.type === 'mousemove' ? event.screenY - screenY : 0;
9524 }
9525 });
9526
9527 /**
9528 * @interface PointerEvent
9529 * @see http://www.w3.org/TR/pointerevents/
9530 */
9531
9532 var SyntheticPointerEvent = SyntheticMouseEvent.extend({
9533 pointerId: null,
9534 width: null,
9535 height: null,
9536 pressure: null,
9537 tangentialPressure: null,
9538 tiltX: null,
9539 tiltY: null,
9540 twist: null,
9541 pointerType: null,
9542 isPrimary: null
9543 });
9544
9545 var eventTypes$2 = {
9546 mouseEnter: {
9547 registrationName: 'onMouseEnter',
9548 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
9549 },
9550 mouseLeave: {
9551 registrationName: 'onMouseLeave',
9552 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
9553 },
9554 pointerEnter: {
9555 registrationName: 'onPointerEnter',
9556 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
9557 },
9558 pointerLeave: {
9559 registrationName: 'onPointerLeave',
9560 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
9561 }
9562 };
9563 var EnterLeaveEventPlugin = {
9564 eventTypes: eventTypes$2,
9565
9566 /**
9567 * For almost every interaction we care about, there will be both a top-level
9568 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
9569 * we do not extract duplicate events. However, moving the mouse into the
9570 * browser from outside will not fire a `mouseout` event. In this case, we use
9571 * the `mouseover` top-level event.
9572 */
9573 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
9574 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
9575 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
9576
9577 if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0 && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
9578 // If this is an over event with a target, then we've already dispatched
9579 // the event in the out event of the other target. If this is replayed,
9580 // then it's because we couldn't dispatch against this target previously
9581 // so we have to do it now instead.
9582 return null;
9583 }
9584
9585 if (!isOutEvent && !isOverEvent) {
9586 // Must not be a mouse or pointer in or out - ignoring.
9587 return null;
9588 }
9589
9590 var win;
9591
9592 if (nativeEventTarget.window === nativeEventTarget) {
9593 // `nativeEventTarget` is probably a window object.
9594 win = nativeEventTarget;
9595 } else {
9596 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
9597 var doc = nativeEventTarget.ownerDocument;
9598
9599 if (doc) {
9600 win = doc.defaultView || doc.parentWindow;
9601 } else {
9602 win = window;
9603 }
9604 }
9605
9606 var from;
9607 var to;
9608
9609 if (isOutEvent) {
9610 from = targetInst;
9611 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
9612 to = related ? getClosestInstanceFromNode(related) : null;
9613
9614 if (to !== null) {
9615 var nearestMounted = getNearestMountedFiber(to);
9616
9617 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
9618 to = null;
9619 }
9620 }
9621 } else {
9622 // Moving to a node from outside the window.
9623 from = null;
9624 to = targetInst;
9625 }
9626
9627 if (from === to) {
9628 // Nothing pertains to our managed components.
9629 return null;
9630 }
9631
9632 var eventInterface, leaveEventType, enterEventType, eventTypePrefix;
9633
9634 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
9635 eventInterface = SyntheticMouseEvent;
9636 leaveEventType = eventTypes$2.mouseLeave;
9637 enterEventType = eventTypes$2.mouseEnter;
9638 eventTypePrefix = 'mouse';
9639 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
9640 eventInterface = SyntheticPointerEvent;
9641 leaveEventType = eventTypes$2.pointerLeave;
9642 enterEventType = eventTypes$2.pointerEnter;
9643 eventTypePrefix = 'pointer';
9644 }
9645
9646 var fromNode = from == null ? win : getNodeFromInstance$1(from);
9647 var toNode = to == null ? win : getNodeFromInstance$1(to);
9648 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
9649 leave.type = eventTypePrefix + 'leave';
9650 leave.target = fromNode;
9651 leave.relatedTarget = toNode;
9652 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
9653 enter.type = eventTypePrefix + 'enter';
9654 enter.target = toNode;
9655 enter.relatedTarget = fromNode;
9656 accumulateEnterLeaveDispatches(leave, enter, from, to); // If we are not processing the first ancestor, then we
9657 // should not process the same nativeEvent again, as we
9658 // will have already processed it in the first ancestor.
9659
9660 if ((eventSystemFlags & IS_FIRST_ANCESTOR) === 0) {
9661 return [leave];
9662 }
9663
9664 return [leave, enter];
9665 }
9666 };
9667
9668 /**
9669 * inlined Object.is polyfill to avoid requiring consumers ship their own
9670 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
9671 */
9672 function is(x, y) {
9673 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
9674 ;
9675 }
9676
9677 var objectIs = typeof Object.is === 'function' ? Object.is : is;
9678
9679 var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
9680 /**
9681 * Performs equality by iterating through keys on an object and returning false
9682 * when any key has values which are not strictly equal between the arguments.
9683 * Returns true when the values of all keys are strictly equal.
9684 */
9685
9686 function shallowEqual(objA, objB) {
9687 if (objectIs(objA, objB)) {
9688 return true;
9689 }
9690
9691 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
9692 return false;
9693 }
9694
9695 var keysA = Object.keys(objA);
9696 var keysB = Object.keys(objB);
9697
9698 if (keysA.length !== keysB.length) {
9699 return false;
9700 } // Test for A's keys different from B.
9701
9702
9703 for (var i = 0; i < keysA.length; i++) {
9704 if (!hasOwnProperty$2.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
9705 return false;
9706 }
9707 }
9708
9709 return true;
9710 }
9711
9712 var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
9713 var eventTypes$3 = {
9714 select: {
9715 phasedRegistrationNames: {
9716 bubbled: 'onSelect',
9717 captured: 'onSelectCapture'
9718 },
9719 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]
9720 }
9721 };
9722 var activeElement$1 = null;
9723 var activeElementInst$1 = null;
9724 var lastSelection = null;
9725 var mouseDown = false;
9726 /**
9727 * Get an object which is a unique representation of the current selection.
9728 *
9729 * The return value will not be consistent across nodes or browsers, but
9730 * two identical selections on the same node will return identical objects.
9731 *
9732 * @param {DOMElement} node
9733 * @return {object}
9734 */
9735
9736 function getSelection$1(node) {
9737 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
9738 return {
9739 start: node.selectionStart,
9740 end: node.selectionEnd
9741 };
9742 } else {
9743 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
9744 var selection = win.getSelection();
9745 return {
9746 anchorNode: selection.anchorNode,
9747 anchorOffset: selection.anchorOffset,
9748 focusNode: selection.focusNode,
9749 focusOffset: selection.focusOffset
9750 };
9751 }
9752 }
9753 /**
9754 * Get document associated with the event target.
9755 *
9756 * @param {object} nativeEventTarget
9757 * @return {Document}
9758 */
9759
9760
9761 function getEventTargetDocument(eventTarget) {
9762 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
9763 }
9764 /**
9765 * Poll selection to see whether it's changed.
9766 *
9767 * @param {object} nativeEvent
9768 * @param {object} nativeEventTarget
9769 * @return {?SyntheticEvent}
9770 */
9771
9772
9773 function constructSelectEvent(nativeEvent, nativeEventTarget) {
9774 // Ensure we have the right element, and that the user is not dragging a
9775 // selection (this matches native `select` event behavior). In HTML5, select
9776 // fires only on input and textarea thus if there's no focused element we
9777 // won't dispatch.
9778 var doc = getEventTargetDocument(nativeEventTarget);
9779
9780 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
9781 return null;
9782 } // Only fire when selection has actually changed.
9783
9784
9785 var currentSelection = getSelection$1(activeElement$1);
9786
9787 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
9788 lastSelection = currentSelection;
9789 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
9790 syntheticEvent.type = 'select';
9791 syntheticEvent.target = activeElement$1;
9792 accumulateTwoPhaseDispatches(syntheticEvent);
9793 return syntheticEvent;
9794 }
9795
9796 return null;
9797 }
9798 /**
9799 * This plugin creates an `onSelect` event that normalizes select events
9800 * across form elements.
9801 *
9802 * Supported elements are:
9803 * - input (see `isTextInputElement`)
9804 * - textarea
9805 * - contentEditable
9806 *
9807 * This differs from native browser implementations in the following ways:
9808 * - Fires on contentEditable fields as well as inputs.
9809 * - Fires for collapsed selection.
9810 * - Fires after user input.
9811 */
9812
9813
9814 var SelectEventPlugin = {
9815 eventTypes: eventTypes$3,
9816 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, container) {
9817 var containerOrDoc = container || getEventTargetDocument(nativeEventTarget); // Track whether all listeners exists for this plugin. If none exist, we do
9818 // not extract events. See #3639.
9819
9820 if (!containerOrDoc || !isListeningToAllDependencies('onSelect', containerOrDoc)) {
9821 return null;
9822 }
9823
9824 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
9825
9826 switch (topLevelType) {
9827 // Track the input node that has focus.
9828 case TOP_FOCUS:
9829 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
9830 activeElement$1 = targetNode;
9831 activeElementInst$1 = targetInst;
9832 lastSelection = null;
9833 }
9834
9835 break;
9836
9837 case TOP_BLUR:
9838 activeElement$1 = null;
9839 activeElementInst$1 = null;
9840 lastSelection = null;
9841 break;
9842 // Don't fire the event while the user is dragging. This matches the
9843 // semantics of the native select event.
9844
9845 case TOP_MOUSE_DOWN:
9846 mouseDown = true;
9847 break;
9848
9849 case TOP_CONTEXT_MENU:
9850 case TOP_MOUSE_UP:
9851 case TOP_DRAG_END:
9852 mouseDown = false;
9853 return constructSelectEvent(nativeEvent, nativeEventTarget);
9854 // Chrome and IE fire non-standard event when selection is changed (and
9855 // sometimes when it hasn't). IE's event fires out of order with respect
9856 // to key and input events on deletion, so we discard it.
9857 //
9858 // Firefox doesn't support selectionchange, so check selection status
9859 // after each key entry. The selection changes after keydown and before
9860 // keyup, but we check on keydown as well in the case of holding down a
9861 // key, when multiple keydown events are fired but only one keyup is.
9862 // This is also our approach for IE handling, for the reason above.
9863
9864 case TOP_SELECTION_CHANGE:
9865 if (skipSelectionChangeEvent) {
9866 break;
9867 }
9868
9869 // falls through
9870
9871 case TOP_KEY_DOWN:
9872 case TOP_KEY_UP:
9873 return constructSelectEvent(nativeEvent, nativeEventTarget);
9874 }
9875
9876 return null;
9877 }
9878 };
9879
9880 /**
9881 * @interface Event
9882 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
9883 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
9884 */
9885
9886 var SyntheticAnimationEvent = SyntheticEvent.extend({
9887 animationName: null,
9888 elapsedTime: null,
9889 pseudoElement: null
9890 });
9891
9892 /**
9893 * @interface Event
9894 * @see http://www.w3.org/TR/clipboard-apis/
9895 */
9896
9897 var SyntheticClipboardEvent = SyntheticEvent.extend({
9898 clipboardData: function (event) {
9899 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
9900 }
9901 });
9902
9903 /**
9904 * @interface FocusEvent
9905 * @see http://www.w3.org/TR/DOM-Level-3-Events/
9906 */
9907
9908 var SyntheticFocusEvent = SyntheticUIEvent.extend({
9909 relatedTarget: null
9910 });
9911
9912 /**
9913 * `charCode` represents the actual "character code" and is safe to use with
9914 * `String.fromCharCode`. As such, only keys that correspond to printable
9915 * characters produce a valid `charCode`, the only exception to this is Enter.
9916 * The Tab-key is considered non-printable and does not have a `charCode`,
9917 * presumably because it does not produce a tab-character in browsers.
9918 *
9919 * @param {object} nativeEvent Native browser event.
9920 * @return {number} Normalized `charCode` property.
9921 */
9922 function getEventCharCode(nativeEvent) {
9923 var charCode;
9924 var keyCode = nativeEvent.keyCode;
9925
9926 if ('charCode' in nativeEvent) {
9927 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
9928
9929 if (charCode === 0 && keyCode === 13) {
9930 charCode = 13;
9931 }
9932 } else {
9933 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
9934 charCode = keyCode;
9935 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
9936 // report Enter as charCode 10 when ctrl is pressed.
9937
9938
9939 if (charCode === 10) {
9940 charCode = 13;
9941 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
9942 // Must not discard the (non-)printable Enter-key.
9943
9944
9945 if (charCode >= 32 || charCode === 13) {
9946 return charCode;
9947 }
9948
9949 return 0;
9950 }
9951
9952 /**
9953 * Normalization of deprecated HTML5 `key` values
9954 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
9955 */
9956
9957 var normalizeKey = {
9958 Esc: 'Escape',
9959 Spacebar: ' ',
9960 Left: 'ArrowLeft',
9961 Up: 'ArrowUp',
9962 Right: 'ArrowRight',
9963 Down: 'ArrowDown',
9964 Del: 'Delete',
9965 Win: 'OS',
9966 Menu: 'ContextMenu',
9967 Apps: 'ContextMenu',
9968 Scroll: 'ScrollLock',
9969 MozPrintableKey: 'Unidentified'
9970 };
9971 /**
9972 * Translation from legacy `keyCode` to HTML5 `key`
9973 * Only special keys supported, all others depend on keyboard layout or browser
9974 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
9975 */
9976
9977 var translateToKey = {
9978 '8': 'Backspace',
9979 '9': 'Tab',
9980 '12': 'Clear',
9981 '13': 'Enter',
9982 '16': 'Shift',
9983 '17': 'Control',
9984 '18': 'Alt',
9985 '19': 'Pause',
9986 '20': 'CapsLock',
9987 '27': 'Escape',
9988 '32': ' ',
9989 '33': 'PageUp',
9990 '34': 'PageDown',
9991 '35': 'End',
9992 '36': 'Home',
9993 '37': 'ArrowLeft',
9994 '38': 'ArrowUp',
9995 '39': 'ArrowRight',
9996 '40': 'ArrowDown',
9997 '45': 'Insert',
9998 '46': 'Delete',
9999 '112': 'F1',
10000 '113': 'F2',
10001 '114': 'F3',
10002 '115': 'F4',
10003 '116': 'F5',
10004 '117': 'F6',
10005 '118': 'F7',
10006 '119': 'F8',
10007 '120': 'F9',
10008 '121': 'F10',
10009 '122': 'F11',
10010 '123': 'F12',
10011 '144': 'NumLock',
10012 '145': 'ScrollLock',
10013 '224': 'Meta'
10014 };
10015 /**
10016 * @param {object} nativeEvent Native browser event.
10017 * @return {string} Normalized `key` property.
10018 */
10019
10020 function getEventKey(nativeEvent) {
10021 if (nativeEvent.key) {
10022 // Normalize inconsistent values reported by browsers due to
10023 // implementations of a working draft specification.
10024 // FireFox implements `key` but returns `MozPrintableKey` for all
10025 // printable characters (normalized to `Unidentified`), ignore it.
10026 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
10027
10028 if (key !== 'Unidentified') {
10029 return key;
10030 }
10031 } // Browser does not implement `key`, polyfill as much of it as we can.
10032
10033
10034 if (nativeEvent.type === 'keypress') {
10035 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
10036 // thus be captured by `keypress`, no other non-printable key should.
10037
10038 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
10039 }
10040
10041 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
10042 // While user keyboard layout determines the actual meaning of each
10043 // `keyCode` value, almost all function keys have a universal value.
10044 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
10045 }
10046
10047 return '';
10048 }
10049
10050 /**
10051 * @interface KeyboardEvent
10052 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10053 */
10054
10055 var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
10056 key: getEventKey,
10057 location: null,
10058 ctrlKey: null,
10059 shiftKey: null,
10060 altKey: null,
10061 metaKey: null,
10062 repeat: null,
10063 locale: null,
10064 getModifierState: getEventModifierState,
10065 // Legacy Interface
10066 charCode: function (event) {
10067 // `charCode` is the result of a KeyPress event and represents the value of
10068 // the actual printable character.
10069 // KeyPress is deprecated, but its replacement is not yet final and not
10070 // implemented in any major browser. Only KeyPress has charCode.
10071 if (event.type === 'keypress') {
10072 return getEventCharCode(event);
10073 }
10074
10075 return 0;
10076 },
10077 keyCode: function (event) {
10078 // `keyCode` is the result of a KeyDown/Up event and represents the value of
10079 // physical keyboard key.
10080 // The actual meaning of the value depends on the users' keyboard layout
10081 // which cannot be detected. Assuming that it is a US keyboard layout
10082 // provides a surprisingly accurate mapping for US and European users.
10083 // Due to this, it is left to the user to implement at this time.
10084 if (event.type === 'keydown' || event.type === 'keyup') {
10085 return event.keyCode;
10086 }
10087
10088 return 0;
10089 },
10090 which: function (event) {
10091 // `which` is an alias for either `keyCode` or `charCode` depending on the
10092 // type of the event.
10093 if (event.type === 'keypress') {
10094 return getEventCharCode(event);
10095 }
10096
10097 if (event.type === 'keydown' || event.type === 'keyup') {
10098 return event.keyCode;
10099 }
10100
10101 return 0;
10102 }
10103 });
10104
10105 /**
10106 * @interface DragEvent
10107 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10108 */
10109
10110 var SyntheticDragEvent = SyntheticMouseEvent.extend({
10111 dataTransfer: null
10112 });
10113
10114 /**
10115 * @interface TouchEvent
10116 * @see http://www.w3.org/TR/touch-events/
10117 */
10118
10119 var SyntheticTouchEvent = SyntheticUIEvent.extend({
10120 touches: null,
10121 targetTouches: null,
10122 changedTouches: null,
10123 altKey: null,
10124 metaKey: null,
10125 ctrlKey: null,
10126 shiftKey: null,
10127 getModifierState: getEventModifierState
10128 });
10129
10130 /**
10131 * @interface Event
10132 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
10133 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
10134 */
10135
10136 var SyntheticTransitionEvent = SyntheticEvent.extend({
10137 propertyName: null,
10138 elapsedTime: null,
10139 pseudoElement: null
10140 });
10141
10142 /**
10143 * @interface WheelEvent
10144 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10145 */
10146
10147 var SyntheticWheelEvent = SyntheticMouseEvent.extend({
10148 deltaX: function (event) {
10149 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
10150 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
10151 },
10152 deltaY: function (event) {
10153 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
10154 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
10155 'wheelDelta' in event ? -event.wheelDelta : 0;
10156 },
10157 deltaZ: null,
10158 // Browsers without "deltaMode" is reporting in raw wheel delta where one
10159 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
10160 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
10161 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
10162 deltaMode: null
10163 });
10164
10165 var 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];
10166 var SimpleEventPlugin = {
10167 // simpleEventPluginEventTypes gets populated from
10168 // the DOMEventProperties module.
10169 eventTypes: simpleEventPluginEventTypes,
10170 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
10171 var dispatchConfig = topLevelEventsToDispatchConfig.get(topLevelType);
10172
10173 if (!dispatchConfig) {
10174 return null;
10175 }
10176
10177 var EventConstructor;
10178
10179 switch (topLevelType) {
10180 case TOP_KEY_PRESS:
10181 // Firefox creates a keypress event for function keys too. This removes
10182 // the unwanted keypress events. Enter is however both printable and
10183 // non-printable. One would expect Tab to be as well (but it isn't).
10184 if (getEventCharCode(nativeEvent) === 0) {
10185 return null;
10186 }
10187
10188 /* falls through */
10189
10190 case TOP_KEY_DOWN:
10191 case TOP_KEY_UP:
10192 EventConstructor = SyntheticKeyboardEvent;
10193 break;
10194
10195 case TOP_BLUR:
10196 case TOP_FOCUS:
10197 EventConstructor = SyntheticFocusEvent;
10198 break;
10199
10200 case TOP_CLICK:
10201 // Firefox creates a click event on right mouse clicks. This removes the
10202 // unwanted click events.
10203 if (nativeEvent.button === 2) {
10204 return null;
10205 }
10206
10207 /* falls through */
10208
10209 case TOP_AUX_CLICK:
10210 case TOP_DOUBLE_CLICK:
10211 case TOP_MOUSE_DOWN:
10212 case TOP_MOUSE_MOVE:
10213 case TOP_MOUSE_UP: // TODO: Disabled elements should not respond to mouse events
10214
10215 /* falls through */
10216
10217 case TOP_MOUSE_OUT:
10218 case TOP_MOUSE_OVER:
10219 case TOP_CONTEXT_MENU:
10220 EventConstructor = SyntheticMouseEvent;
10221 break;
10222
10223 case TOP_DRAG:
10224 case TOP_DRAG_END:
10225 case TOP_DRAG_ENTER:
10226 case TOP_DRAG_EXIT:
10227 case TOP_DRAG_LEAVE:
10228 case TOP_DRAG_OVER:
10229 case TOP_DRAG_START:
10230 case TOP_DROP:
10231 EventConstructor = SyntheticDragEvent;
10232 break;
10233
10234 case TOP_TOUCH_CANCEL:
10235 case TOP_TOUCH_END:
10236 case TOP_TOUCH_MOVE:
10237 case TOP_TOUCH_START:
10238 EventConstructor = SyntheticTouchEvent;
10239 break;
10240
10241 case TOP_ANIMATION_END:
10242 case TOP_ANIMATION_ITERATION:
10243 case TOP_ANIMATION_START:
10244 EventConstructor = SyntheticAnimationEvent;
10245 break;
10246
10247 case TOP_TRANSITION_END:
10248 EventConstructor = SyntheticTransitionEvent;
10249 break;
10250
10251 case TOP_SCROLL:
10252 EventConstructor = SyntheticUIEvent;
10253 break;
10254
10255 case TOP_WHEEL:
10256 EventConstructor = SyntheticWheelEvent;
10257 break;
10258
10259 case TOP_COPY:
10260 case TOP_CUT:
10261 case TOP_PASTE:
10262 EventConstructor = SyntheticClipboardEvent;
10263 break;
10264
10265 case TOP_GOT_POINTER_CAPTURE:
10266 case TOP_LOST_POINTER_CAPTURE:
10267 case TOP_POINTER_CANCEL:
10268 case TOP_POINTER_DOWN:
10269 case TOP_POINTER_MOVE:
10270 case TOP_POINTER_OUT:
10271 case TOP_POINTER_OVER:
10272 case TOP_POINTER_UP:
10273 EventConstructor = SyntheticPointerEvent;
10274 break;
10275
10276 default:
10277 {
10278 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
10279 error('SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
10280 }
10281 } // HTML Events
10282 // @see http://www.w3.org/TR/html5/index.html#events-0
10283
10284
10285 EventConstructor = SyntheticEvent;
10286 break;
10287 }
10288
10289 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
10290 accumulateTwoPhaseDispatches(event);
10291 return event;
10292 }
10293 };
10294
10295 /**
10296 * Specifies a deterministic ordering of `EventPlugin`s. A convenient way to
10297 * reason about plugins, without having to package every one of them. This
10298 * is better than having plugins be ordered in the same order that they
10299 * are injected because that ordering would be influenced by the packaging order.
10300 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
10301 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
10302 */
10303
10304 var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
10305 /**
10306 * Inject modules for resolving DOM hierarchy and plugin ordering.
10307 */
10308
10309 injectEventPluginOrder(DOMEventPluginOrder);
10310 setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
10311 /**
10312 * Some important event plugins included by default (without having to require
10313 * them).
10314 */
10315
10316 injectEventPluginsByName({
10317 SimpleEventPlugin: SimpleEventPlugin,
10318 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
10319 ChangeEventPlugin: ChangeEventPlugin,
10320 SelectEventPlugin: SelectEventPlugin,
10321 BeforeInputEventPlugin: BeforeInputEventPlugin
10322 });
10323
10324 // Prefix measurements so that it's possible to filter them.
10325 // Longer prefixes are hard to read in DevTools.
10326 var reactEmoji = "\u269B";
10327 var warningEmoji = "\u26D4";
10328 var 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.
10329 // TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
10330
10331 var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
10332 // Reusing `currentFiber` would be confusing for this because user code fiber
10333 // can change during commit phase too, but we don't need to unwind it (since
10334 // lifecycles in the commit phase don't resemble a tree).
10335
10336 var currentPhase = null;
10337 var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
10338 // so we will keep track of it, and include it in the report.
10339 // Track commits caused by cascading updates.
10340
10341 var isCommitting = false;
10342 var hasScheduledUpdateInCurrentCommit = false;
10343 var hasScheduledUpdateInCurrentPhase = false;
10344 var commitCountInCurrentWorkLoop = 0;
10345 var effectCountInCurrentCommit = 0;
10346 // to avoid stretch the commit phase with measurement overhead.
10347
10348 var labelsInCurrentCommit = new Set();
10349
10350 var formatMarkName = function (markName) {
10351 return reactEmoji + " " + markName;
10352 };
10353
10354 var formatLabel = function (label, warning) {
10355 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
10356 var suffix = warning ? " Warning: " + warning : '';
10357 return "" + prefix + label + suffix;
10358 };
10359
10360 var beginMark = function (markName) {
10361 performance.mark(formatMarkName(markName));
10362 };
10363
10364 var clearMark = function (markName) {
10365 performance.clearMarks(formatMarkName(markName));
10366 };
10367
10368 var endMark = function (label, markName, warning) {
10369 var formattedMarkName = formatMarkName(markName);
10370 var formattedLabel = formatLabel(label, warning);
10371
10372 try {
10373 performance.measure(formattedLabel, formattedMarkName);
10374 } catch (err) {} // If previous mark was missing for some reason, this will throw.
10375 // This could only happen if React crashed in an unexpected place earlier.
10376 // Don't pile on with more errors.
10377 // Clear marks immediately to avoid growing buffer.
10378
10379
10380 performance.clearMarks(formattedMarkName);
10381 performance.clearMeasures(formattedLabel);
10382 };
10383
10384 var getFiberMarkName = function (label, debugID) {
10385 return label + " (#" + debugID + ")";
10386 };
10387
10388 var getFiberLabel = function (componentName, isMounted, phase) {
10389 if (phase === null) {
10390 // These are composite component total time measurements.
10391 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
10392 } else {
10393 // Composite component methods.
10394 return componentName + "." + phase;
10395 }
10396 };
10397
10398 var beginFiberMark = function (fiber, phase) {
10399 var componentName = getComponentName(fiber.type) || 'Unknown';
10400 var debugID = fiber._debugID;
10401 var isMounted = fiber.alternate !== null;
10402 var label = getFiberLabel(componentName, isMounted, phase);
10403
10404 if (isCommitting && labelsInCurrentCommit.has(label)) {
10405 // During the commit phase, we don't show duplicate labels because
10406 // there is a fixed overhead for every measurement, and we don't
10407 // want to stretch the commit phase beyond necessary.
10408 return false;
10409 }
10410
10411 labelsInCurrentCommit.add(label);
10412 var markName = getFiberMarkName(label, debugID);
10413 beginMark(markName);
10414 return true;
10415 };
10416
10417 var clearFiberMark = function (fiber, phase) {
10418 var componentName = getComponentName(fiber.type) || 'Unknown';
10419 var debugID = fiber._debugID;
10420 var isMounted = fiber.alternate !== null;
10421 var label = getFiberLabel(componentName, isMounted, phase);
10422 var markName = getFiberMarkName(label, debugID);
10423 clearMark(markName);
10424 };
10425
10426 var endFiberMark = function (fiber, phase, warning) {
10427 var componentName = getComponentName(fiber.type) || 'Unknown';
10428 var debugID = fiber._debugID;
10429 var isMounted = fiber.alternate !== null;
10430 var label = getFiberLabel(componentName, isMounted, phase);
10431 var markName = getFiberMarkName(label, debugID);
10432 endMark(label, markName, warning);
10433 };
10434
10435 var shouldIgnoreFiber = function (fiber) {
10436 // Host components should be skipped in the timeline.
10437 // We could check typeof fiber.type, but does this work with RN?
10438 switch (fiber.tag) {
10439 case HostRoot:
10440 case HostComponent:
10441 case HostText:
10442 case HostPortal:
10443 case Fragment:
10444 case ContextProvider:
10445 case ContextConsumer:
10446 case Mode:
10447 return true;
10448
10449 default:
10450 return false;
10451 }
10452 };
10453
10454 var clearPendingPhaseMeasurement = function () {
10455 if (currentPhase !== null && currentPhaseFiber !== null) {
10456 clearFiberMark(currentPhaseFiber, currentPhase);
10457 }
10458
10459 currentPhaseFiber = null;
10460 currentPhase = null;
10461 hasScheduledUpdateInCurrentPhase = false;
10462 };
10463
10464 var pauseTimers = function () {
10465 // Stops all currently active measurements so that they can be resumed
10466 // if we continue in a later deferred loop from the same unit of work.
10467 var fiber = currentFiber;
10468
10469 while (fiber) {
10470 if (fiber._debugIsCurrentlyTiming) {
10471 endFiberMark(fiber, null, null);
10472 }
10473
10474 fiber = fiber.return;
10475 }
10476 };
10477
10478 var resumeTimersRecursively = function (fiber) {
10479 if (fiber.return !== null) {
10480 resumeTimersRecursively(fiber.return);
10481 }
10482
10483 if (fiber._debugIsCurrentlyTiming) {
10484 beginFiberMark(fiber, null);
10485 }
10486 };
10487
10488 var resumeTimers = function () {
10489 // Resumes all measurements that were active during the last deferred loop.
10490 if (currentFiber !== null) {
10491 resumeTimersRecursively(currentFiber);
10492 }
10493 };
10494
10495 function recordEffect() {
10496 {
10497 effectCountInCurrentCommit++;
10498 }
10499 }
10500 function recordScheduleUpdate() {
10501 {
10502 if (isCommitting) {
10503 hasScheduledUpdateInCurrentCommit = true;
10504 }
10505
10506 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
10507 hasScheduledUpdateInCurrentPhase = true;
10508 }
10509 }
10510 }
10511 function startWorkTimer(fiber) {
10512 {
10513 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10514 return;
10515 } // If we pause, this is the fiber to unwind from.
10516
10517
10518 currentFiber = fiber;
10519
10520 if (!beginFiberMark(fiber, null)) {
10521 return;
10522 }
10523
10524 fiber._debugIsCurrentlyTiming = true;
10525 }
10526 }
10527 function cancelWorkTimer(fiber) {
10528 {
10529 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10530 return;
10531 } // Remember we shouldn't complete measurement for this fiber.
10532 // Otherwise flamechart will be deep even for small updates.
10533
10534
10535 fiber._debugIsCurrentlyTiming = false;
10536 clearFiberMark(fiber, null);
10537 }
10538 }
10539 function stopWorkTimer(fiber) {
10540 {
10541 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10542 return;
10543 } // If we pause, its parent is the fiber to unwind from.
10544
10545
10546 currentFiber = fiber.return;
10547
10548 if (!fiber._debugIsCurrentlyTiming) {
10549 return;
10550 }
10551
10552 fiber._debugIsCurrentlyTiming = false;
10553 endFiberMark(fiber, null, null);
10554 }
10555 }
10556 function stopFailedWorkTimer(fiber) {
10557 {
10558 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10559 return;
10560 } // If we pause, its parent is the fiber to unwind from.
10561
10562
10563 currentFiber = fiber.return;
10564
10565 if (!fiber._debugIsCurrentlyTiming) {
10566 return;
10567 }
10568
10569 fiber._debugIsCurrentlyTiming = false;
10570 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
10571 endFiberMark(fiber, null, warning);
10572 }
10573 }
10574 function startPhaseTimer(fiber, phase) {
10575 {
10576 if (!supportsUserTiming) {
10577 return;
10578 }
10579
10580 clearPendingPhaseMeasurement();
10581
10582 if (!beginFiberMark(fiber, phase)) {
10583 return;
10584 }
10585
10586 currentPhaseFiber = fiber;
10587 currentPhase = phase;
10588 }
10589 }
10590 function stopPhaseTimer() {
10591 {
10592 if (!supportsUserTiming) {
10593 return;
10594 }
10595
10596 if (currentPhase !== null && currentPhaseFiber !== null) {
10597 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
10598 endFiberMark(currentPhaseFiber, currentPhase, warning);
10599 }
10600
10601 currentPhase = null;
10602 currentPhaseFiber = null;
10603 }
10604 }
10605 function startWorkLoopTimer(nextUnitOfWork) {
10606 {
10607 currentFiber = nextUnitOfWork;
10608
10609 if (!supportsUserTiming) {
10610 return;
10611 }
10612
10613 commitCountInCurrentWorkLoop = 0; // This is top level call.
10614 // Any other measurements are performed within.
10615
10616 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
10617
10618 resumeTimers();
10619 }
10620 }
10621 function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
10622 {
10623 if (!supportsUserTiming) {
10624 return;
10625 }
10626
10627 var warning = null;
10628
10629 if (interruptedBy !== null) {
10630 if (interruptedBy.tag === HostRoot) {
10631 warning = 'A top-level update interrupted the previous render';
10632 } else {
10633 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
10634 warning = "An update to " + componentName + " interrupted the previous render";
10635 }
10636 } else if (commitCountInCurrentWorkLoop > 1) {
10637 warning = 'There were cascading updates';
10638 }
10639
10640 commitCountInCurrentWorkLoop = 0;
10641 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
10642
10643 pauseTimers();
10644 endMark(label, '(React Tree Reconciliation)', warning);
10645 }
10646 }
10647 function startCommitTimer() {
10648 {
10649 if (!supportsUserTiming) {
10650 return;
10651 }
10652
10653 isCommitting = true;
10654 hasScheduledUpdateInCurrentCommit = false;
10655 labelsInCurrentCommit.clear();
10656 beginMark('(Committing Changes)');
10657 }
10658 }
10659 function stopCommitTimer() {
10660 {
10661 if (!supportsUserTiming) {
10662 return;
10663 }
10664
10665 var warning = null;
10666
10667 if (hasScheduledUpdateInCurrentCommit) {
10668 warning = 'Lifecycle hook scheduled a cascading update';
10669 } else if (commitCountInCurrentWorkLoop > 0) {
10670 warning = 'Caused by a cascading update in earlier commit';
10671 }
10672
10673 hasScheduledUpdateInCurrentCommit = false;
10674 commitCountInCurrentWorkLoop++;
10675 isCommitting = false;
10676 labelsInCurrentCommit.clear();
10677 endMark('(Committing Changes)', '(Committing Changes)', warning);
10678 }
10679 }
10680 function startCommitSnapshotEffectsTimer() {
10681 {
10682 if (!supportsUserTiming) {
10683 return;
10684 }
10685
10686 effectCountInCurrentCommit = 0;
10687 beginMark('(Committing Snapshot Effects)');
10688 }
10689 }
10690 function stopCommitSnapshotEffectsTimer() {
10691 {
10692 if (!supportsUserTiming) {
10693 return;
10694 }
10695
10696 var count = effectCountInCurrentCommit;
10697 effectCountInCurrentCommit = 0;
10698 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
10699 }
10700 }
10701 function startCommitHostEffectsTimer() {
10702 {
10703 if (!supportsUserTiming) {
10704 return;
10705 }
10706
10707 effectCountInCurrentCommit = 0;
10708 beginMark('(Committing Host Effects)');
10709 }
10710 }
10711 function stopCommitHostEffectsTimer() {
10712 {
10713 if (!supportsUserTiming) {
10714 return;
10715 }
10716
10717 var count = effectCountInCurrentCommit;
10718 effectCountInCurrentCommit = 0;
10719 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
10720 }
10721 }
10722 function startCommitLifeCyclesTimer() {
10723 {
10724 if (!supportsUserTiming) {
10725 return;
10726 }
10727
10728 effectCountInCurrentCommit = 0;
10729 beginMark('(Calling Lifecycle Methods)');
10730 }
10731 }
10732 function stopCommitLifeCyclesTimer() {
10733 {
10734 if (!supportsUserTiming) {
10735 return;
10736 }
10737
10738 var count = effectCountInCurrentCommit;
10739 effectCountInCurrentCommit = 0;
10740 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
10741 }
10742 }
10743
10744 var valueStack = [];
10745 var fiberStack;
10746
10747 {
10748 fiberStack = [];
10749 }
10750
10751 var index = -1;
10752
10753 function createCursor(defaultValue) {
10754 return {
10755 current: defaultValue
10756 };
10757 }
10758
10759 function pop(cursor, fiber) {
10760 if (index < 0) {
10761 {
10762 error('Unexpected pop.');
10763 }
10764
10765 return;
10766 }
10767
10768 {
10769 if (fiber !== fiberStack[index]) {
10770 error('Unexpected Fiber popped.');
10771 }
10772 }
10773
10774 cursor.current = valueStack[index];
10775 valueStack[index] = null;
10776
10777 {
10778 fiberStack[index] = null;
10779 }
10780
10781 index--;
10782 }
10783
10784 function push(cursor, value, fiber) {
10785 index++;
10786 valueStack[index] = cursor.current;
10787
10788 {
10789 fiberStack[index] = fiber;
10790 }
10791
10792 cursor.current = value;
10793 }
10794
10795 var warnedAboutMissingGetChildContext;
10796
10797 {
10798 warnedAboutMissingGetChildContext = {};
10799 }
10800
10801 var emptyContextObject = {};
10802
10803 {
10804 Object.freeze(emptyContextObject);
10805 } // A cursor to the current merged context object on the stack.
10806
10807
10808 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
10809
10810 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
10811 // We use this to get access to the parent context after we have already
10812 // pushed the next context provider, and now need to merge their contexts.
10813
10814 var previousContext = emptyContextObject;
10815
10816 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
10817 {
10818 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
10819 // If the fiber is a context provider itself, when we read its context
10820 // we may have already pushed its own child context on the stack. A context
10821 // provider should not "see" its own child context. Therefore we read the
10822 // previous (parent) context instead for a context provider.
10823 return previousContext;
10824 }
10825
10826 return contextStackCursor.current;
10827 }
10828 }
10829
10830 function cacheContext(workInProgress, unmaskedContext, maskedContext) {
10831 {
10832 var instance = workInProgress.stateNode;
10833 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
10834 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
10835 }
10836 }
10837
10838 function getMaskedContext(workInProgress, unmaskedContext) {
10839 {
10840 var type = workInProgress.type;
10841 var contextTypes = type.contextTypes;
10842
10843 if (!contextTypes) {
10844 return emptyContextObject;
10845 } // Avoid recreating masked context unless unmasked context has changed.
10846 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
10847 // This may trigger infinite loops if componentWillReceiveProps calls setState.
10848
10849
10850 var instance = workInProgress.stateNode;
10851
10852 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
10853 return instance.__reactInternalMemoizedMaskedChildContext;
10854 }
10855
10856 var context = {};
10857
10858 for (var key in contextTypes) {
10859 context[key] = unmaskedContext[key];
10860 }
10861
10862 {
10863 var name = getComponentName(type) || 'Unknown';
10864 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
10865 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
10866 // Context is created before the class component is instantiated so check for instance.
10867
10868
10869 if (instance) {
10870 cacheContext(workInProgress, unmaskedContext, context);
10871 }
10872
10873 return context;
10874 }
10875 }
10876
10877 function hasContextChanged() {
10878 {
10879 return didPerformWorkStackCursor.current;
10880 }
10881 }
10882
10883 function isContextProvider(type) {
10884 {
10885 var childContextTypes = type.childContextTypes;
10886 return childContextTypes !== null && childContextTypes !== undefined;
10887 }
10888 }
10889
10890 function popContext(fiber) {
10891 {
10892 pop(didPerformWorkStackCursor, fiber);
10893 pop(contextStackCursor, fiber);
10894 }
10895 }
10896
10897 function popTopLevelContextObject(fiber) {
10898 {
10899 pop(didPerformWorkStackCursor, fiber);
10900 pop(contextStackCursor, fiber);
10901 }
10902 }
10903
10904 function pushTopLevelContextObject(fiber, context, didChange) {
10905 {
10906 if (!(contextStackCursor.current === emptyContextObject)) {
10907 {
10908 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
10909 }
10910 }
10911
10912 push(contextStackCursor, context, fiber);
10913 push(didPerformWorkStackCursor, didChange, fiber);
10914 }
10915 }
10916
10917 function processChildContext(fiber, type, parentContext) {
10918 {
10919 var instance = fiber.stateNode;
10920 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
10921 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
10922
10923 if (typeof instance.getChildContext !== 'function') {
10924 {
10925 var componentName = getComponentName(type) || 'Unknown';
10926
10927 if (!warnedAboutMissingGetChildContext[componentName]) {
10928 warnedAboutMissingGetChildContext[componentName] = true;
10929
10930 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);
10931 }
10932 }
10933
10934 return parentContext;
10935 }
10936
10937 var childContext;
10938 startPhaseTimer(fiber, 'getChildContext');
10939 childContext = instance.getChildContext();
10940 stopPhaseTimer();
10941
10942 for (var contextKey in childContext) {
10943 if (!(contextKey in childContextTypes)) {
10944 {
10945 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
10946 }
10947 }
10948 }
10949
10950 {
10951 var name = getComponentName(type) || 'Unknown';
10952 checkPropTypes_1(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
10953 // somebody calls unstable_renderSubtreeIntoContainer() and we process
10954 // context from the parent component instance. The stack will be missing
10955 // because it's outside of the reconciliation, and so the pointer has not
10956 // been set. This is rare and doesn't matter. We'll also remove that API.
10957 getCurrentFiberStackInDev);
10958 }
10959
10960 return _assign({}, parentContext, {}, childContext);
10961 }
10962 }
10963
10964 function pushContextProvider(workInProgress) {
10965 {
10966 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
10967 // If the instance does not exist yet, we will push null at first,
10968 // and replace it on the stack later when invalidating the context.
10969
10970 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
10971 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
10972
10973 previousContext = contextStackCursor.current;
10974 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
10975 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
10976 return true;
10977 }
10978 }
10979
10980 function invalidateContextProvider(workInProgress, type, didChange) {
10981 {
10982 var instance = workInProgress.stateNode;
10983
10984 if (!instance) {
10985 {
10986 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
10987 }
10988 }
10989
10990 if (didChange) {
10991 // Merge parent and own context.
10992 // Skip this if we're not updating due to sCU.
10993 // This avoids unnecessarily recomputing memoized values.
10994 var mergedContext = processChildContext(workInProgress, type, previousContext);
10995 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
10996 // It is important to unwind the context in the reverse order.
10997
10998 pop(didPerformWorkStackCursor, workInProgress);
10999 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
11000
11001 push(contextStackCursor, mergedContext, workInProgress);
11002 push(didPerformWorkStackCursor, didChange, workInProgress);
11003 } else {
11004 pop(didPerformWorkStackCursor, workInProgress);
11005 push(didPerformWorkStackCursor, didChange, workInProgress);
11006 }
11007 }
11008 }
11009
11010 function findCurrentUnmaskedContext(fiber) {
11011 {
11012 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11013 // makes sense elsewhere
11014 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
11015 {
11016 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." );
11017 }
11018 }
11019
11020 var node = fiber;
11021
11022 do {
11023 switch (node.tag) {
11024 case HostRoot:
11025 return node.stateNode.context;
11026
11027 case ClassComponent:
11028 {
11029 var Component = node.type;
11030
11031 if (isContextProvider(Component)) {
11032 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11033 }
11034
11035 break;
11036 }
11037 }
11038
11039 node = node.return;
11040 } while (node !== null);
11041
11042 {
11043 {
11044 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
11045 }
11046 }
11047 }
11048 }
11049
11050 var LegacyRoot = 0;
11051 var BlockingRoot = 1;
11052 var ConcurrentRoot = 2;
11053
11054 var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
11055 var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing,
11056 __interactionsRef = _ReactInternals$Sched$1.__interactionsRef,
11057 __subscriberRef = _ReactInternals$Sched$1.__subscriberRef,
11058 unstable_clear = _ReactInternals$Sched$1.unstable_clear,
11059 unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent,
11060 unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID,
11061 unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe,
11062 unstable_trace = _ReactInternals$Sched$1.unstable_trace,
11063 unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe,
11064 unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
11065
11066 var Scheduler_runWithPriority = unstable_runWithPriority,
11067 Scheduler_scheduleCallback = unstable_scheduleCallback,
11068 Scheduler_cancelCallback = unstable_cancelCallback,
11069 Scheduler_shouldYield = unstable_shouldYield,
11070 Scheduler_requestPaint = unstable_requestPaint,
11071 Scheduler_now = unstable_now,
11072 Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel,
11073 Scheduler_ImmediatePriority = unstable_ImmediatePriority,
11074 Scheduler_UserBlockingPriority = unstable_UserBlockingPriority,
11075 Scheduler_NormalPriority = unstable_NormalPriority,
11076 Scheduler_LowPriority = unstable_LowPriority,
11077 Scheduler_IdlePriority = unstable_IdlePriority;
11078
11079 {
11080 // Provide explicit error message when production+profiling bundle of e.g.
11081 // react-dom is used with production (non-profiling) bundle of
11082 // scheduler/tracing
11083 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
11084 {
11085 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" );
11086 }
11087 }
11088 }
11089
11090 var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
11091 // ascending numbers so we can compare them like numbers. They start at 90 to
11092 // avoid clashing with Scheduler's priorities.
11093
11094 var ImmediatePriority = 99;
11095 var UserBlockingPriority$1 = 98;
11096 var NormalPriority = 97;
11097 var LowPriority = 96;
11098 var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
11099
11100 var NoPriority = 90;
11101 var shouldYield = Scheduler_shouldYield;
11102 var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
11103 Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
11104 var syncQueue = null;
11105 var immediateQueueCallbackNode = null;
11106 var isFlushingSyncQueue = false;
11107 var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
11108 // This will be the case for modern browsers that support `performance.now`. In
11109 // older browsers, Scheduler falls back to `Date.now`, which returns a Unix
11110 // timestamp. In that case, subtract the module initialization time to simulate
11111 // the behavior of performance.now and keep our times small enough to fit
11112 // within 32 bits.
11113 // TODO: Consider lifting this into Scheduler.
11114
11115 var now = initialTimeMs < 10000 ? Scheduler_now : function () {
11116 return Scheduler_now() - initialTimeMs;
11117 };
11118 function getCurrentPriorityLevel() {
11119 switch (Scheduler_getCurrentPriorityLevel()) {
11120 case Scheduler_ImmediatePriority:
11121 return ImmediatePriority;
11122
11123 case Scheduler_UserBlockingPriority:
11124 return UserBlockingPriority$1;
11125
11126 case Scheduler_NormalPriority:
11127 return NormalPriority;
11128
11129 case Scheduler_LowPriority:
11130 return LowPriority;
11131
11132 case Scheduler_IdlePriority:
11133 return IdlePriority;
11134
11135 default:
11136 {
11137 {
11138 throw Error( "Unknown priority level." );
11139 }
11140 }
11141
11142 }
11143 }
11144
11145 function reactPriorityToSchedulerPriority(reactPriorityLevel) {
11146 switch (reactPriorityLevel) {
11147 case ImmediatePriority:
11148 return Scheduler_ImmediatePriority;
11149
11150 case UserBlockingPriority$1:
11151 return Scheduler_UserBlockingPriority;
11152
11153 case NormalPriority:
11154 return Scheduler_NormalPriority;
11155
11156 case LowPriority:
11157 return Scheduler_LowPriority;
11158
11159 case IdlePriority:
11160 return Scheduler_IdlePriority;
11161
11162 default:
11163 {
11164 {
11165 throw Error( "Unknown priority level." );
11166 }
11167 }
11168
11169 }
11170 }
11171
11172 function runWithPriority$1(reactPriorityLevel, fn) {
11173 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11174 return Scheduler_runWithPriority(priorityLevel, fn);
11175 }
11176 function scheduleCallback(reactPriorityLevel, callback, options) {
11177 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11178 return Scheduler_scheduleCallback(priorityLevel, callback, options);
11179 }
11180 function scheduleSyncCallback(callback) {
11181 // Push this callback into an internal queue. We'll flush these either in
11182 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
11183 if (syncQueue === null) {
11184 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
11185
11186 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
11187 } else {
11188 // Push onto existing queue. Don't need to schedule a callback because
11189 // we already scheduled one when we created the queue.
11190 syncQueue.push(callback);
11191 }
11192
11193 return fakeCallbackNode;
11194 }
11195 function cancelCallback(callbackNode) {
11196 if (callbackNode !== fakeCallbackNode) {
11197 Scheduler_cancelCallback(callbackNode);
11198 }
11199 }
11200 function flushSyncCallbackQueue() {
11201 if (immediateQueueCallbackNode !== null) {
11202 var node = immediateQueueCallbackNode;
11203 immediateQueueCallbackNode = null;
11204 Scheduler_cancelCallback(node);
11205 }
11206
11207 flushSyncCallbackQueueImpl();
11208 }
11209
11210 function flushSyncCallbackQueueImpl() {
11211 if (!isFlushingSyncQueue && syncQueue !== null) {
11212 // Prevent re-entrancy.
11213 isFlushingSyncQueue = true;
11214 var i = 0;
11215
11216 try {
11217 var _isSync = true;
11218 var queue = syncQueue;
11219 runWithPriority$1(ImmediatePriority, function () {
11220 for (; i < queue.length; i++) {
11221 var callback = queue[i];
11222
11223 do {
11224 callback = callback(_isSync);
11225 } while (callback !== null);
11226 }
11227 });
11228 syncQueue = null;
11229 } catch (error) {
11230 // If something throws, leave the remaining callbacks on the queue.
11231 if (syncQueue !== null) {
11232 syncQueue = syncQueue.slice(i + 1);
11233 } // Resume flushing in the next tick
11234
11235
11236 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
11237 throw error;
11238 } finally {
11239 isFlushingSyncQueue = false;
11240 }
11241 }
11242 }
11243
11244 var NoMode = 0;
11245 var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
11246 // tag instead
11247
11248 var BlockingMode = 2;
11249 var ConcurrentMode = 4;
11250 var ProfileMode = 8;
11251
11252 // Max 31 bit integer. The max integer size in V8 for 32-bit systems.
11253 // Math.pow(2, 30) - 1
11254 // 0b111111111111111111111111111111
11255 var MAX_SIGNED_31_BIT_INT = 1073741823;
11256
11257 var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
11258 // Never work can be committed in an inconsistent state without tearing the UI.
11259 // The main example is offscreen content, like a hidden subtree. So one possible
11260 // name is Offscreen. However, it also includes dehydrated Suspense boundaries,
11261 // which are inconsistent in the sense that they haven't finished yet, but
11262 // aren't visibly inconsistent because the server rendered HTML matches what the
11263 // hydrated tree would look like.
11264
11265 var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
11266 // order to be consistent.
11267
11268 var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase
11269 // priority of hover targets.
11270
11271 var ContinuousHydration = 3;
11272 var Sync = MAX_SIGNED_31_BIT_INT;
11273 var Batched = Sync - 1;
11274 var UNIT_SIZE = 10;
11275 var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
11276
11277 function msToExpirationTime(ms) {
11278 // Always subtract from the offset so that we don't clash with the magic number for NoWork.
11279 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
11280 }
11281 function expirationTimeToMs(expirationTime) {
11282 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
11283 }
11284
11285 function ceiling(num, precision) {
11286 return ((num / precision | 0) + 1) * precision;
11287 }
11288
11289 function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
11290 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
11291 } // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
11292 // the names to reflect.
11293
11294
11295 var LOW_PRIORITY_EXPIRATION = 5000;
11296 var LOW_PRIORITY_BATCH_SIZE = 250;
11297 function computeAsyncExpiration(currentTime) {
11298 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
11299 }
11300 function computeSuspenseExpiration(currentTime, timeoutMs) {
11301 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
11302 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
11303 } // We intentionally set a higher expiration time for interactive updates in
11304 // dev than in production.
11305 //
11306 // If the main thread is being blocked so long that you hit the expiration,
11307 // it's a problem that could be solved with better scheduling.
11308 //
11309 // People will be more likely to notice this and fix it with the long
11310 // expiration time in development.
11311 //
11312 // In production we opt for better UX at the risk of masking scheduling
11313 // problems, by expiring fast.
11314
11315 var HIGH_PRIORITY_EXPIRATION = 500 ;
11316 var HIGH_PRIORITY_BATCH_SIZE = 100;
11317 function computeInteractiveExpiration(currentTime) {
11318 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
11319 }
11320 function inferPriorityFromExpirationTime(currentTime, expirationTime) {
11321 if (expirationTime === Sync) {
11322 return ImmediatePriority;
11323 }
11324
11325 if (expirationTime === Never || expirationTime === Idle) {
11326 return IdlePriority;
11327 }
11328
11329 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
11330
11331 if (msUntil <= 0) {
11332 return ImmediatePriority;
11333 }
11334
11335 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
11336 return UserBlockingPriority$1;
11337 }
11338
11339 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
11340 return NormalPriority;
11341 } // TODO: Handle LowPriority
11342 // Assume anything lower has idle priority
11343
11344
11345 return IdlePriority;
11346 }
11347
11348 var ReactStrictModeWarnings = {
11349 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
11350 flushPendingUnsafeLifecycleWarnings: function () {},
11351 recordLegacyContextWarning: function (fiber, instance) {},
11352 flushLegacyContextWarning: function () {},
11353 discardPendingWarnings: function () {}
11354 };
11355
11356 {
11357 var findStrictRoot = function (fiber) {
11358 var maybeStrictRoot = null;
11359 var node = fiber;
11360
11361 while (node !== null) {
11362 if (node.mode & StrictMode) {
11363 maybeStrictRoot = node;
11364 }
11365
11366 node = node.return;
11367 }
11368
11369 return maybeStrictRoot;
11370 };
11371
11372 var setToSortedString = function (set) {
11373 var array = [];
11374 set.forEach(function (value) {
11375 array.push(value);
11376 });
11377 return array.sort().join(', ');
11378 };
11379
11380 var pendingComponentWillMountWarnings = [];
11381 var pendingUNSAFE_ComponentWillMountWarnings = [];
11382 var pendingComponentWillReceivePropsWarnings = [];
11383 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11384 var pendingComponentWillUpdateWarnings = [];
11385 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
11386
11387 var didWarnAboutUnsafeLifecycles = new Set();
11388
11389 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
11390 // Dedup strategy: Warn once per component.
11391 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
11392 return;
11393 }
11394
11395 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
11396 instance.componentWillMount.__suppressDeprecationWarning !== true) {
11397 pendingComponentWillMountWarnings.push(fiber);
11398 }
11399
11400 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
11401 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
11402 }
11403
11404 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11405 pendingComponentWillReceivePropsWarnings.push(fiber);
11406 }
11407
11408 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11409 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
11410 }
11411
11412 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11413 pendingComponentWillUpdateWarnings.push(fiber);
11414 }
11415
11416 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
11417 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
11418 }
11419 };
11420
11421 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
11422 // We do an initial pass to gather component names
11423 var componentWillMountUniqueNames = new Set();
11424
11425 if (pendingComponentWillMountWarnings.length > 0) {
11426 pendingComponentWillMountWarnings.forEach(function (fiber) {
11427 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11428 didWarnAboutUnsafeLifecycles.add(fiber.type);
11429 });
11430 pendingComponentWillMountWarnings = [];
11431 }
11432
11433 var UNSAFE_componentWillMountUniqueNames = new Set();
11434
11435 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
11436 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
11437 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11438 didWarnAboutUnsafeLifecycles.add(fiber.type);
11439 });
11440 pendingUNSAFE_ComponentWillMountWarnings = [];
11441 }
11442
11443 var componentWillReceivePropsUniqueNames = new Set();
11444
11445 if (pendingComponentWillReceivePropsWarnings.length > 0) {
11446 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
11447 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11448 didWarnAboutUnsafeLifecycles.add(fiber.type);
11449 });
11450 pendingComponentWillReceivePropsWarnings = [];
11451 }
11452
11453 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
11454
11455 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
11456 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
11457 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11458 didWarnAboutUnsafeLifecycles.add(fiber.type);
11459 });
11460 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11461 }
11462
11463 var componentWillUpdateUniqueNames = new Set();
11464
11465 if (pendingComponentWillUpdateWarnings.length > 0) {
11466 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
11467 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11468 didWarnAboutUnsafeLifecycles.add(fiber.type);
11469 });
11470 pendingComponentWillUpdateWarnings = [];
11471 }
11472
11473 var UNSAFE_componentWillUpdateUniqueNames = new Set();
11474
11475 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
11476 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
11477 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11478 didWarnAboutUnsafeLifecycles.add(fiber.type);
11479 });
11480 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11481 } // Finally, we flush all the warnings
11482 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
11483
11484
11485 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
11486 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
11487
11488 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);
11489 }
11490
11491 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
11492 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
11493
11494 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);
11495 }
11496
11497 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
11498 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
11499
11500 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);
11501 }
11502
11503 if (componentWillMountUniqueNames.size > 0) {
11504 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
11505
11506 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);
11507 }
11508
11509 if (componentWillReceivePropsUniqueNames.size > 0) {
11510 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
11511
11512 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);
11513 }
11514
11515 if (componentWillUpdateUniqueNames.size > 0) {
11516 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
11517
11518 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);
11519 }
11520 };
11521
11522 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
11523
11524 var didWarnAboutLegacyContext = new Set();
11525
11526 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
11527 var strictRoot = findStrictRoot(fiber);
11528
11529 if (strictRoot === null) {
11530 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.');
11531
11532 return;
11533 } // Dedup strategy: Warn once per component.
11534
11535
11536 if (didWarnAboutLegacyContext.has(fiber.type)) {
11537 return;
11538 }
11539
11540 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
11541
11542 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
11543 if (warningsForRoot === undefined) {
11544 warningsForRoot = [];
11545 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
11546 }
11547
11548 warningsForRoot.push(fiber);
11549 }
11550 };
11551
11552 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
11553 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
11554 if (fiberArray.length === 0) {
11555 return;
11556 }
11557
11558 var firstFiber = fiberArray[0];
11559 var uniqueNames = new Set();
11560 fiberArray.forEach(function (fiber) {
11561 uniqueNames.add(getComponentName(fiber.type) || 'Component');
11562 didWarnAboutLegacyContext.add(fiber.type);
11563 });
11564 var sortedNames = setToSortedString(uniqueNames);
11565 var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
11566
11567 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);
11568 });
11569 };
11570
11571 ReactStrictModeWarnings.discardPendingWarnings = function () {
11572 pendingComponentWillMountWarnings = [];
11573 pendingUNSAFE_ComponentWillMountWarnings = [];
11574 pendingComponentWillReceivePropsWarnings = [];
11575 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11576 pendingComponentWillUpdateWarnings = [];
11577 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11578 pendingLegacyContextWarning = new Map();
11579 };
11580 }
11581
11582 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
11583
11584 var failedBoundaries = null;
11585 var setRefreshHandler = function (handler) {
11586 {
11587 resolveFamily = handler;
11588 }
11589 };
11590 function resolveFunctionForHotReloading(type) {
11591 {
11592 if (resolveFamily === null) {
11593 // Hot reloading is disabled.
11594 return type;
11595 }
11596
11597 var family = resolveFamily(type);
11598
11599 if (family === undefined) {
11600 return type;
11601 } // Use the latest known implementation.
11602
11603
11604 return family.current;
11605 }
11606 }
11607 function resolveClassForHotReloading(type) {
11608 // No implementation differences.
11609 return resolveFunctionForHotReloading(type);
11610 }
11611 function resolveForwardRefForHotReloading(type) {
11612 {
11613 if (resolveFamily === null) {
11614 // Hot reloading is disabled.
11615 return type;
11616 }
11617
11618 var family = resolveFamily(type);
11619
11620 if (family === undefined) {
11621 // Check if we're dealing with a real forwardRef. Don't want to crash early.
11622 if (type !== null && type !== undefined && typeof type.render === 'function') {
11623 // ForwardRef is special because its resolved .type is an object,
11624 // but it's possible that we only have its inner render function in the map.
11625 // If that inner render function is different, we'll build a new forwardRef type.
11626 var currentRender = resolveFunctionForHotReloading(type.render);
11627
11628 if (type.render !== currentRender) {
11629 var syntheticType = {
11630 $$typeof: REACT_FORWARD_REF_TYPE,
11631 render: currentRender
11632 };
11633
11634 if (type.displayName !== undefined) {
11635 syntheticType.displayName = type.displayName;
11636 }
11637
11638 return syntheticType;
11639 }
11640 }
11641
11642 return type;
11643 } // Use the latest known implementation.
11644
11645
11646 return family.current;
11647 }
11648 }
11649 function isCompatibleFamilyForHotReloading(fiber, element) {
11650 {
11651 if (resolveFamily === null) {
11652 // Hot reloading is disabled.
11653 return false;
11654 }
11655
11656 var prevType = fiber.elementType;
11657 var nextType = element.type; // If we got here, we know types aren't === equal.
11658
11659 var needsCompareFamilies = false;
11660 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
11661
11662 switch (fiber.tag) {
11663 case ClassComponent:
11664 {
11665 if (typeof nextType === 'function') {
11666 needsCompareFamilies = true;
11667 }
11668
11669 break;
11670 }
11671
11672 case FunctionComponent:
11673 {
11674 if (typeof nextType === 'function') {
11675 needsCompareFamilies = true;
11676 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11677 // We don't know the inner type yet.
11678 // We're going to assume that the lazy inner type is stable,
11679 // and so it is sufficient to avoid reconciling it away.
11680 // We're not going to unwrap or actually use the new lazy type.
11681 needsCompareFamilies = true;
11682 }
11683
11684 break;
11685 }
11686
11687 case ForwardRef:
11688 {
11689 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
11690 needsCompareFamilies = true;
11691 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11692 needsCompareFamilies = true;
11693 }
11694
11695 break;
11696 }
11697
11698 case MemoComponent:
11699 case SimpleMemoComponent:
11700 {
11701 if ($$typeofNextType === REACT_MEMO_TYPE) {
11702 // TODO: if it was but can no longer be simple,
11703 // we shouldn't set this.
11704 needsCompareFamilies = true;
11705 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11706 needsCompareFamilies = true;
11707 }
11708
11709 break;
11710 }
11711
11712 default:
11713 return false;
11714 } // Check if both types have a family and it's the same one.
11715
11716
11717 if (needsCompareFamilies) {
11718 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
11719 // This means both of them need to be registered to preserve state.
11720 // If we unwrapped and compared the inner types for wrappers instead,
11721 // then we would risk falsely saying two separate memo(Foo)
11722 // calls are equivalent because they wrap the same Foo function.
11723 var prevFamily = resolveFamily(prevType);
11724
11725 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
11726 return true;
11727 }
11728 }
11729
11730 return false;
11731 }
11732 }
11733 function markFailedErrorBoundaryForHotReloading(fiber) {
11734 {
11735 if (resolveFamily === null) {
11736 // Hot reloading is disabled.
11737 return;
11738 }
11739
11740 if (typeof WeakSet !== 'function') {
11741 return;
11742 }
11743
11744 if (failedBoundaries === null) {
11745 failedBoundaries = new WeakSet();
11746 }
11747
11748 failedBoundaries.add(fiber);
11749 }
11750 }
11751 var scheduleRefresh = function (root, update) {
11752 {
11753 if (resolveFamily === null) {
11754 // Hot reloading is disabled.
11755 return;
11756 }
11757
11758 var staleFamilies = update.staleFamilies,
11759 updatedFamilies = update.updatedFamilies;
11760 flushPassiveEffects();
11761 flushSync(function () {
11762 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
11763 });
11764 }
11765 };
11766 var scheduleRoot = function (root, element) {
11767 {
11768 if (root.context !== emptyContextObject) {
11769 // Super edge case: root has a legacy _renderSubtree context
11770 // but we don't know the parentComponent so we can't pass it.
11771 // Just ignore. We'll delete this with _renderSubtree code path later.
11772 return;
11773 }
11774
11775 flushPassiveEffects();
11776 syncUpdates(function () {
11777 updateContainer(element, root, null, null);
11778 });
11779 }
11780 };
11781
11782 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
11783 {
11784 var alternate = fiber.alternate,
11785 child = fiber.child,
11786 sibling = fiber.sibling,
11787 tag = fiber.tag,
11788 type = fiber.type;
11789 var candidateType = null;
11790
11791 switch (tag) {
11792 case FunctionComponent:
11793 case SimpleMemoComponent:
11794 case ClassComponent:
11795 candidateType = type;
11796 break;
11797
11798 case ForwardRef:
11799 candidateType = type.render;
11800 break;
11801 }
11802
11803 if (resolveFamily === null) {
11804 throw new Error('Expected resolveFamily to be set during hot reload.');
11805 }
11806
11807 var needsRender = false;
11808 var needsRemount = false;
11809
11810 if (candidateType !== null) {
11811 var family = resolveFamily(candidateType);
11812
11813 if (family !== undefined) {
11814 if (staleFamilies.has(family)) {
11815 needsRemount = true;
11816 } else if (updatedFamilies.has(family)) {
11817 if (tag === ClassComponent) {
11818 needsRemount = true;
11819 } else {
11820 needsRender = true;
11821 }
11822 }
11823 }
11824 }
11825
11826 if (failedBoundaries !== null) {
11827 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
11828 needsRemount = true;
11829 }
11830 }
11831
11832 if (needsRemount) {
11833 fiber._debugNeedsRemount = true;
11834 }
11835
11836 if (needsRemount || needsRender) {
11837 scheduleWork(fiber, Sync);
11838 }
11839
11840 if (child !== null && !needsRemount) {
11841 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
11842 }
11843
11844 if (sibling !== null) {
11845 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
11846 }
11847 }
11848 }
11849
11850 var findHostInstancesForRefresh = function (root, families) {
11851 {
11852 var hostInstances = new Set();
11853 var types = new Set(families.map(function (family) {
11854 return family.current;
11855 }));
11856 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
11857 return hostInstances;
11858 }
11859 };
11860
11861 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
11862 {
11863 var child = fiber.child,
11864 sibling = fiber.sibling,
11865 tag = fiber.tag,
11866 type = fiber.type;
11867 var candidateType = null;
11868
11869 switch (tag) {
11870 case FunctionComponent:
11871 case SimpleMemoComponent:
11872 case ClassComponent:
11873 candidateType = type;
11874 break;
11875
11876 case ForwardRef:
11877 candidateType = type.render;
11878 break;
11879 }
11880
11881 var didMatch = false;
11882
11883 if (candidateType !== null) {
11884 if (types.has(candidateType)) {
11885 didMatch = true;
11886 }
11887 }
11888
11889 if (didMatch) {
11890 // We have a match. This only drills down to the closest host components.
11891 // There's no need to search deeper because for the purpose of giving
11892 // visual feedback, "flashing" outermost parent rectangles is sufficient.
11893 findHostInstancesForFiberShallowly(fiber, hostInstances);
11894 } else {
11895 // If there's no match, maybe there will be one further down in the child tree.
11896 if (child !== null) {
11897 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
11898 }
11899 }
11900
11901 if (sibling !== null) {
11902 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
11903 }
11904 }
11905 }
11906
11907 function findHostInstancesForFiberShallowly(fiber, hostInstances) {
11908 {
11909 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
11910
11911 if (foundHostInstances) {
11912 return;
11913 } // If we didn't find any host children, fallback to closest host parent.
11914
11915
11916 var node = fiber;
11917
11918 while (true) {
11919 switch (node.tag) {
11920 case HostComponent:
11921 hostInstances.add(node.stateNode);
11922 return;
11923
11924 case HostPortal:
11925 hostInstances.add(node.stateNode.containerInfo);
11926 return;
11927
11928 case HostRoot:
11929 hostInstances.add(node.stateNode.containerInfo);
11930 return;
11931 }
11932
11933 if (node.return === null) {
11934 throw new Error('Expected to reach root first.');
11935 }
11936
11937 node = node.return;
11938 }
11939 }
11940 }
11941
11942 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
11943 {
11944 var node = fiber;
11945 var foundHostInstances = false;
11946
11947 while (true) {
11948 if (node.tag === HostComponent) {
11949 // We got a match.
11950 foundHostInstances = true;
11951 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
11952 } else if (node.child !== null) {
11953 node.child.return = node;
11954 node = node.child;
11955 continue;
11956 }
11957
11958 if (node === fiber) {
11959 return foundHostInstances;
11960 }
11961
11962 while (node.sibling === null) {
11963 if (node.return === null || node.return === fiber) {
11964 return foundHostInstances;
11965 }
11966
11967 node = node.return;
11968 }
11969
11970 node.sibling.return = node.return;
11971 node = node.sibling;
11972 }
11973 }
11974
11975 return false;
11976 }
11977
11978 function resolveDefaultProps(Component, baseProps) {
11979 if (Component && Component.defaultProps) {
11980 // Resolve default props. Taken from ReactElement
11981 var props = _assign({}, baseProps);
11982
11983 var defaultProps = Component.defaultProps;
11984
11985 for (var propName in defaultProps) {
11986 if (props[propName] === undefined) {
11987 props[propName] = defaultProps[propName];
11988 }
11989 }
11990
11991 return props;
11992 }
11993
11994 return baseProps;
11995 }
11996 function readLazyComponentType(lazyComponent) {
11997 initializeLazyComponentType(lazyComponent);
11998
11999 if (lazyComponent._status !== Resolved) {
12000 throw lazyComponent._result;
12001 }
12002
12003 return lazyComponent._result;
12004 }
12005
12006 var valueCursor = createCursor(null);
12007 var rendererSigil;
12008
12009 {
12010 // Use this to detect multiple renderers using the same context
12011 rendererSigil = {};
12012 }
12013
12014 var currentlyRenderingFiber = null;
12015 var lastContextDependency = null;
12016 var lastContextWithAllBitsObserved = null;
12017 var isDisallowedContextReadInDEV = false;
12018 function resetContextDependencies() {
12019 // This is called right before React yields execution, to ensure `readContext`
12020 // cannot be called outside the render phase.
12021 currentlyRenderingFiber = null;
12022 lastContextDependency = null;
12023 lastContextWithAllBitsObserved = null;
12024
12025 {
12026 isDisallowedContextReadInDEV = false;
12027 }
12028 }
12029 function enterDisallowedContextReadInDEV() {
12030 {
12031 isDisallowedContextReadInDEV = true;
12032 }
12033 }
12034 function exitDisallowedContextReadInDEV() {
12035 {
12036 isDisallowedContextReadInDEV = false;
12037 }
12038 }
12039 function pushProvider(providerFiber, nextValue) {
12040 var context = providerFiber.type._context;
12041
12042 {
12043 push(valueCursor, context._currentValue, providerFiber);
12044 context._currentValue = nextValue;
12045
12046 {
12047 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
12048 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
12049 }
12050
12051 context._currentRenderer = rendererSigil;
12052 }
12053 }
12054 }
12055 function popProvider(providerFiber) {
12056 var currentValue = valueCursor.current;
12057 pop(valueCursor, providerFiber);
12058 var context = providerFiber.type._context;
12059
12060 {
12061 context._currentValue = currentValue;
12062 }
12063 }
12064 function calculateChangedBits(context, newValue, oldValue) {
12065 if (objectIs(oldValue, newValue)) {
12066 // No change
12067 return 0;
12068 } else {
12069 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
12070
12071 {
12072 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
12073 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
12074 }
12075 }
12076
12077 return changedBits | 0;
12078 }
12079 }
12080 function scheduleWorkOnParentPath(parent, renderExpirationTime) {
12081 // Update the child expiration time of all the ancestors, including
12082 // the alternates.
12083 var node = parent;
12084
12085 while (node !== null) {
12086 var alternate = node.alternate;
12087
12088 if (node.childExpirationTime < renderExpirationTime) {
12089 node.childExpirationTime = renderExpirationTime;
12090
12091 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
12092 alternate.childExpirationTime = renderExpirationTime;
12093 }
12094 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
12095 alternate.childExpirationTime = renderExpirationTime;
12096 } else {
12097 // Neither alternate was updated, which means the rest of the
12098 // ancestor path already has sufficient priority.
12099 break;
12100 }
12101
12102 node = node.return;
12103 }
12104 }
12105 function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
12106 var fiber = workInProgress.child;
12107
12108 if (fiber !== null) {
12109 // Set the return pointer of the child to the work-in-progress fiber.
12110 fiber.return = workInProgress;
12111 }
12112
12113 while (fiber !== null) {
12114 var nextFiber = void 0; // Visit this fiber.
12115
12116 var list = fiber.dependencies;
12117
12118 if (list !== null) {
12119 nextFiber = fiber.child;
12120 var dependency = list.firstContext;
12121
12122 while (dependency !== null) {
12123 // Check if the context matches.
12124 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
12125 // Match! Schedule an update on this fiber.
12126 if (fiber.tag === ClassComponent) {
12127 // Schedule a force update on the work-in-progress.
12128 var update = createUpdate(renderExpirationTime, null);
12129 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
12130 // update to the current fiber, too, which means it will persist even if
12131 // this render is thrown away. Since it's a race condition, not sure it's
12132 // worth fixing.
12133
12134 enqueueUpdate(fiber, update);
12135 }
12136
12137 if (fiber.expirationTime < renderExpirationTime) {
12138 fiber.expirationTime = renderExpirationTime;
12139 }
12140
12141 var alternate = fiber.alternate;
12142
12143 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
12144 alternate.expirationTime = renderExpirationTime;
12145 }
12146
12147 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
12148
12149 if (list.expirationTime < renderExpirationTime) {
12150 list.expirationTime = renderExpirationTime;
12151 } // Since we already found a match, we can stop traversing the
12152 // dependency list.
12153
12154
12155 break;
12156 }
12157
12158 dependency = dependency.next;
12159 }
12160 } else if (fiber.tag === ContextProvider) {
12161 // Don't scan deeper if this is a matching provider
12162 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
12163 } else {
12164 // Traverse down.
12165 nextFiber = fiber.child;
12166 }
12167
12168 if (nextFiber !== null) {
12169 // Set the return pointer of the child to the work-in-progress fiber.
12170 nextFiber.return = fiber;
12171 } else {
12172 // No child. Traverse to next sibling.
12173 nextFiber = fiber;
12174
12175 while (nextFiber !== null) {
12176 if (nextFiber === workInProgress) {
12177 // We're back to the root of this subtree. Exit.
12178 nextFiber = null;
12179 break;
12180 }
12181
12182 var sibling = nextFiber.sibling;
12183
12184 if (sibling !== null) {
12185 // Set the return pointer of the sibling to the work-in-progress fiber.
12186 sibling.return = nextFiber.return;
12187 nextFiber = sibling;
12188 break;
12189 } // No more siblings. Traverse up.
12190
12191
12192 nextFiber = nextFiber.return;
12193 }
12194 }
12195
12196 fiber = nextFiber;
12197 }
12198 }
12199 function prepareToReadContext(workInProgress, renderExpirationTime) {
12200 currentlyRenderingFiber = workInProgress;
12201 lastContextDependency = null;
12202 lastContextWithAllBitsObserved = null;
12203 var dependencies = workInProgress.dependencies;
12204
12205 if (dependencies !== null) {
12206 var firstContext = dependencies.firstContext;
12207
12208 if (firstContext !== null) {
12209 if (dependencies.expirationTime >= renderExpirationTime) {
12210 // Context list has a pending update. Mark that this fiber performed work.
12211 markWorkInProgressReceivedUpdate();
12212 } // Reset the work-in-progress list
12213
12214
12215 dependencies.firstContext = null;
12216 }
12217 }
12218 }
12219 function readContext(context, observedBits) {
12220 {
12221 // This warning would fire if you read context inside a Hook like useMemo.
12222 // Unlike the class check below, it's not enforced in production for perf.
12223 if (isDisallowedContextReadInDEV) {
12224 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().');
12225 }
12226 }
12227
12228 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
12229 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
12230
12231 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
12232 // Observe all updates.
12233 lastContextWithAllBitsObserved = context;
12234 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
12235 } else {
12236 resolvedObservedBits = observedBits;
12237 }
12238
12239 var contextItem = {
12240 context: context,
12241 observedBits: resolvedObservedBits,
12242 next: null
12243 };
12244
12245 if (lastContextDependency === null) {
12246 if (!(currentlyRenderingFiber !== null)) {
12247 {
12248 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()." );
12249 }
12250 } // This is the first dependency for this component. Create a new list.
12251
12252
12253 lastContextDependency = contextItem;
12254 currentlyRenderingFiber.dependencies = {
12255 expirationTime: NoWork,
12256 firstContext: contextItem,
12257 responders: null
12258 };
12259 } else {
12260 // Append a new context item.
12261 lastContextDependency = lastContextDependency.next = contextItem;
12262 }
12263 }
12264
12265 return context._currentValue ;
12266 }
12267
12268 var UpdateState = 0;
12269 var ReplaceState = 1;
12270 var ForceUpdate = 2;
12271 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
12272 // It should only be read right after calling `processUpdateQueue`, via
12273 // `checkHasForceUpdateAfterProcessing`.
12274
12275 var hasForceUpdate = false;
12276 var didWarnUpdateInsideUpdate;
12277 var currentlyProcessingQueue;
12278
12279 {
12280 didWarnUpdateInsideUpdate = false;
12281 currentlyProcessingQueue = null;
12282 }
12283
12284 function initializeUpdateQueue(fiber) {
12285 var queue = {
12286 baseState: fiber.memoizedState,
12287 baseQueue: null,
12288 shared: {
12289 pending: null
12290 },
12291 effects: null
12292 };
12293 fiber.updateQueue = queue;
12294 }
12295 function cloneUpdateQueue(current, workInProgress) {
12296 // Clone the update queue from current. Unless it's already a clone.
12297 var queue = workInProgress.updateQueue;
12298 var currentQueue = current.updateQueue;
12299
12300 if (queue === currentQueue) {
12301 var clone = {
12302 baseState: currentQueue.baseState,
12303 baseQueue: currentQueue.baseQueue,
12304 shared: currentQueue.shared,
12305 effects: currentQueue.effects
12306 };
12307 workInProgress.updateQueue = clone;
12308 }
12309 }
12310 function createUpdate(expirationTime, suspenseConfig) {
12311 var update = {
12312 expirationTime: expirationTime,
12313 suspenseConfig: suspenseConfig,
12314 tag: UpdateState,
12315 payload: null,
12316 callback: null,
12317 next: null
12318 };
12319 update.next = update;
12320
12321 {
12322 update.priority = getCurrentPriorityLevel();
12323 }
12324
12325 return update;
12326 }
12327 function enqueueUpdate(fiber, update) {
12328 var updateQueue = fiber.updateQueue;
12329
12330 if (updateQueue === null) {
12331 // Only occurs if the fiber has been unmounted.
12332 return;
12333 }
12334
12335 var sharedQueue = updateQueue.shared;
12336 var pending = sharedQueue.pending;
12337
12338 if (pending === null) {
12339 // This is the first update. Create a circular list.
12340 update.next = update;
12341 } else {
12342 update.next = pending.next;
12343 pending.next = update;
12344 }
12345
12346 sharedQueue.pending = update;
12347
12348 {
12349 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
12350 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.');
12351
12352 didWarnUpdateInsideUpdate = true;
12353 }
12354 }
12355 }
12356 function enqueueCapturedUpdate(workInProgress, update) {
12357 var current = workInProgress.alternate;
12358
12359 if (current !== null) {
12360 // Ensure the work-in-progress queue is a clone
12361 cloneUpdateQueue(current, workInProgress);
12362 } // Captured updates go only on the work-in-progress queue.
12363
12364
12365 var queue = workInProgress.updateQueue; // Append the update to the end of the list.
12366
12367 var last = queue.baseQueue;
12368
12369 if (last === null) {
12370 queue.baseQueue = update.next = update;
12371 update.next = update;
12372 } else {
12373 update.next = last.next;
12374 last.next = update;
12375 }
12376 }
12377
12378 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
12379 switch (update.tag) {
12380 case ReplaceState:
12381 {
12382 var payload = update.payload;
12383
12384 if (typeof payload === 'function') {
12385 // Updater function
12386 {
12387 enterDisallowedContextReadInDEV();
12388
12389 if ( workInProgress.mode & StrictMode) {
12390 payload.call(instance, prevState, nextProps);
12391 }
12392 }
12393
12394 var nextState = payload.call(instance, prevState, nextProps);
12395
12396 {
12397 exitDisallowedContextReadInDEV();
12398 }
12399
12400 return nextState;
12401 } // State object
12402
12403
12404 return payload;
12405 }
12406
12407 case CaptureUpdate:
12408 {
12409 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
12410 }
12411 // Intentional fallthrough
12412
12413 case UpdateState:
12414 {
12415 var _payload = update.payload;
12416 var partialState;
12417
12418 if (typeof _payload === 'function') {
12419 // Updater function
12420 {
12421 enterDisallowedContextReadInDEV();
12422
12423 if ( workInProgress.mode & StrictMode) {
12424 _payload.call(instance, prevState, nextProps);
12425 }
12426 }
12427
12428 partialState = _payload.call(instance, prevState, nextProps);
12429
12430 {
12431 exitDisallowedContextReadInDEV();
12432 }
12433 } else {
12434 // Partial state object
12435 partialState = _payload;
12436 }
12437
12438 if (partialState === null || partialState === undefined) {
12439 // Null and undefined are treated as no-ops.
12440 return prevState;
12441 } // Merge the partial state and the previous state.
12442
12443
12444 return _assign({}, prevState, partialState);
12445 }
12446
12447 case ForceUpdate:
12448 {
12449 hasForceUpdate = true;
12450 return prevState;
12451 }
12452 }
12453
12454 return prevState;
12455 }
12456
12457 function processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {
12458 // This is always non-null on a ClassComponent or HostRoot
12459 var queue = workInProgress.updateQueue;
12460 hasForceUpdate = false;
12461
12462 {
12463 currentlyProcessingQueue = queue.shared;
12464 } // The last rebase update that is NOT part of the base state.
12465
12466
12467 var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.
12468
12469 var pendingQueue = queue.shared.pending;
12470
12471 if (pendingQueue !== null) {
12472 // We have new updates that haven't been processed yet.
12473 // We'll add them to the base queue.
12474 if (baseQueue !== null) {
12475 // Merge the pending queue and the base queue.
12476 var baseFirst = baseQueue.next;
12477 var pendingFirst = pendingQueue.next;
12478 baseQueue.next = pendingFirst;
12479 pendingQueue.next = baseFirst;
12480 }
12481
12482 baseQueue = pendingQueue;
12483 queue.shared.pending = null; // TODO: Pass `current` as argument
12484
12485 var current = workInProgress.alternate;
12486
12487 if (current !== null) {
12488 var currentQueue = current.updateQueue;
12489
12490 if (currentQueue !== null) {
12491 currentQueue.baseQueue = pendingQueue;
12492 }
12493 }
12494 } // These values may change as we process the queue.
12495
12496
12497 if (baseQueue !== null) {
12498 var first = baseQueue.next; // Iterate through the list of updates to compute the result.
12499
12500 var newState = queue.baseState;
12501 var newExpirationTime = NoWork;
12502 var newBaseState = null;
12503 var newBaseQueueFirst = null;
12504 var newBaseQueueLast = null;
12505
12506 if (first !== null) {
12507 var update = first;
12508
12509 do {
12510 var updateExpirationTime = update.expirationTime;
12511
12512 if (updateExpirationTime < renderExpirationTime) {
12513 // Priority is insufficient. Skip this update. If this is the first
12514 // skipped update, the previous update/state is the new base
12515 // update/state.
12516 var clone = {
12517 expirationTime: update.expirationTime,
12518 suspenseConfig: update.suspenseConfig,
12519 tag: update.tag,
12520 payload: update.payload,
12521 callback: update.callback,
12522 next: null
12523 };
12524
12525 if (newBaseQueueLast === null) {
12526 newBaseQueueFirst = newBaseQueueLast = clone;
12527 newBaseState = newState;
12528 } else {
12529 newBaseQueueLast = newBaseQueueLast.next = clone;
12530 } // Update the remaining priority in the queue.
12531
12532
12533 if (updateExpirationTime > newExpirationTime) {
12534 newExpirationTime = updateExpirationTime;
12535 }
12536 } else {
12537 // This update does have sufficient priority.
12538 if (newBaseQueueLast !== null) {
12539 var _clone = {
12540 expirationTime: Sync,
12541 // This update is going to be committed so we never want uncommit it.
12542 suspenseConfig: update.suspenseConfig,
12543 tag: update.tag,
12544 payload: update.payload,
12545 callback: update.callback,
12546 next: null
12547 };
12548 newBaseQueueLast = newBaseQueueLast.next = _clone;
12549 } // Mark the event time of this update as relevant to this render pass.
12550 // TODO: This should ideally use the true event time of this update rather than
12551 // its priority which is a derived and not reverseable value.
12552 // TODO: We should skip this update if it was already committed but currently
12553 // we have no way of detecting the difference between a committed and suspended
12554 // update here.
12555
12556
12557 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
12558
12559 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
12560 var callback = update.callback;
12561
12562 if (callback !== null) {
12563 workInProgress.effectTag |= Callback;
12564 var effects = queue.effects;
12565
12566 if (effects === null) {
12567 queue.effects = [update];
12568 } else {
12569 effects.push(update);
12570 }
12571 }
12572 }
12573
12574 update = update.next;
12575
12576 if (update === null || update === first) {
12577 pendingQueue = queue.shared.pending;
12578
12579 if (pendingQueue === null) {
12580 break;
12581 } else {
12582 // An update was scheduled from inside a reducer. Add the new
12583 // pending updates to the end of the list and keep processing.
12584 update = baseQueue.next = pendingQueue.next;
12585 pendingQueue.next = first;
12586 queue.baseQueue = baseQueue = pendingQueue;
12587 queue.shared.pending = null;
12588 }
12589 }
12590 } while (true);
12591 }
12592
12593 if (newBaseQueueLast === null) {
12594 newBaseState = newState;
12595 } else {
12596 newBaseQueueLast.next = newBaseQueueFirst;
12597 }
12598
12599 queue.baseState = newBaseState;
12600 queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.
12601 // This should be fine because the only two other things that contribute to
12602 // expiration time are props and context. We're already in the middle of the
12603 // begin phase by the time we start processing the queue, so we've already
12604 // dealt with the props. Context in components that specify
12605 // shouldComponentUpdate is tricky; but we'll have to account for
12606 // that regardless.
12607
12608 markUnprocessedUpdateTime(newExpirationTime);
12609 workInProgress.expirationTime = newExpirationTime;
12610 workInProgress.memoizedState = newState;
12611 }
12612
12613 {
12614 currentlyProcessingQueue = null;
12615 }
12616 }
12617
12618 function callCallback(callback, context) {
12619 if (!(typeof callback === 'function')) {
12620 {
12621 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
12622 }
12623 }
12624
12625 callback.call(context);
12626 }
12627
12628 function resetHasForceUpdateBeforeProcessing() {
12629 hasForceUpdate = false;
12630 }
12631 function checkHasForceUpdateAfterProcessing() {
12632 return hasForceUpdate;
12633 }
12634 function commitUpdateQueue(finishedWork, finishedQueue, instance) {
12635 // Commit the effects
12636 var effects = finishedQueue.effects;
12637 finishedQueue.effects = null;
12638
12639 if (effects !== null) {
12640 for (var i = 0; i < effects.length; i++) {
12641 var effect = effects[i];
12642 var callback = effect.callback;
12643
12644 if (callback !== null) {
12645 effect.callback = null;
12646 callCallback(callback, instance);
12647 }
12648 }
12649 }
12650 }
12651
12652 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
12653 function requestCurrentSuspenseConfig() {
12654 return ReactCurrentBatchConfig.suspense;
12655 }
12656
12657 var fakeInternalInstance = {};
12658 var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
12659 // We'll use it to determine whether we need to initialize legacy refs.
12660
12661 var emptyRefsObject = new React.Component().refs;
12662 var didWarnAboutStateAssignmentForComponent;
12663 var didWarnAboutUninitializedState;
12664 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
12665 var didWarnAboutLegacyLifecyclesAndDerivedState;
12666 var didWarnAboutUndefinedDerivedState;
12667 var warnOnUndefinedDerivedState;
12668 var warnOnInvalidCallback;
12669 var didWarnAboutDirectlyAssigningPropsToState;
12670 var didWarnAboutContextTypeAndContextTypes;
12671 var didWarnAboutInvalidateContextType;
12672
12673 {
12674 didWarnAboutStateAssignmentForComponent = new Set();
12675 didWarnAboutUninitializedState = new Set();
12676 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
12677 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
12678 didWarnAboutDirectlyAssigningPropsToState = new Set();
12679 didWarnAboutUndefinedDerivedState = new Set();
12680 didWarnAboutContextTypeAndContextTypes = new Set();
12681 didWarnAboutInvalidateContextType = new Set();
12682 var didWarnOnInvalidCallback = new Set();
12683
12684 warnOnInvalidCallback = function (callback, callerName) {
12685 if (callback === null || typeof callback === 'function') {
12686 return;
12687 }
12688
12689 var key = callerName + "_" + callback;
12690
12691 if (!didWarnOnInvalidCallback.has(key)) {
12692 didWarnOnInvalidCallback.add(key);
12693
12694 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
12695 }
12696 };
12697
12698 warnOnUndefinedDerivedState = function (type, partialState) {
12699 if (partialState === undefined) {
12700 var componentName = getComponentName(type) || 'Component';
12701
12702 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
12703 didWarnAboutUndefinedDerivedState.add(componentName);
12704
12705 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
12706 }
12707 }
12708 }; // This is so gross but it's at least non-critical and can be removed if
12709 // it causes problems. This is meant to give a nicer error message for
12710 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
12711 // ...)) which otherwise throws a "_processChildContext is not a function"
12712 // exception.
12713
12714
12715 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
12716 enumerable: false,
12717 value: function () {
12718 {
12719 {
12720 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)." );
12721 }
12722 }
12723 }
12724 });
12725 Object.freeze(fakeInternalInstance);
12726 }
12727
12728 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
12729 var prevState = workInProgress.memoizedState;
12730
12731 {
12732 if ( workInProgress.mode & StrictMode) {
12733 // Invoke the function an extra time to help detect side-effects.
12734 getDerivedStateFromProps(nextProps, prevState);
12735 }
12736 }
12737
12738 var partialState = getDerivedStateFromProps(nextProps, prevState);
12739
12740 {
12741 warnOnUndefinedDerivedState(ctor, partialState);
12742 } // Merge the partial state and the previous state.
12743
12744
12745 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
12746 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
12747 // base state.
12748
12749 if (workInProgress.expirationTime === NoWork) {
12750 // Queue is always non-null for classes
12751 var updateQueue = workInProgress.updateQueue;
12752 updateQueue.baseState = memoizedState;
12753 }
12754 }
12755 var classComponentUpdater = {
12756 isMounted: isMounted,
12757 enqueueSetState: function (inst, payload, callback) {
12758 var fiber = get(inst);
12759 var currentTime = requestCurrentTimeForUpdate();
12760 var suspenseConfig = requestCurrentSuspenseConfig();
12761 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12762 var update = createUpdate(expirationTime, suspenseConfig);
12763 update.payload = payload;
12764
12765 if (callback !== undefined && callback !== null) {
12766 {
12767 warnOnInvalidCallback(callback, 'setState');
12768 }
12769
12770 update.callback = callback;
12771 }
12772
12773 enqueueUpdate(fiber, update);
12774 scheduleWork(fiber, expirationTime);
12775 },
12776 enqueueReplaceState: function (inst, payload, callback) {
12777 var fiber = get(inst);
12778 var currentTime = requestCurrentTimeForUpdate();
12779 var suspenseConfig = requestCurrentSuspenseConfig();
12780 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12781 var update = createUpdate(expirationTime, suspenseConfig);
12782 update.tag = ReplaceState;
12783 update.payload = payload;
12784
12785 if (callback !== undefined && callback !== null) {
12786 {
12787 warnOnInvalidCallback(callback, 'replaceState');
12788 }
12789
12790 update.callback = callback;
12791 }
12792
12793 enqueueUpdate(fiber, update);
12794 scheduleWork(fiber, expirationTime);
12795 },
12796 enqueueForceUpdate: function (inst, callback) {
12797 var fiber = get(inst);
12798 var currentTime = requestCurrentTimeForUpdate();
12799 var suspenseConfig = requestCurrentSuspenseConfig();
12800 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
12801 var update = createUpdate(expirationTime, suspenseConfig);
12802 update.tag = ForceUpdate;
12803
12804 if (callback !== undefined && callback !== null) {
12805 {
12806 warnOnInvalidCallback(callback, 'forceUpdate');
12807 }
12808
12809 update.callback = callback;
12810 }
12811
12812 enqueueUpdate(fiber, update);
12813 scheduleWork(fiber, expirationTime);
12814 }
12815 };
12816
12817 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
12818 var instance = workInProgress.stateNode;
12819
12820 if (typeof instance.shouldComponentUpdate === 'function') {
12821 {
12822 if ( workInProgress.mode & StrictMode) {
12823 // Invoke the function an extra time to help detect side-effects.
12824 instance.shouldComponentUpdate(newProps, newState, nextContext);
12825 }
12826 }
12827
12828 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
12829 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
12830 stopPhaseTimer();
12831
12832 {
12833 if (shouldUpdate === undefined) {
12834 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
12835 }
12836 }
12837
12838 return shouldUpdate;
12839 }
12840
12841 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
12842 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
12843 }
12844
12845 return true;
12846 }
12847
12848 function checkClassInstance(workInProgress, ctor, newProps) {
12849 var instance = workInProgress.stateNode;
12850
12851 {
12852 var name = getComponentName(ctor) || 'Component';
12853 var renderPresent = instance.render;
12854
12855 if (!renderPresent) {
12856 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
12857 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
12858 } else {
12859 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
12860 }
12861 }
12862
12863 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
12864 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);
12865 }
12866
12867 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
12868 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);
12869 }
12870
12871 if (instance.propTypes) {
12872 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
12873 }
12874
12875 if (instance.contextType) {
12876 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
12877 }
12878
12879 {
12880 if (instance.contextTypes) {
12881 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
12882 }
12883
12884 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
12885 didWarnAboutContextTypeAndContextTypes.add(ctor);
12886
12887 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
12888 }
12889 }
12890
12891 if (typeof instance.componentShouldUpdate === 'function') {
12892 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);
12893 }
12894
12895 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
12896 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');
12897 }
12898
12899 if (typeof instance.componentDidUnmount === 'function') {
12900 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
12901 }
12902
12903 if (typeof instance.componentDidReceiveProps === 'function') {
12904 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);
12905 }
12906
12907 if (typeof instance.componentWillRecieveProps === 'function') {
12908 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
12909 }
12910
12911 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
12912 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
12913 }
12914
12915 var hasMutatedProps = instance.props !== newProps;
12916
12917 if (instance.props !== undefined && hasMutatedProps) {
12918 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
12919 }
12920
12921 if (instance.defaultProps) {
12922 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);
12923 }
12924
12925 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
12926 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
12927
12928 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
12929 }
12930
12931 if (typeof instance.getDerivedStateFromProps === 'function') {
12932 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12933 }
12934
12935 if (typeof instance.getDerivedStateFromError === 'function') {
12936 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
12937 }
12938
12939 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
12940 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
12941 }
12942
12943 var _state = instance.state;
12944
12945 if (_state && (typeof _state !== 'object' || isArray(_state))) {
12946 error('%s.state: must be set to an object or null', name);
12947 }
12948
12949 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
12950 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
12951 }
12952 }
12953 }
12954
12955 function adoptClassInstance(workInProgress, instance) {
12956 instance.updater = classComponentUpdater;
12957 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
12958
12959 set(instance, workInProgress);
12960
12961 {
12962 instance._reactInternalInstance = fakeInternalInstance;
12963 }
12964 }
12965
12966 function constructClassInstance(workInProgress, ctor, props) {
12967 var isLegacyContextConsumer = false;
12968 var unmaskedContext = emptyContextObject;
12969 var context = emptyContextObject;
12970 var contextType = ctor.contextType;
12971
12972 {
12973 if ('contextType' in ctor) {
12974 var isValid = // Allow null for conditional declaration
12975 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
12976
12977 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
12978 didWarnAboutInvalidateContextType.add(ctor);
12979 var addendum = '';
12980
12981 if (contextType === undefined) {
12982 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.';
12983 } else if (typeof contextType !== 'object') {
12984 addendum = ' However, it is set to a ' + typeof contextType + '.';
12985 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
12986 addendum = ' Did you accidentally pass the Context.Provider instead?';
12987 } else if (contextType._context !== undefined) {
12988 // <Context.Consumer>
12989 addendum = ' Did you accidentally pass the Context.Consumer instead?';
12990 } else {
12991 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
12992 }
12993
12994 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
12995 }
12996 }
12997 }
12998
12999 if (typeof contextType === 'object' && contextType !== null) {
13000 context = readContext(contextType);
13001 } else {
13002 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13003 var contextTypes = ctor.contextTypes;
13004 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
13005 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
13006 } // Instantiate twice to help detect side-effects.
13007
13008
13009 {
13010 if ( workInProgress.mode & StrictMode) {
13011 new ctor(props, context); // eslint-disable-line no-new
13012 }
13013 }
13014
13015 var instance = new ctor(props, context);
13016 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
13017 adoptClassInstance(workInProgress, instance);
13018
13019 {
13020 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
13021 var componentName = getComponentName(ctor) || 'Component';
13022
13023 if (!didWarnAboutUninitializedState.has(componentName)) {
13024 didWarnAboutUninitializedState.add(componentName);
13025
13026 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);
13027 }
13028 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
13029 // Warn about these lifecycles if they are present.
13030 // Don't warn about react-lifecycles-compat polyfilled methods though.
13031
13032
13033 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
13034 var foundWillMountName = null;
13035 var foundWillReceivePropsName = null;
13036 var foundWillUpdateName = null;
13037
13038 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
13039 foundWillMountName = 'componentWillMount';
13040 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
13041 foundWillMountName = 'UNSAFE_componentWillMount';
13042 }
13043
13044 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
13045 foundWillReceivePropsName = 'componentWillReceiveProps';
13046 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13047 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
13048 }
13049
13050 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
13051 foundWillUpdateName = 'componentWillUpdate';
13052 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13053 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
13054 }
13055
13056 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
13057 var _componentName = getComponentName(ctor) || 'Component';
13058
13059 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
13060
13061 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
13062 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
13063
13064 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 : '');
13065 }
13066 }
13067 }
13068 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
13069 // ReactFiberContext usually updates this cache but can't for newly-created instances.
13070
13071
13072 if (isLegacyContextConsumer) {
13073 cacheContext(workInProgress, unmaskedContext, context);
13074 }
13075
13076 return instance;
13077 }
13078
13079 function callComponentWillMount(workInProgress, instance) {
13080 startPhaseTimer(workInProgress, 'componentWillMount');
13081 var oldState = instance.state;
13082
13083 if (typeof instance.componentWillMount === 'function') {
13084 instance.componentWillMount();
13085 }
13086
13087 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13088 instance.UNSAFE_componentWillMount();
13089 }
13090
13091 stopPhaseTimer();
13092
13093 if (oldState !== instance.state) {
13094 {
13095 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
13096 }
13097
13098 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13099 }
13100 }
13101
13102 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
13103 var oldState = instance.state;
13104 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
13105
13106 if (typeof instance.componentWillReceiveProps === 'function') {
13107 instance.componentWillReceiveProps(newProps, nextContext);
13108 }
13109
13110 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13111 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
13112 }
13113
13114 stopPhaseTimer();
13115
13116 if (instance.state !== oldState) {
13117 {
13118 var componentName = getComponentName(workInProgress.type) || 'Component';
13119
13120 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
13121 didWarnAboutStateAssignmentForComponent.add(componentName);
13122
13123 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
13124 }
13125 }
13126
13127 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13128 }
13129 } // Invokes the mount life-cycles on a previously never rendered instance.
13130
13131
13132 function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13133 {
13134 checkClassInstance(workInProgress, ctor, newProps);
13135 }
13136
13137 var instance = workInProgress.stateNode;
13138 instance.props = newProps;
13139 instance.state = workInProgress.memoizedState;
13140 instance.refs = emptyRefsObject;
13141 initializeUpdateQueue(workInProgress);
13142 var contextType = ctor.contextType;
13143
13144 if (typeof contextType === 'object' && contextType !== null) {
13145 instance.context = readContext(contextType);
13146 } else {
13147 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13148 instance.context = getMaskedContext(workInProgress, unmaskedContext);
13149 }
13150
13151 {
13152 if (instance.state === newProps) {
13153 var componentName = getComponentName(ctor) || 'Component';
13154
13155 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
13156 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
13157
13158 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);
13159 }
13160 }
13161
13162 if (workInProgress.mode & StrictMode) {
13163 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
13164 }
13165
13166 {
13167 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
13168 }
13169 }
13170
13171 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13172 instance.state = workInProgress.memoizedState;
13173 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13174
13175 if (typeof getDerivedStateFromProps === 'function') {
13176 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13177 instance.state = workInProgress.memoizedState;
13178 } // In order to support react-lifecycles-compat polyfilled components,
13179 // Unsafe lifecycles should not be invoked for components using the new APIs.
13180
13181
13182 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13183 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
13184 // process them now.
13185
13186 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13187 instance.state = workInProgress.memoizedState;
13188 }
13189
13190 if (typeof instance.componentDidMount === 'function') {
13191 workInProgress.effectTag |= Update;
13192 }
13193 }
13194
13195 function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13196 var instance = workInProgress.stateNode;
13197 var oldProps = workInProgress.memoizedProps;
13198 instance.props = oldProps;
13199 var oldContext = instance.context;
13200 var contextType = ctor.contextType;
13201 var nextContext = emptyContextObject;
13202
13203 if (typeof contextType === 'object' && contextType !== null) {
13204 nextContext = readContext(contextType);
13205 } else {
13206 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13207 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
13208 }
13209
13210 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13211 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13212 // ever the previously attempted to render - not the "current". However,
13213 // during componentDidUpdate we pass the "current" props.
13214 // In order to support react-lifecycles-compat polyfilled components,
13215 // Unsafe lifecycles should not be invoked for components using the new APIs.
13216
13217 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13218 if (oldProps !== newProps || oldContext !== nextContext) {
13219 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13220 }
13221 }
13222
13223 resetHasForceUpdateBeforeProcessing();
13224 var oldState = workInProgress.memoizedState;
13225 var newState = instance.state = oldState;
13226 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13227 newState = workInProgress.memoizedState;
13228
13229 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13230 // If an update was already in progress, we should schedule an Update
13231 // effect even though we're bailing out, so that cWU/cDU are called.
13232 if (typeof instance.componentDidMount === 'function') {
13233 workInProgress.effectTag |= Update;
13234 }
13235
13236 return false;
13237 }
13238
13239 if (typeof getDerivedStateFromProps === 'function') {
13240 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13241 newState = workInProgress.memoizedState;
13242 }
13243
13244 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13245
13246 if (shouldUpdate) {
13247 // In order to support react-lifecycles-compat polyfilled components,
13248 // Unsafe lifecycles should not be invoked for components using the new APIs.
13249 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13250 startPhaseTimer(workInProgress, 'componentWillMount');
13251
13252 if (typeof instance.componentWillMount === 'function') {
13253 instance.componentWillMount();
13254 }
13255
13256 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13257 instance.UNSAFE_componentWillMount();
13258 }
13259
13260 stopPhaseTimer();
13261 }
13262
13263 if (typeof instance.componentDidMount === 'function') {
13264 workInProgress.effectTag |= Update;
13265 }
13266 } else {
13267 // If an update was already in progress, we should schedule an Update
13268 // effect even though we're bailing out, so that cWU/cDU are called.
13269 if (typeof instance.componentDidMount === 'function') {
13270 workInProgress.effectTag |= Update;
13271 } // If shouldComponentUpdate returned false, we should still update the
13272 // memoized state to indicate that this work can be reused.
13273
13274
13275 workInProgress.memoizedProps = newProps;
13276 workInProgress.memoizedState = newState;
13277 } // Update the existing instance's state, props, and context pointers even
13278 // if shouldComponentUpdate returns false.
13279
13280
13281 instance.props = newProps;
13282 instance.state = newState;
13283 instance.context = nextContext;
13284 return shouldUpdate;
13285 } // Invokes the update life-cycles and returns false if it shouldn't rerender.
13286
13287
13288 function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
13289 var instance = workInProgress.stateNode;
13290 cloneUpdateQueue(current, workInProgress);
13291 var oldProps = workInProgress.memoizedProps;
13292 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
13293 var oldContext = instance.context;
13294 var contextType = ctor.contextType;
13295 var nextContext = emptyContextObject;
13296
13297 if (typeof contextType === 'object' && contextType !== null) {
13298 nextContext = readContext(contextType);
13299 } else {
13300 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13301 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13302 }
13303
13304 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13305 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13306 // ever the previously attempted to render - not the "current". However,
13307 // during componentDidUpdate we pass the "current" props.
13308 // In order to support react-lifecycles-compat polyfilled components,
13309 // Unsafe lifecycles should not be invoked for components using the new APIs.
13310
13311 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13312 if (oldProps !== newProps || oldContext !== nextContext) {
13313 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13314 }
13315 }
13316
13317 resetHasForceUpdateBeforeProcessing();
13318 var oldState = workInProgress.memoizedState;
13319 var newState = instance.state = oldState;
13320 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
13321 newState = workInProgress.memoizedState;
13322
13323 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13324 // If an update was already in progress, we should schedule an Update
13325 // effect even though we're bailing out, so that cWU/cDU are called.
13326 if (typeof instance.componentDidUpdate === 'function') {
13327 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13328 workInProgress.effectTag |= Update;
13329 }
13330 }
13331
13332 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13333 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13334 workInProgress.effectTag |= Snapshot;
13335 }
13336 }
13337
13338 return false;
13339 }
13340
13341 if (typeof getDerivedStateFromProps === 'function') {
13342 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13343 newState = workInProgress.memoizedState;
13344 }
13345
13346 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13347
13348 if (shouldUpdate) {
13349 // In order to support react-lifecycles-compat polyfilled components,
13350 // Unsafe lifecycles should not be invoked for components using the new APIs.
13351 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13352 startPhaseTimer(workInProgress, 'componentWillUpdate');
13353
13354 if (typeof instance.componentWillUpdate === 'function') {
13355 instance.componentWillUpdate(newProps, newState, nextContext);
13356 }
13357
13358 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13359 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13360 }
13361
13362 stopPhaseTimer();
13363 }
13364
13365 if (typeof instance.componentDidUpdate === 'function') {
13366 workInProgress.effectTag |= Update;
13367 }
13368
13369 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13370 workInProgress.effectTag |= Snapshot;
13371 }
13372 } else {
13373 // If an update was already in progress, we should schedule an Update
13374 // effect even though we're bailing out, so that cWU/cDU are called.
13375 if (typeof instance.componentDidUpdate === 'function') {
13376 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13377 workInProgress.effectTag |= Update;
13378 }
13379 }
13380
13381 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13382 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13383 workInProgress.effectTag |= Snapshot;
13384 }
13385 } // If shouldComponentUpdate returned false, we should still update the
13386 // memoized props/state to indicate that this work can be reused.
13387
13388
13389 workInProgress.memoizedProps = newProps;
13390 workInProgress.memoizedState = newState;
13391 } // Update the existing instance's state, props, and context pointers even
13392 // if shouldComponentUpdate returns false.
13393
13394
13395 instance.props = newProps;
13396 instance.state = newState;
13397 instance.context = nextContext;
13398 return shouldUpdate;
13399 }
13400
13401 var didWarnAboutMaps;
13402 var didWarnAboutGenerators;
13403 var didWarnAboutStringRefs;
13404 var ownerHasKeyUseWarning;
13405 var ownerHasFunctionTypeWarning;
13406
13407 var warnForMissingKey = function (child) {};
13408
13409 {
13410 didWarnAboutMaps = false;
13411 didWarnAboutGenerators = false;
13412 didWarnAboutStringRefs = {};
13413 /**
13414 * Warn if there's no key explicitly set on dynamic arrays of children or
13415 * object keys are not valid. This allows us to keep track of children between
13416 * updates.
13417 */
13418
13419 ownerHasKeyUseWarning = {};
13420 ownerHasFunctionTypeWarning = {};
13421
13422 warnForMissingKey = function (child) {
13423 if (child === null || typeof child !== 'object') {
13424 return;
13425 }
13426
13427 if (!child._store || child._store.validated || child.key != null) {
13428 return;
13429 }
13430
13431 if (!(typeof child._store === 'object')) {
13432 {
13433 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
13434 }
13435 }
13436
13437 child._store.validated = true;
13438 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
13439
13440 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
13441 return;
13442 }
13443
13444 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
13445
13446 error('Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
13447 };
13448 }
13449
13450 var isArray$1 = Array.isArray;
13451
13452 function coerceRef(returnFiber, current, element) {
13453 var mixedRef = element.ref;
13454
13455 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13456 {
13457 // TODO: Clean this up once we turn on the string ref warning for
13458 // everyone, because the strict mode case will no longer be relevant
13459 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
13460 // because these cannot be automatically converted to an arrow function
13461 // using a codemod. Therefore, we don't have to warn about string refs again.
13462 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
13463 var componentName = getComponentName(returnFiber.type) || 'Component';
13464
13465 if (!didWarnAboutStringRefs[componentName]) {
13466 {
13467 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));
13468 }
13469
13470 didWarnAboutStringRefs[componentName] = true;
13471 }
13472 }
13473 }
13474
13475 if (element._owner) {
13476 var owner = element._owner;
13477 var inst;
13478
13479 if (owner) {
13480 var ownerFiber = owner;
13481
13482 if (!(ownerFiber.tag === ClassComponent)) {
13483 {
13484 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" );
13485 }
13486 }
13487
13488 inst = ownerFiber.stateNode;
13489 }
13490
13491 if (!inst) {
13492 {
13493 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
13494 }
13495 }
13496
13497 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
13498
13499 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
13500 return current.ref;
13501 }
13502
13503 var ref = function (value) {
13504 var refs = inst.refs;
13505
13506 if (refs === emptyRefsObject) {
13507 // This is a lazy pooled frozen object, so we need to initialize.
13508 refs = inst.refs = {};
13509 }
13510
13511 if (value === null) {
13512 delete refs[stringRef];
13513 } else {
13514 refs[stringRef] = value;
13515 }
13516 };
13517
13518 ref._stringRef = stringRef;
13519 return ref;
13520 } else {
13521 if (!(typeof mixedRef === 'string')) {
13522 {
13523 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
13524 }
13525 }
13526
13527 if (!element._owner) {
13528 {
13529 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." );
13530 }
13531 }
13532 }
13533 }
13534
13535 return mixedRef;
13536 }
13537
13538 function throwOnInvalidObjectType(returnFiber, newChild) {
13539 if (returnFiber.type !== 'textarea') {
13540 var addendum = '';
13541
13542 {
13543 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
13544 }
13545
13546 {
13547 {
13548 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 );
13549 }
13550 }
13551 }
13552 }
13553
13554 function warnOnFunctionType() {
13555 {
13556 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();
13557
13558 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
13559 return;
13560 }
13561
13562 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
13563
13564 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.');
13565 }
13566 } // This wrapper function exists because I expect to clone the code in each path
13567 // to be able to optimize each path individually by branching early. This needs
13568 // a compiler or we can do it manually. Helpers that don't need this branching
13569 // live outside of this function.
13570
13571
13572 function ChildReconciler(shouldTrackSideEffects) {
13573 function deleteChild(returnFiber, childToDelete) {
13574 if (!shouldTrackSideEffects) {
13575 // Noop.
13576 return;
13577 } // Deletions are added in reversed order so we add it to the front.
13578 // At this point, the return fiber's effect list is empty except for
13579 // deletions, so we can just append the deletion to the list. The remaining
13580 // effects aren't added until the complete phase. Once we implement
13581 // resuming, this may not be true.
13582
13583
13584 var last = returnFiber.lastEffect;
13585
13586 if (last !== null) {
13587 last.nextEffect = childToDelete;
13588 returnFiber.lastEffect = childToDelete;
13589 } else {
13590 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13591 }
13592
13593 childToDelete.nextEffect = null;
13594 childToDelete.effectTag = Deletion;
13595 }
13596
13597 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13598 if (!shouldTrackSideEffects) {
13599 // Noop.
13600 return null;
13601 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
13602 // assuming that after the first child we've already added everything.
13603
13604
13605 var childToDelete = currentFirstChild;
13606
13607 while (childToDelete !== null) {
13608 deleteChild(returnFiber, childToDelete);
13609 childToDelete = childToDelete.sibling;
13610 }
13611
13612 return null;
13613 }
13614
13615 function mapRemainingChildren(returnFiber, currentFirstChild) {
13616 // Add the remaining children to a temporary map so that we can find them by
13617 // keys quickly. Implicit (null) keys get added to this set with their index
13618 // instead.
13619 var existingChildren = new Map();
13620 var existingChild = currentFirstChild;
13621
13622 while (existingChild !== null) {
13623 if (existingChild.key !== null) {
13624 existingChildren.set(existingChild.key, existingChild);
13625 } else {
13626 existingChildren.set(existingChild.index, existingChild);
13627 }
13628
13629 existingChild = existingChild.sibling;
13630 }
13631
13632 return existingChildren;
13633 }
13634
13635 function useFiber(fiber, pendingProps) {
13636 // We currently set sibling to null and index to 0 here because it is easy
13637 // to forget to do before returning it. E.g. for the single child case.
13638 var clone = createWorkInProgress(fiber, pendingProps);
13639 clone.index = 0;
13640 clone.sibling = null;
13641 return clone;
13642 }
13643
13644 function placeChild(newFiber, lastPlacedIndex, newIndex) {
13645 newFiber.index = newIndex;
13646
13647 if (!shouldTrackSideEffects) {
13648 // Noop.
13649 return lastPlacedIndex;
13650 }
13651
13652 var current = newFiber.alternate;
13653
13654 if (current !== null) {
13655 var oldIndex = current.index;
13656
13657 if (oldIndex < lastPlacedIndex) {
13658 // This is a move.
13659 newFiber.effectTag = Placement;
13660 return lastPlacedIndex;
13661 } else {
13662 // This item can stay in place.
13663 return oldIndex;
13664 }
13665 } else {
13666 // This is an insertion.
13667 newFiber.effectTag = Placement;
13668 return lastPlacedIndex;
13669 }
13670 }
13671
13672 function placeSingleChild(newFiber) {
13673 // This is simpler for the single child case. We only need to do a
13674 // placement for inserting new children.
13675 if (shouldTrackSideEffects && newFiber.alternate === null) {
13676 newFiber.effectTag = Placement;
13677 }
13678
13679 return newFiber;
13680 }
13681
13682 function updateTextNode(returnFiber, current, textContent, expirationTime) {
13683 if (current === null || current.tag !== HostText) {
13684 // Insert
13685 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
13686 created.return = returnFiber;
13687 return created;
13688 } else {
13689 // Update
13690 var existing = useFiber(current, textContent);
13691 existing.return = returnFiber;
13692 return existing;
13693 }
13694 }
13695
13696 function updateElement(returnFiber, current, element, expirationTime) {
13697 if (current !== null) {
13698 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
13699 isCompatibleFamilyForHotReloading(current, element) )) {
13700 // Move based on index
13701 var existing = useFiber(current, element.props);
13702 existing.ref = coerceRef(returnFiber, current, element);
13703 existing.return = returnFiber;
13704
13705 {
13706 existing._debugSource = element._source;
13707 existing._debugOwner = element._owner;
13708 }
13709
13710 return existing;
13711 }
13712 } // Insert
13713
13714
13715 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
13716 created.ref = coerceRef(returnFiber, current, element);
13717 created.return = returnFiber;
13718 return created;
13719 }
13720
13721 function updatePortal(returnFiber, current, portal, expirationTime) {
13722 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
13723 // Insert
13724 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
13725 created.return = returnFiber;
13726 return created;
13727 } else {
13728 // Update
13729 var existing = useFiber(current, portal.children || []);
13730 existing.return = returnFiber;
13731 return existing;
13732 }
13733 }
13734
13735 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
13736 if (current === null || current.tag !== Fragment) {
13737 // Insert
13738 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
13739 created.return = returnFiber;
13740 return created;
13741 } else {
13742 // Update
13743 var existing = useFiber(current, fragment);
13744 existing.return = returnFiber;
13745 return existing;
13746 }
13747 }
13748
13749 function createChild(returnFiber, newChild, expirationTime) {
13750 if (typeof newChild === 'string' || typeof newChild === 'number') {
13751 // Text nodes don't have keys. If the previous node is implicitly keyed
13752 // we can continue to replace it without aborting even if it is not a text
13753 // node.
13754 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
13755 created.return = returnFiber;
13756 return created;
13757 }
13758
13759 if (typeof newChild === 'object' && newChild !== null) {
13760 switch (newChild.$$typeof) {
13761 case REACT_ELEMENT_TYPE:
13762 {
13763 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
13764
13765 _created.ref = coerceRef(returnFiber, null, newChild);
13766 _created.return = returnFiber;
13767 return _created;
13768 }
13769
13770 case REACT_PORTAL_TYPE:
13771 {
13772 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
13773
13774 _created2.return = returnFiber;
13775 return _created2;
13776 }
13777 }
13778
13779 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13780 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
13781
13782 _created3.return = returnFiber;
13783 return _created3;
13784 }
13785
13786 throwOnInvalidObjectType(returnFiber, newChild);
13787 }
13788
13789 {
13790 if (typeof newChild === 'function') {
13791 warnOnFunctionType();
13792 }
13793 }
13794
13795 return null;
13796 }
13797
13798 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
13799 // Update the fiber if the keys match, otherwise return null.
13800 var key = oldFiber !== null ? oldFiber.key : null;
13801
13802 if (typeof newChild === 'string' || typeof newChild === 'number') {
13803 // Text nodes don't have keys. If the previous node is implicitly keyed
13804 // we can continue to replace it without aborting even if it is not a text
13805 // node.
13806 if (key !== null) {
13807 return null;
13808 }
13809
13810 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
13811 }
13812
13813 if (typeof newChild === 'object' && newChild !== null) {
13814 switch (newChild.$$typeof) {
13815 case REACT_ELEMENT_TYPE:
13816 {
13817 if (newChild.key === key) {
13818 if (newChild.type === REACT_FRAGMENT_TYPE) {
13819 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
13820 }
13821
13822 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
13823 } else {
13824 return null;
13825 }
13826 }
13827
13828 case REACT_PORTAL_TYPE:
13829 {
13830 if (newChild.key === key) {
13831 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
13832 } else {
13833 return null;
13834 }
13835 }
13836 }
13837
13838 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13839 if (key !== null) {
13840 return null;
13841 }
13842
13843 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
13844 }
13845
13846 throwOnInvalidObjectType(returnFiber, newChild);
13847 }
13848
13849 {
13850 if (typeof newChild === 'function') {
13851 warnOnFunctionType();
13852 }
13853 }
13854
13855 return null;
13856 }
13857
13858 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
13859 if (typeof newChild === 'string' || typeof newChild === 'number') {
13860 // Text nodes don't have keys, so we neither have to check the old nor
13861 // new node for the key. If both are text nodes, they match.
13862 var matchedFiber = existingChildren.get(newIdx) || null;
13863 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
13864 }
13865
13866 if (typeof newChild === 'object' && newChild !== null) {
13867 switch (newChild.$$typeof) {
13868 case REACT_ELEMENT_TYPE:
13869 {
13870 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13871
13872 if (newChild.type === REACT_FRAGMENT_TYPE) {
13873 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
13874 }
13875
13876 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
13877 }
13878
13879 case REACT_PORTAL_TYPE:
13880 {
13881 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
13882
13883 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
13884 }
13885 }
13886
13887 if (isArray$1(newChild) || getIteratorFn(newChild)) {
13888 var _matchedFiber3 = existingChildren.get(newIdx) || null;
13889
13890 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
13891 }
13892
13893 throwOnInvalidObjectType(returnFiber, newChild);
13894 }
13895
13896 {
13897 if (typeof newChild === 'function') {
13898 warnOnFunctionType();
13899 }
13900 }
13901
13902 return null;
13903 }
13904 /**
13905 * Warns if there is a duplicate or missing key
13906 */
13907
13908
13909 function warnOnInvalidKey(child, knownKeys) {
13910 {
13911 if (typeof child !== 'object' || child === null) {
13912 return knownKeys;
13913 }
13914
13915 switch (child.$$typeof) {
13916 case REACT_ELEMENT_TYPE:
13917 case REACT_PORTAL_TYPE:
13918 warnForMissingKey(child);
13919 var key = child.key;
13920
13921 if (typeof key !== 'string') {
13922 break;
13923 }
13924
13925 if (knownKeys === null) {
13926 knownKeys = new Set();
13927 knownKeys.add(key);
13928 break;
13929 }
13930
13931 if (!knownKeys.has(key)) {
13932 knownKeys.add(key);
13933 break;
13934 }
13935
13936 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);
13937
13938 break;
13939 }
13940 }
13941
13942 return knownKeys;
13943 }
13944
13945 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
13946 // This algorithm can't optimize by searching from both ends since we
13947 // don't have backpointers on fibers. I'm trying to see how far we can get
13948 // with that model. If it ends up not being worth the tradeoffs, we can
13949 // add it later.
13950 // Even with a two ended optimization, we'd want to optimize for the case
13951 // where there are few changes and brute force the comparison instead of
13952 // going for the Map. It'd like to explore hitting that path first in
13953 // forward-only mode and only go for the Map once we notice that we need
13954 // lots of look ahead. This doesn't handle reversal as well as two ended
13955 // search but that's unusual. Besides, for the two ended optimization to
13956 // work on Iterables, we'd need to copy the whole set.
13957 // In this first iteration, we'll just live with hitting the bad case
13958 // (adding everything to a Map) in for every insert/move.
13959 // If you change this code, also update reconcileChildrenIterator() which
13960 // uses the same algorithm.
13961 {
13962 // First, validate keys.
13963 var knownKeys = null;
13964
13965 for (var i = 0; i < newChildren.length; i++) {
13966 var child = newChildren[i];
13967 knownKeys = warnOnInvalidKey(child, knownKeys);
13968 }
13969 }
13970
13971 var resultingFirstChild = null;
13972 var previousNewFiber = null;
13973 var oldFiber = currentFirstChild;
13974 var lastPlacedIndex = 0;
13975 var newIdx = 0;
13976 var nextOldFiber = null;
13977
13978 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
13979 if (oldFiber.index > newIdx) {
13980 nextOldFiber = oldFiber;
13981 oldFiber = null;
13982 } else {
13983 nextOldFiber = oldFiber.sibling;
13984 }
13985
13986 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
13987
13988 if (newFiber === null) {
13989 // TODO: This breaks on empty slots like null children. That's
13990 // unfortunate because it triggers the slow path all the time. We need
13991 // a better way to communicate whether this was a miss or null,
13992 // boolean, undefined, etc.
13993 if (oldFiber === null) {
13994 oldFiber = nextOldFiber;
13995 }
13996
13997 break;
13998 }
13999
14000 if (shouldTrackSideEffects) {
14001 if (oldFiber && newFiber.alternate === null) {
14002 // We matched the slot, but we didn't reuse the existing fiber, so we
14003 // need to delete the existing child.
14004 deleteChild(returnFiber, oldFiber);
14005 }
14006 }
14007
14008 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14009
14010 if (previousNewFiber === null) {
14011 // TODO: Move out of the loop. This only happens for the first run.
14012 resultingFirstChild = newFiber;
14013 } else {
14014 // TODO: Defer siblings if we're not at the right index for this slot.
14015 // I.e. if we had null values before, then we want to defer this
14016 // for each null value. However, we also don't want to call updateSlot
14017 // with the previous one.
14018 previousNewFiber.sibling = newFiber;
14019 }
14020
14021 previousNewFiber = newFiber;
14022 oldFiber = nextOldFiber;
14023 }
14024
14025 if (newIdx === newChildren.length) {
14026 // We've reached the end of the new children. We can delete the rest.
14027 deleteRemainingChildren(returnFiber, oldFiber);
14028 return resultingFirstChild;
14029 }
14030
14031 if (oldFiber === null) {
14032 // If we don't have any more existing children we can choose a fast path
14033 // since the rest will all be insertions.
14034 for (; newIdx < newChildren.length; newIdx++) {
14035 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
14036
14037 if (_newFiber === null) {
14038 continue;
14039 }
14040
14041 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
14042
14043 if (previousNewFiber === null) {
14044 // TODO: Move out of the loop. This only happens for the first run.
14045 resultingFirstChild = _newFiber;
14046 } else {
14047 previousNewFiber.sibling = _newFiber;
14048 }
14049
14050 previousNewFiber = _newFiber;
14051 }
14052
14053 return resultingFirstChild;
14054 } // Add all children to a key map for quick lookups.
14055
14056
14057 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
14058
14059 for (; newIdx < newChildren.length; newIdx++) {
14060 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
14061
14062 if (_newFiber2 !== null) {
14063 if (shouldTrackSideEffects) {
14064 if (_newFiber2.alternate !== null) {
14065 // The new fiber is a work in progress, but if there exists a
14066 // current, that means that we reused the fiber. We need to delete
14067 // it from the child list so that we don't add it to the deletion
14068 // list.
14069 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
14070 }
14071 }
14072
14073 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
14074
14075 if (previousNewFiber === null) {
14076 resultingFirstChild = _newFiber2;
14077 } else {
14078 previousNewFiber.sibling = _newFiber2;
14079 }
14080
14081 previousNewFiber = _newFiber2;
14082 }
14083 }
14084
14085 if (shouldTrackSideEffects) {
14086 // Any existing children that weren't consumed above were deleted. We need
14087 // to add them to the deletion list.
14088 existingChildren.forEach(function (child) {
14089 return deleteChild(returnFiber, child);
14090 });
14091 }
14092
14093 return resultingFirstChild;
14094 }
14095
14096 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
14097 // This is the same implementation as reconcileChildrenArray(),
14098 // but using the iterator instead.
14099 var iteratorFn = getIteratorFn(newChildrenIterable);
14100
14101 if (!(typeof iteratorFn === 'function')) {
14102 {
14103 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
14104 }
14105 }
14106
14107 {
14108 // We don't support rendering Generators because it's a mutation.
14109 // See https://github.com/facebook/react/issues/12995
14110 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
14111 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
14112 if (!didWarnAboutGenerators) {
14113 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.');
14114 }
14115
14116 didWarnAboutGenerators = true;
14117 } // Warn about using Maps as children
14118
14119
14120 if (newChildrenIterable.entries === iteratorFn) {
14121 if (!didWarnAboutMaps) {
14122 error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');
14123 }
14124
14125 didWarnAboutMaps = true;
14126 } // First, validate keys.
14127 // We'll get a different iterator later for the main pass.
14128
14129
14130 var _newChildren = iteratorFn.call(newChildrenIterable);
14131
14132 if (_newChildren) {
14133 var knownKeys = null;
14134
14135 var _step = _newChildren.next();
14136
14137 for (; !_step.done; _step = _newChildren.next()) {
14138 var child = _step.value;
14139 knownKeys = warnOnInvalidKey(child, knownKeys);
14140 }
14141 }
14142 }
14143
14144 var newChildren = iteratorFn.call(newChildrenIterable);
14145
14146 if (!(newChildren != null)) {
14147 {
14148 throw Error( "An iterable object provided no iterator." );
14149 }
14150 }
14151
14152 var resultingFirstChild = null;
14153 var previousNewFiber = null;
14154 var oldFiber = currentFirstChild;
14155 var lastPlacedIndex = 0;
14156 var newIdx = 0;
14157 var nextOldFiber = null;
14158 var step = newChildren.next();
14159
14160 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
14161 if (oldFiber.index > newIdx) {
14162 nextOldFiber = oldFiber;
14163 oldFiber = null;
14164 } else {
14165 nextOldFiber = oldFiber.sibling;
14166 }
14167
14168 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
14169
14170 if (newFiber === null) {
14171 // TODO: This breaks on empty slots like null children. That's
14172 // unfortunate because it triggers the slow path all the time. We need
14173 // a better way to communicate whether this was a miss or null,
14174 // boolean, undefined, etc.
14175 if (oldFiber === null) {
14176 oldFiber = nextOldFiber;
14177 }
14178
14179 break;
14180 }
14181
14182 if (shouldTrackSideEffects) {
14183 if (oldFiber && newFiber.alternate === null) {
14184 // We matched the slot, but we didn't reuse the existing fiber, so we
14185 // need to delete the existing child.
14186 deleteChild(returnFiber, oldFiber);
14187 }
14188 }
14189
14190 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14191
14192 if (previousNewFiber === null) {
14193 // TODO: Move out of the loop. This only happens for the first run.
14194 resultingFirstChild = newFiber;
14195 } else {
14196 // TODO: Defer siblings if we're not at the right index for this slot.
14197 // I.e. if we had null values before, then we want to defer this
14198 // for each null value. However, we also don't want to call updateSlot
14199 // with the previous one.
14200 previousNewFiber.sibling = newFiber;
14201 }
14202
14203 previousNewFiber = newFiber;
14204 oldFiber = nextOldFiber;
14205 }
14206
14207 if (step.done) {
14208 // We've reached the end of the new children. We can delete the rest.
14209 deleteRemainingChildren(returnFiber, oldFiber);
14210 return resultingFirstChild;
14211 }
14212
14213 if (oldFiber === null) {
14214 // If we don't have any more existing children we can choose a fast path
14215 // since the rest will all be insertions.
14216 for (; !step.done; newIdx++, step = newChildren.next()) {
14217 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
14218
14219 if (_newFiber3 === null) {
14220 continue;
14221 }
14222
14223 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
14224
14225 if (previousNewFiber === null) {
14226 // TODO: Move out of the loop. This only happens for the first run.
14227 resultingFirstChild = _newFiber3;
14228 } else {
14229 previousNewFiber.sibling = _newFiber3;
14230 }
14231
14232 previousNewFiber = _newFiber3;
14233 }
14234
14235 return resultingFirstChild;
14236 } // Add all children to a key map for quick lookups.
14237
14238
14239 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
14240
14241 for (; !step.done; newIdx++, step = newChildren.next()) {
14242 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
14243
14244 if (_newFiber4 !== null) {
14245 if (shouldTrackSideEffects) {
14246 if (_newFiber4.alternate !== null) {
14247 // The new fiber is a work in progress, but if there exists a
14248 // current, that means that we reused the fiber. We need to delete
14249 // it from the child list so that we don't add it to the deletion
14250 // list.
14251 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
14252 }
14253 }
14254
14255 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
14256
14257 if (previousNewFiber === null) {
14258 resultingFirstChild = _newFiber4;
14259 } else {
14260 previousNewFiber.sibling = _newFiber4;
14261 }
14262
14263 previousNewFiber = _newFiber4;
14264 }
14265 }
14266
14267 if (shouldTrackSideEffects) {
14268 // Any existing children that weren't consumed above were deleted. We need
14269 // to add them to the deletion list.
14270 existingChildren.forEach(function (child) {
14271 return deleteChild(returnFiber, child);
14272 });
14273 }
14274
14275 return resultingFirstChild;
14276 }
14277
14278 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
14279 // There's no need to check for keys on text nodes since we don't have a
14280 // way to define them.
14281 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
14282 // We already have an existing node so let's just update it and delete
14283 // the rest.
14284 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
14285 var existing = useFiber(currentFirstChild, textContent);
14286 existing.return = returnFiber;
14287 return existing;
14288 } // The existing first child is not a text node so we need to create one
14289 // and delete the existing ones.
14290
14291
14292 deleteRemainingChildren(returnFiber, currentFirstChild);
14293 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
14294 created.return = returnFiber;
14295 return created;
14296 }
14297
14298 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
14299 var key = element.key;
14300 var child = currentFirstChild;
14301
14302 while (child !== null) {
14303 // TODO: If key === null and child.key === null, then this only applies to
14304 // the first item in the list.
14305 if (child.key === key) {
14306 switch (child.tag) {
14307 case Fragment:
14308 {
14309 if (element.type === REACT_FRAGMENT_TYPE) {
14310 deleteRemainingChildren(returnFiber, child.sibling);
14311 var existing = useFiber(child, element.props.children);
14312 existing.return = returnFiber;
14313
14314 {
14315 existing._debugSource = element._source;
14316 existing._debugOwner = element._owner;
14317 }
14318
14319 return existing;
14320 }
14321
14322 break;
14323 }
14324
14325 case Block:
14326
14327 // We intentionally fallthrough here if enableBlocksAPI is not on.
14328 // eslint-disable-next-lined no-fallthrough
14329
14330 default:
14331 {
14332 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
14333 isCompatibleFamilyForHotReloading(child, element) )) {
14334 deleteRemainingChildren(returnFiber, child.sibling);
14335
14336 var _existing3 = useFiber(child, element.props);
14337
14338 _existing3.ref = coerceRef(returnFiber, child, element);
14339 _existing3.return = returnFiber;
14340
14341 {
14342 _existing3._debugSource = element._source;
14343 _existing3._debugOwner = element._owner;
14344 }
14345
14346 return _existing3;
14347 }
14348
14349 break;
14350 }
14351 } // Didn't match.
14352
14353
14354 deleteRemainingChildren(returnFiber, child);
14355 break;
14356 } else {
14357 deleteChild(returnFiber, child);
14358 }
14359
14360 child = child.sibling;
14361 }
14362
14363 if (element.type === REACT_FRAGMENT_TYPE) {
14364 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
14365 created.return = returnFiber;
14366 return created;
14367 } else {
14368 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
14369
14370 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
14371 _created4.return = returnFiber;
14372 return _created4;
14373 }
14374 }
14375
14376 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
14377 var key = portal.key;
14378 var child = currentFirstChild;
14379
14380 while (child !== null) {
14381 // TODO: If key === null and child.key === null, then this only applies to
14382 // the first item in the list.
14383 if (child.key === key) {
14384 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
14385 deleteRemainingChildren(returnFiber, child.sibling);
14386 var existing = useFiber(child, portal.children || []);
14387 existing.return = returnFiber;
14388 return existing;
14389 } else {
14390 deleteRemainingChildren(returnFiber, child);
14391 break;
14392 }
14393 } else {
14394 deleteChild(returnFiber, child);
14395 }
14396
14397 child = child.sibling;
14398 }
14399
14400 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
14401 created.return = returnFiber;
14402 return created;
14403 } // This API will tag the children with the side-effect of the reconciliation
14404 // itself. They will be added to the side-effect list as we pass through the
14405 // children and the parent.
14406
14407
14408 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
14409 // This function is not recursive.
14410 // If the top level item is an array, we treat it as a set of children,
14411 // not as a fragment. Nested arrays on the other hand will be treated as
14412 // fragment nodes. Recursion happens at the normal flow.
14413 // Handle top level unkeyed fragments as if they were arrays.
14414 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14415 // We treat the ambiguous cases above the same.
14416 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
14417
14418 if (isUnkeyedTopLevelFragment) {
14419 newChild = newChild.props.children;
14420 } // Handle object types
14421
14422
14423 var isObject = typeof newChild === 'object' && newChild !== null;
14424
14425 if (isObject) {
14426 switch (newChild.$$typeof) {
14427 case REACT_ELEMENT_TYPE:
14428 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
14429
14430 case REACT_PORTAL_TYPE:
14431 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
14432 }
14433 }
14434
14435 if (typeof newChild === 'string' || typeof newChild === 'number') {
14436 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
14437 }
14438
14439 if (isArray$1(newChild)) {
14440 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
14441 }
14442
14443 if (getIteratorFn(newChild)) {
14444 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
14445 }
14446
14447 if (isObject) {
14448 throwOnInvalidObjectType(returnFiber, newChild);
14449 }
14450
14451 {
14452 if (typeof newChild === 'function') {
14453 warnOnFunctionType();
14454 }
14455 }
14456
14457 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14458 // If the new child is undefined, and the return fiber is a composite
14459 // component, throw an error. If Fiber return types are disabled,
14460 // we already threw above.
14461 switch (returnFiber.tag) {
14462 case ClassComponent:
14463 {
14464 {
14465 var instance = returnFiber.stateNode;
14466
14467 if (instance.render._isMockFunction) {
14468 // We allow auto-mocks to proceed as if they're returning null.
14469 break;
14470 }
14471 }
14472 }
14473 // Intentionally fall through to the next case, which handles both
14474 // functions and classes
14475 // eslint-disable-next-lined no-fallthrough
14476
14477 case FunctionComponent:
14478 {
14479 var Component = returnFiber.type;
14480
14481 {
14482 {
14483 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." );
14484 }
14485 }
14486 }
14487 }
14488 } // Remaining cases are all treated as empty.
14489
14490
14491 return deleteRemainingChildren(returnFiber, currentFirstChild);
14492 }
14493
14494 return reconcileChildFibers;
14495 }
14496
14497 var reconcileChildFibers = ChildReconciler(true);
14498 var mountChildFibers = ChildReconciler(false);
14499 function cloneChildFibers(current, workInProgress) {
14500 if (!(current === null || workInProgress.child === current.child)) {
14501 {
14502 throw Error( "Resuming work not yet implemented." );
14503 }
14504 }
14505
14506 if (workInProgress.child === null) {
14507 return;
14508 }
14509
14510 var currentChild = workInProgress.child;
14511 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
14512 workInProgress.child = newChild;
14513 newChild.return = workInProgress;
14514
14515 while (currentChild.sibling !== null) {
14516 currentChild = currentChild.sibling;
14517 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
14518 newChild.return = workInProgress;
14519 }
14520
14521 newChild.sibling = null;
14522 } // Reset a workInProgress child set to prepare it for a second pass.
14523
14524 function resetChildFibers(workInProgress, renderExpirationTime) {
14525 var child = workInProgress.child;
14526
14527 while (child !== null) {
14528 resetWorkInProgress(child, renderExpirationTime);
14529 child = child.sibling;
14530 }
14531 }
14532
14533 var NO_CONTEXT = {};
14534 var contextStackCursor$1 = createCursor(NO_CONTEXT);
14535 var contextFiberStackCursor = createCursor(NO_CONTEXT);
14536 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
14537
14538 function requiredContext(c) {
14539 if (!(c !== NO_CONTEXT)) {
14540 {
14541 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
14542 }
14543 }
14544
14545 return c;
14546 }
14547
14548 function getRootHostContainer() {
14549 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14550 return rootInstance;
14551 }
14552
14553 function pushHostContainer(fiber, nextRootInstance) {
14554 // Push current root instance onto the stack;
14555 // This allows us to reset root when portals are popped.
14556 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
14557 // This enables us to pop only Fibers that provide unique contexts.
14558
14559 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
14560 // However, we can't just call getRootHostContext() and push it because
14561 // we'd have a different number of entries on the stack depending on
14562 // whether getRootHostContext() throws somewhere in renderer code or not.
14563 // So we push an empty value first. This lets us safely unwind on errors.
14564
14565 push(contextStackCursor$1, NO_CONTEXT, fiber);
14566 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
14567
14568 pop(contextStackCursor$1, fiber);
14569 push(contextStackCursor$1, nextRootContext, fiber);
14570 }
14571
14572 function popHostContainer(fiber) {
14573 pop(contextStackCursor$1, fiber);
14574 pop(contextFiberStackCursor, fiber);
14575 pop(rootInstanceStackCursor, fiber);
14576 }
14577
14578 function getHostContext() {
14579 var context = requiredContext(contextStackCursor$1.current);
14580 return context;
14581 }
14582
14583 function pushHostContext(fiber) {
14584 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14585 var context = requiredContext(contextStackCursor$1.current);
14586 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
14587
14588 if (context === nextContext) {
14589 return;
14590 } // Track the context and the Fiber that provided it.
14591 // This enables us to pop only Fibers that provide unique contexts.
14592
14593
14594 push(contextFiberStackCursor, fiber, fiber);
14595 push(contextStackCursor$1, nextContext, fiber);
14596 }
14597
14598 function popHostContext(fiber) {
14599 // Do not pop unless this Fiber provided the current context.
14600 // pushHostContext() only pushes Fibers that provide unique contexts.
14601 if (contextFiberStackCursor.current !== fiber) {
14602 return;
14603 }
14604
14605 pop(contextStackCursor$1, fiber);
14606 pop(contextFiberStackCursor, fiber);
14607 }
14608
14609 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
14610 // inherited deeply down the subtree. The upper bits only affect
14611 // this immediate suspense boundary and gets reset each new
14612 // boundary or suspense list.
14613
14614 var SubtreeSuspenseContextMask = 1; // Subtree Flags:
14615 // InvisibleParentSuspenseContext indicates that one of our parent Suspense
14616 // boundaries is not currently showing visible main content.
14617 // Either because it is already showing a fallback or is not mounted at all.
14618 // We can use this to determine if it is desirable to trigger a fallback at
14619 // the parent. If not, then we might need to trigger undesirable boundaries
14620 // and/or suspend the commit to avoid hiding the parent content.
14621
14622 var InvisibleParentSuspenseContext = 1; // Shallow Flags:
14623 // ForceSuspenseFallback can be used by SuspenseList to force newly added
14624 // items into their fallback state during one of the render passes.
14625
14626 var ForceSuspenseFallback = 2;
14627 var suspenseStackCursor = createCursor(DefaultSuspenseContext);
14628 function hasSuspenseContext(parentContext, flag) {
14629 return (parentContext & flag) !== 0;
14630 }
14631 function setDefaultShallowSuspenseContext(parentContext) {
14632 return parentContext & SubtreeSuspenseContextMask;
14633 }
14634 function setShallowSuspenseContext(parentContext, shallowContext) {
14635 return parentContext & SubtreeSuspenseContextMask | shallowContext;
14636 }
14637 function addSubtreeSuspenseContext(parentContext, subtreeContext) {
14638 return parentContext | subtreeContext;
14639 }
14640 function pushSuspenseContext(fiber, newContext) {
14641 push(suspenseStackCursor, newContext, fiber);
14642 }
14643 function popSuspenseContext(fiber) {
14644 pop(suspenseStackCursor, fiber);
14645 }
14646
14647 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
14648 // If it was the primary children that just suspended, capture and render the
14649 // fallback. Otherwise, don't capture and bubble to the next boundary.
14650 var nextState = workInProgress.memoizedState;
14651
14652 if (nextState !== null) {
14653 if (nextState.dehydrated !== null) {
14654 // A dehydrated boundary always captures.
14655 return true;
14656 }
14657
14658 return false;
14659 }
14660
14661 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
14662
14663 if (props.fallback === undefined) {
14664 return false;
14665 } // Regular boundaries always capture.
14666
14667
14668 if (props.unstable_avoidThisFallback !== true) {
14669 return true;
14670 } // If it's a boundary we should avoid, then we prefer to bubble up to the
14671 // parent boundary if it is currently invisible.
14672
14673
14674 if (hasInvisibleParent) {
14675 return false;
14676 } // If the parent is not able to handle it, we must handle it.
14677
14678
14679 return true;
14680 }
14681 function findFirstSuspended(row) {
14682 var node = row;
14683
14684 while (node !== null) {
14685 if (node.tag === SuspenseComponent) {
14686 var state = node.memoizedState;
14687
14688 if (state !== null) {
14689 var dehydrated = state.dehydrated;
14690
14691 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
14692 return node;
14693 }
14694 }
14695 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
14696 // keep track of whether it suspended or not.
14697 node.memoizedProps.revealOrder !== undefined) {
14698 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
14699
14700 if (didSuspend) {
14701 return node;
14702 }
14703 } else if (node.child !== null) {
14704 node.child.return = node;
14705 node = node.child;
14706 continue;
14707 }
14708
14709 if (node === row) {
14710 return null;
14711 }
14712
14713 while (node.sibling === null) {
14714 if (node.return === null || node.return === row) {
14715 return null;
14716 }
14717
14718 node = node.return;
14719 }
14720
14721 node.sibling.return = node.return;
14722 node = node.sibling;
14723 }
14724
14725 return null;
14726 }
14727
14728 function createDeprecatedResponderListener(responder, props) {
14729 var eventResponderListener = {
14730 responder: responder,
14731 props: props
14732 };
14733
14734 {
14735 Object.freeze(eventResponderListener);
14736 }
14737
14738 return eventResponderListener;
14739 }
14740
14741 var HasEffect =
14742 /* */
14743 1; // Represents the phase in which the effect (not the clean-up) fires.
14744
14745 var Layout =
14746 /* */
14747 2;
14748 var Passive$1 =
14749 /* */
14750 4;
14751
14752 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
14753 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
14754 var didWarnAboutMismatchedHooksForComponent;
14755
14756 {
14757 didWarnAboutMismatchedHooksForComponent = new Set();
14758 }
14759
14760 // These are set right before calling the component.
14761 var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
14762 // the work-in-progress hook.
14763
14764 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
14765 // current hook list is the list that belongs to the current fiber. The
14766 // work-in-progress hook list is a new list that will be added to the
14767 // work-in-progress fiber.
14768
14769 var currentHook = null;
14770 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
14771 // does not get reset if we do another render pass; only when we're completely
14772 // finished evaluating this component. This is an optimization so we know
14773 // whether we need to clear render phase updates after a throw.
14774
14775 var didScheduleRenderPhaseUpdate = false;
14776 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
14777
14778 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
14779 // The list stores the order of hooks used during the initial render (mount).
14780 // Subsequent renders (updates) reference this list.
14781
14782 var hookTypesDev = null;
14783 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
14784 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
14785 // When true, such Hooks will always be "remounted". Only used during hot reload.
14786
14787 var ignorePreviousDependencies = false;
14788
14789 function mountHookTypesDev() {
14790 {
14791 var hookName = currentHookNameInDev;
14792
14793 if (hookTypesDev === null) {
14794 hookTypesDev = [hookName];
14795 } else {
14796 hookTypesDev.push(hookName);
14797 }
14798 }
14799 }
14800
14801 function updateHookTypesDev() {
14802 {
14803 var hookName = currentHookNameInDev;
14804
14805 if (hookTypesDev !== null) {
14806 hookTypesUpdateIndexDev++;
14807
14808 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
14809 warnOnHookMismatchInDev(hookName);
14810 }
14811 }
14812 }
14813 }
14814
14815 function checkDepsAreArrayDev(deps) {
14816 {
14817 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
14818 // Verify deps, but only on mount to avoid extra checks.
14819 // It's unlikely their type would change as usually you define them inline.
14820 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);
14821 }
14822 }
14823 }
14824
14825 function warnOnHookMismatchInDev(currentHookName) {
14826 {
14827 var componentName = getComponentName(currentlyRenderingFiber$1.type);
14828
14829 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
14830 didWarnAboutMismatchedHooksForComponent.add(componentName);
14831
14832 if (hookTypesDev !== null) {
14833 var table = '';
14834 var secondColumnStart = 30;
14835
14836 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
14837 var oldHookName = hookTypesDev[i];
14838 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
14839 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
14840 // lol @ IE not supporting String#repeat
14841
14842 while (row.length < secondColumnStart) {
14843 row += ' ';
14844 }
14845
14846 row += newHookName + '\n';
14847 table += row;
14848 }
14849
14850 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);
14851 }
14852 }
14853 }
14854 }
14855
14856 function throwInvalidHookError() {
14857 {
14858 {
14859 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." );
14860 }
14861 }
14862 }
14863
14864 function areHookInputsEqual(nextDeps, prevDeps) {
14865 {
14866 if (ignorePreviousDependencies) {
14867 // Only true when this component is being hot reloaded.
14868 return false;
14869 }
14870 }
14871
14872 if (prevDeps === null) {
14873 {
14874 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);
14875 }
14876
14877 return false;
14878 }
14879
14880 {
14881 // Don't bother comparing lengths in prod because these arrays should be
14882 // passed inline.
14883 if (nextDeps.length !== prevDeps.length) {
14884 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(', ') + "]");
14885 }
14886 }
14887
14888 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
14889 if (objectIs(nextDeps[i], prevDeps[i])) {
14890 continue;
14891 }
14892
14893 return false;
14894 }
14895
14896 return true;
14897 }
14898
14899 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {
14900 renderExpirationTime = nextRenderExpirationTime;
14901 currentlyRenderingFiber$1 = workInProgress;
14902
14903 {
14904 hookTypesDev = current !== null ? current._debugHookTypes : null;
14905 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
14906
14907 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
14908 }
14909
14910 workInProgress.memoizedState = null;
14911 workInProgress.updateQueue = null;
14912 workInProgress.expirationTime = NoWork; // The following should have already been reset
14913 // currentHook = null;
14914 // workInProgressHook = null;
14915 // didScheduleRenderPhaseUpdate = false;
14916 // TODO Warn if no hooks are used at all during mount, then some are used during update.
14917 // Currently we will identify the update render as a mount because memoizedState === null.
14918 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
14919 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
14920 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
14921 // so memoizedState would be null during updates and mounts.
14922
14923 {
14924 if (current !== null && current.memoizedState !== null) {
14925 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
14926 } else if (hookTypesDev !== null) {
14927 // This dispatcher handles an edge case where a component is updating,
14928 // but no stateful hooks have been used.
14929 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
14930 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
14931 // This dispatcher does that.
14932 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
14933 } else {
14934 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
14935 }
14936 }
14937
14938 var children = Component(props, secondArg); // Check if there was a render phase update
14939
14940 if (workInProgress.expirationTime === renderExpirationTime) {
14941 // Keep rendering in a loop for as long as render phase updates continue to
14942 // be scheduled. Use a counter to prevent infinite loops.
14943 var numberOfReRenders = 0;
14944
14945 do {
14946 workInProgress.expirationTime = NoWork;
14947
14948 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
14949 {
14950 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
14951 }
14952 }
14953
14954 numberOfReRenders += 1;
14955
14956 {
14957 // Even when hot reloading, allow dependencies to stabilize
14958 // after first render to prevent infinite render phase updates.
14959 ignorePreviousDependencies = false;
14960 } // Start over from the beginning of the list
14961
14962
14963 currentHook = null;
14964 workInProgressHook = null;
14965 workInProgress.updateQueue = null;
14966
14967 {
14968 // Also validate hook order for cascading updates.
14969 hookTypesUpdateIndexDev = -1;
14970 }
14971
14972 ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV ;
14973 children = Component(props, secondArg);
14974 } while (workInProgress.expirationTime === renderExpirationTime);
14975 } // We can assume the previous dispatcher is always this one, since we set it
14976 // at the beginning of the render phase and there's no re-entrancy.
14977
14978
14979 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
14980
14981 {
14982 workInProgress._debugHookTypes = hookTypesDev;
14983 } // This check uses currentHook so that it works the same in DEV and prod bundles.
14984 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
14985
14986
14987 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
14988 renderExpirationTime = NoWork;
14989 currentlyRenderingFiber$1 = null;
14990 currentHook = null;
14991 workInProgressHook = null;
14992
14993 {
14994 currentHookNameInDev = null;
14995 hookTypesDev = null;
14996 hookTypesUpdateIndexDev = -1;
14997 }
14998
14999 didScheduleRenderPhaseUpdate = false;
15000
15001 if (!!didRenderTooFewHooks) {
15002 {
15003 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
15004 }
15005 }
15006
15007 return children;
15008 }
15009 function bailoutHooks(current, workInProgress, expirationTime) {
15010 workInProgress.updateQueue = current.updateQueue;
15011 workInProgress.effectTag &= ~(Passive | Update);
15012
15013 if (current.expirationTime <= expirationTime) {
15014 current.expirationTime = NoWork;
15015 }
15016 }
15017 function resetHooksAfterThrow() {
15018 // We can assume the previous dispatcher is always this one, since we set it
15019 // at the beginning of the render phase and there's no re-entrancy.
15020 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
15021
15022 if (didScheduleRenderPhaseUpdate) {
15023 // There were render phase updates. These are only valid for this render
15024 // phase, which we are now aborting. Remove the updates from the queues so
15025 // they do not persist to the next render. Do not remove updates from hooks
15026 // that weren't processed.
15027 //
15028 // Only reset the updates from the queue if it has a clone. If it does
15029 // not have a clone, that means it wasn't processed, and the updates were
15030 // scheduled before we entered the render phase.
15031 var hook = currentlyRenderingFiber$1.memoizedState;
15032
15033 while (hook !== null) {
15034 var queue = hook.queue;
15035
15036 if (queue !== null) {
15037 queue.pending = null;
15038 }
15039
15040 hook = hook.next;
15041 }
15042 }
15043
15044 renderExpirationTime = NoWork;
15045 currentlyRenderingFiber$1 = null;
15046 currentHook = null;
15047 workInProgressHook = null;
15048
15049 {
15050 hookTypesDev = null;
15051 hookTypesUpdateIndexDev = -1;
15052 currentHookNameInDev = null;
15053 }
15054
15055 didScheduleRenderPhaseUpdate = false;
15056 }
15057
15058 function mountWorkInProgressHook() {
15059 var hook = {
15060 memoizedState: null,
15061 baseState: null,
15062 baseQueue: null,
15063 queue: null,
15064 next: null
15065 };
15066
15067 if (workInProgressHook === null) {
15068 // This is the first hook in the list
15069 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
15070 } else {
15071 // Append to the end of the list
15072 workInProgressHook = workInProgressHook.next = hook;
15073 }
15074
15075 return workInProgressHook;
15076 }
15077
15078 function updateWorkInProgressHook() {
15079 // This function is used both for updates and for re-renders triggered by a
15080 // render phase update. It assumes there is either a current hook we can
15081 // clone, or a work-in-progress hook from a previous render pass that we can
15082 // use as a base. When we reach the end of the base list, we must switch to
15083 // the dispatcher used for mounts.
15084 var nextCurrentHook;
15085
15086 if (currentHook === null) {
15087 var current = currentlyRenderingFiber$1.alternate;
15088
15089 if (current !== null) {
15090 nextCurrentHook = current.memoizedState;
15091 } else {
15092 nextCurrentHook = null;
15093 }
15094 } else {
15095 nextCurrentHook = currentHook.next;
15096 }
15097
15098 var nextWorkInProgressHook;
15099
15100 if (workInProgressHook === null) {
15101 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
15102 } else {
15103 nextWorkInProgressHook = workInProgressHook.next;
15104 }
15105
15106 if (nextWorkInProgressHook !== null) {
15107 // There's already a work-in-progress. Reuse it.
15108 workInProgressHook = nextWorkInProgressHook;
15109 nextWorkInProgressHook = workInProgressHook.next;
15110 currentHook = nextCurrentHook;
15111 } else {
15112 // Clone from the current hook.
15113 if (!(nextCurrentHook !== null)) {
15114 {
15115 throw Error( "Rendered more hooks than during the previous render." );
15116 }
15117 }
15118
15119 currentHook = nextCurrentHook;
15120 var newHook = {
15121 memoizedState: currentHook.memoizedState,
15122 baseState: currentHook.baseState,
15123 baseQueue: currentHook.baseQueue,
15124 queue: currentHook.queue,
15125 next: null
15126 };
15127
15128 if (workInProgressHook === null) {
15129 // This is the first hook in the list.
15130 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
15131 } else {
15132 // Append to the end of the list.
15133 workInProgressHook = workInProgressHook.next = newHook;
15134 }
15135 }
15136
15137 return workInProgressHook;
15138 }
15139
15140 function createFunctionComponentUpdateQueue() {
15141 return {
15142 lastEffect: null
15143 };
15144 }
15145
15146 function basicStateReducer(state, action) {
15147 // $FlowFixMe: Flow doesn't like mixed types
15148 return typeof action === 'function' ? action(state) : action;
15149 }
15150
15151 function mountReducer(reducer, initialArg, init) {
15152 var hook = mountWorkInProgressHook();
15153 var initialState;
15154
15155 if (init !== undefined) {
15156 initialState = init(initialArg);
15157 } else {
15158 initialState = initialArg;
15159 }
15160
15161 hook.memoizedState = hook.baseState = initialState;
15162 var queue = hook.queue = {
15163 pending: null,
15164 dispatch: null,
15165 lastRenderedReducer: reducer,
15166 lastRenderedState: initialState
15167 };
15168 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15169 return [hook.memoizedState, dispatch];
15170 }
15171
15172 function updateReducer(reducer, initialArg, init) {
15173 var hook = updateWorkInProgressHook();
15174 var queue = hook.queue;
15175
15176 if (!(queue !== null)) {
15177 {
15178 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15179 }
15180 }
15181
15182 queue.lastRenderedReducer = reducer;
15183 var current = currentHook; // The last rebase update that is NOT part of the base state.
15184
15185 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
15186
15187 var pendingQueue = queue.pending;
15188
15189 if (pendingQueue !== null) {
15190 // We have new updates that haven't been processed yet.
15191 // We'll add them to the base queue.
15192 if (baseQueue !== null) {
15193 // Merge the pending queue and the base queue.
15194 var baseFirst = baseQueue.next;
15195 var pendingFirst = pendingQueue.next;
15196 baseQueue.next = pendingFirst;
15197 pendingQueue.next = baseFirst;
15198 }
15199
15200 current.baseQueue = baseQueue = pendingQueue;
15201 queue.pending = null;
15202 }
15203
15204 if (baseQueue !== null) {
15205 // We have a queue to process.
15206 var first = baseQueue.next;
15207 var newState = current.baseState;
15208 var newBaseState = null;
15209 var newBaseQueueFirst = null;
15210 var newBaseQueueLast = null;
15211 var update = first;
15212
15213 do {
15214 var updateExpirationTime = update.expirationTime;
15215
15216 if (updateExpirationTime < renderExpirationTime) {
15217 // Priority is insufficient. Skip this update. If this is the first
15218 // skipped update, the previous update/state is the new base
15219 // update/state.
15220 var clone = {
15221 expirationTime: update.expirationTime,
15222 suspenseConfig: update.suspenseConfig,
15223 action: update.action,
15224 eagerReducer: update.eagerReducer,
15225 eagerState: update.eagerState,
15226 next: null
15227 };
15228
15229 if (newBaseQueueLast === null) {
15230 newBaseQueueFirst = newBaseQueueLast = clone;
15231 newBaseState = newState;
15232 } else {
15233 newBaseQueueLast = newBaseQueueLast.next = clone;
15234 } // Update the remaining priority in the queue.
15235
15236
15237 if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {
15238 currentlyRenderingFiber$1.expirationTime = updateExpirationTime;
15239 markUnprocessedUpdateTime(updateExpirationTime);
15240 }
15241 } else {
15242 // This update does have sufficient priority.
15243 if (newBaseQueueLast !== null) {
15244 var _clone = {
15245 expirationTime: Sync,
15246 // This update is going to be committed so we never want uncommit it.
15247 suspenseConfig: update.suspenseConfig,
15248 action: update.action,
15249 eagerReducer: update.eagerReducer,
15250 eagerState: update.eagerState,
15251 next: null
15252 };
15253 newBaseQueueLast = newBaseQueueLast.next = _clone;
15254 } // Mark the event time of this update as relevant to this render pass.
15255 // TODO: This should ideally use the true event time of this update rather than
15256 // its priority which is a derived and not reverseable value.
15257 // TODO: We should skip this update if it was already committed but currently
15258 // we have no way of detecting the difference between a committed and suspended
15259 // update here.
15260
15261
15262 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
15263
15264 if (update.eagerReducer === reducer) {
15265 // If this update was processed eagerly, and its reducer matches the
15266 // current reducer, we can use the eagerly computed state.
15267 newState = update.eagerState;
15268 } else {
15269 var action = update.action;
15270 newState = reducer(newState, action);
15271 }
15272 }
15273
15274 update = update.next;
15275 } while (update !== null && update !== first);
15276
15277 if (newBaseQueueLast === null) {
15278 newBaseState = newState;
15279 } else {
15280 newBaseQueueLast.next = newBaseQueueFirst;
15281 } // Mark that the fiber performed work, but only if the new state is
15282 // different from the current state.
15283
15284
15285 if (!objectIs(newState, hook.memoizedState)) {
15286 markWorkInProgressReceivedUpdate();
15287 }
15288
15289 hook.memoizedState = newState;
15290 hook.baseState = newBaseState;
15291 hook.baseQueue = newBaseQueueLast;
15292 queue.lastRenderedState = newState;
15293 }
15294
15295 var dispatch = queue.dispatch;
15296 return [hook.memoizedState, dispatch];
15297 }
15298
15299 function rerenderReducer(reducer, initialArg, init) {
15300 var hook = updateWorkInProgressHook();
15301 var queue = hook.queue;
15302
15303 if (!(queue !== null)) {
15304 {
15305 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
15306 }
15307 }
15308
15309 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
15310 // work-in-progress hook.
15311
15312 var dispatch = queue.dispatch;
15313 var lastRenderPhaseUpdate = queue.pending;
15314 var newState = hook.memoizedState;
15315
15316 if (lastRenderPhaseUpdate !== null) {
15317 // The queue doesn't persist past this render pass.
15318 queue.pending = null;
15319 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
15320 var update = firstRenderPhaseUpdate;
15321
15322 do {
15323 // Process this render phase update. We don't have to check the
15324 // priority because it will always be the same as the current
15325 // render's.
15326 var action = update.action;
15327 newState = reducer(newState, action);
15328 update = update.next;
15329 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
15330 // different from the current state.
15331
15332
15333 if (!objectIs(newState, hook.memoizedState)) {
15334 markWorkInProgressReceivedUpdate();
15335 }
15336
15337 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
15338 // the base state unless the queue is empty.
15339 // TODO: Not sure if this is the desired semantics, but it's what we
15340 // do for gDSFP. I can't remember why.
15341
15342 if (hook.baseQueue === null) {
15343 hook.baseState = newState;
15344 }
15345
15346 queue.lastRenderedState = newState;
15347 }
15348
15349 return [newState, dispatch];
15350 }
15351
15352 function mountState(initialState) {
15353 var hook = mountWorkInProgressHook();
15354
15355 if (typeof initialState === 'function') {
15356 // $FlowFixMe: Flow doesn't like mixed types
15357 initialState = initialState();
15358 }
15359
15360 hook.memoizedState = hook.baseState = initialState;
15361 var queue = hook.queue = {
15362 pending: null,
15363 dispatch: null,
15364 lastRenderedReducer: basicStateReducer,
15365 lastRenderedState: initialState
15366 };
15367 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
15368 return [hook.memoizedState, dispatch];
15369 }
15370
15371 function updateState(initialState) {
15372 return updateReducer(basicStateReducer);
15373 }
15374
15375 function rerenderState(initialState) {
15376 return rerenderReducer(basicStateReducer);
15377 }
15378
15379 function pushEffect(tag, create, destroy, deps) {
15380 var effect = {
15381 tag: tag,
15382 create: create,
15383 destroy: destroy,
15384 deps: deps,
15385 // Circular
15386 next: null
15387 };
15388 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
15389
15390 if (componentUpdateQueue === null) {
15391 componentUpdateQueue = createFunctionComponentUpdateQueue();
15392 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
15393 componentUpdateQueue.lastEffect = effect.next = effect;
15394 } else {
15395 var lastEffect = componentUpdateQueue.lastEffect;
15396
15397 if (lastEffect === null) {
15398 componentUpdateQueue.lastEffect = effect.next = effect;
15399 } else {
15400 var firstEffect = lastEffect.next;
15401 lastEffect.next = effect;
15402 effect.next = firstEffect;
15403 componentUpdateQueue.lastEffect = effect;
15404 }
15405 }
15406
15407 return effect;
15408 }
15409
15410 function mountRef(initialValue) {
15411 var hook = mountWorkInProgressHook();
15412 var ref = {
15413 current: initialValue
15414 };
15415
15416 {
15417 Object.seal(ref);
15418 }
15419
15420 hook.memoizedState = ref;
15421 return ref;
15422 }
15423
15424 function updateRef(initialValue) {
15425 var hook = updateWorkInProgressHook();
15426 return hook.memoizedState;
15427 }
15428
15429 function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15430 var hook = mountWorkInProgressHook();
15431 var nextDeps = deps === undefined ? null : deps;
15432 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
15433 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);
15434 }
15435
15436 function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15437 var hook = updateWorkInProgressHook();
15438 var nextDeps = deps === undefined ? null : deps;
15439 var destroy = undefined;
15440
15441 if (currentHook !== null) {
15442 var prevEffect = currentHook.memoizedState;
15443 destroy = prevEffect.destroy;
15444
15445 if (nextDeps !== null) {
15446 var prevDeps = prevEffect.deps;
15447
15448 if (areHookInputsEqual(nextDeps, prevDeps)) {
15449 pushEffect(hookEffectTag, create, destroy, nextDeps);
15450 return;
15451 }
15452 }
15453 }
15454
15455 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
15456 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);
15457 }
15458
15459 function mountEffect(create, deps) {
15460 {
15461 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15462 if ('undefined' !== typeof jest) {
15463 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15464 }
15465 }
15466
15467 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
15468 }
15469
15470 function updateEffect(create, deps) {
15471 {
15472 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15473 if ('undefined' !== typeof jest) {
15474 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15475 }
15476 }
15477
15478 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
15479 }
15480
15481 function mountLayoutEffect(create, deps) {
15482 return mountEffectImpl(Update, Layout, create, deps);
15483 }
15484
15485 function updateLayoutEffect(create, deps) {
15486 return updateEffectImpl(Update, Layout, create, deps);
15487 }
15488
15489 function imperativeHandleEffect(create, ref) {
15490 if (typeof ref === 'function') {
15491 var refCallback = ref;
15492
15493 var _inst = create();
15494
15495 refCallback(_inst);
15496 return function () {
15497 refCallback(null);
15498 };
15499 } else if (ref !== null && ref !== undefined) {
15500 var refObject = ref;
15501
15502 {
15503 if (!refObject.hasOwnProperty('current')) {
15504 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(', ') + '}');
15505 }
15506 }
15507
15508 var _inst2 = create();
15509
15510 refObject.current = _inst2;
15511 return function () {
15512 refObject.current = null;
15513 };
15514 }
15515 }
15516
15517 function mountImperativeHandle(ref, create, deps) {
15518 {
15519 if (typeof create !== 'function') {
15520 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15521 }
15522 } // TODO: If deps are provided, should we skip comparing the ref itself?
15523
15524
15525 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15526 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15527 }
15528
15529 function updateImperativeHandle(ref, create, deps) {
15530 {
15531 if (typeof create !== 'function') {
15532 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
15533 }
15534 } // TODO: If deps are provided, should we skip comparing the ref itself?
15535
15536
15537 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15538 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15539 }
15540
15541 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
15542 // The react-debug-hooks package injects its own implementation
15543 // so that e.g. DevTools can display custom hook values.
15544 }
15545
15546 var updateDebugValue = mountDebugValue;
15547
15548 function mountCallback(callback, deps) {
15549 var hook = mountWorkInProgressHook();
15550 var nextDeps = deps === undefined ? null : deps;
15551 hook.memoizedState = [callback, nextDeps];
15552 return callback;
15553 }
15554
15555 function updateCallback(callback, deps) {
15556 var hook = updateWorkInProgressHook();
15557 var nextDeps = deps === undefined ? null : deps;
15558 var prevState = hook.memoizedState;
15559
15560 if (prevState !== null) {
15561 if (nextDeps !== null) {
15562 var prevDeps = prevState[1];
15563
15564 if (areHookInputsEqual(nextDeps, prevDeps)) {
15565 return prevState[0];
15566 }
15567 }
15568 }
15569
15570 hook.memoizedState = [callback, nextDeps];
15571 return callback;
15572 }
15573
15574 function mountMemo(nextCreate, deps) {
15575 var hook = mountWorkInProgressHook();
15576 var nextDeps = deps === undefined ? null : deps;
15577 var nextValue = nextCreate();
15578 hook.memoizedState = [nextValue, nextDeps];
15579 return nextValue;
15580 }
15581
15582 function updateMemo(nextCreate, deps) {
15583 var hook = updateWorkInProgressHook();
15584 var nextDeps = deps === undefined ? null : deps;
15585 var prevState = hook.memoizedState;
15586
15587 if (prevState !== null) {
15588 // Assume these are defined. If they're not, areHookInputsEqual will warn.
15589 if (nextDeps !== null) {
15590 var prevDeps = prevState[1];
15591
15592 if (areHookInputsEqual(nextDeps, prevDeps)) {
15593 return prevState[0];
15594 }
15595 }
15596 }
15597
15598 var nextValue = nextCreate();
15599 hook.memoizedState = [nextValue, nextDeps];
15600 return nextValue;
15601 }
15602
15603 function mountDeferredValue(value, config) {
15604 var _mountState = mountState(value),
15605 prevValue = _mountState[0],
15606 setValue = _mountState[1];
15607
15608 mountEffect(function () {
15609 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15610 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15611
15612 try {
15613 setValue(value);
15614 } finally {
15615 ReactCurrentBatchConfig$1.suspense = previousConfig;
15616 }
15617 }, [value, config]);
15618 return prevValue;
15619 }
15620
15621 function updateDeferredValue(value, config) {
15622 var _updateState = updateState(),
15623 prevValue = _updateState[0],
15624 setValue = _updateState[1];
15625
15626 updateEffect(function () {
15627 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15628 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15629
15630 try {
15631 setValue(value);
15632 } finally {
15633 ReactCurrentBatchConfig$1.suspense = previousConfig;
15634 }
15635 }, [value, config]);
15636 return prevValue;
15637 }
15638
15639 function rerenderDeferredValue(value, config) {
15640 var _rerenderState = rerenderState(),
15641 prevValue = _rerenderState[0],
15642 setValue = _rerenderState[1];
15643
15644 updateEffect(function () {
15645 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15646 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15647
15648 try {
15649 setValue(value);
15650 } finally {
15651 ReactCurrentBatchConfig$1.suspense = previousConfig;
15652 }
15653 }, [value, config]);
15654 return prevValue;
15655 }
15656
15657 function startTransition(setPending, config, callback) {
15658 var priorityLevel = getCurrentPriorityLevel();
15659 runWithPriority$1(priorityLevel < UserBlockingPriority$1 ? UserBlockingPriority$1 : priorityLevel, function () {
15660 setPending(true);
15661 });
15662 runWithPriority$1(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {
15663 var previousConfig = ReactCurrentBatchConfig$1.suspense;
15664 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
15665
15666 try {
15667 setPending(false);
15668 callback();
15669 } finally {
15670 ReactCurrentBatchConfig$1.suspense = previousConfig;
15671 }
15672 });
15673 }
15674
15675 function mountTransition(config) {
15676 var _mountState2 = mountState(false),
15677 isPending = _mountState2[0],
15678 setPending = _mountState2[1];
15679
15680 var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15681 return [start, isPending];
15682 }
15683
15684 function updateTransition(config) {
15685 var _updateState2 = updateState(),
15686 isPending = _updateState2[0],
15687 setPending = _updateState2[1];
15688
15689 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15690 return [start, isPending];
15691 }
15692
15693 function rerenderTransition(config) {
15694 var _rerenderState2 = rerenderState(),
15695 isPending = _rerenderState2[0],
15696 setPending = _rerenderState2[1];
15697
15698 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
15699 return [start, isPending];
15700 }
15701
15702 function dispatchAction(fiber, queue, action) {
15703 {
15704 if (typeof arguments[3] === 'function') {
15705 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().');
15706 }
15707 }
15708
15709 var currentTime = requestCurrentTimeForUpdate();
15710 var suspenseConfig = requestCurrentSuspenseConfig();
15711 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
15712 var update = {
15713 expirationTime: expirationTime,
15714 suspenseConfig: suspenseConfig,
15715 action: action,
15716 eagerReducer: null,
15717 eagerState: null,
15718 next: null
15719 };
15720
15721 {
15722 update.priority = getCurrentPriorityLevel();
15723 } // Append the update to the end of the list.
15724
15725
15726 var pending = queue.pending;
15727
15728 if (pending === null) {
15729 // This is the first update. Create a circular list.
15730 update.next = update;
15731 } else {
15732 update.next = pending.next;
15733 pending.next = update;
15734 }
15735
15736 queue.pending = update;
15737 var alternate = fiber.alternate;
15738
15739 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
15740 // This is a render phase update. Stash it in a lazily-created map of
15741 // queue -> linked list of updates. After this render pass, we'll restart
15742 // and apply the stashed updates on top of the work-in-progress hook.
15743 didScheduleRenderPhaseUpdate = true;
15744 update.expirationTime = renderExpirationTime;
15745 currentlyRenderingFiber$1.expirationTime = renderExpirationTime;
15746 } else {
15747 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
15748 // The queue is currently empty, which means we can eagerly compute the
15749 // next state before entering the render phase. If the new state is the
15750 // same as the current state, we may be able to bail out entirely.
15751 var lastRenderedReducer = queue.lastRenderedReducer;
15752
15753 if (lastRenderedReducer !== null) {
15754 var prevDispatcher;
15755
15756 {
15757 prevDispatcher = ReactCurrentDispatcher.current;
15758 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
15759 }
15760
15761 try {
15762 var currentState = queue.lastRenderedState;
15763 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
15764 // it, on the update object. If the reducer hasn't changed by the
15765 // time we enter the render phase, then the eager state can be used
15766 // without calling the reducer again.
15767
15768 update.eagerReducer = lastRenderedReducer;
15769 update.eagerState = eagerState;
15770
15771 if (objectIs(eagerState, currentState)) {
15772 // Fast path. We can bail out without scheduling React to re-render.
15773 // It's still possible that we'll need to rebase this update later,
15774 // if the component re-renders for a different reason and by that
15775 // time the reducer has changed.
15776 return;
15777 }
15778 } catch (error) {// Suppress the error. It will throw again in the render phase.
15779 } finally {
15780 {
15781 ReactCurrentDispatcher.current = prevDispatcher;
15782 }
15783 }
15784 }
15785 }
15786
15787 {
15788 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15789 if ('undefined' !== typeof jest) {
15790 warnIfNotScopedWithMatchingAct(fiber);
15791 warnIfNotCurrentlyActingUpdatesInDev(fiber);
15792 }
15793 }
15794
15795 scheduleWork(fiber, expirationTime);
15796 }
15797 }
15798
15799 var ContextOnlyDispatcher = {
15800 readContext: readContext,
15801 useCallback: throwInvalidHookError,
15802 useContext: throwInvalidHookError,
15803 useEffect: throwInvalidHookError,
15804 useImperativeHandle: throwInvalidHookError,
15805 useLayoutEffect: throwInvalidHookError,
15806 useMemo: throwInvalidHookError,
15807 useReducer: throwInvalidHookError,
15808 useRef: throwInvalidHookError,
15809 useState: throwInvalidHookError,
15810 useDebugValue: throwInvalidHookError,
15811 useResponder: throwInvalidHookError,
15812 useDeferredValue: throwInvalidHookError,
15813 useTransition: throwInvalidHookError
15814 };
15815 var HooksDispatcherOnMountInDEV = null;
15816 var HooksDispatcherOnMountWithHookTypesInDEV = null;
15817 var HooksDispatcherOnUpdateInDEV = null;
15818 var HooksDispatcherOnRerenderInDEV = null;
15819 var InvalidNestedHooksDispatcherOnMountInDEV = null;
15820 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
15821 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
15822
15823 {
15824 var warnInvalidContextAccess = function () {
15825 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().');
15826 };
15827
15828 var warnInvalidHookAccess = function () {
15829 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');
15830 };
15831
15832 HooksDispatcherOnMountInDEV = {
15833 readContext: function (context, observedBits) {
15834 return readContext(context, observedBits);
15835 },
15836 useCallback: function (callback, deps) {
15837 currentHookNameInDev = 'useCallback';
15838 mountHookTypesDev();
15839 checkDepsAreArrayDev(deps);
15840 return mountCallback(callback, deps);
15841 },
15842 useContext: function (context, observedBits) {
15843 currentHookNameInDev = 'useContext';
15844 mountHookTypesDev();
15845 return readContext(context, observedBits);
15846 },
15847 useEffect: function (create, deps) {
15848 currentHookNameInDev = 'useEffect';
15849 mountHookTypesDev();
15850 checkDepsAreArrayDev(deps);
15851 return mountEffect(create, deps);
15852 },
15853 useImperativeHandle: function (ref, create, deps) {
15854 currentHookNameInDev = 'useImperativeHandle';
15855 mountHookTypesDev();
15856 checkDepsAreArrayDev(deps);
15857 return mountImperativeHandle(ref, create, deps);
15858 },
15859 useLayoutEffect: function (create, deps) {
15860 currentHookNameInDev = 'useLayoutEffect';
15861 mountHookTypesDev();
15862 checkDepsAreArrayDev(deps);
15863 return mountLayoutEffect(create, deps);
15864 },
15865 useMemo: function (create, deps) {
15866 currentHookNameInDev = 'useMemo';
15867 mountHookTypesDev();
15868 checkDepsAreArrayDev(deps);
15869 var prevDispatcher = ReactCurrentDispatcher.current;
15870 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15871
15872 try {
15873 return mountMemo(create, deps);
15874 } finally {
15875 ReactCurrentDispatcher.current = prevDispatcher;
15876 }
15877 },
15878 useReducer: function (reducer, initialArg, init) {
15879 currentHookNameInDev = 'useReducer';
15880 mountHookTypesDev();
15881 var prevDispatcher = ReactCurrentDispatcher.current;
15882 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15883
15884 try {
15885 return mountReducer(reducer, initialArg, init);
15886 } finally {
15887 ReactCurrentDispatcher.current = prevDispatcher;
15888 }
15889 },
15890 useRef: function (initialValue) {
15891 currentHookNameInDev = 'useRef';
15892 mountHookTypesDev();
15893 return mountRef(initialValue);
15894 },
15895 useState: function (initialState) {
15896 currentHookNameInDev = 'useState';
15897 mountHookTypesDev();
15898 var prevDispatcher = ReactCurrentDispatcher.current;
15899 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15900
15901 try {
15902 return mountState(initialState);
15903 } finally {
15904 ReactCurrentDispatcher.current = prevDispatcher;
15905 }
15906 },
15907 useDebugValue: function (value, formatterFn) {
15908 currentHookNameInDev = 'useDebugValue';
15909 mountHookTypesDev();
15910 return mountDebugValue();
15911 },
15912 useResponder: function (responder, props) {
15913 currentHookNameInDev = 'useResponder';
15914 mountHookTypesDev();
15915 return createDeprecatedResponderListener(responder, props);
15916 },
15917 useDeferredValue: function (value, config) {
15918 currentHookNameInDev = 'useDeferredValue';
15919 mountHookTypesDev();
15920 return mountDeferredValue(value, config);
15921 },
15922 useTransition: function (config) {
15923 currentHookNameInDev = 'useTransition';
15924 mountHookTypesDev();
15925 return mountTransition(config);
15926 }
15927 };
15928 HooksDispatcherOnMountWithHookTypesInDEV = {
15929 readContext: function (context, observedBits) {
15930 return readContext(context, observedBits);
15931 },
15932 useCallback: function (callback, deps) {
15933 currentHookNameInDev = 'useCallback';
15934 updateHookTypesDev();
15935 return mountCallback(callback, deps);
15936 },
15937 useContext: function (context, observedBits) {
15938 currentHookNameInDev = 'useContext';
15939 updateHookTypesDev();
15940 return readContext(context, observedBits);
15941 },
15942 useEffect: function (create, deps) {
15943 currentHookNameInDev = 'useEffect';
15944 updateHookTypesDev();
15945 return mountEffect(create, deps);
15946 },
15947 useImperativeHandle: function (ref, create, deps) {
15948 currentHookNameInDev = 'useImperativeHandle';
15949 updateHookTypesDev();
15950 return mountImperativeHandle(ref, create, deps);
15951 },
15952 useLayoutEffect: function (create, deps) {
15953 currentHookNameInDev = 'useLayoutEffect';
15954 updateHookTypesDev();
15955 return mountLayoutEffect(create, deps);
15956 },
15957 useMemo: function (create, deps) {
15958 currentHookNameInDev = 'useMemo';
15959 updateHookTypesDev();
15960 var prevDispatcher = ReactCurrentDispatcher.current;
15961 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15962
15963 try {
15964 return mountMemo(create, deps);
15965 } finally {
15966 ReactCurrentDispatcher.current = prevDispatcher;
15967 }
15968 },
15969 useReducer: function (reducer, initialArg, init) {
15970 currentHookNameInDev = 'useReducer';
15971 updateHookTypesDev();
15972 var prevDispatcher = ReactCurrentDispatcher.current;
15973 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15974
15975 try {
15976 return mountReducer(reducer, initialArg, init);
15977 } finally {
15978 ReactCurrentDispatcher.current = prevDispatcher;
15979 }
15980 },
15981 useRef: function (initialValue) {
15982 currentHookNameInDev = 'useRef';
15983 updateHookTypesDev();
15984 return mountRef(initialValue);
15985 },
15986 useState: function (initialState) {
15987 currentHookNameInDev = 'useState';
15988 updateHookTypesDev();
15989 var prevDispatcher = ReactCurrentDispatcher.current;
15990 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
15991
15992 try {
15993 return mountState(initialState);
15994 } finally {
15995 ReactCurrentDispatcher.current = prevDispatcher;
15996 }
15997 },
15998 useDebugValue: function (value, formatterFn) {
15999 currentHookNameInDev = 'useDebugValue';
16000 updateHookTypesDev();
16001 return mountDebugValue();
16002 },
16003 useResponder: function (responder, props) {
16004 currentHookNameInDev = 'useResponder';
16005 updateHookTypesDev();
16006 return createDeprecatedResponderListener(responder, props);
16007 },
16008 useDeferredValue: function (value, config) {
16009 currentHookNameInDev = 'useDeferredValue';
16010 updateHookTypesDev();
16011 return mountDeferredValue(value, config);
16012 },
16013 useTransition: function (config) {
16014 currentHookNameInDev = 'useTransition';
16015 updateHookTypesDev();
16016 return mountTransition(config);
16017 }
16018 };
16019 HooksDispatcherOnUpdateInDEV = {
16020 readContext: function (context, observedBits) {
16021 return readContext(context, observedBits);
16022 },
16023 useCallback: function (callback, deps) {
16024 currentHookNameInDev = 'useCallback';
16025 updateHookTypesDev();
16026 return updateCallback(callback, deps);
16027 },
16028 useContext: function (context, observedBits) {
16029 currentHookNameInDev = 'useContext';
16030 updateHookTypesDev();
16031 return readContext(context, observedBits);
16032 },
16033 useEffect: function (create, deps) {
16034 currentHookNameInDev = 'useEffect';
16035 updateHookTypesDev();
16036 return updateEffect(create, deps);
16037 },
16038 useImperativeHandle: function (ref, create, deps) {
16039 currentHookNameInDev = 'useImperativeHandle';
16040 updateHookTypesDev();
16041 return updateImperativeHandle(ref, create, deps);
16042 },
16043 useLayoutEffect: function (create, deps) {
16044 currentHookNameInDev = 'useLayoutEffect';
16045 updateHookTypesDev();
16046 return updateLayoutEffect(create, deps);
16047 },
16048 useMemo: function (create, deps) {
16049 currentHookNameInDev = 'useMemo';
16050 updateHookTypesDev();
16051 var prevDispatcher = ReactCurrentDispatcher.current;
16052 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16053
16054 try {
16055 return updateMemo(create, deps);
16056 } finally {
16057 ReactCurrentDispatcher.current = prevDispatcher;
16058 }
16059 },
16060 useReducer: function (reducer, initialArg, init) {
16061 currentHookNameInDev = 'useReducer';
16062 updateHookTypesDev();
16063 var prevDispatcher = ReactCurrentDispatcher.current;
16064 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16065
16066 try {
16067 return updateReducer(reducer, initialArg, init);
16068 } finally {
16069 ReactCurrentDispatcher.current = prevDispatcher;
16070 }
16071 },
16072 useRef: function (initialValue) {
16073 currentHookNameInDev = 'useRef';
16074 updateHookTypesDev();
16075 return updateRef();
16076 },
16077 useState: function (initialState) {
16078 currentHookNameInDev = 'useState';
16079 updateHookTypesDev();
16080 var prevDispatcher = ReactCurrentDispatcher.current;
16081 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16082
16083 try {
16084 return updateState(initialState);
16085 } finally {
16086 ReactCurrentDispatcher.current = prevDispatcher;
16087 }
16088 },
16089 useDebugValue: function (value, formatterFn) {
16090 currentHookNameInDev = 'useDebugValue';
16091 updateHookTypesDev();
16092 return updateDebugValue();
16093 },
16094 useResponder: function (responder, props) {
16095 currentHookNameInDev = 'useResponder';
16096 updateHookTypesDev();
16097 return createDeprecatedResponderListener(responder, props);
16098 },
16099 useDeferredValue: function (value, config) {
16100 currentHookNameInDev = 'useDeferredValue';
16101 updateHookTypesDev();
16102 return updateDeferredValue(value, config);
16103 },
16104 useTransition: function (config) {
16105 currentHookNameInDev = 'useTransition';
16106 updateHookTypesDev();
16107 return updateTransition(config);
16108 }
16109 };
16110 HooksDispatcherOnRerenderInDEV = {
16111 readContext: function (context, observedBits) {
16112 return readContext(context, observedBits);
16113 },
16114 useCallback: function (callback, deps) {
16115 currentHookNameInDev = 'useCallback';
16116 updateHookTypesDev();
16117 return updateCallback(callback, deps);
16118 },
16119 useContext: function (context, observedBits) {
16120 currentHookNameInDev = 'useContext';
16121 updateHookTypesDev();
16122 return readContext(context, observedBits);
16123 },
16124 useEffect: function (create, deps) {
16125 currentHookNameInDev = 'useEffect';
16126 updateHookTypesDev();
16127 return updateEffect(create, deps);
16128 },
16129 useImperativeHandle: function (ref, create, deps) {
16130 currentHookNameInDev = 'useImperativeHandle';
16131 updateHookTypesDev();
16132 return updateImperativeHandle(ref, create, deps);
16133 },
16134 useLayoutEffect: function (create, deps) {
16135 currentHookNameInDev = 'useLayoutEffect';
16136 updateHookTypesDev();
16137 return updateLayoutEffect(create, deps);
16138 },
16139 useMemo: function (create, deps) {
16140 currentHookNameInDev = 'useMemo';
16141 updateHookTypesDev();
16142 var prevDispatcher = ReactCurrentDispatcher.current;
16143 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16144
16145 try {
16146 return updateMemo(create, deps);
16147 } finally {
16148 ReactCurrentDispatcher.current = prevDispatcher;
16149 }
16150 },
16151 useReducer: function (reducer, initialArg, init) {
16152 currentHookNameInDev = 'useReducer';
16153 updateHookTypesDev();
16154 var prevDispatcher = ReactCurrentDispatcher.current;
16155 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16156
16157 try {
16158 return rerenderReducer(reducer, initialArg, init);
16159 } finally {
16160 ReactCurrentDispatcher.current = prevDispatcher;
16161 }
16162 },
16163 useRef: function (initialValue) {
16164 currentHookNameInDev = 'useRef';
16165 updateHookTypesDev();
16166 return updateRef();
16167 },
16168 useState: function (initialState) {
16169 currentHookNameInDev = 'useState';
16170 updateHookTypesDev();
16171 var prevDispatcher = ReactCurrentDispatcher.current;
16172 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
16173
16174 try {
16175 return rerenderState(initialState);
16176 } finally {
16177 ReactCurrentDispatcher.current = prevDispatcher;
16178 }
16179 },
16180 useDebugValue: function (value, formatterFn) {
16181 currentHookNameInDev = 'useDebugValue';
16182 updateHookTypesDev();
16183 return updateDebugValue();
16184 },
16185 useResponder: function (responder, props) {
16186 currentHookNameInDev = 'useResponder';
16187 updateHookTypesDev();
16188 return createDeprecatedResponderListener(responder, props);
16189 },
16190 useDeferredValue: function (value, config) {
16191 currentHookNameInDev = 'useDeferredValue';
16192 updateHookTypesDev();
16193 return rerenderDeferredValue(value, config);
16194 },
16195 useTransition: function (config) {
16196 currentHookNameInDev = 'useTransition';
16197 updateHookTypesDev();
16198 return rerenderTransition(config);
16199 }
16200 };
16201 InvalidNestedHooksDispatcherOnMountInDEV = {
16202 readContext: function (context, observedBits) {
16203 warnInvalidContextAccess();
16204 return readContext(context, observedBits);
16205 },
16206 useCallback: function (callback, deps) {
16207 currentHookNameInDev = 'useCallback';
16208 warnInvalidHookAccess();
16209 mountHookTypesDev();
16210 return mountCallback(callback, deps);
16211 },
16212 useContext: function (context, observedBits) {
16213 currentHookNameInDev = 'useContext';
16214 warnInvalidHookAccess();
16215 mountHookTypesDev();
16216 return readContext(context, observedBits);
16217 },
16218 useEffect: function (create, deps) {
16219 currentHookNameInDev = 'useEffect';
16220 warnInvalidHookAccess();
16221 mountHookTypesDev();
16222 return mountEffect(create, deps);
16223 },
16224 useImperativeHandle: function (ref, create, deps) {
16225 currentHookNameInDev = 'useImperativeHandle';
16226 warnInvalidHookAccess();
16227 mountHookTypesDev();
16228 return mountImperativeHandle(ref, create, deps);
16229 },
16230 useLayoutEffect: function (create, deps) {
16231 currentHookNameInDev = 'useLayoutEffect';
16232 warnInvalidHookAccess();
16233 mountHookTypesDev();
16234 return mountLayoutEffect(create, deps);
16235 },
16236 useMemo: function (create, deps) {
16237 currentHookNameInDev = 'useMemo';
16238 warnInvalidHookAccess();
16239 mountHookTypesDev();
16240 var prevDispatcher = ReactCurrentDispatcher.current;
16241 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16242
16243 try {
16244 return mountMemo(create, deps);
16245 } finally {
16246 ReactCurrentDispatcher.current = prevDispatcher;
16247 }
16248 },
16249 useReducer: function (reducer, initialArg, init) {
16250 currentHookNameInDev = 'useReducer';
16251 warnInvalidHookAccess();
16252 mountHookTypesDev();
16253 var prevDispatcher = ReactCurrentDispatcher.current;
16254 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16255
16256 try {
16257 return mountReducer(reducer, initialArg, init);
16258 } finally {
16259 ReactCurrentDispatcher.current = prevDispatcher;
16260 }
16261 },
16262 useRef: function (initialValue) {
16263 currentHookNameInDev = 'useRef';
16264 warnInvalidHookAccess();
16265 mountHookTypesDev();
16266 return mountRef(initialValue);
16267 },
16268 useState: function (initialState) {
16269 currentHookNameInDev = 'useState';
16270 warnInvalidHookAccess();
16271 mountHookTypesDev();
16272 var prevDispatcher = ReactCurrentDispatcher.current;
16273 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
16274
16275 try {
16276 return mountState(initialState);
16277 } finally {
16278 ReactCurrentDispatcher.current = prevDispatcher;
16279 }
16280 },
16281 useDebugValue: function (value, formatterFn) {
16282 currentHookNameInDev = 'useDebugValue';
16283 warnInvalidHookAccess();
16284 mountHookTypesDev();
16285 return mountDebugValue();
16286 },
16287 useResponder: function (responder, props) {
16288 currentHookNameInDev = 'useResponder';
16289 warnInvalidHookAccess();
16290 mountHookTypesDev();
16291 return createDeprecatedResponderListener(responder, props);
16292 },
16293 useDeferredValue: function (value, config) {
16294 currentHookNameInDev = 'useDeferredValue';
16295 warnInvalidHookAccess();
16296 mountHookTypesDev();
16297 return mountDeferredValue(value, config);
16298 },
16299 useTransition: function (config) {
16300 currentHookNameInDev = 'useTransition';
16301 warnInvalidHookAccess();
16302 mountHookTypesDev();
16303 return mountTransition(config);
16304 }
16305 };
16306 InvalidNestedHooksDispatcherOnUpdateInDEV = {
16307 readContext: function (context, observedBits) {
16308 warnInvalidContextAccess();
16309 return readContext(context, observedBits);
16310 },
16311 useCallback: function (callback, deps) {
16312 currentHookNameInDev = 'useCallback';
16313 warnInvalidHookAccess();
16314 updateHookTypesDev();
16315 return updateCallback(callback, deps);
16316 },
16317 useContext: function (context, observedBits) {
16318 currentHookNameInDev = 'useContext';
16319 warnInvalidHookAccess();
16320 updateHookTypesDev();
16321 return readContext(context, observedBits);
16322 },
16323 useEffect: function (create, deps) {
16324 currentHookNameInDev = 'useEffect';
16325 warnInvalidHookAccess();
16326 updateHookTypesDev();
16327 return updateEffect(create, deps);
16328 },
16329 useImperativeHandle: function (ref, create, deps) {
16330 currentHookNameInDev = 'useImperativeHandle';
16331 warnInvalidHookAccess();
16332 updateHookTypesDev();
16333 return updateImperativeHandle(ref, create, deps);
16334 },
16335 useLayoutEffect: function (create, deps) {
16336 currentHookNameInDev = 'useLayoutEffect';
16337 warnInvalidHookAccess();
16338 updateHookTypesDev();
16339 return updateLayoutEffect(create, deps);
16340 },
16341 useMemo: function (create, deps) {
16342 currentHookNameInDev = 'useMemo';
16343 warnInvalidHookAccess();
16344 updateHookTypesDev();
16345 var prevDispatcher = ReactCurrentDispatcher.current;
16346 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16347
16348 try {
16349 return updateMemo(create, deps);
16350 } finally {
16351 ReactCurrentDispatcher.current = prevDispatcher;
16352 }
16353 },
16354 useReducer: function (reducer, initialArg, init) {
16355 currentHookNameInDev = 'useReducer';
16356 warnInvalidHookAccess();
16357 updateHookTypesDev();
16358 var prevDispatcher = ReactCurrentDispatcher.current;
16359 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16360
16361 try {
16362 return updateReducer(reducer, initialArg, init);
16363 } finally {
16364 ReactCurrentDispatcher.current = prevDispatcher;
16365 }
16366 },
16367 useRef: function (initialValue) {
16368 currentHookNameInDev = 'useRef';
16369 warnInvalidHookAccess();
16370 updateHookTypesDev();
16371 return updateRef();
16372 },
16373 useState: function (initialState) {
16374 currentHookNameInDev = 'useState';
16375 warnInvalidHookAccess();
16376 updateHookTypesDev();
16377 var prevDispatcher = ReactCurrentDispatcher.current;
16378 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16379
16380 try {
16381 return updateState(initialState);
16382 } finally {
16383 ReactCurrentDispatcher.current = prevDispatcher;
16384 }
16385 },
16386 useDebugValue: function (value, formatterFn) {
16387 currentHookNameInDev = 'useDebugValue';
16388 warnInvalidHookAccess();
16389 updateHookTypesDev();
16390 return updateDebugValue();
16391 },
16392 useResponder: function (responder, props) {
16393 currentHookNameInDev = 'useResponder';
16394 warnInvalidHookAccess();
16395 updateHookTypesDev();
16396 return createDeprecatedResponderListener(responder, props);
16397 },
16398 useDeferredValue: function (value, config) {
16399 currentHookNameInDev = 'useDeferredValue';
16400 warnInvalidHookAccess();
16401 updateHookTypesDev();
16402 return updateDeferredValue(value, config);
16403 },
16404 useTransition: function (config) {
16405 currentHookNameInDev = 'useTransition';
16406 warnInvalidHookAccess();
16407 updateHookTypesDev();
16408 return updateTransition(config);
16409 }
16410 };
16411 InvalidNestedHooksDispatcherOnRerenderInDEV = {
16412 readContext: function (context, observedBits) {
16413 warnInvalidContextAccess();
16414 return readContext(context, observedBits);
16415 },
16416 useCallback: function (callback, deps) {
16417 currentHookNameInDev = 'useCallback';
16418 warnInvalidHookAccess();
16419 updateHookTypesDev();
16420 return updateCallback(callback, deps);
16421 },
16422 useContext: function (context, observedBits) {
16423 currentHookNameInDev = 'useContext';
16424 warnInvalidHookAccess();
16425 updateHookTypesDev();
16426 return readContext(context, observedBits);
16427 },
16428 useEffect: function (create, deps) {
16429 currentHookNameInDev = 'useEffect';
16430 warnInvalidHookAccess();
16431 updateHookTypesDev();
16432 return updateEffect(create, deps);
16433 },
16434 useImperativeHandle: function (ref, create, deps) {
16435 currentHookNameInDev = 'useImperativeHandle';
16436 warnInvalidHookAccess();
16437 updateHookTypesDev();
16438 return updateImperativeHandle(ref, create, deps);
16439 },
16440 useLayoutEffect: function (create, deps) {
16441 currentHookNameInDev = 'useLayoutEffect';
16442 warnInvalidHookAccess();
16443 updateHookTypesDev();
16444 return updateLayoutEffect(create, deps);
16445 },
16446 useMemo: function (create, deps) {
16447 currentHookNameInDev = 'useMemo';
16448 warnInvalidHookAccess();
16449 updateHookTypesDev();
16450 var prevDispatcher = ReactCurrentDispatcher.current;
16451 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16452
16453 try {
16454 return updateMemo(create, deps);
16455 } finally {
16456 ReactCurrentDispatcher.current = prevDispatcher;
16457 }
16458 },
16459 useReducer: function (reducer, initialArg, init) {
16460 currentHookNameInDev = 'useReducer';
16461 warnInvalidHookAccess();
16462 updateHookTypesDev();
16463 var prevDispatcher = ReactCurrentDispatcher.current;
16464 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16465
16466 try {
16467 return rerenderReducer(reducer, initialArg, init);
16468 } finally {
16469 ReactCurrentDispatcher.current = prevDispatcher;
16470 }
16471 },
16472 useRef: function (initialValue) {
16473 currentHookNameInDev = 'useRef';
16474 warnInvalidHookAccess();
16475 updateHookTypesDev();
16476 return updateRef();
16477 },
16478 useState: function (initialState) {
16479 currentHookNameInDev = 'useState';
16480 warnInvalidHookAccess();
16481 updateHookTypesDev();
16482 var prevDispatcher = ReactCurrentDispatcher.current;
16483 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16484
16485 try {
16486 return rerenderState(initialState);
16487 } finally {
16488 ReactCurrentDispatcher.current = prevDispatcher;
16489 }
16490 },
16491 useDebugValue: function (value, formatterFn) {
16492 currentHookNameInDev = 'useDebugValue';
16493 warnInvalidHookAccess();
16494 updateHookTypesDev();
16495 return updateDebugValue();
16496 },
16497 useResponder: function (responder, props) {
16498 currentHookNameInDev = 'useResponder';
16499 warnInvalidHookAccess();
16500 updateHookTypesDev();
16501 return createDeprecatedResponderListener(responder, props);
16502 },
16503 useDeferredValue: function (value, config) {
16504 currentHookNameInDev = 'useDeferredValue';
16505 warnInvalidHookAccess();
16506 updateHookTypesDev();
16507 return rerenderDeferredValue(value, config);
16508 },
16509 useTransition: function (config) {
16510 currentHookNameInDev = 'useTransition';
16511 warnInvalidHookAccess();
16512 updateHookTypesDev();
16513 return rerenderTransition(config);
16514 }
16515 };
16516 }
16517
16518 var now$1 = unstable_now;
16519 var commitTime = 0;
16520 var profilerStartTime = -1;
16521
16522 function getCommitTime() {
16523 return commitTime;
16524 }
16525
16526 function recordCommitTime() {
16527
16528 commitTime = now$1();
16529 }
16530
16531 function startProfilerTimer(fiber) {
16532
16533 profilerStartTime = now$1();
16534
16535 if (fiber.actualStartTime < 0) {
16536 fiber.actualStartTime = now$1();
16537 }
16538 }
16539
16540 function stopProfilerTimerIfRunning(fiber) {
16541
16542 profilerStartTime = -1;
16543 }
16544
16545 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
16546
16547 if (profilerStartTime >= 0) {
16548 var elapsedTime = now$1() - profilerStartTime;
16549 fiber.actualDuration += elapsedTime;
16550
16551 if (overrideBaseTime) {
16552 fiber.selfBaseDuration = elapsedTime;
16553 }
16554
16555 profilerStartTime = -1;
16556 }
16557 }
16558
16559 // This may have been an insertion or a hydration.
16560
16561 var hydrationParentFiber = null;
16562 var nextHydratableInstance = null;
16563 var isHydrating = false;
16564
16565 function enterHydrationState(fiber) {
16566
16567 var parentInstance = fiber.stateNode.containerInfo;
16568 nextHydratableInstance = getFirstHydratableChild(parentInstance);
16569 hydrationParentFiber = fiber;
16570 isHydrating = true;
16571 return true;
16572 }
16573
16574 function deleteHydratableInstance(returnFiber, instance) {
16575 {
16576 switch (returnFiber.tag) {
16577 case HostRoot:
16578 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
16579 break;
16580
16581 case HostComponent:
16582 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
16583 break;
16584 }
16585 }
16586
16587 var childToDelete = createFiberFromHostInstanceForDeletion();
16588 childToDelete.stateNode = instance;
16589 childToDelete.return = returnFiber;
16590 childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
16591 // these children are not part of the reconciliation list of children.
16592 // Even if we abort and rereconcile the children, that will try to hydrate
16593 // again and the nodes are still in the host tree so these will be
16594 // recreated.
16595
16596 if (returnFiber.lastEffect !== null) {
16597 returnFiber.lastEffect.nextEffect = childToDelete;
16598 returnFiber.lastEffect = childToDelete;
16599 } else {
16600 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
16601 }
16602 }
16603
16604 function insertNonHydratedInstance(returnFiber, fiber) {
16605 fiber.effectTag = fiber.effectTag & ~Hydrating | Placement;
16606
16607 {
16608 switch (returnFiber.tag) {
16609 case HostRoot:
16610 {
16611 var parentContainer = returnFiber.stateNode.containerInfo;
16612
16613 switch (fiber.tag) {
16614 case HostComponent:
16615 var type = fiber.type;
16616 var props = fiber.pendingProps;
16617 didNotFindHydratableContainerInstance(parentContainer, type);
16618 break;
16619
16620 case HostText:
16621 var text = fiber.pendingProps;
16622 didNotFindHydratableContainerTextInstance(parentContainer, text);
16623 break;
16624 }
16625
16626 break;
16627 }
16628
16629 case HostComponent:
16630 {
16631 var parentType = returnFiber.type;
16632 var parentProps = returnFiber.memoizedProps;
16633 var parentInstance = returnFiber.stateNode;
16634
16635 switch (fiber.tag) {
16636 case HostComponent:
16637 var _type = fiber.type;
16638 var _props = fiber.pendingProps;
16639 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type);
16640 break;
16641
16642 case HostText:
16643 var _text = fiber.pendingProps;
16644 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
16645 break;
16646
16647 case SuspenseComponent:
16648 didNotFindHydratableSuspenseInstance(parentType, parentProps);
16649 break;
16650 }
16651
16652 break;
16653 }
16654
16655 default:
16656 return;
16657 }
16658 }
16659 }
16660
16661 function tryHydrate(fiber, nextInstance) {
16662 switch (fiber.tag) {
16663 case HostComponent:
16664 {
16665 var type = fiber.type;
16666 var props = fiber.pendingProps;
16667 var instance = canHydrateInstance(nextInstance, type);
16668
16669 if (instance !== null) {
16670 fiber.stateNode = instance;
16671 return true;
16672 }
16673
16674 return false;
16675 }
16676
16677 case HostText:
16678 {
16679 var text = fiber.pendingProps;
16680 var textInstance = canHydrateTextInstance(nextInstance, text);
16681
16682 if (textInstance !== null) {
16683 fiber.stateNode = textInstance;
16684 return true;
16685 }
16686
16687 return false;
16688 }
16689
16690 case SuspenseComponent:
16691 {
16692
16693 return false;
16694 }
16695
16696 default:
16697 return false;
16698 }
16699 }
16700
16701 function tryToClaimNextHydratableInstance(fiber) {
16702 if (!isHydrating) {
16703 return;
16704 }
16705
16706 var nextInstance = nextHydratableInstance;
16707
16708 if (!nextInstance) {
16709 // Nothing to hydrate. Make it an insertion.
16710 insertNonHydratedInstance(hydrationParentFiber, fiber);
16711 isHydrating = false;
16712 hydrationParentFiber = fiber;
16713 return;
16714 }
16715
16716 var firstAttemptedInstance = nextInstance;
16717
16718 if (!tryHydrate(fiber, nextInstance)) {
16719 // If we can't hydrate this instance let's try the next one.
16720 // We use this as a heuristic. It's based on intuition and not data so it
16721 // might be flawed or unnecessary.
16722 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
16723
16724 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
16725 // Nothing to hydrate. Make it an insertion.
16726 insertNonHydratedInstance(hydrationParentFiber, fiber);
16727 isHydrating = false;
16728 hydrationParentFiber = fiber;
16729 return;
16730 } // We matched the next one, we'll now assume that the first one was
16731 // superfluous and we'll delete it. Since we can't eagerly delete it
16732 // we'll have to schedule a deletion. To do that, this node needs a dummy
16733 // fiber associated with it.
16734
16735
16736 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
16737 }
16738
16739 hydrationParentFiber = fiber;
16740 nextHydratableInstance = getFirstHydratableChild(nextInstance);
16741 }
16742
16743 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
16744
16745 var instance = fiber.stateNode;
16746 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.
16747
16748 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
16749 // is a new ref we mark this as an update.
16750
16751 if (updatePayload !== null) {
16752 return true;
16753 }
16754
16755 return false;
16756 }
16757
16758 function prepareToHydrateHostTextInstance(fiber) {
16759
16760 var textInstance = fiber.stateNode;
16761 var textContent = fiber.memoizedProps;
16762 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
16763
16764 {
16765 if (shouldUpdate) {
16766 // We assume that prepareToHydrateHostTextInstance is called in a context where the
16767 // hydration parent is the parent host component of this host text.
16768 var returnFiber = hydrationParentFiber;
16769
16770 if (returnFiber !== null) {
16771 switch (returnFiber.tag) {
16772 case HostRoot:
16773 {
16774 var parentContainer = returnFiber.stateNode.containerInfo;
16775 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
16776 break;
16777 }
16778
16779 case HostComponent:
16780 {
16781 var parentType = returnFiber.type;
16782 var parentProps = returnFiber.memoizedProps;
16783 var parentInstance = returnFiber.stateNode;
16784 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
16785 break;
16786 }
16787 }
16788 }
16789 }
16790 }
16791
16792 return shouldUpdate;
16793 }
16794
16795 function skipPastDehydratedSuspenseInstance(fiber) {
16796
16797 var suspenseState = fiber.memoizedState;
16798 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
16799
16800 if (!suspenseInstance) {
16801 {
16802 throw Error( "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." );
16803 }
16804 }
16805
16806 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
16807 }
16808
16809 function popToNextHostParent(fiber) {
16810 var parent = fiber.return;
16811
16812 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
16813 parent = parent.return;
16814 }
16815
16816 hydrationParentFiber = parent;
16817 }
16818
16819 function popHydrationState(fiber) {
16820
16821 if (fiber !== hydrationParentFiber) {
16822 // We're deeper than the current hydration context, inside an inserted
16823 // tree.
16824 return false;
16825 }
16826
16827 if (!isHydrating) {
16828 // If we're not currently hydrating but we're in a hydration context, then
16829 // we were an insertion and now need to pop up reenter hydration of our
16830 // siblings.
16831 popToNextHostParent(fiber);
16832 isHydrating = true;
16833 return false;
16834 }
16835
16836 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.
16837 // We only do this deeper than head and body since they tend to have random
16838 // other nodes in them. We also ignore components with pure text content in
16839 // side of them.
16840 // TODO: Better heuristic.
16841
16842 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
16843 var nextInstance = nextHydratableInstance;
16844
16845 while (nextInstance) {
16846 deleteHydratableInstance(fiber, nextInstance);
16847 nextInstance = getNextHydratableSibling(nextInstance);
16848 }
16849 }
16850
16851 popToNextHostParent(fiber);
16852
16853 if (fiber.tag === SuspenseComponent) {
16854 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
16855 } else {
16856 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
16857 }
16858
16859 return true;
16860 }
16861
16862 function resetHydrationState() {
16863
16864 hydrationParentFiber = null;
16865 nextHydratableInstance = null;
16866 isHydrating = false;
16867 }
16868
16869 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
16870 var didReceiveUpdate = false;
16871 var didWarnAboutBadClass;
16872 var didWarnAboutModulePatternComponent;
16873 var didWarnAboutContextTypeOnFunctionComponent;
16874 var didWarnAboutGetDerivedStateOnFunctionComponent;
16875 var didWarnAboutFunctionRefs;
16876 var didWarnAboutReassigningProps;
16877 var didWarnAboutRevealOrder;
16878 var didWarnAboutTailOptions;
16879
16880 {
16881 didWarnAboutBadClass = {};
16882 didWarnAboutModulePatternComponent = {};
16883 didWarnAboutContextTypeOnFunctionComponent = {};
16884 didWarnAboutGetDerivedStateOnFunctionComponent = {};
16885 didWarnAboutFunctionRefs = {};
16886 didWarnAboutReassigningProps = false;
16887 didWarnAboutRevealOrder = {};
16888 didWarnAboutTailOptions = {};
16889 }
16890
16891 function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
16892 if (current === null) {
16893 // If this is a fresh new component that hasn't been rendered yet, we
16894 // won't update its child set by applying minimal side-effects. Instead,
16895 // we will add them all to the child before it gets rendered. That means
16896 // we can optimize this reconciliation pass by not tracking side-effects.
16897 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16898 } else {
16899 // If the current child is the same as the work in progress, it means that
16900 // we haven't yet started any work on these children. Therefore, we use
16901 // the clone algorithm to create a copy of all the current children.
16902 // If we had any progressed work already, that is invalid at this point so
16903 // let's throw it out.
16904 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
16905 }
16906 }
16907
16908 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
16909 // This function is fork of reconcileChildren. It's used in cases where we
16910 // want to reconcile without matching against the existing set. This has the
16911 // effect of all current children being unmounted; even if the type and key
16912 // are the same, the old child is unmounted and a new child is created.
16913 //
16914 // To do this, we're going to go through the reconcile algorithm twice. In
16915 // the first pass, we schedule a deletion for all the current children by
16916 // passing null.
16917 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
16918 // pass null in place of where we usually pass the current child set. This has
16919 // the effect of remounting all children regardless of whether their
16920 // identities match.
16921
16922 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16923 }
16924
16925 function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
16926 // TODO: current can be non-null here even if the component
16927 // hasn't yet mounted. This happens after the first render suspends.
16928 // We'll need to figure out if this is fine or can cause issues.
16929 {
16930 if (workInProgress.type !== workInProgress.elementType) {
16931 // Lazy component props can't be validated in createElement
16932 // because they're only guaranteed to be resolved here.
16933 var innerPropTypes = Component.propTypes;
16934
16935 if (innerPropTypes) {
16936 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
16937 'prop', getComponentName(Component), getCurrentFiberStackInDev);
16938 }
16939 }
16940 }
16941
16942 var render = Component.render;
16943 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
16944
16945 var nextChildren;
16946 prepareToReadContext(workInProgress, renderExpirationTime);
16947
16948 {
16949 ReactCurrentOwner$1.current = workInProgress;
16950 setIsRendering(true);
16951 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
16952
16953 if ( workInProgress.mode & StrictMode) {
16954 // Only double-render components with Hooks
16955 if (workInProgress.memoizedState !== null) {
16956 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
16957 }
16958 }
16959
16960 setIsRendering(false);
16961 }
16962
16963 if (current !== null && !didReceiveUpdate) {
16964 bailoutHooks(current, workInProgress, renderExpirationTime);
16965 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
16966 } // React DevTools reads this flag.
16967
16968
16969 workInProgress.effectTag |= PerformedWork;
16970 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
16971 return workInProgress.child;
16972 }
16973
16974 function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
16975 if (current === null) {
16976 var type = Component.type;
16977
16978 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
16979 Component.defaultProps === undefined) {
16980 var resolvedType = type;
16981
16982 {
16983 resolvedType = resolveFunctionForHotReloading(type);
16984 } // If this is a plain function component without default props,
16985 // and with only the default shallow comparison, we upgrade it
16986 // to a SimpleMemoComponent to allow fast path updates.
16987
16988
16989 workInProgress.tag = SimpleMemoComponent;
16990 workInProgress.type = resolvedType;
16991
16992 {
16993 validateFunctionComponentInDev(workInProgress, type);
16994 }
16995
16996 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
16997 }
16998
16999 {
17000 var innerPropTypes = type.propTypes;
17001
17002 if (innerPropTypes) {
17003 // Inner memo component props aren't currently validated in createElement.
17004 // We could move it there, but we'd still need this for lazy code path.
17005 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
17006 'prop', getComponentName(type), getCurrentFiberStackInDev);
17007 }
17008 }
17009
17010 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
17011 child.ref = workInProgress.ref;
17012 child.return = workInProgress;
17013 workInProgress.child = child;
17014 return child;
17015 }
17016
17017 {
17018 var _type = Component.type;
17019 var _innerPropTypes = _type.propTypes;
17020
17021 if (_innerPropTypes) {
17022 // Inner memo component props aren't currently validated in createElement.
17023 // We could move it there, but we'd still need this for lazy code path.
17024 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
17025 'prop', getComponentName(_type), getCurrentFiberStackInDev);
17026 }
17027 }
17028
17029 var currentChild = current.child; // This is always exactly one child
17030
17031 if (updateExpirationTime < renderExpirationTime) {
17032 // This will be the props with resolved defaultProps,
17033 // unlike current.memoizedProps which will be the unresolved ones.
17034 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
17035
17036 var compare = Component.compare;
17037 compare = compare !== null ? compare : shallowEqual;
17038
17039 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
17040 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17041 }
17042 } // React DevTools reads this flag.
17043
17044
17045 workInProgress.effectTag |= PerformedWork;
17046 var newChild = createWorkInProgress(currentChild, nextProps);
17047 newChild.ref = workInProgress.ref;
17048 newChild.return = workInProgress;
17049 workInProgress.child = newChild;
17050 return newChild;
17051 }
17052
17053 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
17054 // TODO: current can be non-null here even if the component
17055 // hasn't yet mounted. This happens when the inner render suspends.
17056 // We'll need to figure out if this is fine or can cause issues.
17057 {
17058 if (workInProgress.type !== workInProgress.elementType) {
17059 // Lazy component props can't be validated in createElement
17060 // because they're only guaranteed to be resolved here.
17061 var outerMemoType = workInProgress.elementType;
17062
17063 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
17064 // We warn when you define propTypes on lazy()
17065 // so let's just skip over it to find memo() outer wrapper.
17066 // Inner props for memo are validated later.
17067 outerMemoType = refineResolvedLazyComponent(outerMemoType);
17068 }
17069
17070 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
17071
17072 if (outerPropTypes) {
17073 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
17074 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
17075 } // Inner propTypes will be validated in the function component path.
17076
17077 }
17078 }
17079
17080 if (current !== null) {
17081 var prevProps = current.memoizedProps;
17082
17083 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
17084 workInProgress.type === current.type )) {
17085 didReceiveUpdate = false;
17086
17087 if (updateExpirationTime < renderExpirationTime) {
17088 // The pending update priority was cleared at the beginning of
17089 // beginWork. We're about to bail out, but there might be additional
17090 // updates at a lower priority. Usually, the priority level of the
17091 // remaining updates is accumlated during the evaluation of the
17092 // component (i.e. when processing the update queue). But since since
17093 // we're bailing out early *without* evaluating the component, we need
17094 // to account for it here, too. Reset to the value of the current fiber.
17095 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
17096 // because a MemoComponent fiber does not have hooks or an update queue;
17097 // rather, it wraps around an inner component, which may or may not
17098 // contains hooks.
17099 // TODO: Move the reset at in beginWork out of the common path so that
17100 // this is no longer necessary.
17101 workInProgress.expirationTime = current.expirationTime;
17102 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17103 }
17104 }
17105 }
17106
17107 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
17108 }
17109
17110 function updateFragment(current, workInProgress, renderExpirationTime) {
17111 var nextChildren = workInProgress.pendingProps;
17112 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17113 return workInProgress.child;
17114 }
17115
17116 function updateMode(current, workInProgress, renderExpirationTime) {
17117 var nextChildren = workInProgress.pendingProps.children;
17118 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17119 return workInProgress.child;
17120 }
17121
17122 function updateProfiler(current, workInProgress, renderExpirationTime) {
17123 {
17124 workInProgress.effectTag |= Update;
17125 }
17126
17127 var nextProps = workInProgress.pendingProps;
17128 var nextChildren = nextProps.children;
17129 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17130 return workInProgress.child;
17131 }
17132
17133 function markRef(current, workInProgress) {
17134 var ref = workInProgress.ref;
17135
17136 if (current === null && ref !== null || current !== null && current.ref !== ref) {
17137 // Schedule a Ref effect
17138 workInProgress.effectTag |= Ref;
17139 }
17140 }
17141
17142 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
17143 {
17144 if (workInProgress.type !== workInProgress.elementType) {
17145 // Lazy component props can't be validated in createElement
17146 // because they're only guaranteed to be resolved here.
17147 var innerPropTypes = Component.propTypes;
17148
17149 if (innerPropTypes) {
17150 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
17151 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17152 }
17153 }
17154 }
17155
17156 var context;
17157
17158 {
17159 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
17160 context = getMaskedContext(workInProgress, unmaskedContext);
17161 }
17162
17163 var nextChildren;
17164 prepareToReadContext(workInProgress, renderExpirationTime);
17165
17166 {
17167 ReactCurrentOwner$1.current = workInProgress;
17168 setIsRendering(true);
17169 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
17170
17171 if ( workInProgress.mode & StrictMode) {
17172 // Only double-render components with Hooks
17173 if (workInProgress.memoizedState !== null) {
17174 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
17175 }
17176 }
17177
17178 setIsRendering(false);
17179 }
17180
17181 if (current !== null && !didReceiveUpdate) {
17182 bailoutHooks(current, workInProgress, renderExpirationTime);
17183 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17184 } // React DevTools reads this flag.
17185
17186
17187 workInProgress.effectTag |= PerformedWork;
17188 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17189 return workInProgress.child;
17190 }
17191
17192 function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
17193 {
17194 if (workInProgress.type !== workInProgress.elementType) {
17195 // Lazy component props can't be validated in createElement
17196 // because they're only guaranteed to be resolved here.
17197 var innerPropTypes = Component.propTypes;
17198
17199 if (innerPropTypes) {
17200 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
17201 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17202 }
17203 }
17204 } // Push context providers early to prevent context stack mismatches.
17205 // During mounting we don't know the child context yet as the instance doesn't exist.
17206 // We will invalidate the child context in finishClassComponent() right after rendering.
17207
17208
17209 var hasContext;
17210
17211 if (isContextProvider(Component)) {
17212 hasContext = true;
17213 pushContextProvider(workInProgress);
17214 } else {
17215 hasContext = false;
17216 }
17217
17218 prepareToReadContext(workInProgress, renderExpirationTime);
17219 var instance = workInProgress.stateNode;
17220 var shouldUpdate;
17221
17222 if (instance === null) {
17223 if (current !== null) {
17224 // A class component without an instance only mounts if it suspended
17225 // inside a non-concurrent tree, in an inconsistent state. We want to
17226 // treat it like a new mount, even though an empty version of it already
17227 // committed. Disconnect the alternate pointers.
17228 current.alternate = null;
17229 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17230
17231 workInProgress.effectTag |= Placement;
17232 } // In the initial pass we might need to construct the instance.
17233
17234
17235 constructClassInstance(workInProgress, Component, nextProps);
17236 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17237 shouldUpdate = true;
17238 } else if (current === null) {
17239 // In a resume, we'll already have an instance we can reuse.
17240 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17241 } else {
17242 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
17243 }
17244
17245 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
17246
17247 {
17248 var inst = workInProgress.stateNode;
17249
17250 if (inst.props !== nextProps) {
17251 if (!didWarnAboutReassigningProps) {
17252 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');
17253 }
17254
17255 didWarnAboutReassigningProps = true;
17256 }
17257 }
17258
17259 return nextUnitOfWork;
17260 }
17261
17262 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
17263 // Refs should update even if shouldComponentUpdate returns false
17264 markRef(current, workInProgress);
17265 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
17266
17267 if (!shouldUpdate && !didCaptureError) {
17268 // Context providers should defer to sCU for rendering
17269 if (hasContext) {
17270 invalidateContextProvider(workInProgress, Component, false);
17271 }
17272
17273 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17274 }
17275
17276 var instance = workInProgress.stateNode; // Rerender
17277
17278 ReactCurrentOwner$1.current = workInProgress;
17279 var nextChildren;
17280
17281 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
17282 // If we captured an error, but getDerivedStateFromError is not defined,
17283 // unmount all the children. componentDidCatch will schedule an update to
17284 // re-render a fallback. This is temporary until we migrate everyone to
17285 // the new API.
17286 // TODO: Warn in a future release.
17287 nextChildren = null;
17288
17289 {
17290 stopProfilerTimerIfRunning();
17291 }
17292 } else {
17293 {
17294 setIsRendering(true);
17295 nextChildren = instance.render();
17296
17297 if ( workInProgress.mode & StrictMode) {
17298 instance.render();
17299 }
17300
17301 setIsRendering(false);
17302 }
17303 } // React DevTools reads this flag.
17304
17305
17306 workInProgress.effectTag |= PerformedWork;
17307
17308 if (current !== null && didCaptureError) {
17309 // If we're recovering from an error, reconcile without reusing any of
17310 // the existing children. Conceptually, the normal children and the children
17311 // that are shown on error are two different sets, so we shouldn't reuse
17312 // normal children even if their identities match.
17313 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
17314 } else {
17315 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17316 } // Memoize state using the values we just used to render.
17317 // TODO: Restructure so we never read values from the instance.
17318
17319
17320 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
17321
17322 if (hasContext) {
17323 invalidateContextProvider(workInProgress, Component, true);
17324 }
17325
17326 return workInProgress.child;
17327 }
17328
17329 function pushHostRootContext(workInProgress) {
17330 var root = workInProgress.stateNode;
17331
17332 if (root.pendingContext) {
17333 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
17334 } else if (root.context) {
17335 // Should always be set
17336 pushTopLevelContextObject(workInProgress, root.context, false);
17337 }
17338
17339 pushHostContainer(workInProgress, root.containerInfo);
17340 }
17341
17342 function updateHostRoot(current, workInProgress, renderExpirationTime) {
17343 pushHostRootContext(workInProgress);
17344 var updateQueue = workInProgress.updateQueue;
17345
17346 if (!(current !== null && updateQueue !== null)) {
17347 {
17348 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." );
17349 }
17350 }
17351
17352 var nextProps = workInProgress.pendingProps;
17353 var prevState = workInProgress.memoizedState;
17354 var prevChildren = prevState !== null ? prevState.element : null;
17355 cloneUpdateQueue(current, workInProgress);
17356 processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);
17357 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
17358 // being called "element".
17359
17360 var nextChildren = nextState.element;
17361
17362 if (nextChildren === prevChildren) {
17363 // If the state is the same as before, that's a bailout because we had
17364 // no work that expires at this time.
17365 resetHydrationState();
17366 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
17367 }
17368
17369 var root = workInProgress.stateNode;
17370
17371 if (root.hydrate && enterHydrationState(workInProgress)) {
17372 // If we don't have any current children this might be the first pass.
17373 // We always try to hydrate. If this isn't a hydration pass there won't
17374 // be any children to hydrate which is effectively the same thing as
17375 // not hydrating.
17376 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
17377 workInProgress.child = child;
17378 var node = child;
17379
17380 while (node) {
17381 // Mark each child as hydrating. This is a fast path to know whether this
17382 // tree is part of a hydrating tree. This is used to determine if a child
17383 // node has fully mounted yet, and for scheduling event replaying.
17384 // Conceptually this is similar to Placement in that a new subtree is
17385 // inserted into the React tree here. It just happens to not need DOM
17386 // mutations because it already exists.
17387 node.effectTag = node.effectTag & ~Placement | Hydrating;
17388 node = node.sibling;
17389 }
17390 } else {
17391 // Otherwise reset hydration state in case we aborted and resumed another
17392 // root.
17393 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17394 resetHydrationState();
17395 }
17396
17397 return workInProgress.child;
17398 }
17399
17400 function updateHostComponent(current, workInProgress, renderExpirationTime) {
17401 pushHostContext(workInProgress);
17402
17403 if (current === null) {
17404 tryToClaimNextHydratableInstance(workInProgress);
17405 }
17406
17407 var type = workInProgress.type;
17408 var nextProps = workInProgress.pendingProps;
17409 var prevProps = current !== null ? current.memoizedProps : null;
17410 var nextChildren = nextProps.children;
17411 var isDirectTextChild = shouldSetTextContent(type, nextProps);
17412
17413 if (isDirectTextChild) {
17414 // We special case a direct text child of a host node. This is a common
17415 // case. We won't handle it as a reified child. We will instead handle
17416 // this in the host environment that also has access to this prop. That
17417 // avoids allocating another HostText fiber and traversing it.
17418 nextChildren = null;
17419 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
17420 // If we're switching from a direct text child to a normal child, or to
17421 // empty, we need to schedule the text content to be reset.
17422 workInProgress.effectTag |= ContentReset;
17423 }
17424
17425 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
17426
17427 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
17428 {
17429 markSpawnedWork(Never);
17430 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
17431
17432
17433 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
17434 return null;
17435 }
17436
17437 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
17438 return workInProgress.child;
17439 }
17440
17441 function updateHostText(current, workInProgress) {
17442 if (current === null) {
17443 tryToClaimNextHydratableInstance(workInProgress);
17444 } // Nothing to do here. This is terminal. We'll do the completion step
17445 // immediately after.
17446
17447
17448 return null;
17449 }
17450
17451 function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
17452 if (_current !== null) {
17453 // A lazy component only mounts if it suspended inside a non-
17454 // concurrent tree, in an inconsistent state. We want to treat it like
17455 // a new mount, even though an empty version of it already committed.
17456 // Disconnect the alternate pointers.
17457 _current.alternate = null;
17458 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17459
17460 workInProgress.effectTag |= Placement;
17461 }
17462
17463 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
17464 // Cancel and resume right after we know the tag.
17465
17466 cancelWorkTimer(workInProgress);
17467 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
17468
17469 workInProgress.type = Component;
17470 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
17471 startWorkTimer(workInProgress);
17472 var resolvedProps = resolveDefaultProps(Component, props);
17473 var child;
17474
17475 switch (resolvedTag) {
17476 case FunctionComponent:
17477 {
17478 {
17479 validateFunctionComponentInDev(workInProgress, Component);
17480 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
17481 }
17482
17483 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17484 return child;
17485 }
17486
17487 case ClassComponent:
17488 {
17489 {
17490 workInProgress.type = Component = resolveClassForHotReloading(Component);
17491 }
17492
17493 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17494 return child;
17495 }
17496
17497 case ForwardRef:
17498 {
17499 {
17500 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
17501 }
17502
17503 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17504 return child;
17505 }
17506
17507 case MemoComponent:
17508 {
17509 {
17510 if (workInProgress.type !== workInProgress.elementType) {
17511 var outerPropTypes = Component.propTypes;
17512
17513 if (outerPropTypes) {
17514 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
17515 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17516 }
17517 }
17518 }
17519
17520 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
17521 updateExpirationTime, renderExpirationTime);
17522 return child;
17523 }
17524 }
17525
17526 var hint = '';
17527
17528 {
17529 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
17530 hint = ' Did you wrap a component in React.lazy() more than once?';
17531 }
17532 } // This message intentionally doesn't mention ForwardRef or MemoComponent
17533 // because the fact that it's a separate type of work is an
17534 // implementation detail.
17535
17536
17537 {
17538 {
17539 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
17540 }
17541 }
17542 }
17543
17544 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
17545 if (_current !== null) {
17546 // An incomplete component only mounts if it suspended inside a non-
17547 // concurrent tree, in an inconsistent state. We want to treat it like
17548 // a new mount, even though an empty version of it already committed.
17549 // Disconnect the alternate pointers.
17550 _current.alternate = null;
17551 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17552
17553 workInProgress.effectTag |= Placement;
17554 } // Promote the fiber to a class and try rendering again.
17555
17556
17557 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
17558 // Push context providers early to prevent context stack mismatches.
17559 // During mounting we don't know the child context yet as the instance doesn't exist.
17560 // We will invalidate the child context in finishClassComponent() right after rendering.
17561
17562 var hasContext;
17563
17564 if (isContextProvider(Component)) {
17565 hasContext = true;
17566 pushContextProvider(workInProgress);
17567 } else {
17568 hasContext = false;
17569 }
17570
17571 prepareToReadContext(workInProgress, renderExpirationTime);
17572 constructClassInstance(workInProgress, Component, nextProps);
17573 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17574 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17575 }
17576
17577 function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
17578 if (_current !== null) {
17579 // An indeterminate component only mounts if it suspended inside a non-
17580 // concurrent tree, in an inconsistent state. We want to treat it like
17581 // a new mount, even though an empty version of it already committed.
17582 // Disconnect the alternate pointers.
17583 _current.alternate = null;
17584 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
17585
17586 workInProgress.effectTag |= Placement;
17587 }
17588
17589 var props = workInProgress.pendingProps;
17590 var context;
17591
17592 {
17593 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
17594 context = getMaskedContext(workInProgress, unmaskedContext);
17595 }
17596
17597 prepareToReadContext(workInProgress, renderExpirationTime);
17598 var value;
17599
17600 {
17601 if (Component.prototype && typeof Component.prototype.render === 'function') {
17602 var componentName = getComponentName(Component) || 'Unknown';
17603
17604 if (!didWarnAboutBadClass[componentName]) {
17605 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);
17606
17607 didWarnAboutBadClass[componentName] = true;
17608 }
17609 }
17610
17611 if (workInProgress.mode & StrictMode) {
17612 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
17613 }
17614
17615 setIsRendering(true);
17616 ReactCurrentOwner$1.current = workInProgress;
17617 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17618 setIsRendering(false);
17619 } // React DevTools reads this flag.
17620
17621
17622 workInProgress.effectTag |= PerformedWork;
17623
17624 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17625 {
17626 var _componentName = getComponentName(Component) || 'Unknown';
17627
17628 if (!didWarnAboutModulePatternComponent[_componentName]) {
17629 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);
17630
17631 didWarnAboutModulePatternComponent[_componentName] = true;
17632 }
17633 } // Proceed under the assumption that this is a class instance
17634
17635
17636 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
17637
17638 workInProgress.memoizedState = null;
17639 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
17640 // During mounting we don't know the child context yet as the instance doesn't exist.
17641 // We will invalidate the child context in finishClassComponent() right after rendering.
17642
17643 var hasContext = false;
17644
17645 if (isContextProvider(Component)) {
17646 hasContext = true;
17647 pushContextProvider(workInProgress);
17648 } else {
17649 hasContext = false;
17650 }
17651
17652 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
17653 initializeUpdateQueue(workInProgress);
17654 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
17655
17656 if (typeof getDerivedStateFromProps === 'function') {
17657 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
17658 }
17659
17660 adoptClassInstance(workInProgress, value);
17661 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
17662 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17663 } else {
17664 // Proceed under the assumption that this is a function component
17665 workInProgress.tag = FunctionComponent;
17666
17667 {
17668
17669 if ( workInProgress.mode & StrictMode) {
17670 // Only double-render components with Hooks
17671 if (workInProgress.memoizedState !== null) {
17672 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17673 }
17674 }
17675 }
17676
17677 reconcileChildren(null, workInProgress, value, renderExpirationTime);
17678
17679 {
17680 validateFunctionComponentInDev(workInProgress, Component);
17681 }
17682
17683 return workInProgress.child;
17684 }
17685 }
17686
17687 function validateFunctionComponentInDev(workInProgress, Component) {
17688 {
17689 if (Component) {
17690 if (Component.childContextTypes) {
17691 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
17692 }
17693 }
17694
17695 if (workInProgress.ref !== null) {
17696 var info = '';
17697 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
17698
17699 if (ownerName) {
17700 info += '\n\nCheck the render method of `' + ownerName + '`.';
17701 }
17702
17703 var warningKey = ownerName || workInProgress._debugID || '';
17704 var debugSource = workInProgress._debugSource;
17705
17706 if (debugSource) {
17707 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
17708 }
17709
17710 if (!didWarnAboutFunctionRefs[warningKey]) {
17711 didWarnAboutFunctionRefs[warningKey] = true;
17712
17713 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
17714 }
17715 }
17716
17717 if (typeof Component.getDerivedStateFromProps === 'function') {
17718 var _componentName2 = getComponentName(Component) || 'Unknown';
17719
17720 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
17721 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
17722
17723 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
17724 }
17725 }
17726
17727 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
17728 var _componentName3 = getComponentName(Component) || 'Unknown';
17729
17730 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
17731 error('%s: Function components do not support contextType.', _componentName3);
17732
17733 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
17734 }
17735 }
17736 }
17737 }
17738
17739 var SUSPENDED_MARKER = {
17740 dehydrated: null,
17741 retryTime: NoWork
17742 };
17743
17744 function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
17745 // If the context is telling us that we should show a fallback, and we're not
17746 // already showing content, then we should show the fallback instead.
17747 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
17748 }
17749
17750 function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
17751 var mode = workInProgress.mode;
17752 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
17753
17754 {
17755 if (shouldSuspend(workInProgress)) {
17756 workInProgress.effectTag |= DidCapture;
17757 }
17758 }
17759
17760 var suspenseContext = suspenseStackCursor.current;
17761 var nextDidTimeout = false;
17762 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
17763
17764 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
17765 // Something in this boundary's subtree already suspended. Switch to
17766 // rendering the fallback children.
17767 nextDidTimeout = true;
17768 workInProgress.effectTag &= ~DidCapture;
17769 } else {
17770 // Attempting the main content
17771 if (current === null || current.memoizedState !== null) {
17772 // This is a new mount or this boundary is already showing a fallback state.
17773 // Mark this subtree context as having at least one invisible parent that could
17774 // handle the fallback state.
17775 // Boundaries without fallbacks or should be avoided are not considered since
17776 // they cannot handle preferred fallback states.
17777 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
17778 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
17779 }
17780 }
17781 }
17782
17783 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
17784 pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to
17785 // showing the fallback children in place of the "primary" children.
17786 // However, we don't want to delete the primary children because then their
17787 // state will be lost (both the React state and the host state, e.g.
17788 // uncontrolled form inputs). Instead we keep them mounted and hide them.
17789 // Both the fallback children AND the primary children are rendered at the
17790 // same time. Once the primary children are un-suspended, we can delete
17791 // the fallback children — don't need to preserve their state.
17792 //
17793 // The two sets of children are siblings in the host environment, but
17794 // semantically, for purposes of reconciliation, they are two separate sets.
17795 // So we store them using two fragment fibers.
17796 //
17797 // However, we want to avoid allocating extra fibers for every placeholder.
17798 // They're only necessary when the children time out, because that's the
17799 // only time when both sets are mounted.
17800 //
17801 // So, the extra fragment fibers are only used if the children time out.
17802 // Otherwise, we render the primary children directly. This requires some
17803 // custom reconciliation logic to preserve the state of the primary
17804 // children. It's essentially a very basic form of re-parenting.
17805
17806 if (current === null) {
17807 // If we're currently hydrating, try to hydrate this boundary.
17808 // But only if this has a fallback.
17809 if (nextProps.fallback !== undefined) {
17810 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
17811 } // This is the initial mount. This branch is pretty simple because there's
17812 // no previous state that needs to be preserved.
17813
17814
17815 if (nextDidTimeout) {
17816 // Mount separate fragments for primary and fallback children.
17817 var nextFallbackChildren = nextProps.fallback;
17818 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
17819 primaryChildFragment.return = workInProgress;
17820
17821 if ((workInProgress.mode & BlockingMode) === NoMode) {
17822 // Outside of blocking mode, we commit the effects from the
17823 // partially completed, timed-out tree, too.
17824 var progressedState = workInProgress.memoizedState;
17825 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
17826 primaryChildFragment.child = progressedPrimaryChild;
17827 var progressedChild = progressedPrimaryChild;
17828
17829 while (progressedChild !== null) {
17830 progressedChild.return = primaryChildFragment;
17831 progressedChild = progressedChild.sibling;
17832 }
17833 }
17834
17835 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
17836 fallbackChildFragment.return = workInProgress;
17837 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
17838 // fallback children.
17839
17840 workInProgress.memoizedState = SUSPENDED_MARKER;
17841 workInProgress.child = primaryChildFragment;
17842 return fallbackChildFragment;
17843 } else {
17844 // Mount the primary children without an intermediate fragment fiber.
17845 var nextPrimaryChildren = nextProps.children;
17846 workInProgress.memoizedState = null;
17847 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
17848 }
17849 } else {
17850 // This is an update. This branch is more complicated because we need to
17851 // ensure the state of the primary children is preserved.
17852 var prevState = current.memoizedState;
17853
17854 if (prevState !== null) {
17855 // wrapped in a fragment fiber.
17856
17857
17858 var currentPrimaryChildFragment = current.child;
17859 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
17860
17861 if (nextDidTimeout) {
17862 // Still timed out. Reuse the current primary children by cloning
17863 // its fragment. We're going to skip over these entirely.
17864 var _nextFallbackChildren2 = nextProps.fallback;
17865
17866 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);
17867
17868 _primaryChildFragment2.return = workInProgress;
17869
17870 if ((workInProgress.mode & BlockingMode) === NoMode) {
17871 // Outside of blocking mode, we commit the effects from the
17872 // partially completed, timed-out tree, too.
17873 var _progressedState = workInProgress.memoizedState;
17874
17875 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
17876
17877 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
17878 _primaryChildFragment2.child = _progressedPrimaryChild;
17879 var _progressedChild2 = _progressedPrimaryChild;
17880
17881 while (_progressedChild2 !== null) {
17882 _progressedChild2.return = _primaryChildFragment2;
17883 _progressedChild2 = _progressedChild2.sibling;
17884 }
17885 }
17886 } // Because primaryChildFragment is a new fiber that we're inserting as the
17887 // parent of a new tree, we need to set its treeBaseDuration.
17888
17889
17890 if ( workInProgress.mode & ProfileMode) {
17891 // treeBaseDuration is the sum of all the child tree base durations.
17892 var _treeBaseDuration = 0;
17893 var _hiddenChild = _primaryChildFragment2.child;
17894
17895 while (_hiddenChild !== null) {
17896 _treeBaseDuration += _hiddenChild.treeBaseDuration;
17897 _hiddenChild = _hiddenChild.sibling;
17898 }
17899
17900 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
17901 } // Clone the fallback child fragment, too. These we'll continue
17902 // working on.
17903
17904
17905 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);
17906
17907 _fallbackChildFragment2.return = workInProgress;
17908 _primaryChildFragment2.sibling = _fallbackChildFragment2;
17909 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
17910 // fallback children.
17911
17912 workInProgress.memoizedState = SUSPENDED_MARKER;
17913 workInProgress.child = _primaryChildFragment2;
17914 return _fallbackChildFragment2;
17915 } else {
17916 // No longer suspended. Switch back to showing the primary children,
17917 // and remove the intermediate fragment fiber.
17918 var _nextPrimaryChildren = nextProps.children;
17919 var currentPrimaryChild = currentPrimaryChildFragment.child;
17920 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
17921 // children. Wait until the complete phase, after we've confirmed the
17922 // fallback is no longer needed.
17923 // TODO: Would it be better to store the fallback fragment on
17924 // the stateNode?
17925 // Continue rendering the children, like we normally do.
17926
17927 workInProgress.memoizedState = null;
17928 return workInProgress.child = primaryChild;
17929 }
17930 } else {
17931 // The current tree has not already timed out. That means the primary
17932 // children are not wrapped in a fragment fiber.
17933 var _currentPrimaryChild = current.child;
17934
17935 if (nextDidTimeout) {
17936 // Timed out. Wrap the children in a fragment fiber to keep them
17937 // separate from the fallback children.
17938 var _nextFallbackChildren3 = nextProps.fallback;
17939
17940 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
17941 // going to render this fragment.
17942 null, mode, NoWork, null);
17943
17944 _primaryChildFragment3.return = workInProgress;
17945 _primaryChildFragment3.child = _currentPrimaryChild;
17946
17947 if (_currentPrimaryChild !== null) {
17948 _currentPrimaryChild.return = _primaryChildFragment3;
17949 } // Even though we're creating a new fiber, there are no new children,
17950 // because we're reusing an already mounted tree. So we don't need to
17951 // schedule a placement.
17952 // primaryChildFragment.effectTag |= Placement;
17953
17954
17955 if ((workInProgress.mode & BlockingMode) === NoMode) {
17956 // Outside of blocking mode, we commit the effects from the
17957 // partially completed, timed-out tree, too.
17958 var _progressedState2 = workInProgress.memoizedState;
17959
17960 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
17961
17962 _primaryChildFragment3.child = _progressedPrimaryChild2;
17963 var _progressedChild3 = _progressedPrimaryChild2;
17964
17965 while (_progressedChild3 !== null) {
17966 _progressedChild3.return = _primaryChildFragment3;
17967 _progressedChild3 = _progressedChild3.sibling;
17968 }
17969 } // Because primaryChildFragment is a new fiber that we're inserting as the
17970 // parent of a new tree, we need to set its treeBaseDuration.
17971
17972
17973 if ( workInProgress.mode & ProfileMode) {
17974 // treeBaseDuration is the sum of all the child tree base durations.
17975 var _treeBaseDuration2 = 0;
17976 var _hiddenChild2 = _primaryChildFragment3.child;
17977
17978 while (_hiddenChild2 !== null) {
17979 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
17980 _hiddenChild2 = _hiddenChild2.sibling;
17981 }
17982
17983 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
17984 } // Create a fragment from the fallback children, too.
17985
17986
17987 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
17988
17989 _fallbackChildFragment3.return = workInProgress;
17990 _primaryChildFragment3.sibling = _fallbackChildFragment3;
17991 _fallbackChildFragment3.effectTag |= Placement;
17992 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
17993 // fallback children.
17994
17995 workInProgress.memoizedState = SUSPENDED_MARKER;
17996 workInProgress.child = _primaryChildFragment3;
17997 return _fallbackChildFragment3;
17998 } else {
17999 // Still haven't timed out. Continue rendering the children, like we
18000 // normally do.
18001 workInProgress.memoizedState = null;
18002 var _nextPrimaryChildren2 = nextProps.children;
18003 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
18004 }
18005 }
18006 }
18007 }
18008
18009 function scheduleWorkOnFiber(fiber, renderExpirationTime) {
18010 if (fiber.expirationTime < renderExpirationTime) {
18011 fiber.expirationTime = renderExpirationTime;
18012 }
18013
18014 var alternate = fiber.alternate;
18015
18016 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
18017 alternate.expirationTime = renderExpirationTime;
18018 }
18019
18020 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
18021 }
18022
18023 function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
18024 // Mark any Suspense boundaries with fallbacks as having work to do.
18025 // If they were previously forced into fallbacks, they may now be able
18026 // to unblock.
18027 var node = firstChild;
18028
18029 while (node !== null) {
18030 if (node.tag === SuspenseComponent) {
18031 var state = node.memoizedState;
18032
18033 if (state !== null) {
18034 scheduleWorkOnFiber(node, renderExpirationTime);
18035 }
18036 } else if (node.tag === SuspenseListComponent) {
18037 // If the tail is hidden there might not be an Suspense boundaries
18038 // to schedule work on. In this case we have to schedule it on the
18039 // list itself.
18040 // We don't have to traverse to the children of the list since
18041 // the list will propagate the change when it rerenders.
18042 scheduleWorkOnFiber(node, renderExpirationTime);
18043 } else if (node.child !== null) {
18044 node.child.return = node;
18045 node = node.child;
18046 continue;
18047 }
18048
18049 if (node === workInProgress) {
18050 return;
18051 }
18052
18053 while (node.sibling === null) {
18054 if (node.return === null || node.return === workInProgress) {
18055 return;
18056 }
18057
18058 node = node.return;
18059 }
18060
18061 node.sibling.return = node.return;
18062 node = node.sibling;
18063 }
18064 }
18065
18066 function findLastContentRow(firstChild) {
18067 // This is going to find the last row among these children that is already
18068 // showing content on the screen, as opposed to being in fallback state or
18069 // new. If a row has multiple Suspense boundaries, any of them being in the
18070 // fallback state, counts as the whole row being in a fallback state.
18071 // Note that the "rows" will be workInProgress, but any nested children
18072 // will still be current since we haven't rendered them yet. The mounted
18073 // order may not be the same as the new order. We use the new order.
18074 var row = firstChild;
18075 var lastContentRow = null;
18076
18077 while (row !== null) {
18078 var currentRow = row.alternate; // New rows can't be content rows.
18079
18080 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18081 lastContentRow = row;
18082 }
18083
18084 row = row.sibling;
18085 }
18086
18087 return lastContentRow;
18088 }
18089
18090 function validateRevealOrder(revealOrder) {
18091 {
18092 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
18093 didWarnAboutRevealOrder[revealOrder] = true;
18094
18095 if (typeof revealOrder === 'string') {
18096 switch (revealOrder.toLowerCase()) {
18097 case 'together':
18098 case 'forwards':
18099 case 'backwards':
18100 {
18101 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
18102
18103 break;
18104 }
18105
18106 case 'forward':
18107 case 'backward':
18108 {
18109 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());
18110
18111 break;
18112 }
18113
18114 default:
18115 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18116
18117 break;
18118 }
18119 } else {
18120 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18121 }
18122 }
18123 }
18124 }
18125
18126 function validateTailOptions(tailMode, revealOrder) {
18127 {
18128 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
18129 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
18130 didWarnAboutTailOptions[tailMode] = true;
18131
18132 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
18133 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
18134 didWarnAboutTailOptions[tailMode] = true;
18135
18136 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
18137 }
18138 }
18139 }
18140 }
18141
18142 function validateSuspenseListNestedChild(childSlot, index) {
18143 {
18144 var isArray = Array.isArray(childSlot);
18145 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
18146
18147 if (isArray || isIterable) {
18148 var type = isArray ? 'array' : 'iterable';
18149
18150 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);
18151
18152 return false;
18153 }
18154 }
18155
18156 return true;
18157 }
18158
18159 function validateSuspenseListChildren(children, revealOrder) {
18160 {
18161 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
18162 if (Array.isArray(children)) {
18163 for (var i = 0; i < children.length; i++) {
18164 if (!validateSuspenseListNestedChild(children[i], i)) {
18165 return;
18166 }
18167 }
18168 } else {
18169 var iteratorFn = getIteratorFn(children);
18170
18171 if (typeof iteratorFn === 'function') {
18172 var childrenIterator = iteratorFn.call(children);
18173
18174 if (childrenIterator) {
18175 var step = childrenIterator.next();
18176 var _i = 0;
18177
18178 for (; !step.done; step = childrenIterator.next()) {
18179 if (!validateSuspenseListNestedChild(step.value, _i)) {
18180 return;
18181 }
18182
18183 _i++;
18184 }
18185 }
18186 } else {
18187 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);
18188 }
18189 }
18190 }
18191 }
18192 }
18193
18194 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
18195 var renderState = workInProgress.memoizedState;
18196
18197 if (renderState === null) {
18198 workInProgress.memoizedState = {
18199 isBackwards: isBackwards,
18200 rendering: null,
18201 renderingStartTime: 0,
18202 last: lastContentRow,
18203 tail: tail,
18204 tailExpiration: 0,
18205 tailMode: tailMode,
18206 lastEffect: lastEffectBeforeRendering
18207 };
18208 } else {
18209 // We can reuse the existing object from previous renders.
18210 renderState.isBackwards = isBackwards;
18211 renderState.rendering = null;
18212 renderState.renderingStartTime = 0;
18213 renderState.last = lastContentRow;
18214 renderState.tail = tail;
18215 renderState.tailExpiration = 0;
18216 renderState.tailMode = tailMode;
18217 renderState.lastEffect = lastEffectBeforeRendering;
18218 }
18219 } // This can end up rendering this component multiple passes.
18220 // The first pass splits the children fibers into two sets. A head and tail.
18221 // We first render the head. If anything is in fallback state, we do another
18222 // pass through beginWork to rerender all children (including the tail) with
18223 // the force suspend context. If the first render didn't have anything in
18224 // in fallback state. Then we render each row in the tail one-by-one.
18225 // That happens in the completeWork phase without going back to beginWork.
18226
18227
18228 function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
18229 var nextProps = workInProgress.pendingProps;
18230 var revealOrder = nextProps.revealOrder;
18231 var tailMode = nextProps.tail;
18232 var newChildren = nextProps.children;
18233 validateRevealOrder(revealOrder);
18234 validateTailOptions(tailMode, revealOrder);
18235 validateSuspenseListChildren(newChildren, revealOrder);
18236 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18237 var suspenseContext = suspenseStackCursor.current;
18238 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
18239
18240 if (shouldForceFallback) {
18241 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
18242 workInProgress.effectTag |= DidCapture;
18243 } else {
18244 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
18245
18246 if (didSuspendBefore) {
18247 // If we previously forced a fallback, we need to schedule work
18248 // on any nested boundaries to let them know to try to render
18249 // again. This is the same as context updating.
18250 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
18251 }
18252
18253 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18254 }
18255
18256 pushSuspenseContext(workInProgress, suspenseContext);
18257
18258 if ((workInProgress.mode & BlockingMode) === NoMode) {
18259 // Outside of blocking mode, SuspenseList doesn't work so we just
18260 // use make it a noop by treating it as the default revealOrder.
18261 workInProgress.memoizedState = null;
18262 } else {
18263 switch (revealOrder) {
18264 case 'forwards':
18265 {
18266 var lastContentRow = findLastContentRow(workInProgress.child);
18267 var tail;
18268
18269 if (lastContentRow === null) {
18270 // The whole list is part of the tail.
18271 // TODO: We could fast path by just rendering the tail now.
18272 tail = workInProgress.child;
18273 workInProgress.child = null;
18274 } else {
18275 // Disconnect the tail rows after the content row.
18276 // We're going to render them separately later.
18277 tail = lastContentRow.sibling;
18278 lastContentRow.sibling = null;
18279 }
18280
18281 initSuspenseListRenderState(workInProgress, false, // isBackwards
18282 tail, lastContentRow, tailMode, workInProgress.lastEffect);
18283 break;
18284 }
18285
18286 case 'backwards':
18287 {
18288 // We're going to find the first row that has existing content.
18289 // At the same time we're going to reverse the list of everything
18290 // we pass in the meantime. That's going to be our tail in reverse
18291 // order.
18292 var _tail = null;
18293 var row = workInProgress.child;
18294 workInProgress.child = null;
18295
18296 while (row !== null) {
18297 var currentRow = row.alternate; // New rows can't be content rows.
18298
18299 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18300 // This is the beginning of the main content.
18301 workInProgress.child = row;
18302 break;
18303 }
18304
18305 var nextRow = row.sibling;
18306 row.sibling = _tail;
18307 _tail = row;
18308 row = nextRow;
18309 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
18310
18311
18312 initSuspenseListRenderState(workInProgress, true, // isBackwards
18313 _tail, null, // last
18314 tailMode, workInProgress.lastEffect);
18315 break;
18316 }
18317
18318 case 'together':
18319 {
18320 initSuspenseListRenderState(workInProgress, false, // isBackwards
18321 null, // tail
18322 null, // last
18323 undefined, workInProgress.lastEffect);
18324 break;
18325 }
18326
18327 default:
18328 {
18329 // The default reveal order is the same as not having
18330 // a boundary.
18331 workInProgress.memoizedState = null;
18332 }
18333 }
18334 }
18335
18336 return workInProgress.child;
18337 }
18338
18339 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
18340 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18341 var nextChildren = workInProgress.pendingProps;
18342
18343 if (current === null) {
18344 // Portals are special because we don't append the children during mount
18345 // but at commit. Therefore we need to track insertions which the normal
18346 // flow doesn't do during mount. This doesn't happen at the root because
18347 // the root always starts with a "current" with a null child.
18348 // TODO: Consider unifying this with how the root works.
18349 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
18350 } else {
18351 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
18352 }
18353
18354 return workInProgress.child;
18355 }
18356
18357 function updateContextProvider(current, workInProgress, renderExpirationTime) {
18358 var providerType = workInProgress.type;
18359 var context = providerType._context;
18360 var newProps = workInProgress.pendingProps;
18361 var oldProps = workInProgress.memoizedProps;
18362 var newValue = newProps.value;
18363
18364 {
18365 var providerPropTypes = workInProgress.type.propTypes;
18366
18367 if (providerPropTypes) {
18368 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
18369 }
18370 }
18371
18372 pushProvider(workInProgress, newValue);
18373
18374 if (oldProps !== null) {
18375 var oldValue = oldProps.value;
18376 var changedBits = calculateChangedBits(context, newValue, oldValue);
18377
18378 if (changedBits === 0) {
18379 // No change. Bailout early if children are the same.
18380 if (oldProps.children === newProps.children && !hasContextChanged()) {
18381 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18382 }
18383 } else {
18384 // The context value changed. Search for matching consumers and schedule
18385 // them to update.
18386 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
18387 }
18388 }
18389
18390 var newChildren = newProps.children;
18391 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18392 return workInProgress.child;
18393 }
18394
18395 var hasWarnedAboutUsingContextAsConsumer = false;
18396
18397 function updateContextConsumer(current, workInProgress, renderExpirationTime) {
18398 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
18399 // DEV mode, we create a separate object for Context.Consumer that acts
18400 // like a proxy to Context. This proxy object adds unnecessary code in PROD
18401 // so we use the old behaviour (Context.Consumer references Context) to
18402 // reduce size and overhead. The separate object references context via
18403 // a property called "_context", which also gives us the ability to check
18404 // in DEV mode if this property exists or not and warn if it does not.
18405
18406 {
18407 if (context._context === undefined) {
18408 // This may be because it's a Context (rather than a Consumer).
18409 // Or it may be because it's older React where they're the same thing.
18410 // We only want to warn if we're sure it's a new React.
18411 if (context !== context.Consumer) {
18412 if (!hasWarnedAboutUsingContextAsConsumer) {
18413 hasWarnedAboutUsingContextAsConsumer = true;
18414
18415 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
18416 }
18417 }
18418 } else {
18419 context = context._context;
18420 }
18421 }
18422
18423 var newProps = workInProgress.pendingProps;
18424 var render = newProps.children;
18425
18426 {
18427 if (typeof render !== 'function') {
18428 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.');
18429 }
18430 }
18431
18432 prepareToReadContext(workInProgress, renderExpirationTime);
18433 var newValue = readContext(context, newProps.unstable_observedBits);
18434 var newChildren;
18435
18436 {
18437 ReactCurrentOwner$1.current = workInProgress;
18438 setIsRendering(true);
18439 newChildren = render(newValue);
18440 setIsRendering(false);
18441 } // React DevTools reads this flag.
18442
18443
18444 workInProgress.effectTag |= PerformedWork;
18445 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
18446 return workInProgress.child;
18447 }
18448
18449 function markWorkInProgressReceivedUpdate() {
18450 didReceiveUpdate = true;
18451 }
18452
18453 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
18454 cancelWorkTimer(workInProgress);
18455
18456 if (current !== null) {
18457 // Reuse previous dependencies
18458 workInProgress.dependencies = current.dependencies;
18459 }
18460
18461 {
18462 // Don't update "base" render times for bailouts.
18463 stopProfilerTimerIfRunning();
18464 }
18465
18466 var updateExpirationTime = workInProgress.expirationTime;
18467
18468 if (updateExpirationTime !== NoWork) {
18469 markUnprocessedUpdateTime(updateExpirationTime);
18470 } // Check if the children have any pending work.
18471
18472
18473 var childExpirationTime = workInProgress.childExpirationTime;
18474
18475 if (childExpirationTime < renderExpirationTime) {
18476 // The children don't have any work either. We can skip them.
18477 // TODO: Once we add back resuming, we should check if the children are
18478 // a work-in-progress set. If so, we need to transfer their effects.
18479 return null;
18480 } else {
18481 // This fiber doesn't have work, but its subtree does. Clone the child
18482 // fibers and continue.
18483 cloneChildFibers(current, workInProgress);
18484 return workInProgress.child;
18485 }
18486 }
18487
18488 function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
18489 {
18490 var returnFiber = oldWorkInProgress.return;
18491
18492 if (returnFiber === null) {
18493 throw new Error('Cannot swap the root fiber.');
18494 } // Disconnect from the old current.
18495 // It will get deleted.
18496
18497
18498 current.alternate = null;
18499 oldWorkInProgress.alternate = null; // Connect to the new tree.
18500
18501 newWorkInProgress.index = oldWorkInProgress.index;
18502 newWorkInProgress.sibling = oldWorkInProgress.sibling;
18503 newWorkInProgress.return = oldWorkInProgress.return;
18504 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
18505
18506 if (oldWorkInProgress === returnFiber.child) {
18507 returnFiber.child = newWorkInProgress;
18508 } else {
18509 var prevSibling = returnFiber.child;
18510
18511 if (prevSibling === null) {
18512 throw new Error('Expected parent to have a child.');
18513 }
18514
18515 while (prevSibling.sibling !== oldWorkInProgress) {
18516 prevSibling = prevSibling.sibling;
18517
18518 if (prevSibling === null) {
18519 throw new Error('Expected to find the previous sibling.');
18520 }
18521 }
18522
18523 prevSibling.sibling = newWorkInProgress;
18524 } // Delete the old fiber and place the new one.
18525 // Since the old fiber is disconnected, we have to schedule it manually.
18526
18527
18528 var last = returnFiber.lastEffect;
18529
18530 if (last !== null) {
18531 last.nextEffect = current;
18532 returnFiber.lastEffect = current;
18533 } else {
18534 returnFiber.firstEffect = returnFiber.lastEffect = current;
18535 }
18536
18537 current.nextEffect = null;
18538 current.effectTag = Deletion;
18539 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
18540
18541 return newWorkInProgress;
18542 }
18543 }
18544
18545 function beginWork(current, workInProgress, renderExpirationTime) {
18546 var updateExpirationTime = workInProgress.expirationTime;
18547
18548 {
18549 if (workInProgress._debugNeedsRemount && current !== null) {
18550 // This will restart the begin phase with a new fiber.
18551 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
18552 }
18553 }
18554
18555 if (current !== null) {
18556 var oldProps = current.memoizedProps;
18557 var newProps = workInProgress.pendingProps;
18558
18559 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
18560 workInProgress.type !== current.type )) {
18561 // If props or context changed, mark the fiber as having performed work.
18562 // This may be unset if the props are determined to be equal later (memo).
18563 didReceiveUpdate = true;
18564 } else if (updateExpirationTime < renderExpirationTime) {
18565 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
18566 // the begin phase. There's still some bookkeeping we that needs to be done
18567 // in this optimized path, mostly pushing stuff onto the stack.
18568
18569 switch (workInProgress.tag) {
18570 case HostRoot:
18571 pushHostRootContext(workInProgress);
18572 resetHydrationState();
18573 break;
18574
18575 case HostComponent:
18576 pushHostContext(workInProgress);
18577
18578 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
18579 {
18580 markSpawnedWork(Never);
18581 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
18582
18583
18584 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
18585 return null;
18586 }
18587
18588 break;
18589
18590 case ClassComponent:
18591 {
18592 var Component = workInProgress.type;
18593
18594 if (isContextProvider(Component)) {
18595 pushContextProvider(workInProgress);
18596 }
18597
18598 break;
18599 }
18600
18601 case HostPortal:
18602 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18603 break;
18604
18605 case ContextProvider:
18606 {
18607 var newValue = workInProgress.memoizedProps.value;
18608 pushProvider(workInProgress, newValue);
18609 break;
18610 }
18611
18612 case Profiler:
18613 {
18614 // Profiler should only call onRender when one of its descendants actually rendered.
18615 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
18616
18617 if (hasChildWork) {
18618 workInProgress.effectTag |= Update;
18619 }
18620 }
18621
18622 break;
18623
18624 case SuspenseComponent:
18625 {
18626 var state = workInProgress.memoizedState;
18627
18628 if (state !== null) {
18629 // whether to retry the primary children, or to skip over it and
18630 // go straight to the fallback. Check the priority of the primary
18631 // child fragment.
18632
18633
18634 var primaryChildFragment = workInProgress.child;
18635 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
18636
18637 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
18638 // The primary children have pending work. Use the normal path
18639 // to attempt to render the primary children again.
18640 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
18641 } else {
18642 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
18643 // priority. Bailout.
18644
18645 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18646
18647 if (child !== null) {
18648 // The fallback children have pending work. Skip over the
18649 // primary children and work on the fallback.
18650 return child.sibling;
18651 } else {
18652 return null;
18653 }
18654 }
18655 } else {
18656 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18657 }
18658
18659 break;
18660 }
18661
18662 case SuspenseListComponent:
18663 {
18664 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
18665
18666 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
18667
18668 if (didSuspendBefore) {
18669 if (_hasChildWork) {
18670 // If something was in fallback state last time, and we have all the
18671 // same children then we're still in progressive loading state.
18672 // Something might get unblocked by state updates or retries in the
18673 // tree which will affect the tail. So we need to use the normal
18674 // path to compute the correct tail.
18675 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
18676 } // If none of the children had any work, that means that none of
18677 // them got retried so they'll still be blocked in the same way
18678 // as before. We can fast bail out.
18679
18680
18681 workInProgress.effectTag |= DidCapture;
18682 } // If nothing suspended before and we're rendering the same children,
18683 // then the tail doesn't matter. Anything new that suspends will work
18684 // in the "together" mode, so we can continue from the state we had.
18685
18686
18687 var renderState = workInProgress.memoizedState;
18688
18689 if (renderState !== null) {
18690 // Reset to the "together" mode in case we've started a different
18691 // update in the past but didn't complete it.
18692 renderState.rendering = null;
18693 renderState.tail = null;
18694 }
18695
18696 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
18697
18698 if (_hasChildWork) {
18699 break;
18700 } else {
18701 // If none of the children had any work, that means that none of
18702 // them got retried so they'll still be blocked in the same way
18703 // as before. We can fast bail out.
18704 return null;
18705 }
18706 }
18707 }
18708
18709 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
18710 } else {
18711 // An update was scheduled on this fiber, but there are no new props
18712 // nor legacy context. Set this to false. If an update queue or context
18713 // consumer produces a changed value, it will set this to true. Otherwise,
18714 // the component will assume the children have not changed and bail out.
18715 didReceiveUpdate = false;
18716 }
18717 } else {
18718 didReceiveUpdate = false;
18719 } // Before entering the begin phase, clear pending update priority.
18720 // TODO: This assumes that we're about to evaluate the component and process
18721 // the update queue. However, there's an exception: SimpleMemoComponent
18722 // sometimes bails out later in the begin phase. This indicates that we should
18723 // move this assignment out of the common path and into each branch.
18724
18725
18726 workInProgress.expirationTime = NoWork;
18727
18728 switch (workInProgress.tag) {
18729 case IndeterminateComponent:
18730 {
18731 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
18732 }
18733
18734 case LazyComponent:
18735 {
18736 var elementType = workInProgress.elementType;
18737 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
18738 }
18739
18740 case FunctionComponent:
18741 {
18742 var _Component = workInProgress.type;
18743 var unresolvedProps = workInProgress.pendingProps;
18744 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
18745 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
18746 }
18747
18748 case ClassComponent:
18749 {
18750 var _Component2 = workInProgress.type;
18751 var _unresolvedProps = workInProgress.pendingProps;
18752
18753 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
18754
18755 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
18756 }
18757
18758 case HostRoot:
18759 return updateHostRoot(current, workInProgress, renderExpirationTime);
18760
18761 case HostComponent:
18762 return updateHostComponent(current, workInProgress, renderExpirationTime);
18763
18764 case HostText:
18765 return updateHostText(current, workInProgress);
18766
18767 case SuspenseComponent:
18768 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
18769
18770 case HostPortal:
18771 return updatePortalComponent(current, workInProgress, renderExpirationTime);
18772
18773 case ForwardRef:
18774 {
18775 var type = workInProgress.type;
18776 var _unresolvedProps2 = workInProgress.pendingProps;
18777
18778 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
18779
18780 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
18781 }
18782
18783 case Fragment:
18784 return updateFragment(current, workInProgress, renderExpirationTime);
18785
18786 case Mode:
18787 return updateMode(current, workInProgress, renderExpirationTime);
18788
18789 case Profiler:
18790 return updateProfiler(current, workInProgress, renderExpirationTime);
18791
18792 case ContextProvider:
18793 return updateContextProvider(current, workInProgress, renderExpirationTime);
18794
18795 case ContextConsumer:
18796 return updateContextConsumer(current, workInProgress, renderExpirationTime);
18797
18798 case MemoComponent:
18799 {
18800 var _type2 = workInProgress.type;
18801 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
18802
18803 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
18804
18805 {
18806 if (workInProgress.type !== workInProgress.elementType) {
18807 var outerPropTypes = _type2.propTypes;
18808
18809 if (outerPropTypes) {
18810 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
18811 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
18812 }
18813 }
18814 }
18815
18816 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
18817 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
18818 }
18819
18820 case SimpleMemoComponent:
18821 {
18822 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
18823 }
18824
18825 case IncompleteClassComponent:
18826 {
18827 var _Component3 = workInProgress.type;
18828 var _unresolvedProps4 = workInProgress.pendingProps;
18829
18830 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
18831
18832 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
18833 }
18834
18835 case SuspenseListComponent:
18836 {
18837 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
18838 }
18839 }
18840
18841 {
18842 {
18843 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
18844 }
18845 }
18846 }
18847
18848 function markUpdate(workInProgress) {
18849 // Tag the fiber with an update effect. This turns a Placement into
18850 // a PlacementAndUpdate.
18851 workInProgress.effectTag |= Update;
18852 }
18853
18854 function markRef$1(workInProgress) {
18855 workInProgress.effectTag |= Ref;
18856 }
18857
18858 var appendAllChildren;
18859 var updateHostContainer;
18860 var updateHostComponent$1;
18861 var updateHostText$1;
18862
18863 {
18864 // Mutation mode
18865 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
18866 // We only have the top Fiber that was created but we need recurse down its
18867 // children to find all the terminal nodes.
18868 var node = workInProgress.child;
18869
18870 while (node !== null) {
18871 if (node.tag === HostComponent || node.tag === HostText) {
18872 appendInitialChild(parent, node.stateNode);
18873 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
18874 node.child.return = node;
18875 node = node.child;
18876 continue;
18877 }
18878
18879 if (node === workInProgress) {
18880 return;
18881 }
18882
18883 while (node.sibling === null) {
18884 if (node.return === null || node.return === workInProgress) {
18885 return;
18886 }
18887
18888 node = node.return;
18889 }
18890
18891 node.sibling.return = node.return;
18892 node = node.sibling;
18893 }
18894 };
18895
18896 updateHostContainer = function (workInProgress) {// Noop
18897 };
18898
18899 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
18900 // If we have an alternate, that means this is an update and we need to
18901 // schedule a side-effect to do the updates.
18902 var oldProps = current.memoizedProps;
18903
18904 if (oldProps === newProps) {
18905 // In mutation mode, this is sufficient for a bailout because
18906 // we won't touch this node even if children changed.
18907 return;
18908 } // If we get updated because one of our children updated, we don't
18909 // have newProps so we'll have to reuse them.
18910 // TODO: Split the update API as separate for the props vs. children.
18911 // Even better would be if children weren't special cased at all tho.
18912
18913
18914 var instance = workInProgress.stateNode;
18915 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
18916 // component is hitting the resume path. Figure out why. Possibly
18917 // related to `hidden`.
18918
18919 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
18920
18921 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
18922 // is a new ref we mark this as an update. All the work is done in commitWork.
18923
18924 if (updatePayload) {
18925 markUpdate(workInProgress);
18926 }
18927 };
18928
18929 updateHostText$1 = function (current, workInProgress, oldText, newText) {
18930 // If the text differs, mark it as an update. All the work in done in commitWork.
18931 if (oldText !== newText) {
18932 markUpdate(workInProgress);
18933 }
18934 };
18935 }
18936
18937 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
18938 switch (renderState.tailMode) {
18939 case 'hidden':
18940 {
18941 // Any insertions at the end of the tail list after this point
18942 // should be invisible. If there are already mounted boundaries
18943 // anything before them are not considered for collapsing.
18944 // Therefore we need to go through the whole tail to find if
18945 // there are any.
18946 var tailNode = renderState.tail;
18947 var lastTailNode = null;
18948
18949 while (tailNode !== null) {
18950 if (tailNode.alternate !== null) {
18951 lastTailNode = tailNode;
18952 }
18953
18954 tailNode = tailNode.sibling;
18955 } // Next we're simply going to delete all insertions after the
18956 // last rendered item.
18957
18958
18959 if (lastTailNode === null) {
18960 // All remaining items in the tail are insertions.
18961 renderState.tail = null;
18962 } else {
18963 // Detach the insertion after the last node that was already
18964 // inserted.
18965 lastTailNode.sibling = null;
18966 }
18967
18968 break;
18969 }
18970
18971 case 'collapsed':
18972 {
18973 // Any insertions at the end of the tail list after this point
18974 // should be invisible. If there are already mounted boundaries
18975 // anything before them are not considered for collapsing.
18976 // Therefore we need to go through the whole tail to find if
18977 // there are any.
18978 var _tailNode = renderState.tail;
18979 var _lastTailNode = null;
18980
18981 while (_tailNode !== null) {
18982 if (_tailNode.alternate !== null) {
18983 _lastTailNode = _tailNode;
18984 }
18985
18986 _tailNode = _tailNode.sibling;
18987 } // Next we're simply going to delete all insertions after the
18988 // last rendered item.
18989
18990
18991 if (_lastTailNode === null) {
18992 // All remaining items in the tail are insertions.
18993 if (!hasRenderedATailFallback && renderState.tail !== null) {
18994 // We suspended during the head. We want to show at least one
18995 // row at the tail. So we'll keep on and cut off the rest.
18996 renderState.tail.sibling = null;
18997 } else {
18998 renderState.tail = null;
18999 }
19000 } else {
19001 // Detach the insertion after the last node that was already
19002 // inserted.
19003 _lastTailNode.sibling = null;
19004 }
19005
19006 break;
19007 }
19008 }
19009 }
19010
19011 function completeWork(current, workInProgress, renderExpirationTime) {
19012 var newProps = workInProgress.pendingProps;
19013
19014 switch (workInProgress.tag) {
19015 case IndeterminateComponent:
19016 case LazyComponent:
19017 case SimpleMemoComponent:
19018 case FunctionComponent:
19019 case ForwardRef:
19020 case Fragment:
19021 case Mode:
19022 case Profiler:
19023 case ContextConsumer:
19024 case MemoComponent:
19025 return null;
19026
19027 case ClassComponent:
19028 {
19029 var Component = workInProgress.type;
19030
19031 if (isContextProvider(Component)) {
19032 popContext(workInProgress);
19033 }
19034
19035 return null;
19036 }
19037
19038 case HostRoot:
19039 {
19040 popHostContainer(workInProgress);
19041 popTopLevelContextObject(workInProgress);
19042 var fiberRoot = workInProgress.stateNode;
19043
19044 if (fiberRoot.pendingContext) {
19045 fiberRoot.context = fiberRoot.pendingContext;
19046 fiberRoot.pendingContext = null;
19047 }
19048
19049 if (current === null || current.child === null) {
19050 // If we hydrated, pop so that we can delete any remaining children
19051 // that weren't hydrated.
19052 var wasHydrated = popHydrationState(workInProgress);
19053
19054 if (wasHydrated) {
19055 // If we hydrated, then we'll need to schedule an update for
19056 // the commit side-effects on the root.
19057 markUpdate(workInProgress);
19058 }
19059 }
19060
19061 updateHostContainer(workInProgress);
19062 return null;
19063 }
19064
19065 case HostComponent:
19066 {
19067 popHostContext(workInProgress);
19068 var rootContainerInstance = getRootHostContainer();
19069 var type = workInProgress.type;
19070
19071 if (current !== null && workInProgress.stateNode != null) {
19072 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
19073
19074 if (current.ref !== workInProgress.ref) {
19075 markRef$1(workInProgress);
19076 }
19077 } else {
19078 if (!newProps) {
19079 if (!(workInProgress.stateNode !== null)) {
19080 {
19081 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19082 }
19083 } // This can happen when we abort work.
19084
19085
19086 return null;
19087 }
19088
19089 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
19090 // "stack" as the parent. Then append children as we go in beginWork
19091 // or completeWork depending on whether we want to add them top->down or
19092 // bottom->up. Top->down is faster in IE11.
19093
19094 var _wasHydrated = popHydrationState(workInProgress);
19095
19096 if (_wasHydrated) {
19097 // TODO: Move this and createInstance step into the beginPhase
19098 // to consolidate.
19099 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
19100 // If changes to the hydrated node need to be applied at the
19101 // commit-phase we mark this as such.
19102 markUpdate(workInProgress);
19103 }
19104 } else {
19105 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
19106 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
19107
19108 workInProgress.stateNode = instance;
19109 // (eg DOM renderer supports auto-focus for certain elements).
19110 // Make sure such renderers get scheduled for later work.
19111
19112
19113 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
19114 markUpdate(workInProgress);
19115 }
19116 }
19117
19118 if (workInProgress.ref !== null) {
19119 // If there is a ref on a host node we need to schedule a callback
19120 markRef$1(workInProgress);
19121 }
19122 }
19123
19124 return null;
19125 }
19126
19127 case HostText:
19128 {
19129 var newText = newProps;
19130
19131 if (current && workInProgress.stateNode != null) {
19132 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
19133 // to schedule a side-effect to do the updates.
19134
19135 updateHostText$1(current, workInProgress, oldText, newText);
19136 } else {
19137 if (typeof newText !== 'string') {
19138 if (!(workInProgress.stateNode !== null)) {
19139 {
19140 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
19141 }
19142 } // This can happen when we abort work.
19143
19144 }
19145
19146 var _rootContainerInstance = getRootHostContainer();
19147
19148 var _currentHostContext = getHostContext();
19149
19150 var _wasHydrated2 = popHydrationState(workInProgress);
19151
19152 if (_wasHydrated2) {
19153 if (prepareToHydrateHostTextInstance(workInProgress)) {
19154 markUpdate(workInProgress);
19155 }
19156 } else {
19157 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
19158 }
19159 }
19160
19161 return null;
19162 }
19163
19164 case SuspenseComponent:
19165 {
19166 popSuspenseContext(workInProgress);
19167 var nextState = workInProgress.memoizedState;
19168
19169 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
19170 // Something suspended. Re-render with the fallback children.
19171 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
19172
19173 return workInProgress;
19174 }
19175
19176 var nextDidTimeout = nextState !== null;
19177 var prevDidTimeout = false;
19178
19179 if (current === null) {
19180 if (workInProgress.memoizedProps.fallback !== undefined) {
19181 popHydrationState(workInProgress);
19182 }
19183 } else {
19184 var prevState = current.memoizedState;
19185 prevDidTimeout = prevState !== null;
19186
19187 if (!nextDidTimeout && prevState !== null) {
19188 // We just switched from the fallback to the normal children.
19189 // Delete the fallback.
19190 // TODO: Would it be better to store the fallback fragment on
19191 // the stateNode during the begin phase?
19192 var currentFallbackChild = current.child.sibling;
19193
19194 if (currentFallbackChild !== null) {
19195 // Deletions go at the beginning of the return fiber's effect list
19196 var first = workInProgress.firstEffect;
19197
19198 if (first !== null) {
19199 workInProgress.firstEffect = currentFallbackChild;
19200 currentFallbackChild.nextEffect = first;
19201 } else {
19202 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
19203 currentFallbackChild.nextEffect = null;
19204 }
19205
19206 currentFallbackChild.effectTag = Deletion;
19207 }
19208 }
19209 }
19210
19211 if (nextDidTimeout && !prevDidTimeout) {
19212 // If this subtreee is running in blocking mode we can suspend,
19213 // otherwise we won't suspend.
19214 // TODO: This will still suspend a synchronous tree if anything
19215 // in the concurrent tree already suspended during this render.
19216 // This is a known bug.
19217 if ((workInProgress.mode & BlockingMode) !== NoMode) {
19218 // TODO: Move this back to throwException because this is too late
19219 // if this is a large tree which is common for initial loads. We
19220 // don't know if we should restart a render or not until we get
19221 // this marker, and this is too late.
19222 // If this render already had a ping or lower pri updates,
19223 // and this is the first time we know we're going to suspend we
19224 // should be able to immediately restart from within throwException.
19225 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
19226
19227 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
19228 // If this was in an invisible tree or a new render, then showing
19229 // this boundary is ok.
19230 renderDidSuspend();
19231 } else {
19232 // Otherwise, we're going to have to hide content so we should
19233 // suspend for longer if possible.
19234 renderDidSuspendDelayIfPossible();
19235 }
19236 }
19237 }
19238
19239 {
19240 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
19241 if (nextDidTimeout || prevDidTimeout) {
19242 // If this boundary just timed out, schedule an effect to attach a
19243 // retry listener to the promise. This flag is also used to hide the
19244 // primary children. In mutation mode, we also need the flag to
19245 // *unhide* children that were previously hidden, so check if this
19246 // is currently timed out, too.
19247 workInProgress.effectTag |= Update;
19248 }
19249 }
19250
19251 return null;
19252 }
19253
19254 case HostPortal:
19255 popHostContainer(workInProgress);
19256 updateHostContainer(workInProgress);
19257 return null;
19258
19259 case ContextProvider:
19260 // Pop provider fiber
19261 popProvider(workInProgress);
19262 return null;
19263
19264 case IncompleteClassComponent:
19265 {
19266 // Same as class component case. I put it down here so that the tags are
19267 // sequential to ensure this switch is compiled to a jump table.
19268 var _Component = workInProgress.type;
19269
19270 if (isContextProvider(_Component)) {
19271 popContext(workInProgress);
19272 }
19273
19274 return null;
19275 }
19276
19277 case SuspenseListComponent:
19278 {
19279 popSuspenseContext(workInProgress);
19280 var renderState = workInProgress.memoizedState;
19281
19282 if (renderState === null) {
19283 // We're running in the default, "independent" mode.
19284 // We don't do anything in this mode.
19285 return null;
19286 }
19287
19288 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
19289 var renderedTail = renderState.rendering;
19290
19291 if (renderedTail === null) {
19292 // We just rendered the head.
19293 if (!didSuspendAlready) {
19294 // This is the first pass. We need to figure out if anything is still
19295 // suspended in the rendered set.
19296 // If new content unsuspended, but there's still some content that
19297 // didn't. Then we need to do a second pass that forces everything
19298 // to keep showing their fallbacks.
19299 // We might be suspended if something in this render pass suspended, or
19300 // something in the previous committed pass suspended. Otherwise,
19301 // there's no chance so we can skip the expensive call to
19302 // findFirstSuspended.
19303 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
19304
19305 if (!cannotBeSuspended) {
19306 var row = workInProgress.child;
19307
19308 while (row !== null) {
19309 var suspended = findFirstSuspended(row);
19310
19311 if (suspended !== null) {
19312 didSuspendAlready = true;
19313 workInProgress.effectTag |= DidCapture;
19314 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
19315 // part of the second pass. In that case nothing will subscribe to
19316 // its thennables. Instead, we'll transfer its thennables to the
19317 // SuspenseList so that it can retry if they resolve.
19318 // There might be multiple of these in the list but since we're
19319 // going to wait for all of them anyway, it doesn't really matter
19320 // which ones gets to ping. In theory we could get clever and keep
19321 // track of how many dependencies remain but it gets tricky because
19322 // in the meantime, we can add/remove/change items and dependencies.
19323 // We might bail out of the loop before finding any but that
19324 // doesn't matter since that means that the other boundaries that
19325 // we did find already has their listeners attached.
19326
19327 var newThennables = suspended.updateQueue;
19328
19329 if (newThennables !== null) {
19330 workInProgress.updateQueue = newThennables;
19331 workInProgress.effectTag |= Update;
19332 } // Rerender the whole list, but this time, we'll force fallbacks
19333 // to stay in place.
19334 // Reset the effect list before doing the second pass since that's now invalid.
19335
19336
19337 if (renderState.lastEffect === null) {
19338 workInProgress.firstEffect = null;
19339 }
19340
19341 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
19342
19343 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
19344 // rerender the children.
19345
19346 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
19347 return workInProgress.child;
19348 }
19349
19350 row = row.sibling;
19351 }
19352 }
19353 } else {
19354 cutOffTailIfNeeded(renderState, false);
19355 } // Next we're going to render the tail.
19356
19357 } else {
19358 // Append the rendered row to the child list.
19359 if (!didSuspendAlready) {
19360 var _suspended = findFirstSuspended(renderedTail);
19361
19362 if (_suspended !== null) {
19363 workInProgress.effectTag |= DidCapture;
19364 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
19365 // get lost if this row ends up dropped during a second pass.
19366
19367 var _newThennables = _suspended.updateQueue;
19368
19369 if (_newThennables !== null) {
19370 workInProgress.updateQueue = _newThennables;
19371 workInProgress.effectTag |= Update;
19372 }
19373
19374 cutOffTailIfNeeded(renderState, true); // This might have been modified.
19375
19376 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
19377 // We need to delete the row we just rendered.
19378 // Reset the effect list to what it was before we rendered this
19379 // child. The nested children have already appended themselves.
19380 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
19381
19382 if (lastEffect !== null) {
19383 lastEffect.nextEffect = null;
19384 } // We're done.
19385
19386
19387 return null;
19388 }
19389 } else if ( // The time it took to render last row is greater than time until
19390 // the expiration.
19391 now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {
19392 // We have now passed our CPU deadline and we'll just give up further
19393 // attempts to render the main content and only render fallbacks.
19394 // The assumption is that this is usually faster.
19395 workInProgress.effectTag |= DidCapture;
19396 didSuspendAlready = true;
19397 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19398 // to get it started back up to attempt the next item. If we can show
19399 // them, then they really have the same priority as this render.
19400 // So we'll pick it back up the very next render pass once we've had
19401 // an opportunity to yield for paint.
19402
19403 var nextPriority = renderExpirationTime - 1;
19404 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
19405
19406 {
19407 markSpawnedWork(nextPriority);
19408 }
19409 }
19410 }
19411
19412 if (renderState.isBackwards) {
19413 // The effect list of the backwards tail will have been added
19414 // to the end. This breaks the guarantee that life-cycles fire in
19415 // sibling order but that isn't a strong guarantee promised by React.
19416 // Especially since these might also just pop in during future commits.
19417 // Append to the beginning of the list.
19418 renderedTail.sibling = workInProgress.child;
19419 workInProgress.child = renderedTail;
19420 } else {
19421 var previousSibling = renderState.last;
19422
19423 if (previousSibling !== null) {
19424 previousSibling.sibling = renderedTail;
19425 } else {
19426 workInProgress.child = renderedTail;
19427 }
19428
19429 renderState.last = renderedTail;
19430 }
19431 }
19432
19433 if (renderState.tail !== null) {
19434 // We still have tail rows to render.
19435 if (renderState.tailExpiration === 0) {
19436 // Heuristic for how long we're willing to spend rendering rows
19437 // until we just give up and show what we have so far.
19438 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
19439 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this
19440 // is a per component value. It should really be since the start
19441 // of the total render or last commit. Consider using something like
19442 // globalMostRecentFallbackTime. That doesn't account for being
19443 // suspended for part of the time or when it's a new render.
19444 // It should probably use a global start time value instead.
19445 } // Pop a row.
19446
19447
19448 var next = renderState.tail;
19449 renderState.rendering = next;
19450 renderState.tail = next.sibling;
19451 renderState.lastEffect = workInProgress.lastEffect;
19452 renderState.renderingStartTime = now();
19453 next.sibling = null; // Restore the context.
19454 // TODO: We can probably just avoid popping it instead and only
19455 // setting it the first time we go from not suspended to suspended.
19456
19457 var suspenseContext = suspenseStackCursor.current;
19458
19459 if (didSuspendAlready) {
19460 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19461 } else {
19462 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19463 }
19464
19465 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
19466
19467 return next;
19468 }
19469
19470 return null;
19471 }
19472 }
19473
19474 {
19475 {
19476 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
19477 }
19478 }
19479 }
19480
19481 function unwindWork(workInProgress, renderExpirationTime) {
19482 switch (workInProgress.tag) {
19483 case ClassComponent:
19484 {
19485 var Component = workInProgress.type;
19486
19487 if (isContextProvider(Component)) {
19488 popContext(workInProgress);
19489 }
19490
19491 var effectTag = workInProgress.effectTag;
19492
19493 if (effectTag & ShouldCapture) {
19494 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
19495 return workInProgress;
19496 }
19497
19498 return null;
19499 }
19500
19501 case HostRoot:
19502 {
19503 popHostContainer(workInProgress);
19504 popTopLevelContextObject(workInProgress);
19505 var _effectTag = workInProgress.effectTag;
19506
19507 if (!((_effectTag & DidCapture) === NoEffect)) {
19508 {
19509 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
19510 }
19511 }
19512
19513 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
19514 return workInProgress;
19515 }
19516
19517 case HostComponent:
19518 {
19519 // TODO: popHydrationState
19520 popHostContext(workInProgress);
19521 return null;
19522 }
19523
19524 case SuspenseComponent:
19525 {
19526 popSuspenseContext(workInProgress);
19527
19528 var _effectTag2 = workInProgress.effectTag;
19529
19530 if (_effectTag2 & ShouldCapture) {
19531 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
19532
19533 return workInProgress;
19534 }
19535
19536 return null;
19537 }
19538
19539 case SuspenseListComponent:
19540 {
19541 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
19542 // caught by a nested boundary. If not, it should bubble through.
19543
19544 return null;
19545 }
19546
19547 case HostPortal:
19548 popHostContainer(workInProgress);
19549 return null;
19550
19551 case ContextProvider:
19552 popProvider(workInProgress);
19553 return null;
19554
19555 default:
19556 return null;
19557 }
19558 }
19559
19560 function unwindInterruptedWork(interruptedWork) {
19561 switch (interruptedWork.tag) {
19562 case ClassComponent:
19563 {
19564 var childContextTypes = interruptedWork.type.childContextTypes;
19565
19566 if (childContextTypes !== null && childContextTypes !== undefined) {
19567 popContext(interruptedWork);
19568 }
19569
19570 break;
19571 }
19572
19573 case HostRoot:
19574 {
19575 popHostContainer(interruptedWork);
19576 popTopLevelContextObject(interruptedWork);
19577 break;
19578 }
19579
19580 case HostComponent:
19581 {
19582 popHostContext(interruptedWork);
19583 break;
19584 }
19585
19586 case HostPortal:
19587 popHostContainer(interruptedWork);
19588 break;
19589
19590 case SuspenseComponent:
19591 popSuspenseContext(interruptedWork);
19592 break;
19593
19594 case SuspenseListComponent:
19595 popSuspenseContext(interruptedWork);
19596 break;
19597
19598 case ContextProvider:
19599 popProvider(interruptedWork);
19600 break;
19601 }
19602 }
19603
19604 function createCapturedValue(value, source) {
19605 // If the value is an error, call this function immediately after it is thrown
19606 // so the stack is accurate.
19607 return {
19608 value: value,
19609 source: source,
19610 stack: getStackByFiberInDevAndProd(source)
19611 };
19612 }
19613
19614 function logCapturedError(capturedError) {
19615
19616 var error = capturedError.error;
19617
19618 {
19619 var componentName = capturedError.componentName,
19620 componentStack = capturedError.componentStack,
19621 errorBoundaryName = capturedError.errorBoundaryName,
19622 errorBoundaryFound = capturedError.errorBoundaryFound,
19623 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
19624 // `preventDefault()` in window `error` handler.
19625 // We record this information as an expando on the error.
19626
19627 if (error != null && error._suppressLogging) {
19628 if (errorBoundaryFound && willRetry) {
19629 // The error is recoverable and was silenced.
19630 // Ignore it and don't print the stack addendum.
19631 // This is handy for testing error boundaries without noise.
19632 return;
19633 } // The error is fatal. Since the silencing might have
19634 // been accidental, we'll surface it anyway.
19635 // However, the browser would have silenced the original error
19636 // so we'll print it first, and then print the stack addendum.
19637
19638
19639 console['error'](error); // Don't transform to our wrapper
19640 // For a more detailed description of this block, see:
19641 // https://github.com/facebook/react/pull/13384
19642 }
19643
19644 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
19645 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
19646
19647 if (errorBoundaryFound && errorBoundaryName) {
19648 if (willRetry) {
19649 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
19650 } else {
19651 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
19652 }
19653 } else {
19654 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.';
19655 }
19656
19657 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
19658 // We don't include the original error message and JS stack because the browser
19659 // has already printed it. Even if the application swallows the error, it is still
19660 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
19661
19662 console['error'](combinedMessage); // Don't transform to our wrapper
19663 }
19664 }
19665
19666 var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
19667
19668 {
19669 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
19670 }
19671
19672 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
19673 function logError(boundary, errorInfo) {
19674 var source = errorInfo.source;
19675 var stack = errorInfo.stack;
19676
19677 if (stack === null && source !== null) {
19678 stack = getStackByFiberInDevAndProd(source);
19679 }
19680
19681 var capturedError = {
19682 componentName: source !== null ? getComponentName(source.type) : null,
19683 componentStack: stack !== null ? stack : '',
19684 error: errorInfo.value,
19685 errorBoundary: null,
19686 errorBoundaryName: null,
19687 errorBoundaryFound: false,
19688 willRetry: false
19689 };
19690
19691 if (boundary !== null && boundary.tag === ClassComponent) {
19692 capturedError.errorBoundary = boundary.stateNode;
19693 capturedError.errorBoundaryName = getComponentName(boundary.type);
19694 capturedError.errorBoundaryFound = true;
19695 capturedError.willRetry = true;
19696 }
19697
19698 try {
19699 logCapturedError(capturedError);
19700 } catch (e) {
19701 // This method must not throw, or React internal state will get messed up.
19702 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
19703 // we want to report this error outside of the normal stack as a last resort.
19704 // https://github.com/facebook/react/issues/13188
19705 setTimeout(function () {
19706 throw e;
19707 });
19708 }
19709 }
19710
19711 var callComponentWillUnmountWithTimer = function (current, instance) {
19712 startPhaseTimer(current, 'componentWillUnmount');
19713 instance.props = current.memoizedProps;
19714 instance.state = current.memoizedState;
19715 instance.componentWillUnmount();
19716 stopPhaseTimer();
19717 }; // Capture errors so they don't interrupt unmounting.
19718
19719
19720 function safelyCallComponentWillUnmount(current, instance) {
19721 {
19722 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
19723
19724 if (hasCaughtError()) {
19725 var unmountError = clearCaughtError();
19726 captureCommitPhaseError(current, unmountError);
19727 }
19728 }
19729 }
19730
19731 function safelyDetachRef(current) {
19732 var ref = current.ref;
19733
19734 if (ref !== null) {
19735 if (typeof ref === 'function') {
19736 {
19737 invokeGuardedCallback(null, ref, null, null);
19738
19739 if (hasCaughtError()) {
19740 var refError = clearCaughtError();
19741 captureCommitPhaseError(current, refError);
19742 }
19743 }
19744 } else {
19745 ref.current = null;
19746 }
19747 }
19748 }
19749
19750 function safelyCallDestroy(current, destroy) {
19751 {
19752 invokeGuardedCallback(null, destroy, null);
19753
19754 if (hasCaughtError()) {
19755 var error = clearCaughtError();
19756 captureCommitPhaseError(current, error);
19757 }
19758 }
19759 }
19760
19761 function commitBeforeMutationLifeCycles(current, finishedWork) {
19762 switch (finishedWork.tag) {
19763 case FunctionComponent:
19764 case ForwardRef:
19765 case SimpleMemoComponent:
19766 case Block:
19767 {
19768 return;
19769 }
19770
19771 case ClassComponent:
19772 {
19773 if (finishedWork.effectTag & Snapshot) {
19774 if (current !== null) {
19775 var prevProps = current.memoizedProps;
19776 var prevState = current.memoizedState;
19777 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
19778 var instance = finishedWork.stateNode; // We could update instance props and state here,
19779 // but instead we rely on them being set during last render.
19780 // TODO: revisit this when we implement resuming.
19781
19782 {
19783 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19784 if (instance.props !== finishedWork.memoizedProps) {
19785 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');
19786 }
19787
19788 if (instance.state !== finishedWork.memoizedState) {
19789 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');
19790 }
19791 }
19792 }
19793
19794 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
19795
19796 {
19797 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
19798
19799 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
19800 didWarnSet.add(finishedWork.type);
19801
19802 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
19803 }
19804 }
19805
19806 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
19807 stopPhaseTimer();
19808 }
19809 }
19810
19811 return;
19812 }
19813
19814 case HostRoot:
19815 case HostComponent:
19816 case HostText:
19817 case HostPortal:
19818 case IncompleteClassComponent:
19819 // Nothing to do for these component types
19820 return;
19821 }
19822
19823 {
19824 {
19825 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." );
19826 }
19827 }
19828 }
19829
19830 function commitHookEffectListUnmount(tag, finishedWork) {
19831 var updateQueue = finishedWork.updateQueue;
19832 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
19833
19834 if (lastEffect !== null) {
19835 var firstEffect = lastEffect.next;
19836 var effect = firstEffect;
19837
19838 do {
19839 if ((effect.tag & tag) === tag) {
19840 // Unmount
19841 var destroy = effect.destroy;
19842 effect.destroy = undefined;
19843
19844 if (destroy !== undefined) {
19845 destroy();
19846 }
19847 }
19848
19849 effect = effect.next;
19850 } while (effect !== firstEffect);
19851 }
19852 }
19853
19854 function commitHookEffectListMount(tag, finishedWork) {
19855 var updateQueue = finishedWork.updateQueue;
19856 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
19857
19858 if (lastEffect !== null) {
19859 var firstEffect = lastEffect.next;
19860 var effect = firstEffect;
19861
19862 do {
19863 if ((effect.tag & tag) === tag) {
19864 // Mount
19865 var create = effect.create;
19866 effect.destroy = create();
19867
19868 {
19869 var destroy = effect.destroy;
19870
19871 if (destroy !== undefined && typeof destroy !== 'function') {
19872 var addendum = void 0;
19873
19874 if (destroy === null) {
19875 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
19876 } else if (typeof destroy.then === 'function') {
19877 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';
19878 } else {
19879 addendum = ' You returned: ' + destroy;
19880 }
19881
19882 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
19883 }
19884 }
19885 }
19886
19887 effect = effect.next;
19888 } while (effect !== firstEffect);
19889 }
19890 }
19891
19892 function commitPassiveHookEffects(finishedWork) {
19893 if ((finishedWork.effectTag & Passive) !== NoEffect) {
19894 switch (finishedWork.tag) {
19895 case FunctionComponent:
19896 case ForwardRef:
19897 case SimpleMemoComponent:
19898 case Block:
19899 {
19900 // TODO (#17945) We should call all passive destroy functions (for all fibers)
19901 // before calling any create functions. The current approach only serializes
19902 // these for a single fiber.
19903 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
19904 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
19905 break;
19906 }
19907 }
19908 }
19909 }
19910
19911 function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
19912 switch (finishedWork.tag) {
19913 case FunctionComponent:
19914 case ForwardRef:
19915 case SimpleMemoComponent:
19916 case Block:
19917 {
19918 // At this point layout effects have already been destroyed (during mutation phase).
19919 // This is done to prevent sibling component effects from interfering with each other,
19920 // e.g. a destroy function in one component should never override a ref set
19921 // by a create function in another component during the same commit.
19922 commitHookEffectListMount(Layout | HasEffect, finishedWork);
19923
19924 return;
19925 }
19926
19927 case ClassComponent:
19928 {
19929 var instance = finishedWork.stateNode;
19930
19931 if (finishedWork.effectTag & Update) {
19932 if (current === null) {
19933 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
19934 // but instead we rely on them being set during last render.
19935 // TODO: revisit this when we implement resuming.
19936
19937 {
19938 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19939 if (instance.props !== finishedWork.memoizedProps) {
19940 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');
19941 }
19942
19943 if (instance.state !== finishedWork.memoizedState) {
19944 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');
19945 }
19946 }
19947 }
19948
19949 instance.componentDidMount();
19950 stopPhaseTimer();
19951 } else {
19952 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
19953 var prevState = current.memoizedState;
19954 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
19955 // but instead we rely on them being set during last render.
19956 // TODO: revisit this when we implement resuming.
19957
19958 {
19959 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19960 if (instance.props !== finishedWork.memoizedProps) {
19961 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');
19962 }
19963
19964 if (instance.state !== finishedWork.memoizedState) {
19965 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');
19966 }
19967 }
19968 }
19969
19970 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
19971 stopPhaseTimer();
19972 }
19973 }
19974
19975 var updateQueue = finishedWork.updateQueue;
19976
19977 if (updateQueue !== null) {
19978 {
19979 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
19980 if (instance.props !== finishedWork.memoizedProps) {
19981 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');
19982 }
19983
19984 if (instance.state !== finishedWork.memoizedState) {
19985 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');
19986 }
19987 }
19988 } // We could update instance props and state here,
19989 // but instead we rely on them being set during last render.
19990 // TODO: revisit this when we implement resuming.
19991
19992
19993 commitUpdateQueue(finishedWork, updateQueue, instance);
19994 }
19995
19996 return;
19997 }
19998
19999 case HostRoot:
20000 {
20001 var _updateQueue = finishedWork.updateQueue;
20002
20003 if (_updateQueue !== null) {
20004 var _instance = null;
20005
20006 if (finishedWork.child !== null) {
20007 switch (finishedWork.child.tag) {
20008 case HostComponent:
20009 _instance = getPublicInstance(finishedWork.child.stateNode);
20010 break;
20011
20012 case ClassComponent:
20013 _instance = finishedWork.child.stateNode;
20014 break;
20015 }
20016 }
20017
20018 commitUpdateQueue(finishedWork, _updateQueue, _instance);
20019 }
20020
20021 return;
20022 }
20023
20024 case HostComponent:
20025 {
20026 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
20027 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
20028 // These effects should only be committed when components are first mounted,
20029 // aka when there is no current/alternate.
20030
20031 if (current === null && finishedWork.effectTag & Update) {
20032 var type = finishedWork.type;
20033 var props = finishedWork.memoizedProps;
20034 commitMount(_instance2, type, props);
20035 }
20036
20037 return;
20038 }
20039
20040 case HostText:
20041 {
20042 // We have no life-cycles associated with text.
20043 return;
20044 }
20045
20046 case HostPortal:
20047 {
20048 // We have no life-cycles associated with portals.
20049 return;
20050 }
20051
20052 case Profiler:
20053 {
20054 {
20055 var onRender = finishedWork.memoizedProps.onRender;
20056
20057 if (typeof onRender === 'function') {
20058 {
20059 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
20060 }
20061 }
20062 }
20063
20064 return;
20065 }
20066
20067 case SuspenseComponent:
20068 {
20069 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
20070 return;
20071 }
20072
20073 case SuspenseListComponent:
20074 case IncompleteClassComponent:
20075 case FundamentalComponent:
20076 case ScopeComponent:
20077 return;
20078 }
20079
20080 {
20081 {
20082 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." );
20083 }
20084 }
20085 }
20086
20087 function hideOrUnhideAllChildren(finishedWork, isHidden) {
20088 {
20089 // We only have the top Fiber that was inserted but we need to recurse down its
20090 // children to find all the terminal nodes.
20091 var node = finishedWork;
20092
20093 while (true) {
20094 if (node.tag === HostComponent) {
20095 var instance = node.stateNode;
20096
20097 if (isHidden) {
20098 hideInstance(instance);
20099 } else {
20100 unhideInstance(node.stateNode, node.memoizedProps);
20101 }
20102 } else if (node.tag === HostText) {
20103 var _instance3 = node.stateNode;
20104
20105 if (isHidden) {
20106 hideTextInstance(_instance3);
20107 } else {
20108 unhideTextInstance(_instance3, node.memoizedProps);
20109 }
20110 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
20111 // Found a nested Suspense component that timed out. Skip over the
20112 // primary child fragment, which should remain hidden.
20113 var fallbackChildFragment = node.child.sibling;
20114 fallbackChildFragment.return = node;
20115 node = fallbackChildFragment;
20116 continue;
20117 } else if (node.child !== null) {
20118 node.child.return = node;
20119 node = node.child;
20120 continue;
20121 }
20122
20123 if (node === finishedWork) {
20124 return;
20125 }
20126
20127 while (node.sibling === null) {
20128 if (node.return === null || node.return === finishedWork) {
20129 return;
20130 }
20131
20132 node = node.return;
20133 }
20134
20135 node.sibling.return = node.return;
20136 node = node.sibling;
20137 }
20138 }
20139 }
20140
20141 function commitAttachRef(finishedWork) {
20142 var ref = finishedWork.ref;
20143
20144 if (ref !== null) {
20145 var instance = finishedWork.stateNode;
20146 var instanceToUse;
20147
20148 switch (finishedWork.tag) {
20149 case HostComponent:
20150 instanceToUse = getPublicInstance(instance);
20151 break;
20152
20153 default:
20154 instanceToUse = instance;
20155 } // Moved outside to ensure DCE works with this flag
20156
20157 if (typeof ref === 'function') {
20158 ref(instanceToUse);
20159 } else {
20160 {
20161 if (!ref.hasOwnProperty('current')) {
20162 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
20163 }
20164 }
20165
20166 ref.current = instanceToUse;
20167 }
20168 }
20169 }
20170
20171 function commitDetachRef(current) {
20172 var currentRef = current.ref;
20173
20174 if (currentRef !== null) {
20175 if (typeof currentRef === 'function') {
20176 currentRef(null);
20177 } else {
20178 currentRef.current = null;
20179 }
20180 }
20181 } // User-originating errors (lifecycles and refs) should not interrupt
20182 // deletion, so don't let them throw. Host-originating errors should
20183 // interrupt deletion, so it's okay
20184
20185
20186 function commitUnmount(finishedRoot, current, renderPriorityLevel) {
20187 onCommitUnmount(current);
20188
20189 switch (current.tag) {
20190 case FunctionComponent:
20191 case ForwardRef:
20192 case MemoComponent:
20193 case SimpleMemoComponent:
20194 case Block:
20195 {
20196 var updateQueue = current.updateQueue;
20197
20198 if (updateQueue !== null) {
20199 var lastEffect = updateQueue.lastEffect;
20200
20201 if (lastEffect !== null) {
20202 var firstEffect = lastEffect.next;
20203
20204 {
20205 // When the owner fiber is deleted, the destroy function of a passive
20206 // effect hook is called during the synchronous commit phase. This is
20207 // a concession to implementation complexity. Calling it in the
20208 // passive effect phase (like they usually are, when dependencies
20209 // change during an update) would require either traversing the
20210 // children of the deleted fiber again, or including unmount effects
20211 // as part of the fiber effect list.
20212 //
20213 // Because this is during the sync commit phase, we need to change
20214 // the priority.
20215 //
20216 // TODO: Reconsider this implementation trade off.
20217 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
20218 runWithPriority$1(priorityLevel, function () {
20219 var effect = firstEffect;
20220
20221 do {
20222 var _destroy = effect.destroy;
20223
20224 if (_destroy !== undefined) {
20225 safelyCallDestroy(current, _destroy);
20226 }
20227
20228 effect = effect.next;
20229 } while (effect !== firstEffect);
20230 });
20231 }
20232 }
20233 }
20234
20235 return;
20236 }
20237
20238 case ClassComponent:
20239 {
20240 safelyDetachRef(current);
20241 var instance = current.stateNode;
20242
20243 if (typeof instance.componentWillUnmount === 'function') {
20244 safelyCallComponentWillUnmount(current, instance);
20245 }
20246
20247 return;
20248 }
20249
20250 case HostComponent:
20251 {
20252
20253 safelyDetachRef(current);
20254 return;
20255 }
20256
20257 case HostPortal:
20258 {
20259 // TODO: this is recursive.
20260 // We are also not using this parent because
20261 // the portal will get pushed immediately.
20262 {
20263 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
20264 }
20265
20266 return;
20267 }
20268
20269 case FundamentalComponent:
20270 {
20271
20272 return;
20273 }
20274
20275 case DehydratedFragment:
20276 {
20277
20278 return;
20279 }
20280
20281 case ScopeComponent:
20282 {
20283
20284 return;
20285 }
20286 }
20287 }
20288
20289 function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
20290 // While we're inside a removed host node we don't want to call
20291 // removeChild on the inner nodes because they're removed by the top
20292 // call anyway. We also want to call componentWillUnmount on all
20293 // composites before this host node is removed from the tree. Therefore
20294 // we do an inner loop while we're still inside the host node.
20295 var node = root;
20296
20297 while (true) {
20298 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
20299 // Skip portals because commitUnmount() currently visits them recursively.
20300
20301 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
20302 // If we don't use mutation we drill down into portals here instead.
20303 node.tag !== HostPortal)) {
20304 node.child.return = node;
20305 node = node.child;
20306 continue;
20307 }
20308
20309 if (node === root) {
20310 return;
20311 }
20312
20313 while (node.sibling === null) {
20314 if (node.return === null || node.return === root) {
20315 return;
20316 }
20317
20318 node = node.return;
20319 }
20320
20321 node.sibling.return = node.return;
20322 node = node.sibling;
20323 }
20324 }
20325
20326 function detachFiber(current) {
20327 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
20328 // should clear the child pointer of the parent alternate to let this
20329 // get GC:ed but we don't know which for sure which parent is the current
20330 // one so we'll settle for GC:ing the subtree of this child. This child
20331 // itself will be GC:ed when the parent updates the next time.
20332
20333 current.return = null;
20334 current.child = null;
20335 current.memoizedState = null;
20336 current.updateQueue = null;
20337 current.dependencies = null;
20338 current.alternate = null;
20339 current.firstEffect = null;
20340 current.lastEffect = null;
20341 current.pendingProps = null;
20342 current.memoizedProps = null;
20343 current.stateNode = null;
20344
20345 if (alternate !== null) {
20346 detachFiber(alternate);
20347 }
20348 }
20349
20350 function getHostParentFiber(fiber) {
20351 var parent = fiber.return;
20352
20353 while (parent !== null) {
20354 if (isHostParent(parent)) {
20355 return parent;
20356 }
20357
20358 parent = parent.return;
20359 }
20360
20361 {
20362 {
20363 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
20364 }
20365 }
20366 }
20367
20368 function isHostParent(fiber) {
20369 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
20370 }
20371
20372 function getHostSibling(fiber) {
20373 // We're going to search forward into the tree until we find a sibling host
20374 // node. Unfortunately, if multiple insertions are done in a row we have to
20375 // search past them. This leads to exponential search for the next sibling.
20376 // TODO: Find a more efficient way to do this.
20377 var node = fiber;
20378
20379 siblings: while (true) {
20380 // If we didn't find anything, let's try the next sibling.
20381 while (node.sibling === null) {
20382 if (node.return === null || isHostParent(node.return)) {
20383 // If we pop out of the root or hit the parent the fiber we are the
20384 // last sibling.
20385 return null;
20386 }
20387
20388 node = node.return;
20389 }
20390
20391 node.sibling.return = node.return;
20392 node = node.sibling;
20393
20394 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
20395 // If it is not host node and, we might have a host node inside it.
20396 // Try to search down until we find one.
20397 if (node.effectTag & Placement) {
20398 // If we don't have a child, try the siblings instead.
20399 continue siblings;
20400 } // If we don't have a child, try the siblings instead.
20401 // We also skip portals because they are not part of this host tree.
20402
20403
20404 if (node.child === null || node.tag === HostPortal) {
20405 continue siblings;
20406 } else {
20407 node.child.return = node;
20408 node = node.child;
20409 }
20410 } // Check if this host node is stable or about to be placed.
20411
20412
20413 if (!(node.effectTag & Placement)) {
20414 // Found it!
20415 return node.stateNode;
20416 }
20417 }
20418 }
20419
20420 function commitPlacement(finishedWork) {
20421
20422
20423 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
20424
20425 var parent;
20426 var isContainer;
20427 var parentStateNode = parentFiber.stateNode;
20428
20429 switch (parentFiber.tag) {
20430 case HostComponent:
20431 parent = parentStateNode;
20432 isContainer = false;
20433 break;
20434
20435 case HostRoot:
20436 parent = parentStateNode.containerInfo;
20437 isContainer = true;
20438 break;
20439
20440 case HostPortal:
20441 parent = parentStateNode.containerInfo;
20442 isContainer = true;
20443 break;
20444
20445 case FundamentalComponent:
20446
20447 // eslint-disable-next-line-no-fallthrough
20448
20449 default:
20450 {
20451 {
20452 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
20453 }
20454 }
20455
20456 }
20457
20458 if (parentFiber.effectTag & ContentReset) {
20459 // Reset the text content of the parent before doing any insertions
20460 resetTextContent(parent); // Clear ContentReset from the effect tag
20461
20462 parentFiber.effectTag &= ~ContentReset;
20463 }
20464
20465 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
20466 // children to find all the terminal nodes.
20467
20468 if (isContainer) {
20469 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
20470 } else {
20471 insertOrAppendPlacementNode(finishedWork, before, parent);
20472 }
20473 }
20474
20475 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
20476 var tag = node.tag;
20477 var isHost = tag === HostComponent || tag === HostText;
20478
20479 if (isHost || enableFundamentalAPI ) {
20480 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
20481
20482 if (before) {
20483 insertInContainerBefore(parent, stateNode, before);
20484 } else {
20485 appendChildToContainer(parent, stateNode);
20486 }
20487 } else if (tag === HostPortal) ; else {
20488 var child = node.child;
20489
20490 if (child !== null) {
20491 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
20492 var sibling = child.sibling;
20493
20494 while (sibling !== null) {
20495 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
20496 sibling = sibling.sibling;
20497 }
20498 }
20499 }
20500 }
20501
20502 function insertOrAppendPlacementNode(node, before, parent) {
20503 var tag = node.tag;
20504 var isHost = tag === HostComponent || tag === HostText;
20505
20506 if (isHost || enableFundamentalAPI ) {
20507 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
20508
20509 if (before) {
20510 insertBefore(parent, stateNode, before);
20511 } else {
20512 appendChild(parent, stateNode);
20513 }
20514 } else if (tag === HostPortal) ; else {
20515 var child = node.child;
20516
20517 if (child !== null) {
20518 insertOrAppendPlacementNode(child, before, parent);
20519 var sibling = child.sibling;
20520
20521 while (sibling !== null) {
20522 insertOrAppendPlacementNode(sibling, before, parent);
20523 sibling = sibling.sibling;
20524 }
20525 }
20526 }
20527 }
20528
20529 function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
20530 // We only have the top Fiber that was deleted but we need to recurse down its
20531 // children to find all the terminal nodes.
20532 var node = current; // Each iteration, currentParent is populated with node's host parent if not
20533 // currentParentIsValid.
20534
20535 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
20536
20537 var currentParent;
20538 var currentParentIsContainer;
20539
20540 while (true) {
20541 if (!currentParentIsValid) {
20542 var parent = node.return;
20543
20544 findParent: while (true) {
20545 if (!(parent !== null)) {
20546 {
20547 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
20548 }
20549 }
20550
20551 var parentStateNode = parent.stateNode;
20552
20553 switch (parent.tag) {
20554 case HostComponent:
20555 currentParent = parentStateNode;
20556 currentParentIsContainer = false;
20557 break findParent;
20558
20559 case HostRoot:
20560 currentParent = parentStateNode.containerInfo;
20561 currentParentIsContainer = true;
20562 break findParent;
20563
20564 case HostPortal:
20565 currentParent = parentStateNode.containerInfo;
20566 currentParentIsContainer = true;
20567 break findParent;
20568
20569 }
20570
20571 parent = parent.return;
20572 }
20573
20574 currentParentIsValid = true;
20575 }
20576
20577 if (node.tag === HostComponent || node.tag === HostText) {
20578 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
20579 // node from the tree.
20580
20581 if (currentParentIsContainer) {
20582 removeChildFromContainer(currentParent, node.stateNode);
20583 } else {
20584 removeChild(currentParent, node.stateNode);
20585 } // Don't visit children because we already visited them.
20586
20587 } else if (node.tag === HostPortal) {
20588 if (node.child !== null) {
20589 // When we go into a portal, it becomes the parent to remove from.
20590 // We will reassign it back when we pop the portal on the way up.
20591 currentParent = node.stateNode.containerInfo;
20592 currentParentIsContainer = true; // Visit children because portals might contain host components.
20593
20594 node.child.return = node;
20595 node = node.child;
20596 continue;
20597 }
20598 } else {
20599 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
20600
20601 if (node.child !== null) {
20602 node.child.return = node;
20603 node = node.child;
20604 continue;
20605 }
20606 }
20607
20608 if (node === current) {
20609 return;
20610 }
20611
20612 while (node.sibling === null) {
20613 if (node.return === null || node.return === current) {
20614 return;
20615 }
20616
20617 node = node.return;
20618
20619 if (node.tag === HostPortal) {
20620 // When we go out of the portal, we need to restore the parent.
20621 // Since we don't keep a stack of them, we will search for it.
20622 currentParentIsValid = false;
20623 }
20624 }
20625
20626 node.sibling.return = node.return;
20627 node = node.sibling;
20628 }
20629 }
20630
20631 function commitDeletion(finishedRoot, current, renderPriorityLevel) {
20632 {
20633 // Recursively delete all host nodes from the parent.
20634 // Detach refs and call componentWillUnmount() on the whole subtree.
20635 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
20636 }
20637
20638 detachFiber(current);
20639 }
20640
20641 function commitWork(current, finishedWork) {
20642
20643 switch (finishedWork.tag) {
20644 case FunctionComponent:
20645 case ForwardRef:
20646 case MemoComponent:
20647 case SimpleMemoComponent:
20648 case Block:
20649 {
20650 // Layout effects are destroyed during the mutation phase so that all
20651 // destroy functions for all fibers are called before any create functions.
20652 // This prevents sibling component effects from interfering with each other,
20653 // e.g. a destroy function in one component should never override a ref set
20654 // by a create function in another component during the same commit.
20655 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
20656 return;
20657 }
20658
20659 case ClassComponent:
20660 {
20661 return;
20662 }
20663
20664 case HostComponent:
20665 {
20666 var instance = finishedWork.stateNode;
20667
20668 if (instance != null) {
20669 // Commit the work prepared earlier.
20670 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
20671 // as the newProps. The updatePayload will contain the real change in
20672 // this case.
20673
20674 var oldProps = current !== null ? current.memoizedProps : newProps;
20675 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
20676
20677 var updatePayload = finishedWork.updateQueue;
20678 finishedWork.updateQueue = null;
20679
20680 if (updatePayload !== null) {
20681 commitUpdate(instance, updatePayload, type, oldProps, newProps);
20682 }
20683 }
20684
20685 return;
20686 }
20687
20688 case HostText:
20689 {
20690 if (!(finishedWork.stateNode !== null)) {
20691 {
20692 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
20693 }
20694 }
20695
20696 var textInstance = finishedWork.stateNode;
20697 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
20698 // as the newProps. The updatePayload will contain the real change in
20699 // this case.
20700
20701 var oldText = current !== null ? current.memoizedProps : newText;
20702 commitTextUpdate(textInstance, oldText, newText);
20703 return;
20704 }
20705
20706 case HostRoot:
20707 {
20708 {
20709 var _root = finishedWork.stateNode;
20710
20711 if (_root.hydrate) {
20712 // We've just hydrated. No need to hydrate again.
20713 _root.hydrate = false;
20714 commitHydratedContainer(_root.containerInfo);
20715 }
20716 }
20717
20718 return;
20719 }
20720
20721 case Profiler:
20722 {
20723 return;
20724 }
20725
20726 case SuspenseComponent:
20727 {
20728 commitSuspenseComponent(finishedWork);
20729 attachSuspenseRetryListeners(finishedWork);
20730 return;
20731 }
20732
20733 case SuspenseListComponent:
20734 {
20735 attachSuspenseRetryListeners(finishedWork);
20736 return;
20737 }
20738
20739 case IncompleteClassComponent:
20740 {
20741 return;
20742 }
20743 }
20744
20745 {
20746 {
20747 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." );
20748 }
20749 }
20750 }
20751
20752 function commitSuspenseComponent(finishedWork) {
20753 var newState = finishedWork.memoizedState;
20754 var newDidTimeout;
20755 var primaryChildParent = finishedWork;
20756
20757 if (newState === null) {
20758 newDidTimeout = false;
20759 } else {
20760 newDidTimeout = true;
20761 primaryChildParent = finishedWork.child;
20762 markCommitTimeOfFallback();
20763 }
20764
20765 if ( primaryChildParent !== null) {
20766 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
20767 }
20768 }
20769
20770 function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
20771
20772 var newState = finishedWork.memoizedState;
20773
20774 if (newState === null) {
20775 var current = finishedWork.alternate;
20776
20777 if (current !== null) {
20778 var prevState = current.memoizedState;
20779
20780 if (prevState !== null) {
20781 var suspenseInstance = prevState.dehydrated;
20782
20783 if (suspenseInstance !== null) {
20784 commitHydratedSuspenseInstance(suspenseInstance);
20785 }
20786 }
20787 }
20788 }
20789 }
20790
20791 function attachSuspenseRetryListeners(finishedWork) {
20792 // If this boundary just timed out, then it will have a set of thenables.
20793 // For each thenable, attach a listener so that when it resolves, React
20794 // attempts to re-render the boundary in the primary (pre-timeout) state.
20795 var thenables = finishedWork.updateQueue;
20796
20797 if (thenables !== null) {
20798 finishedWork.updateQueue = null;
20799 var retryCache = finishedWork.stateNode;
20800
20801 if (retryCache === null) {
20802 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
20803 }
20804
20805 thenables.forEach(function (thenable) {
20806 // Memoize using the boundary fiber to prevent redundant listeners.
20807 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
20808
20809 if (!retryCache.has(thenable)) {
20810 {
20811 if (thenable.__reactDoNotTraceInteractions !== true) {
20812 retry = unstable_wrap(retry);
20813 }
20814 }
20815
20816 retryCache.add(thenable);
20817 thenable.then(retry, retry);
20818 }
20819 });
20820 }
20821 }
20822
20823 function commitResetTextContent(current) {
20824
20825 resetTextContent(current.stateNode);
20826 }
20827
20828 var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
20829
20830 function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
20831 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
20832
20833 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
20834 // being called "element".
20835
20836 update.payload = {
20837 element: null
20838 };
20839 var error = errorInfo.value;
20840
20841 update.callback = function () {
20842 onUncaughtError(error);
20843 logError(fiber, errorInfo);
20844 };
20845
20846 return update;
20847 }
20848
20849 function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
20850 var update = createUpdate(expirationTime, null);
20851 update.tag = CaptureUpdate;
20852 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
20853
20854 if (typeof getDerivedStateFromError === 'function') {
20855 var error$1 = errorInfo.value;
20856
20857 update.payload = function () {
20858 logError(fiber, errorInfo);
20859 return getDerivedStateFromError(error$1);
20860 };
20861 }
20862
20863 var inst = fiber.stateNode;
20864
20865 if (inst !== null && typeof inst.componentDidCatch === 'function') {
20866 update.callback = function callback() {
20867 {
20868 markFailedErrorBoundaryForHotReloading(fiber);
20869 }
20870
20871 if (typeof getDerivedStateFromError !== 'function') {
20872 // To preserve the preexisting retry behavior of error boundaries,
20873 // we keep track of which ones already failed during this batch.
20874 // This gets reset before we yield back to the browser.
20875 // TODO: Warn in strict mode if getDerivedStateFromError is
20876 // not defined.
20877 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
20878
20879 logError(fiber, errorInfo);
20880 }
20881
20882 var error$1 = errorInfo.value;
20883 var stack = errorInfo.stack;
20884 this.componentDidCatch(error$1, {
20885 componentStack: stack !== null ? stack : ''
20886 });
20887
20888 {
20889 if (typeof getDerivedStateFromError !== 'function') {
20890 // If componentDidCatch is the only error boundary method defined,
20891 // then it needs to call setState to recover from errors.
20892 // If no state update is scheduled then the boundary will swallow the error.
20893 if (fiber.expirationTime !== Sync) {
20894 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');
20895 }
20896 }
20897 }
20898 };
20899 } else {
20900 update.callback = function () {
20901 markFailedErrorBoundaryForHotReloading(fiber);
20902 };
20903 }
20904
20905 return update;
20906 }
20907
20908 function attachPingListener(root, renderExpirationTime, thenable) {
20909 // Attach a listener to the promise to "ping" the root and retry. But
20910 // only if one does not already exist for the current render expiration
20911 // time (which acts like a "thread ID" here).
20912 var pingCache = root.pingCache;
20913 var threadIDs;
20914
20915 if (pingCache === null) {
20916 pingCache = root.pingCache = new PossiblyWeakMap$1();
20917 threadIDs = new Set();
20918 pingCache.set(thenable, threadIDs);
20919 } else {
20920 threadIDs = pingCache.get(thenable);
20921
20922 if (threadIDs === undefined) {
20923 threadIDs = new Set();
20924 pingCache.set(thenable, threadIDs);
20925 }
20926 }
20927
20928 if (!threadIDs.has(renderExpirationTime)) {
20929 // Memoize using the thread ID to prevent redundant listeners.
20930 threadIDs.add(renderExpirationTime);
20931 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
20932 thenable.then(ping, ping);
20933 }
20934 }
20935
20936 function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
20937 // The source fiber did not complete.
20938 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
20939
20940 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
20941
20942 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
20943 // This is a thenable.
20944 var thenable = value;
20945
20946 if ((sourceFiber.mode & BlockingMode) === NoMode) {
20947 // Reset the memoizedState to what it was before we attempted
20948 // to render it.
20949 var currentSource = sourceFiber.alternate;
20950
20951 if (currentSource) {
20952 sourceFiber.updateQueue = currentSource.updateQueue;
20953 sourceFiber.memoizedState = currentSource.memoizedState;
20954 sourceFiber.expirationTime = currentSource.expirationTime;
20955 } else {
20956 sourceFiber.updateQueue = null;
20957 sourceFiber.memoizedState = null;
20958 }
20959 }
20960
20961 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
20962
20963 var _workInProgress = returnFiber;
20964
20965 do {
20966 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
20967 // Found the nearest boundary.
20968 // Stash the promise on the boundary fiber. If the boundary times out, we'll
20969 // attach another listener to flip the boundary back to its normal state.
20970 var thenables = _workInProgress.updateQueue;
20971
20972 if (thenables === null) {
20973 var updateQueue = new Set();
20974 updateQueue.add(thenable);
20975 _workInProgress.updateQueue = updateQueue;
20976 } else {
20977 thenables.add(thenable);
20978 } // If the boundary is outside of blocking mode, we should *not*
20979 // suspend the commit. Pretend as if the suspended component rendered
20980 // null and keep rendering. In the commit phase, we'll schedule a
20981 // subsequent synchronous update to re-render the Suspense.
20982 //
20983 // Note: It doesn't matter whether the component that suspended was
20984 // inside a blocking mode tree. If the Suspense is outside of it, we
20985 // should *not* suspend the commit.
20986
20987
20988 if ((_workInProgress.mode & BlockingMode) === NoMode) {
20989 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
20990 // But we shouldn't call any lifecycle methods or callbacks. Remove
20991 // all lifecycle effect tags.
20992
20993 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
20994
20995 if (sourceFiber.tag === ClassComponent) {
20996 var currentSourceFiber = sourceFiber.alternate;
20997
20998 if (currentSourceFiber === null) {
20999 // This is a new mount. Change the tag so it's not mistaken for a
21000 // completed class component. For example, we should not call
21001 // componentWillUnmount if it is deleted.
21002 sourceFiber.tag = IncompleteClassComponent;
21003 } else {
21004 // When we try rendering again, we should not reuse the current fiber,
21005 // since it's known to be in an inconsistent state. Use a force update to
21006 // prevent a bail out.
21007 var update = createUpdate(Sync, null);
21008 update.tag = ForceUpdate;
21009 enqueueUpdate(sourceFiber, update);
21010 }
21011 } // The source fiber did not complete. Mark it with Sync priority to
21012 // indicate that it still has pending work.
21013
21014
21015 sourceFiber.expirationTime = Sync; // Exit without suspending.
21016
21017 return;
21018 } // Confirmed that the boundary is in a concurrent mode tree. Continue
21019 // with the normal suspend path.
21020 //
21021 // After this we'll use a set of heuristics to determine whether this
21022 // render pass will run to completion or restart or "suspend" the commit.
21023 // The actual logic for this is spread out in different places.
21024 //
21025 // This first principle is that if we're going to suspend when we complete
21026 // a root, then we should also restart if we get an update or ping that
21027 // might unsuspend it, and vice versa. The only reason to suspend is
21028 // because you think you might want to restart before committing. However,
21029 // it doesn't make sense to restart only while in the period we're suspended.
21030 //
21031 // Restarting too aggressively is also not good because it starves out any
21032 // intermediate loading state. So we use heuristics to determine when.
21033 // Suspense Heuristics
21034 //
21035 // If nothing threw a Promise or all the same fallbacks are already showing,
21036 // then don't suspend/restart.
21037 //
21038 // If this is an initial render of a new tree of Suspense boundaries and
21039 // those trigger a fallback, then don't suspend/restart. We want to ensure
21040 // that we can show the initial loading state as quickly as possible.
21041 //
21042 // If we hit a "Delayed" case, such as when we'd switch from content back into
21043 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
21044 // this case. If none is defined, JND is used instead.
21045 //
21046 // If we're already showing a fallback and it gets "retried", allowing us to show
21047 // another level, but there's still an inner boundary that would show a fallback,
21048 // then we suspend/restart for 500ms since the last time we showed a fallback
21049 // anywhere in the tree. This effectively throttles progressive loading into a
21050 // consistent train of commits. This also gives us an opportunity to restart to
21051 // get to the completed state slightly earlier.
21052 //
21053 // If there's ambiguity due to batching it's resolved in preference of:
21054 // 1) "delayed", 2) "initial render", 3) "retry".
21055 //
21056 // We want to ensure that a "busy" state doesn't get force committed. We want to
21057 // ensure that new initial loading states can commit as soon as possible.
21058
21059
21060 attachPingListener(root, renderExpirationTime, thenable);
21061 _workInProgress.effectTag |= ShouldCapture;
21062 _workInProgress.expirationTime = renderExpirationTime;
21063 return;
21064 } // This boundary already captured during this render. Continue to the next
21065 // boundary.
21066
21067
21068 _workInProgress = _workInProgress.return;
21069 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
21070 // TODO: Use invariant so the message is stripped in prod?
21071
21072
21073 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));
21074 } // We didn't find a boundary that could handle this type of exception. Start
21075 // over and traverse parent path again, this time treating the exception
21076 // as an error.
21077
21078
21079 renderDidError();
21080 value = createCapturedValue(value, sourceFiber);
21081 var workInProgress = returnFiber;
21082
21083 do {
21084 switch (workInProgress.tag) {
21085 case HostRoot:
21086 {
21087 var _errorInfo = value;
21088 workInProgress.effectTag |= ShouldCapture;
21089 workInProgress.expirationTime = renderExpirationTime;
21090
21091 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
21092
21093 enqueueCapturedUpdate(workInProgress, _update);
21094 return;
21095 }
21096
21097 case ClassComponent:
21098 // Capture and retry
21099 var errorInfo = value;
21100 var ctor = workInProgress.type;
21101 var instance = workInProgress.stateNode;
21102
21103 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
21104 workInProgress.effectTag |= ShouldCapture;
21105 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
21106
21107 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
21108
21109 enqueueCapturedUpdate(workInProgress, _update2);
21110 return;
21111 }
21112
21113 break;
21114 }
21115
21116 workInProgress = workInProgress.return;
21117 } while (workInProgress !== null);
21118 }
21119
21120 var ceil = Math.ceil;
21121 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
21122 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
21123 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
21124 var NoContext =
21125 /* */
21126 0;
21127 var BatchedContext =
21128 /* */
21129 1;
21130 var EventContext =
21131 /* */
21132 2;
21133 var DiscreteEventContext =
21134 /* */
21135 4;
21136 var LegacyUnbatchedContext =
21137 /* */
21138 8;
21139 var RenderContext =
21140 /* */
21141 16;
21142 var CommitContext =
21143 /* */
21144 32;
21145 var RootIncomplete = 0;
21146 var RootFatalErrored = 1;
21147 var RootErrored = 2;
21148 var RootSuspended = 3;
21149 var RootSuspendedWithDelay = 4;
21150 var RootCompleted = 5;
21151 // Describes where we are in the React execution stack
21152 var executionContext = NoContext; // The root we're working on
21153
21154 var workInProgressRoot = null; // The fiber we're working on
21155
21156 var workInProgress = null; // The expiration time we're rendering
21157
21158 var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.
21159
21160 var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
21161
21162 var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
21163 // This is conceptually a time stamp but expressed in terms of an ExpirationTime
21164 // because we deal mostly with expiration times in the hot path, so this avoids
21165 // the conversion happening in the hot path.
21166
21167 var workInProgressRootLatestProcessedExpirationTime = Sync;
21168 var workInProgressRootLatestSuspenseTimeout = Sync;
21169 var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
21170 // includes unprocessed updates, not work in bailed out children.
21171
21172 var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
21173 // This flag determines if it might be worthwhile to restart if an opportunity
21174 // happens latere.
21175
21176 var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
21177 // model where we don't commit new loading states in too quick succession.
21178
21179 var globalMostRecentFallbackTime = 0;
21180 var FALLBACK_THROTTLE_MS = 500;
21181 var nextEffect = null;
21182 var hasUncaughtError = false;
21183 var firstUncaughtError = null;
21184 var legacyErrorBoundariesThatAlreadyFailed = null;
21185 var rootDoesHavePassiveEffects = false;
21186 var rootWithPendingPassiveEffects = null;
21187 var pendingPassiveEffectsRenderPriority = NoPriority;
21188 var pendingPassiveEffectsExpirationTime = NoWork;
21189 var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
21190
21191 var NESTED_UPDATE_LIMIT = 50;
21192 var nestedUpdateCount = 0;
21193 var rootWithNestedUpdates = null;
21194 var NESTED_PASSIVE_UPDATE_LIMIT = 50;
21195 var nestedPassiveUpdateCount = 0;
21196 var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
21197 // during the commit phase. This enables them to be traced across components
21198 // that spawn new work during render. E.g. hidden boundaries, suspended SSR
21199 // hydration or SuspenseList.
21200
21201 var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
21202 // time). However, if two updates are scheduled within the same event, we
21203 // should treat their start times as simultaneous, even if the actual clock
21204 // time has advanced between the first and second call.
21205 // In other words, because expiration times determine how updates are batched,
21206 // we want all updates of like priority that occur within the same event to
21207 // receive the same expiration time. Otherwise we get tearing.
21208
21209 var currentEventTime = NoWork;
21210 function requestCurrentTimeForUpdate() {
21211 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21212 // We're inside React, so it's fine to read the actual time.
21213 return msToExpirationTime(now());
21214 } // We're not inside React, so we may be in the middle of a browser event.
21215
21216
21217 if (currentEventTime !== NoWork) {
21218 // Use the same start time for all updates until we enter React again.
21219 return currentEventTime;
21220 } // This is the first update since React yielded. Compute a new start time.
21221
21222
21223 currentEventTime = msToExpirationTime(now());
21224 return currentEventTime;
21225 }
21226 function getCurrentTime() {
21227 return msToExpirationTime(now());
21228 }
21229 function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
21230 var mode = fiber.mode;
21231
21232 if ((mode & BlockingMode) === NoMode) {
21233 return Sync;
21234 }
21235
21236 var priorityLevel = getCurrentPriorityLevel();
21237
21238 if ((mode & ConcurrentMode) === NoMode) {
21239 return priorityLevel === ImmediatePriority ? Sync : Batched;
21240 }
21241
21242 if ((executionContext & RenderContext) !== NoContext) {
21243 // Use whatever time we're already rendering
21244 // TODO: Should there be a way to opt out, like with `runWithPriority`?
21245 return renderExpirationTime$1;
21246 }
21247
21248 var expirationTime;
21249
21250 if (suspenseConfig !== null) {
21251 // Compute an expiration time based on the Suspense timeout.
21252 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
21253 } else {
21254 // Compute an expiration time based on the Scheduler priority.
21255 switch (priorityLevel) {
21256 case ImmediatePriority:
21257 expirationTime = Sync;
21258 break;
21259
21260 case UserBlockingPriority$1:
21261 // TODO: Rename this to computeUserBlockingExpiration
21262 expirationTime = computeInteractiveExpiration(currentTime);
21263 break;
21264
21265 case NormalPriority:
21266 case LowPriority:
21267 // TODO: Handle LowPriority
21268 // TODO: Rename this to... something better.
21269 expirationTime = computeAsyncExpiration(currentTime);
21270 break;
21271
21272 case IdlePriority:
21273 expirationTime = Idle;
21274 break;
21275
21276 default:
21277 {
21278 {
21279 throw Error( "Expected a valid priority level" );
21280 }
21281 }
21282
21283 }
21284 } // If we're in the middle of rendering a tree, do not update at the same
21285 // expiration time that is already rendering.
21286 // TODO: We shouldn't have to do this if the update is on a different root.
21287 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
21288 // the root when we check for this condition.
21289
21290
21291 if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {
21292 // This is a trick to move this update into a separate batch
21293 expirationTime -= 1;
21294 }
21295
21296 return expirationTime;
21297 }
21298 function scheduleUpdateOnFiber(fiber, expirationTime) {
21299 checkForNestedUpdates();
21300 warnAboutRenderPhaseUpdatesInDEV(fiber);
21301 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
21302
21303 if (root === null) {
21304 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
21305 return;
21306 }
21307
21308 checkForInterruption(fiber, expirationTime);
21309 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
21310 // priority as an argument to that function and this one.
21311
21312 var priorityLevel = getCurrentPriorityLevel();
21313
21314 if (expirationTime === Sync) {
21315 if ( // Check if we're inside unbatchedUpdates
21316 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
21317 (executionContext & (RenderContext | CommitContext)) === NoContext) {
21318 // Register pending interactions on the root to avoid losing traced interaction data.
21319 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
21320 // root inside of batchedUpdates should be synchronous, but layout updates
21321 // should be deferred until the end of the batch.
21322
21323 performSyncWorkOnRoot(root);
21324 } else {
21325 ensureRootIsScheduled(root);
21326 schedulePendingInteractions(root, expirationTime);
21327
21328 if (executionContext === NoContext) {
21329 // Flush the synchronous work now, unless we're already working or inside
21330 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
21331 // scheduleCallbackForFiber to preserve the ability to schedule a callback
21332 // without immediately flushing it. We only do this for user-initiated
21333 // updates, to preserve historical behavior of legacy mode.
21334 flushSyncCallbackQueue();
21335 }
21336 }
21337 } else {
21338 ensureRootIsScheduled(root);
21339 schedulePendingInteractions(root, expirationTime);
21340 }
21341
21342 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
21343 // discrete, even inside a discrete event.
21344 priorityLevel === UserBlockingPriority$1 || priorityLevel === ImmediatePriority)) {
21345 // This is the result of a discrete event. Track the lowest priority
21346 // discrete update per root so we can flush them early, if needed.
21347 if (rootsWithPendingDiscreteUpdates === null) {
21348 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
21349 } else {
21350 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
21351
21352 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
21353 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
21354 }
21355 }
21356 }
21357 }
21358 var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
21359 // work without treating it as a typical update that originates from an event;
21360 // e.g. retrying a Suspense boundary isn't an update, but it does schedule work
21361 // on a fiber.
21362
21363 function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
21364 // Update the source fiber's expiration time
21365 if (fiber.expirationTime < expirationTime) {
21366 fiber.expirationTime = expirationTime;
21367 }
21368
21369 var alternate = fiber.alternate;
21370
21371 if (alternate !== null && alternate.expirationTime < expirationTime) {
21372 alternate.expirationTime = expirationTime;
21373 } // Walk the parent path to the root and update the child expiration time.
21374
21375
21376 var node = fiber.return;
21377 var root = null;
21378
21379 if (node === null && fiber.tag === HostRoot) {
21380 root = fiber.stateNode;
21381 } else {
21382 while (node !== null) {
21383 alternate = node.alternate;
21384
21385 if (node.childExpirationTime < expirationTime) {
21386 node.childExpirationTime = expirationTime;
21387
21388 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21389 alternate.childExpirationTime = expirationTime;
21390 }
21391 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21392 alternate.childExpirationTime = expirationTime;
21393 }
21394
21395 if (node.return === null && node.tag === HostRoot) {
21396 root = node.stateNode;
21397 break;
21398 }
21399
21400 node = node.return;
21401 }
21402 }
21403
21404 if (root !== null) {
21405 if (workInProgressRoot === root) {
21406 // Received an update to a tree that's in the middle of rendering. Mark
21407 // that's unprocessed work on this root.
21408 markUnprocessedUpdateTime(expirationTime);
21409
21410 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
21411 // The root already suspended with a delay, which means this render
21412 // definitely won't finish. Since we have a new update, let's mark it as
21413 // suspended now, right before marking the incoming update. This has the
21414 // effect of interrupting the current render and switching to the update.
21415 // TODO: This happens to work when receiving an update during the render
21416 // phase, because of the trick inside computeExpirationForFiber to
21417 // subtract 1 from `renderExpirationTime` to move it into a
21418 // separate bucket. But we should probably model it with an exception,
21419 // using the same mechanism we use to force hydration of a subtree.
21420 // TODO: This does not account for low pri updates that were already
21421 // scheduled before the root started rendering. Need to track the next
21422 // pending expiration time (perhaps by backtracking the return path) and
21423 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
21424 markRootSuspendedAtTime(root, renderExpirationTime$1);
21425 }
21426 } // Mark that the root has a pending update.
21427
21428
21429 markRootUpdatedAtTime(root, expirationTime);
21430 }
21431
21432 return root;
21433 }
21434
21435 function getNextRootExpirationTimeToWorkOn(root) {
21436 // Determines the next expiration time that the root should render, taking
21437 // into account levels that may be suspended, or levels that may have
21438 // received a ping.
21439 var lastExpiredTime = root.lastExpiredTime;
21440
21441 if (lastExpiredTime !== NoWork) {
21442 return lastExpiredTime;
21443 } // "Pending" refers to any update that hasn't committed yet, including if it
21444 // suspended. The "suspended" range is therefore a subset.
21445
21446
21447 var firstPendingTime = root.firstPendingTime;
21448
21449 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
21450 // The highest priority pending time is not suspended. Let's work on that.
21451 return firstPendingTime;
21452 } // If the first pending time is suspended, check if there's a lower priority
21453 // pending level that we know about. Or check if we received a ping. Work
21454 // on whichever is higher priority.
21455
21456
21457 var lastPingedTime = root.lastPingedTime;
21458 var nextKnownPendingLevel = root.nextKnownPendingLevel;
21459 var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
21460
21461 if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {
21462 // Don't work on Idle/Never priority unless everything else is committed.
21463 return NoWork;
21464 }
21465
21466 return nextLevel;
21467 } // Use this function to schedule a task for a root. There's only one task per
21468 // root; if a task was already scheduled, we'll check to make sure the
21469 // expiration time of the existing task is the same as the expiration time of
21470 // the next level that the root has work on. This function is called on every
21471 // update, and right before exiting a task.
21472
21473
21474 function ensureRootIsScheduled(root) {
21475 var lastExpiredTime = root.lastExpiredTime;
21476
21477 if (lastExpiredTime !== NoWork) {
21478 // Special case: Expired work should flush synchronously.
21479 root.callbackExpirationTime = Sync;
21480 root.callbackPriority = ImmediatePriority;
21481 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
21482 return;
21483 }
21484
21485 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
21486 var existingCallbackNode = root.callbackNode;
21487
21488 if (expirationTime === NoWork) {
21489 // There's nothing to work on.
21490 if (existingCallbackNode !== null) {
21491 root.callbackNode = null;
21492 root.callbackExpirationTime = NoWork;
21493 root.callbackPriority = NoPriority;
21494 }
21495
21496 return;
21497 } // TODO: If this is an update, we already read the current time. Pass the
21498 // time as an argument.
21499
21500
21501 var currentTime = requestCurrentTimeForUpdate();
21502 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
21503 // expiration time. Otherwise, we'll cancel it and schedule a new one.
21504
21505 if (existingCallbackNode !== null) {
21506 var existingCallbackPriority = root.callbackPriority;
21507 var existingCallbackExpirationTime = root.callbackExpirationTime;
21508
21509 if ( // Callback must have the exact same expiration time.
21510 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
21511 existingCallbackPriority >= priorityLevel) {
21512 // Existing callback is sufficient.
21513 return;
21514 } // Need to schedule a new task.
21515 // TODO: Instead of scheduling a new task, we should be able to change the
21516 // priority of the existing one.
21517
21518
21519 cancelCallback(existingCallbackNode);
21520 }
21521
21522 root.callbackExpirationTime = expirationTime;
21523 root.callbackPriority = priorityLevel;
21524 var callbackNode;
21525
21526 if (expirationTime === Sync) {
21527 // Sync React callbacks are scheduled on a special internal queue
21528 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
21529 } else {
21530 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
21531 // ordering because tasks are processed in timeout order.
21532 {
21533 timeout: expirationTimeToMs(expirationTime) - now()
21534 });
21535 }
21536
21537 root.callbackNode = callbackNode;
21538 } // This is the entry point for every concurrent task, i.e. anything that
21539 // goes through Scheduler.
21540
21541
21542 function performConcurrentWorkOnRoot(root, didTimeout) {
21543 // Since we know we're in a React event, we can clear the current
21544 // event time. The next update will compute a new event time.
21545 currentEventTime = NoWork;
21546
21547 if (didTimeout) {
21548 // The render task took too long to complete. Mark the current time as
21549 // expired to synchronously render all expired work in a single batch.
21550 var currentTime = requestCurrentTimeForUpdate();
21551 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
21552
21553 ensureRootIsScheduled(root);
21554 return null;
21555 } // Determine the next expiration time to work on, using the fields stored
21556 // on the root.
21557
21558
21559 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
21560
21561 if (expirationTime !== NoWork) {
21562 var originalCallbackNode = root.callbackNode;
21563
21564 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
21565 {
21566 throw Error( "Should not already be working." );
21567 }
21568 }
21569
21570 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
21571 // and prepare a fresh one. Otherwise we'll continue where we left off.
21572
21573 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
21574 prepareFreshStack(root, expirationTime);
21575 startWorkOnPendingInteractions(root, expirationTime);
21576 } // If we have a work-in-progress fiber, it means there's still work to do
21577 // in this root.
21578
21579
21580 if (workInProgress !== null) {
21581 var prevExecutionContext = executionContext;
21582 executionContext |= RenderContext;
21583 var prevDispatcher = pushDispatcher();
21584 var prevInteractions = pushInteractions(root);
21585 startWorkLoopTimer(workInProgress);
21586
21587 do {
21588 try {
21589 workLoopConcurrent();
21590 break;
21591 } catch (thrownValue) {
21592 handleError(root, thrownValue);
21593 }
21594 } while (true);
21595
21596 resetContextDependencies();
21597 executionContext = prevExecutionContext;
21598 popDispatcher(prevDispatcher);
21599
21600 {
21601 popInteractions(prevInteractions);
21602 }
21603
21604 if (workInProgressRootExitStatus === RootFatalErrored) {
21605 var fatalError = workInProgressRootFatalError;
21606 stopInterruptedWorkLoopTimer();
21607 prepareFreshStack(root, expirationTime);
21608 markRootSuspendedAtTime(root, expirationTime);
21609 ensureRootIsScheduled(root);
21610 throw fatalError;
21611 }
21612
21613 if (workInProgress !== null) {
21614 // There's still work left over. Exit without committing.
21615 stopInterruptedWorkLoopTimer();
21616 } else {
21617 // We now have a consistent tree. The next step is either to commit it,
21618 // or, if something suspended, wait to commit it after a timeout.
21619 stopFinishedWorkLoopTimer();
21620 var finishedWork = root.finishedWork = root.current.alternate;
21621 root.finishedExpirationTime = expirationTime;
21622 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
21623 }
21624
21625 ensureRootIsScheduled(root);
21626
21627 if (root.callbackNode === originalCallbackNode) {
21628 // The task node scheduled for this root is the same one that's
21629 // currently executed. Need to return a continuation.
21630 return performConcurrentWorkOnRoot.bind(null, root);
21631 }
21632 }
21633 }
21634
21635 return null;
21636 }
21637
21638 function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
21639 // Set this to null to indicate there's no in-progress render.
21640 workInProgressRoot = null;
21641
21642 switch (exitStatus) {
21643 case RootIncomplete:
21644 case RootFatalErrored:
21645 {
21646 {
21647 {
21648 throw Error( "Root did not complete. This is a bug in React." );
21649 }
21650 }
21651 }
21652 // Flow knows about invariant, so it complains if I add a break
21653 // statement, but eslint doesn't know about invariant, so it complains
21654 // if I do. eslint-disable-next-line no-fallthrough
21655
21656 case RootErrored:
21657 {
21658 // If this was an async render, the error may have happened due to
21659 // a mutation in a concurrent event. Try rendering one more time,
21660 // synchronously, to see if the error goes away. If there are
21661 // lower priority updates, let's include those, too, in case they
21662 // fix the inconsistency. Render at Idle to include all updates.
21663 // If it was Idle or Never or some not-yet-invented time, render
21664 // at that time.
21665 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
21666 // and therefore not hit this path again.
21667
21668 break;
21669 }
21670
21671 case RootSuspended:
21672 {
21673 markRootSuspendedAtTime(root, expirationTime);
21674 var lastSuspendedTime = root.lastSuspendedTime;
21675
21676 if (expirationTime === lastSuspendedTime) {
21677 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
21678 } // We have an acceptable loading state. We need to figure out if we
21679 // should immediately commit it or wait a bit.
21680 // If we have processed new updates during this render, we may now
21681 // have a new loading state ready. We want to ensure that we commit
21682 // that as soon as possible.
21683
21684
21685 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
21686
21687 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
21688 !( IsThisRendererActing.current)) {
21689 // If we have not processed any new updates during this pass, then
21690 // this is either a retry of an existing fallback state or a
21691 // hidden tree. Hidden trees shouldn't be batched with other work
21692 // and after that's fixed it can only be a retry. We're going to
21693 // throttle committing retries so that we don't show too many
21694 // loading states too quickly.
21695 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
21696
21697 if (msUntilTimeout > 10) {
21698 if (workInProgressRootHasPendingPing) {
21699 var lastPingedTime = root.lastPingedTime;
21700
21701 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
21702 // This render was pinged but we didn't get to restart
21703 // earlier so try restarting now instead.
21704 root.lastPingedTime = expirationTime;
21705 prepareFreshStack(root, expirationTime);
21706 break;
21707 }
21708 }
21709
21710 var nextTime = getNextRootExpirationTimeToWorkOn(root);
21711
21712 if (nextTime !== NoWork && nextTime !== expirationTime) {
21713 // There's additional work on this root.
21714 break;
21715 }
21716
21717 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
21718 // We should prefer to render the fallback of at the last
21719 // suspended level. Ping the last suspended level to try
21720 // rendering it again.
21721 root.lastPingedTime = lastSuspendedTime;
21722 break;
21723 } // The render is suspended, it hasn't timed out, and there's no
21724 // lower priority work to do. Instead of committing the fallback
21725 // immediately, wait for more data to arrive.
21726
21727
21728 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
21729 break;
21730 }
21731 } // The work expired. Commit immediately.
21732
21733
21734 commitRoot(root);
21735 break;
21736 }
21737
21738 case RootSuspendedWithDelay:
21739 {
21740 markRootSuspendedAtTime(root, expirationTime);
21741 var _lastSuspendedTime = root.lastSuspendedTime;
21742
21743 if (expirationTime === _lastSuspendedTime) {
21744 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
21745 }
21746
21747 if ( // do not delay if we're inside an act() scope
21748 !( IsThisRendererActing.current)) {
21749 // We're suspended in a state that should be avoided. We'll try to
21750 // avoid committing it for as long as the timeouts let us.
21751 if (workInProgressRootHasPendingPing) {
21752 var _lastPingedTime = root.lastPingedTime;
21753
21754 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
21755 // This render was pinged but we didn't get to restart earlier
21756 // so try restarting now instead.
21757 root.lastPingedTime = expirationTime;
21758 prepareFreshStack(root, expirationTime);
21759 break;
21760 }
21761 }
21762
21763 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
21764
21765 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
21766 // There's additional work on this root.
21767 break;
21768 }
21769
21770 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
21771 // We should prefer to render the fallback of at the last
21772 // suspended level. Ping the last suspended level to try
21773 // rendering it again.
21774 root.lastPingedTime = _lastSuspendedTime;
21775 break;
21776 }
21777
21778 var _msUntilTimeout;
21779
21780 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
21781 // We have processed a suspense config whose expiration time we
21782 // can use as the timeout.
21783 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
21784 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
21785 // This should never normally happen because only new updates
21786 // cause delayed states, so we should have processed something.
21787 // However, this could also happen in an offscreen tree.
21788 _msUntilTimeout = 0;
21789 } else {
21790 // If we don't have a suspense config, we're going to use a
21791 // heuristic to determine how long we can suspend.
21792 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
21793 var currentTimeMs = now();
21794 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
21795 var timeElapsed = currentTimeMs - eventTimeMs;
21796
21797 if (timeElapsed < 0) {
21798 // We get this wrong some time since we estimate the time.
21799 timeElapsed = 0;
21800 }
21801
21802 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
21803 // event time is exact instead of inferred from expiration time
21804 // we don't need this.
21805
21806 if (timeUntilExpirationMs < _msUntilTimeout) {
21807 _msUntilTimeout = timeUntilExpirationMs;
21808 }
21809 } // Don't bother with a very short suspense time.
21810
21811
21812 if (_msUntilTimeout > 10) {
21813 // The render is suspended, it hasn't timed out, and there's no
21814 // lower priority work to do. Instead of committing the fallback
21815 // immediately, wait for more data to arrive.
21816 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
21817 break;
21818 }
21819 } // The work expired. Commit immediately.
21820
21821
21822 commitRoot(root);
21823 break;
21824 }
21825
21826 case RootCompleted:
21827 {
21828 // The work completed. Ready to commit.
21829 if ( // do not delay if we're inside an act() scope
21830 !( IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
21831 // If we have exceeded the minimum loading delay, which probably
21832 // means we have shown a spinner already, we might have to suspend
21833 // a bit longer to ensure that the spinner is shown for
21834 // enough time.
21835 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
21836
21837 if (_msUntilTimeout2 > 10) {
21838 markRootSuspendedAtTime(root, expirationTime);
21839 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
21840 break;
21841 }
21842 }
21843
21844 commitRoot(root);
21845 break;
21846 }
21847
21848 default:
21849 {
21850 {
21851 {
21852 throw Error( "Unknown root exit status." );
21853 }
21854 }
21855 }
21856 }
21857 } // This is the entry point for synchronous tasks that don't go
21858 // through Scheduler
21859
21860
21861 function performSyncWorkOnRoot(root) {
21862 // Check if there's expired work on this root. Otherwise, render at Sync.
21863 var lastExpiredTime = root.lastExpiredTime;
21864 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
21865
21866 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
21867 {
21868 throw Error( "Should not already be working." );
21869 }
21870 }
21871
21872 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
21873 // and prepare a fresh one. Otherwise we'll continue where we left off.
21874
21875 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
21876 prepareFreshStack(root, expirationTime);
21877 startWorkOnPendingInteractions(root, expirationTime);
21878 } // If we have a work-in-progress fiber, it means there's still work to do
21879 // in this root.
21880
21881
21882 if (workInProgress !== null) {
21883 var prevExecutionContext = executionContext;
21884 executionContext |= RenderContext;
21885 var prevDispatcher = pushDispatcher();
21886 var prevInteractions = pushInteractions(root);
21887 startWorkLoopTimer(workInProgress);
21888
21889 do {
21890 try {
21891 workLoopSync();
21892 break;
21893 } catch (thrownValue) {
21894 handleError(root, thrownValue);
21895 }
21896 } while (true);
21897
21898 resetContextDependencies();
21899 executionContext = prevExecutionContext;
21900 popDispatcher(prevDispatcher);
21901
21902 {
21903 popInteractions(prevInteractions);
21904 }
21905
21906 if (workInProgressRootExitStatus === RootFatalErrored) {
21907 var fatalError = workInProgressRootFatalError;
21908 stopInterruptedWorkLoopTimer();
21909 prepareFreshStack(root, expirationTime);
21910 markRootSuspendedAtTime(root, expirationTime);
21911 ensureRootIsScheduled(root);
21912 throw fatalError;
21913 }
21914
21915 if (workInProgress !== null) {
21916 // This is a sync render, so we should have finished the whole tree.
21917 {
21918 {
21919 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
21920 }
21921 }
21922 } else {
21923 // We now have a consistent tree. Because this is a sync render, we
21924 // will commit it even if something suspended.
21925 stopFinishedWorkLoopTimer();
21926 root.finishedWork = root.current.alternate;
21927 root.finishedExpirationTime = expirationTime;
21928 finishSyncRender(root);
21929 } // Before exiting, make sure there's a callback scheduled for the next
21930 // pending level.
21931
21932
21933 ensureRootIsScheduled(root);
21934 }
21935
21936 return null;
21937 }
21938
21939 function finishSyncRender(root) {
21940 // Set this to null to indicate there's no in-progress render.
21941 workInProgressRoot = null;
21942 commitRoot(root);
21943 }
21944 function flushDiscreteUpdates() {
21945 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
21946 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
21947 // those two cases. Need to fix this before exposing flushDiscreteUpdates
21948 // as a public API.
21949 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {
21950 {
21951 if ((executionContext & RenderContext) !== NoContext) {
21952 error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');
21953 }
21954 } // We're already rendering, so we can't synchronously flush pending work.
21955 // This is probably a nested event dispatch triggered by a lifecycle/effect,
21956 // like `el.focus()`. Exit.
21957
21958
21959 return;
21960 }
21961
21962 flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that
21963 // they fire before the next serial event.
21964
21965 flushPassiveEffects();
21966 }
21967 function syncUpdates(fn, a, b, c) {
21968 return runWithPriority$1(ImmediatePriority, fn.bind(null, a, b, c));
21969 }
21970
21971 function flushPendingDiscreteUpdates() {
21972 if (rootsWithPendingDiscreteUpdates !== null) {
21973 // For each root with pending discrete updates, schedule a callback to
21974 // immediately flush them.
21975 var roots = rootsWithPendingDiscreteUpdates;
21976 rootsWithPendingDiscreteUpdates = null;
21977 roots.forEach(function (expirationTime, root) {
21978 markRootExpiredAtTime(root, expirationTime);
21979 ensureRootIsScheduled(root);
21980 }); // Now flush the immediate queue.
21981
21982 flushSyncCallbackQueue();
21983 }
21984 }
21985
21986 function batchedUpdates$1(fn, a) {
21987 var prevExecutionContext = executionContext;
21988 executionContext |= BatchedContext;
21989
21990 try {
21991 return fn(a);
21992 } finally {
21993 executionContext = prevExecutionContext;
21994
21995 if (executionContext === NoContext) {
21996 // Flush the immediate callbacks that were scheduled during this batch
21997 flushSyncCallbackQueue();
21998 }
21999 }
22000 }
22001 function batchedEventUpdates$1(fn, a) {
22002 var prevExecutionContext = executionContext;
22003 executionContext |= EventContext;
22004
22005 try {
22006 return fn(a);
22007 } finally {
22008 executionContext = prevExecutionContext;
22009
22010 if (executionContext === NoContext) {
22011 // Flush the immediate callbacks that were scheduled during this batch
22012 flushSyncCallbackQueue();
22013 }
22014 }
22015 }
22016 function discreteUpdates$1(fn, a, b, c, d) {
22017 var prevExecutionContext = executionContext;
22018 executionContext |= DiscreteEventContext;
22019
22020 try {
22021 // Should this
22022 return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c, d));
22023 } finally {
22024 executionContext = prevExecutionContext;
22025
22026 if (executionContext === NoContext) {
22027 // Flush the immediate callbacks that were scheduled during this batch
22028 flushSyncCallbackQueue();
22029 }
22030 }
22031 }
22032 function unbatchedUpdates(fn, a) {
22033 var prevExecutionContext = executionContext;
22034 executionContext &= ~BatchedContext;
22035 executionContext |= LegacyUnbatchedContext;
22036
22037 try {
22038 return fn(a);
22039 } finally {
22040 executionContext = prevExecutionContext;
22041
22042 if (executionContext === NoContext) {
22043 // Flush the immediate callbacks that were scheduled during this batch
22044 flushSyncCallbackQueue();
22045 }
22046 }
22047 }
22048 function flushSync(fn, a) {
22049 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
22050 {
22051 {
22052 throw Error( "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." );
22053 }
22054 }
22055 }
22056
22057 var prevExecutionContext = executionContext;
22058 executionContext |= BatchedContext;
22059
22060 try {
22061 return runWithPriority$1(ImmediatePriority, fn.bind(null, a));
22062 } finally {
22063 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
22064 // Note that this will happen even if batchedUpdates is higher up
22065 // the stack.
22066
22067 flushSyncCallbackQueue();
22068 }
22069 }
22070
22071 function prepareFreshStack(root, expirationTime) {
22072 root.finishedWork = null;
22073 root.finishedExpirationTime = NoWork;
22074 var timeoutHandle = root.timeoutHandle;
22075
22076 if (timeoutHandle !== noTimeout) {
22077 // The root previous suspended and scheduled a timeout to commit a fallback
22078 // state. Now that we have additional work, cancel the timeout.
22079 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
22080
22081 cancelTimeout(timeoutHandle);
22082 }
22083
22084 if (workInProgress !== null) {
22085 var interruptedWork = workInProgress.return;
22086
22087 while (interruptedWork !== null) {
22088 unwindInterruptedWork(interruptedWork);
22089 interruptedWork = interruptedWork.return;
22090 }
22091 }
22092
22093 workInProgressRoot = root;
22094 workInProgress = createWorkInProgress(root.current, null);
22095 renderExpirationTime$1 = expirationTime;
22096 workInProgressRootExitStatus = RootIncomplete;
22097 workInProgressRootFatalError = null;
22098 workInProgressRootLatestProcessedExpirationTime = Sync;
22099 workInProgressRootLatestSuspenseTimeout = Sync;
22100 workInProgressRootCanSuspendUsingConfig = null;
22101 workInProgressRootNextUnprocessedUpdateTime = NoWork;
22102 workInProgressRootHasPendingPing = false;
22103
22104 {
22105 spawnedWorkDuringRender = null;
22106 }
22107
22108 {
22109 ReactStrictModeWarnings.discardPendingWarnings();
22110 }
22111 }
22112
22113 function handleError(root, thrownValue) {
22114 do {
22115 try {
22116 // Reset module-level state that was set during the render phase.
22117 resetContextDependencies();
22118 resetHooksAfterThrow();
22119 resetCurrentFiber();
22120
22121 if (workInProgress === null || workInProgress.return === null) {
22122 // Expected to be working on a non-root fiber. This is a fatal error
22123 // because there's no ancestor that can handle it; the root is
22124 // supposed to capture all errors that weren't caught by an error
22125 // boundary.
22126 workInProgressRootExitStatus = RootFatalErrored;
22127 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
22128 // sibling, or the parent if there are no siblings. But since the root
22129 // has no siblings nor a parent, we set it to null. Usually this is
22130 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
22131 // interntionally not calling those, we need set it here.
22132 // TODO: Consider calling `unwindWork` to pop the contexts.
22133
22134 workInProgress = null;
22135 return null;
22136 }
22137
22138 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
22139 // Record the time spent rendering before an error was thrown. This
22140 // avoids inaccurate Profiler durations in the case of a
22141 // suspended render.
22142 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
22143 }
22144
22145 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);
22146 workInProgress = completeUnitOfWork(workInProgress);
22147 } catch (yetAnotherThrownValue) {
22148 // Something in the return path also threw.
22149 thrownValue = yetAnotherThrownValue;
22150 continue;
22151 } // Return to the normal work loop.
22152
22153
22154 return;
22155 } while (true);
22156 }
22157
22158 function pushDispatcher(root) {
22159 var prevDispatcher = ReactCurrentDispatcher$1.current;
22160 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
22161
22162 if (prevDispatcher === null) {
22163 // The React isomorphic package does not include a default dispatcher.
22164 // Instead the first renderer will lazily attach one, in order to give
22165 // nicer error messages.
22166 return ContextOnlyDispatcher;
22167 } else {
22168 return prevDispatcher;
22169 }
22170 }
22171
22172 function popDispatcher(prevDispatcher) {
22173 ReactCurrentDispatcher$1.current = prevDispatcher;
22174 }
22175
22176 function pushInteractions(root) {
22177 {
22178 var prevInteractions = __interactionsRef.current;
22179 __interactionsRef.current = root.memoizedInteractions;
22180 return prevInteractions;
22181 }
22182 }
22183
22184 function popInteractions(prevInteractions) {
22185 {
22186 __interactionsRef.current = prevInteractions;
22187 }
22188 }
22189
22190 function markCommitTimeOfFallback() {
22191 globalMostRecentFallbackTime = now();
22192 }
22193 function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
22194 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
22195 workInProgressRootLatestProcessedExpirationTime = expirationTime;
22196 }
22197
22198 if (suspenseConfig !== null) {
22199 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
22200 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
22201
22202 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
22203 }
22204 }
22205 }
22206 function markUnprocessedUpdateTime(expirationTime) {
22207 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
22208 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
22209 }
22210 }
22211 function renderDidSuspend() {
22212 if (workInProgressRootExitStatus === RootIncomplete) {
22213 workInProgressRootExitStatus = RootSuspended;
22214 }
22215 }
22216 function renderDidSuspendDelayIfPossible() {
22217 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
22218 workInProgressRootExitStatus = RootSuspendedWithDelay;
22219 } // Check if there's a lower priority update somewhere else in the tree.
22220
22221
22222 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
22223 // Mark the current render as suspended, and then mark that there's a
22224 // pending update.
22225 // TODO: This should immediately interrupt the current render, instead
22226 // of waiting until the next time we yield.
22227 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);
22228 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
22229 }
22230 }
22231 function renderDidError() {
22232 if (workInProgressRootExitStatus !== RootCompleted) {
22233 workInProgressRootExitStatus = RootErrored;
22234 }
22235 } // Called during render to determine if anything has suspended.
22236 // Returns false if we're not sure.
22237
22238 function renderHasNotSuspendedYet() {
22239 // If something errored or completed, we can't really be sure,
22240 // so those are false.
22241 return workInProgressRootExitStatus === RootIncomplete;
22242 }
22243
22244 function inferTimeFromExpirationTime(expirationTime) {
22245 // We don't know exactly when the update was scheduled, but we can infer an
22246 // approximate start time from the expiration time.
22247 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22248 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
22249 }
22250
22251 function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
22252 // We don't know exactly when the update was scheduled, but we can infer an
22253 // approximate start time from the expiration time by subtracting the timeout
22254 // that was added to the event time.
22255 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22256 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
22257 } // The work loop is an extremely hot path. Tell Closure not to inline it.
22258
22259 /** @noinline */
22260
22261
22262 function workLoopSync() {
22263 // Already timed out, so perform work without checking if we need to yield.
22264 while (workInProgress !== null) {
22265 workInProgress = performUnitOfWork(workInProgress);
22266 }
22267 }
22268 /** @noinline */
22269
22270
22271 function workLoopConcurrent() {
22272 // Perform work until Scheduler asks us to yield
22273 while (workInProgress !== null && !shouldYield()) {
22274 workInProgress = performUnitOfWork(workInProgress);
22275 }
22276 }
22277
22278 function performUnitOfWork(unitOfWork) {
22279 // The current, flushed, state of this fiber is the alternate. Ideally
22280 // nothing should rely on this, but relying on it here means that we don't
22281 // need an additional field on the work in progress.
22282 var current = unitOfWork.alternate;
22283 startWorkTimer(unitOfWork);
22284 setCurrentFiber(unitOfWork);
22285 var next;
22286
22287 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
22288 startProfilerTimer(unitOfWork);
22289 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
22290 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
22291 } else {
22292 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
22293 }
22294
22295 resetCurrentFiber();
22296 unitOfWork.memoizedProps = unitOfWork.pendingProps;
22297
22298 if (next === null) {
22299 // If this doesn't spawn new work, complete the current work.
22300 next = completeUnitOfWork(unitOfWork);
22301 }
22302
22303 ReactCurrentOwner$2.current = null;
22304 return next;
22305 }
22306
22307 function completeUnitOfWork(unitOfWork) {
22308 // Attempt to complete the current unit of work, then move to the next
22309 // sibling. If there are no more siblings, return to the parent fiber.
22310 workInProgress = unitOfWork;
22311
22312 do {
22313 // The current, flushed, state of this fiber is the alternate. Ideally
22314 // nothing should rely on this, but relying on it here means that we don't
22315 // need an additional field on the work in progress.
22316 var current = workInProgress.alternate;
22317 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
22318
22319 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
22320 setCurrentFiber(workInProgress);
22321 var next = void 0;
22322
22323 if ( (workInProgress.mode & ProfileMode) === NoMode) {
22324 next = completeWork(current, workInProgress, renderExpirationTime$1);
22325 } else {
22326 startProfilerTimer(workInProgress);
22327 next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
22328
22329 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
22330 }
22331
22332 stopWorkTimer(workInProgress);
22333 resetCurrentFiber();
22334 resetChildExpirationTime(workInProgress);
22335
22336 if (next !== null) {
22337 // Completing this fiber spawned new work. Work on that next.
22338 return next;
22339 }
22340
22341 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
22342 (returnFiber.effectTag & Incomplete) === NoEffect) {
22343 // Append all the effects of the subtree and this fiber onto the effect
22344 // list of the parent. The completion order of the children affects the
22345 // side-effect order.
22346 if (returnFiber.firstEffect === null) {
22347 returnFiber.firstEffect = workInProgress.firstEffect;
22348 }
22349
22350 if (workInProgress.lastEffect !== null) {
22351 if (returnFiber.lastEffect !== null) {
22352 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
22353 }
22354
22355 returnFiber.lastEffect = workInProgress.lastEffect;
22356 } // If this fiber had side-effects, we append it AFTER the children's
22357 // side-effects. We can perform certain side-effects earlier if needed,
22358 // by doing multiple passes over the effect list. We don't want to
22359 // schedule our own side-effect on our own list because if end up
22360 // reusing children we'll schedule this effect onto itself since we're
22361 // at the end.
22362
22363
22364 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
22365 // list. PerformedWork effect is read by React DevTools but shouldn't be
22366 // committed.
22367
22368 if (effectTag > PerformedWork) {
22369 if (returnFiber.lastEffect !== null) {
22370 returnFiber.lastEffect.nextEffect = workInProgress;
22371 } else {
22372 returnFiber.firstEffect = workInProgress;
22373 }
22374
22375 returnFiber.lastEffect = workInProgress;
22376 }
22377 }
22378 } else {
22379 // This fiber did not complete because something threw. Pop values off
22380 // the stack without entering the complete phase. If this is a boundary,
22381 // capture values if possible.
22382 var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.
22383
22384
22385 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22386 // Record the render duration for the fiber that errored.
22387 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
22388
22389 var actualDuration = workInProgress.actualDuration;
22390 var child = workInProgress.child;
22391
22392 while (child !== null) {
22393 actualDuration += child.actualDuration;
22394 child = child.sibling;
22395 }
22396
22397 workInProgress.actualDuration = actualDuration;
22398 }
22399
22400 if (_next !== null) {
22401 // If completing this work spawned new work, do that next. We'll come
22402 // back here again.
22403 // Since we're restarting, remove anything that is not a host effect
22404 // from the effect tag.
22405 // TODO: The name stopFailedWorkTimer is misleading because Suspense
22406 // also captures and restarts.
22407 stopFailedWorkTimer(workInProgress);
22408 _next.effectTag &= HostEffectMask;
22409 return _next;
22410 }
22411
22412 stopWorkTimer(workInProgress);
22413
22414 if (returnFiber !== null) {
22415 // Mark the parent fiber as incomplete and clear its effect list.
22416 returnFiber.firstEffect = returnFiber.lastEffect = null;
22417 returnFiber.effectTag |= Incomplete;
22418 }
22419 }
22420
22421 var siblingFiber = workInProgress.sibling;
22422
22423 if (siblingFiber !== null) {
22424 // If there is more work to do in this returnFiber, do that next.
22425 return siblingFiber;
22426 } // Otherwise, return to the parent
22427
22428
22429 workInProgress = returnFiber;
22430 } while (workInProgress !== null); // We've reached the root.
22431
22432
22433 if (workInProgressRootExitStatus === RootIncomplete) {
22434 workInProgressRootExitStatus = RootCompleted;
22435 }
22436
22437 return null;
22438 }
22439
22440 function getRemainingExpirationTime(fiber) {
22441 var updateExpirationTime = fiber.expirationTime;
22442 var childExpirationTime = fiber.childExpirationTime;
22443 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
22444 }
22445
22446 function resetChildExpirationTime(completedWork) {
22447 if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {
22448 // The children of this component are hidden. Don't bubble their
22449 // expiration times.
22450 return;
22451 }
22452
22453 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
22454
22455 if ( (completedWork.mode & ProfileMode) !== NoMode) {
22456 // In profiling mode, resetChildExpirationTime is also used to reset
22457 // profiler durations.
22458 var actualDuration = completedWork.actualDuration;
22459 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
22460 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
22461 // When work is done, it should bubble to the parent's actualDuration. If
22462 // the fiber has not been cloned though, (meaning no work was done), then
22463 // this value will reflect the amount of time spent working on a previous
22464 // render. In that case it should not bubble. We determine whether it was
22465 // cloned by comparing the child pointer.
22466
22467 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
22468 var child = completedWork.child;
22469
22470 while (child !== null) {
22471 var childUpdateExpirationTime = child.expirationTime;
22472 var childChildExpirationTime = child.childExpirationTime;
22473
22474 if (childUpdateExpirationTime > newChildExpirationTime) {
22475 newChildExpirationTime = childUpdateExpirationTime;
22476 }
22477
22478 if (childChildExpirationTime > newChildExpirationTime) {
22479 newChildExpirationTime = childChildExpirationTime;
22480 }
22481
22482 if (shouldBubbleActualDurations) {
22483 actualDuration += child.actualDuration;
22484 }
22485
22486 treeBaseDuration += child.treeBaseDuration;
22487 child = child.sibling;
22488 }
22489
22490 completedWork.actualDuration = actualDuration;
22491 completedWork.treeBaseDuration = treeBaseDuration;
22492 } else {
22493 var _child = completedWork.child;
22494
22495 while (_child !== null) {
22496 var _childUpdateExpirationTime = _child.expirationTime;
22497 var _childChildExpirationTime = _child.childExpirationTime;
22498
22499 if (_childUpdateExpirationTime > newChildExpirationTime) {
22500 newChildExpirationTime = _childUpdateExpirationTime;
22501 }
22502
22503 if (_childChildExpirationTime > newChildExpirationTime) {
22504 newChildExpirationTime = _childChildExpirationTime;
22505 }
22506
22507 _child = _child.sibling;
22508 }
22509 }
22510
22511 completedWork.childExpirationTime = newChildExpirationTime;
22512 }
22513
22514 function commitRoot(root) {
22515 var renderPriorityLevel = getCurrentPriorityLevel();
22516 runWithPriority$1(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
22517 return null;
22518 }
22519
22520 function commitRootImpl(root, renderPriorityLevel) {
22521 do {
22522 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
22523 // means `flushPassiveEffects` will sometimes result in additional
22524 // passive effects. So we need to keep flushing in a loop until there are
22525 // no more pending effects.
22526 // TODO: Might be better if `flushPassiveEffects` did not automatically
22527 // flush synchronous work at the end, to avoid factoring hazards like this.
22528 flushPassiveEffects();
22529 } while (rootWithPendingPassiveEffects !== null);
22530
22531 flushRenderPhaseStrictModeWarningsInDEV();
22532
22533 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22534 {
22535 throw Error( "Should not already be working." );
22536 }
22537 }
22538
22539 var finishedWork = root.finishedWork;
22540 var expirationTime = root.finishedExpirationTime;
22541
22542 if (finishedWork === null) {
22543 return null;
22544 }
22545
22546 root.finishedWork = null;
22547 root.finishedExpirationTime = NoWork;
22548
22549 if (!(finishedWork !== root.current)) {
22550 {
22551 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
22552 }
22553 } // commitRoot never returns a continuation; it always finishes synchronously.
22554 // So we can clear these now to allow a new callback to be scheduled.
22555
22556
22557 root.callbackNode = null;
22558 root.callbackExpirationTime = NoWork;
22559 root.callbackPriority = NoPriority;
22560 root.nextKnownPendingLevel = NoWork;
22561 startCommitTimer(); // Update the first and last pending times on this root. The new first
22562 // pending time is whatever is left on the root fiber.
22563
22564 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
22565 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
22566
22567 if (root === workInProgressRoot) {
22568 // We can reset these now that they are finished.
22569 workInProgressRoot = null;
22570 workInProgress = null;
22571 renderExpirationTime$1 = NoWork;
22572 } // This indicates that the last root we worked on is not the same one that
22573 // we're committing now. This most commonly happens when a suspended root
22574 // times out.
22575 // Get the list of effects.
22576
22577
22578 var firstEffect;
22579
22580 if (finishedWork.effectTag > PerformedWork) {
22581 // A fiber's effect list consists only of its children, not itself. So if
22582 // the root has an effect, we need to add it to the end of the list. The
22583 // resulting list is the set that would belong to the root's parent, if it
22584 // had one; that is, all the effects in the tree including the root.
22585 if (finishedWork.lastEffect !== null) {
22586 finishedWork.lastEffect.nextEffect = finishedWork;
22587 firstEffect = finishedWork.firstEffect;
22588 } else {
22589 firstEffect = finishedWork;
22590 }
22591 } else {
22592 // There is no effect on the root.
22593 firstEffect = finishedWork.firstEffect;
22594 }
22595
22596 if (firstEffect !== null) {
22597 var prevExecutionContext = executionContext;
22598 executionContext |= CommitContext;
22599 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
22600
22601 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
22602 // of the effect list for each phase: all mutation effects come before all
22603 // layout effects, and so on.
22604 // The first phase a "before mutation" phase. We use this phase to read the
22605 // state of the host tree right before we mutate it. This is where
22606 // getSnapshotBeforeUpdate is called.
22607
22608 startCommitSnapshotEffectsTimer();
22609 prepareForCommit(root.containerInfo);
22610 nextEffect = firstEffect;
22611
22612 do {
22613 {
22614 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
22615
22616 if (hasCaughtError()) {
22617 if (!(nextEffect !== null)) {
22618 {
22619 throw Error( "Should be working on an effect." );
22620 }
22621 }
22622
22623 var error = clearCaughtError();
22624 captureCommitPhaseError(nextEffect, error);
22625 nextEffect = nextEffect.nextEffect;
22626 }
22627 }
22628 } while (nextEffect !== null);
22629
22630 stopCommitSnapshotEffectsTimer();
22631
22632 {
22633 // Mark the current commit time to be shared by all Profilers in this
22634 // batch. This enables them to be grouped later.
22635 recordCommitTime();
22636 } // The next phase is the mutation phase, where we mutate the host tree.
22637
22638
22639 startCommitHostEffectsTimer();
22640 nextEffect = firstEffect;
22641
22642 do {
22643 {
22644 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
22645
22646 if (hasCaughtError()) {
22647 if (!(nextEffect !== null)) {
22648 {
22649 throw Error( "Should be working on an effect." );
22650 }
22651 }
22652
22653 var _error = clearCaughtError();
22654
22655 captureCommitPhaseError(nextEffect, _error);
22656 nextEffect = nextEffect.nextEffect;
22657 }
22658 }
22659 } while (nextEffect !== null);
22660
22661 stopCommitHostEffectsTimer();
22662 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
22663 // the mutation phase, so that the previous tree is still current during
22664 // componentWillUnmount, but before the layout phase, so that the finished
22665 // work is current during componentDidMount/Update.
22666
22667 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
22668 // the host tree after it's been mutated. The idiomatic use case for this is
22669 // layout, but class component lifecycles also fire here for legacy reasons.
22670
22671 startCommitLifeCyclesTimer();
22672 nextEffect = firstEffect;
22673
22674 do {
22675 {
22676 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
22677
22678 if (hasCaughtError()) {
22679 if (!(nextEffect !== null)) {
22680 {
22681 throw Error( "Should be working on an effect." );
22682 }
22683 }
22684
22685 var _error2 = clearCaughtError();
22686
22687 captureCommitPhaseError(nextEffect, _error2);
22688 nextEffect = nextEffect.nextEffect;
22689 }
22690 }
22691 } while (nextEffect !== null);
22692
22693 stopCommitLifeCyclesTimer();
22694 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
22695 // opportunity to paint.
22696
22697 requestPaint();
22698
22699 {
22700 popInteractions(prevInteractions);
22701 }
22702
22703 executionContext = prevExecutionContext;
22704 } else {
22705 // No effects.
22706 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
22707 // no effects.
22708 // TODO: Maybe there's a better way to report this.
22709
22710 startCommitSnapshotEffectsTimer();
22711 stopCommitSnapshotEffectsTimer();
22712
22713 {
22714 recordCommitTime();
22715 }
22716
22717 startCommitHostEffectsTimer();
22718 stopCommitHostEffectsTimer();
22719 startCommitLifeCyclesTimer();
22720 stopCommitLifeCyclesTimer();
22721 }
22722
22723 stopCommitTimer();
22724 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
22725
22726 if (rootDoesHavePassiveEffects) {
22727 // This commit has passive effects. Stash a reference to them. But don't
22728 // schedule a callback until after flushing layout work.
22729 rootDoesHavePassiveEffects = false;
22730 rootWithPendingPassiveEffects = root;
22731 pendingPassiveEffectsExpirationTime = expirationTime;
22732 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
22733 } else {
22734 // We are done with the effect chain at this point so let's clear the
22735 // nextEffect pointers to assist with GC. If we have passive effects, we'll
22736 // clear this in flushPassiveEffects.
22737 nextEffect = firstEffect;
22738
22739 while (nextEffect !== null) {
22740 var nextNextEffect = nextEffect.nextEffect;
22741 nextEffect.nextEffect = null;
22742 nextEffect = nextNextEffect;
22743 }
22744 } // Check if there's remaining work on this root
22745
22746
22747 var remainingExpirationTime = root.firstPendingTime;
22748
22749 if (remainingExpirationTime !== NoWork) {
22750 {
22751 if (spawnedWorkDuringRender !== null) {
22752 var expirationTimes = spawnedWorkDuringRender;
22753 spawnedWorkDuringRender = null;
22754
22755 for (var i = 0; i < expirationTimes.length; i++) {
22756 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
22757 }
22758 }
22759
22760 schedulePendingInteractions(root, remainingExpirationTime);
22761 }
22762 } else {
22763 // If there's no remaining work, we can clear the set of already failed
22764 // error boundaries.
22765 legacyErrorBoundariesThatAlreadyFailed = null;
22766 }
22767
22768 {
22769 if (!rootDidHavePassiveEffects) {
22770 // If there are no passive effects, then we can complete the pending interactions.
22771 // Otherwise, we'll wait until after the passive effects are flushed.
22772 // Wait to do this until after remaining work has been scheduled,
22773 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
22774 finishPendingInteractions(root, expirationTime);
22775 }
22776 }
22777
22778 if (remainingExpirationTime === Sync) {
22779 // Count the number of times the root synchronously re-renders without
22780 // finishing. If there are too many, it indicates an infinite update loop.
22781 if (root === rootWithNestedUpdates) {
22782 nestedUpdateCount++;
22783 } else {
22784 nestedUpdateCount = 0;
22785 rootWithNestedUpdates = root;
22786 }
22787 } else {
22788 nestedUpdateCount = 0;
22789 }
22790
22791 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
22792 // additional work on this root is scheduled.
22793
22794 ensureRootIsScheduled(root);
22795
22796 if (hasUncaughtError) {
22797 hasUncaughtError = false;
22798 var _error3 = firstUncaughtError;
22799 firstUncaughtError = null;
22800 throw _error3;
22801 }
22802
22803 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
22804 // This is a legacy edge case. We just committed the initial mount of
22805 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
22806 // synchronously, but layout updates should be deferred until the end
22807 // of the batch.
22808 return null;
22809 } // If layout work was scheduled, flush it now.
22810
22811
22812 flushSyncCallbackQueue();
22813 return null;
22814 }
22815
22816 function commitBeforeMutationEffects() {
22817 while (nextEffect !== null) {
22818 var effectTag = nextEffect.effectTag;
22819
22820 if ((effectTag & Snapshot) !== NoEffect) {
22821 setCurrentFiber(nextEffect);
22822 recordEffect();
22823 var current = nextEffect.alternate;
22824 commitBeforeMutationLifeCycles(current, nextEffect);
22825 resetCurrentFiber();
22826 }
22827
22828 if ((effectTag & Passive) !== NoEffect) {
22829 // If there are passive effects, schedule a callback to flush at
22830 // the earliest opportunity.
22831 if (!rootDoesHavePassiveEffects) {
22832 rootDoesHavePassiveEffects = true;
22833 scheduleCallback(NormalPriority, function () {
22834 flushPassiveEffects();
22835 return null;
22836 });
22837 }
22838 }
22839
22840 nextEffect = nextEffect.nextEffect;
22841 }
22842 }
22843
22844 function commitMutationEffects(root, renderPriorityLevel) {
22845 // TODO: Should probably move the bulk of this function to commitWork.
22846 while (nextEffect !== null) {
22847 setCurrentFiber(nextEffect);
22848 var effectTag = nextEffect.effectTag;
22849
22850 if (effectTag & ContentReset) {
22851 commitResetTextContent(nextEffect);
22852 }
22853
22854 if (effectTag & Ref) {
22855 var current = nextEffect.alternate;
22856
22857 if (current !== null) {
22858 commitDetachRef(current);
22859 }
22860 } // The following switch statement is only concerned about placement,
22861 // updates, and deletions. To avoid needing to add a case for every possible
22862 // bitmap value, we remove the secondary effects from the effect tag and
22863 // switch on that value.
22864
22865
22866 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
22867
22868 switch (primaryEffectTag) {
22869 case Placement:
22870 {
22871 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
22872 // inserted, before any life-cycles like componentDidMount gets called.
22873 // TODO: findDOMNode doesn't rely on this any more but isMounted does
22874 // and isMounted is deprecated anyway so we should be able to kill this.
22875
22876 nextEffect.effectTag &= ~Placement;
22877 break;
22878 }
22879
22880 case PlacementAndUpdate:
22881 {
22882 // Placement
22883 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
22884 // inserted, before any life-cycles like componentDidMount gets called.
22885
22886 nextEffect.effectTag &= ~Placement; // Update
22887
22888 var _current = nextEffect.alternate;
22889 commitWork(_current, nextEffect);
22890 break;
22891 }
22892
22893 case Hydrating:
22894 {
22895 nextEffect.effectTag &= ~Hydrating;
22896 break;
22897 }
22898
22899 case HydratingAndUpdate:
22900 {
22901 nextEffect.effectTag &= ~Hydrating; // Update
22902
22903 var _current2 = nextEffect.alternate;
22904 commitWork(_current2, nextEffect);
22905 break;
22906 }
22907
22908 case Update:
22909 {
22910 var _current3 = nextEffect.alternate;
22911 commitWork(_current3, nextEffect);
22912 break;
22913 }
22914
22915 case Deletion:
22916 {
22917 commitDeletion(root, nextEffect, renderPriorityLevel);
22918 break;
22919 }
22920 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
22921
22922
22923 recordEffect();
22924 resetCurrentFiber();
22925 nextEffect = nextEffect.nextEffect;
22926 }
22927 }
22928
22929 function commitLayoutEffects(root, committedExpirationTime) {
22930 // TODO: Should probably move the bulk of this function to commitWork.
22931 while (nextEffect !== null) {
22932 setCurrentFiber(nextEffect);
22933 var effectTag = nextEffect.effectTag;
22934
22935 if (effectTag & (Update | Callback)) {
22936 recordEffect();
22937 var current = nextEffect.alternate;
22938 commitLifeCycles(root, current, nextEffect);
22939 }
22940
22941 if (effectTag & Ref) {
22942 recordEffect();
22943 commitAttachRef(nextEffect);
22944 }
22945
22946 resetCurrentFiber();
22947 nextEffect = nextEffect.nextEffect;
22948 }
22949 }
22950
22951 function flushPassiveEffects() {
22952 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
22953 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
22954 pendingPassiveEffectsRenderPriority = NoPriority;
22955 return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);
22956 }
22957 }
22958
22959 function flushPassiveEffectsImpl() {
22960 if (rootWithPendingPassiveEffects === null) {
22961 return false;
22962 }
22963
22964 var root = rootWithPendingPassiveEffects;
22965 var expirationTime = pendingPassiveEffectsExpirationTime;
22966 rootWithPendingPassiveEffects = null;
22967 pendingPassiveEffectsExpirationTime = NoWork;
22968
22969 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22970 {
22971 throw Error( "Cannot flush passive effects while already rendering." );
22972 }
22973 }
22974
22975 var prevExecutionContext = executionContext;
22976 executionContext |= CommitContext;
22977 var prevInteractions = pushInteractions(root);
22978
22979 {
22980 // Note: This currently assumes there are no passive effects on the root fiber
22981 // because the root is not part of its own effect list.
22982 // This could change in the future.
22983 var _effect2 = root.current.firstEffect;
22984
22985 while (_effect2 !== null) {
22986 {
22987 setCurrentFiber(_effect2);
22988 invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
22989
22990 if (hasCaughtError()) {
22991 if (!(_effect2 !== null)) {
22992 {
22993 throw Error( "Should be working on an effect." );
22994 }
22995 }
22996
22997 var _error5 = clearCaughtError();
22998
22999 captureCommitPhaseError(_effect2, _error5);
23000 }
23001
23002 resetCurrentFiber();
23003 }
23004
23005 var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC
23006
23007 _effect2.nextEffect = null;
23008 _effect2 = nextNextEffect;
23009 }
23010 }
23011
23012 {
23013 popInteractions(prevInteractions);
23014 finishPendingInteractions(root, expirationTime);
23015 }
23016
23017 executionContext = prevExecutionContext;
23018 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
23019 // exceeds the limit, we'll fire a warning.
23020
23021 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
23022 return true;
23023 }
23024
23025 function isAlreadyFailedLegacyErrorBoundary(instance) {
23026 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
23027 }
23028 function markLegacyErrorBoundaryAsFailed(instance) {
23029 if (legacyErrorBoundariesThatAlreadyFailed === null) {
23030 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
23031 } else {
23032 legacyErrorBoundariesThatAlreadyFailed.add(instance);
23033 }
23034 }
23035
23036 function prepareToThrowUncaughtError(error) {
23037 if (!hasUncaughtError) {
23038 hasUncaughtError = true;
23039 firstUncaughtError = error;
23040 }
23041 }
23042
23043 var onUncaughtError = prepareToThrowUncaughtError;
23044
23045 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
23046 var errorInfo = createCapturedValue(error, sourceFiber);
23047 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
23048 enqueueUpdate(rootFiber, update);
23049 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
23050
23051 if (root !== null) {
23052 ensureRootIsScheduled(root);
23053 schedulePendingInteractions(root, Sync);
23054 }
23055 }
23056
23057 function captureCommitPhaseError(sourceFiber, error) {
23058 if (sourceFiber.tag === HostRoot) {
23059 // Error was thrown at the root. There is no parent, so the root
23060 // itself should capture it.
23061 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
23062 return;
23063 }
23064
23065 var fiber = sourceFiber.return;
23066
23067 while (fiber !== null) {
23068 if (fiber.tag === HostRoot) {
23069 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
23070 return;
23071 } else if (fiber.tag === ClassComponent) {
23072 var ctor = fiber.type;
23073 var instance = fiber.stateNode;
23074
23075 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
23076 var errorInfo = createCapturedValue(error, sourceFiber);
23077 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
23078 Sync);
23079 enqueueUpdate(fiber, update);
23080 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
23081
23082 if (root !== null) {
23083 ensureRootIsScheduled(root);
23084 schedulePendingInteractions(root, Sync);
23085 }
23086
23087 return;
23088 }
23089 }
23090
23091 fiber = fiber.return;
23092 }
23093 }
23094 function pingSuspendedRoot(root, thenable, suspendedTime) {
23095 var pingCache = root.pingCache;
23096
23097 if (pingCache !== null) {
23098 // The thenable resolved, so we no longer need to memoize, because it will
23099 // never be thrown again.
23100 pingCache.delete(thenable);
23101 }
23102
23103 if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {
23104 // Received a ping at the same priority level at which we're currently
23105 // rendering. We might want to restart this render. This should mirror
23106 // the logic of whether or not a root suspends once it completes.
23107 // TODO: If we're rendering sync either due to Sync, Batched or expired,
23108 // we should probably never restart.
23109 // If we're suspended with delay, we'll always suspend so we can always
23110 // restart. If we're suspended without any updates, it might be a retry.
23111 // If it's early in the retry we can restart. We can't know for sure
23112 // whether we'll eventually process an update during this render pass,
23113 // but it's somewhat unlikely that we get to a ping before that, since
23114 // getting to the root most update is usually very fast.
23115 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
23116 // Restart from the root. Don't need to schedule a ping because
23117 // we're already working on this tree.
23118 prepareFreshStack(root, renderExpirationTime$1);
23119 } else {
23120 // Even though we can't restart right now, we might get an
23121 // opportunity later. So we mark this render as having a ping.
23122 workInProgressRootHasPendingPing = true;
23123 }
23124
23125 return;
23126 }
23127
23128 if (!isRootSuspendedAtTime(root, suspendedTime)) {
23129 // The root is no longer suspended at this time.
23130 return;
23131 }
23132
23133 var lastPingedTime = root.lastPingedTime;
23134
23135 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
23136 // There's already a lower priority ping scheduled.
23137 return;
23138 } // Mark the time at which this ping was scheduled.
23139
23140
23141 root.lastPingedTime = suspendedTime;
23142
23143 ensureRootIsScheduled(root);
23144 schedulePendingInteractions(root, suspendedTime);
23145 }
23146
23147 function retryTimedOutBoundary(boundaryFiber, retryTime) {
23148 // The boundary fiber (a Suspense component or SuspenseList component)
23149 // previously was rendered in its fallback state. One of the promises that
23150 // suspended it has resolved, which means at least part of the tree was
23151 // likely unblocked. Try rendering again, at a new expiration time.
23152 if (retryTime === NoWork) {
23153 var suspenseConfig = null; // Retries don't carry over the already committed update.
23154
23155 var currentTime = requestCurrentTimeForUpdate();
23156 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
23157 } // TODO: Special case idle priority?
23158
23159
23160 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
23161
23162 if (root !== null) {
23163 ensureRootIsScheduled(root);
23164 schedulePendingInteractions(root, retryTime);
23165 }
23166 }
23167 function resolveRetryThenable(boundaryFiber, thenable) {
23168 var retryTime = NoWork; // Default
23169
23170 var retryCache;
23171
23172 {
23173 retryCache = boundaryFiber.stateNode;
23174 }
23175
23176 if (retryCache !== null) {
23177 // The thenable resolved, so we no longer need to memoize, because it will
23178 // never be thrown again.
23179 retryCache.delete(thenable);
23180 }
23181
23182 retryTimedOutBoundary(boundaryFiber, retryTime);
23183 } // Computes the next Just Noticeable Difference (JND) boundary.
23184 // The theory is that a person can't tell the difference between small differences in time.
23185 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
23186 // difference in the experience. However, waiting for longer might mean that we can avoid
23187 // showing an intermediate loading state. The longer we have already waited, the harder it
23188 // is to tell small differences in time. Therefore, the longer we've already waited,
23189 // the longer we can wait additionally. At some point we have to give up though.
23190 // We pick a train model where the next boundary commits at a consistent schedule.
23191 // These particular numbers are vague estimates. We expect to adjust them based on research.
23192
23193 function jnd(timeElapsed) {
23194 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
23195 }
23196
23197 function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
23198 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
23199
23200 if (busyMinDurationMs <= 0) {
23201 return 0;
23202 }
23203
23204 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
23205
23206 var currentTimeMs = now();
23207 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
23208 var timeElapsed = currentTimeMs - eventTimeMs;
23209
23210 if (timeElapsed <= busyDelayMs) {
23211 // If we haven't yet waited longer than the initial delay, we don't
23212 // have to wait any additional time.
23213 return 0;
23214 }
23215
23216 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
23217
23218 return msUntilTimeout;
23219 }
23220
23221 function checkForNestedUpdates() {
23222 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
23223 nestedUpdateCount = 0;
23224 rootWithNestedUpdates = null;
23225
23226 {
23227 {
23228 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." );
23229 }
23230 }
23231 }
23232
23233 {
23234 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
23235 nestedPassiveUpdateCount = 0;
23236
23237 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.');
23238 }
23239 }
23240 }
23241
23242 function flushRenderPhaseStrictModeWarningsInDEV() {
23243 {
23244 ReactStrictModeWarnings.flushLegacyContextWarning();
23245
23246 {
23247 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
23248 }
23249 }
23250 }
23251
23252 function stopFinishedWorkLoopTimer() {
23253 var didCompleteRoot = true;
23254 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23255 interruptedBy = null;
23256 }
23257
23258 function stopInterruptedWorkLoopTimer() {
23259 // TODO: Track which fiber caused the interruption.
23260 var didCompleteRoot = false;
23261 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23262 interruptedBy = null;
23263 }
23264
23265 function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
23266 if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {
23267 interruptedBy = fiberThatReceivedUpdate;
23268 }
23269 }
23270
23271 var didWarnStateUpdateForUnmountedComponent = null;
23272
23273 function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
23274 {
23275 var tag = fiber.tag;
23276
23277 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
23278 // Only warn for user-defined components, not internal ones like Suspense.
23279 return;
23280 }
23281 // the problematic code almost always lies inside that component.
23282
23283
23284 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23285
23286 if (didWarnStateUpdateForUnmountedComponent !== null) {
23287 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
23288 return;
23289 }
23290
23291 didWarnStateUpdateForUnmountedComponent.add(componentName);
23292 } else {
23293 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
23294 }
23295
23296 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));
23297 }
23298 }
23299
23300 var beginWork$1;
23301
23302 {
23303 var dummyFiber = null;
23304
23305 beginWork$1 = function (current, unitOfWork, expirationTime) {
23306 // If a component throws an error, we replay it again in a synchronously
23307 // dispatched event, so that the debugger will treat it as an uncaught
23308 // error See ReactErrorUtils for more information.
23309 // Before entering the begin phase, copy the work-in-progress onto a dummy
23310 // fiber. If beginWork throws, we'll use this to reset the state.
23311 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
23312
23313 try {
23314 return beginWork(current, unitOfWork, expirationTime);
23315 } catch (originalError) {
23316 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
23317 // Don't replay promises. Treat everything else like an error.
23318 throw originalError;
23319 } // Keep this code in sync with handleError; any changes here must have
23320 // corresponding changes there.
23321
23322
23323 resetContextDependencies();
23324 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
23325 // same fiber again.
23326 // Unwind the failed stack frame
23327
23328 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
23329
23330 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
23331
23332 if ( unitOfWork.mode & ProfileMode) {
23333 // Reset the profiler timer.
23334 startProfilerTimer(unitOfWork);
23335 } // Run beginWork again.
23336
23337
23338 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, expirationTime);
23339
23340 if (hasCaughtError()) {
23341 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
23342 // Rethrow this error instead of the original one.
23343
23344 throw replayError;
23345 } else {
23346 // This branch is reachable if the render phase is impure.
23347 throw originalError;
23348 }
23349 }
23350 };
23351 }
23352
23353 var didWarnAboutUpdateInRender = false;
23354 var didWarnAboutUpdateInRenderForAnotherComponent;
23355
23356 {
23357 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
23358 }
23359
23360 function warnAboutRenderPhaseUpdatesInDEV(fiber) {
23361 {
23362 if (isRendering && (executionContext & RenderContext) !== NoContext) {
23363 switch (fiber.tag) {
23364 case FunctionComponent:
23365 case ForwardRef:
23366 case SimpleMemoComponent:
23367 {
23368 var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
23369
23370 var dedupeKey = renderingComponentName;
23371
23372 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
23373 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
23374 var setStateComponentName = getComponentName(fiber.type) || 'Unknown';
23375
23376 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);
23377 }
23378
23379 break;
23380 }
23381
23382 case ClassComponent:
23383 {
23384 if (!didWarnAboutUpdateInRender) {
23385 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
23386
23387 didWarnAboutUpdateInRender = true;
23388 }
23389
23390 break;
23391 }
23392 }
23393 }
23394 }
23395 } // a 'shared' variable that changes when act() opens/closes in tests.
23396
23397
23398 var IsThisRendererActing = {
23399 current: false
23400 };
23401 function warnIfNotScopedWithMatchingAct(fiber) {
23402 {
23403 if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
23404 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));
23405 }
23406 }
23407 }
23408 function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
23409 {
23410 if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23411 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));
23412 }
23413 }
23414 }
23415
23416 function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
23417 {
23418 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23419 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));
23420 }
23421 }
23422 }
23423
23424 var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
23425
23426 var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
23427 // scheduler is the actual recommendation. The alternative could be a testing build,
23428 // a new lib, or whatever; we dunno just yet. This message is for early adopters
23429 // to get their tests right.
23430
23431 function warnIfUnmockedScheduler(fiber) {
23432 {
23433 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
23434 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
23435 didWarnAboutUnmockedScheduler = true;
23436
23437 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');
23438 }
23439 }
23440 }
23441 }
23442
23443 function computeThreadID(root, expirationTime) {
23444 // Interaction threads are unique per root and expiration time.
23445 return expirationTime * 1000 + root.interactionThreadID;
23446 }
23447
23448 function markSpawnedWork(expirationTime) {
23449
23450 if (spawnedWorkDuringRender === null) {
23451 spawnedWorkDuringRender = [expirationTime];
23452 } else {
23453 spawnedWorkDuringRender.push(expirationTime);
23454 }
23455 }
23456
23457 function scheduleInteractions(root, expirationTime, interactions) {
23458
23459 if (interactions.size > 0) {
23460 var pendingInteractionMap = root.pendingInteractionMap;
23461 var pendingInteractions = pendingInteractionMap.get(expirationTime);
23462
23463 if (pendingInteractions != null) {
23464 interactions.forEach(function (interaction) {
23465 if (!pendingInteractions.has(interaction)) {
23466 // Update the pending async work count for previously unscheduled interaction.
23467 interaction.__count++;
23468 }
23469
23470 pendingInteractions.add(interaction);
23471 });
23472 } else {
23473 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
23474
23475 interactions.forEach(function (interaction) {
23476 interaction.__count++;
23477 });
23478 }
23479
23480 var subscriber = __subscriberRef.current;
23481
23482 if (subscriber !== null) {
23483 var threadID = computeThreadID(root, expirationTime);
23484 subscriber.onWorkScheduled(interactions, threadID);
23485 }
23486 }
23487 }
23488
23489 function schedulePendingInteractions(root, expirationTime) {
23490
23491 scheduleInteractions(root, expirationTime, __interactionsRef.current);
23492 }
23493
23494 function startWorkOnPendingInteractions(root, expirationTime) {
23495 // we can accurately attribute time spent working on it, And so that cascading
23496 // work triggered during the render phase will be associated with it.
23497
23498
23499 var interactions = new Set();
23500 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23501 if (scheduledExpirationTime >= expirationTime) {
23502 scheduledInteractions.forEach(function (interaction) {
23503 return interactions.add(interaction);
23504 });
23505 }
23506 }); // Store the current set of interactions on the FiberRoot for a few reasons:
23507 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
23508 // without having to recalculate it. We will also use it in commitWork() to
23509 // pass to any Profiler onRender() hooks. This also provides DevTools with a
23510 // way to access it when the onCommitRoot() hook is called.
23511
23512 root.memoizedInteractions = interactions;
23513
23514 if (interactions.size > 0) {
23515 var subscriber = __subscriberRef.current;
23516
23517 if (subscriber !== null) {
23518 var threadID = computeThreadID(root, expirationTime);
23519
23520 try {
23521 subscriber.onWorkStarted(interactions, threadID);
23522 } catch (error) {
23523 // If the subscriber throws, rethrow it in a separate task
23524 scheduleCallback(ImmediatePriority, function () {
23525 throw error;
23526 });
23527 }
23528 }
23529 }
23530 }
23531
23532 function finishPendingInteractions(root, committedExpirationTime) {
23533
23534 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
23535 var subscriber;
23536
23537 try {
23538 subscriber = __subscriberRef.current;
23539
23540 if (subscriber !== null && root.memoizedInteractions.size > 0) {
23541 var threadID = computeThreadID(root, committedExpirationTime);
23542 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
23543 }
23544 } catch (error) {
23545 // If the subscriber throws, rethrow it in a separate task
23546 scheduleCallback(ImmediatePriority, function () {
23547 throw error;
23548 });
23549 } finally {
23550 // Clear completed interactions from the pending Map.
23551 // Unless the render was suspended or cascading work was scheduled,
23552 // In which case– leave pending interactions until the subsequent render.
23553 var pendingInteractionMap = root.pendingInteractionMap;
23554 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23555 // Only decrement the pending interaction count if we're done.
23556 // If there's still work at the current priority,
23557 // That indicates that we are waiting for suspense data.
23558 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
23559 pendingInteractionMap.delete(scheduledExpirationTime);
23560 scheduledInteractions.forEach(function (interaction) {
23561 interaction.__count--;
23562
23563 if (subscriber !== null && interaction.__count === 0) {
23564 try {
23565 subscriber.onInteractionScheduledWorkCompleted(interaction);
23566 } catch (error) {
23567 // If the subscriber throws, rethrow it in a separate task
23568 scheduleCallback(ImmediatePriority, function () {
23569 throw error;
23570 });
23571 }
23572 }
23573 });
23574 }
23575 });
23576 }
23577 }
23578
23579 var onScheduleFiberRoot = null;
23580 var onCommitFiberRoot = null;
23581 var onCommitFiberUnmount = null;
23582 var hasLoggedError = false;
23583 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
23584 function injectInternals(internals) {
23585 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
23586 // No DevTools
23587 return false;
23588 }
23589
23590 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
23591
23592 if (hook.isDisabled) {
23593 // This isn't a real property on the hook, but it can be set to opt out
23594 // of DevTools integration and associated warnings and logs.
23595 // https://github.com/facebook/react/issues/3877
23596 return true;
23597 }
23598
23599 if (!hook.supportsFiber) {
23600 {
23601 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');
23602 } // DevTools exists, even though it doesn't support Fiber.
23603
23604
23605 return true;
23606 }
23607
23608 try {
23609 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
23610
23611 if (true) {
23612 // Only used by Fast Refresh
23613 if (typeof hook.onScheduleFiberRoot === 'function') {
23614 onScheduleFiberRoot = function (root, children) {
23615 try {
23616 hook.onScheduleFiberRoot(rendererID, root, children);
23617 } catch (err) {
23618 if (true && !hasLoggedError) {
23619 hasLoggedError = true;
23620
23621 error('React instrumentation encountered an error: %s', err);
23622 }
23623 }
23624 };
23625 }
23626 }
23627
23628 onCommitFiberRoot = function (root, expirationTime) {
23629 try {
23630 var didError = (root.current.effectTag & DidCapture) === DidCapture;
23631
23632 if (enableProfilerTimer) {
23633 var currentTime = getCurrentTime();
23634 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
23635 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
23636 } else {
23637 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
23638 }
23639 } catch (err) {
23640 if (true) {
23641 if (!hasLoggedError) {
23642 hasLoggedError = true;
23643
23644 error('React instrumentation encountered an error: %s', err);
23645 }
23646 }
23647 }
23648 };
23649
23650 onCommitFiberUnmount = function (fiber) {
23651 try {
23652 hook.onCommitFiberUnmount(rendererID, fiber);
23653 } catch (err) {
23654 if (true) {
23655 if (!hasLoggedError) {
23656 hasLoggedError = true;
23657
23658 error('React instrumentation encountered an error: %s', err);
23659 }
23660 }
23661 }
23662 };
23663 } catch (err) {
23664 // Catch all errors because it is unsafe to throw during initialization.
23665 {
23666 error('React instrumentation encountered an error: %s.', err);
23667 }
23668 } // DevTools exists
23669
23670
23671 return true;
23672 }
23673 function onScheduleRoot(root, children) {
23674 if (typeof onScheduleFiberRoot === 'function') {
23675 onScheduleFiberRoot(root, children);
23676 }
23677 }
23678 function onCommitRoot(root, expirationTime) {
23679 if (typeof onCommitFiberRoot === 'function') {
23680 onCommitFiberRoot(root, expirationTime);
23681 }
23682 }
23683 function onCommitUnmount(fiber) {
23684 if (typeof onCommitFiberUnmount === 'function') {
23685 onCommitFiberUnmount(fiber);
23686 }
23687 }
23688
23689 var hasBadMapPolyfill;
23690
23691 {
23692 hasBadMapPolyfill = false;
23693
23694 try {
23695 var nonExtensibleObject = Object.preventExtensions({});
23696 var testMap = new Map([[nonExtensibleObject, null]]);
23697 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
23698 // https://github.com/rollup/rollup/issues/1771
23699 // TODO: we can remove these if Rollup fixes the bug.
23700
23701 testMap.set(0, 0);
23702 testSet.add(0);
23703 } catch (e) {
23704 // TODO: Consider warning about bad polyfills
23705 hasBadMapPolyfill = true;
23706 }
23707 }
23708
23709 var debugCounter = 1;
23710
23711 function FiberNode(tag, pendingProps, key, mode) {
23712 // Instance
23713 this.tag = tag;
23714 this.key = key;
23715 this.elementType = null;
23716 this.type = null;
23717 this.stateNode = null; // Fiber
23718
23719 this.return = null;
23720 this.child = null;
23721 this.sibling = null;
23722 this.index = 0;
23723 this.ref = null;
23724 this.pendingProps = pendingProps;
23725 this.memoizedProps = null;
23726 this.updateQueue = null;
23727 this.memoizedState = null;
23728 this.dependencies = null;
23729 this.mode = mode; // Effects
23730
23731 this.effectTag = NoEffect;
23732 this.nextEffect = null;
23733 this.firstEffect = null;
23734 this.lastEffect = null;
23735 this.expirationTime = NoWork;
23736 this.childExpirationTime = NoWork;
23737 this.alternate = null;
23738
23739 {
23740 // Note: The following is done to avoid a v8 performance cliff.
23741 //
23742 // Initializing the fields below to smis and later updating them with
23743 // double values will cause Fibers to end up having separate shapes.
23744 // This behavior/bug has something to do with Object.preventExtension().
23745 // Fortunately this only impacts DEV builds.
23746 // Unfortunately it makes React unusably slow for some applications.
23747 // To work around this, initialize the fields below with doubles.
23748 //
23749 // Learn more about this here:
23750 // https://github.com/facebook/react/issues/14365
23751 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
23752 this.actualDuration = Number.NaN;
23753 this.actualStartTime = Number.NaN;
23754 this.selfBaseDuration = Number.NaN;
23755 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
23756 // This won't trigger the performance cliff mentioned above,
23757 // and it simplifies other profiler code (including DevTools).
23758
23759 this.actualDuration = 0;
23760 this.actualStartTime = -1;
23761 this.selfBaseDuration = 0;
23762 this.treeBaseDuration = 0;
23763 } // This is normally DEV-only except www when it adds listeners.
23764 // TODO: remove the User Timing integration in favor of Root Events.
23765
23766
23767 {
23768 this._debugID = debugCounter++;
23769 this._debugIsCurrentlyTiming = false;
23770 }
23771
23772 {
23773 this._debugSource = null;
23774 this._debugOwner = null;
23775 this._debugNeedsRemount = false;
23776 this._debugHookTypes = null;
23777
23778 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
23779 Object.preventExtensions(this);
23780 }
23781 }
23782 } // This is a constructor function, rather than a POJO constructor, still
23783 // please ensure we do the following:
23784 // 1) Nobody should add any instance methods on this. Instance methods can be
23785 // more difficult to predict when they get optimized and they are almost
23786 // never inlined properly in static compilers.
23787 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
23788 // always know when it is a fiber.
23789 // 3) We might want to experiment with using numeric keys since they are easier
23790 // to optimize in a non-JIT environment.
23791 // 4) We can easily go from a constructor to a createFiber object literal if that
23792 // is faster.
23793 // 5) It should be easy to port this to a C struct and keep a C implementation
23794 // compatible.
23795
23796
23797 var createFiber = function (tag, pendingProps, key, mode) {
23798 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
23799 return new FiberNode(tag, pendingProps, key, mode);
23800 };
23801
23802 function shouldConstruct(Component) {
23803 var prototype = Component.prototype;
23804 return !!(prototype && prototype.isReactComponent);
23805 }
23806
23807 function isSimpleFunctionComponent(type) {
23808 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
23809 }
23810 function resolveLazyComponentTag(Component) {
23811 if (typeof Component === 'function') {
23812 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
23813 } else if (Component !== undefined && Component !== null) {
23814 var $$typeof = Component.$$typeof;
23815
23816 if ($$typeof === REACT_FORWARD_REF_TYPE) {
23817 return ForwardRef;
23818 }
23819
23820 if ($$typeof === REACT_MEMO_TYPE) {
23821 return MemoComponent;
23822 }
23823 }
23824
23825 return IndeterminateComponent;
23826 } // This is used to create an alternate fiber to do work on.
23827
23828 function createWorkInProgress(current, pendingProps) {
23829 var workInProgress = current.alternate;
23830
23831 if (workInProgress === null) {
23832 // We use a double buffering pooling technique because we know that we'll
23833 // only ever need at most two versions of a tree. We pool the "other" unused
23834 // node that we're free to reuse. This is lazily created to avoid allocating
23835 // extra objects for things that are never updated. It also allow us to
23836 // reclaim the extra memory if needed.
23837 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
23838 workInProgress.elementType = current.elementType;
23839 workInProgress.type = current.type;
23840 workInProgress.stateNode = current.stateNode;
23841
23842 {
23843 // DEV-only fields
23844 {
23845 workInProgress._debugID = current._debugID;
23846 }
23847
23848 workInProgress._debugSource = current._debugSource;
23849 workInProgress._debugOwner = current._debugOwner;
23850 workInProgress._debugHookTypes = current._debugHookTypes;
23851 }
23852
23853 workInProgress.alternate = current;
23854 current.alternate = workInProgress;
23855 } else {
23856 workInProgress.pendingProps = pendingProps; // We already have an alternate.
23857 // Reset the effect tag.
23858
23859 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
23860
23861 workInProgress.nextEffect = null;
23862 workInProgress.firstEffect = null;
23863 workInProgress.lastEffect = null;
23864
23865 {
23866 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
23867 // This prevents time from endlessly accumulating in new commits.
23868 // This has the downside of resetting values for different priority renders,
23869 // But works for yielding (the common case) and should support resuming.
23870 workInProgress.actualDuration = 0;
23871 workInProgress.actualStartTime = -1;
23872 }
23873 }
23874
23875 workInProgress.childExpirationTime = current.childExpirationTime;
23876 workInProgress.expirationTime = current.expirationTime;
23877 workInProgress.child = current.child;
23878 workInProgress.memoizedProps = current.memoizedProps;
23879 workInProgress.memoizedState = current.memoizedState;
23880 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
23881 // it cannot be shared with the current fiber.
23882
23883 var currentDependencies = current.dependencies;
23884 workInProgress.dependencies = currentDependencies === null ? null : {
23885 expirationTime: currentDependencies.expirationTime,
23886 firstContext: currentDependencies.firstContext,
23887 responders: currentDependencies.responders
23888 }; // These will be overridden during the parent's reconciliation
23889
23890 workInProgress.sibling = current.sibling;
23891 workInProgress.index = current.index;
23892 workInProgress.ref = current.ref;
23893
23894 {
23895 workInProgress.selfBaseDuration = current.selfBaseDuration;
23896 workInProgress.treeBaseDuration = current.treeBaseDuration;
23897 }
23898
23899 {
23900 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
23901
23902 switch (workInProgress.tag) {
23903 case IndeterminateComponent:
23904 case FunctionComponent:
23905 case SimpleMemoComponent:
23906 workInProgress.type = resolveFunctionForHotReloading(current.type);
23907 break;
23908
23909 case ClassComponent:
23910 workInProgress.type = resolveClassForHotReloading(current.type);
23911 break;
23912
23913 case ForwardRef:
23914 workInProgress.type = resolveForwardRefForHotReloading(current.type);
23915 break;
23916 }
23917 }
23918
23919 return workInProgress;
23920 } // Used to reuse a Fiber for a second pass.
23921
23922 function resetWorkInProgress(workInProgress, renderExpirationTime) {
23923 // This resets the Fiber to what createFiber or createWorkInProgress would
23924 // have set the values to before during the first pass. Ideally this wouldn't
23925 // be necessary but unfortunately many code paths reads from the workInProgress
23926 // when they should be reading from current and writing to workInProgress.
23927 // We assume pendingProps, index, key, ref, return are still untouched to
23928 // avoid doing another reconciliation.
23929 // Reset the effect tag but keep any Placement tags, since that's something
23930 // that child fiber is setting, not the reconciliation.
23931 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
23932
23933 workInProgress.nextEffect = null;
23934 workInProgress.firstEffect = null;
23935 workInProgress.lastEffect = null;
23936 var current = workInProgress.alternate;
23937
23938 if (current === null) {
23939 // Reset to createFiber's initial values.
23940 workInProgress.childExpirationTime = NoWork;
23941 workInProgress.expirationTime = renderExpirationTime;
23942 workInProgress.child = null;
23943 workInProgress.memoizedProps = null;
23944 workInProgress.memoizedState = null;
23945 workInProgress.updateQueue = null;
23946 workInProgress.dependencies = null;
23947
23948 {
23949 // Note: We don't reset the actualTime counts. It's useful to accumulate
23950 // actual time across multiple render passes.
23951 workInProgress.selfBaseDuration = 0;
23952 workInProgress.treeBaseDuration = 0;
23953 }
23954 } else {
23955 // Reset to the cloned values that createWorkInProgress would've.
23956 workInProgress.childExpirationTime = current.childExpirationTime;
23957 workInProgress.expirationTime = current.expirationTime;
23958 workInProgress.child = current.child;
23959 workInProgress.memoizedProps = current.memoizedProps;
23960 workInProgress.memoizedState = current.memoizedState;
23961 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
23962 // it cannot be shared with the current fiber.
23963
23964 var currentDependencies = current.dependencies;
23965 workInProgress.dependencies = currentDependencies === null ? null : {
23966 expirationTime: currentDependencies.expirationTime,
23967 firstContext: currentDependencies.firstContext,
23968 responders: currentDependencies.responders
23969 };
23970
23971 {
23972 // Note: We don't reset the actualTime counts. It's useful to accumulate
23973 // actual time across multiple render passes.
23974 workInProgress.selfBaseDuration = current.selfBaseDuration;
23975 workInProgress.treeBaseDuration = current.treeBaseDuration;
23976 }
23977 }
23978
23979 return workInProgress;
23980 }
23981 function createHostRootFiber(tag) {
23982 var mode;
23983
23984 if (tag === ConcurrentRoot) {
23985 mode = ConcurrentMode | BlockingMode | StrictMode;
23986 } else if (tag === BlockingRoot) {
23987 mode = BlockingMode | StrictMode;
23988 } else {
23989 mode = NoMode;
23990 }
23991
23992 if ( isDevToolsPresent) {
23993 // Always collect profile timings when DevTools are present.
23994 // This enables DevTools to start capturing timing at any point–
23995 // Without some nodes in the tree having empty base times.
23996 mode |= ProfileMode;
23997 }
23998
23999 return createFiber(HostRoot, null, null, mode);
24000 }
24001 function createFiberFromTypeAndProps(type, // React$ElementType
24002 key, pendingProps, owner, mode, expirationTime) {
24003 var fiber;
24004 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
24005
24006 var resolvedType = type;
24007
24008 if (typeof type === 'function') {
24009 if (shouldConstruct(type)) {
24010 fiberTag = ClassComponent;
24011
24012 {
24013 resolvedType = resolveClassForHotReloading(resolvedType);
24014 }
24015 } else {
24016 {
24017 resolvedType = resolveFunctionForHotReloading(resolvedType);
24018 }
24019 }
24020 } else if (typeof type === 'string') {
24021 fiberTag = HostComponent;
24022 } else {
24023 getTag: switch (type) {
24024 case REACT_FRAGMENT_TYPE:
24025 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
24026
24027 case REACT_CONCURRENT_MODE_TYPE:
24028 fiberTag = Mode;
24029 mode |= ConcurrentMode | BlockingMode | StrictMode;
24030 break;
24031
24032 case REACT_STRICT_MODE_TYPE:
24033 fiberTag = Mode;
24034 mode |= StrictMode;
24035 break;
24036
24037 case REACT_PROFILER_TYPE:
24038 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
24039
24040 case REACT_SUSPENSE_TYPE:
24041 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
24042
24043 case REACT_SUSPENSE_LIST_TYPE:
24044 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
24045
24046 default:
24047 {
24048 if (typeof type === 'object' && type !== null) {
24049 switch (type.$$typeof) {
24050 case REACT_PROVIDER_TYPE:
24051 fiberTag = ContextProvider;
24052 break getTag;
24053
24054 case REACT_CONTEXT_TYPE:
24055 // This is a consumer
24056 fiberTag = ContextConsumer;
24057 break getTag;
24058
24059 case REACT_FORWARD_REF_TYPE:
24060 fiberTag = ForwardRef;
24061
24062 {
24063 resolvedType = resolveForwardRefForHotReloading(resolvedType);
24064 }
24065
24066 break getTag;
24067
24068 case REACT_MEMO_TYPE:
24069 fiberTag = MemoComponent;
24070 break getTag;
24071
24072 case REACT_LAZY_TYPE:
24073 fiberTag = LazyComponent;
24074 resolvedType = null;
24075 break getTag;
24076
24077 case REACT_BLOCK_TYPE:
24078 fiberTag = Block;
24079 break getTag;
24080
24081 }
24082 }
24083
24084 var info = '';
24085
24086 {
24087 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
24088 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.';
24089 }
24090
24091 var ownerName = owner ? getComponentName(owner.type) : null;
24092
24093 if (ownerName) {
24094 info += '\n\nCheck the render method of `' + ownerName + '`.';
24095 }
24096 }
24097
24098 {
24099 {
24100 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 );
24101 }
24102 }
24103 }
24104 }
24105 }
24106
24107 fiber = createFiber(fiberTag, pendingProps, key, mode);
24108 fiber.elementType = type;
24109 fiber.type = resolvedType;
24110 fiber.expirationTime = expirationTime;
24111 return fiber;
24112 }
24113 function createFiberFromElement(element, mode, expirationTime) {
24114 var owner = null;
24115
24116 {
24117 owner = element._owner;
24118 }
24119
24120 var type = element.type;
24121 var key = element.key;
24122 var pendingProps = element.props;
24123 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
24124
24125 {
24126 fiber._debugSource = element._source;
24127 fiber._debugOwner = element._owner;
24128 }
24129
24130 return fiber;
24131 }
24132 function createFiberFromFragment(elements, mode, expirationTime, key) {
24133 var fiber = createFiber(Fragment, elements, key, mode);
24134 fiber.expirationTime = expirationTime;
24135 return fiber;
24136 }
24137
24138 function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
24139 {
24140 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
24141 error('Profiler must specify an "id" string and "onRender" function as props');
24142 }
24143 }
24144
24145 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
24146
24147 fiber.elementType = REACT_PROFILER_TYPE;
24148 fiber.type = REACT_PROFILER_TYPE;
24149 fiber.expirationTime = expirationTime;
24150 return fiber;
24151 }
24152
24153 function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
24154 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
24155 // This needs to be fixed in getComponentName so that it relies on the tag
24156 // instead.
24157
24158 fiber.type = REACT_SUSPENSE_TYPE;
24159 fiber.elementType = REACT_SUSPENSE_TYPE;
24160 fiber.expirationTime = expirationTime;
24161 return fiber;
24162 }
24163 function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
24164 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
24165
24166 {
24167 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
24168 // This needs to be fixed in getComponentName so that it relies on the tag
24169 // instead.
24170 fiber.type = REACT_SUSPENSE_LIST_TYPE;
24171 }
24172
24173 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
24174 fiber.expirationTime = expirationTime;
24175 return fiber;
24176 }
24177 function createFiberFromText(content, mode, expirationTime) {
24178 var fiber = createFiber(HostText, content, null, mode);
24179 fiber.expirationTime = expirationTime;
24180 return fiber;
24181 }
24182 function createFiberFromHostInstanceForDeletion() {
24183 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.
24184
24185 fiber.elementType = 'DELETED';
24186 fiber.type = 'DELETED';
24187 return fiber;
24188 }
24189 function createFiberFromPortal(portal, mode, expirationTime) {
24190 var pendingProps = portal.children !== null ? portal.children : [];
24191 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
24192 fiber.expirationTime = expirationTime;
24193 fiber.stateNode = {
24194 containerInfo: portal.containerInfo,
24195 pendingChildren: null,
24196 // Used by persistent updates
24197 implementation: portal.implementation
24198 };
24199 return fiber;
24200 } // Used for stashing WIP properties to replay failed work in DEV.
24201
24202 function assignFiberPropertiesInDEV(target, source) {
24203 if (target === null) {
24204 // This Fiber's initial properties will always be overwritten.
24205 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
24206 target = createFiber(IndeterminateComponent, null, null, NoMode);
24207 } // This is intentionally written as a list of all properties.
24208 // We tried to use Object.assign() instead but this is called in
24209 // the hottest path, and Object.assign() was too slow:
24210 // https://github.com/facebook/react/issues/12502
24211 // This code is DEV-only so size is not a concern.
24212
24213
24214 target.tag = source.tag;
24215 target.key = source.key;
24216 target.elementType = source.elementType;
24217 target.type = source.type;
24218 target.stateNode = source.stateNode;
24219 target.return = source.return;
24220 target.child = source.child;
24221 target.sibling = source.sibling;
24222 target.index = source.index;
24223 target.ref = source.ref;
24224 target.pendingProps = source.pendingProps;
24225 target.memoizedProps = source.memoizedProps;
24226 target.updateQueue = source.updateQueue;
24227 target.memoizedState = source.memoizedState;
24228 target.dependencies = source.dependencies;
24229 target.mode = source.mode;
24230 target.effectTag = source.effectTag;
24231 target.nextEffect = source.nextEffect;
24232 target.firstEffect = source.firstEffect;
24233 target.lastEffect = source.lastEffect;
24234 target.expirationTime = source.expirationTime;
24235 target.childExpirationTime = source.childExpirationTime;
24236 target.alternate = source.alternate;
24237
24238 {
24239 target.actualDuration = source.actualDuration;
24240 target.actualStartTime = source.actualStartTime;
24241 target.selfBaseDuration = source.selfBaseDuration;
24242 target.treeBaseDuration = source.treeBaseDuration;
24243 }
24244
24245 {
24246 target._debugID = source._debugID;
24247 }
24248
24249 target._debugSource = source._debugSource;
24250 target._debugOwner = source._debugOwner;
24251 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
24252 target._debugNeedsRemount = source._debugNeedsRemount;
24253 target._debugHookTypes = source._debugHookTypes;
24254 return target;
24255 }
24256
24257 function FiberRootNode(containerInfo, tag, hydrate) {
24258 this.tag = tag;
24259 this.current = null;
24260 this.containerInfo = containerInfo;
24261 this.pendingChildren = null;
24262 this.pingCache = null;
24263 this.finishedExpirationTime = NoWork;
24264 this.finishedWork = null;
24265 this.timeoutHandle = noTimeout;
24266 this.context = null;
24267 this.pendingContext = null;
24268 this.hydrate = hydrate;
24269 this.callbackNode = null;
24270 this.callbackPriority = NoPriority;
24271 this.firstPendingTime = NoWork;
24272 this.firstSuspendedTime = NoWork;
24273 this.lastSuspendedTime = NoWork;
24274 this.nextKnownPendingLevel = NoWork;
24275 this.lastPingedTime = NoWork;
24276 this.lastExpiredTime = NoWork;
24277
24278 {
24279 this.interactionThreadID = unstable_getThreadID();
24280 this.memoizedInteractions = new Set();
24281 this.pendingInteractionMap = new Map();
24282 }
24283 }
24284
24285 function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
24286 var root = new FiberRootNode(containerInfo, tag, hydrate);
24287 // stateNode is any.
24288
24289
24290 var uninitializedFiber = createHostRootFiber(tag);
24291 root.current = uninitializedFiber;
24292 uninitializedFiber.stateNode = root;
24293 initializeUpdateQueue(uninitializedFiber);
24294 return root;
24295 }
24296 function isRootSuspendedAtTime(root, expirationTime) {
24297 var firstSuspendedTime = root.firstSuspendedTime;
24298 var lastSuspendedTime = root.lastSuspendedTime;
24299 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
24300 }
24301 function markRootSuspendedAtTime(root, expirationTime) {
24302 var firstSuspendedTime = root.firstSuspendedTime;
24303 var lastSuspendedTime = root.lastSuspendedTime;
24304
24305 if (firstSuspendedTime < expirationTime) {
24306 root.firstSuspendedTime = expirationTime;
24307 }
24308
24309 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
24310 root.lastSuspendedTime = expirationTime;
24311 }
24312
24313 if (expirationTime <= root.lastPingedTime) {
24314 root.lastPingedTime = NoWork;
24315 }
24316
24317 if (expirationTime <= root.lastExpiredTime) {
24318 root.lastExpiredTime = NoWork;
24319 }
24320 }
24321 function markRootUpdatedAtTime(root, expirationTime) {
24322 // Update the range of pending times
24323 var firstPendingTime = root.firstPendingTime;
24324
24325 if (expirationTime > firstPendingTime) {
24326 root.firstPendingTime = expirationTime;
24327 } // Update the range of suspended times. Treat everything lower priority or
24328 // equal to this update as unsuspended.
24329
24330
24331 var firstSuspendedTime = root.firstSuspendedTime;
24332
24333 if (firstSuspendedTime !== NoWork) {
24334 if (expirationTime >= firstSuspendedTime) {
24335 // The entire suspended range is now unsuspended.
24336 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
24337 } else if (expirationTime >= root.lastSuspendedTime) {
24338 root.lastSuspendedTime = expirationTime + 1;
24339 } // This is a pending level. Check if it's higher priority than the next
24340 // known pending level.
24341
24342
24343 if (expirationTime > root.nextKnownPendingLevel) {
24344 root.nextKnownPendingLevel = expirationTime;
24345 }
24346 }
24347 }
24348 function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
24349 // Update the range of pending times
24350 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
24351 // equal to this update as unsuspended.
24352
24353 if (finishedExpirationTime <= root.lastSuspendedTime) {
24354 // The entire suspended range is now unsuspended.
24355 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
24356 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
24357 // Part of the suspended range is now unsuspended. Narrow the range to
24358 // include everything between the unsuspended time (non-inclusive) and the
24359 // last suspended time.
24360 root.firstSuspendedTime = finishedExpirationTime - 1;
24361 }
24362
24363 if (finishedExpirationTime <= root.lastPingedTime) {
24364 // Clear the pinged time
24365 root.lastPingedTime = NoWork;
24366 }
24367
24368 if (finishedExpirationTime <= root.lastExpiredTime) {
24369 // Clear the expired time
24370 root.lastExpiredTime = NoWork;
24371 }
24372 }
24373 function markRootExpiredAtTime(root, expirationTime) {
24374 var lastExpiredTime = root.lastExpiredTime;
24375
24376 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
24377 root.lastExpiredTime = expirationTime;
24378 }
24379 }
24380
24381 var didWarnAboutNestedUpdates;
24382 var didWarnAboutFindNodeInStrictMode;
24383
24384 {
24385 didWarnAboutNestedUpdates = false;
24386 didWarnAboutFindNodeInStrictMode = {};
24387 }
24388
24389 function getContextForSubtree(parentComponent) {
24390 if (!parentComponent) {
24391 return emptyContextObject;
24392 }
24393
24394 var fiber = get(parentComponent);
24395 var parentContext = findCurrentUnmaskedContext(fiber);
24396
24397 if (fiber.tag === ClassComponent) {
24398 var Component = fiber.type;
24399
24400 if (isContextProvider(Component)) {
24401 return processChildContext(fiber, Component, parentContext);
24402 }
24403 }
24404
24405 return parentContext;
24406 }
24407
24408 function findHostInstanceWithWarning(component, methodName) {
24409 {
24410 var fiber = get(component);
24411
24412 if (fiber === undefined) {
24413 if (typeof component.render === 'function') {
24414 {
24415 {
24416 throw Error( "Unable to find node on an unmounted component." );
24417 }
24418 }
24419 } else {
24420 {
24421 {
24422 throw Error( "Argument appears to not be a ReactComponent. Keys: " + Object.keys(component) );
24423 }
24424 }
24425 }
24426 }
24427
24428 var hostFiber = findCurrentHostFiber(fiber);
24429
24430 if (hostFiber === null) {
24431 return null;
24432 }
24433
24434 if (hostFiber.mode & StrictMode) {
24435 var componentName = getComponentName(fiber.type) || 'Component';
24436
24437 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
24438 didWarnAboutFindNodeInStrictMode[componentName] = true;
24439
24440 if (fiber.mode & StrictMode) {
24441 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));
24442 } else {
24443 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));
24444 }
24445 }
24446 }
24447
24448 return hostFiber.stateNode;
24449 }
24450 }
24451
24452 function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
24453 return createFiberRoot(containerInfo, tag, hydrate);
24454 }
24455 function updateContainer(element, container, parentComponent, callback) {
24456 {
24457 onScheduleRoot(container, element);
24458 }
24459
24460 var current$1 = container.current;
24461 var currentTime = requestCurrentTimeForUpdate();
24462
24463 {
24464 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
24465 if ('undefined' !== typeof jest) {
24466 warnIfUnmockedScheduler(current$1);
24467 warnIfNotScopedWithMatchingAct(current$1);
24468 }
24469 }
24470
24471 var suspenseConfig = requestCurrentSuspenseConfig();
24472 var expirationTime = computeExpirationForFiber(currentTime, current$1, suspenseConfig);
24473 var context = getContextForSubtree(parentComponent);
24474
24475 if (container.context === null) {
24476 container.context = context;
24477 } else {
24478 container.pendingContext = context;
24479 }
24480
24481 {
24482 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
24483 didWarnAboutNestedUpdates = true;
24484
24485 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');
24486 }
24487 }
24488
24489 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
24490 // being called "element".
24491
24492 update.payload = {
24493 element: element
24494 };
24495 callback = callback === undefined ? null : callback;
24496
24497 if (callback !== null) {
24498 {
24499 if (typeof callback !== 'function') {
24500 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
24501 }
24502 }
24503
24504 update.callback = callback;
24505 }
24506
24507 enqueueUpdate(current$1, update);
24508 scheduleWork(current$1, expirationTime);
24509 return expirationTime;
24510 }
24511 function getPublicRootInstance(container) {
24512 var containerFiber = container.current;
24513
24514 if (!containerFiber.child) {
24515 return null;
24516 }
24517
24518 switch (containerFiber.child.tag) {
24519 case HostComponent:
24520 return getPublicInstance(containerFiber.child.stateNode);
24521
24522 default:
24523 return containerFiber.child.stateNode;
24524 }
24525 }
24526
24527 function markRetryTimeImpl(fiber, retryTime) {
24528 var suspenseState = fiber.memoizedState;
24529
24530 if (suspenseState !== null && suspenseState.dehydrated !== null) {
24531 if (suspenseState.retryTime < retryTime) {
24532 suspenseState.retryTime = retryTime;
24533 }
24534 }
24535 } // Increases the priority of thennables when they resolve within this boundary.
24536
24537
24538 function markRetryTimeIfNotHydrated(fiber, retryTime) {
24539 markRetryTimeImpl(fiber, retryTime);
24540 var alternate = fiber.alternate;
24541
24542 if (alternate) {
24543 markRetryTimeImpl(alternate, retryTime);
24544 }
24545 }
24546
24547 function attemptUserBlockingHydration$1(fiber) {
24548 if (fiber.tag !== SuspenseComponent) {
24549 // We ignore HostRoots here because we can't increase
24550 // their priority and they should not suspend on I/O,
24551 // since you have to wrap anything that might suspend in
24552 // Suspense.
24553 return;
24554 }
24555
24556 var expTime = computeInteractiveExpiration(requestCurrentTimeForUpdate());
24557 scheduleWork(fiber, expTime);
24558 markRetryTimeIfNotHydrated(fiber, expTime);
24559 }
24560 function attemptContinuousHydration$1(fiber) {
24561 if (fiber.tag !== SuspenseComponent) {
24562 // We ignore HostRoots here because we can't increase
24563 // their priority and they should not suspend on I/O,
24564 // since you have to wrap anything that might suspend in
24565 // Suspense.
24566 return;
24567 }
24568
24569 scheduleWork(fiber, ContinuousHydration);
24570 markRetryTimeIfNotHydrated(fiber, ContinuousHydration);
24571 }
24572 function attemptHydrationAtCurrentPriority$1(fiber) {
24573 if (fiber.tag !== SuspenseComponent) {
24574 // We ignore HostRoots here because we can't increase
24575 // their priority other than synchronously flush it.
24576 return;
24577 }
24578
24579 var currentTime = requestCurrentTimeForUpdate();
24580 var expTime = computeExpirationForFiber(currentTime, fiber, null);
24581 scheduleWork(fiber, expTime);
24582 markRetryTimeIfNotHydrated(fiber, expTime);
24583 }
24584 function findHostInstanceWithNoPortals(fiber) {
24585 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
24586
24587 if (hostFiber === null) {
24588 return null;
24589 }
24590
24591 if (hostFiber.tag === FundamentalComponent) {
24592 return hostFiber.stateNode.instance;
24593 }
24594
24595 return hostFiber.stateNode;
24596 }
24597
24598 var shouldSuspendImpl = function (fiber) {
24599 return false;
24600 };
24601
24602 function shouldSuspend(fiber) {
24603 return shouldSuspendImpl(fiber);
24604 }
24605 var overrideHookState = null;
24606 var overrideProps = null;
24607 var scheduleUpdate = null;
24608 var setSuspenseHandler = null;
24609
24610 {
24611 var copyWithSetImpl = function (obj, path, idx, value) {
24612 if (idx >= path.length) {
24613 return value;
24614 }
24615
24616 var key = path[idx];
24617 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
24618
24619 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
24620 return updated;
24621 };
24622
24623 var copyWithSet = function (obj, path, value) {
24624 return copyWithSetImpl(obj, path, 0, value);
24625 }; // Support DevTools editable values for useState and useReducer.
24626
24627
24628 overrideHookState = function (fiber, id, path, value) {
24629 // For now, the "id" of stateful hooks is just the stateful hook index.
24630 // This may change in the future with e.g. nested hooks.
24631 var currentHook = fiber.memoizedState;
24632
24633 while (currentHook !== null && id > 0) {
24634 currentHook = currentHook.next;
24635 id--;
24636 }
24637
24638 if (currentHook !== null) {
24639 var newState = copyWithSet(currentHook.memoizedState, path, value);
24640 currentHook.memoizedState = newState;
24641 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
24642 // because there is no update we can add for useReducer hooks that won't trigger an error.
24643 // (There's no appropriate action type for DevTools overrides.)
24644 // As a result though, React will see the scheduled update as a noop and bailout.
24645 // Shallow cloning props works as a workaround for now to bypass the bailout check.
24646
24647 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
24648 scheduleWork(fiber, Sync);
24649 }
24650 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
24651
24652
24653 overrideProps = function (fiber, path, value) {
24654 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
24655
24656 if (fiber.alternate) {
24657 fiber.alternate.pendingProps = fiber.pendingProps;
24658 }
24659
24660 scheduleWork(fiber, Sync);
24661 };
24662
24663 scheduleUpdate = function (fiber) {
24664 scheduleWork(fiber, Sync);
24665 };
24666
24667 setSuspenseHandler = function (newShouldSuspendImpl) {
24668 shouldSuspendImpl = newShouldSuspendImpl;
24669 };
24670 }
24671
24672 function injectIntoDevTools(devToolsConfig) {
24673 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
24674 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
24675 return injectInternals(_assign({}, devToolsConfig, {
24676 overrideHookState: overrideHookState,
24677 overrideProps: overrideProps,
24678 setSuspenseHandler: setSuspenseHandler,
24679 scheduleUpdate: scheduleUpdate,
24680 currentDispatcherRef: ReactCurrentDispatcher,
24681 findHostInstanceByFiber: function (fiber) {
24682 var hostFiber = findCurrentHostFiber(fiber);
24683
24684 if (hostFiber === null) {
24685 return null;
24686 }
24687
24688 return hostFiber.stateNode;
24689 },
24690 findFiberByHostInstance: function (instance) {
24691 if (!findFiberByHostInstance) {
24692 // Might not be implemented by the renderer.
24693 return null;
24694 }
24695
24696 return findFiberByHostInstance(instance);
24697 },
24698 // React Refresh
24699 findHostInstancesForRefresh: findHostInstancesForRefresh ,
24700 scheduleRefresh: scheduleRefresh ,
24701 scheduleRoot: scheduleRoot ,
24702 setRefreshHandler: setRefreshHandler ,
24703 // Enables DevTools to append owner stacks to error messages in DEV mode.
24704 getCurrentFiber: function () {
24705 return current;
24706 }
24707 }));
24708 }
24709 var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
24710
24711 function ReactDOMRoot(container, options) {
24712 this._internalRoot = createRootImpl(container, ConcurrentRoot, options);
24713 }
24714
24715 function ReactDOMBlockingRoot(container, tag, options) {
24716 this._internalRoot = createRootImpl(container, tag, options);
24717 }
24718
24719 ReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children) {
24720 var root = this._internalRoot;
24721
24722 {
24723 if (typeof arguments[1] === 'function') {
24724 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
24725 }
24726
24727 var container = root.containerInfo;
24728
24729 if (container.nodeType !== COMMENT_NODE) {
24730 var hostInstance = findHostInstanceWithNoPortals(root.current);
24731
24732 if (hostInstance) {
24733 if (hostInstance.parentNode !== container) {
24734 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.");
24735 }
24736 }
24737 }
24738 }
24739
24740 updateContainer(children, root, null, null);
24741 };
24742
24743 ReactDOMRoot.prototype.unmount = ReactDOMBlockingRoot.prototype.unmount = function () {
24744 {
24745 if (typeof arguments[0] === 'function') {
24746 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
24747 }
24748 }
24749
24750 var root = this._internalRoot;
24751 var container = root.containerInfo;
24752 updateContainer(null, root, null, function () {
24753 unmarkContainerAsRoot(container);
24754 });
24755 };
24756
24757 function createRootImpl(container, tag, options) {
24758 // Tag is either LegacyRoot or Concurrent Root
24759 var hydrate = options != null && options.hydrate === true;
24760 var hydrationCallbacks = options != null && options.hydrationOptions || null;
24761 var root = createContainer(container, tag, hydrate);
24762 markContainerAsRoot(root.current, container);
24763
24764 if (hydrate && tag !== LegacyRoot) {
24765 var doc = container.nodeType === DOCUMENT_NODE ? container : container.ownerDocument;
24766 eagerlyTrapReplayableEvents(container, doc);
24767 }
24768
24769 return root;
24770 }
24771 function createLegacyRoot(container, options) {
24772 return new ReactDOMBlockingRoot(container, LegacyRoot, options);
24773 }
24774 function isValidContainer(node) {
24775 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 '));
24776 }
24777
24778 var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
24779 var topLevelUpdateWarnings;
24780 var warnedAboutHydrateAPI = false;
24781
24782 {
24783 topLevelUpdateWarnings = function (container) {
24784 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
24785 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
24786
24787 if (hostInstance) {
24788 if (hostInstance.parentNode !== container) {
24789 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.');
24790 }
24791 }
24792 }
24793
24794 var isRootRenderedBySomeReact = !!container._reactRootContainer;
24795 var rootEl = getReactRootElementInContainer(container);
24796 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
24797
24798 if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
24799 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.');
24800 }
24801
24802 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
24803 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.');
24804 }
24805 };
24806 }
24807
24808 function getReactRootElementInContainer(container) {
24809 if (!container) {
24810 return null;
24811 }
24812
24813 if (container.nodeType === DOCUMENT_NODE) {
24814 return container.documentElement;
24815 } else {
24816 return container.firstChild;
24817 }
24818 }
24819
24820 function shouldHydrateDueToLegacyHeuristic(container) {
24821 var rootElement = getReactRootElementInContainer(container);
24822 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
24823 }
24824
24825 function legacyCreateRootFromDOMContainer(container, forceHydrate) {
24826 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content.
24827
24828 if (!shouldHydrate) {
24829 var warned = false;
24830 var rootSibling;
24831
24832 while (rootSibling = container.lastChild) {
24833 {
24834 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
24835 warned = true;
24836
24837 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.');
24838 }
24839 }
24840
24841 container.removeChild(rootSibling);
24842 }
24843 }
24844
24845 {
24846 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
24847 warnedAboutHydrateAPI = true;
24848
24849 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.');
24850 }
24851 }
24852
24853 return createLegacyRoot(container, shouldHydrate ? {
24854 hydrate: true
24855 } : undefined);
24856 }
24857
24858 function warnOnInvalidCallback$1(callback, callerName) {
24859 {
24860 if (callback !== null && typeof callback !== 'function') {
24861 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
24862 }
24863 }
24864 }
24865
24866 function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
24867 {
24868 topLevelUpdateWarnings(container);
24869 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');
24870 } // TODO: Without `any` type, Flow says "Property cannot be accessed on any
24871 // member of intersection type." Whyyyyyy.
24872
24873
24874 var root = container._reactRootContainer;
24875 var fiberRoot;
24876
24877 if (!root) {
24878 // Initial mount
24879 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
24880 fiberRoot = root._internalRoot;
24881
24882 if (typeof callback === 'function') {
24883 var originalCallback = callback;
24884
24885 callback = function () {
24886 var instance = getPublicRootInstance(fiberRoot);
24887 originalCallback.call(instance);
24888 };
24889 } // Initial mount should not be batched.
24890
24891
24892 unbatchedUpdates(function () {
24893 updateContainer(children, fiberRoot, parentComponent, callback);
24894 });
24895 } else {
24896 fiberRoot = root._internalRoot;
24897
24898 if (typeof callback === 'function') {
24899 var _originalCallback = callback;
24900
24901 callback = function () {
24902 var instance = getPublicRootInstance(fiberRoot);
24903
24904 _originalCallback.call(instance);
24905 };
24906 } // Update
24907
24908
24909 updateContainer(children, fiberRoot, parentComponent, callback);
24910 }
24911
24912 return getPublicRootInstance(fiberRoot);
24913 }
24914
24915 function findDOMNode(componentOrElement) {
24916 {
24917 var owner = ReactCurrentOwner$3.current;
24918
24919 if (owner !== null && owner.stateNode !== null) {
24920 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
24921
24922 if (!warnedAboutRefsInRender) {
24923 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');
24924 }
24925
24926 owner.stateNode._warnedAboutRefsInRender = true;
24927 }
24928 }
24929
24930 if (componentOrElement == null) {
24931 return null;
24932 }
24933
24934 if (componentOrElement.nodeType === ELEMENT_NODE) {
24935 return componentOrElement;
24936 }
24937
24938 {
24939 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
24940 }
24941 }
24942 function hydrate(element, container, callback) {
24943 if (!isValidContainer(container)) {
24944 {
24945 throw Error( "Target container is not a DOM element." );
24946 }
24947 }
24948
24949 {
24950 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
24951
24952 if (isModernRoot) {
24953 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)?');
24954 }
24955 } // TODO: throw or warn if we couldn't hydrate?
24956
24957
24958 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
24959 }
24960 function render(element, container, callback) {
24961 if (!isValidContainer(container)) {
24962 {
24963 throw Error( "Target container is not a DOM element." );
24964 }
24965 }
24966
24967 {
24968 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
24969
24970 if (isModernRoot) {
24971 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)?');
24972 }
24973 }
24974
24975 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
24976 }
24977 function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
24978 if (!isValidContainer(containerNode)) {
24979 {
24980 throw Error( "Target container is not a DOM element." );
24981 }
24982 }
24983
24984 if (!(parentComponent != null && has$1(parentComponent))) {
24985 {
24986 throw Error( "parentComponent must be a valid React Component" );
24987 }
24988 }
24989
24990 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
24991 }
24992 function unmountComponentAtNode(container) {
24993 if (!isValidContainer(container)) {
24994 {
24995 throw Error( "unmountComponentAtNode(...): Target container is not a DOM element." );
24996 }
24997 }
24998
24999 {
25000 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
25001
25002 if (isModernRoot) {
25003 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()?');
25004 }
25005 }
25006
25007 if (container._reactRootContainer) {
25008 {
25009 var rootEl = getReactRootElementInContainer(container);
25010 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
25011
25012 if (renderedByDifferentReact) {
25013 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
25014 }
25015 } // Unmount should not be batched.
25016
25017
25018 unbatchedUpdates(function () {
25019 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
25020 // $FlowFixMe This should probably use `delete container._reactRootContainer`
25021 container._reactRootContainer = null;
25022 unmarkContainerAsRoot(container);
25023 });
25024 }); // If you call unmountComponentAtNode twice in quick succession, you'll
25025 // get `true` twice. That's probably fine?
25026
25027 return true;
25028 } else {
25029 {
25030 var _rootEl = getReactRootElementInContainer(container);
25031
25032 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl)); // Check if the container itself is a React root node.
25033
25034 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
25035
25036 if (hasNonRootReactChild) {
25037 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.');
25038 }
25039 }
25040
25041 return false;
25042 }
25043 }
25044
25045 function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
25046 implementation) {
25047 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
25048 return {
25049 // This tag allow us to uniquely identify this as a React Portal
25050 $$typeof: REACT_PORTAL_TYPE,
25051 key: key == null ? null : '' + key,
25052 children: children,
25053 containerInfo: containerInfo,
25054 implementation: implementation
25055 };
25056 }
25057
25058 var ReactVersion = '16.13.1';
25059
25060 setAttemptUserBlockingHydration(attemptUserBlockingHydration$1);
25061 setAttemptContinuousHydration(attemptContinuousHydration$1);
25062 setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
25063 var didWarnAboutUnstableCreatePortal = false;
25064
25065 {
25066 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
25067 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
25068 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
25069 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');
25070 }
25071 }
25072
25073 setRestoreImplementation(restoreControlledState$3);
25074 setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);
25075
25076 function createPortal$1(children, container) {
25077 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
25078
25079 if (!isValidContainer(container)) {
25080 {
25081 throw Error( "Target container is not a DOM element." );
25082 }
25083 } // TODO: pass ReactDOM portal implementation as third argument
25084 // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
25085
25086
25087 return createPortal(children, container, null, key);
25088 }
25089
25090 function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
25091
25092 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
25093 }
25094
25095 function unstable_createPortal(children, container) {
25096 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
25097
25098 {
25099 if (!didWarnAboutUnstableCreatePortal) {
25100 didWarnAboutUnstableCreatePortal = true;
25101
25102 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.');
25103 }
25104 }
25105
25106 return createPortal$1(children, container, key);
25107 }
25108
25109 var Internals = {
25110 // Keep in sync with ReactDOMUnstableNativeDependencies.js
25111 // ReactTestUtils.js, and ReactTestUtilsAct.js. This is an array for better minification.
25112 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch, flushPassiveEffects, IsThisRendererActing]
25113 };
25114 var foundDevTools = injectIntoDevTools({
25115 findFiberByHostInstance: getClosestInstanceFromNode,
25116 bundleType: 1 ,
25117 version: ReactVersion,
25118 rendererPackageName: 'react-dom'
25119 });
25120
25121 {
25122 if (!foundDevTools && canUseDOM && window.top === window.self) {
25123 // If we're in Chrome or Firefox, provide a download link if not installed.
25124 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
25125 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
25126
25127 if (/^(https?|file):$/.test(protocol)) {
25128 // eslint-disable-next-line react-internal/no-production-logging
25129 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');
25130 }
25131 }
25132 }
25133 }
25134
25135 exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
25136 exports.createPortal = createPortal$1;
25137 exports.findDOMNode = findDOMNode;
25138 exports.flushSync = flushSync;
25139 exports.hydrate = hydrate;
25140 exports.render = render;
25141 exports.unmountComponentAtNode = unmountComponentAtNode;
25142 exports.unstable_batchedUpdates = batchedUpdates$1;
25143 exports.unstable_createPortal = unstable_createPortal;
25144 exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
25145 exports.version = ReactVersion;
25146
25147})));