UNPKG

931 kBJavaScriptView Raw
1/** @license React v16.9.0
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' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.ReactDOM = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18// Do not require this module directly! Use normal `invariant` calls with
19// template literal strings. The messages will be converted to ReactError during
20// build, and in production they will be minified.
21
22// Do not require this module directly! Use normal `invariant` calls with
23// template literal strings. The messages will be converted to ReactError during
24// build, and in production they will be minified.
25
26function ReactError(error) {
27 error.name = 'Invariant Violation';
28 return error;
29}
30
31/**
32 * Use invariant() to assert state which your program assumes to be true.
33 *
34 * Provide sprintf-style format (only %s is supported) and arguments
35 * to provide information about what broke and what you were
36 * expecting.
37 *
38 * The invariant message will be stripped in production, but the invariant
39 * will remain to ensure logic does not differ in production.
40 */
41
42(function () {
43 if (!React) {
44 {
45 throw ReactError(Error('ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.'));
46 }
47 }
48})();
49
50/**
51 * Injectable ordering of event plugins.
52 */
53var eventPluginOrder = null;
54
55/**
56 * Injectable mapping from names to event plugin modules.
57 */
58var namesToPlugins = {};
59
60/**
61 * Recomputes the plugin list using the injected plugins and plugin ordering.
62 *
63 * @private
64 */
65function recomputePluginOrdering() {
66 if (!eventPluginOrder) {
67 // Wait until an `eventPluginOrder` is injected.
68 return;
69 }
70 for (var pluginName in namesToPlugins) {
71 var pluginModule = namesToPlugins[pluginName];
72 var pluginIndex = eventPluginOrder.indexOf(pluginName);
73 (function () {
74 if (!(pluginIndex > -1)) {
75 {
76 throw ReactError(Error('EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `' + pluginName + '`.'));
77 }
78 }
79 })();
80 if (plugins[pluginIndex]) {
81 continue;
82 }
83 (function () {
84 if (!pluginModule.extractEvents) {
85 {
86 throw ReactError(Error('EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `' + pluginName + '` does not.'));
87 }
88 }
89 })();
90 plugins[pluginIndex] = pluginModule;
91 var publishedEvents = pluginModule.eventTypes;
92 for (var eventName in publishedEvents) {
93 (function () {
94 if (!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName)) {
95 {
96 throw ReactError(Error('EventPluginRegistry: Failed to publish event `' + eventName + '` for plugin `' + pluginName + '`.'));
97 }
98 }
99 })();
100 }
101 }
102}
103
104/**
105 * Publishes an event so that it can be dispatched by the supplied plugin.
106 *
107 * @param {object} dispatchConfig Dispatch configuration for the event.
108 * @param {object} PluginModule Plugin publishing the event.
109 * @return {boolean} True if the event was successfully published.
110 * @private
111 */
112function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
113 (function () {
114 if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) {
115 {
116 throw ReactError(Error('EventPluginHub: More than one plugin attempted to publish the same event name, `' + eventName + '`.'));
117 }
118 }
119 })();
120 eventNameDispatchConfigs[eventName] = dispatchConfig;
121
122 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
123 if (phasedRegistrationNames) {
124 for (var phaseName in phasedRegistrationNames) {
125 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
126 var phasedRegistrationName = phasedRegistrationNames[phaseName];
127 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
128 }
129 }
130 return true;
131 } else if (dispatchConfig.registrationName) {
132 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
133 return true;
134 }
135 return false;
136}
137
138/**
139 * Publishes a registration name that is used to identify dispatched events.
140 *
141 * @param {string} registrationName Registration name to add.
142 * @param {object} PluginModule Plugin publishing the event.
143 * @private
144 */
145function publishRegistrationName(registrationName, pluginModule, eventName) {
146 (function () {
147 if (!!registrationNameModules[registrationName]) {
148 {
149 throw ReactError(Error('EventPluginHub: More than one plugin attempted to publish the same registration name, `' + registrationName + '`.'));
150 }
151 }
152 })();
153 registrationNameModules[registrationName] = pluginModule;
154 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
155
156 {
157 var lowerCasedName = registrationName.toLowerCase();
158 possibleRegistrationNames[lowerCasedName] = registrationName;
159
160 if (registrationName === 'onDoubleClick') {
161 possibleRegistrationNames.ondblclick = registrationName;
162 }
163 }
164}
165
166/**
167 * Registers plugins so that they can extract and dispatch events.
168 *
169 * @see {EventPluginHub}
170 */
171
172/**
173 * Ordered list of injected plugins.
174 */
175var plugins = [];
176
177/**
178 * Mapping from event name to dispatch config
179 */
180var eventNameDispatchConfigs = {};
181
182/**
183 * Mapping from registration name to plugin module
184 */
185var registrationNameModules = {};
186
187/**
188 * Mapping from registration name to event name
189 */
190var registrationNameDependencies = {};
191
192/**
193 * Mapping from lowercase registration names to the properly cased version,
194 * used to warn in the case of missing event handlers. Available
195 * only in true.
196 * @type {Object}
197 */
198var possibleRegistrationNames = {};
199// Trust the developer to only use possibleRegistrationNames in true
200
201/**
202 * Injects an ordering of plugins (by plugin name). This allows the ordering
203 * to be decoupled from injection of the actual plugins so that ordering is
204 * always deterministic regardless of packaging, on-the-fly injection, etc.
205 *
206 * @param {array} InjectedEventPluginOrder
207 * @internal
208 * @see {EventPluginHub.injection.injectEventPluginOrder}
209 */
210function injectEventPluginOrder(injectedEventPluginOrder) {
211 (function () {
212 if (!!eventPluginOrder) {
213 {
214 throw ReactError(Error('EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.'));
215 }
216 }
217 })();
218 // Clone the ordering so it cannot be dynamically mutated.
219 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
220 recomputePluginOrdering();
221}
222
223/**
224 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
225 * in the ordering injected by `injectEventPluginOrder`.
226 *
227 * Plugins can be injected as part of page initialization or on-the-fly.
228 *
229 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
230 * @internal
231 * @see {EventPluginHub.injection.injectEventPluginsByName}
232 */
233function injectEventPluginsByName(injectedNamesToPlugins) {
234 var isOrderingDirty = false;
235 for (var pluginName in injectedNamesToPlugins) {
236 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
237 continue;
238 }
239 var pluginModule = injectedNamesToPlugins[pluginName];
240 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
241 (function () {
242 if (!!namesToPlugins[pluginName]) {
243 {
244 throw ReactError(Error('EventPluginRegistry: Cannot inject two different event plugins using the same name, `' + pluginName + '`.'));
245 }
246 }
247 })();
248 namesToPlugins[pluginName] = pluginModule;
249 isOrderingDirty = true;
250 }
251 }
252 if (isOrderingDirty) {
253 recomputePluginOrdering();
254 }
255}
256
257var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
258 var funcArgs = Array.prototype.slice.call(arguments, 3);
259 try {
260 func.apply(context, funcArgs);
261 } catch (error) {
262 this.onError(error);
263 }
264};
265
266{
267 // In DEV mode, we swap out invokeGuardedCallback for a special version
268 // that plays more nicely with the browser's DevTools. The idea is to preserve
269 // "Pause on exceptions" behavior. Because React wraps all user-provided
270 // functions in invokeGuardedCallback, and the production version of
271 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
272 // like caught exceptions, and the DevTools won't pause unless the developer
273 // takes the extra step of enabling pause on caught exceptions. This is
274 // unintuitive, though, because even though React has caught the error, from
275 // the developer's perspective, the error is uncaught.
276 //
277 // To preserve the expected "Pause on exceptions" behavior, we don't use a
278 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
279 // DOM node, and call the user-provided callback from inside an event handler
280 // for that fake event. If the callback throws, the error is "captured" using
281 // a global event handler. But because the error happens in a different
282 // event loop context, it does not interrupt the normal program flow.
283 // Effectively, this gives us try-catch behavior without actually using
284 // try-catch. Neat!
285
286 // Check that the browser supports the APIs we need to implement our special
287 // DEV version of invokeGuardedCallback
288 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
289 var fakeNode = document.createElement('react');
290
291 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
292 // If document doesn't exist we know for sure we will crash in this method
293 // when we call document.createEvent(). However this can cause confusing
294 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
295 // So we preemptively throw with a better message instead.
296 (function () {
297 if (!(typeof document !== 'undefined')) {
298 {
299 throw ReactError(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.'));
300 }
301 }
302 })();
303 var evt = document.createEvent('Event');
304
305 // Keeps track of whether the user-provided callback threw an error. We
306 // set this to true at the beginning, then set it to false right after
307 // calling the function. If the function errors, `didError` will never be
308 // set to false. This strategy works even if the browser is flaky and
309 // fails to call our global error handler, because it doesn't rely on
310 // the error event at all.
311 var didError = true;
312
313 // Keeps track of the value of window.event so that we can reset it
314 // during the callback to let user code access window.event in the
315 // browsers that support it.
316 var windowEvent = window.event;
317
318 // Keeps track of the descriptor of window.event to restore it after event
319 // dispatching: https://github.com/facebook/react/issues/13688
320 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
321
322 // Create an event handler for our fake event. We will synchronously
323 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
324 // call the user-provided callback.
325 var funcArgs = Array.prototype.slice.call(arguments, 3);
326 function callCallback() {
327 // We immediately remove the callback from event listeners so that
328 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
329 // nested call would trigger the fake event handlers of any call higher
330 // in the stack.
331 fakeNode.removeEventListener(evtType, callCallback, false);
332
333 // We check for window.hasOwnProperty('event') to prevent the
334 // window.event assignment in both IE <= 10 as they throw an error
335 // "Member not found" in strict mode, and in Firefox which does not
336 // support window.event.
337 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
338 window.event = windowEvent;
339 }
340
341 func.apply(context, funcArgs);
342 didError = false;
343 }
344
345 // Create a global error event handler. We use this to capture the value
346 // that was thrown. It's possible that this error handler will fire more
347 // than once; for example, if non-React code also calls `dispatchEvent`
348 // and a handler for that event throws. We should be resilient to most of
349 // those cases. Even if our error event handler fires more than once, the
350 // last error event is always used. If the callback actually does error,
351 // we know that the last error event is the correct one, because it's not
352 // possible for anything else to have happened in between our callback
353 // erroring and the code that follows the `dispatchEvent` call below. If
354 // the callback doesn't error, but the error event was fired, we know to
355 // ignore it because `didError` will be false, as described above.
356 var error = void 0;
357 // Use this to track whether the error event is ever called.
358 var didSetError = false;
359 var isCrossOriginError = false;
360
361 function handleWindowError(event) {
362 error = event.error;
363 didSetError = true;
364 if (error === null && event.colno === 0 && event.lineno === 0) {
365 isCrossOriginError = true;
366 }
367 if (event.defaultPrevented) {
368 // Some other error handler has prevented default.
369 // Browsers silence the error report if this happens.
370 // We'll remember this to later decide whether to log it or not.
371 if (error != null && typeof error === 'object') {
372 try {
373 error._suppressLogging = true;
374 } catch (inner) {
375 // Ignore.
376 }
377 }
378 }
379 }
380
381 // Create a fake event type.
382 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
383
384 // Attach our event handlers
385 window.addEventListener('error', handleWindowError);
386 fakeNode.addEventListener(evtType, callCallback, false);
387
388 // Synchronously dispatch our fake event. If the user-provided function
389 // errors, it will trigger our global error handler.
390 evt.initEvent(evtType, false, false);
391 fakeNode.dispatchEvent(evt);
392
393 if (windowEventDescriptor) {
394 Object.defineProperty(window, 'event', windowEventDescriptor);
395 }
396
397 if (didError) {
398 if (!didSetError) {
399 // The callback errored, but the error event never fired.
400 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.');
401 } else if (isCrossOriginError) {
402 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.');
403 }
404 this.onError(error);
405 }
406
407 // Remove our event listeners
408 window.removeEventListener('error', handleWindowError);
409 };
410
411 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
412 }
413}
414
415var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
416
417// Used by Fiber to simulate a try-catch.
418var hasError = false;
419var caughtError = null;
420
421// Used by event system to capture/rethrow the first error.
422var hasRethrowError = false;
423var rethrowError = null;
424
425var reporter = {
426 onError: function (error) {
427 hasError = true;
428 caughtError = error;
429 }
430};
431
432/**
433 * Call a function while guarding against errors that happens within it.
434 * Returns an error if it throws, otherwise null.
435 *
436 * In production, this is implemented using a try-catch. The reason we don't
437 * use a try-catch directly is so that we can swap out a different
438 * implementation in DEV mode.
439 *
440 * @param {String} name of the guard to use for logging or debugging
441 * @param {Function} func The function to invoke
442 * @param {*} context The context to use when calling the function
443 * @param {...*} args Arguments for function
444 */
445function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
446 hasError = false;
447 caughtError = null;
448 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
449}
450
451/**
452 * Same as invokeGuardedCallback, but instead of returning an error, it stores
453 * it in a global so it can be rethrown by `rethrowCaughtError` later.
454 * TODO: See if caughtError and rethrowError can be unified.
455 *
456 * @param {String} name of the guard to use for logging or debugging
457 * @param {Function} func The function to invoke
458 * @param {*} context The context to use when calling the function
459 * @param {...*} args Arguments for function
460 */
461function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
462 invokeGuardedCallback.apply(this, arguments);
463 if (hasError) {
464 var error = clearCaughtError();
465 if (!hasRethrowError) {
466 hasRethrowError = true;
467 rethrowError = error;
468 }
469 }
470}
471
472/**
473 * During execution of guarded functions we will capture the first error which
474 * we will rethrow to be handled by the top level error handler.
475 */
476function rethrowCaughtError() {
477 if (hasRethrowError) {
478 var error = rethrowError;
479 hasRethrowError = false;
480 rethrowError = null;
481 throw error;
482 }
483}
484
485function hasCaughtError() {
486 return hasError;
487}
488
489function clearCaughtError() {
490 if (hasError) {
491 var error = caughtError;
492 hasError = false;
493 caughtError = null;
494 return error;
495 } else {
496 (function () {
497 {
498 {
499 throw ReactError(Error('clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'));
500 }
501 }
502 })();
503 }
504}
505
506/**
507 * Similar to invariant but only logs a warning if the condition is not met.
508 * This can be used to log issues in development environments in critical
509 * paths. Removing the logging code for production environments will keep the
510 * same logic and follow the same code paths.
511 */
512
513var warningWithoutStack = function () {};
514
515{
516 warningWithoutStack = function (condition, format) {
517 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
518 args[_key - 2] = arguments[_key];
519 }
520
521 if (format === undefined) {
522 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
523 }
524 if (args.length > 8) {
525 // Check before the condition to catch violations early.
526 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
527 }
528 if (condition) {
529 return;
530 }
531 if (typeof console !== 'undefined') {
532 var argsWithFormat = args.map(function (item) {
533 return '' + item;
534 });
535 argsWithFormat.unshift('Warning: ' + format);
536
537 // We intentionally don't use spread (or .apply) directly because it
538 // breaks IE9: https://github.com/facebook/react/issues/13610
539 Function.prototype.apply.call(console.error, console, argsWithFormat);
540 }
541 try {
542 // --- Welcome to debugging React ---
543 // This error was thrown as a convenience so that you can use this stack
544 // to find the callsite that caused this warning to fire.
545 var argIndex = 0;
546 var message = 'Warning: ' + format.replace(/%s/g, function () {
547 return args[argIndex++];
548 });
549 throw new Error(message);
550 } catch (x) {}
551 };
552}
553
554var warningWithoutStack$1 = warningWithoutStack;
555
556var getFiberCurrentPropsFromNode = null;
557var getInstanceFromNode = null;
558var getNodeFromInstance = null;
559
560function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
561 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
562 getInstanceFromNode = getInstanceFromNodeImpl;
563 getNodeFromInstance = getNodeFromInstanceImpl;
564 {
565 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
566 }
567}
568
569var validateEventDispatches = void 0;
570{
571 validateEventDispatches = function (event) {
572 var dispatchListeners = event._dispatchListeners;
573 var dispatchInstances = event._dispatchInstances;
574
575 var listenersIsArr = Array.isArray(dispatchListeners);
576 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
577
578 var instancesIsArr = Array.isArray(dispatchInstances);
579 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
580
581 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
582 };
583}
584
585/**
586 * Dispatch the event to the listener.
587 * @param {SyntheticEvent} event SyntheticEvent to handle
588 * @param {function} listener Application-level callback
589 * @param {*} inst Internal component instance
590 */
591function executeDispatch(event, listener, inst) {
592 var type = event.type || 'unknown-event';
593 event.currentTarget = getNodeFromInstance(inst);
594 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
595 event.currentTarget = null;
596}
597
598/**
599 * Standard/simple iteration through an event's collected dispatches.
600 */
601function executeDispatchesInOrder(event) {
602 var dispatchListeners = event._dispatchListeners;
603 var dispatchInstances = event._dispatchInstances;
604 {
605 validateEventDispatches(event);
606 }
607 if (Array.isArray(dispatchListeners)) {
608 for (var i = 0; i < dispatchListeners.length; i++) {
609 if (event.isPropagationStopped()) {
610 break;
611 }
612 // Listeners and Instances are two parallel arrays that are always in sync.
613 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
614 }
615 } else if (dispatchListeners) {
616 executeDispatch(event, dispatchListeners, dispatchInstances);
617 }
618 event._dispatchListeners = null;
619 event._dispatchInstances = null;
620}
621
622/**
623 * @see executeDispatchesInOrderStopAtTrueImpl
624 */
625
626
627/**
628 * Execution of a "direct" dispatch - there must be at most one dispatch
629 * accumulated on the event or it is considered an error. It doesn't really make
630 * sense for an event with multiple dispatches (bubbled) to keep track of the
631 * return values at each dispatch execution, but it does tend to make sense when
632 * dealing with "direct" dispatches.
633 *
634 * @return {*} The return value of executing the single dispatch.
635 */
636
637
638/**
639 * @param {SyntheticEvent} event
640 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
641 */
642
643/**
644 * Accumulates items that must not be null or undefined into the first one. This
645 * is used to conserve memory by avoiding array allocations, and thus sacrifices
646 * API cleanness. Since `current` can be null before being passed in and not
647 * null after this function, make sure to assign it back to `current`:
648 *
649 * `a = accumulateInto(a, b);`
650 *
651 * This API should be sparingly used. Try `accumulate` for something cleaner.
652 *
653 * @return {*|array<*>} An accumulation of items.
654 */
655
656function accumulateInto(current, next) {
657 (function () {
658 if (!(next != null)) {
659 {
660 throw ReactError(Error('accumulateInto(...): Accumulated items must not be null or undefined.'));
661 }
662 }
663 })();
664
665 if (current == null) {
666 return next;
667 }
668
669 // Both are not empty. Warning: Never call x.concat(y) when you are not
670 // certain that x is an Array (x could be a string with concat method).
671 if (Array.isArray(current)) {
672 if (Array.isArray(next)) {
673 current.push.apply(current, next);
674 return current;
675 }
676 current.push(next);
677 return current;
678 }
679
680 if (Array.isArray(next)) {
681 // A bit too dangerous to mutate `next`.
682 return [current].concat(next);
683 }
684
685 return [current, next];
686}
687
688/**
689 * @param {array} arr an "accumulation" of items which is either an Array or
690 * a single item. Useful when paired with the `accumulate` module. This is a
691 * simple utility that allows us to reason about a collection of items, but
692 * handling the case when there is exactly one item (and we do not need to
693 * allocate an array).
694 * @param {function} cb Callback invoked with each element or a collection.
695 * @param {?} [scope] Scope used as `this` in a callback.
696 */
697function forEachAccumulated(arr, cb, scope) {
698 if (Array.isArray(arr)) {
699 arr.forEach(cb, scope);
700 } else if (arr) {
701 cb.call(scope, arr);
702 }
703}
704
705/**
706 * Internal queue of events that have accumulated their dispatches and are
707 * waiting to have their dispatches executed.
708 */
709var eventQueue = null;
710
711/**
712 * Dispatches an event and releases it back into the pool, unless persistent.
713 *
714 * @param {?object} event Synthetic event to be dispatched.
715 * @private
716 */
717var executeDispatchesAndRelease = function (event) {
718 if (event) {
719 executeDispatchesInOrder(event);
720
721 if (!event.isPersistent()) {
722 event.constructor.release(event);
723 }
724 }
725};
726var executeDispatchesAndReleaseTopLevel = function (e) {
727 return executeDispatchesAndRelease(e);
728};
729
730function runEventsInBatch(events) {
731 if (events !== null) {
732 eventQueue = accumulateInto(eventQueue, events);
733 }
734
735 // Set `eventQueue` to null before processing it so that we can tell if more
736 // events get enqueued while processing.
737 var processingEventQueue = eventQueue;
738 eventQueue = null;
739
740 if (!processingEventQueue) {
741 return;
742 }
743
744 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
745 (function () {
746 if (!!eventQueue) {
747 {
748 throw ReactError(Error('processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.'));
749 }
750 }
751 })();
752 // This would be a good time to rethrow if any of the event handlers threw.
753 rethrowCaughtError();
754}
755
756function isInteractive(tag) {
757 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
758}
759
760function shouldPreventMouseEvent(name, type, props) {
761 switch (name) {
762 case 'onClick':
763 case 'onClickCapture':
764 case 'onDoubleClick':
765 case 'onDoubleClickCapture':
766 case 'onMouseDown':
767 case 'onMouseDownCapture':
768 case 'onMouseMove':
769 case 'onMouseMoveCapture':
770 case 'onMouseUp':
771 case 'onMouseUpCapture':
772 return !!(props.disabled && isInteractive(type));
773 default:
774 return false;
775 }
776}
777
778/**
779 * This is a unified interface for event plugins to be installed and configured.
780 *
781 * Event plugins can implement the following properties:
782 *
783 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
784 * Required. When a top-level event is fired, this method is expected to
785 * extract synthetic events that will in turn be queued and dispatched.
786 *
787 * `eventTypes` {object}
788 * Optional, plugins that fire events must publish a mapping of registration
789 * names that are used to register listeners. Values of this mapping must
790 * be objects that contain `registrationName` or `phasedRegistrationNames`.
791 *
792 * `executeDispatch` {function(object, function, string)}
793 * Optional, allows plugins to override how an event gets dispatched. By
794 * default, the listener is simply invoked.
795 *
796 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
797 *
798 * @public
799 */
800
801/**
802 * Methods for injecting dependencies.
803 */
804var injection = {
805 /**
806 * @param {array} InjectedEventPluginOrder
807 * @public
808 */
809 injectEventPluginOrder: injectEventPluginOrder,
810
811 /**
812 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
813 */
814 injectEventPluginsByName: injectEventPluginsByName
815};
816
817/**
818 * @param {object} inst The instance, which is the source of events.
819 * @param {string} registrationName Name of listener (e.g. `onClick`).
820 * @return {?function} The stored callback.
821 */
822function getListener(inst, registrationName) {
823 var listener = void 0;
824
825 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
826 // live here; needs to be moved to a better place soon
827 var stateNode = inst.stateNode;
828 if (!stateNode) {
829 // Work in progress (ex: onload events in incremental mode).
830 return null;
831 }
832 var props = getFiberCurrentPropsFromNode(stateNode);
833 if (!props) {
834 // Work in progress.
835 return null;
836 }
837 listener = props[registrationName];
838 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
839 return null;
840 }
841 (function () {
842 if (!(!listener || typeof listener === 'function')) {
843 {
844 throw ReactError(Error('Expected `' + registrationName + '` listener to be a function, instead got a value of `' + typeof listener + '` type.'));
845 }
846 }
847 })();
848 return listener;
849}
850
851/**
852 * Allows registered plugins an opportunity to extract events from top-level
853 * native browser events.
854 *
855 * @return {*} An accumulation of synthetic events.
856 * @internal
857 */
858function extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
859 var events = null;
860 for (var i = 0; i < plugins.length; i++) {
861 // Not every plugin in the ordering may be loaded at runtime.
862 var possiblePlugin = plugins[i];
863 if (possiblePlugin) {
864 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
865 if (extractedEvents) {
866 events = accumulateInto(events, extractedEvents);
867 }
868 }
869 }
870 return events;
871}
872
873function runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
874 var events = extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
875 runEventsInBatch(events);
876}
877
878var FunctionComponent = 0;
879var ClassComponent = 1;
880var IndeterminateComponent = 2; // Before we know whether it is function or class
881var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
882var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
883var HostComponent = 5;
884var HostText = 6;
885var Fragment = 7;
886var Mode = 8;
887var ContextConsumer = 9;
888var ContextProvider = 10;
889var ForwardRef = 11;
890var Profiler = 12;
891var SuspenseComponent = 13;
892var MemoComponent = 14;
893var SimpleMemoComponent = 15;
894var LazyComponent = 16;
895var IncompleteClassComponent = 17;
896var DehydratedSuspenseComponent = 18;
897var SuspenseListComponent = 19;
898var FundamentalComponent = 20;
899
900var randomKey = Math.random().toString(36).slice(2);
901var internalInstanceKey = '__reactInternalInstance$' + randomKey;
902var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
903
904function precacheFiberNode(hostInst, node) {
905 node[internalInstanceKey] = hostInst;
906}
907
908/**
909 * Given a DOM node, return the closest ReactDOMComponent or
910 * ReactDOMTextComponent instance ancestor.
911 */
912function getClosestInstanceFromNode(node) {
913 if (node[internalInstanceKey]) {
914 return node[internalInstanceKey];
915 }
916
917 while (!node[internalInstanceKey]) {
918 if (node.parentNode) {
919 node = node.parentNode;
920 } else {
921 // Top of the tree. This node must not be part of a React tree (or is
922 // unmounted, potentially).
923 return null;
924 }
925 }
926
927 var inst = node[internalInstanceKey];
928 if (inst.tag === HostComponent || inst.tag === HostText) {
929 // In Fiber, this will always be the deepest root.
930 return inst;
931 }
932
933 return null;
934}
935
936/**
937 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
938 * instance, or null if the node was not rendered by this React.
939 */
940function getInstanceFromNode$1(node) {
941 var inst = node[internalInstanceKey];
942 if (inst) {
943 if (inst.tag === HostComponent || inst.tag === HostText) {
944 return inst;
945 } else {
946 return null;
947 }
948 }
949 return null;
950}
951
952/**
953 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
954 * DOM node.
955 */
956function getNodeFromInstance$1(inst) {
957 if (inst.tag === HostComponent || inst.tag === HostText) {
958 // In Fiber this, is just the state node right now. We assume it will be
959 // a host component or host text.
960 return inst.stateNode;
961 }
962
963 // Without this first invariant, passing a non-DOM-component triggers the next
964 // invariant for a missing parent, which is super confusing.
965 (function () {
966 {
967 {
968 throw ReactError(Error('getNodeFromInstance: Invalid argument.'));
969 }
970 }
971 })();
972}
973
974function getFiberCurrentPropsFromNode$1(node) {
975 return node[internalEventHandlersKey] || null;
976}
977
978function updateFiberProps(node, props) {
979 node[internalEventHandlersKey] = props;
980}
981
982function getParent(inst) {
983 do {
984 inst = inst.return;
985 // TODO: If this is a HostRoot we might want to bail out.
986 // That is depending on if we want nested subtrees (layers) to bubble
987 // events to their parent. We could also go through parentNode on the
988 // host node but that wouldn't work for React Native and doesn't let us
989 // do the portal feature.
990 } while (inst && inst.tag !== HostComponent);
991 if (inst) {
992 return inst;
993 }
994 return null;
995}
996
997/**
998 * Return the lowest common ancestor of A and B, or null if they are in
999 * different trees.
1000 */
1001function getLowestCommonAncestor(instA, instB) {
1002 var depthA = 0;
1003 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
1004 depthA++;
1005 }
1006 var depthB = 0;
1007 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
1008 depthB++;
1009 }
1010
1011 // If A is deeper, crawl up.
1012 while (depthA - depthB > 0) {
1013 instA = getParent(instA);
1014 depthA--;
1015 }
1016
1017 // If B is deeper, crawl up.
1018 while (depthB - depthA > 0) {
1019 instB = getParent(instB);
1020 depthB--;
1021 }
1022
1023 // Walk in lockstep until we find a match.
1024 var depth = depthA;
1025 while (depth--) {
1026 if (instA === instB || instA === instB.alternate) {
1027 return instA;
1028 }
1029 instA = getParent(instA);
1030 instB = getParent(instB);
1031 }
1032 return null;
1033}
1034
1035/**
1036 * Return if A is an ancestor of B.
1037 */
1038
1039
1040/**
1041 * Return the parent instance of the passed-in instance.
1042 */
1043
1044
1045/**
1046 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
1047 */
1048function traverseTwoPhase(inst, fn, arg) {
1049 var path = [];
1050 while (inst) {
1051 path.push(inst);
1052 inst = getParent(inst);
1053 }
1054 var i = void 0;
1055 for (i = path.length; i-- > 0;) {
1056 fn(path[i], 'captured', arg);
1057 }
1058 for (i = 0; i < path.length; i++) {
1059 fn(path[i], 'bubbled', arg);
1060 }
1061}
1062
1063/**
1064 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
1065 * should would receive a `mouseEnter` or `mouseLeave` event.
1066 *
1067 * Does not invoke the callback on the nearest common ancestor because nothing
1068 * "entered" or "left" that element.
1069 */
1070function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1071 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1072 var pathFrom = [];
1073 while (true) {
1074 if (!from) {
1075 break;
1076 }
1077 if (from === common) {
1078 break;
1079 }
1080 var alternate = from.alternate;
1081 if (alternate !== null && alternate === common) {
1082 break;
1083 }
1084 pathFrom.push(from);
1085 from = getParent(from);
1086 }
1087 var pathTo = [];
1088 while (true) {
1089 if (!to) {
1090 break;
1091 }
1092 if (to === common) {
1093 break;
1094 }
1095 var _alternate = to.alternate;
1096 if (_alternate !== null && _alternate === common) {
1097 break;
1098 }
1099 pathTo.push(to);
1100 to = getParent(to);
1101 }
1102 for (var i = 0; i < pathFrom.length; i++) {
1103 fn(pathFrom[i], 'bubbled', argFrom);
1104 }
1105 for (var _i = pathTo.length; _i-- > 0;) {
1106 fn(pathTo[_i], 'captured', argTo);
1107 }
1108}
1109
1110/**
1111 * Some event types have a notion of different registration names for different
1112 * "phases" of propagation. This finds listeners by a given phase.
1113 */
1114function listenerAtPhase(inst, event, propagationPhase) {
1115 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1116 return getListener(inst, registrationName);
1117}
1118
1119/**
1120 * A small set of propagation patterns, each of which will accept a small amount
1121 * of information, and generate a set of "dispatch ready event objects" - which
1122 * are sets of events that have already been annotated with a set of dispatched
1123 * listener functions/ids. The API is designed this way to discourage these
1124 * propagation strategies from actually executing the dispatches, since we
1125 * always want to collect the entire set of dispatches before executing even a
1126 * single one.
1127 */
1128
1129/**
1130 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1131 * here, allows us to not have to bind or create functions for each event.
1132 * Mutating the event's members allows us to not have to create a wrapping
1133 * "dispatch" object that pairs the event with the listener.
1134 */
1135function accumulateDirectionalDispatches(inst, phase, event) {
1136 {
1137 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
1138 }
1139 var listener = listenerAtPhase(inst, event, phase);
1140 if (listener) {
1141 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1142 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1143 }
1144}
1145
1146/**
1147 * Collect dispatches (must be entirely collected before dispatching - see unit
1148 * tests). Lazily allocate the array to conserve memory. We must loop through
1149 * each event and perform the traversal for each one. We cannot perform a
1150 * single traversal for the entire collection of events because each event may
1151 * have a different target.
1152 */
1153function accumulateTwoPhaseDispatchesSingle(event) {
1154 if (event && event.dispatchConfig.phasedRegistrationNames) {
1155 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1156 }
1157}
1158
1159/**
1160 * Accumulates without regard to direction, does not look for phased
1161 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1162 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1163 */
1164function accumulateDispatches(inst, ignoredDirection, event) {
1165 if (inst && event && event.dispatchConfig.registrationName) {
1166 var registrationName = event.dispatchConfig.registrationName;
1167 var listener = getListener(inst, registrationName);
1168 if (listener) {
1169 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1170 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1171 }
1172 }
1173}
1174
1175/**
1176 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1177 * `dispatchMarker`.
1178 * @param {SyntheticEvent} event
1179 */
1180function accumulateDirectDispatchesSingle(event) {
1181 if (event && event.dispatchConfig.registrationName) {
1182 accumulateDispatches(event._targetInst, null, event);
1183 }
1184}
1185
1186function accumulateTwoPhaseDispatches(events) {
1187 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1188}
1189
1190
1191
1192function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1193 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1194}
1195
1196function accumulateDirectDispatches(events) {
1197 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1198}
1199
1200var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
1201
1202// Do not use the below two methods directly!
1203// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
1204// (It is the only module that is allowed to access these methods.)
1205
1206function unsafeCastStringToDOMTopLevelType(topLevelType) {
1207 return topLevelType;
1208}
1209
1210function unsafeCastDOMTopLevelTypeToString(topLevelType) {
1211 return topLevelType;
1212}
1213
1214/**
1215 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
1216 *
1217 * @param {string} styleProp
1218 * @param {string} eventName
1219 * @returns {object}
1220 */
1221function makePrefixMap(styleProp, eventName) {
1222 var prefixes = {};
1223
1224 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
1225 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
1226 prefixes['Moz' + styleProp] = 'moz' + eventName;
1227
1228 return prefixes;
1229}
1230
1231/**
1232 * A list of event names to a configurable list of vendor prefixes.
1233 */
1234var vendorPrefixes = {
1235 animationend: makePrefixMap('Animation', 'AnimationEnd'),
1236 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
1237 animationstart: makePrefixMap('Animation', 'AnimationStart'),
1238 transitionend: makePrefixMap('Transition', 'TransitionEnd')
1239};
1240
1241/**
1242 * Event names that have already been detected and prefixed (if applicable).
1243 */
1244var prefixedEventNames = {};
1245
1246/**
1247 * Element to check for prefixes on.
1248 */
1249var style = {};
1250
1251/**
1252 * Bootstrap if a DOM exists.
1253 */
1254if (canUseDOM) {
1255 style = document.createElement('div').style;
1256
1257 // On some platforms, in particular some releases of Android 4.x,
1258 // the un-prefixed "animation" and "transition" properties are defined on the
1259 // style object but the events that fire will still be prefixed, so we need
1260 // to check if the un-prefixed events are usable, and if not remove them from the map.
1261 if (!('AnimationEvent' in window)) {
1262 delete vendorPrefixes.animationend.animation;
1263 delete vendorPrefixes.animationiteration.animation;
1264 delete vendorPrefixes.animationstart.animation;
1265 }
1266
1267 // Same as above
1268 if (!('TransitionEvent' in window)) {
1269 delete vendorPrefixes.transitionend.transition;
1270 }
1271}
1272
1273/**
1274 * Attempts to determine the correct vendor prefixed event name.
1275 *
1276 * @param {string} eventName
1277 * @returns {string}
1278 */
1279function getVendorPrefixedEventName(eventName) {
1280 if (prefixedEventNames[eventName]) {
1281 return prefixedEventNames[eventName];
1282 } else if (!vendorPrefixes[eventName]) {
1283 return eventName;
1284 }
1285
1286 var prefixMap = vendorPrefixes[eventName];
1287
1288 for (var styleProp in prefixMap) {
1289 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
1290 return prefixedEventNames[eventName] = prefixMap[styleProp];
1291 }
1292 }
1293
1294 return eventName;
1295}
1296
1297/**
1298 * To identify top level events in ReactDOM, we use constants defined by this
1299 * module. This is the only module that uses the unsafe* methods to express
1300 * that the constants actually correspond to the browser event names. This lets
1301 * us save some bundle size by avoiding a top level type -> event name map.
1302 * The rest of ReactDOM code should import top level types from this file.
1303 */
1304var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
1305var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
1306var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
1307var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
1308var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
1309var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
1310var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
1311var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
1312var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
1313var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
1314var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
1315var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
1316var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
1317var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
1318var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
1319var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
1320var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
1321var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
1322var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
1323var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
1324var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
1325var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
1326var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
1327var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
1328var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
1329var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
1330var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
1331var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
1332var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
1333var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
1334var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
1335var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
1336var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
1337var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
1338var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
1339var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
1340var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
1341var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
1342var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
1343var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
1344var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
1345var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
1346var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
1347var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
1348var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
1349var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
1350var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
1351var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
1352var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
1353var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
1354var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
1355var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
1356var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
1357var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
1358var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
1359
1360
1361var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
1362var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
1363var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
1364var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
1365var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
1366var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
1367var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
1368var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
1369var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
1370var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
1371var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
1372var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
1373var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
1374var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
1375var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
1376var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
1377var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
1378var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
1379var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
1380var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
1381var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
1382var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
1383var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
1384var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
1385var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');
1386
1387// List of events that need to be individually attached to media elements.
1388// Note that events in this list will *not* be listened to at the top level
1389// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
1390var 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];
1391
1392function getRawEventName(topLevelType) {
1393 return unsafeCastDOMTopLevelTypeToString(topLevelType);
1394}
1395
1396/**
1397 * These variables store information about text content of a target node,
1398 * allowing comparison of content before and after a given event.
1399 *
1400 * Identify the node where selection currently begins, then observe
1401 * both its text content and its current position in the DOM. Since the
1402 * browser may natively replace the target node during composition, we can
1403 * use its position to find its replacement.
1404 *
1405 *
1406 */
1407
1408var root = null;
1409var startText = null;
1410var fallbackText = null;
1411
1412function initialize(nativeEventTarget) {
1413 root = nativeEventTarget;
1414 startText = getText();
1415 return true;
1416}
1417
1418function reset() {
1419 root = null;
1420 startText = null;
1421 fallbackText = null;
1422}
1423
1424function getData() {
1425 if (fallbackText) {
1426 return fallbackText;
1427 }
1428
1429 var start = void 0;
1430 var startValue = startText;
1431 var startLength = startValue.length;
1432 var end = void 0;
1433 var endValue = getText();
1434 var endLength = endValue.length;
1435
1436 for (start = 0; start < startLength; start++) {
1437 if (startValue[start] !== endValue[start]) {
1438 break;
1439 }
1440 }
1441
1442 var minEnd = startLength - start;
1443 for (end = 1; end <= minEnd; end++) {
1444 if (startValue[startLength - end] !== endValue[endLength - end]) {
1445 break;
1446 }
1447 }
1448
1449 var sliceTail = end > 1 ? 1 - end : undefined;
1450 fallbackText = endValue.slice(start, sliceTail);
1451 return fallbackText;
1452}
1453
1454function getText() {
1455 if ('value' in root) {
1456 return root.value;
1457 }
1458 return root.textContent;
1459}
1460
1461var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1462
1463var _assign = ReactInternals.assign;
1464
1465/* eslint valid-typeof: 0 */
1466
1467var EVENT_POOL_SIZE = 10;
1468
1469/**
1470 * @interface Event
1471 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1472 */
1473var EventInterface = {
1474 type: null,
1475 target: null,
1476 // currentTarget is set when dispatching; no use in copying it here
1477 currentTarget: function () {
1478 return null;
1479 },
1480 eventPhase: null,
1481 bubbles: null,
1482 cancelable: null,
1483 timeStamp: function (event) {
1484 return event.timeStamp || Date.now();
1485 },
1486 defaultPrevented: null,
1487 isTrusted: null
1488};
1489
1490function functionThatReturnsTrue() {
1491 return true;
1492}
1493
1494function functionThatReturnsFalse() {
1495 return false;
1496}
1497
1498/**
1499 * Synthetic events are dispatched by event plugins, typically in response to a
1500 * top-level event delegation handler.
1501 *
1502 * These systems should generally use pooling to reduce the frequency of garbage
1503 * collection. The system should check `isPersistent` to determine whether the
1504 * event should be released into the pool after being dispatched. Users that
1505 * need a persisted event should invoke `persist`.
1506 *
1507 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1508 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1509 * DOM interface; custom application-specific events can also subclass this.
1510 *
1511 * @param {object} dispatchConfig Configuration used to dispatch this event.
1512 * @param {*} targetInst Marker identifying the event target.
1513 * @param {object} nativeEvent Native browser event.
1514 * @param {DOMEventTarget} nativeEventTarget Target node.
1515 */
1516function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1517 {
1518 // these have a getter/setter for warnings
1519 delete this.nativeEvent;
1520 delete this.preventDefault;
1521 delete this.stopPropagation;
1522 delete this.isDefaultPrevented;
1523 delete this.isPropagationStopped;
1524 }
1525
1526 this.dispatchConfig = dispatchConfig;
1527 this._targetInst = targetInst;
1528 this.nativeEvent = nativeEvent;
1529
1530 var Interface = this.constructor.Interface;
1531 for (var propName in Interface) {
1532 if (!Interface.hasOwnProperty(propName)) {
1533 continue;
1534 }
1535 {
1536 delete this[propName]; // this has a getter/setter for warnings
1537 }
1538 var normalize = Interface[propName];
1539 if (normalize) {
1540 this[propName] = normalize(nativeEvent);
1541 } else {
1542 if (propName === 'target') {
1543 this.target = nativeEventTarget;
1544 } else {
1545 this[propName] = nativeEvent[propName];
1546 }
1547 }
1548 }
1549
1550 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1551 if (defaultPrevented) {
1552 this.isDefaultPrevented = functionThatReturnsTrue;
1553 } else {
1554 this.isDefaultPrevented = functionThatReturnsFalse;
1555 }
1556 this.isPropagationStopped = functionThatReturnsFalse;
1557 return this;
1558}
1559
1560_assign(SyntheticEvent.prototype, {
1561 preventDefault: function () {
1562 this.defaultPrevented = true;
1563 var event = this.nativeEvent;
1564 if (!event) {
1565 return;
1566 }
1567
1568 if (event.preventDefault) {
1569 event.preventDefault();
1570 } else if (typeof event.returnValue !== 'unknown') {
1571 event.returnValue = false;
1572 }
1573 this.isDefaultPrevented = functionThatReturnsTrue;
1574 },
1575
1576 stopPropagation: function () {
1577 var event = this.nativeEvent;
1578 if (!event) {
1579 return;
1580 }
1581
1582 if (event.stopPropagation) {
1583 event.stopPropagation();
1584 } else if (typeof event.cancelBubble !== 'unknown') {
1585 // The ChangeEventPlugin registers a "propertychange" event for
1586 // IE. This event does not support bubbling or cancelling, and
1587 // any references to cancelBubble throw "Member not found". A
1588 // typeof check of "unknown" circumvents this issue (and is also
1589 // IE specific).
1590 event.cancelBubble = true;
1591 }
1592
1593 this.isPropagationStopped = functionThatReturnsTrue;
1594 },
1595
1596 /**
1597 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1598 * them back into the pool. This allows a way to hold onto a reference that
1599 * won't be added back into the pool.
1600 */
1601 persist: function () {
1602 this.isPersistent = functionThatReturnsTrue;
1603 },
1604
1605 /**
1606 * Checks if this event should be released back into the pool.
1607 *
1608 * @return {boolean} True if this should not be released, false otherwise.
1609 */
1610 isPersistent: functionThatReturnsFalse,
1611
1612 /**
1613 * `PooledClass` looks for `destructor` on each instance it releases.
1614 */
1615 destructor: function () {
1616 var Interface = this.constructor.Interface;
1617 for (var propName in Interface) {
1618 {
1619 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1620 }
1621 }
1622 this.dispatchConfig = null;
1623 this._targetInst = null;
1624 this.nativeEvent = null;
1625 this.isDefaultPrevented = functionThatReturnsFalse;
1626 this.isPropagationStopped = functionThatReturnsFalse;
1627 this._dispatchListeners = null;
1628 this._dispatchInstances = null;
1629 {
1630 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1631 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
1632 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
1633 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
1634 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
1635 }
1636 }
1637});
1638
1639SyntheticEvent.Interface = EventInterface;
1640
1641/**
1642 * Helper to reduce boilerplate when creating subclasses.
1643 */
1644SyntheticEvent.extend = function (Interface) {
1645 var Super = this;
1646
1647 var E = function () {};
1648 E.prototype = Super.prototype;
1649 var prototype = new E();
1650
1651 function Class() {
1652 return Super.apply(this, arguments);
1653 }
1654 _assign(prototype, Class.prototype);
1655 Class.prototype = prototype;
1656 Class.prototype.constructor = Class;
1657
1658 Class.Interface = _assign({}, Super.Interface, Interface);
1659 Class.extend = Super.extend;
1660 addEventPoolingTo(Class);
1661
1662 return Class;
1663};
1664
1665addEventPoolingTo(SyntheticEvent);
1666
1667/**
1668 * Helper to nullify syntheticEvent instance properties when destructing
1669 *
1670 * @param {String} propName
1671 * @param {?object} getVal
1672 * @return {object} defineProperty object
1673 */
1674function getPooledWarningPropertyDefinition(propName, getVal) {
1675 var isFunction = typeof getVal === 'function';
1676 return {
1677 configurable: true,
1678 set: set,
1679 get: get
1680 };
1681
1682 function set(val) {
1683 var action = isFunction ? 'setting the method' : 'setting the property';
1684 warn(action, 'This is effectively a no-op');
1685 return val;
1686 }
1687
1688 function get() {
1689 var action = isFunction ? 'accessing the method' : 'accessing the property';
1690 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1691 warn(action, result);
1692 return getVal;
1693 }
1694
1695 function warn(action, result) {
1696 var warningCondition = false;
1697 !warningCondition ? warningWithoutStack$1(false, "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) : void 0;
1698 }
1699}
1700
1701function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1702 var EventConstructor = this;
1703 if (EventConstructor.eventPool.length) {
1704 var instance = EventConstructor.eventPool.pop();
1705 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1706 return instance;
1707 }
1708 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1709}
1710
1711function releasePooledEvent(event) {
1712 var EventConstructor = this;
1713 (function () {
1714 if (!(event instanceof EventConstructor)) {
1715 {
1716 throw ReactError(Error('Trying to release an event instance into a pool of a different type.'));
1717 }
1718 }
1719 })();
1720 event.destructor();
1721 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1722 EventConstructor.eventPool.push(event);
1723 }
1724}
1725
1726function addEventPoolingTo(EventConstructor) {
1727 EventConstructor.eventPool = [];
1728 EventConstructor.getPooled = getPooledEvent;
1729 EventConstructor.release = releasePooledEvent;
1730}
1731
1732/**
1733 * @interface Event
1734 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1735 */
1736var SyntheticCompositionEvent = SyntheticEvent.extend({
1737 data: null
1738});
1739
1740/**
1741 * @interface Event
1742 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1743 * /#events-inputevents
1744 */
1745var SyntheticInputEvent = SyntheticEvent.extend({
1746 data: null
1747});
1748
1749var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1750var START_KEYCODE = 229;
1751
1752var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
1753
1754var documentMode = null;
1755if (canUseDOM && 'documentMode' in document) {
1756 documentMode = document.documentMode;
1757}
1758
1759// Webkit offers a very useful `textInput` event that can be used to
1760// directly represent `beforeInput`. The IE `textinput` event is not as
1761// useful, so we don't use it.
1762var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode;
1763
1764// In IE9+, we have access to composition events, but the data supplied
1765// by the native compositionend event may be incorrect. Japanese ideographic
1766// spaces, for instance (\u3000) are not recorded correctly.
1767var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1768
1769var SPACEBAR_CODE = 32;
1770var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1771
1772// Events and their corresponding property names.
1773var eventTypes = {
1774 beforeInput: {
1775 phasedRegistrationNames: {
1776 bubbled: 'onBeforeInput',
1777 captured: 'onBeforeInputCapture'
1778 },
1779 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
1780 },
1781 compositionEnd: {
1782 phasedRegistrationNames: {
1783 bubbled: 'onCompositionEnd',
1784 captured: 'onCompositionEndCapture'
1785 },
1786 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1787 },
1788 compositionStart: {
1789 phasedRegistrationNames: {
1790 bubbled: 'onCompositionStart',
1791 captured: 'onCompositionStartCapture'
1792 },
1793 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1794 },
1795 compositionUpdate: {
1796 phasedRegistrationNames: {
1797 bubbled: 'onCompositionUpdate',
1798 captured: 'onCompositionUpdateCapture'
1799 },
1800 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1801 }
1802};
1803
1804// Track whether we've ever handled a keypress on the space key.
1805var hasSpaceKeypress = false;
1806
1807/**
1808 * Return whether a native keypress event is assumed to be a command.
1809 * This is required because Firefox fires `keypress` events for key commands
1810 * (cut, copy, select-all, etc.) even though no character is inserted.
1811 */
1812function isKeypressCommand(nativeEvent) {
1813 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1814 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1815 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1816}
1817
1818/**
1819 * Translate native top level events into event types.
1820 *
1821 * @param {string} topLevelType
1822 * @return {object}
1823 */
1824function getCompositionEventType(topLevelType) {
1825 switch (topLevelType) {
1826 case TOP_COMPOSITION_START:
1827 return eventTypes.compositionStart;
1828 case TOP_COMPOSITION_END:
1829 return eventTypes.compositionEnd;
1830 case TOP_COMPOSITION_UPDATE:
1831 return eventTypes.compositionUpdate;
1832 }
1833}
1834
1835/**
1836 * Does our fallback best-guess model think this event signifies that
1837 * composition has begun?
1838 *
1839 * @param {string} topLevelType
1840 * @param {object} nativeEvent
1841 * @return {boolean}
1842 */
1843function isFallbackCompositionStart(topLevelType, nativeEvent) {
1844 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
1845}
1846
1847/**
1848 * Does our fallback mode think that this event is the end of composition?
1849 *
1850 * @param {string} topLevelType
1851 * @param {object} nativeEvent
1852 * @return {boolean}
1853 */
1854function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1855 switch (topLevelType) {
1856 case TOP_KEY_UP:
1857 // Command keys insert or clear IME input.
1858 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1859 case TOP_KEY_DOWN:
1860 // Expect IME keyCode on each keydown. If we get any other
1861 // code we must have exited earlier.
1862 return nativeEvent.keyCode !== START_KEYCODE;
1863 case TOP_KEY_PRESS:
1864 case TOP_MOUSE_DOWN:
1865 case TOP_BLUR:
1866 // Events are not possible without cancelling IME.
1867 return true;
1868 default:
1869 return false;
1870 }
1871}
1872
1873/**
1874 * Google Input Tools provides composition data via a CustomEvent,
1875 * with the `data` property populated in the `detail` object. If this
1876 * is available on the event object, use it. If not, this is a plain
1877 * composition event and we have nothing special to extract.
1878 *
1879 * @param {object} nativeEvent
1880 * @return {?string}
1881 */
1882function getDataFromCustomEvent(nativeEvent) {
1883 var detail = nativeEvent.detail;
1884 if (typeof detail === 'object' && 'data' in detail) {
1885 return detail.data;
1886 }
1887 return null;
1888}
1889
1890/**
1891 * Check if a composition event was triggered by Korean IME.
1892 * Our fallback mode does not work well with IE's Korean IME,
1893 * so just use native composition events when Korean IME is used.
1894 * Although CompositionEvent.locale property is deprecated,
1895 * it is available in IE, where our fallback mode is enabled.
1896 *
1897 * @param {object} nativeEvent
1898 * @return {boolean}
1899 */
1900function isUsingKoreanIME(nativeEvent) {
1901 return nativeEvent.locale === 'ko';
1902}
1903
1904// Track the current IME composition status, if any.
1905var isComposing = false;
1906
1907/**
1908 * @return {?object} A SyntheticCompositionEvent.
1909 */
1910function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1911 var eventType = void 0;
1912 var fallbackData = void 0;
1913
1914 if (canUseCompositionEvent) {
1915 eventType = getCompositionEventType(topLevelType);
1916 } else if (!isComposing) {
1917 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1918 eventType = eventTypes.compositionStart;
1919 }
1920 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1921 eventType = eventTypes.compositionEnd;
1922 }
1923
1924 if (!eventType) {
1925 return null;
1926 }
1927
1928 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
1929 // The current composition is stored statically and must not be
1930 // overwritten while composition continues.
1931 if (!isComposing && eventType === eventTypes.compositionStart) {
1932 isComposing = initialize(nativeEventTarget);
1933 } else if (eventType === eventTypes.compositionEnd) {
1934 if (isComposing) {
1935 fallbackData = getData();
1936 }
1937 }
1938 }
1939
1940 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1941
1942 if (fallbackData) {
1943 // Inject data generated from fallback path into the synthetic event.
1944 // This matches the property of native CompositionEventInterface.
1945 event.data = fallbackData;
1946 } else {
1947 var customData = getDataFromCustomEvent(nativeEvent);
1948 if (customData !== null) {
1949 event.data = customData;
1950 }
1951 }
1952
1953 accumulateTwoPhaseDispatches(event);
1954 return event;
1955}
1956
1957/**
1958 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
1959 * @param {object} nativeEvent Native browser event.
1960 * @return {?string} The string corresponding to this `beforeInput` event.
1961 */
1962function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1963 switch (topLevelType) {
1964 case TOP_COMPOSITION_END:
1965 return getDataFromCustomEvent(nativeEvent);
1966 case TOP_KEY_PRESS:
1967 /**
1968 * If native `textInput` events are available, our goal is to make
1969 * use of them. However, there is a special case: the spacebar key.
1970 * In Webkit, preventing default on a spacebar `textInput` event
1971 * cancels character insertion, but it *also* causes the browser
1972 * to fall back to its default spacebar behavior of scrolling the
1973 * page.
1974 *
1975 * Tracking at:
1976 * https://code.google.com/p/chromium/issues/detail?id=355103
1977 *
1978 * To avoid this issue, use the keypress event as if no `textInput`
1979 * event is available.
1980 */
1981 var which = nativeEvent.which;
1982 if (which !== SPACEBAR_CODE) {
1983 return null;
1984 }
1985
1986 hasSpaceKeypress = true;
1987 return SPACEBAR_CHAR;
1988
1989 case TOP_TEXT_INPUT:
1990 // Record the characters to be added to the DOM.
1991 var chars = nativeEvent.data;
1992
1993 // If it's a spacebar character, assume that we have already handled
1994 // it at the keypress level and bail immediately. Android Chrome
1995 // doesn't give us keycodes, so we need to ignore it.
1996 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1997 return null;
1998 }
1999
2000 return chars;
2001
2002 default:
2003 // For other native event types, do nothing.
2004 return null;
2005 }
2006}
2007
2008/**
2009 * For browsers that do not provide the `textInput` event, extract the
2010 * appropriate string to use for SyntheticInputEvent.
2011 *
2012 * @param {number} topLevelType Number from `TopLevelEventTypes`.
2013 * @param {object} nativeEvent Native browser event.
2014 * @return {?string} The fallback string for this `beforeInput` event.
2015 */
2016function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
2017 // If we are currently composing (IME) and using a fallback to do so,
2018 // try to extract the composed characters from the fallback object.
2019 // If composition event is available, we extract a string only at
2020 // compositionevent, otherwise extract it at fallback events.
2021 if (isComposing) {
2022 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
2023 var chars = getData();
2024 reset();
2025 isComposing = false;
2026 return chars;
2027 }
2028 return null;
2029 }
2030
2031 switch (topLevelType) {
2032 case TOP_PASTE:
2033 // If a paste event occurs after a keypress, throw out the input
2034 // chars. Paste events should not lead to BeforeInput events.
2035 return null;
2036 case TOP_KEY_PRESS:
2037 /**
2038 * As of v27, Firefox may fire keypress events even when no character
2039 * will be inserted. A few possibilities:
2040 *
2041 * - `which` is `0`. Arrow keys, Esc key, etc.
2042 *
2043 * - `which` is the pressed key code, but no char is available.
2044 * Ex: 'AltGr + d` in Polish. There is no modified character for
2045 * this key combination and no character is inserted into the
2046 * document, but FF fires the keypress for char code `100` anyway.
2047 * No `input` event will occur.
2048 *
2049 * - `which` is the pressed key code, but a command combination is
2050 * being used. Ex: `Cmd+C`. No character is inserted, and no
2051 * `input` event will occur.
2052 */
2053 if (!isKeypressCommand(nativeEvent)) {
2054 // IE fires the `keypress` event when a user types an emoji via
2055 // Touch keyboard of Windows. In such a case, the `char` property
2056 // holds an emoji character like `\uD83D\uDE0A`. Because its length
2057 // is 2, the property `which` does not represent an emoji correctly.
2058 // In such a case, we directly return the `char` property instead of
2059 // using `which`.
2060 if (nativeEvent.char && nativeEvent.char.length > 1) {
2061 return nativeEvent.char;
2062 } else if (nativeEvent.which) {
2063 return String.fromCharCode(nativeEvent.which);
2064 }
2065 }
2066 return null;
2067 case TOP_COMPOSITION_END:
2068 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
2069 default:
2070 return null;
2071 }
2072}
2073
2074/**
2075 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
2076 * `textInput` or fallback behavior.
2077 *
2078 * @return {?object} A SyntheticInputEvent.
2079 */
2080function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2081 var chars = void 0;
2082
2083 if (canUseTextInputEvent) {
2084 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
2085 } else {
2086 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
2087 }
2088
2089 // If no characters are being inserted, no BeforeInput event should
2090 // be fired.
2091 if (!chars) {
2092 return null;
2093 }
2094
2095 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
2096
2097 event.data = chars;
2098 accumulateTwoPhaseDispatches(event);
2099 return event;
2100}
2101
2102/**
2103 * Create an `onBeforeInput` event to match
2104 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
2105 *
2106 * This event plugin is based on the native `textInput` event
2107 * available in Chrome, Safari, Opera, and IE. This event fires after
2108 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
2109 *
2110 * `beforeInput` is spec'd but not implemented in any browsers, and
2111 * the `input` event does not provide any useful information about what has
2112 * actually been added, contrary to the spec. Thus, `textInput` is the best
2113 * available event to identify the characters that have actually been inserted
2114 * into the target node.
2115 *
2116 * This plugin is also responsible for emitting `composition` events, thus
2117 * allowing us to share composition fallback code for both `beforeInput` and
2118 * `composition` event types.
2119 */
2120var BeforeInputEventPlugin = {
2121 eventTypes: eventTypes,
2122
2123 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2124 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2125
2126 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2127
2128 if (composition === null) {
2129 return beforeInput;
2130 }
2131
2132 if (beforeInput === null) {
2133 return composition;
2134 }
2135
2136 return [composition, beforeInput];
2137 }
2138};
2139
2140// Use to restore controlled state after a change event has fired.
2141
2142var restoreImpl = null;
2143var restoreTarget = null;
2144var restoreQueue = null;
2145
2146function restoreStateOfTarget(target) {
2147 // We perform this translation at the end of the event loop so that we
2148 // always receive the correct fiber here
2149 var internalInstance = getInstanceFromNode(target);
2150 if (!internalInstance) {
2151 // Unmounted
2152 return;
2153 }
2154 (function () {
2155 if (!(typeof restoreImpl === 'function')) {
2156 {
2157 throw ReactError(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.'));
2158 }
2159 }
2160 })();
2161 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2162 restoreImpl(internalInstance.stateNode, internalInstance.type, props);
2163}
2164
2165function setRestoreImplementation(impl) {
2166 restoreImpl = impl;
2167}
2168
2169function enqueueStateRestore(target) {
2170 if (restoreTarget) {
2171 if (restoreQueue) {
2172 restoreQueue.push(target);
2173 } else {
2174 restoreQueue = [target];
2175 }
2176 } else {
2177 restoreTarget = target;
2178 }
2179}
2180
2181function needsStateRestore() {
2182 return restoreTarget !== null || restoreQueue !== null;
2183}
2184
2185function restoreStateIfNeeded() {
2186 if (!restoreTarget) {
2187 return;
2188 }
2189 var target = restoreTarget;
2190 var queuedTargets = restoreQueue;
2191 restoreTarget = null;
2192 restoreQueue = null;
2193
2194 restoreStateOfTarget(target);
2195 if (queuedTargets) {
2196 for (var i = 0; i < queuedTargets.length; i++) {
2197 restoreStateOfTarget(queuedTargets[i]);
2198 }
2199 }
2200}
2201
2202var enableUserTimingAPI = true;
2203
2204// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
2205var debugRenderPhaseSideEffects = false;
2206
2207// In some cases, StrictMode should also double-render lifecycles.
2208// This can be confusing for tests though,
2209// And it can be bad for performance in production.
2210// This feature flag can be used to control the behavior:
2211var debugRenderPhaseSideEffectsForStrictMode = true;
2212
2213// To preserve the "Pause on caught exceptions" behavior of the debugger, we
2214// replay the begin phase of a failed component inside invokeGuardedCallback.
2215var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
2216
2217// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
2218var warnAboutDeprecatedLifecycles = true;
2219
2220// Gather advanced timing metrics for Profiler subtrees.
2221var enableProfilerTimer = true;
2222
2223// Trace which interactions trigger each commit.
2224var enableSchedulerTracing = true;
2225
2226// Only used in www builds.
2227var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
2228
2229// Only used in www builds.
2230
2231
2232// Only used in www builds.
2233
2234
2235// Disable javascript: URL strings in href for XSS protection.
2236var disableJavaScriptURLs = false;
2237
2238// React Fire: prevent the value and checked attributes from syncing
2239// with their related DOM properties
2240var disableInputAttributeSyncing = false;
2241
2242// These APIs will no longer be "unstable" in the upcoming 16.7 release,
2243// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
2244var enableStableConcurrentModeAPIs = false;
2245
2246var warnAboutShorthandPropertyCollision = false;
2247
2248// See https://github.com/react-native-community/discussions-and-proposals/issues/72 for more information
2249// This is a flag so we can fix warnings in RN core before turning it on
2250
2251
2252// Experimental React Flare event system and event components support.
2253var enableFlareAPI = false;
2254
2255// Experimental Host Component support.
2256var enableFundamentalAPI = false;
2257
2258// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
2259
2260
2261// We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
2262// Till then, we warn about the missing mock, but still fallback to a sync mode compatible version
2263var warnAboutUnmockedScheduler = false;
2264// Temporary flag to revert the fix in #15650
2265var revertPassiveEffectsChange = false;
2266
2267// For tests, we flush suspense fallbacks in an act scope;
2268// *except* in some of our own tests, where we test incremental loading states.
2269var flushSuspenseFallbacksInTests = true;
2270
2271// Changes priority of some events like mousemove to user-blocking priority,
2272// but without making them discrete. The flag exists in case it causes
2273// starvation problems.
2274var enableUserBlockingEvents = false;
2275
2276// Add a callback property to suspense to notify which promises are currently
2277// in the update queue. This allows reporting and tracing of what is causing
2278// the user to see a loading state.
2279var enableSuspenseCallback = false;
2280
2281// Part of the simplification of React.createElement so we can eventually move
2282// from React.createElement to React.jsx
2283// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
2284var warnAboutDefaultPropsOnFunctionComponents = false;
2285
2286var disableLegacyContext = false;
2287
2288var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
2289
2290// Used as a way to call batchedUpdates when we don't have a reference to
2291// the renderer. Such as when we're dispatching events or if third party
2292// libraries need to call batchedUpdates. Eventually, this API will go away when
2293// everything is batched by default. We'll then have a similar API to opt-out of
2294// scheduled work and instead do synchronous work.
2295
2296// Defaults
2297var batchedUpdatesImpl = function (fn, bookkeeping) {
2298 return fn(bookkeeping);
2299};
2300var discreteUpdatesImpl = function (fn, a, b, c) {
2301 return fn(a, b, c);
2302};
2303var flushDiscreteUpdatesImpl = function () {};
2304var batchedEventUpdatesImpl = batchedUpdatesImpl;
2305
2306var isInsideEventHandler = false;
2307
2308function finishEventHandler() {
2309 // Here we wait until all updates have propagated, which is important
2310 // when using controlled components within layers:
2311 // https://github.com/facebook/react/issues/1698
2312 // Then we restore state of any controlled component.
2313 var controlledComponentsHavePendingUpdates = needsStateRestore();
2314 if (controlledComponentsHavePendingUpdates) {
2315 // If a controlled event was fired, we may need to restore the state of
2316 // the DOM node back to the controlled value. This is necessary when React
2317 // bails out of the update without touching the DOM.
2318 flushDiscreteUpdatesImpl();
2319 restoreStateIfNeeded();
2320 }
2321}
2322
2323function batchedUpdates(fn, bookkeeping) {
2324 if (isInsideEventHandler) {
2325 // If we are currently inside another batch, we need to wait until it
2326 // fully completes before restoring state.
2327 return fn(bookkeeping);
2328 }
2329 isInsideEventHandler = true;
2330 try {
2331 return batchedUpdatesImpl(fn, bookkeeping);
2332 } finally {
2333 isInsideEventHandler = false;
2334 finishEventHandler();
2335 }
2336}
2337
2338function batchedEventUpdates(fn, a, b) {
2339 if (isInsideEventHandler) {
2340 // If we are currently inside another batch, we need to wait until it
2341 // fully completes before restoring state.
2342 return fn(a, b);
2343 }
2344 isInsideEventHandler = true;
2345 try {
2346 return batchedEventUpdatesImpl(fn, a, b);
2347 } finally {
2348 isInsideEventHandler = false;
2349 finishEventHandler();
2350 }
2351}
2352
2353function discreteUpdates(fn, a, b, c) {
2354 var prevIsInsideEventHandler = isInsideEventHandler;
2355 isInsideEventHandler = true;
2356 try {
2357 return discreteUpdatesImpl(fn, a, b, c);
2358 } finally {
2359 isInsideEventHandler = prevIsInsideEventHandler;
2360 if (!isInsideEventHandler) {
2361 finishEventHandler();
2362 }
2363 }
2364}
2365
2366var lastFlushedEventTimeStamp = 0;
2367function flushDiscreteUpdatesIfNeeded(timeStamp) {
2368 // event.timeStamp isn't overly reliable due to inconsistencies in
2369 // how different browsers have historically provided the time stamp.
2370 // Some browsers provide high-resolution time stamps for all events,
2371 // some provide low-resolution time stamps for all events. FF < 52
2372 // even mixes both time stamps together. Some browsers even report
2373 // negative time stamps or time stamps that are 0 (iOS9) in some cases.
2374 // Given we are only comparing two time stamps with equality (!==),
2375 // we are safe from the resolution differences. If the time stamp is 0
2376 // we bail-out of preventing the flush, which can affect semantics,
2377 // such as if an earlier flush removes or adds event listeners that
2378 // are fired in the subsequent flush. However, this is the same
2379 // behaviour as we had before this change, so the risks are low.
2380 if (!isInsideEventHandler && (!enableFlareAPI || timeStamp === 0 || lastFlushedEventTimeStamp !== timeStamp)) {
2381 lastFlushedEventTimeStamp = timeStamp;
2382 flushDiscreteUpdatesImpl();
2383 }
2384}
2385
2386function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {
2387 batchedUpdatesImpl = _batchedUpdatesImpl;
2388 discreteUpdatesImpl = _discreteUpdatesImpl;
2389 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
2390 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
2391}
2392
2393/**
2394 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2395 */
2396var supportedInputTypes = {
2397 color: true,
2398 date: true,
2399 datetime: true,
2400 'datetime-local': true,
2401 email: true,
2402 month: true,
2403 number: true,
2404 password: true,
2405 range: true,
2406 search: true,
2407 tel: true,
2408 text: true,
2409 time: true,
2410 url: true,
2411 week: true
2412};
2413
2414function isTextInputElement(elem) {
2415 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2416
2417 if (nodeName === 'input') {
2418 return !!supportedInputTypes[elem.type];
2419 }
2420
2421 if (nodeName === 'textarea') {
2422 return true;
2423 }
2424
2425 return false;
2426}
2427
2428/**
2429 * HTML nodeType values that represent the type of the node
2430 */
2431
2432var ELEMENT_NODE = 1;
2433var TEXT_NODE = 3;
2434var COMMENT_NODE = 8;
2435var DOCUMENT_NODE = 9;
2436var DOCUMENT_FRAGMENT_NODE = 11;
2437
2438/**
2439 * Gets the target node from a native browser event by accounting for
2440 * inconsistencies in browser DOM APIs.
2441 *
2442 * @param {object} nativeEvent Native browser event.
2443 * @return {DOMEventTarget} Target node.
2444 */
2445function getEventTarget(nativeEvent) {
2446 // Fallback to nativeEvent.srcElement for IE9
2447 // https://github.com/facebook/react/issues/12506
2448 var target = nativeEvent.target || nativeEvent.srcElement || window;
2449
2450 // Normalize SVG <use> element events #4963
2451 if (target.correspondingUseElement) {
2452 target = target.correspondingUseElement;
2453 }
2454
2455 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2456 // @see http://www.quirksmode.org/js/events_properties.html
2457 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2458}
2459
2460/**
2461 * Checks if an event is supported in the current execution environment.
2462 *
2463 * NOTE: This will not work correctly for non-generic events such as `change`,
2464 * `reset`, `load`, `error`, and `select`.
2465 *
2466 * Borrows from Modernizr.
2467 *
2468 * @param {string} eventNameSuffix Event name, e.g. "click".
2469 * @return {boolean} True if the event is supported.
2470 * @internal
2471 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2472 */
2473function isEventSupported(eventNameSuffix) {
2474 if (!canUseDOM) {
2475 return false;
2476 }
2477
2478 var eventName = 'on' + eventNameSuffix;
2479 var isSupported = eventName in document;
2480
2481 if (!isSupported) {
2482 var element = document.createElement('div');
2483 element.setAttribute(eventName, 'return;');
2484 isSupported = typeof element[eventName] === 'function';
2485 }
2486
2487 return isSupported;
2488}
2489
2490function isCheckable(elem) {
2491 var type = elem.type;
2492 var nodeName = elem.nodeName;
2493 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2494}
2495
2496function getTracker(node) {
2497 return node._valueTracker;
2498}
2499
2500function detachTracker(node) {
2501 node._valueTracker = null;
2502}
2503
2504function getValueFromNode(node) {
2505 var value = '';
2506 if (!node) {
2507 return value;
2508 }
2509
2510 if (isCheckable(node)) {
2511 value = node.checked ? 'true' : 'false';
2512 } else {
2513 value = node.value;
2514 }
2515
2516 return value;
2517}
2518
2519function trackValueOnNode(node) {
2520 var valueField = isCheckable(node) ? 'checked' : 'value';
2521 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2522
2523 var currentValue = '' + node[valueField];
2524
2525 // if someone has already defined a value or Safari, then bail
2526 // and don't track value will cause over reporting of changes,
2527 // but it's better then a hard failure
2528 // (needed for certain tests that spyOn input values and Safari)
2529 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2530 return;
2531 }
2532 var get = descriptor.get,
2533 set = descriptor.set;
2534
2535 Object.defineProperty(node, valueField, {
2536 configurable: true,
2537 get: function () {
2538 return get.call(this);
2539 },
2540 set: function (value) {
2541 currentValue = '' + value;
2542 set.call(this, value);
2543 }
2544 });
2545 // We could've passed this the first time
2546 // but it triggers a bug in IE11 and Edge 14/15.
2547 // Calling defineProperty() again should be equivalent.
2548 // https://github.com/facebook/react/issues/11768
2549 Object.defineProperty(node, valueField, {
2550 enumerable: descriptor.enumerable
2551 });
2552
2553 var tracker = {
2554 getValue: function () {
2555 return currentValue;
2556 },
2557 setValue: function (value) {
2558 currentValue = '' + value;
2559 },
2560 stopTracking: function () {
2561 detachTracker(node);
2562 delete node[valueField];
2563 }
2564 };
2565 return tracker;
2566}
2567
2568function track(node) {
2569 if (getTracker(node)) {
2570 return;
2571 }
2572
2573 // TODO: Once it's just Fiber we can move this to node._wrapperState
2574 node._valueTracker = trackValueOnNode(node);
2575}
2576
2577function updateValueIfChanged(node) {
2578 if (!node) {
2579 return false;
2580 }
2581
2582 var tracker = getTracker(node);
2583 // if there is no tracker at this point it's unlikely
2584 // that trying again will succeed
2585 if (!tracker) {
2586 return true;
2587 }
2588
2589 var lastValue = tracker.getValue();
2590 var nextValue = getValueFromNode(node);
2591 if (nextValue !== lastValue) {
2592 tracker.setValue(nextValue);
2593 return true;
2594 }
2595 return false;
2596}
2597
2598var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2599
2600// Prevent newer renderers from RTE when used with older react package versions.
2601// Current owner and dispatcher used to share the same ref,
2602// but PR #14548 split them out to better support the react-debug-tools package.
2603if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
2604 ReactSharedInternals.ReactCurrentDispatcher = {
2605 current: null
2606 };
2607}
2608if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
2609 ReactSharedInternals.ReactCurrentBatchConfig = {
2610 suspense: null
2611 };
2612}
2613
2614var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
2615
2616var describeComponentFrame = function (name, source, ownerName) {
2617 var sourceInfo = '';
2618 if (source) {
2619 var path = source.fileName;
2620 var fileName = path.replace(BEFORE_SLASH_RE, '');
2621 {
2622 // In DEV, include code for a common special case:
2623 // prefer "folder/index.js" instead of just "index.js".
2624 if (/^index\./.test(fileName)) {
2625 var match = path.match(BEFORE_SLASH_RE);
2626 if (match) {
2627 var pathBeforeSlash = match[1];
2628 if (pathBeforeSlash) {
2629 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
2630 fileName = folderName + '/' + fileName;
2631 }
2632 }
2633 }
2634 }
2635 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
2636 } else if (ownerName) {
2637 sourceInfo = ' (created by ' + ownerName + ')';
2638 }
2639 return '\n in ' + (name || 'Unknown') + sourceInfo;
2640};
2641
2642// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2643// nor polyfill, then a plain number is used for performance.
2644var hasSymbol = typeof Symbol === 'function' && Symbol.for;
2645
2646var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
2647var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
2648var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
2649var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
2650var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
2651var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
2652var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
2653// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
2654// (unstable) APIs that have been removed. Can we remove the symbols?
2655
2656var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
2657var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
2658var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
2659var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
2660var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
2661var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
2662var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
2663var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
2664
2665var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2666var FAUX_ITERATOR_SYMBOL = '@@iterator';
2667
2668function getIteratorFn(maybeIterable) {
2669 if (maybeIterable === null || typeof maybeIterable !== 'object') {
2670 return null;
2671 }
2672 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2673 if (typeof maybeIterator === 'function') {
2674 return maybeIterator;
2675 }
2676 return null;
2677}
2678
2679var Pending = 0;
2680var Resolved = 1;
2681var Rejected = 2;
2682
2683function refineResolvedLazyComponent(lazyComponent) {
2684 return lazyComponent._status === Resolved ? lazyComponent._result : null;
2685}
2686
2687function getWrappedName(outerType, innerType, wrapperName) {
2688 var functionName = innerType.displayName || innerType.name || '';
2689 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
2690}
2691
2692function getComponentName(type) {
2693 if (type == null) {
2694 // Host root, text node or just invalid type.
2695 return null;
2696 }
2697 {
2698 if (typeof type.tag === 'number') {
2699 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
2700 }
2701 }
2702 if (typeof type === 'function') {
2703 return type.displayName || type.name || null;
2704 }
2705 if (typeof type === 'string') {
2706 return type;
2707 }
2708 switch (type) {
2709 case REACT_FRAGMENT_TYPE:
2710 return 'Fragment';
2711 case REACT_PORTAL_TYPE:
2712 return 'Portal';
2713 case REACT_PROFILER_TYPE:
2714 return 'Profiler';
2715 case REACT_STRICT_MODE_TYPE:
2716 return 'StrictMode';
2717 case REACT_SUSPENSE_TYPE:
2718 return 'Suspense';
2719 case REACT_SUSPENSE_LIST_TYPE:
2720 return 'SuspenseList';
2721 }
2722 if (typeof type === 'object') {
2723 switch (type.$$typeof) {
2724 case REACT_CONTEXT_TYPE:
2725 return 'Context.Consumer';
2726 case REACT_PROVIDER_TYPE:
2727 return 'Context.Provider';
2728 case REACT_FORWARD_REF_TYPE:
2729 return getWrappedName(type, type.render, 'ForwardRef');
2730 case REACT_MEMO_TYPE:
2731 return getComponentName(type.type);
2732 case REACT_LAZY_TYPE:
2733 {
2734 var thenable = type;
2735 var resolvedThenable = refineResolvedLazyComponent(thenable);
2736 if (resolvedThenable) {
2737 return getComponentName(resolvedThenable);
2738 }
2739 break;
2740 }
2741 }
2742 }
2743 return null;
2744}
2745
2746var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2747
2748function describeFiber(fiber) {
2749 switch (fiber.tag) {
2750 case HostRoot:
2751 case HostPortal:
2752 case HostText:
2753 case Fragment:
2754 case ContextProvider:
2755 case ContextConsumer:
2756 return '';
2757 default:
2758 var owner = fiber._debugOwner;
2759 var source = fiber._debugSource;
2760 var name = getComponentName(fiber.type);
2761 var ownerName = null;
2762 if (owner) {
2763 ownerName = getComponentName(owner.type);
2764 }
2765 return describeComponentFrame(name, source, ownerName);
2766 }
2767}
2768
2769function getStackByFiberInDevAndProd(workInProgress) {
2770 var info = '';
2771 var node = workInProgress;
2772 do {
2773 info += describeFiber(node);
2774 node = node.return;
2775 } while (node);
2776 return info;
2777}
2778
2779var current = null;
2780var phase = null;
2781
2782function getCurrentFiberOwnerNameInDevOrNull() {
2783 {
2784 if (current === null) {
2785 return null;
2786 }
2787 var owner = current._debugOwner;
2788 if (owner !== null && typeof owner !== 'undefined') {
2789 return getComponentName(owner.type);
2790 }
2791 }
2792 return null;
2793}
2794
2795function getCurrentFiberStackInDev() {
2796 {
2797 if (current === null) {
2798 return '';
2799 }
2800 // Safe because if current fiber exists, we are reconciling,
2801 // and it is guaranteed to be the work-in-progress version.
2802 return getStackByFiberInDevAndProd(current);
2803 }
2804 return '';
2805}
2806
2807function resetCurrentFiber() {
2808 {
2809 ReactDebugCurrentFrame.getCurrentStack = null;
2810 current = null;
2811 phase = null;
2812 }
2813}
2814
2815function setCurrentFiber(fiber) {
2816 {
2817 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
2818 current = fiber;
2819 phase = null;
2820 }
2821}
2822
2823function setCurrentPhase(lifeCyclePhase) {
2824 {
2825 phase = lifeCyclePhase;
2826 }
2827}
2828
2829/**
2830 * Similar to invariant but only logs a warning if the condition is not met.
2831 * This can be used to log issues in development environments in critical
2832 * paths. Removing the logging code for production environments will keep the
2833 * same logic and follow the same code paths.
2834 */
2835
2836var warning = warningWithoutStack$1;
2837
2838{
2839 warning = function (condition, format) {
2840 if (condition) {
2841 return;
2842 }
2843 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2844 var stack = ReactDebugCurrentFrame.getStackAddendum();
2845 // eslint-disable-next-line react-internal/warning-and-invariant-args
2846
2847 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
2848 args[_key - 2] = arguments[_key];
2849 }
2850
2851 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
2852 };
2853}
2854
2855var warning$1 = warning;
2856
2857// A reserved attribute.
2858// It is handled by React separately and shouldn't be written to the DOM.
2859var RESERVED = 0;
2860
2861// A simple string attribute.
2862// Attributes that aren't in the whitelist are presumed to have this type.
2863var STRING = 1;
2864
2865// A string attribute that accepts booleans in React. In HTML, these are called
2866// "enumerated" attributes with "true" and "false" as possible values.
2867// When true, it should be set to a "true" string.
2868// When false, it should be set to a "false" string.
2869var BOOLEANISH_STRING = 2;
2870
2871// A real boolean attribute.
2872// When true, it should be present (set either to an empty string or its name).
2873// When false, it should be omitted.
2874var BOOLEAN = 3;
2875
2876// An attribute that can be used as a flag as well as with a value.
2877// When true, it should be present (set either to an empty string or its name).
2878// When false, it should be omitted.
2879// For any other value, should be present with that value.
2880var OVERLOADED_BOOLEAN = 4;
2881
2882// An attribute that must be numeric or parse as a numeric.
2883// When falsy, it should be removed.
2884var NUMERIC = 5;
2885
2886// An attribute that must be positive numeric or parse as a positive numeric.
2887// When falsy, it should be removed.
2888var POSITIVE_NUMERIC = 6;
2889
2890/* eslint-disable max-len */
2891var 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';
2892/* eslint-enable max-len */
2893var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2894
2895
2896var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2897var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2898
2899var hasOwnProperty = Object.prototype.hasOwnProperty;
2900var illegalAttributeNameCache = {};
2901var validatedAttributeNameCache = {};
2902
2903function isAttributeNameSafe(attributeName) {
2904 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
2905 return true;
2906 }
2907 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
2908 return false;
2909 }
2910 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2911 validatedAttributeNameCache[attributeName] = true;
2912 return true;
2913 }
2914 illegalAttributeNameCache[attributeName] = true;
2915 {
2916 warning$1(false, 'Invalid attribute name: `%s`', attributeName);
2917 }
2918 return false;
2919}
2920
2921function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2922 if (propertyInfo !== null) {
2923 return propertyInfo.type === RESERVED;
2924 }
2925 if (isCustomComponentTag) {
2926 return false;
2927 }
2928 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2929 return true;
2930 }
2931 return false;
2932}
2933
2934function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2935 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2936 return false;
2937 }
2938 switch (typeof value) {
2939 case 'function':
2940 // $FlowIssue symbol is perfectly valid here
2941 case 'symbol':
2942 // eslint-disable-line
2943 return true;
2944 case 'boolean':
2945 {
2946 if (isCustomComponentTag) {
2947 return false;
2948 }
2949 if (propertyInfo !== null) {
2950 return !propertyInfo.acceptsBooleans;
2951 } else {
2952 var prefix = name.toLowerCase().slice(0, 5);
2953 return prefix !== 'data-' && prefix !== 'aria-';
2954 }
2955 }
2956 default:
2957 return false;
2958 }
2959}
2960
2961function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2962 if (value === null || typeof value === 'undefined') {
2963 return true;
2964 }
2965 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2966 return true;
2967 }
2968 if (isCustomComponentTag) {
2969 return false;
2970 }
2971 if (propertyInfo !== null) {
2972 switch (propertyInfo.type) {
2973 case BOOLEAN:
2974 return !value;
2975 case OVERLOADED_BOOLEAN:
2976 return value === false;
2977 case NUMERIC:
2978 return isNaN(value);
2979 case POSITIVE_NUMERIC:
2980 return isNaN(value) || value < 1;
2981 }
2982 }
2983 return false;
2984}
2985
2986function getPropertyInfo(name) {
2987 return properties.hasOwnProperty(name) ? properties[name] : null;
2988}
2989
2990function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL) {
2991 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2992 this.attributeName = attributeName;
2993 this.attributeNamespace = attributeNamespace;
2994 this.mustUseProperty = mustUseProperty;
2995 this.propertyName = name;
2996 this.type = type;
2997 this.sanitizeURL = sanitizeURL;
2998}
2999
3000// When adding attributes to this list, be sure to also add them to
3001// the `possibleStandardNames` module to ensure casing and incorrect
3002// name warnings.
3003var properties = {};
3004
3005// These props are reserved by React. They shouldn't be written to the DOM.
3006['children', 'dangerouslySetInnerHTML',
3007// TODO: This prevents the assignment of defaultValue to regular
3008// elements (not just inputs). Now that ReactDOMInput assigns to the
3009// defaultValue property -- do we need this?
3010'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
3011 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
3012 name, // attributeName
3013 null, // attributeNamespace
3014 false);
3015} // sanitizeURL
3016);
3017
3018// A few React string attributes have a different name.
3019// This is a mapping from React prop names to the attribute names.
3020[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
3021 var name = _ref[0],
3022 attributeName = _ref[1];
3023
3024 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
3025 attributeName, // attributeName
3026 null, // attributeNamespace
3027 false);
3028} // sanitizeURL
3029);
3030
3031// These are "enumerated" HTML attributes that accept "true" and "false".
3032// In React, we let users pass `true` and `false` even though technically
3033// these aren't boolean attributes (they are coerced to strings).
3034['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
3035 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
3036 name.toLowerCase(), // attributeName
3037 null, // attributeNamespace
3038 false);
3039} // sanitizeURL
3040);
3041
3042// These are "enumerated" SVG attributes that accept "true" and "false".
3043// In React, we let users pass `true` and `false` even though technically
3044// these aren't boolean attributes (they are coerced to strings).
3045// Since these are SVG attributes, their attribute names are case-sensitive.
3046['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
3047 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
3048 name, // attributeName
3049 null, // attributeNamespace
3050 false);
3051} // sanitizeURL
3052);
3053
3054// These are HTML boolean attributes.
3055['allowFullScreen', 'async',
3056// Note: there is a special case that prevents it from being written to the DOM
3057// on the client side because the browsers are inconsistent. Instead we call focus().
3058'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
3059// Microdata
3060'itemScope'].forEach(function (name) {
3061 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
3062 name.toLowerCase(), // attributeName
3063 null, // attributeNamespace
3064 false);
3065} // sanitizeURL
3066);
3067
3068// These are the few React props that we set as DOM properties
3069// rather than attributes. These are all booleans.
3070['checked',
3071// Note: `option.selected` is not updated if `select.multiple` is
3072// disabled with `removeAttribute`. We have special logic for handling this.
3073'multiple', 'muted', 'selected'].forEach(function (name) {
3074 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
3075 name, // attributeName
3076 null, // attributeNamespace
3077 false);
3078} // sanitizeURL
3079);
3080
3081// These are HTML attributes that are "overloaded booleans": they behave like
3082// booleans, but can also accept a string value.
3083['capture', 'download'].forEach(function (name) {
3084 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
3085 name, // attributeName
3086 null, // attributeNamespace
3087 false);
3088} // sanitizeURL
3089);
3090
3091// These are HTML attributes that must be positive numbers.
3092['cols', 'rows', 'size', 'span'].forEach(function (name) {
3093 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
3094 name, // attributeName
3095 null, // attributeNamespace
3096 false);
3097} // sanitizeURL
3098);
3099
3100// These are HTML attributes that must be numbers.
3101['rowSpan', 'start'].forEach(function (name) {
3102 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
3103 name.toLowerCase(), // attributeName
3104 null, // attributeNamespace
3105 false);
3106} // sanitizeURL
3107);
3108
3109var CAMELIZE = /[\-\:]([a-z])/g;
3110var capitalize = function (token) {
3111 return token[1].toUpperCase();
3112};
3113
3114// This is a list of all SVG attributes that need special casing, namespacing,
3115// or boolean value assignment. Regular attributes that just accept strings
3116// and have the same names are omitted, just like in the HTML whitelist.
3117// Some of these attributes can be hard to find. This list was created by
3118// scrapping the MDN documentation.
3119['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'].forEach(function (attributeName) {
3120 var name = attributeName.replace(CAMELIZE, capitalize);
3121 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
3122 attributeName, null, // attributeNamespace
3123 false);
3124} // sanitizeURL
3125);
3126
3127// String SVG attributes with the xlink namespace.
3128['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
3129 var name = attributeName.replace(CAMELIZE, capitalize);
3130 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
3131 attributeName, 'http://www.w3.org/1999/xlink', false);
3132} // sanitizeURL
3133);
3134
3135// String SVG attributes with the xml namespace.
3136['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
3137 var name = attributeName.replace(CAMELIZE, capitalize);
3138 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
3139 attributeName, 'http://www.w3.org/XML/1998/namespace', false);
3140} // sanitizeURL
3141);
3142
3143// These attribute exists both in HTML and SVG.
3144// The attribute name is case-sensitive in SVG so we can't just use
3145// the React name like we do for attributes that exist only in HTML.
3146['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
3147 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
3148 attributeName.toLowerCase(), // attributeName
3149 null, // attributeNamespace
3150 false);
3151} // sanitizeURL
3152);
3153
3154// These attributes accept URLs. These must not allow javascript: URLS.
3155// These will also need to accept Trusted Types object in the future.
3156var xlinkHref = 'xlinkHref';
3157properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
3158'xlink:href', 'http://www.w3.org/1999/xlink', true);
3159
3160['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
3161 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
3162 attributeName.toLowerCase(), // attributeName
3163 null, // attributeNamespace
3164 true);
3165} // sanitizeURL
3166);
3167
3168var ReactDebugCurrentFrame$1 = null;
3169{
3170 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
3171}
3172
3173// A javascript: URL can contain leading C0 control or \u0020 SPACE,
3174// and any newline or tab are filtered out as if they're not part of the URL.
3175// https://url.spec.whatwg.org/#url-parsing
3176// Tab or newline are defined as \r\n\t:
3177// https://infra.spec.whatwg.org/#ascii-tab-or-newline
3178// A C0 control is a code point in the range \u0000 NULL to \u001F
3179// INFORMATION SEPARATOR ONE, inclusive:
3180// https://infra.spec.whatwg.org/#c0-control-or-space
3181
3182/* eslint-disable max-len */
3183var 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;
3184
3185var didWarn = false;
3186
3187function sanitizeURL(url) {
3188 if (disableJavaScriptURLs) {
3189 (function () {
3190 if (!!isJavaScriptProtocol.test(url)) {
3191 {
3192 throw ReactError(Error('React has blocked a javascript: URL as a security precaution.' + (ReactDebugCurrentFrame$1.getStackAddendum())));
3193 }
3194 }
3195 })();
3196 } else if (true && !didWarn && isJavaScriptProtocol.test(url)) {
3197 didWarn = true;
3198 warning$1(false, '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));
3199 }
3200}
3201
3202/**
3203 * Get the value for a property on a node. Only used in DEV for SSR validation.
3204 * The "expected" argument is used as a hint of what the expected value is.
3205 * Some properties have multiple equivalent values.
3206 */
3207function getValueForProperty(node, name, expected, propertyInfo) {
3208 {
3209 if (propertyInfo.mustUseProperty) {
3210 var propertyName = propertyInfo.propertyName;
3211
3212 return node[propertyName];
3213 } else {
3214 if (!disableJavaScriptURLs && propertyInfo.sanitizeURL) {
3215 // If we haven't fully disabled javascript: URLs, and if
3216 // the hydration is successful of a javascript: URL, we
3217 // still want to warn on the client.
3218 sanitizeURL('' + expected);
3219 }
3220
3221 var attributeName = propertyInfo.attributeName;
3222
3223 var stringValue = null;
3224
3225 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
3226 if (node.hasAttribute(attributeName)) {
3227 var value = node.getAttribute(attributeName);
3228 if (value === '') {
3229 return true;
3230 }
3231 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
3232 return value;
3233 }
3234 if (value === '' + expected) {
3235 return expected;
3236 }
3237 return value;
3238 }
3239 } else if (node.hasAttribute(attributeName)) {
3240 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
3241 // We had an attribute but shouldn't have had one, so read it
3242 // for the error message.
3243 return node.getAttribute(attributeName);
3244 }
3245 if (propertyInfo.type === BOOLEAN) {
3246 // If this was a boolean, it doesn't matter what the value is
3247 // the fact that we have it is the same as the expected.
3248 return expected;
3249 }
3250 // Even if this property uses a namespace we use getAttribute
3251 // because we assume its namespaced name is the same as our config.
3252 // To use getAttributeNS we need the local name which we don't have
3253 // in our config atm.
3254 stringValue = node.getAttribute(attributeName);
3255 }
3256
3257 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
3258 return stringValue === null ? expected : stringValue;
3259 } else if (stringValue === '' + expected) {
3260 return expected;
3261 } else {
3262 return stringValue;
3263 }
3264 }
3265 }
3266}
3267
3268/**
3269 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
3270 * The third argument is used as a hint of what the expected value is. Some
3271 * attributes have multiple equivalent values.
3272 */
3273function getValueForAttribute(node, name, expected) {
3274 {
3275 if (!isAttributeNameSafe(name)) {
3276 return;
3277 }
3278 if (!node.hasAttribute(name)) {
3279 return expected === undefined ? undefined : null;
3280 }
3281 var value = node.getAttribute(name);
3282 if (value === '' + expected) {
3283 return expected;
3284 }
3285 return value;
3286 }
3287}
3288
3289/**
3290 * Sets the value for a property on a node.
3291 *
3292 * @param {DOMElement} node
3293 * @param {string} name
3294 * @param {*} value
3295 */
3296function setValueForProperty(node, name, value, isCustomComponentTag) {
3297 var propertyInfo = getPropertyInfo(name);
3298 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
3299 return;
3300 }
3301 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
3302 value = null;
3303 }
3304 // If the prop isn't in the special list, treat it as a simple attribute.
3305 if (isCustomComponentTag || propertyInfo === null) {
3306 if (isAttributeNameSafe(name)) {
3307 var _attributeName = name;
3308 if (value === null) {
3309 node.removeAttribute(_attributeName);
3310 } else {
3311 node.setAttribute(_attributeName, '' + value);
3312 }
3313 }
3314 return;
3315 }
3316 var mustUseProperty = propertyInfo.mustUseProperty;
3317
3318 if (mustUseProperty) {
3319 var propertyName = propertyInfo.propertyName;
3320
3321 if (value === null) {
3322 var type = propertyInfo.type;
3323
3324 node[propertyName] = type === BOOLEAN ? false : '';
3325 } else {
3326 // Contrary to `setAttribute`, object properties are properly
3327 // `toString`ed by IE8/9.
3328 node[propertyName] = value;
3329 }
3330 return;
3331 }
3332 // The rest are treated as attributes with special cases.
3333 var attributeName = propertyInfo.attributeName,
3334 attributeNamespace = propertyInfo.attributeNamespace;
3335
3336 if (value === null) {
3337 node.removeAttribute(attributeName);
3338 } else {
3339 var _type = propertyInfo.type;
3340
3341 var attributeValue = void 0;
3342 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
3343 attributeValue = '';
3344 } else {
3345 // `setAttribute` with objects becomes only `[object]` in IE8/9,
3346 // ('' + value) makes it output the correct toString()-value.
3347 attributeValue = '' + value;
3348 if (propertyInfo.sanitizeURL) {
3349 sanitizeURL(attributeValue);
3350 }
3351 }
3352 if (attributeNamespace) {
3353 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
3354 } else {
3355 node.setAttribute(attributeName, attributeValue);
3356 }
3357 }
3358}
3359
3360// Flow does not allow string concatenation of most non-string types. To work
3361// around this limitation, we use an opaque type that can only be obtained by
3362// passing the value through getToStringValue first.
3363function toString(value) {
3364 return '' + value;
3365}
3366
3367function getToStringValue(value) {
3368 switch (typeof value) {
3369 case 'boolean':
3370 case 'number':
3371 case 'object':
3372 case 'string':
3373 case 'undefined':
3374 return value;
3375 default:
3376 // function, symbol are assigned as empty strings
3377 return '';
3378 }
3379}
3380
3381/**
3382 * Copyright (c) 2013-present, Facebook, Inc.
3383 *
3384 * This source code is licensed under the MIT license found in the
3385 * LICENSE file in the root directory of this source tree.
3386 */
3387
3388
3389
3390var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
3391
3392var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
3393
3394/**
3395 * Copyright (c) 2013-present, Facebook, Inc.
3396 *
3397 * This source code is licensed under the MIT license found in the
3398 * LICENSE file in the root directory of this source tree.
3399 */
3400
3401
3402
3403var printWarning = function() {};
3404
3405{
3406 var ReactPropTypesSecret = ReactPropTypesSecret_1;
3407 var loggedTypeFailures = {};
3408
3409 printWarning = function(text) {
3410 var message = 'Warning: ' + text;
3411 if (typeof console !== 'undefined') {
3412 console.error(message);
3413 }
3414 try {
3415 // --- Welcome to debugging React ---
3416 // This error was thrown as a convenience so that you can use this stack
3417 // to find the callsite that caused this warning to fire.
3418 throw new Error(message);
3419 } catch (x) {}
3420 };
3421}
3422
3423/**
3424 * Assert that the values match with the type specs.
3425 * Error messages are memorized and will only be shown once.
3426 *
3427 * @param {object} typeSpecs Map of name to a ReactPropType
3428 * @param {object} values Runtime values that need to be type-checked
3429 * @param {string} location e.g. "prop", "context", "child context"
3430 * @param {string} componentName Name of the component for error messages.
3431 * @param {?Function} getStack Returns the component stack.
3432 * @private
3433 */
3434function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
3435 {
3436 for (var typeSpecName in typeSpecs) {
3437 if (typeSpecs.hasOwnProperty(typeSpecName)) {
3438 var error;
3439 // Prop type validation may throw. In case they do, we don't want to
3440 // fail the render phase where it didn't fail before. So we log it.
3441 // After these have been cleaned up, we'll let them throw.
3442 try {
3443 // This is intentionally an invariant that gets caught. It's the same
3444 // behavior as without this statement except with a better message.
3445 if (typeof typeSpecs[typeSpecName] !== 'function') {
3446 var err = Error(
3447 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
3448 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
3449 );
3450 err.name = 'Invariant Violation';
3451 throw err;
3452 }
3453 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
3454 } catch (ex) {
3455 error = ex;
3456 }
3457 if (error && !(error instanceof Error)) {
3458 printWarning(
3459 (componentName || 'React class') + ': type specification of ' +
3460 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
3461 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
3462 'You may have forgotten to pass an argument to the type checker ' +
3463 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
3464 'shape all require an argument).'
3465 );
3466
3467 }
3468 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
3469 // Only monitor this failure once because there tends to be a lot of the
3470 // same error.
3471 loggedTypeFailures[error.message] = true;
3472
3473 var stack = getStack ? getStack() : '';
3474
3475 printWarning(
3476 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
3477 );
3478 }
3479 }
3480 }
3481 }
3482}
3483
3484var checkPropTypes_1 = checkPropTypes;
3485
3486var ReactDebugCurrentFrame$2 = null;
3487
3488var ReactControlledValuePropTypes = {
3489 checkPropTypes: null
3490};
3491
3492{
3493 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
3494
3495 var hasReadOnlyValue = {
3496 button: true,
3497 checkbox: true,
3498 image: true,
3499 hidden: true,
3500 radio: true,
3501 reset: true,
3502 submit: true
3503 };
3504
3505 var propTypes = {
3506 value: function (props, propName, componentName) {
3507 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null || enableFlareAPI && props.listeners) {
3508 return null;
3509 }
3510 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`.');
3511 },
3512 checked: function (props, propName, componentName) {
3513 if (props.onChange || props.readOnly || props.disabled || props[propName] == null || enableFlareAPI && props.listeners) {
3514 return null;
3515 }
3516 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`.');
3517 }
3518 };
3519
3520 /**
3521 * Provide a linked `value` attribute for controlled forms. You should not use
3522 * this outside of the ReactDOM controlled form components.
3523 */
3524 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
3525 checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$2.getStackAddendum);
3526 };
3527}
3528
3529// TODO: direct imports like some-package/src/* are bad. Fix me.
3530var didWarnValueDefaultValue = false;
3531var didWarnCheckedDefaultChecked = false;
3532var didWarnControlledToUncontrolled = false;
3533var didWarnUncontrolledToControlled = false;
3534
3535function isControlled(props) {
3536 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3537 return usesChecked ? props.checked != null : props.value != null;
3538}
3539
3540/**
3541 * Implements an <input> host component that allows setting these optional
3542 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3543 *
3544 * If `checked` or `value` are not supplied (or null/undefined), user actions
3545 * that affect the checked state or value will trigger updates to the element.
3546 *
3547 * If they are supplied (and not null/undefined), the rendered element will not
3548 * trigger updates to the element. Instead, the props must change in order for
3549 * the rendered element to be updated.
3550 *
3551 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3552 * with an empty value (or `defaultValue`).
3553 *
3554 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3555 */
3556
3557function getHostProps(element, props) {
3558 var node = element;
3559 var checked = props.checked;
3560
3561 var hostProps = _assign({}, props, {
3562 defaultChecked: undefined,
3563 defaultValue: undefined,
3564 value: undefined,
3565 checked: checked != null ? checked : node._wrapperState.initialChecked
3566 });
3567
3568 return hostProps;
3569}
3570
3571function initWrapperState(element, props) {
3572 {
3573 ReactControlledValuePropTypes.checkPropTypes('input', props);
3574
3575 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3576 warning$1(false, '%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);
3577 didWarnCheckedDefaultChecked = true;
3578 }
3579 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3580 warning$1(false, '%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);
3581 didWarnValueDefaultValue = true;
3582 }
3583 }
3584
3585 var node = element;
3586 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3587
3588 node._wrapperState = {
3589 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3590 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
3591 controlled: isControlled(props)
3592 };
3593}
3594
3595function updateChecked(element, props) {
3596 var node = element;
3597 var checked = props.checked;
3598 if (checked != null) {
3599 setValueForProperty(node, 'checked', checked, false);
3600 }
3601}
3602
3603function updateWrapper(element, props) {
3604 var node = element;
3605 {
3606 var _controlled = isControlled(props);
3607
3608 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3609 warning$1(false, '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);
3610 didWarnUncontrolledToControlled = true;
3611 }
3612 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3613 warning$1(false, '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);
3614 didWarnControlledToUncontrolled = true;
3615 }
3616 }
3617
3618 updateChecked(element, props);
3619
3620 var value = getToStringValue(props.value);
3621 var type = props.type;
3622
3623 if (value != null) {
3624 if (type === 'number') {
3625 if (value === 0 && node.value === '' ||
3626 // We explicitly want to coerce to number here if possible.
3627 // eslint-disable-next-line
3628 node.value != value) {
3629 node.value = toString(value);
3630 }
3631 } else if (node.value !== toString(value)) {
3632 node.value = toString(value);
3633 }
3634 } else if (type === 'submit' || type === 'reset') {
3635 // Submit/reset inputs need the attribute removed completely to avoid
3636 // blank-text buttons.
3637 node.removeAttribute('value');
3638 return;
3639 }
3640
3641 if (disableInputAttributeSyncing) {
3642 // When not syncing the value attribute, React only assigns a new value
3643 // whenever the defaultValue React prop has changed. When not present,
3644 // React does nothing
3645 if (props.hasOwnProperty('defaultValue')) {
3646 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3647 }
3648 } else {
3649 // When syncing the value attribute, the value comes from a cascade of
3650 // properties:
3651 // 1. The value React property
3652 // 2. The defaultValue React property
3653 // 3. Otherwise there should be no change
3654 if (props.hasOwnProperty('value')) {
3655 setDefaultValue(node, props.type, value);
3656 } else if (props.hasOwnProperty('defaultValue')) {
3657 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3658 }
3659 }
3660
3661 if (disableInputAttributeSyncing) {
3662 // When not syncing the checked attribute, the attribute is directly
3663 // controllable from the defaultValue React property. It needs to be
3664 // updated as new props come in.
3665 if (props.defaultChecked == null) {
3666 node.removeAttribute('checked');
3667 } else {
3668 node.defaultChecked = !!props.defaultChecked;
3669 }
3670 } else {
3671 // When syncing the checked attribute, it only changes when it needs
3672 // to be removed, such as transitioning from a checkbox into a text input
3673 if (props.checked == null && props.defaultChecked != null) {
3674 node.defaultChecked = !!props.defaultChecked;
3675 }
3676 }
3677}
3678
3679function postMountWrapper(element, props, isHydrating) {
3680 var node = element;
3681
3682 // Do not assign value if it is already set. This prevents user text input
3683 // from being lost during SSR hydration.
3684 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3685 var type = props.type;
3686 var isButton = type === 'submit' || type === 'reset';
3687
3688 // Avoid setting value attribute on submit/reset inputs as it overrides the
3689 // default value provided by the browser. See: #12872
3690 if (isButton && (props.value === undefined || props.value === null)) {
3691 return;
3692 }
3693
3694 var _initialValue = toString(node._wrapperState.initialValue);
3695
3696 // Do not assign value if it is already set. This prevents user text input
3697 // from being lost during SSR hydration.
3698 if (!isHydrating) {
3699 if (disableInputAttributeSyncing) {
3700 var value = getToStringValue(props.value);
3701
3702 // When not syncing the value attribute, the value property points
3703 // directly to the React prop. Only assign it if it exists.
3704 if (value != null) {
3705 // Always assign on buttons so that it is possible to assign an
3706 // empty string to clear button text.
3707 //
3708 // Otherwise, do not re-assign the value property if is empty. This
3709 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
3710 // prematurely marking required inputs as invalid. Equality is compared
3711 // to the current value in case the browser provided value is not an
3712 // empty string.
3713 if (isButton || value !== node.value) {
3714 node.value = toString(value);
3715 }
3716 }
3717 } else {
3718 // When syncing the value attribute, the value property should use
3719 // the wrapperState._initialValue property. This uses:
3720 //
3721 // 1. The value React property when present
3722 // 2. The defaultValue React property when present
3723 // 3. An empty string
3724 if (_initialValue !== node.value) {
3725 node.value = _initialValue;
3726 }
3727 }
3728 }
3729
3730 if (disableInputAttributeSyncing) {
3731 // When not syncing the value attribute, assign the value attribute
3732 // directly from the defaultValue React property (when present)
3733 var defaultValue = getToStringValue(props.defaultValue);
3734 if (defaultValue != null) {
3735 node.defaultValue = toString(defaultValue);
3736 }
3737 } else {
3738 // Otherwise, the value attribute is synchronized to the property,
3739 // so we assign defaultValue to the same thing as the value property
3740 // assignment step above.
3741 node.defaultValue = _initialValue;
3742 }
3743 }
3744
3745 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3746 // this is needed to work around a chrome bug where setting defaultChecked
3747 // will sometimes influence the value of checked (even after detachment).
3748 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3749 // We need to temporarily unset name to avoid disrupting radio button groups.
3750 var name = node.name;
3751 if (name !== '') {
3752 node.name = '';
3753 }
3754
3755 if (disableInputAttributeSyncing) {
3756 // When not syncing the checked attribute, the checked property
3757 // never gets assigned. It must be manually set. We don't want
3758 // to do this when hydrating so that existing user input isn't
3759 // modified
3760 if (!isHydrating) {
3761 updateChecked(element, props);
3762 }
3763
3764 // Only assign the checked attribute if it is defined. This saves
3765 // a DOM write when controlling the checked attribute isn't needed
3766 // (text inputs, submit/reset)
3767 if (props.hasOwnProperty('defaultChecked')) {
3768 node.defaultChecked = !node.defaultChecked;
3769 node.defaultChecked = !!props.defaultChecked;
3770 }
3771 } else {
3772 // When syncing the checked attribute, both the checked property and
3773 // attribute are assigned at the same time using defaultChecked. This uses:
3774 //
3775 // 1. The checked React property when present
3776 // 2. The defaultChecked React property when present
3777 // 3. Otherwise, false
3778 node.defaultChecked = !node.defaultChecked;
3779 node.defaultChecked = !!node._wrapperState.initialChecked;
3780 }
3781
3782 if (name !== '') {
3783 node.name = name;
3784 }
3785}
3786
3787function restoreControlledState(element, props) {
3788 var node = element;
3789 updateWrapper(node, props);
3790 updateNamedCousins(node, props);
3791}
3792
3793function updateNamedCousins(rootNode, props) {
3794 var name = props.name;
3795 if (props.type === 'radio' && name != null) {
3796 var queryRoot = rootNode;
3797
3798 while (queryRoot.parentNode) {
3799 queryRoot = queryRoot.parentNode;
3800 }
3801
3802 // If `rootNode.form` was non-null, then we could try `form.elements`,
3803 // but that sometimes behaves strangely in IE8. We could also try using
3804 // `form.getElementsByName`, but that will only return direct children
3805 // and won't include inputs that use the HTML5 `form=` attribute. Since
3806 // the input might not even be in a form. It might not even be in the
3807 // document. Let's just use the local `querySelectorAll` to ensure we don't
3808 // miss anything.
3809 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3810
3811 for (var i = 0; i < group.length; i++) {
3812 var otherNode = group[i];
3813 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3814 continue;
3815 }
3816 // This will throw if radio buttons rendered by different copies of React
3817 // and the same name are rendered into the same form (same as #1939).
3818 // That's probably okay; we don't support it just as we don't support
3819 // mixing React radio buttons with non-React ones.
3820 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3821 (function () {
3822 if (!otherProps) {
3823 {
3824 throw ReactError(Error('ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.'));
3825 }
3826 }
3827 })();
3828
3829 // We need update the tracked value on the named cousin since the value
3830 // was changed but the input saw no event or value set
3831 updateValueIfChanged(otherNode);
3832
3833 // If this is a controlled radio button group, forcing the input that
3834 // was previously checked to update will cause it to be come re-checked
3835 // as appropriate.
3836 updateWrapper(otherNode, otherProps);
3837 }
3838 }
3839}
3840
3841// In Chrome, assigning defaultValue to certain input types triggers input validation.
3842// For number inputs, the display value loses trailing decimal points. For email inputs,
3843// Chrome raises "The specified value <x> is not a valid email address".
3844//
3845// Here we check to see if the defaultValue has actually changed, avoiding these problems
3846// when the user is inputting text
3847//
3848// https://github.com/facebook/react/issues/7253
3849function setDefaultValue(node, type, value) {
3850 if (
3851 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3852 type !== 'number' || node.ownerDocument.activeElement !== node) {
3853 if (value == null) {
3854 node.defaultValue = toString(node._wrapperState.initialValue);
3855 } else if (node.defaultValue !== toString(value)) {
3856 node.defaultValue = toString(value);
3857 }
3858 }
3859}
3860
3861var eventTypes$1 = {
3862 change: {
3863 phasedRegistrationNames: {
3864 bubbled: 'onChange',
3865 captured: 'onChangeCapture'
3866 },
3867 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
3868 }
3869};
3870
3871function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3872 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3873 event.type = 'change';
3874 // Flag this event loop as needing state restore.
3875 enqueueStateRestore(target);
3876 accumulateTwoPhaseDispatches(event);
3877 return event;
3878}
3879/**
3880 * For IE shims
3881 */
3882var activeElement = null;
3883var activeElementInst = null;
3884
3885/**
3886 * SECTION: handle `change` event
3887 */
3888function shouldUseChangeEvent(elem) {
3889 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3890 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3891}
3892
3893function manualDispatchChangeEvent(nativeEvent) {
3894 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3895
3896 // If change and propertychange bubbled, we'd just bind to it like all the
3897 // other events and have it go through ReactBrowserEventEmitter. Since it
3898 // doesn't, we manually listen for the events and so we have to enqueue and
3899 // process the abstract event manually.
3900 //
3901 // Batching is necessary here in order to ensure that all event handlers run
3902 // before the next rerender (including event handlers attached to ancestor
3903 // elements instead of directly on the input). Without this, controlled
3904 // components don't work properly in conjunction with event bubbling because
3905 // the component is rerendered and the value reverted before all the event
3906 // handlers can run. See https://github.com/facebook/react/issues/708.
3907 batchedUpdates(runEventInBatch, event);
3908}
3909
3910function runEventInBatch(event) {
3911 runEventsInBatch(event);
3912}
3913
3914function getInstIfValueChanged(targetInst) {
3915 var targetNode = getNodeFromInstance$1(targetInst);
3916 if (updateValueIfChanged(targetNode)) {
3917 return targetInst;
3918 }
3919}
3920
3921function getTargetInstForChangeEvent(topLevelType, targetInst) {
3922 if (topLevelType === TOP_CHANGE) {
3923 return targetInst;
3924 }
3925}
3926
3927/**
3928 * SECTION: handle `input` event
3929 */
3930var isInputEventSupported = false;
3931if (canUseDOM) {
3932 // IE9 claims to support the input event but fails to trigger it when
3933 // deleting text, so we ignore its input events.
3934 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3935}
3936
3937/**
3938 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3939 * and override the value property so that we can distinguish user events from
3940 * value changes in JS.
3941 */
3942function startWatchingForValueChange(target, targetInst) {
3943 activeElement = target;
3944 activeElementInst = targetInst;
3945 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3946}
3947
3948/**
3949 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3950 * if any exists.
3951 */
3952function stopWatchingForValueChange() {
3953 if (!activeElement) {
3954 return;
3955 }
3956 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3957 activeElement = null;
3958 activeElementInst = null;
3959}
3960
3961/**
3962 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3963 * the value of the active element has changed.
3964 */
3965function handlePropertyChange(nativeEvent) {
3966 if (nativeEvent.propertyName !== 'value') {
3967 return;
3968 }
3969 if (getInstIfValueChanged(activeElementInst)) {
3970 manualDispatchChangeEvent(nativeEvent);
3971 }
3972}
3973
3974function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3975 if (topLevelType === TOP_FOCUS) {
3976 // In IE9, propertychange fires for most input events but is buggy and
3977 // doesn't fire when text is deleted, but conveniently, selectionchange
3978 // appears to fire in all of the remaining cases so we catch those and
3979 // forward the event if the value has changed
3980 // In either case, we don't want to call the event handler if the value
3981 // is changed from JS so we redefine a setter for `.value` that updates
3982 // our activeElementValue variable, allowing us to ignore those changes
3983 //
3984 // stopWatching() should be a noop here but we call it just in case we
3985 // missed a blur event somehow.
3986 stopWatchingForValueChange();
3987 startWatchingForValueChange(target, targetInst);
3988 } else if (topLevelType === TOP_BLUR) {
3989 stopWatchingForValueChange();
3990 }
3991}
3992
3993// For IE8 and IE9.
3994function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3995 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
3996 // On the selectionchange event, the target is just document which isn't
3997 // helpful for us so just check activeElement instead.
3998 //
3999 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
4000 // propertychange on the first input event after setting `value` from a
4001 // script and fires only keydown, keypress, keyup. Catching keyup usually
4002 // gets it and catching keydown lets us fire an event for the first
4003 // keystroke if user does a key repeat (it'll be a little delayed: right
4004 // before the second keystroke). Other input methods (e.g., paste) seem to
4005 // fire selectionchange normally.
4006 return getInstIfValueChanged(activeElementInst);
4007 }
4008}
4009
4010/**
4011 * SECTION: handle `click` event
4012 */
4013function shouldUseClickEvent(elem) {
4014 // Use the `click` event to detect changes to checkbox and radio inputs.
4015 // This approach works across all browsers, whereas `change` does not fire
4016 // until `blur` in IE8.
4017 var nodeName = elem.nodeName;
4018 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
4019}
4020
4021function getTargetInstForClickEvent(topLevelType, targetInst) {
4022 if (topLevelType === TOP_CLICK) {
4023 return getInstIfValueChanged(targetInst);
4024 }
4025}
4026
4027function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
4028 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
4029 return getInstIfValueChanged(targetInst);
4030 }
4031}
4032
4033function handleControlledInputBlur(node) {
4034 var state = node._wrapperState;
4035
4036 if (!state || !state.controlled || node.type !== 'number') {
4037 return;
4038 }
4039
4040 if (!disableInputAttributeSyncing) {
4041 // If controlled, assign the value attribute to the current value on blur
4042 setDefaultValue(node, 'number', node.value);
4043 }
4044}
4045
4046/**
4047 * This plugin creates an `onChange` event that normalizes change events
4048 * across form elements. This event fires at a time when it's possible to
4049 * change the element's value without seeing a flicker.
4050 *
4051 * Supported elements are:
4052 * - input (see `isTextInputElement`)
4053 * - textarea
4054 * - select
4055 */
4056var ChangeEventPlugin = {
4057 eventTypes: eventTypes$1,
4058
4059 _isInputEventSupported: isInputEventSupported,
4060
4061 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4062 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
4063
4064 var getTargetInstFunc = void 0,
4065 handleEventFunc = void 0;
4066 if (shouldUseChangeEvent(targetNode)) {
4067 getTargetInstFunc = getTargetInstForChangeEvent;
4068 } else if (isTextInputElement(targetNode)) {
4069 if (isInputEventSupported) {
4070 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
4071 } else {
4072 getTargetInstFunc = getTargetInstForInputEventPolyfill;
4073 handleEventFunc = handleEventsForInputEventPolyfill;
4074 }
4075 } else if (shouldUseClickEvent(targetNode)) {
4076 getTargetInstFunc = getTargetInstForClickEvent;
4077 }
4078
4079 if (getTargetInstFunc) {
4080 var inst = getTargetInstFunc(topLevelType, targetInst);
4081 if (inst) {
4082 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
4083 return event;
4084 }
4085 }
4086
4087 if (handleEventFunc) {
4088 handleEventFunc(topLevelType, targetNode, targetInst);
4089 }
4090
4091 // When blurring, set the value attribute for number inputs
4092 if (topLevelType === TOP_BLUR) {
4093 handleControlledInputBlur(targetNode);
4094 }
4095 }
4096};
4097
4098/**
4099 * Module that is injectable into `EventPluginHub`, that specifies a
4100 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
4101 * plugins, without having to package every one of them. This is better than
4102 * having plugins be ordered in the same order that they are injected because
4103 * that ordering would be influenced by the packaging order.
4104 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
4105 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
4106 */
4107var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
4108
4109var SyntheticUIEvent = SyntheticEvent.extend({
4110 view: null,
4111 detail: null
4112});
4113
4114var modifierKeyToProp = {
4115 Alt: 'altKey',
4116 Control: 'ctrlKey',
4117 Meta: 'metaKey',
4118 Shift: 'shiftKey'
4119};
4120
4121// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
4122// getModifierState. If getModifierState is not supported, we map it to a set of
4123// modifier keys exposed by the event. In this case, Lock-keys are not supported.
4124/**
4125 * Translation from modifier key to the associated property in the event.
4126 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
4127 */
4128
4129function modifierStateGetter(keyArg) {
4130 var syntheticEvent = this;
4131 var nativeEvent = syntheticEvent.nativeEvent;
4132 if (nativeEvent.getModifierState) {
4133 return nativeEvent.getModifierState(keyArg);
4134 }
4135 var keyProp = modifierKeyToProp[keyArg];
4136 return keyProp ? !!nativeEvent[keyProp] : false;
4137}
4138
4139function getEventModifierState(nativeEvent) {
4140 return modifierStateGetter;
4141}
4142
4143var previousScreenX = 0;
4144var previousScreenY = 0;
4145// Use flags to signal movementX/Y has already been set
4146var isMovementXSet = false;
4147var isMovementYSet = false;
4148
4149/**
4150 * @interface MouseEvent
4151 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4152 */
4153var SyntheticMouseEvent = SyntheticUIEvent.extend({
4154 screenX: null,
4155 screenY: null,
4156 clientX: null,
4157 clientY: null,
4158 pageX: null,
4159 pageY: null,
4160 ctrlKey: null,
4161 shiftKey: null,
4162 altKey: null,
4163 metaKey: null,
4164 getModifierState: getEventModifierState,
4165 button: null,
4166 buttons: null,
4167 relatedTarget: function (event) {
4168 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
4169 },
4170 movementX: function (event) {
4171 if ('movementX' in event) {
4172 return event.movementX;
4173 }
4174
4175 var screenX = previousScreenX;
4176 previousScreenX = event.screenX;
4177
4178 if (!isMovementXSet) {
4179 isMovementXSet = true;
4180 return 0;
4181 }
4182
4183 return event.type === 'mousemove' ? event.screenX - screenX : 0;
4184 },
4185 movementY: function (event) {
4186 if ('movementY' in event) {
4187 return event.movementY;
4188 }
4189
4190 var screenY = previousScreenY;
4191 previousScreenY = event.screenY;
4192
4193 if (!isMovementYSet) {
4194 isMovementYSet = true;
4195 return 0;
4196 }
4197
4198 return event.type === 'mousemove' ? event.screenY - screenY : 0;
4199 }
4200});
4201
4202/**
4203 * @interface PointerEvent
4204 * @see http://www.w3.org/TR/pointerevents/
4205 */
4206var SyntheticPointerEvent = SyntheticMouseEvent.extend({
4207 pointerId: null,
4208 width: null,
4209 height: null,
4210 pressure: null,
4211 tangentialPressure: null,
4212 tiltX: null,
4213 tiltY: null,
4214 twist: null,
4215 pointerType: null,
4216 isPrimary: null
4217});
4218
4219var eventTypes$2 = {
4220 mouseEnter: {
4221 registrationName: 'onMouseEnter',
4222 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
4223 },
4224 mouseLeave: {
4225 registrationName: 'onMouseLeave',
4226 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
4227 },
4228 pointerEnter: {
4229 registrationName: 'onPointerEnter',
4230 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
4231 },
4232 pointerLeave: {
4233 registrationName: 'onPointerLeave',
4234 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
4235 }
4236};
4237
4238var EnterLeaveEventPlugin = {
4239 eventTypes: eventTypes$2,
4240
4241 /**
4242 * For almost every interaction we care about, there will be both a top-level
4243 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
4244 * we do not extract duplicate events. However, moving the mouse into the
4245 * browser from outside will not fire a `mouseout` event. In this case, we use
4246 * the `mouseover` top-level event.
4247 */
4248 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4249 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
4250 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
4251
4252 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
4253 return null;
4254 }
4255
4256 if (!isOutEvent && !isOverEvent) {
4257 // Must not be a mouse or pointer in or out - ignoring.
4258 return null;
4259 }
4260
4261 var win = void 0;
4262 if (nativeEventTarget.window === nativeEventTarget) {
4263 // `nativeEventTarget` is probably a window object.
4264 win = nativeEventTarget;
4265 } else {
4266 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
4267 var doc = nativeEventTarget.ownerDocument;
4268 if (doc) {
4269 win = doc.defaultView || doc.parentWindow;
4270 } else {
4271 win = window;
4272 }
4273 }
4274
4275 var from = void 0;
4276 var to = void 0;
4277 if (isOutEvent) {
4278 from = targetInst;
4279 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
4280 to = related ? getClosestInstanceFromNode(related) : null;
4281 } else {
4282 // Moving to a node from outside the window.
4283 from = null;
4284 to = targetInst;
4285 }
4286
4287 if (from === to) {
4288 // Nothing pertains to our managed components.
4289 return null;
4290 }
4291
4292 var eventInterface = void 0,
4293 leaveEventType = void 0,
4294 enterEventType = void 0,
4295 eventTypePrefix = void 0;
4296
4297 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
4298 eventInterface = SyntheticMouseEvent;
4299 leaveEventType = eventTypes$2.mouseLeave;
4300 enterEventType = eventTypes$2.mouseEnter;
4301 eventTypePrefix = 'mouse';
4302 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
4303 eventInterface = SyntheticPointerEvent;
4304 leaveEventType = eventTypes$2.pointerLeave;
4305 enterEventType = eventTypes$2.pointerEnter;
4306 eventTypePrefix = 'pointer';
4307 }
4308
4309 var fromNode = from == null ? win : getNodeFromInstance$1(from);
4310 var toNode = to == null ? win : getNodeFromInstance$1(to);
4311
4312 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
4313 leave.type = eventTypePrefix + 'leave';
4314 leave.target = fromNode;
4315 leave.relatedTarget = toNode;
4316
4317 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
4318 enter.type = eventTypePrefix + 'enter';
4319 enter.target = toNode;
4320 enter.relatedTarget = fromNode;
4321
4322 accumulateEnterLeaveDispatches(leave, enter, from, to);
4323
4324 return [leave, enter];
4325 }
4326};
4327
4328/**
4329 * inlined Object.is polyfill to avoid requiring consumers ship their own
4330 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
4331 */
4332function is(x, y) {
4333 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
4334 ;
4335}
4336
4337var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
4338
4339/**
4340 * Performs equality by iterating through keys on an object and returning false
4341 * when any key has values which are not strictly equal between the arguments.
4342 * Returns true when the values of all keys are strictly equal.
4343 */
4344function shallowEqual(objA, objB) {
4345 if (is(objA, objB)) {
4346 return true;
4347 }
4348
4349 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
4350 return false;
4351 }
4352
4353 var keysA = Object.keys(objA);
4354 var keysB = Object.keys(objB);
4355
4356 if (keysA.length !== keysB.length) {
4357 return false;
4358 }
4359
4360 // Test for A's keys different from B.
4361 for (var i = 0; i < keysA.length; i++) {
4362 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
4363 return false;
4364 }
4365 }
4366
4367 return true;
4368}
4369
4370var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
4371
4372var _ReactInternals$Sched = ReactInternals$1.Scheduler;
4373var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
4374var unstable_now = _ReactInternals$Sched.unstable_now;
4375var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
4376var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
4377var unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint;
4378var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
4379var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
4380var unstable_next = _ReactInternals$Sched.unstable_next;
4381var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
4382var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
4383var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
4384var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
4385var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
4386var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
4387var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
4388var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
4389var unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate;
4390var unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
4391
4392var PLUGIN_EVENT_SYSTEM = 1;
4393var RESPONDER_EVENT_SYSTEM = 1 << 1;
4394var IS_PASSIVE = 1 << 2;
4395var IS_ACTIVE = 1 << 3;
4396var PASSIVE_NOT_SUPPORTED = 1 << 4;
4397
4398function createResponderListener(responder, props) {
4399 var eventResponderListener = {
4400 responder: responder,
4401 props: props
4402 };
4403 {
4404 Object.freeze(eventResponderListener);
4405 }
4406 return eventResponderListener;
4407}
4408
4409function isFiberSuspenseAndTimedOut(fiber) {
4410 return fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
4411}
4412
4413function getSuspenseFallbackChild(fiber) {
4414 return fiber.child.sibling.child;
4415}
4416
4417
4418
4419
4420
4421function createResponderInstance(responder, responderProps, responderState, target, fiber) {
4422 return {
4423 fiber: fiber,
4424 props: responderProps,
4425 responder: responder,
4426 rootEventTypes: null,
4427 state: responderState,
4428 target: target
4429 };
4430}
4431
4432var DiscreteEvent = 0;
4433var UserBlockingEvent = 1;
4434var ContinuousEvent = 2;
4435
4436// Intentionally not named imports because Rollup would use dynamic dispatch for
4437// CommonJS interop named imports.
4438var UserBlockingPriority$1 = unstable_UserBlockingPriority;
4439var runWithPriority$1 = unstable_runWithPriority;
4440
4441
4442var listenToResponderEventTypesImpl = void 0;
4443
4444function setListenToResponderEventTypes(_listenToResponderEventTypesImpl) {
4445 listenToResponderEventTypesImpl = _listenToResponderEventTypesImpl;
4446}
4447
4448var activeTimeouts = new Map();
4449var rootEventTypesToEventResponderInstances = new Map();
4450var ownershipChangeListeners = new Set();
4451
4452var globalOwner = null;
4453
4454var currentTimeStamp = 0;
4455var currentTimers = new Map();
4456var currentInstance = null;
4457var currentEventQueue = null;
4458var currentEventQueuePriority = ContinuousEvent;
4459var currentTimerIDCounter = 0;
4460var currentDocument = null;
4461
4462var eventResponderContext = {
4463 dispatchEvent: function (eventValue, eventListener, eventPriority) {
4464 validateResponderContext();
4465 validateEventValue(eventValue);
4466 if (eventPriority < currentEventQueuePriority) {
4467 currentEventQueuePriority = eventPriority;
4468 }
4469 currentEventQueue.push(createEventQueueItem(eventValue, eventListener));
4470 },
4471 isTargetWithinResponder: function (target) {
4472 validateResponderContext();
4473 if (target != null) {
4474 var fiber = getClosestInstanceFromNode(target);
4475 var responderFiber = currentInstance.fiber;
4476
4477 while (fiber !== null) {
4478 if (fiber === responderFiber || fiber.alternate === responderFiber) {
4479 return true;
4480 }
4481 fiber = fiber.return;
4482 }
4483 }
4484 return false;
4485 },
4486 isTargetWithinResponderScope: function (target) {
4487 validateResponderContext();
4488 var componentInstance = currentInstance;
4489 var responder = componentInstance.responder;
4490
4491 if (target != null) {
4492 var fiber = getClosestInstanceFromNode(target);
4493 var responderFiber = currentInstance.fiber;
4494
4495 while (fiber !== null) {
4496 if (fiber === responderFiber || fiber.alternate === responderFiber) {
4497 return true;
4498 }
4499 if (doesFiberHaveResponder(fiber, responder)) {
4500 return false;
4501 }
4502 fiber = fiber.return;
4503 }
4504 }
4505 return false;
4506 },
4507 isTargetWithinNode: function (childTarget, parentTarget) {
4508 validateResponderContext();
4509 var childFiber = getClosestInstanceFromNode(childTarget);
4510 var parentFiber = getClosestInstanceFromNode(parentTarget);
4511 var parentAlternateFiber = parentFiber.alternate;
4512
4513 var node = childFiber;
4514 while (node !== null) {
4515 if (node === parentFiber || node === parentAlternateFiber) {
4516 return true;
4517 }
4518 node = node.return;
4519 }
4520 return false;
4521 },
4522 addRootEventTypes: function (rootEventTypes) {
4523 validateResponderContext();
4524 var activeDocument = getActiveDocument();
4525 listenToResponderEventTypesImpl(rootEventTypes, activeDocument);
4526 for (var i = 0; i < rootEventTypes.length; i++) {
4527 var rootEventType = rootEventTypes[i];
4528 var eventResponderInstance = currentInstance;
4529 registerRootEventType(rootEventType, eventResponderInstance);
4530 }
4531 },
4532 removeRootEventTypes: function (rootEventTypes) {
4533 validateResponderContext();
4534 for (var i = 0; i < rootEventTypes.length; i++) {
4535 var rootEventType = rootEventTypes[i];
4536 var rootEventResponders = rootEventTypesToEventResponderInstances.get(rootEventType);
4537 var rootEventTypesSet = currentInstance.rootEventTypes;
4538 if (rootEventTypesSet !== null) {
4539 rootEventTypesSet.delete(rootEventType);
4540 }
4541 if (rootEventResponders !== undefined) {
4542 rootEventResponders.delete(currentInstance);
4543 }
4544 }
4545 },
4546 hasOwnership: function () {
4547 validateResponderContext();
4548 return globalOwner === currentInstance;
4549 },
4550 requestGlobalOwnership: function () {
4551 validateResponderContext();
4552 if (globalOwner !== null) {
4553 return false;
4554 }
4555 globalOwner = currentInstance;
4556 triggerOwnershipListeners();
4557 return true;
4558 },
4559 releaseOwnership: function () {
4560 validateResponderContext();
4561 return releaseOwnershipForEventResponderInstance(currentInstance);
4562 },
4563 setTimeout: function (func, delay) {
4564 validateResponderContext();
4565 if (currentTimers === null) {
4566 currentTimers = new Map();
4567 }
4568 var timeout = currentTimers.get(delay);
4569
4570 var timerId = currentTimerIDCounter++;
4571 if (timeout === undefined) {
4572 var _timers = new Map();
4573 var _id = setTimeout(function () {
4574 processTimers(_timers, delay);
4575 }, delay);
4576 timeout = {
4577 id: _id,
4578 timers: _timers
4579 };
4580 currentTimers.set(delay, timeout);
4581 }
4582 timeout.timers.set(timerId, {
4583 instance: currentInstance,
4584 func: func,
4585 id: timerId,
4586 timeStamp: currentTimeStamp
4587 });
4588 activeTimeouts.set(timerId, timeout);
4589 return timerId;
4590 },
4591 clearTimeout: function (timerId) {
4592 validateResponderContext();
4593 var timeout = activeTimeouts.get(timerId);
4594
4595 if (timeout !== undefined) {
4596 var _timers2 = timeout.timers;
4597 _timers2.delete(timerId);
4598 if (_timers2.size === 0) {
4599 clearTimeout(timeout.id);
4600 }
4601 }
4602 },
4603 getFocusableElementsInScope: function (deep) {
4604 validateResponderContext();
4605 var focusableElements = [];
4606 var eventResponderInstance = currentInstance;
4607 var currentResponder = eventResponderInstance.responder;
4608 var focusScopeFiber = eventResponderInstance.fiber;
4609 if (deep) {
4610 var deepNode = focusScopeFiber.return;
4611 while (deepNode !== null) {
4612 if (doesFiberHaveResponder(deepNode, currentResponder)) {
4613 focusScopeFiber = deepNode;
4614 }
4615 deepNode = deepNode.return;
4616 }
4617 }
4618 var child = focusScopeFiber.child;
4619
4620 if (child !== null) {
4621 collectFocusableElements(child, focusableElements);
4622 }
4623 return focusableElements;
4624 },
4625
4626 getActiveDocument: getActiveDocument,
4627 objectAssign: _assign,
4628 getTimeStamp: function () {
4629 validateResponderContext();
4630 return currentTimeStamp;
4631 },
4632 isTargetWithinHostComponent: function (target, elementType) {
4633 validateResponderContext();
4634 var fiber = getClosestInstanceFromNode(target);
4635
4636 while (fiber !== null) {
4637 if (fiber.tag === HostComponent && fiber.type === elementType) {
4638 return true;
4639 }
4640 fiber = fiber.return;
4641 }
4642 return false;
4643 },
4644
4645 enqueueStateRestore: enqueueStateRestore
4646};
4647
4648function validateEventValue(eventValue) {
4649 if (typeof eventValue === 'object' && eventValue !== null) {
4650 var target = eventValue.target,
4651 type = eventValue.type,
4652 _timeStamp = eventValue.timeStamp;
4653
4654
4655 if (target == null || type == null || _timeStamp == null) {
4656 throw new Error('context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.');
4657 }
4658 var showWarning = function (name) {
4659 {
4660 warning$1(false, '%s is not available on event objects created from event responder modules (React Flare). ' + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', name, name);
4661 }
4662 };
4663 eventValue.preventDefault = function () {
4664 {
4665 showWarning('preventDefault()');
4666 }
4667 };
4668 eventValue.stopPropagation = function () {
4669 {
4670 showWarning('stopPropagation()');
4671 }
4672 };
4673 eventValue.isDefaultPrevented = function () {
4674 {
4675 showWarning('isDefaultPrevented()');
4676 }
4677 };
4678 eventValue.isPropagationStopped = function () {
4679 {
4680 showWarning('isPropagationStopped()');
4681 }
4682 };
4683 // $FlowFixMe: we don't need value, Flow thinks we do
4684 Object.defineProperty(eventValue, 'nativeEvent', {
4685 get: function () {
4686 {
4687 showWarning('nativeEvent');
4688 }
4689 }
4690 });
4691 }
4692}
4693
4694function collectFocusableElements(node, focusableElements) {
4695 if (isFiberSuspenseAndTimedOut(node)) {
4696 var fallbackChild = getSuspenseFallbackChild(node);
4697 if (fallbackChild !== null) {
4698 collectFocusableElements(fallbackChild, focusableElements);
4699 }
4700 } else {
4701 if (isFiberHostComponentFocusable(node)) {
4702 focusableElements.push(node.stateNode);
4703 } else {
4704 var child = node.child;
4705
4706 if (child !== null) {
4707 collectFocusableElements(child, focusableElements);
4708 }
4709 }
4710 }
4711 var sibling = node.sibling;
4712
4713 if (sibling !== null) {
4714 collectFocusableElements(sibling, focusableElements);
4715 }
4716}
4717
4718function createEventQueueItem(value, listener) {
4719 return {
4720 value: value,
4721 listener: listener
4722 };
4723}
4724
4725function doesFiberHaveResponder(fiber, responder) {
4726 if (fiber.tag === HostComponent) {
4727 var dependencies = fiber.dependencies;
4728 if (dependencies !== null) {
4729 var respondersMap = dependencies.responders;
4730 if (respondersMap !== null && respondersMap.has(responder)) {
4731 return true;
4732 }
4733 }
4734 }
4735 return false;
4736}
4737
4738function getActiveDocument() {
4739 return currentDocument;
4740}
4741
4742function releaseOwnershipForEventResponderInstance(eventResponderInstance) {
4743 if (globalOwner === eventResponderInstance) {
4744 globalOwner = null;
4745 triggerOwnershipListeners();
4746 return true;
4747 }
4748 return false;
4749}
4750
4751function isFiberHostComponentFocusable(fiber) {
4752 if (fiber.tag !== HostComponent) {
4753 return false;
4754 }
4755 var type = fiber.type,
4756 memoizedProps = fiber.memoizedProps;
4757
4758 if (memoizedProps.tabIndex === -1 || memoizedProps.disabled) {
4759 return false;
4760 }
4761 if (memoizedProps.tabIndex === 0 || memoizedProps.contentEditable === true) {
4762 return true;
4763 }
4764 if (type === 'a' || type === 'area') {
4765 return !!memoizedProps.href && memoizedProps.rel !== 'ignore';
4766 }
4767 if (type === 'input') {
4768 return memoizedProps.type !== 'hidden' && memoizedProps.type !== 'file';
4769 }
4770 return type === 'button' || type === 'textarea' || type === 'object' || type === 'select' || type === 'iframe' || type === 'embed';
4771}
4772
4773function processTimers(timers, delay) {
4774 var timersArr = Array.from(timers.values());
4775 currentEventQueuePriority = ContinuousEvent;
4776 try {
4777 for (var i = 0; i < timersArr.length; i++) {
4778 var _timersArr$i = timersArr[i],
4779 _instance = _timersArr$i.instance,
4780 _func = _timersArr$i.func,
4781 _id2 = _timersArr$i.id,
4782 _timeStamp2 = _timersArr$i.timeStamp;
4783
4784 currentInstance = _instance;
4785 currentEventQueue = [];
4786 currentTimeStamp = _timeStamp2 + delay;
4787 try {
4788 _func();
4789 } finally {
4790 activeTimeouts.delete(_id2);
4791 }
4792 }
4793 processEventQueue();
4794 } finally {
4795 currentTimers = null;
4796 currentInstance = null;
4797 currentEventQueue = null;
4798 currentTimeStamp = 0;
4799 }
4800}
4801
4802function createDOMResponderEvent(topLevelType, nativeEvent, nativeEventTarget, passive, passiveSupported) {
4803 var _ref = nativeEvent,
4804 pointerType = _ref.pointerType;
4805
4806 var eventPointerType = '';
4807 var pointerId = null;
4808
4809 if (pointerType !== undefined) {
4810 eventPointerType = pointerType;
4811 pointerId = nativeEvent.pointerId;
4812 } else if (nativeEvent.key !== undefined) {
4813 eventPointerType = 'keyboard';
4814 } else if (nativeEvent.button !== undefined) {
4815 eventPointerType = 'mouse';
4816 } else if (nativeEvent.changedTouches !== undefined) {
4817 eventPointerType = 'touch';
4818 }
4819
4820 return {
4821 nativeEvent: nativeEvent,
4822 passive: passive,
4823 passiveSupported: passiveSupported,
4824 pointerId: pointerId,
4825 pointerType: eventPointerType,
4826 responderTarget: null,
4827 target: nativeEventTarget,
4828 type: topLevelType
4829 };
4830}
4831
4832function processEvents(eventQueue) {
4833 for (var i = 0, length = eventQueue.length; i < length; i++) {
4834 var _eventQueue$i = eventQueue[i],
4835 _value = _eventQueue$i.value,
4836 _listener = _eventQueue$i.listener;
4837
4838 var type = typeof _value === 'object' && _value !== null ? _value.type : '';
4839 invokeGuardedCallbackAndCatchFirstError(type, _listener, undefined, _value);
4840 }
4841}
4842
4843function processEventQueue() {
4844 var eventQueue = currentEventQueue;
4845 if (eventQueue.length === 0) {
4846 return;
4847 }
4848 switch (currentEventQueuePriority) {
4849 case DiscreteEvent:
4850 {
4851 flushDiscreteUpdatesIfNeeded(currentTimeStamp);
4852 discreteUpdates(function () {
4853 batchedEventUpdates(processEvents, eventQueue);
4854 });
4855 break;
4856 }
4857 case UserBlockingEvent:
4858 {
4859 if (enableUserBlockingEvents) {
4860 runWithPriority$1(UserBlockingPriority$1, batchedEventUpdates.bind(null, processEvents, eventQueue));
4861 } else {
4862 batchedEventUpdates(processEvents, eventQueue);
4863 }
4864 break;
4865 }
4866 case ContinuousEvent:
4867 {
4868 batchedEventUpdates(processEvents, eventQueue);
4869 break;
4870 }
4871 }
4872}
4873
4874function responderEventTypesContainType(eventTypes, type) {
4875 for (var i = 0, len = eventTypes.length; i < len; i++) {
4876 if (eventTypes[i] === type) {
4877 return true;
4878 }
4879 }
4880 return false;
4881}
4882
4883function validateResponderTargetEventTypes(eventType, responder) {
4884 var targetEventTypes = responder.targetEventTypes;
4885 // Validate the target event type exists on the responder
4886
4887 if (targetEventTypes !== null) {
4888 return responderEventTypesContainType(targetEventTypes, eventType);
4889 }
4890 return false;
4891}
4892
4893function validateOwnership(responderInstance) {
4894 return globalOwner === null || globalOwner === responderInstance;
4895}
4896
4897function traverseAndHandleEventResponderInstances(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags) {
4898 var isPassiveEvent = (eventSystemFlags & IS_PASSIVE) !== 0;
4899 var isPassiveSupported = (eventSystemFlags & PASSIVE_NOT_SUPPORTED) === 0;
4900 var isPassive = isPassiveEvent || !isPassiveSupported;
4901 var eventType = isPassive ? topLevelType : topLevelType + '_active';
4902
4903 // Trigger event responders in this order:
4904 // - Bubble target responder phase
4905 // - Root responder phase
4906
4907 var visitedResponders = new Set();
4908 var responderEvent = createDOMResponderEvent(topLevelType, nativeEvent, nativeEventTarget, isPassiveEvent, isPassiveSupported);
4909 var node = targetFiber;
4910 while (node !== null) {
4911 var _node = node,
4912 dependencies = _node.dependencies,
4913 tag = _node.tag;
4914
4915 if (tag === HostComponent && dependencies !== null) {
4916 var respondersMap = dependencies.responders;
4917 if (respondersMap !== null) {
4918 var responderInstances = Array.from(respondersMap.values());
4919 for (var i = 0, length = responderInstances.length; i < length; i++) {
4920 var responderInstance = responderInstances[i];
4921
4922 if (validateOwnership(responderInstance)) {
4923 var props = responderInstance.props,
4924 responder = responderInstance.responder,
4925 state = responderInstance.state,
4926 target = responderInstance.target;
4927
4928 if (!visitedResponders.has(responder) && validateResponderTargetEventTypes(eventType, responder)) {
4929 visitedResponders.add(responder);
4930 var onEvent = responder.onEvent;
4931 if (onEvent !== null) {
4932 currentInstance = responderInstance;
4933 responderEvent.responderTarget = target;
4934 onEvent(responderEvent, eventResponderContext, props, state);
4935 }
4936 }
4937 }
4938 }
4939 }
4940 }
4941 node = node.return;
4942 }
4943 // Root phase
4944 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(eventType);
4945 if (rootEventResponderInstances !== undefined) {
4946 var _responderInstances = Array.from(rootEventResponderInstances);
4947
4948 for (var _i = 0; _i < _responderInstances.length; _i++) {
4949 var _responderInstance = _responderInstances[_i];
4950 if (!validateOwnership(_responderInstance)) {
4951 continue;
4952 }
4953 var _props = _responderInstance.props,
4954 _responder = _responderInstance.responder,
4955 _state = _responderInstance.state,
4956 _target = _responderInstance.target;
4957
4958 var onRootEvent = _responder.onRootEvent;
4959 if (onRootEvent !== null) {
4960 currentInstance = _responderInstance;
4961 responderEvent.responderTarget = _target;
4962 onRootEvent(responderEvent, eventResponderContext, _props, _state);
4963 }
4964 }
4965 }
4966}
4967
4968function triggerOwnershipListeners() {
4969 var listeningInstances = Array.from(ownershipChangeListeners);
4970 var previousInstance = currentInstance;
4971 var previousEventQueuePriority = currentEventQueuePriority;
4972 var previousEventQueue = currentEventQueue;
4973 try {
4974 for (var i = 0; i < listeningInstances.length; i++) {
4975 var _instance2 = listeningInstances[i];
4976 var props = _instance2.props,
4977 responder = _instance2.responder,
4978 state = _instance2.state;
4979
4980 currentInstance = _instance2;
4981 currentEventQueuePriority = ContinuousEvent;
4982 currentEventQueue = [];
4983 var onOwnershipChange = responder.onOwnershipChange;
4984 if (onOwnershipChange !== null) {
4985 onOwnershipChange(eventResponderContext, props, state);
4986 }
4987 }
4988 processEventQueue();
4989 } finally {
4990 currentInstance = previousInstance;
4991 currentEventQueue = previousEventQueue;
4992 currentEventQueuePriority = previousEventQueuePriority;
4993 }
4994}
4995
4996function mountEventResponder(responder, responderInstance, props, state) {
4997 if (responder.onOwnershipChange !== null) {
4998 ownershipChangeListeners.add(responderInstance);
4999 }
5000 var onMount = responder.onMount;
5001 if (onMount !== null) {
5002 currentEventQueuePriority = ContinuousEvent;
5003 currentInstance = responderInstance;
5004 currentEventQueue = [];
5005 try {
5006 onMount(eventResponderContext, props, state);
5007 processEventQueue();
5008 } finally {
5009 currentEventQueue = null;
5010 currentInstance = null;
5011 currentTimers = null;
5012 }
5013 }
5014}
5015
5016function unmountEventResponder(responderInstance) {
5017 var responder = responderInstance.responder;
5018 var onUnmount = responder.onUnmount;
5019 if (onUnmount !== null) {
5020 var props = responderInstance.props,
5021 state = responderInstance.state;
5022
5023 currentEventQueue = [];
5024 currentEventQueuePriority = ContinuousEvent;
5025 currentInstance = responderInstance;
5026 try {
5027 onUnmount(eventResponderContext, props, state);
5028 processEventQueue();
5029 } finally {
5030 currentEventQueue = null;
5031 currentInstance = null;
5032 currentTimers = null;
5033 }
5034 }
5035 releaseOwnershipForEventResponderInstance(responderInstance);
5036 if (responder.onOwnershipChange !== null) {
5037 ownershipChangeListeners.delete(responderInstance);
5038 }
5039 var rootEventTypesSet = responderInstance.rootEventTypes;
5040 if (rootEventTypesSet !== null) {
5041 var rootEventTypes = Array.from(rootEventTypesSet);
5042
5043 for (var i = 0; i < rootEventTypes.length; i++) {
5044 var topLevelEventType = rootEventTypes[i];
5045 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(topLevelEventType);
5046 if (rootEventResponderInstances !== undefined) {
5047 rootEventResponderInstances.delete(responderInstance);
5048 }
5049 }
5050 }
5051}
5052
5053function validateResponderContext() {
5054 (function () {
5055 if (!(currentInstance !== null)) {
5056 {
5057 throw ReactError(Error('An event responder context was used outside of an event cycle. Use context.setTimeout() to use asynchronous responder context outside of event cycle .'));
5058 }
5059 }
5060 })();
5061}
5062
5063function dispatchEventForResponderEventSystem(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags) {
5064 if (enableFlareAPI) {
5065 var previousEventQueue = currentEventQueue;
5066 var previousInstance = currentInstance;
5067 var previousTimers = currentTimers;
5068 var previousTimeStamp = currentTimeStamp;
5069 var previousDocument = currentDocument;
5070 var previousEventQueuePriority = currentEventQueuePriority;
5071 currentTimers = null;
5072 currentEventQueue = [];
5073 currentEventQueuePriority = ContinuousEvent;
5074 // nodeType 9 is DOCUMENT_NODE
5075 currentDocument = nativeEventTarget.nodeType === 9 ? nativeEventTarget : nativeEventTarget.ownerDocument;
5076 // We might want to control timeStamp another way here
5077 currentTimeStamp = nativeEvent.timeStamp;
5078 try {
5079 traverseAndHandleEventResponderInstances(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags);
5080 processEventQueue();
5081 } finally {
5082 currentTimers = previousTimers;
5083 currentInstance = previousInstance;
5084 currentEventQueue = previousEventQueue;
5085 currentTimeStamp = previousTimeStamp;
5086 currentDocument = previousDocument;
5087 currentEventQueuePriority = previousEventQueuePriority;
5088 }
5089 }
5090}
5091
5092function addRootEventTypesForResponderInstance(responderInstance, rootEventTypes) {
5093 for (var i = 0; i < rootEventTypes.length; i++) {
5094 var rootEventType = rootEventTypes[i];
5095 registerRootEventType(rootEventType, responderInstance);
5096 }
5097}
5098
5099function registerRootEventType(rootEventType, eventResponderInstance) {
5100 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(rootEventType);
5101 if (rootEventResponderInstances === undefined) {
5102 rootEventResponderInstances = new Set();
5103 rootEventTypesToEventResponderInstances.set(rootEventType, rootEventResponderInstances);
5104 }
5105 var rootEventTypesSet = eventResponderInstance.rootEventTypes;
5106 if (rootEventTypesSet === null) {
5107 rootEventTypesSet = eventResponderInstance.rootEventTypes = new Set();
5108 }
5109 (function () {
5110 if (!!rootEventTypesSet.has(rootEventType)) {
5111 {
5112 throw ReactError(Error('addRootEventTypes() found a duplicate root event type of "' + rootEventType + '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.'));
5113 }
5114 }
5115 })();
5116 rootEventTypesSet.add(rootEventType);
5117 rootEventResponderInstances.add(eventResponderInstance);
5118}
5119
5120/**
5121 * `ReactInstanceMap` maintains a mapping from a public facing stateful
5122 * instance (key) and the internal representation (value). This allows public
5123 * methods to accept the user facing instance as an argument and map them back
5124 * to internal methods.
5125 *
5126 * Note that this module is currently shared and assumed to be stateless.
5127 * If this becomes an actual Map, that will break.
5128 */
5129
5130/**
5131 * This API should be called `delete` but we'd have to make sure to always
5132 * transform these to strings for IE support. When this transform is fully
5133 * supported we can rename it.
5134 */
5135
5136
5137function get(key) {
5138 return key._reactInternalFiber;
5139}
5140
5141function has(key) {
5142 return key._reactInternalFiber !== undefined;
5143}
5144
5145function set(key, value) {
5146 key._reactInternalFiber = value;
5147}
5148
5149// Don't change these two values. They're used by React Dev Tools.
5150var NoEffect = /* */0;
5151var PerformedWork = /* */1;
5152
5153// You can change the rest (and add more).
5154var Placement = /* */2;
5155var Update = /* */4;
5156var PlacementAndUpdate = /* */6;
5157var Deletion = /* */8;
5158var ContentReset = /* */16;
5159var Callback = /* */32;
5160var DidCapture = /* */64;
5161var Ref = /* */128;
5162var Snapshot = /* */256;
5163var Passive = /* */512;
5164
5165// Passive & Update & Callback & Ref & Snapshot
5166var LifecycleEffectMask = /* */932;
5167
5168// Union of all host effects
5169var HostEffectMask = /* */1023;
5170
5171var Incomplete = /* */1024;
5172var ShouldCapture = /* */2048;
5173
5174var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
5175
5176var MOUNTING = 1;
5177var MOUNTED = 2;
5178var UNMOUNTED = 3;
5179
5180function isFiberMountedImpl(fiber) {
5181 var node = fiber;
5182 if (!fiber.alternate) {
5183 // If there is no alternate, this might be a new tree that isn't inserted
5184 // yet. If it is, then it will have a pending insertion effect on it.
5185 if ((node.effectTag & Placement) !== NoEffect) {
5186 return MOUNTING;
5187 }
5188 while (node.return) {
5189 node = node.return;
5190 if ((node.effectTag & Placement) !== NoEffect) {
5191 return MOUNTING;
5192 }
5193 }
5194 } else {
5195 while (node.return) {
5196 node = node.return;
5197 }
5198 }
5199 if (node.tag === HostRoot) {
5200 // TODO: Check if this was a nested HostRoot when used with
5201 // renderContainerIntoSubtree.
5202 return MOUNTED;
5203 }
5204 // If we didn't hit the root, that means that we're in an disconnected tree
5205 // that has been unmounted.
5206 return UNMOUNTED;
5207}
5208
5209function isFiberMounted(fiber) {
5210 return isFiberMountedImpl(fiber) === MOUNTED;
5211}
5212
5213function isMounted(component) {
5214 {
5215 var owner = ReactCurrentOwner$1.current;
5216 if (owner !== null && owner.tag === ClassComponent) {
5217 var ownerFiber = owner;
5218 var instance = ownerFiber.stateNode;
5219 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%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') : void 0;
5220 instance._warnedAboutRefsInRender = true;
5221 }
5222 }
5223
5224 var fiber = get(component);
5225 if (!fiber) {
5226 return false;
5227 }
5228 return isFiberMountedImpl(fiber) === MOUNTED;
5229}
5230
5231function assertIsMounted(fiber) {
5232 (function () {
5233 if (!(isFiberMountedImpl(fiber) === MOUNTED)) {
5234 {
5235 throw ReactError(Error('Unable to find node on an unmounted component.'));
5236 }
5237 }
5238 })();
5239}
5240
5241function findCurrentFiberUsingSlowPath(fiber) {
5242 var alternate = fiber.alternate;
5243 if (!alternate) {
5244 // If there is no alternate, then we only need to check if it is mounted.
5245 var state = isFiberMountedImpl(fiber);
5246 (function () {
5247 if (!(state !== UNMOUNTED)) {
5248 {
5249 throw ReactError(Error('Unable to find node on an unmounted component.'));
5250 }
5251 }
5252 })();
5253 if (state === MOUNTING) {
5254 return null;
5255 }
5256 return fiber;
5257 }
5258 // If we have two possible branches, we'll walk backwards up to the root
5259 // to see what path the root points to. On the way we may hit one of the
5260 // special cases and we'll deal with them.
5261 var a = fiber;
5262 var b = alternate;
5263 while (true) {
5264 var parentA = a.return;
5265 if (parentA === null) {
5266 // We're at the root.
5267 break;
5268 }
5269 var parentB = parentA.alternate;
5270 if (parentB === null) {
5271 // There is no alternate. This is an unusual case. Currently, it only
5272 // happens when a Suspense component is hidden. An extra fragment fiber
5273 // is inserted in between the Suspense fiber and its children. Skip
5274 // over this extra fragment fiber and proceed to the next parent.
5275 var nextParent = parentA.return;
5276 if (nextParent !== null) {
5277 a = b = nextParent;
5278 continue;
5279 }
5280 // If there's no parent, we're at the root.
5281 break;
5282 }
5283
5284 // If both copies of the parent fiber point to the same child, we can
5285 // assume that the child is current. This happens when we bailout on low
5286 // priority: the bailed out fiber's child reuses the current child.
5287 if (parentA.child === parentB.child) {
5288 var child = parentA.child;
5289 while (child) {
5290 if (child === a) {
5291 // We've determined that A is the current branch.
5292 assertIsMounted(parentA);
5293 return fiber;
5294 }
5295 if (child === b) {
5296 // We've determined that B is the current branch.
5297 assertIsMounted(parentA);
5298 return alternate;
5299 }
5300 child = child.sibling;
5301 }
5302 // We should never have an alternate for any mounting node. So the only
5303 // way this could possibly happen is if this was unmounted, if at all.
5304 (function () {
5305 {
5306 {
5307 throw ReactError(Error('Unable to find node on an unmounted component.'));
5308 }
5309 }
5310 })();
5311 }
5312
5313 if (a.return !== b.return) {
5314 // The return pointer of A and the return pointer of B point to different
5315 // fibers. We assume that return pointers never criss-cross, so A must
5316 // belong to the child set of A.return, and B must belong to the child
5317 // set of B.return.
5318 a = parentA;
5319 b = parentB;
5320 } else {
5321 // The return pointers point to the same fiber. We'll have to use the
5322 // default, slow path: scan the child sets of each parent alternate to see
5323 // which child belongs to which set.
5324 //
5325 // Search parent A's child set
5326 var didFindChild = false;
5327 var _child = parentA.child;
5328 while (_child) {
5329 if (_child === a) {
5330 didFindChild = true;
5331 a = parentA;
5332 b = parentB;
5333 break;
5334 }
5335 if (_child === b) {
5336 didFindChild = true;
5337 b = parentA;
5338 a = parentB;
5339 break;
5340 }
5341 _child = _child.sibling;
5342 }
5343 if (!didFindChild) {
5344 // Search parent B's child set
5345 _child = parentB.child;
5346 while (_child) {
5347 if (_child === a) {
5348 didFindChild = true;
5349 a = parentB;
5350 b = parentA;
5351 break;
5352 }
5353 if (_child === b) {
5354 didFindChild = true;
5355 b = parentB;
5356 a = parentA;
5357 break;
5358 }
5359 _child = _child.sibling;
5360 }
5361 (function () {
5362 if (!didFindChild) {
5363 {
5364 throw ReactError(Error('Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.'));
5365 }
5366 }
5367 })();
5368 }
5369 }
5370
5371 (function () {
5372 if (!(a.alternate === b)) {
5373 {
5374 throw ReactError(Error('Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.'));
5375 }
5376 }
5377 })();
5378 }
5379 // If the root is not a host container, we're in a disconnected tree. I.e.
5380 // unmounted.
5381 (function () {
5382 if (!(a.tag === HostRoot)) {
5383 {
5384 throw ReactError(Error('Unable to find node on an unmounted component.'));
5385 }
5386 }
5387 })();
5388 if (a.stateNode.current === a) {
5389 // We've determined that A is the current branch.
5390 return fiber;
5391 }
5392 // Otherwise B has to be current branch.
5393 return alternate;
5394}
5395
5396function findCurrentHostFiber(parent) {
5397 var currentParent = findCurrentFiberUsingSlowPath(parent);
5398 if (!currentParent) {
5399 return null;
5400 }
5401
5402 // Next we'll drill down this component to find the first HostComponent/Text.
5403 var node = currentParent;
5404 while (true) {
5405 if (node.tag === HostComponent || node.tag === HostText) {
5406 return node;
5407 } else if (node.child) {
5408 node.child.return = node;
5409 node = node.child;
5410 continue;
5411 }
5412 if (node === currentParent) {
5413 return null;
5414 }
5415 while (!node.sibling) {
5416 if (!node.return || node.return === currentParent) {
5417 return null;
5418 }
5419 node = node.return;
5420 }
5421 node.sibling.return = node.return;
5422 node = node.sibling;
5423 }
5424 // Flow needs the return null here, but ESLint complains about it.
5425 // eslint-disable-next-line no-unreachable
5426 return null;
5427}
5428
5429function findCurrentHostFiberWithNoPortals(parent) {
5430 var currentParent = findCurrentFiberUsingSlowPath(parent);
5431 if (!currentParent) {
5432 return null;
5433 }
5434
5435 // Next we'll drill down this component to find the first HostComponent/Text.
5436 var node = currentParent;
5437 while (true) {
5438 if (node.tag === HostComponent || node.tag === HostText || node.tag === FundamentalComponent) {
5439 return node;
5440 } else if (node.child && node.tag !== HostPortal) {
5441 node.child.return = node;
5442 node = node.child;
5443 continue;
5444 }
5445 if (node === currentParent) {
5446 return null;
5447 }
5448 while (!node.sibling) {
5449 if (!node.return || node.return === currentParent) {
5450 return null;
5451 }
5452 node = node.return;
5453 }
5454 node.sibling.return = node.return;
5455 node = node.sibling;
5456 }
5457 // Flow needs the return null here, but ESLint complains about it.
5458 // eslint-disable-next-line no-unreachable
5459 return null;
5460}
5461
5462function addEventBubbleListener(element, eventType, listener) {
5463 element.addEventListener(eventType, listener, false);
5464}
5465
5466function addEventCaptureListener(element, eventType, listener) {
5467 element.addEventListener(eventType, listener, true);
5468}
5469
5470function addEventCaptureListenerWithPassiveFlag(element, eventType, listener, passive) {
5471 element.addEventListener(eventType, listener, {
5472 capture: true,
5473 passive: passive
5474 });
5475}
5476
5477/**
5478 * @interface Event
5479 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
5480 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
5481 */
5482var SyntheticAnimationEvent = SyntheticEvent.extend({
5483 animationName: null,
5484 elapsedTime: null,
5485 pseudoElement: null
5486});
5487
5488/**
5489 * @interface Event
5490 * @see http://www.w3.org/TR/clipboard-apis/
5491 */
5492var SyntheticClipboardEvent = SyntheticEvent.extend({
5493 clipboardData: function (event) {
5494 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
5495 }
5496});
5497
5498/**
5499 * @interface FocusEvent
5500 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5501 */
5502var SyntheticFocusEvent = SyntheticUIEvent.extend({
5503 relatedTarget: null
5504});
5505
5506/**
5507 * `charCode` represents the actual "character code" and is safe to use with
5508 * `String.fromCharCode`. As such, only keys that correspond to printable
5509 * characters produce a valid `charCode`, the only exception to this is Enter.
5510 * The Tab-key is considered non-printable and does not have a `charCode`,
5511 * presumably because it does not produce a tab-character in browsers.
5512 *
5513 * @param {object} nativeEvent Native browser event.
5514 * @return {number} Normalized `charCode` property.
5515 */
5516function getEventCharCode(nativeEvent) {
5517 var charCode = void 0;
5518 var keyCode = nativeEvent.keyCode;
5519
5520 if ('charCode' in nativeEvent) {
5521 charCode = nativeEvent.charCode;
5522
5523 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
5524 if (charCode === 0 && keyCode === 13) {
5525 charCode = 13;
5526 }
5527 } else {
5528 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
5529 charCode = keyCode;
5530 }
5531
5532 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
5533 // report Enter as charCode 10 when ctrl is pressed.
5534 if (charCode === 10) {
5535 charCode = 13;
5536 }
5537
5538 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
5539 // Must not discard the (non-)printable Enter-key.
5540 if (charCode >= 32 || charCode === 13) {
5541 return charCode;
5542 }
5543
5544 return 0;
5545}
5546
5547/**
5548 * Normalization of deprecated HTML5 `key` values
5549 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5550 */
5551var normalizeKey = {
5552 Esc: 'Escape',
5553 Spacebar: ' ',
5554 Left: 'ArrowLeft',
5555 Up: 'ArrowUp',
5556 Right: 'ArrowRight',
5557 Down: 'ArrowDown',
5558 Del: 'Delete',
5559 Win: 'OS',
5560 Menu: 'ContextMenu',
5561 Apps: 'ContextMenu',
5562 Scroll: 'ScrollLock',
5563 MozPrintableKey: 'Unidentified'
5564};
5565
5566/**
5567 * Translation from legacy `keyCode` to HTML5 `key`
5568 * Only special keys supported, all others depend on keyboard layout or browser
5569 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5570 */
5571var translateToKey = {
5572 '8': 'Backspace',
5573 '9': 'Tab',
5574 '12': 'Clear',
5575 '13': 'Enter',
5576 '16': 'Shift',
5577 '17': 'Control',
5578 '18': 'Alt',
5579 '19': 'Pause',
5580 '20': 'CapsLock',
5581 '27': 'Escape',
5582 '32': ' ',
5583 '33': 'PageUp',
5584 '34': 'PageDown',
5585 '35': 'End',
5586 '36': 'Home',
5587 '37': 'ArrowLeft',
5588 '38': 'ArrowUp',
5589 '39': 'ArrowRight',
5590 '40': 'ArrowDown',
5591 '45': 'Insert',
5592 '46': 'Delete',
5593 '112': 'F1',
5594 '113': 'F2',
5595 '114': 'F3',
5596 '115': 'F4',
5597 '116': 'F5',
5598 '117': 'F6',
5599 '118': 'F7',
5600 '119': 'F8',
5601 '120': 'F9',
5602 '121': 'F10',
5603 '122': 'F11',
5604 '123': 'F12',
5605 '144': 'NumLock',
5606 '145': 'ScrollLock',
5607 '224': 'Meta'
5608};
5609
5610/**
5611 * @param {object} nativeEvent Native browser event.
5612 * @return {string} Normalized `key` property.
5613 */
5614function getEventKey(nativeEvent) {
5615 if (nativeEvent.key) {
5616 // Normalize inconsistent values reported by browsers due to
5617 // implementations of a working draft specification.
5618
5619 // FireFox implements `key` but returns `MozPrintableKey` for all
5620 // printable characters (normalized to `Unidentified`), ignore it.
5621 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
5622 if (key !== 'Unidentified') {
5623 return key;
5624 }
5625 }
5626
5627 // Browser does not implement `key`, polyfill as much of it as we can.
5628 if (nativeEvent.type === 'keypress') {
5629 var charCode = getEventCharCode(nativeEvent);
5630
5631 // The enter-key is technically both printable and non-printable and can
5632 // thus be captured by `keypress`, no other non-printable key should.
5633 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
5634 }
5635 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
5636 // While user keyboard layout determines the actual meaning of each
5637 // `keyCode` value, almost all function keys have a universal value.
5638 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
5639 }
5640 return '';
5641}
5642
5643/**
5644 * @interface KeyboardEvent
5645 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5646 */
5647var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
5648 key: getEventKey,
5649 location: null,
5650 ctrlKey: null,
5651 shiftKey: null,
5652 altKey: null,
5653 metaKey: null,
5654 repeat: null,
5655 locale: null,
5656 getModifierState: getEventModifierState,
5657 // Legacy Interface
5658 charCode: function (event) {
5659 // `charCode` is the result of a KeyPress event and represents the value of
5660 // the actual printable character.
5661
5662 // KeyPress is deprecated, but its replacement is not yet final and not
5663 // implemented in any major browser. Only KeyPress has charCode.
5664 if (event.type === 'keypress') {
5665 return getEventCharCode(event);
5666 }
5667 return 0;
5668 },
5669 keyCode: function (event) {
5670 // `keyCode` is the result of a KeyDown/Up event and represents the value of
5671 // physical keyboard key.
5672
5673 // The actual meaning of the value depends on the users' keyboard layout
5674 // which cannot be detected. Assuming that it is a US keyboard layout
5675 // provides a surprisingly accurate mapping for US and European users.
5676 // Due to this, it is left to the user to implement at this time.
5677 if (event.type === 'keydown' || event.type === 'keyup') {
5678 return event.keyCode;
5679 }
5680 return 0;
5681 },
5682 which: function (event) {
5683 // `which` is an alias for either `keyCode` or `charCode` depending on the
5684 // type of the event.
5685 if (event.type === 'keypress') {
5686 return getEventCharCode(event);
5687 }
5688 if (event.type === 'keydown' || event.type === 'keyup') {
5689 return event.keyCode;
5690 }
5691 return 0;
5692 }
5693});
5694
5695/**
5696 * @interface DragEvent
5697 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5698 */
5699var SyntheticDragEvent = SyntheticMouseEvent.extend({
5700 dataTransfer: null
5701});
5702
5703/**
5704 * @interface TouchEvent
5705 * @see http://www.w3.org/TR/touch-events/
5706 */
5707var SyntheticTouchEvent = SyntheticUIEvent.extend({
5708 touches: null,
5709 targetTouches: null,
5710 changedTouches: null,
5711 altKey: null,
5712 metaKey: null,
5713 ctrlKey: null,
5714 shiftKey: null,
5715 getModifierState: getEventModifierState
5716});
5717
5718/**
5719 * @interface Event
5720 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
5721 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
5722 */
5723var SyntheticTransitionEvent = SyntheticEvent.extend({
5724 propertyName: null,
5725 elapsedTime: null,
5726 pseudoElement: null
5727});
5728
5729/**
5730 * @interface WheelEvent
5731 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5732 */
5733var SyntheticWheelEvent = SyntheticMouseEvent.extend({
5734 deltaX: function (event) {
5735 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
5736 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
5737 },
5738 deltaY: function (event) {
5739 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
5740 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
5741 'wheelDelta' in event ? -event.wheelDelta : 0;
5742 },
5743
5744 deltaZ: null,
5745
5746 // Browsers without "deltaMode" is reporting in raw wheel delta where one
5747 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
5748 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
5749 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
5750 deltaMode: null
5751});
5752
5753/**
5754 * Turns
5755 * ['abort', ...]
5756 * into
5757 * eventTypes = {
5758 * 'abort': {
5759 * phasedRegistrationNames: {
5760 * bubbled: 'onAbort',
5761 * captured: 'onAbortCapture',
5762 * },
5763 * dependencies: [TOP_ABORT],
5764 * },
5765 * ...
5766 * };
5767 * topLevelEventsToDispatchConfig = new Map([
5768 * [TOP_ABORT, { sameConfig }],
5769 * ]);
5770 */
5771
5772var eventTuples = [
5773// Discrete events
5774[TOP_BLUR, 'blur', DiscreteEvent], [TOP_CANCEL, 'cancel', DiscreteEvent], [TOP_CLICK, 'click', DiscreteEvent], [TOP_CLOSE, 'close', DiscreteEvent], [TOP_CONTEXT_MENU, 'contextMenu', DiscreteEvent], [TOP_COPY, 'copy', DiscreteEvent], [TOP_CUT, 'cut', DiscreteEvent], [TOP_AUX_CLICK, 'auxClick', DiscreteEvent], [TOP_DOUBLE_CLICK, 'doubleClick', DiscreteEvent], [TOP_DRAG_END, 'dragEnd', DiscreteEvent], [TOP_DRAG_START, 'dragStart', DiscreteEvent], [TOP_DROP, 'drop', DiscreteEvent], [TOP_FOCUS, 'focus', DiscreteEvent], [TOP_INPUT, 'input', DiscreteEvent], [TOP_INVALID, 'invalid', DiscreteEvent], [TOP_KEY_DOWN, 'keyDown', DiscreteEvent], [TOP_KEY_PRESS, 'keyPress', DiscreteEvent], [TOP_KEY_UP, 'keyUp', DiscreteEvent], [TOP_MOUSE_DOWN, 'mouseDown', DiscreteEvent], [TOP_MOUSE_UP, 'mouseUp', DiscreteEvent], [TOP_PASTE, 'paste', DiscreteEvent], [TOP_PAUSE, 'pause', DiscreteEvent], [TOP_PLAY, 'play', DiscreteEvent], [TOP_POINTER_CANCEL, 'pointerCancel', DiscreteEvent], [TOP_POINTER_DOWN, 'pointerDown', DiscreteEvent], [TOP_POINTER_UP, 'pointerUp', DiscreteEvent], [TOP_RATE_CHANGE, 'rateChange', DiscreteEvent], [TOP_RESET, 'reset', DiscreteEvent], [TOP_SEEKED, 'seeked', DiscreteEvent], [TOP_SUBMIT, 'submit', DiscreteEvent], [TOP_TOUCH_CANCEL, 'touchCancel', DiscreteEvent], [TOP_TOUCH_END, 'touchEnd', DiscreteEvent], [TOP_TOUCH_START, 'touchStart', DiscreteEvent], [TOP_VOLUME_CHANGE, 'volumeChange', DiscreteEvent],
5775
5776// User-blocking events
5777[TOP_DRAG, 'drag', UserBlockingEvent], [TOP_DRAG_ENTER, 'dragEnter', UserBlockingEvent], [TOP_DRAG_EXIT, 'dragExit', UserBlockingEvent], [TOP_DRAG_LEAVE, 'dragLeave', UserBlockingEvent], [TOP_DRAG_OVER, 'dragOver', UserBlockingEvent], [TOP_MOUSE_MOVE, 'mouseMove', UserBlockingEvent], [TOP_MOUSE_OUT, 'mouseOut', UserBlockingEvent], [TOP_MOUSE_OVER, 'mouseOver', UserBlockingEvent], [TOP_POINTER_MOVE, 'pointerMove', UserBlockingEvent], [TOP_POINTER_OUT, 'pointerOut', UserBlockingEvent], [TOP_POINTER_OVER, 'pointerOver', UserBlockingEvent], [TOP_SCROLL, 'scroll', UserBlockingEvent], [TOP_TOGGLE, 'toggle', UserBlockingEvent], [TOP_TOUCH_MOVE, 'touchMove', UserBlockingEvent], [TOP_WHEEL, 'wheel', UserBlockingEvent],
5778
5779// Continuous events
5780[TOP_ABORT, 'abort', ContinuousEvent], [TOP_ANIMATION_END, 'animationEnd', ContinuousEvent], [TOP_ANIMATION_ITERATION, 'animationIteration', ContinuousEvent], [TOP_ANIMATION_START, 'animationStart', ContinuousEvent], [TOP_CAN_PLAY, 'canPlay', ContinuousEvent], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough', ContinuousEvent], [TOP_DURATION_CHANGE, 'durationChange', ContinuousEvent], [TOP_EMPTIED, 'emptied', ContinuousEvent], [TOP_ENCRYPTED, 'encrypted', ContinuousEvent], [TOP_ENDED, 'ended', ContinuousEvent], [TOP_ERROR, 'error', ContinuousEvent], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture', ContinuousEvent], [TOP_LOAD, 'load', ContinuousEvent], [TOP_LOADED_DATA, 'loadedData', ContinuousEvent], [TOP_LOADED_METADATA, 'loadedMetadata', ContinuousEvent], [TOP_LOAD_START, 'loadStart', ContinuousEvent], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture', ContinuousEvent], [TOP_PLAYING, 'playing', ContinuousEvent], [TOP_PROGRESS, 'progress', ContinuousEvent], [TOP_SEEKING, 'seeking', ContinuousEvent], [TOP_STALLED, 'stalled', ContinuousEvent], [TOP_SUSPEND, 'suspend', ContinuousEvent], [TOP_TIME_UPDATE, 'timeUpdate', ContinuousEvent], [TOP_TRANSITION_END, 'transitionEnd', ContinuousEvent], [TOP_WAITING, 'waiting', ContinuousEvent]];
5781
5782var eventTypes$4 = {};
5783var topLevelEventsToDispatchConfig = {};
5784
5785for (var i = 0; i < eventTuples.length; i++) {
5786 var eventTuple = eventTuples[i];
5787 var topEvent = eventTuple[0];
5788 var event = eventTuple[1];
5789 var eventPriority = eventTuple[2];
5790
5791 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
5792 var onEvent = 'on' + capitalizedEvent;
5793
5794 var config = {
5795 phasedRegistrationNames: {
5796 bubbled: onEvent,
5797 captured: onEvent + 'Capture'
5798 },
5799 dependencies: [topEvent],
5800 eventPriority: eventPriority
5801 };
5802 eventTypes$4[event] = config;
5803 topLevelEventsToDispatchConfig[topEvent] = config;
5804}
5805
5806// Only used in DEV for exhaustiveness validation.
5807var 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];
5808
5809var SimpleEventPlugin = {
5810 eventTypes: eventTypes$4,
5811
5812 getEventPriority: function (topLevelType) {
5813 var config = topLevelEventsToDispatchConfig[topLevelType];
5814 return config !== undefined ? config.eventPriority : ContinuousEvent;
5815 },
5816
5817
5818 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5819 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
5820 if (!dispatchConfig) {
5821 return null;
5822 }
5823 var EventConstructor = void 0;
5824 switch (topLevelType) {
5825 case TOP_KEY_PRESS:
5826 // Firefox creates a keypress event for function keys too. This removes
5827 // the unwanted keypress events. Enter is however both printable and
5828 // non-printable. One would expect Tab to be as well (but it isn't).
5829 if (getEventCharCode(nativeEvent) === 0) {
5830 return null;
5831 }
5832 /* falls through */
5833 case TOP_KEY_DOWN:
5834 case TOP_KEY_UP:
5835 EventConstructor = SyntheticKeyboardEvent;
5836 break;
5837 case TOP_BLUR:
5838 case TOP_FOCUS:
5839 EventConstructor = SyntheticFocusEvent;
5840 break;
5841 case TOP_CLICK:
5842 // Firefox creates a click event on right mouse clicks. This removes the
5843 // unwanted click events.
5844 if (nativeEvent.button === 2) {
5845 return null;
5846 }
5847 /* falls through */
5848 case TOP_AUX_CLICK:
5849 case TOP_DOUBLE_CLICK:
5850 case TOP_MOUSE_DOWN:
5851 case TOP_MOUSE_MOVE:
5852 case TOP_MOUSE_UP:
5853 // TODO: Disabled elements should not respond to mouse events
5854 /* falls through */
5855 case TOP_MOUSE_OUT:
5856 case TOP_MOUSE_OVER:
5857 case TOP_CONTEXT_MENU:
5858 EventConstructor = SyntheticMouseEvent;
5859 break;
5860 case TOP_DRAG:
5861 case TOP_DRAG_END:
5862 case TOP_DRAG_ENTER:
5863 case TOP_DRAG_EXIT:
5864 case TOP_DRAG_LEAVE:
5865 case TOP_DRAG_OVER:
5866 case TOP_DRAG_START:
5867 case TOP_DROP:
5868 EventConstructor = SyntheticDragEvent;
5869 break;
5870 case TOP_TOUCH_CANCEL:
5871 case TOP_TOUCH_END:
5872 case TOP_TOUCH_MOVE:
5873 case TOP_TOUCH_START:
5874 EventConstructor = SyntheticTouchEvent;
5875 break;
5876 case TOP_ANIMATION_END:
5877 case TOP_ANIMATION_ITERATION:
5878 case TOP_ANIMATION_START:
5879 EventConstructor = SyntheticAnimationEvent;
5880 break;
5881 case TOP_TRANSITION_END:
5882 EventConstructor = SyntheticTransitionEvent;
5883 break;
5884 case TOP_SCROLL:
5885 EventConstructor = SyntheticUIEvent;
5886 break;
5887 case TOP_WHEEL:
5888 EventConstructor = SyntheticWheelEvent;
5889 break;
5890 case TOP_COPY:
5891 case TOP_CUT:
5892 case TOP_PASTE:
5893 EventConstructor = SyntheticClipboardEvent;
5894 break;
5895 case TOP_GOT_POINTER_CAPTURE:
5896 case TOP_LOST_POINTER_CAPTURE:
5897 case TOP_POINTER_CANCEL:
5898 case TOP_POINTER_DOWN:
5899 case TOP_POINTER_MOVE:
5900 case TOP_POINTER_OUT:
5901 case TOP_POINTER_OVER:
5902 case TOP_POINTER_UP:
5903 EventConstructor = SyntheticPointerEvent;
5904 break;
5905 default:
5906 {
5907 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
5908 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
5909 }
5910 }
5911 // HTML Events
5912 // @see http://www.w3.org/TR/html5/index.html#events-0
5913 EventConstructor = SyntheticEvent;
5914 break;
5915 }
5916 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
5917 accumulateTwoPhaseDispatches(event);
5918 return event;
5919 }
5920};
5921
5922var passiveBrowserEventsSupported = false;
5923
5924// Check if browser support events with passive listeners
5925// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
5926if (enableFlareAPI && canUseDOM) {
5927 try {
5928 var options = {};
5929 // $FlowFixMe: Ignore Flow complaining about needing a value
5930 Object.defineProperty(options, 'passive', {
5931 get: function () {
5932 passiveBrowserEventsSupported = true;
5933 }
5934 });
5935 window.addEventListener('test', options, options);
5936 window.removeEventListener('test', options, options);
5937 } catch (e) {
5938 passiveBrowserEventsSupported = false;
5939 }
5940}
5941
5942// Intentionally not named imports because Rollup would use dynamic dispatch for
5943// CommonJS interop named imports.
5944var UserBlockingPriority = unstable_UserBlockingPriority;
5945var runWithPriority = unstable_runWithPriority;
5946var getEventPriority = SimpleEventPlugin.getEventPriority;
5947
5948
5949var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
5950var callbackBookkeepingPool = [];
5951
5952/**
5953 * Find the deepest React component completely containing the root of the
5954 * passed-in instance (for use when entire React trees are nested within each
5955 * other). If React trees are not nested, returns null.
5956 */
5957function findRootContainerNode(inst) {
5958 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
5959 // traversal, but caching is difficult to do correctly without using a
5960 // mutation observer to listen for all DOM changes.
5961 while (inst.return) {
5962 inst = inst.return;
5963 }
5964 if (inst.tag !== HostRoot) {
5965 // This can happen if we're in a detached tree.
5966 return null;
5967 }
5968 return inst.stateNode.containerInfo;
5969}
5970
5971// Used to store ancestor hierarchy in top level callback
5972function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
5973 if (callbackBookkeepingPool.length) {
5974 var instance = callbackBookkeepingPool.pop();
5975 instance.topLevelType = topLevelType;
5976 instance.nativeEvent = nativeEvent;
5977 instance.targetInst = targetInst;
5978 return instance;
5979 }
5980 return {
5981 topLevelType: topLevelType,
5982 nativeEvent: nativeEvent,
5983 targetInst: targetInst,
5984 ancestors: []
5985 };
5986}
5987
5988function releaseTopLevelCallbackBookKeeping(instance) {
5989 instance.topLevelType = null;
5990 instance.nativeEvent = null;
5991 instance.targetInst = null;
5992 instance.ancestors.length = 0;
5993 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
5994 callbackBookkeepingPool.push(instance);
5995 }
5996}
5997
5998function handleTopLevel(bookKeeping) {
5999 var targetInst = bookKeeping.targetInst;
6000
6001 // Loop through the hierarchy, in case there's any nested components.
6002 // It's important that we build the array of ancestors before calling any
6003 // event handlers, because event handlers can modify the DOM, leading to
6004 // inconsistencies with ReactMount's node cache. See #1105.
6005 var ancestor = targetInst;
6006 do {
6007 if (!ancestor) {
6008 var _ancestors = bookKeeping.ancestors;
6009 _ancestors.push(ancestor);
6010 break;
6011 }
6012 var root = findRootContainerNode(ancestor);
6013 if (!root) {
6014 break;
6015 }
6016 bookKeeping.ancestors.push(ancestor);
6017 ancestor = getClosestInstanceFromNode(root);
6018 } while (ancestor);
6019
6020 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
6021 targetInst = bookKeeping.ancestors[i];
6022 var eventTarget = getEventTarget(bookKeeping.nativeEvent);
6023 var _topLevelType = bookKeeping.topLevelType;
6024 var _nativeEvent = bookKeeping.nativeEvent;
6025
6026 runExtractedPluginEventsInBatch(_topLevelType, targetInst, _nativeEvent, eventTarget);
6027 }
6028}
6029
6030// TODO: can we stop exporting these?
6031var _enabled = true;
6032
6033function setEnabled(enabled) {
6034 _enabled = !!enabled;
6035}
6036
6037function isEnabled() {
6038 return _enabled;
6039}
6040
6041function trapBubbledEvent(topLevelType, element) {
6042 trapEventForPluginEventSystem(element, topLevelType, false);
6043}
6044
6045function trapCapturedEvent(topLevelType, element) {
6046 trapEventForPluginEventSystem(element, topLevelType, true);
6047}
6048
6049function trapEventForResponderEventSystem(element, topLevelType, passive) {
6050 if (enableFlareAPI) {
6051 var rawEventName = getRawEventName(topLevelType);
6052 var eventFlags = RESPONDER_EVENT_SYSTEM;
6053
6054 // If passive option is not supported, then the event will be
6055 // active and not passive, but we flag it as using not being
6056 // supported too. This way the responder event plugins know,
6057 // and can provide polyfills if needed.
6058 if (passive) {
6059 if (passiveBrowserEventsSupported) {
6060 eventFlags |= IS_PASSIVE;
6061 } else {
6062 eventFlags |= IS_ACTIVE;
6063 eventFlags |= PASSIVE_NOT_SUPPORTED;
6064 passive = false;
6065 }
6066 } else {
6067 eventFlags |= IS_ACTIVE;
6068 }
6069 // Check if interactive and wrap in discreteUpdates
6070 var listener = dispatchEvent.bind(null, topLevelType, eventFlags);
6071 if (passiveBrowserEventsSupported) {
6072 addEventCaptureListenerWithPassiveFlag(element, rawEventName, listener, passive);
6073 } else {
6074 addEventCaptureListener(element, rawEventName, listener);
6075 }
6076 }
6077}
6078
6079function trapEventForPluginEventSystem(element, topLevelType, capture) {
6080 var listener = void 0;
6081 switch (getEventPriority(topLevelType)) {
6082 case DiscreteEvent:
6083 listener = dispatchDiscreteEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
6084 break;
6085 case UserBlockingEvent:
6086 listener = dispatchUserBlockingUpdate.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
6087 break;
6088 case ContinuousEvent:
6089 default:
6090 listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
6091 break;
6092 }
6093
6094 var rawEventName = getRawEventName(topLevelType);
6095 if (capture) {
6096 addEventCaptureListener(element, rawEventName, listener);
6097 } else {
6098 addEventBubbleListener(element, rawEventName, listener);
6099 }
6100}
6101
6102function dispatchDiscreteEvent(topLevelType, eventSystemFlags, nativeEvent) {
6103 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
6104 discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, nativeEvent);
6105}
6106
6107function dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, nativeEvent) {
6108 if (enableUserBlockingEvents) {
6109 runWithPriority(UserBlockingPriority, dispatchEvent.bind(null, topLevelType, eventSystemFlags, nativeEvent));
6110 } else {
6111 dispatchEvent(topLevelType, eventSystemFlags, nativeEvent);
6112 }
6113}
6114
6115function dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst) {
6116 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
6117
6118 try {
6119 // Event queue being processed in the same cycle allows
6120 // `preventDefault`.
6121 batchedEventUpdates(handleTopLevel, bookKeeping);
6122 } finally {
6123 releaseTopLevelCallbackBookKeeping(bookKeeping);
6124 }
6125}
6126
6127function dispatchEvent(topLevelType, eventSystemFlags, nativeEvent) {
6128 if (!_enabled) {
6129 return;
6130 }
6131 var nativeEventTarget = getEventTarget(nativeEvent);
6132 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
6133
6134 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
6135 // If we get an event (ex: img onload) before committing that
6136 // component's mount, ignore it for now (that is, treat it as if it was an
6137 // event on a non-React tree). We might also consider queueing events and
6138 // dispatching them after the mount.
6139 targetInst = null;
6140 }
6141
6142 if (enableFlareAPI) {
6143 if (eventSystemFlags === PLUGIN_EVENT_SYSTEM) {
6144 dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
6145 } else {
6146 // React Flare event system
6147 dispatchEventForResponderEventSystem(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
6148 }
6149 } else {
6150 dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
6151 }
6152}
6153
6154/**
6155 * Summary of `ReactBrowserEventEmitter` event handling:
6156 *
6157 * - Top-level delegation is used to trap most native browser events. This
6158 * may only occur in the main thread and is the responsibility of
6159 * ReactDOMEventListener, which is injected and can therefore support
6160 * pluggable event sources. This is the only work that occurs in the main
6161 * thread.
6162 *
6163 * - We normalize and de-duplicate events to account for browser quirks. This
6164 * may be done in the worker thread.
6165 *
6166 * - Forward these native events (with the associated top-level type used to
6167 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
6168 * to extract any synthetic events.
6169 *
6170 * - The `EventPluginHub` will then process each event by annotating them with
6171 * "dispatches", a sequence of listeners and IDs that care about that event.
6172 *
6173 * - The `EventPluginHub` then dispatches the events.
6174 *
6175 * Overview of React and the event system:
6176 *
6177 * +------------+ .
6178 * | DOM | .
6179 * +------------+ .
6180 * | .
6181 * v .
6182 * +------------+ .
6183 * | ReactEvent | .
6184 * | Listener | .
6185 * +------------+ . +-----------+
6186 * | . +--------+|SimpleEvent|
6187 * | . | |Plugin |
6188 * +-----|------+ . v +-----------+
6189 * | | | . +--------------+ +------------+
6190 * | +-----------.--->|EventPluginHub| | Event |
6191 * | | . | | +-----------+ | Propagators|
6192 * | ReactEvent | . | | |TapEvent | |------------|
6193 * | Emitter | . | |<---+|Plugin | |other plugin|
6194 * | | . | | +-----------+ | utilities |
6195 * | +-----------.--->| | +------------+
6196 * | | | . +--------------+
6197 * +-----|------+ . ^ +-----------+
6198 * | . | |Enter/Leave|
6199 * + . +-------+|Plugin |
6200 * +-------------+ . +-----------+
6201 * | application | .
6202 * |-------------| .
6203 * | | .
6204 * | | .
6205 * +-------------+ .
6206 * .
6207 * React Core . General Purpose Event Plugin System
6208 */
6209
6210var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
6211var elementListeningSets = new PossiblyWeakMap();
6212
6213function getListeningSetForElement(element) {
6214 var listeningSet = elementListeningSets.get(element);
6215 if (listeningSet === undefined) {
6216 listeningSet = new Set();
6217 elementListeningSets.set(element, listeningSet);
6218 }
6219 return listeningSet;
6220}
6221
6222/**
6223 * We listen for bubbled touch events on the document object.
6224 *
6225 * Firefox v8.01 (and possibly others) exhibited strange behavior when
6226 * mounting `onmousemove` events at some node that was not the document
6227 * element. The symptoms were that if your mouse is not moving over something
6228 * contained within that mount point (for example on the background) the
6229 * top-level listeners for `onmousemove` won't be called. However, if you
6230 * register the `mousemove` on the document object, then it will of course
6231 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
6232 * top-level listeners to the document object only, at least for these
6233 * movement types of events and possibly all events.
6234 *
6235 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
6236 *
6237 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
6238 * they bubble to document.
6239 *
6240 * @param {string} registrationName Name of listener (e.g. `onClick`).
6241 * @param {object} mountAt Container where to mount the listener
6242 */
6243function listenTo(registrationName, mountAt) {
6244 var listeningSet = getListeningSetForElement(mountAt);
6245 var dependencies = registrationNameDependencies[registrationName];
6246
6247 for (var i = 0; i < dependencies.length; i++) {
6248 var dependency = dependencies[i];
6249 if (!listeningSet.has(dependency)) {
6250 switch (dependency) {
6251 case TOP_SCROLL:
6252 trapCapturedEvent(TOP_SCROLL, mountAt);
6253 break;
6254 case TOP_FOCUS:
6255 case TOP_BLUR:
6256 trapCapturedEvent(TOP_FOCUS, mountAt);
6257 trapCapturedEvent(TOP_BLUR, mountAt);
6258 // We set the flag for a single dependency later in this function,
6259 // but this ensures we mark both as attached rather than just one.
6260 listeningSet.add(TOP_BLUR);
6261 listeningSet.add(TOP_FOCUS);
6262 break;
6263 case TOP_CANCEL:
6264 case TOP_CLOSE:
6265 if (isEventSupported(getRawEventName(dependency))) {
6266 trapCapturedEvent(dependency, mountAt);
6267 }
6268 break;
6269 case TOP_INVALID:
6270 case TOP_SUBMIT:
6271 case TOP_RESET:
6272 // We listen to them on the target DOM elements.
6273 // Some of them bubble so we don't want them to fire twice.
6274 break;
6275 default:
6276 // By default, listen on the top level to all non-media events.
6277 // Media events don't bubble so adding the listener wouldn't do anything.
6278 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
6279 if (!isMediaEvent) {
6280 trapBubbledEvent(dependency, mountAt);
6281 }
6282 break;
6283 }
6284 listeningSet.add(dependency);
6285 }
6286 }
6287}
6288
6289function isListeningToAllDependencies(registrationName, mountAt) {
6290 var listeningSet = getListeningSetForElement(mountAt);
6291 var dependencies = registrationNameDependencies[registrationName];
6292
6293 for (var i = 0; i < dependencies.length; i++) {
6294 var dependency = dependencies[i];
6295 if (!listeningSet.has(dependency)) {
6296 return false;
6297 }
6298 }
6299 return true;
6300}
6301
6302function getActiveElement(doc) {
6303 doc = doc || (typeof document !== 'undefined' ? document : undefined);
6304 if (typeof doc === 'undefined') {
6305 return null;
6306 }
6307 try {
6308 return doc.activeElement || doc.body;
6309 } catch (e) {
6310 return doc.body;
6311 }
6312}
6313
6314/**
6315 * Given any node return the first leaf node without children.
6316 *
6317 * @param {DOMElement|DOMTextNode} node
6318 * @return {DOMElement|DOMTextNode}
6319 */
6320function getLeafNode(node) {
6321 while (node && node.firstChild) {
6322 node = node.firstChild;
6323 }
6324 return node;
6325}
6326
6327/**
6328 * Get the next sibling within a container. This will walk up the
6329 * DOM if a node's siblings have been exhausted.
6330 *
6331 * @param {DOMElement|DOMTextNode} node
6332 * @return {?DOMElement|DOMTextNode}
6333 */
6334function getSiblingNode(node) {
6335 while (node) {
6336 if (node.nextSibling) {
6337 return node.nextSibling;
6338 }
6339 node = node.parentNode;
6340 }
6341}
6342
6343/**
6344 * Get object describing the nodes which contain characters at offset.
6345 *
6346 * @param {DOMElement|DOMTextNode} root
6347 * @param {number} offset
6348 * @return {?object}
6349 */
6350function getNodeForCharacterOffset(root, offset) {
6351 var node = getLeafNode(root);
6352 var nodeStart = 0;
6353 var nodeEnd = 0;
6354
6355 while (node) {
6356 if (node.nodeType === TEXT_NODE) {
6357 nodeEnd = nodeStart + node.textContent.length;
6358
6359 if (nodeStart <= offset && nodeEnd >= offset) {
6360 return {
6361 node: node,
6362 offset: offset - nodeStart
6363 };
6364 }
6365
6366 nodeStart = nodeEnd;
6367 }
6368
6369 node = getLeafNode(getSiblingNode(node));
6370 }
6371}
6372
6373/**
6374 * @param {DOMElement} outerNode
6375 * @return {?object}
6376 */
6377function getOffsets(outerNode) {
6378 var ownerDocument = outerNode.ownerDocument;
6379
6380 var win = ownerDocument && ownerDocument.defaultView || window;
6381 var selection = win.getSelection && win.getSelection();
6382
6383 if (!selection || selection.rangeCount === 0) {
6384 return null;
6385 }
6386
6387 var anchorNode = selection.anchorNode,
6388 anchorOffset = selection.anchorOffset,
6389 focusNode = selection.focusNode,
6390 focusOffset = selection.focusOffset;
6391
6392 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
6393 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
6394 // expose properties, triggering a "Permission denied error" if any of its
6395 // properties are accessed. The only seemingly possible way to avoid erroring
6396 // is to access a property that typically works for non-anonymous divs and
6397 // catch any error that may otherwise arise. See
6398 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
6399
6400 try {
6401 /* eslint-disable no-unused-expressions */
6402 anchorNode.nodeType;
6403 focusNode.nodeType;
6404 /* eslint-enable no-unused-expressions */
6405 } catch (e) {
6406 return null;
6407 }
6408
6409 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
6410}
6411
6412/**
6413 * Returns {start, end} where `start` is the character/codepoint index of
6414 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
6415 * `end` is the index of (focusNode, focusOffset).
6416 *
6417 * Returns null if you pass in garbage input but we should probably just crash.
6418 *
6419 * Exported only for testing.
6420 */
6421function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
6422 var length = 0;
6423 var start = -1;
6424 var end = -1;
6425 var indexWithinAnchor = 0;
6426 var indexWithinFocus = 0;
6427 var node = outerNode;
6428 var parentNode = null;
6429
6430 outer: while (true) {
6431 var next = null;
6432
6433 while (true) {
6434 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
6435 start = length + anchorOffset;
6436 }
6437 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
6438 end = length + focusOffset;
6439 }
6440
6441 if (node.nodeType === TEXT_NODE) {
6442 length += node.nodeValue.length;
6443 }
6444
6445 if ((next = node.firstChild) === null) {
6446 break;
6447 }
6448 // Moving from `node` to its first child `next`.
6449 parentNode = node;
6450 node = next;
6451 }
6452
6453 while (true) {
6454 if (node === outerNode) {
6455 // If `outerNode` has children, this is always the second time visiting
6456 // it. If it has no children, this is still the first loop, and the only
6457 // valid selection is anchorNode and focusNode both equal to this node
6458 // and both offsets 0, in which case we will have handled above.
6459 break outer;
6460 }
6461 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
6462 start = length;
6463 }
6464 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
6465 end = length;
6466 }
6467 if ((next = node.nextSibling) !== null) {
6468 break;
6469 }
6470 node = parentNode;
6471 parentNode = node.parentNode;
6472 }
6473
6474 // Moving from `node` to its next sibling `next`.
6475 node = next;
6476 }
6477
6478 if (start === -1 || end === -1) {
6479 // This should never happen. (Would happen if the anchor/focus nodes aren't
6480 // actually inside the passed-in node.)
6481 return null;
6482 }
6483
6484 return {
6485 start: start,
6486 end: end
6487 };
6488}
6489
6490/**
6491 * In modern non-IE browsers, we can support both forward and backward
6492 * selections.
6493 *
6494 * Note: IE10+ supports the Selection object, but it does not support
6495 * the `extend` method, which means that even in modern IE, it's not possible
6496 * to programmatically create a backward selection. Thus, for all IE
6497 * versions, we use the old IE API to create our selections.
6498 *
6499 * @param {DOMElement|DOMTextNode} node
6500 * @param {object} offsets
6501 */
6502function setOffsets(node, offsets) {
6503 var doc = node.ownerDocument || document;
6504 var win = doc && doc.defaultView || window;
6505
6506 // Edge fails with "Object expected" in some scenarios.
6507 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
6508 // fails when pasting 100+ items)
6509 if (!win.getSelection) {
6510 return;
6511 }
6512
6513 var selection = win.getSelection();
6514 var length = node.textContent.length;
6515 var start = Math.min(offsets.start, length);
6516 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
6517
6518 // IE 11 uses modern selection, but doesn't support the extend method.
6519 // Flip backward selections, so we can set with a single range.
6520 if (!selection.extend && start > end) {
6521 var temp = end;
6522 end = start;
6523 start = temp;
6524 }
6525
6526 var startMarker = getNodeForCharacterOffset(node, start);
6527 var endMarker = getNodeForCharacterOffset(node, end);
6528
6529 if (startMarker && endMarker) {
6530 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
6531 return;
6532 }
6533 var range = doc.createRange();
6534 range.setStart(startMarker.node, startMarker.offset);
6535 selection.removeAllRanges();
6536
6537 if (start > end) {
6538 selection.addRange(range);
6539 selection.extend(endMarker.node, endMarker.offset);
6540 } else {
6541 range.setEnd(endMarker.node, endMarker.offset);
6542 selection.addRange(range);
6543 }
6544 }
6545}
6546
6547function isTextNode(node) {
6548 return node && node.nodeType === TEXT_NODE;
6549}
6550
6551function containsNode(outerNode, innerNode) {
6552 if (!outerNode || !innerNode) {
6553 return false;
6554 } else if (outerNode === innerNode) {
6555 return true;
6556 } else if (isTextNode(outerNode)) {
6557 return false;
6558 } else if (isTextNode(innerNode)) {
6559 return containsNode(outerNode, innerNode.parentNode);
6560 } else if ('contains' in outerNode) {
6561 return outerNode.contains(innerNode);
6562 } else if (outerNode.compareDocumentPosition) {
6563 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
6564 } else {
6565 return false;
6566 }
6567}
6568
6569function isInDocument(node) {
6570 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
6571}
6572
6573function isSameOriginFrame(iframe) {
6574 try {
6575 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
6576 // to throw, e.g. if it has a cross-origin src attribute.
6577 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
6578 // iframe.contentDocument.defaultView;
6579 // A safety way is to access one of the cross origin properties: Window or Location
6580 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
6581 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
6582
6583 return typeof iframe.contentWindow.location.href === 'string';
6584 } catch (err) {
6585 return false;
6586 }
6587}
6588
6589function getActiveElementDeep() {
6590 var win = window;
6591 var element = getActiveElement();
6592 while (element instanceof win.HTMLIFrameElement) {
6593 if (isSameOriginFrame(element)) {
6594 win = element.contentWindow;
6595 } else {
6596 return element;
6597 }
6598 element = getActiveElement(win.document);
6599 }
6600 return element;
6601}
6602
6603/**
6604 * @ReactInputSelection: React input selection module. Based on Selection.js,
6605 * but modified to be suitable for react and has a couple of bug fixes (doesn't
6606 * assume buttons have range selections allowed).
6607 * Input selection module for React.
6608 */
6609
6610/**
6611 * @hasSelectionCapabilities: we get the element types that support selection
6612 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
6613 * and `selectionEnd` rows.
6614 */
6615function hasSelectionCapabilities(elem) {
6616 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
6617 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
6618}
6619
6620function getSelectionInformation() {
6621 var focusedElem = getActiveElementDeep();
6622 return {
6623 focusedElem: focusedElem,
6624 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
6625 };
6626}
6627
6628/**
6629 * @restoreSelection: If any selection information was potentially lost,
6630 * restore it. This is useful when performing operations that could remove dom
6631 * nodes and place them back in, resulting in focus being lost.
6632 */
6633function restoreSelection(priorSelectionInformation) {
6634 var curFocusedElem = getActiveElementDeep();
6635 var priorFocusedElem = priorSelectionInformation.focusedElem;
6636 var priorSelectionRange = priorSelectionInformation.selectionRange;
6637 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
6638 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
6639 setSelection(priorFocusedElem, priorSelectionRange);
6640 }
6641
6642 // Focusing a node can change the scroll position, which is undesirable
6643 var ancestors = [];
6644 var ancestor = priorFocusedElem;
6645 while (ancestor = ancestor.parentNode) {
6646 if (ancestor.nodeType === ELEMENT_NODE) {
6647 ancestors.push({
6648 element: ancestor,
6649 left: ancestor.scrollLeft,
6650 top: ancestor.scrollTop
6651 });
6652 }
6653 }
6654
6655 if (typeof priorFocusedElem.focus === 'function') {
6656 priorFocusedElem.focus();
6657 }
6658
6659 for (var i = 0; i < ancestors.length; i++) {
6660 var info = ancestors[i];
6661 info.element.scrollLeft = info.left;
6662 info.element.scrollTop = info.top;
6663 }
6664 }
6665}
6666
6667/**
6668 * @getSelection: Gets the selection bounds of a focused textarea, input or
6669 * contentEditable node.
6670 * -@input: Look up selection bounds of this input
6671 * -@return {start: selectionStart, end: selectionEnd}
6672 */
6673function getSelection$1(input) {
6674 var selection = void 0;
6675
6676 if ('selectionStart' in input) {
6677 // Modern browser with input or textarea.
6678 selection = {
6679 start: input.selectionStart,
6680 end: input.selectionEnd
6681 };
6682 } else {
6683 // Content editable or old IE textarea.
6684 selection = getOffsets(input);
6685 }
6686
6687 return selection || { start: 0, end: 0 };
6688}
6689
6690/**
6691 * @setSelection: Sets the selection bounds of a textarea or input and focuses
6692 * the input.
6693 * -@input Set selection bounds of this input or textarea
6694 * -@offsets Object of same form that is returned from get*
6695 */
6696function setSelection(input, offsets) {
6697 var start = offsets.start,
6698 end = offsets.end;
6699
6700 if (end === undefined) {
6701 end = start;
6702 }
6703
6704 if ('selectionStart' in input) {
6705 input.selectionStart = start;
6706 input.selectionEnd = Math.min(end, input.value.length);
6707 } else {
6708 setOffsets(input, offsets);
6709 }
6710}
6711
6712var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
6713
6714var eventTypes$3 = {
6715 select: {
6716 phasedRegistrationNames: {
6717 bubbled: 'onSelect',
6718 captured: 'onSelectCapture'
6719 },
6720 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]
6721 }
6722};
6723
6724var activeElement$1 = null;
6725var activeElementInst$1 = null;
6726var lastSelection = null;
6727var mouseDown = false;
6728
6729/**
6730 * Get an object which is a unique representation of the current selection.
6731 *
6732 * The return value will not be consistent across nodes or browsers, but
6733 * two identical selections on the same node will return identical objects.
6734 *
6735 * @param {DOMElement} node
6736 * @return {object}
6737 */
6738function getSelection(node) {
6739 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
6740 return {
6741 start: node.selectionStart,
6742 end: node.selectionEnd
6743 };
6744 } else {
6745 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
6746 var selection = win.getSelection();
6747 return {
6748 anchorNode: selection.anchorNode,
6749 anchorOffset: selection.anchorOffset,
6750 focusNode: selection.focusNode,
6751 focusOffset: selection.focusOffset
6752 };
6753 }
6754}
6755
6756/**
6757 * Get document associated with the event target.
6758 *
6759 * @param {object} nativeEventTarget
6760 * @return {Document}
6761 */
6762function getEventTargetDocument(eventTarget) {
6763 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
6764}
6765
6766/**
6767 * Poll selection to see whether it's changed.
6768 *
6769 * @param {object} nativeEvent
6770 * @param {object} nativeEventTarget
6771 * @return {?SyntheticEvent}
6772 */
6773function constructSelectEvent(nativeEvent, nativeEventTarget) {
6774 // Ensure we have the right element, and that the user is not dragging a
6775 // selection (this matches native `select` event behavior). In HTML5, select
6776 // fires only on input and textarea thus if there's no focused element we
6777 // won't dispatch.
6778 var doc = getEventTargetDocument(nativeEventTarget);
6779
6780 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
6781 return null;
6782 }
6783
6784 // Only fire when selection has actually changed.
6785 var currentSelection = getSelection(activeElement$1);
6786 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
6787 lastSelection = currentSelection;
6788
6789 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
6790
6791 syntheticEvent.type = 'select';
6792 syntheticEvent.target = activeElement$1;
6793
6794 accumulateTwoPhaseDispatches(syntheticEvent);
6795
6796 return syntheticEvent;
6797 }
6798
6799 return null;
6800}
6801
6802/**
6803 * This plugin creates an `onSelect` event that normalizes select events
6804 * across form elements.
6805 *
6806 * Supported elements are:
6807 * - input (see `isTextInputElement`)
6808 * - textarea
6809 * - contentEditable
6810 *
6811 * This differs from native browser implementations in the following ways:
6812 * - Fires on contentEditable fields as well as inputs.
6813 * - Fires for collapsed selection.
6814 * - Fires after user input.
6815 */
6816var SelectEventPlugin = {
6817 eventTypes: eventTypes$3,
6818
6819 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
6820 var doc = getEventTargetDocument(nativeEventTarget);
6821 // Track whether all listeners exists for this plugin. If none exist, we do
6822 // not extract events. See #3639.
6823 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
6824 return null;
6825 }
6826
6827 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
6828
6829 switch (topLevelType) {
6830 // Track the input node that has focus.
6831 case TOP_FOCUS:
6832 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
6833 activeElement$1 = targetNode;
6834 activeElementInst$1 = targetInst;
6835 lastSelection = null;
6836 }
6837 break;
6838 case TOP_BLUR:
6839 activeElement$1 = null;
6840 activeElementInst$1 = null;
6841 lastSelection = null;
6842 break;
6843 // Don't fire the event while the user is dragging. This matches the
6844 // semantics of the native select event.
6845 case TOP_MOUSE_DOWN:
6846 mouseDown = true;
6847 break;
6848 case TOP_CONTEXT_MENU:
6849 case TOP_MOUSE_UP:
6850 case TOP_DRAG_END:
6851 mouseDown = false;
6852 return constructSelectEvent(nativeEvent, nativeEventTarget);
6853 // Chrome and IE fire non-standard event when selection is changed (and
6854 // sometimes when it hasn't). IE's event fires out of order with respect
6855 // to key and input events on deletion, so we discard it.
6856 //
6857 // Firefox doesn't support selectionchange, so check selection status
6858 // after each key entry. The selection changes after keydown and before
6859 // keyup, but we check on keydown as well in the case of holding down a
6860 // key, when multiple keydown events are fired but only one keyup is.
6861 // This is also our approach for IE handling, for the reason above.
6862 case TOP_SELECTION_CHANGE:
6863 if (skipSelectionChangeEvent) {
6864 break;
6865 }
6866 // falls through
6867 case TOP_KEY_DOWN:
6868 case TOP_KEY_UP:
6869 return constructSelectEvent(nativeEvent, nativeEventTarget);
6870 }
6871
6872 return null;
6873 }
6874};
6875
6876/**
6877 * Inject modules for resolving DOM hierarchy and plugin ordering.
6878 */
6879injection.injectEventPluginOrder(DOMEventPluginOrder);
6880setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
6881
6882/**
6883 * Some important event plugins included by default (without having to require
6884 * them).
6885 */
6886injection.injectEventPluginsByName({
6887 SimpleEventPlugin: SimpleEventPlugin,
6888 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
6889 ChangeEventPlugin: ChangeEventPlugin,
6890 SelectEventPlugin: SelectEventPlugin,
6891 BeforeInputEventPlugin: BeforeInputEventPlugin
6892});
6893
6894function endsWith(subject, search) {
6895 var length = subject.length;
6896 return subject.substring(length - search.length, length) === search;
6897}
6898
6899var didWarnSelectedSetOnOption = false;
6900var didWarnInvalidChild = false;
6901
6902function flattenChildren(children) {
6903 var content = '';
6904
6905 // Flatten children. We'll warn if they are invalid
6906 // during validateProps() which runs for hydration too.
6907 // Note that this would throw on non-element objects.
6908 // Elements are stringified (which is normally irrelevant
6909 // but matters for <fbt>).
6910 React.Children.forEach(children, function (child) {
6911 if (child == null) {
6912 return;
6913 }
6914 content += child;
6915 // Note: we don't warn about invalid children here.
6916 // Instead, this is done separately below so that
6917 // it happens during the hydration codepath too.
6918 });
6919
6920 return content;
6921}
6922
6923/**
6924 * Implements an <option> host component that warns when `selected` is set.
6925 */
6926
6927function validateProps(element, props) {
6928 {
6929 // This mirrors the codepath above, but runs for hydration too.
6930 // Warn about invalid children here so that client and hydration are consistent.
6931 // TODO: this seems like it could cause a DEV-only throw for hydration
6932 // if children contains a non-element object. We should try to avoid that.
6933 if (typeof props.children === 'object' && props.children !== null) {
6934 React.Children.forEach(props.children, function (child) {
6935 if (child == null) {
6936 return;
6937 }
6938 if (typeof child === 'string' || typeof child === 'number') {
6939 return;
6940 }
6941 if (typeof child.type !== 'string') {
6942 return;
6943 }
6944 if (!didWarnInvalidChild) {
6945 didWarnInvalidChild = true;
6946 warning$1(false, 'Only strings and numbers are supported as <option> children.');
6947 }
6948 });
6949 }
6950
6951 // TODO: Remove support for `selected` in <option>.
6952 if (props.selected != null && !didWarnSelectedSetOnOption) {
6953 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
6954 didWarnSelectedSetOnOption = true;
6955 }
6956 }
6957}
6958
6959function postMountWrapper$1(element, props) {
6960 // value="" should make a value attribute (#6219)
6961 if (props.value != null) {
6962 element.setAttribute('value', toString(getToStringValue(props.value)));
6963 }
6964}
6965
6966function getHostProps$1(element, props) {
6967 var hostProps = _assign({ children: undefined }, props);
6968 var content = flattenChildren(props.children);
6969
6970 if (content) {
6971 hostProps.children = content;
6972 }
6973
6974 return hostProps;
6975}
6976
6977// TODO: direct imports like some-package/src/* are bad. Fix me.
6978var didWarnValueDefaultValue$1 = void 0;
6979
6980{
6981 didWarnValueDefaultValue$1 = false;
6982}
6983
6984function getDeclarationErrorAddendum() {
6985 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
6986 if (ownerName) {
6987 return '\n\nCheck the render method of `' + ownerName + '`.';
6988 }
6989 return '';
6990}
6991
6992var valuePropNames = ['value', 'defaultValue'];
6993
6994/**
6995 * Validation function for `value` and `defaultValue`.
6996 */
6997function checkSelectPropTypes(props) {
6998 ReactControlledValuePropTypes.checkPropTypes('select', props);
6999
7000 for (var i = 0; i < valuePropNames.length; i++) {
7001 var propName = valuePropNames[i];
7002 if (props[propName] == null) {
7003 continue;
7004 }
7005 var isArray = Array.isArray(props[propName]);
7006 if (props.multiple && !isArray) {
7007 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
7008 } else if (!props.multiple && isArray) {
7009 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
7010 }
7011 }
7012}
7013
7014function updateOptions(node, multiple, propValue, setDefaultSelected) {
7015 var options = node.options;
7016
7017 if (multiple) {
7018 var selectedValues = propValue;
7019 var selectedValue = {};
7020 for (var i = 0; i < selectedValues.length; i++) {
7021 // Prefix to avoid chaos with special keys.
7022 selectedValue['$' + selectedValues[i]] = true;
7023 }
7024 for (var _i = 0; _i < options.length; _i++) {
7025 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
7026 if (options[_i].selected !== selected) {
7027 options[_i].selected = selected;
7028 }
7029 if (selected && setDefaultSelected) {
7030 options[_i].defaultSelected = true;
7031 }
7032 }
7033 } else {
7034 // Do not set `select.value` as exact behavior isn't consistent across all
7035 // browsers for all cases.
7036 var _selectedValue = toString(getToStringValue(propValue));
7037 var defaultSelected = null;
7038 for (var _i2 = 0; _i2 < options.length; _i2++) {
7039 if (options[_i2].value === _selectedValue) {
7040 options[_i2].selected = true;
7041 if (setDefaultSelected) {
7042 options[_i2].defaultSelected = true;
7043 }
7044 return;
7045 }
7046 if (defaultSelected === null && !options[_i2].disabled) {
7047 defaultSelected = options[_i2];
7048 }
7049 }
7050 if (defaultSelected !== null) {
7051 defaultSelected.selected = true;
7052 }
7053 }
7054}
7055
7056/**
7057 * Implements a <select> host component that allows optionally setting the
7058 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
7059 * stringable. If `multiple` is true, the prop must be an array of stringables.
7060 *
7061 * If `value` is not supplied (or null/undefined), user actions that change the
7062 * selected option will trigger updates to the rendered options.
7063 *
7064 * If it is supplied (and not null/undefined), the rendered options will not
7065 * update in response to user actions. Instead, the `value` prop must change in
7066 * order for the rendered options to update.
7067 *
7068 * If `defaultValue` is provided, any options with the supplied values will be
7069 * selected.
7070 */
7071
7072function getHostProps$2(element, props) {
7073 return _assign({}, props, {
7074 value: undefined
7075 });
7076}
7077
7078function initWrapperState$1(element, props) {
7079 var node = element;
7080 {
7081 checkSelectPropTypes(props);
7082 }
7083
7084 node._wrapperState = {
7085 wasMultiple: !!props.multiple
7086 };
7087
7088 {
7089 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
7090 warning$1(false, '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');
7091 didWarnValueDefaultValue$1 = true;
7092 }
7093 }
7094}
7095
7096function postMountWrapper$2(element, props) {
7097 var node = element;
7098 node.multiple = !!props.multiple;
7099 var value = props.value;
7100 if (value != null) {
7101 updateOptions(node, !!props.multiple, value, false);
7102 } else if (props.defaultValue != null) {
7103 updateOptions(node, !!props.multiple, props.defaultValue, true);
7104 }
7105}
7106
7107function postUpdateWrapper(element, props) {
7108 var node = element;
7109 var wasMultiple = node._wrapperState.wasMultiple;
7110 node._wrapperState.wasMultiple = !!props.multiple;
7111
7112 var value = props.value;
7113 if (value != null) {
7114 updateOptions(node, !!props.multiple, value, false);
7115 } else if (wasMultiple !== !!props.multiple) {
7116 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
7117 if (props.defaultValue != null) {
7118 updateOptions(node, !!props.multiple, props.defaultValue, true);
7119 } else {
7120 // Revert the select back to its default unselected state.
7121 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
7122 }
7123 }
7124}
7125
7126function restoreControlledState$2(element, props) {
7127 var node = element;
7128 var value = props.value;
7129
7130 if (value != null) {
7131 updateOptions(node, !!props.multiple, value, false);
7132 }
7133}
7134
7135var didWarnValDefaultVal = false;
7136
7137/**
7138 * Implements a <textarea> host component that allows setting `value`, and
7139 * `defaultValue`. This differs from the traditional DOM API because value is
7140 * usually set as PCDATA children.
7141 *
7142 * If `value` is not supplied (or null/undefined), user actions that affect the
7143 * value will trigger updates to the element.
7144 *
7145 * If `value` is supplied (and not null/undefined), the rendered element will
7146 * not trigger updates to the element. Instead, the `value` prop must change in
7147 * order for the rendered element to be updated.
7148 *
7149 * The rendered element will be initialized with an empty value, the prop
7150 * `defaultValue` if specified, or the children content (deprecated).
7151 */
7152
7153function getHostProps$3(element, props) {
7154 var node = element;
7155 (function () {
7156 if (!(props.dangerouslySetInnerHTML == null)) {
7157 {
7158 throw ReactError(Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.'));
7159 }
7160 }
7161 })();
7162
7163 // Always set children to the same thing. In IE9, the selection range will
7164 // get reset if `textContent` is mutated. We could add a check in setTextContent
7165 // to only set the value if/when the value differs from the node value (which would
7166 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
7167 // solution. The value can be a boolean or object so that's why it's forced
7168 // to be a string.
7169 var hostProps = _assign({}, props, {
7170 value: undefined,
7171 defaultValue: undefined,
7172 children: toString(node._wrapperState.initialValue)
7173 });
7174
7175 return hostProps;
7176}
7177
7178function initWrapperState$2(element, props) {
7179 var node = element;
7180 {
7181 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
7182 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
7183 warning$1(false, '%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');
7184 didWarnValDefaultVal = true;
7185 }
7186 }
7187
7188 var initialValue = props.value;
7189
7190 // Only bother fetching default value if we're going to use it
7191 if (initialValue == null) {
7192 var defaultValue = props.defaultValue;
7193 // TODO (yungsters): Remove support for children content in <textarea>.
7194 var children = props.children;
7195 if (children != null) {
7196 {
7197 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
7198 }
7199 (function () {
7200 if (!(defaultValue == null)) {
7201 {
7202 throw ReactError(Error('If you supply `defaultValue` on a <textarea>, do not pass children.'));
7203 }
7204 }
7205 })();
7206 if (Array.isArray(children)) {
7207 (function () {
7208 if (!(children.length <= 1)) {
7209 {
7210 throw ReactError(Error('<textarea> can only have at most one child.'));
7211 }
7212 }
7213 })();
7214 children = children[0];
7215 }
7216
7217 defaultValue = children;
7218 }
7219 if (defaultValue == null) {
7220 defaultValue = '';
7221 }
7222 initialValue = defaultValue;
7223 }
7224
7225 node._wrapperState = {
7226 initialValue: getToStringValue(initialValue)
7227 };
7228}
7229
7230function updateWrapper$1(element, props) {
7231 var node = element;
7232 var value = getToStringValue(props.value);
7233 var defaultValue = getToStringValue(props.defaultValue);
7234 if (value != null) {
7235 // Cast `value` to a string to ensure the value is set correctly. While
7236 // browsers typically do this as necessary, jsdom doesn't.
7237 var newValue = toString(value);
7238 // To avoid side effects (such as losing text selection), only set value if changed
7239 if (newValue !== node.value) {
7240 node.value = newValue;
7241 }
7242 if (props.defaultValue == null && node.defaultValue !== newValue) {
7243 node.defaultValue = newValue;
7244 }
7245 }
7246 if (defaultValue != null) {
7247 node.defaultValue = toString(defaultValue);
7248 }
7249}
7250
7251function postMountWrapper$3(element, props) {
7252 var node = element;
7253 // This is in postMount because we need access to the DOM node, which is not
7254 // available until after the component has mounted.
7255 var textContent = node.textContent;
7256
7257 // Only set node.value if textContent is equal to the expected
7258 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
7259 // will populate textContent as well.
7260 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
7261 if (textContent === node._wrapperState.initialValue) {
7262 node.value = textContent;
7263 }
7264}
7265
7266function restoreControlledState$3(element, props) {
7267 // DOM component is still mounted; update
7268 updateWrapper$1(element, props);
7269}
7270
7271var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
7272var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
7273var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
7274
7275var Namespaces = {
7276 html: HTML_NAMESPACE$1,
7277 mathml: MATH_NAMESPACE,
7278 svg: SVG_NAMESPACE
7279};
7280
7281// Assumes there is no parent namespace.
7282function getIntrinsicNamespace(type) {
7283 switch (type) {
7284 case 'svg':
7285 return SVG_NAMESPACE;
7286 case 'math':
7287 return MATH_NAMESPACE;
7288 default:
7289 return HTML_NAMESPACE$1;
7290 }
7291}
7292
7293function getChildNamespace(parentNamespace, type) {
7294 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
7295 // No (or default) parent namespace: potential entry point.
7296 return getIntrinsicNamespace(type);
7297 }
7298 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
7299 // We're leaving SVG.
7300 return HTML_NAMESPACE$1;
7301 }
7302 // By default, pass namespace below.
7303 return parentNamespace;
7304}
7305
7306/* globals MSApp */
7307
7308/**
7309 * Create a function which has 'unsafe' privileges (required by windows8 apps)
7310 */
7311var createMicrosoftUnsafeLocalFunction = function (func) {
7312 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
7313 return function (arg0, arg1, arg2, arg3) {
7314 MSApp.execUnsafeLocalFunction(function () {
7315 return func(arg0, arg1, arg2, arg3);
7316 });
7317 };
7318 } else {
7319 return func;
7320 }
7321};
7322
7323// SVG temp container for IE lacking innerHTML
7324var reusableSVGContainer = void 0;
7325
7326/**
7327 * Set the innerHTML property of a node
7328 *
7329 * @param {DOMElement} node
7330 * @param {string} html
7331 * @internal
7332 */
7333var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
7334 // IE does not have innerHTML for SVG nodes, so instead we inject the
7335 // new markup in a temp node and then move the child nodes across into
7336 // the target node
7337
7338 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
7339 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
7340 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
7341 var svgNode = reusableSVGContainer.firstChild;
7342 while (node.firstChild) {
7343 node.removeChild(node.firstChild);
7344 }
7345 while (svgNode.firstChild) {
7346 node.appendChild(svgNode.firstChild);
7347 }
7348 } else {
7349 node.innerHTML = html;
7350 }
7351});
7352
7353/**
7354 * Set the textContent property of a node. For text updates, it's faster
7355 * to set the `nodeValue` of the Text node directly instead of using
7356 * `.textContent` which will remove the existing node and create a new one.
7357 *
7358 * @param {DOMElement} node
7359 * @param {string} text
7360 * @internal
7361 */
7362var setTextContent = function (node, text) {
7363 if (text) {
7364 var firstChild = node.firstChild;
7365
7366 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
7367 firstChild.nodeValue = text;
7368 return;
7369 }
7370 }
7371 node.textContent = text;
7372};
7373
7374// List derived from Gecko source code:
7375// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
7376var shorthandToLonghand = {
7377 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
7378 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
7379 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
7380 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
7381 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
7382 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
7383 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
7384 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
7385 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
7386 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
7387 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
7388 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
7389 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
7390 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
7391 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
7392 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
7393 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
7394 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
7395 columns: ['columnCount', 'columnWidth'],
7396 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
7397 flexFlow: ['flexDirection', 'flexWrap'],
7398 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
7399 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
7400 gap: ['columnGap', 'rowGap'],
7401 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
7402 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
7403 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
7404 gridColumnGap: ['columnGap'],
7405 gridGap: ['columnGap', 'rowGap'],
7406 gridRow: ['gridRowEnd', 'gridRowStart'],
7407 gridRowGap: ['rowGap'],
7408 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
7409 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
7410 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
7411 marker: ['markerEnd', 'markerMid', 'markerStart'],
7412 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
7413 maskPosition: ['maskPositionX', 'maskPositionY'],
7414 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
7415 overflow: ['overflowX', 'overflowY'],
7416 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
7417 placeContent: ['alignContent', 'justifyContent'],
7418 placeItems: ['alignItems', 'justifyItems'],
7419 placeSelf: ['alignSelf', 'justifySelf'],
7420 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
7421 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
7422 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
7423 wordWrap: ['overflowWrap']
7424};
7425
7426/**
7427 * CSS properties which accept numbers but are not in units of "px".
7428 */
7429var isUnitlessNumber = {
7430 animationIterationCount: true,
7431 borderImageOutset: true,
7432 borderImageSlice: true,
7433 borderImageWidth: true,
7434 boxFlex: true,
7435 boxFlexGroup: true,
7436 boxOrdinalGroup: true,
7437 columnCount: true,
7438 columns: true,
7439 flex: true,
7440 flexGrow: true,
7441 flexPositive: true,
7442 flexShrink: true,
7443 flexNegative: true,
7444 flexOrder: true,
7445 gridArea: true,
7446 gridRow: true,
7447 gridRowEnd: true,
7448 gridRowSpan: true,
7449 gridRowStart: true,
7450 gridColumn: true,
7451 gridColumnEnd: true,
7452 gridColumnSpan: true,
7453 gridColumnStart: true,
7454 fontWeight: true,
7455 lineClamp: true,
7456 lineHeight: true,
7457 opacity: true,
7458 order: true,
7459 orphans: true,
7460 tabSize: true,
7461 widows: true,
7462 zIndex: true,
7463 zoom: true,
7464
7465 // SVG-related properties
7466 fillOpacity: true,
7467 floodOpacity: true,
7468 stopOpacity: true,
7469 strokeDasharray: true,
7470 strokeDashoffset: true,
7471 strokeMiterlimit: true,
7472 strokeOpacity: true,
7473 strokeWidth: true
7474};
7475
7476/**
7477 * @param {string} prefix vendor-specific prefix, eg: Webkit
7478 * @param {string} key style name, eg: transitionDuration
7479 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
7480 * WebkitTransitionDuration
7481 */
7482function prefixKey(prefix, key) {
7483 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
7484}
7485
7486/**
7487 * Support style names that may come passed in prefixed by adding permutations
7488 * of vendor prefixes.
7489 */
7490var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
7491
7492// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
7493// infinite loop, because it iterates over the newly added props too.
7494Object.keys(isUnitlessNumber).forEach(function (prop) {
7495 prefixes.forEach(function (prefix) {
7496 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
7497 });
7498});
7499
7500/**
7501 * Convert a value into the proper css writable value. The style name `name`
7502 * should be logical (no hyphens), as specified
7503 * in `CSSProperty.isUnitlessNumber`.
7504 *
7505 * @param {string} name CSS property name such as `topMargin`.
7506 * @param {*} value CSS property value such as `10px`.
7507 * @return {string} Normalized style value with dimensions applied.
7508 */
7509function dangerousStyleValue(name, value, isCustomProperty) {
7510 // Note that we've removed escapeTextForBrowser() calls here since the
7511 // whole string will be escaped when the attribute is injected into
7512 // the markup. If you provide unsafe user data here they can inject
7513 // arbitrary CSS which may be problematic (I couldn't repro this):
7514 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
7515 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
7516 // This is not an XSS hole but instead a potential CSS injection issue
7517 // which has lead to a greater discussion about how we're going to
7518 // trust URLs moving forward. See #2115901
7519
7520 var isEmpty = value == null || typeof value === 'boolean' || value === '';
7521 if (isEmpty) {
7522 return '';
7523 }
7524
7525 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
7526 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
7527 }
7528
7529 return ('' + value).trim();
7530}
7531
7532var uppercasePattern = /([A-Z])/g;
7533var msPattern = /^ms-/;
7534
7535/**
7536 * Hyphenates a camelcased CSS property name, for example:
7537 *
7538 * > hyphenateStyleName('backgroundColor')
7539 * < "background-color"
7540 * > hyphenateStyleName('MozTransition')
7541 * < "-moz-transition"
7542 * > hyphenateStyleName('msTransition')
7543 * < "-ms-transition"
7544 *
7545 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
7546 * is converted to `-ms-`.
7547 */
7548function hyphenateStyleName(name) {
7549 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
7550}
7551
7552var warnValidStyle = function () {};
7553
7554{
7555 // 'msTransform' is correct, but the other prefixes should be capitalized
7556 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
7557 var msPattern$1 = /^-ms-/;
7558 var hyphenPattern = /-(.)/g;
7559
7560 // style values shouldn't contain a semicolon
7561 var badStyleValueWithSemicolonPattern = /;\s*$/;
7562
7563 var warnedStyleNames = {};
7564 var warnedStyleValues = {};
7565 var warnedForNaNValue = false;
7566 var warnedForInfinityValue = false;
7567
7568 var camelize = function (string) {
7569 return string.replace(hyphenPattern, function (_, character) {
7570 return character.toUpperCase();
7571 });
7572 };
7573
7574 var warnHyphenatedStyleName = function (name) {
7575 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
7576 return;
7577 }
7578
7579 warnedStyleNames[name] = true;
7580 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name,
7581 // As Andi Smith suggests
7582 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
7583 // is converted to lowercase `ms`.
7584 camelize(name.replace(msPattern$1, 'ms-')));
7585 };
7586
7587 var warnBadVendoredStyleName = function (name) {
7588 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
7589 return;
7590 }
7591
7592 warnedStyleNames[name] = true;
7593 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
7594 };
7595
7596 var warnStyleValueWithSemicolon = function (name, value) {
7597 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
7598 return;
7599 }
7600
7601 warnedStyleValues[value] = true;
7602 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
7603 };
7604
7605 var warnStyleValueIsNaN = function (name, value) {
7606 if (warnedForNaNValue) {
7607 return;
7608 }
7609
7610 warnedForNaNValue = true;
7611 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name);
7612 };
7613
7614 var warnStyleValueIsInfinity = function (name, value) {
7615 if (warnedForInfinityValue) {
7616 return;
7617 }
7618
7619 warnedForInfinityValue = true;
7620 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name);
7621 };
7622
7623 warnValidStyle = function (name, value) {
7624 if (name.indexOf('-') > -1) {
7625 warnHyphenatedStyleName(name);
7626 } else if (badVendoredStyleNamePattern.test(name)) {
7627 warnBadVendoredStyleName(name);
7628 } else if (badStyleValueWithSemicolonPattern.test(value)) {
7629 warnStyleValueWithSemicolon(name, value);
7630 }
7631
7632 if (typeof value === 'number') {
7633 if (isNaN(value)) {
7634 warnStyleValueIsNaN(name, value);
7635 } else if (!isFinite(value)) {
7636 warnStyleValueIsInfinity(name, value);
7637 }
7638 }
7639 };
7640}
7641
7642var warnValidStyle$1 = warnValidStyle;
7643
7644/**
7645 * Operations for dealing with CSS properties.
7646 */
7647
7648/**
7649 * This creates a string that is expected to be equivalent to the style
7650 * attribute generated by server-side rendering. It by-passes warnings and
7651 * security checks so it's not safe to use this value for anything other than
7652 * comparison. It is only used in DEV for SSR validation.
7653 */
7654function createDangerousStringForStyles(styles) {
7655 {
7656 var serialized = '';
7657 var delimiter = '';
7658 for (var styleName in styles) {
7659 if (!styles.hasOwnProperty(styleName)) {
7660 continue;
7661 }
7662 var styleValue = styles[styleName];
7663 if (styleValue != null) {
7664 var isCustomProperty = styleName.indexOf('--') === 0;
7665 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
7666 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
7667
7668 delimiter = ';';
7669 }
7670 }
7671 return serialized || null;
7672 }
7673}
7674
7675/**
7676 * Sets the value for multiple styles on a node. If a value is specified as
7677 * '' (empty string), the corresponding style property will be unset.
7678 *
7679 * @param {DOMElement} node
7680 * @param {object} styles
7681 */
7682function setValueForStyles(node, styles) {
7683 var style = node.style;
7684 for (var styleName in styles) {
7685 if (!styles.hasOwnProperty(styleName)) {
7686 continue;
7687 }
7688 var isCustomProperty = styleName.indexOf('--') === 0;
7689 {
7690 if (!isCustomProperty) {
7691 warnValidStyle$1(styleName, styles[styleName]);
7692 }
7693 }
7694 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
7695 if (styleName === 'float') {
7696 styleName = 'cssFloat';
7697 }
7698 if (isCustomProperty) {
7699 style.setProperty(styleName, styleValue);
7700 } else {
7701 style[styleName] = styleValue;
7702 }
7703 }
7704}
7705
7706function isValueEmpty(value) {
7707 return value == null || typeof value === 'boolean' || value === '';
7708}
7709
7710/**
7711 * Given {color: 'red', overflow: 'hidden'} returns {
7712 * color: 'color',
7713 * overflowX: 'overflow',
7714 * overflowY: 'overflow',
7715 * }. This can be read as "the overflowY property was set by the overflow
7716 * shorthand". That is, the values are the property that each was derived from.
7717 */
7718function expandShorthandMap(styles) {
7719 var expanded = {};
7720 for (var key in styles) {
7721 var longhands = shorthandToLonghand[key] || [key];
7722 for (var i = 0; i < longhands.length; i++) {
7723 expanded[longhands[i]] = key;
7724 }
7725 }
7726 return expanded;
7727}
7728
7729/**
7730 * When mixing shorthand and longhand property names, we warn during updates if
7731 * we expect an incorrect result to occur. In particular, we warn for:
7732 *
7733 * Updating a shorthand property (longhand gets overwritten):
7734 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
7735 * becomes .style.font = 'baz'
7736 * Removing a shorthand property (longhand gets lost too):
7737 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
7738 * becomes .style.font = ''
7739 * Removing a longhand property (should revert to shorthand; doesn't):
7740 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
7741 * becomes .style.fontVariant = ''
7742 */
7743function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
7744 if (!warnAboutShorthandPropertyCollision) {
7745 return;
7746 }
7747
7748 if (!nextStyles) {
7749 return;
7750 }
7751
7752 var expandedUpdates = expandShorthandMap(styleUpdates);
7753 var expandedStyles = expandShorthandMap(nextStyles);
7754 var warnedAbout = {};
7755 for (var key in expandedUpdates) {
7756 var originalKey = expandedUpdates[key];
7757 var correctOriginalKey = expandedStyles[key];
7758 if (correctOriginalKey && originalKey !== correctOriginalKey) {
7759 var warningKey = originalKey + ',' + correctOriginalKey;
7760 if (warnedAbout[warningKey]) {
7761 continue;
7762 }
7763 warnedAbout[warningKey] = true;
7764 warning$1(false, '%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);
7765 }
7766 }
7767}
7768
7769// For HTML, certain tags should omit their close tag. We keep a whitelist for
7770// those special-case tags.
7771
7772var omittedCloseTags = {
7773 area: true,
7774 base: true,
7775 br: true,
7776 col: true,
7777 embed: true,
7778 hr: true,
7779 img: true,
7780 input: true,
7781 keygen: true,
7782 link: true,
7783 meta: true,
7784 param: true,
7785 source: true,
7786 track: true,
7787 wbr: true
7788 // NOTE: menuitem's close tag should be omitted, but that causes problems.
7789};
7790
7791// For HTML, certain tags cannot have children. This has the same purpose as
7792// `omittedCloseTags` except that `menuitem` should still have its closing tag.
7793
7794var voidElementTags = _assign({
7795 menuitem: true
7796}, omittedCloseTags);
7797
7798// TODO: We can remove this if we add invariantWithStack()
7799// or add stack by default to invariants where possible.
7800var HTML$1 = '__html';
7801
7802var ReactDebugCurrentFrame$3 = null;
7803{
7804 ReactDebugCurrentFrame$3 = ReactSharedInternals.ReactDebugCurrentFrame;
7805}
7806
7807function assertValidProps(tag, props) {
7808 if (!props) {
7809 return;
7810 }
7811 // Note the use of `==` which checks for null or undefined.
7812 if (voidElementTags[tag]) {
7813 (function () {
7814 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {
7815 {
7816 throw ReactError(Error(tag + ' is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.' + (ReactDebugCurrentFrame$3.getStackAddendum())));
7817 }
7818 }
7819 })();
7820 }
7821 if (props.dangerouslySetInnerHTML != null) {
7822 (function () {
7823 if (!(props.children == null)) {
7824 {
7825 throw ReactError(Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.'));
7826 }
7827 }
7828 })();
7829 (function () {
7830 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML$1 in props.dangerouslySetInnerHTML)) {
7831 {
7832 throw ReactError(Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.'));
7833 }
7834 }
7835 })();
7836 }
7837 {
7838 !(props.suppressContentEditableWarning || !props.contentEditable || props.children == null) ? warning$1(false, '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.') : void 0;
7839 }
7840 (function () {
7841 if (!(props.style == null || typeof props.style === 'object')) {
7842 {
7843 throw ReactError(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())));
7844 }
7845 }
7846 })();
7847}
7848
7849function isCustomComponent(tagName, props) {
7850 if (tagName.indexOf('-') === -1) {
7851 return typeof props.is === 'string';
7852 }
7853 switch (tagName) {
7854 // These are reserved SVG and MathML elements.
7855 // We don't mind this whitelist too much because we expect it to never grow.
7856 // The alternative is to track the namespace in a few places which is convoluted.
7857 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
7858 case 'annotation-xml':
7859 case 'color-profile':
7860 case 'font-face':
7861 case 'font-face-src':
7862 case 'font-face-uri':
7863 case 'font-face-format':
7864 case 'font-face-name':
7865 case 'missing-glyph':
7866 return false;
7867 default:
7868 return true;
7869 }
7870}
7871
7872// When adding attributes to the HTML or SVG whitelist, be sure to
7873// also add them to this module to ensure casing and incorrect name
7874// warnings.
7875var possibleStandardNames = {
7876 // HTML
7877 accept: 'accept',
7878 acceptcharset: 'acceptCharset',
7879 'accept-charset': 'acceptCharset',
7880 accesskey: 'accessKey',
7881 action: 'action',
7882 allowfullscreen: 'allowFullScreen',
7883 alt: 'alt',
7884 as: 'as',
7885 async: 'async',
7886 autocapitalize: 'autoCapitalize',
7887 autocomplete: 'autoComplete',
7888 autocorrect: 'autoCorrect',
7889 autofocus: 'autoFocus',
7890 autoplay: 'autoPlay',
7891 autosave: 'autoSave',
7892 capture: 'capture',
7893 cellpadding: 'cellPadding',
7894 cellspacing: 'cellSpacing',
7895 challenge: 'challenge',
7896 charset: 'charSet',
7897 checked: 'checked',
7898 children: 'children',
7899 cite: 'cite',
7900 class: 'className',
7901 classid: 'classID',
7902 classname: 'className',
7903 cols: 'cols',
7904 colspan: 'colSpan',
7905 content: 'content',
7906 contenteditable: 'contentEditable',
7907 contextmenu: 'contextMenu',
7908 controls: 'controls',
7909 controlslist: 'controlsList',
7910 coords: 'coords',
7911 crossorigin: 'crossOrigin',
7912 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
7913 data: 'data',
7914 datetime: 'dateTime',
7915 default: 'default',
7916 defaultchecked: 'defaultChecked',
7917 defaultvalue: 'defaultValue',
7918 defer: 'defer',
7919 dir: 'dir',
7920 disabled: 'disabled',
7921 disablepictureinpicture: 'disablePictureInPicture',
7922 download: 'download',
7923 draggable: 'draggable',
7924 enctype: 'encType',
7925 for: 'htmlFor',
7926 form: 'form',
7927 formmethod: 'formMethod',
7928 formaction: 'formAction',
7929 formenctype: 'formEncType',
7930 formnovalidate: 'formNoValidate',
7931 formtarget: 'formTarget',
7932 frameborder: 'frameBorder',
7933 headers: 'headers',
7934 height: 'height',
7935 hidden: 'hidden',
7936 high: 'high',
7937 href: 'href',
7938 hreflang: 'hrefLang',
7939 htmlfor: 'htmlFor',
7940 httpequiv: 'httpEquiv',
7941 'http-equiv': 'httpEquiv',
7942 icon: 'icon',
7943 id: 'id',
7944 innerhtml: 'innerHTML',
7945 inputmode: 'inputMode',
7946 integrity: 'integrity',
7947 is: 'is',
7948 itemid: 'itemID',
7949 itemprop: 'itemProp',
7950 itemref: 'itemRef',
7951 itemscope: 'itemScope',
7952 itemtype: 'itemType',
7953 keyparams: 'keyParams',
7954 keytype: 'keyType',
7955 kind: 'kind',
7956 label: 'label',
7957 lang: 'lang',
7958 list: 'list',
7959 loop: 'loop',
7960 low: 'low',
7961 manifest: 'manifest',
7962 marginwidth: 'marginWidth',
7963 marginheight: 'marginHeight',
7964 max: 'max',
7965 maxlength: 'maxLength',
7966 media: 'media',
7967 mediagroup: 'mediaGroup',
7968 method: 'method',
7969 min: 'min',
7970 minlength: 'minLength',
7971 multiple: 'multiple',
7972 muted: 'muted',
7973 name: 'name',
7974 nomodule: 'noModule',
7975 nonce: 'nonce',
7976 novalidate: 'noValidate',
7977 open: 'open',
7978 optimum: 'optimum',
7979 pattern: 'pattern',
7980 placeholder: 'placeholder',
7981 playsinline: 'playsInline',
7982 poster: 'poster',
7983 preload: 'preload',
7984 profile: 'profile',
7985 radiogroup: 'radioGroup',
7986 readonly: 'readOnly',
7987 referrerpolicy: 'referrerPolicy',
7988 rel: 'rel',
7989 required: 'required',
7990 reversed: 'reversed',
7991 role: 'role',
7992 rows: 'rows',
7993 rowspan: 'rowSpan',
7994 sandbox: 'sandbox',
7995 scope: 'scope',
7996 scoped: 'scoped',
7997 scrolling: 'scrolling',
7998 seamless: 'seamless',
7999 selected: 'selected',
8000 shape: 'shape',
8001 size: 'size',
8002 sizes: 'sizes',
8003 span: 'span',
8004 spellcheck: 'spellCheck',
8005 src: 'src',
8006 srcdoc: 'srcDoc',
8007 srclang: 'srcLang',
8008 srcset: 'srcSet',
8009 start: 'start',
8010 step: 'step',
8011 style: 'style',
8012 summary: 'summary',
8013 tabindex: 'tabIndex',
8014 target: 'target',
8015 title: 'title',
8016 type: 'type',
8017 usemap: 'useMap',
8018 value: 'value',
8019 width: 'width',
8020 wmode: 'wmode',
8021 wrap: 'wrap',
8022
8023 // SVG
8024 about: 'about',
8025 accentheight: 'accentHeight',
8026 'accent-height': 'accentHeight',
8027 accumulate: 'accumulate',
8028 additive: 'additive',
8029 alignmentbaseline: 'alignmentBaseline',
8030 'alignment-baseline': 'alignmentBaseline',
8031 allowreorder: 'allowReorder',
8032 alphabetic: 'alphabetic',
8033 amplitude: 'amplitude',
8034 arabicform: 'arabicForm',
8035 'arabic-form': 'arabicForm',
8036 ascent: 'ascent',
8037 attributename: 'attributeName',
8038 attributetype: 'attributeType',
8039 autoreverse: 'autoReverse',
8040 azimuth: 'azimuth',
8041 basefrequency: 'baseFrequency',
8042 baselineshift: 'baselineShift',
8043 'baseline-shift': 'baselineShift',
8044 baseprofile: 'baseProfile',
8045 bbox: 'bbox',
8046 begin: 'begin',
8047 bias: 'bias',
8048 by: 'by',
8049 calcmode: 'calcMode',
8050 capheight: 'capHeight',
8051 'cap-height': 'capHeight',
8052 clip: 'clip',
8053 clippath: 'clipPath',
8054 'clip-path': 'clipPath',
8055 clippathunits: 'clipPathUnits',
8056 cliprule: 'clipRule',
8057 'clip-rule': 'clipRule',
8058 color: 'color',
8059 colorinterpolation: 'colorInterpolation',
8060 'color-interpolation': 'colorInterpolation',
8061 colorinterpolationfilters: 'colorInterpolationFilters',
8062 'color-interpolation-filters': 'colorInterpolationFilters',
8063 colorprofile: 'colorProfile',
8064 'color-profile': 'colorProfile',
8065 colorrendering: 'colorRendering',
8066 'color-rendering': 'colorRendering',
8067 contentscripttype: 'contentScriptType',
8068 contentstyletype: 'contentStyleType',
8069 cursor: 'cursor',
8070 cx: 'cx',
8071 cy: 'cy',
8072 d: 'd',
8073 datatype: 'datatype',
8074 decelerate: 'decelerate',
8075 descent: 'descent',
8076 diffuseconstant: 'diffuseConstant',
8077 direction: 'direction',
8078 display: 'display',
8079 divisor: 'divisor',
8080 dominantbaseline: 'dominantBaseline',
8081 'dominant-baseline': 'dominantBaseline',
8082 dur: 'dur',
8083 dx: 'dx',
8084 dy: 'dy',
8085 edgemode: 'edgeMode',
8086 elevation: 'elevation',
8087 enablebackground: 'enableBackground',
8088 'enable-background': 'enableBackground',
8089 end: 'end',
8090 exponent: 'exponent',
8091 externalresourcesrequired: 'externalResourcesRequired',
8092 fill: 'fill',
8093 fillopacity: 'fillOpacity',
8094 'fill-opacity': 'fillOpacity',
8095 fillrule: 'fillRule',
8096 'fill-rule': 'fillRule',
8097 filter: 'filter',
8098 filterres: 'filterRes',
8099 filterunits: 'filterUnits',
8100 floodopacity: 'floodOpacity',
8101 'flood-opacity': 'floodOpacity',
8102 floodcolor: 'floodColor',
8103 'flood-color': 'floodColor',
8104 focusable: 'focusable',
8105 fontfamily: 'fontFamily',
8106 'font-family': 'fontFamily',
8107 fontsize: 'fontSize',
8108 'font-size': 'fontSize',
8109 fontsizeadjust: 'fontSizeAdjust',
8110 'font-size-adjust': 'fontSizeAdjust',
8111 fontstretch: 'fontStretch',
8112 'font-stretch': 'fontStretch',
8113 fontstyle: 'fontStyle',
8114 'font-style': 'fontStyle',
8115 fontvariant: 'fontVariant',
8116 'font-variant': 'fontVariant',
8117 fontweight: 'fontWeight',
8118 'font-weight': 'fontWeight',
8119 format: 'format',
8120 from: 'from',
8121 fx: 'fx',
8122 fy: 'fy',
8123 g1: 'g1',
8124 g2: 'g2',
8125 glyphname: 'glyphName',
8126 'glyph-name': 'glyphName',
8127 glyphorientationhorizontal: 'glyphOrientationHorizontal',
8128 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
8129 glyphorientationvertical: 'glyphOrientationVertical',
8130 'glyph-orientation-vertical': 'glyphOrientationVertical',
8131 glyphref: 'glyphRef',
8132 gradienttransform: 'gradientTransform',
8133 gradientunits: 'gradientUnits',
8134 hanging: 'hanging',
8135 horizadvx: 'horizAdvX',
8136 'horiz-adv-x': 'horizAdvX',
8137 horizoriginx: 'horizOriginX',
8138 'horiz-origin-x': 'horizOriginX',
8139 ideographic: 'ideographic',
8140 imagerendering: 'imageRendering',
8141 'image-rendering': 'imageRendering',
8142 in2: 'in2',
8143 in: 'in',
8144 inlist: 'inlist',
8145 intercept: 'intercept',
8146 k1: 'k1',
8147 k2: 'k2',
8148 k3: 'k3',
8149 k4: 'k4',
8150 k: 'k',
8151 kernelmatrix: 'kernelMatrix',
8152 kernelunitlength: 'kernelUnitLength',
8153 kerning: 'kerning',
8154 keypoints: 'keyPoints',
8155 keysplines: 'keySplines',
8156 keytimes: 'keyTimes',
8157 lengthadjust: 'lengthAdjust',
8158 letterspacing: 'letterSpacing',
8159 'letter-spacing': 'letterSpacing',
8160 lightingcolor: 'lightingColor',
8161 'lighting-color': 'lightingColor',
8162 limitingconeangle: 'limitingConeAngle',
8163 local: 'local',
8164 markerend: 'markerEnd',
8165 'marker-end': 'markerEnd',
8166 markerheight: 'markerHeight',
8167 markermid: 'markerMid',
8168 'marker-mid': 'markerMid',
8169 markerstart: 'markerStart',
8170 'marker-start': 'markerStart',
8171 markerunits: 'markerUnits',
8172 markerwidth: 'markerWidth',
8173 mask: 'mask',
8174 maskcontentunits: 'maskContentUnits',
8175 maskunits: 'maskUnits',
8176 mathematical: 'mathematical',
8177 mode: 'mode',
8178 numoctaves: 'numOctaves',
8179 offset: 'offset',
8180 opacity: 'opacity',
8181 operator: 'operator',
8182 order: 'order',
8183 orient: 'orient',
8184 orientation: 'orientation',
8185 origin: 'origin',
8186 overflow: 'overflow',
8187 overlineposition: 'overlinePosition',
8188 'overline-position': 'overlinePosition',
8189 overlinethickness: 'overlineThickness',
8190 'overline-thickness': 'overlineThickness',
8191 paintorder: 'paintOrder',
8192 'paint-order': 'paintOrder',
8193 panose1: 'panose1',
8194 'panose-1': 'panose1',
8195 pathlength: 'pathLength',
8196 patterncontentunits: 'patternContentUnits',
8197 patterntransform: 'patternTransform',
8198 patternunits: 'patternUnits',
8199 pointerevents: 'pointerEvents',
8200 'pointer-events': 'pointerEvents',
8201 points: 'points',
8202 pointsatx: 'pointsAtX',
8203 pointsaty: 'pointsAtY',
8204 pointsatz: 'pointsAtZ',
8205 prefix: 'prefix',
8206 preservealpha: 'preserveAlpha',
8207 preserveaspectratio: 'preserveAspectRatio',
8208 primitiveunits: 'primitiveUnits',
8209 property: 'property',
8210 r: 'r',
8211 radius: 'radius',
8212 refx: 'refX',
8213 refy: 'refY',
8214 renderingintent: 'renderingIntent',
8215 'rendering-intent': 'renderingIntent',
8216 repeatcount: 'repeatCount',
8217 repeatdur: 'repeatDur',
8218 requiredextensions: 'requiredExtensions',
8219 requiredfeatures: 'requiredFeatures',
8220 resource: 'resource',
8221 restart: 'restart',
8222 result: 'result',
8223 results: 'results',
8224 rotate: 'rotate',
8225 rx: 'rx',
8226 ry: 'ry',
8227 scale: 'scale',
8228 security: 'security',
8229 seed: 'seed',
8230 shaperendering: 'shapeRendering',
8231 'shape-rendering': 'shapeRendering',
8232 slope: 'slope',
8233 spacing: 'spacing',
8234 specularconstant: 'specularConstant',
8235 specularexponent: 'specularExponent',
8236 speed: 'speed',
8237 spreadmethod: 'spreadMethod',
8238 startoffset: 'startOffset',
8239 stddeviation: 'stdDeviation',
8240 stemh: 'stemh',
8241 stemv: 'stemv',
8242 stitchtiles: 'stitchTiles',
8243 stopcolor: 'stopColor',
8244 'stop-color': 'stopColor',
8245 stopopacity: 'stopOpacity',
8246 'stop-opacity': 'stopOpacity',
8247 strikethroughposition: 'strikethroughPosition',
8248 'strikethrough-position': 'strikethroughPosition',
8249 strikethroughthickness: 'strikethroughThickness',
8250 'strikethrough-thickness': 'strikethroughThickness',
8251 string: 'string',
8252 stroke: 'stroke',
8253 strokedasharray: 'strokeDasharray',
8254 'stroke-dasharray': 'strokeDasharray',
8255 strokedashoffset: 'strokeDashoffset',
8256 'stroke-dashoffset': 'strokeDashoffset',
8257 strokelinecap: 'strokeLinecap',
8258 'stroke-linecap': 'strokeLinecap',
8259 strokelinejoin: 'strokeLinejoin',
8260 'stroke-linejoin': 'strokeLinejoin',
8261 strokemiterlimit: 'strokeMiterlimit',
8262 'stroke-miterlimit': 'strokeMiterlimit',
8263 strokewidth: 'strokeWidth',
8264 'stroke-width': 'strokeWidth',
8265 strokeopacity: 'strokeOpacity',
8266 'stroke-opacity': 'strokeOpacity',
8267 suppresscontenteditablewarning: 'suppressContentEditableWarning',
8268 suppresshydrationwarning: 'suppressHydrationWarning',
8269 surfacescale: 'surfaceScale',
8270 systemlanguage: 'systemLanguage',
8271 tablevalues: 'tableValues',
8272 targetx: 'targetX',
8273 targety: 'targetY',
8274 textanchor: 'textAnchor',
8275 'text-anchor': 'textAnchor',
8276 textdecoration: 'textDecoration',
8277 'text-decoration': 'textDecoration',
8278 textlength: 'textLength',
8279 textrendering: 'textRendering',
8280 'text-rendering': 'textRendering',
8281 to: 'to',
8282 transform: 'transform',
8283 typeof: 'typeof',
8284 u1: 'u1',
8285 u2: 'u2',
8286 underlineposition: 'underlinePosition',
8287 'underline-position': 'underlinePosition',
8288 underlinethickness: 'underlineThickness',
8289 'underline-thickness': 'underlineThickness',
8290 unicode: 'unicode',
8291 unicodebidi: 'unicodeBidi',
8292 'unicode-bidi': 'unicodeBidi',
8293 unicoderange: 'unicodeRange',
8294 'unicode-range': 'unicodeRange',
8295 unitsperem: 'unitsPerEm',
8296 'units-per-em': 'unitsPerEm',
8297 unselectable: 'unselectable',
8298 valphabetic: 'vAlphabetic',
8299 'v-alphabetic': 'vAlphabetic',
8300 values: 'values',
8301 vectoreffect: 'vectorEffect',
8302 'vector-effect': 'vectorEffect',
8303 version: 'version',
8304 vertadvy: 'vertAdvY',
8305 'vert-adv-y': 'vertAdvY',
8306 vertoriginx: 'vertOriginX',
8307 'vert-origin-x': 'vertOriginX',
8308 vertoriginy: 'vertOriginY',
8309 'vert-origin-y': 'vertOriginY',
8310 vhanging: 'vHanging',
8311 'v-hanging': 'vHanging',
8312 videographic: 'vIdeographic',
8313 'v-ideographic': 'vIdeographic',
8314 viewbox: 'viewBox',
8315 viewtarget: 'viewTarget',
8316 visibility: 'visibility',
8317 vmathematical: 'vMathematical',
8318 'v-mathematical': 'vMathematical',
8319 vocab: 'vocab',
8320 widths: 'widths',
8321 wordspacing: 'wordSpacing',
8322 'word-spacing': 'wordSpacing',
8323 writingmode: 'writingMode',
8324 'writing-mode': 'writingMode',
8325 x1: 'x1',
8326 x2: 'x2',
8327 x: 'x',
8328 xchannelselector: 'xChannelSelector',
8329 xheight: 'xHeight',
8330 'x-height': 'xHeight',
8331 xlinkactuate: 'xlinkActuate',
8332 'xlink:actuate': 'xlinkActuate',
8333 xlinkarcrole: 'xlinkArcrole',
8334 'xlink:arcrole': 'xlinkArcrole',
8335 xlinkhref: 'xlinkHref',
8336 'xlink:href': 'xlinkHref',
8337 xlinkrole: 'xlinkRole',
8338 'xlink:role': 'xlinkRole',
8339 xlinkshow: 'xlinkShow',
8340 'xlink:show': 'xlinkShow',
8341 xlinktitle: 'xlinkTitle',
8342 'xlink:title': 'xlinkTitle',
8343 xlinktype: 'xlinkType',
8344 'xlink:type': 'xlinkType',
8345 xmlbase: 'xmlBase',
8346 'xml:base': 'xmlBase',
8347 xmllang: 'xmlLang',
8348 'xml:lang': 'xmlLang',
8349 xmlns: 'xmlns',
8350 'xml:space': 'xmlSpace',
8351 xmlnsxlink: 'xmlnsXlink',
8352 'xmlns:xlink': 'xmlnsXlink',
8353 xmlspace: 'xmlSpace',
8354 y1: 'y1',
8355 y2: 'y2',
8356 y: 'y',
8357 ychannelselector: 'yChannelSelector',
8358 z: 'z',
8359 zoomandpan: 'zoomAndPan'
8360};
8361
8362var ariaProperties = {
8363 'aria-current': 0, // state
8364 'aria-details': 0,
8365 'aria-disabled': 0, // state
8366 'aria-hidden': 0, // state
8367 'aria-invalid': 0, // state
8368 'aria-keyshortcuts': 0,
8369 'aria-label': 0,
8370 'aria-roledescription': 0,
8371 // Widget Attributes
8372 'aria-autocomplete': 0,
8373 'aria-checked': 0,
8374 'aria-expanded': 0,
8375 'aria-haspopup': 0,
8376 'aria-level': 0,
8377 'aria-modal': 0,
8378 'aria-multiline': 0,
8379 'aria-multiselectable': 0,
8380 'aria-orientation': 0,
8381 'aria-placeholder': 0,
8382 'aria-pressed': 0,
8383 'aria-readonly': 0,
8384 'aria-required': 0,
8385 'aria-selected': 0,
8386 'aria-sort': 0,
8387 'aria-valuemax': 0,
8388 'aria-valuemin': 0,
8389 'aria-valuenow': 0,
8390 'aria-valuetext': 0,
8391 // Live Region Attributes
8392 'aria-atomic': 0,
8393 'aria-busy': 0,
8394 'aria-live': 0,
8395 'aria-relevant': 0,
8396 // Drag-and-Drop Attributes
8397 'aria-dropeffect': 0,
8398 'aria-grabbed': 0,
8399 // Relationship Attributes
8400 'aria-activedescendant': 0,
8401 'aria-colcount': 0,
8402 'aria-colindex': 0,
8403 'aria-colspan': 0,
8404 'aria-controls': 0,
8405 'aria-describedby': 0,
8406 'aria-errormessage': 0,
8407 'aria-flowto': 0,
8408 'aria-labelledby': 0,
8409 'aria-owns': 0,
8410 'aria-posinset': 0,
8411 'aria-rowcount': 0,
8412 'aria-rowindex': 0,
8413 'aria-rowspan': 0,
8414 'aria-setsize': 0
8415};
8416
8417var warnedProperties = {};
8418var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
8419var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
8420
8421var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
8422
8423function validateProperty(tagName, name) {
8424 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) {
8425 return true;
8426 }
8427
8428 if (rARIACamel.test(name)) {
8429 var ariaName = 'aria-' + name.slice(4).toLowerCase();
8430 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
8431
8432 // If this is an aria-* attribute, but is not listed in the known DOM
8433 // DOM properties, then it is an invalid aria-* attribute.
8434 if (correctName == null) {
8435 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
8436 warnedProperties[name] = true;
8437 return true;
8438 }
8439 // aria-* attributes should be lowercase; suggest the lowercase version.
8440 if (name !== correctName) {
8441 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
8442 warnedProperties[name] = true;
8443 return true;
8444 }
8445 }
8446
8447 if (rARIA.test(name)) {
8448 var lowerCasedName = name.toLowerCase();
8449 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
8450
8451 // If this is an aria-* attribute, but is not listed in the known DOM
8452 // DOM properties, then it is an invalid aria-* attribute.
8453 if (standardName == null) {
8454 warnedProperties[name] = true;
8455 return false;
8456 }
8457 // aria-* attributes should be lowercase; suggest the lowercase version.
8458 if (name !== standardName) {
8459 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
8460 warnedProperties[name] = true;
8461 return true;
8462 }
8463 }
8464
8465 return true;
8466}
8467
8468function warnInvalidARIAProps(type, props) {
8469 var invalidProps = [];
8470
8471 for (var key in props) {
8472 var isValid = validateProperty(type, key);
8473 if (!isValid) {
8474 invalidProps.push(key);
8475 }
8476 }
8477
8478 var unknownPropString = invalidProps.map(function (prop) {
8479 return '`' + prop + '`';
8480 }).join(', ');
8481
8482 if (invalidProps.length === 1) {
8483 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
8484 } else if (invalidProps.length > 1) {
8485 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
8486 }
8487}
8488
8489function validateProperties(type, props) {
8490 if (isCustomComponent(type, props)) {
8491 return;
8492 }
8493 warnInvalidARIAProps(type, props);
8494}
8495
8496var didWarnValueNull = false;
8497
8498function validateProperties$1(type, props) {
8499 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
8500 return;
8501 }
8502
8503 if (props != null && props.value === null && !didWarnValueNull) {
8504 didWarnValueNull = true;
8505 if (type === 'select' && props.multiple) {
8506 warning$1(false, '`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);
8507 } else {
8508 warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
8509 }
8510 }
8511}
8512
8513var validateProperty$1 = function () {};
8514
8515{
8516 var warnedProperties$1 = {};
8517 var _hasOwnProperty = Object.prototype.hasOwnProperty;
8518 var EVENT_NAME_REGEX = /^on./;
8519 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
8520 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
8521 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
8522
8523 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
8524 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
8525 return true;
8526 }
8527
8528 var lowerCasedName = name.toLowerCase();
8529 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
8530 warning$1(false, '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.');
8531 warnedProperties$1[name] = true;
8532 return true;
8533 }
8534
8535 // We can't rely on the event system being injected on the server.
8536 if (canUseEventSystem) {
8537 if (registrationNameModules.hasOwnProperty(name)) {
8538 return true;
8539 }
8540 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
8541 if (registrationName != null) {
8542 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
8543 warnedProperties$1[name] = true;
8544 return true;
8545 }
8546 if (EVENT_NAME_REGEX.test(name)) {
8547 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name);
8548 warnedProperties$1[name] = true;
8549 return true;
8550 }
8551 } else if (EVENT_NAME_REGEX.test(name)) {
8552 // If no event plugins have been injected, we are in a server environment.
8553 // So we can't tell if the event name is correct for sure, but we can filter
8554 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
8555 if (INVALID_EVENT_NAME_REGEX.test(name)) {
8556 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
8557 }
8558 warnedProperties$1[name] = true;
8559 return true;
8560 }
8561
8562 // Let the ARIA attribute hook validate ARIA attributes
8563 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
8564 return true;
8565 }
8566
8567 if (lowerCasedName === 'innerhtml') {
8568 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
8569 warnedProperties$1[name] = true;
8570 return true;
8571 }
8572
8573 if (lowerCasedName === 'aria') {
8574 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
8575 warnedProperties$1[name] = true;
8576 return true;
8577 }
8578
8579 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
8580 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
8581 warnedProperties$1[name] = true;
8582 return true;
8583 }
8584
8585 if (typeof value === 'number' && isNaN(value)) {
8586 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
8587 warnedProperties$1[name] = true;
8588 return true;
8589 }
8590
8591 var propertyInfo = getPropertyInfo(name);
8592 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
8593
8594 // Known attributes should match the casing specified in the property config.
8595 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
8596 var standardName = possibleStandardNames[lowerCasedName];
8597 if (standardName !== name) {
8598 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
8599 warnedProperties$1[name] = true;
8600 return true;
8601 }
8602 } else if (!isReserved && name !== lowerCasedName) {
8603 // Unknown attributes should have lowercase casing since that's how they
8604 // will be cased anyway with server rendering.
8605 warning$1(false, '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);
8606 warnedProperties$1[name] = true;
8607 return true;
8608 }
8609
8610 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
8611 if (value) {
8612 warning$1(false, '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);
8613 } else {
8614 warning$1(false, '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);
8615 }
8616 warnedProperties$1[name] = true;
8617 return true;
8618 }
8619
8620 // Now that we've validated casing, do not validate
8621 // data types for reserved props
8622 if (isReserved) {
8623 return true;
8624 }
8625
8626 // Warn when a known attribute is a bad type
8627 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
8628 warnedProperties$1[name] = true;
8629 return false;
8630 }
8631
8632 // Warn when passing the strings 'false' or 'true' into a boolean prop
8633 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
8634 warning$1(false, '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);
8635 warnedProperties$1[name] = true;
8636 return true;
8637 }
8638
8639 return true;
8640 };
8641}
8642
8643var warnUnknownProperties = function (type, props, canUseEventSystem) {
8644 var unknownProps = [];
8645 for (var key in props) {
8646 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
8647 if (!isValid) {
8648 unknownProps.push(key);
8649 }
8650 }
8651
8652 var unknownPropString = unknownProps.map(function (prop) {
8653 return '`' + prop + '`';
8654 }).join(', ');
8655 if (unknownProps.length === 1) {
8656 warning$1(false, '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);
8657 } else if (unknownProps.length > 1) {
8658 warning$1(false, '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);
8659 }
8660};
8661
8662function validateProperties$2(type, props, canUseEventSystem) {
8663 if (isCustomComponent(type, props)) {
8664 return;
8665 }
8666 warnUnknownProperties(type, props, canUseEventSystem);
8667}
8668
8669// TODO: direct imports like some-package/src/* are bad. Fix me.
8670var didWarnInvalidHydration = false;
8671var didWarnShadyDOM = false;
8672
8673var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
8674var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
8675var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
8676var AUTOFOCUS = 'autoFocus';
8677var CHILDREN = 'children';
8678var STYLE$1 = 'style';
8679var HTML = '__html';
8680var LISTENERS = 'listeners';
8681
8682var HTML_NAMESPACE = Namespaces.html;
8683
8684
8685var warnedUnknownTags = void 0;
8686var suppressHydrationWarning = void 0;
8687
8688var validatePropertiesInDevelopment = void 0;
8689var warnForTextDifference = void 0;
8690var warnForPropDifference = void 0;
8691var warnForExtraAttributes = void 0;
8692var warnForInvalidEventListener = void 0;
8693var canDiffStyleForHydrationWarning = void 0;
8694
8695var normalizeMarkupForTextOrAttribute = void 0;
8696var normalizeHTML = void 0;
8697
8698{
8699 warnedUnknownTags = {
8700 // Chrome is the only major browser not shipping <time>. But as of July
8701 // 2017 it intends to ship it due to widespread usage. We intentionally
8702 // *don't* warn for <time> even if it's unrecognized by Chrome because
8703 // it soon will be, and many apps have been using it anyway.
8704 time: true,
8705 // There are working polyfills for <dialog>. Let people use it.
8706 dialog: true,
8707 // Electron ships a custom <webview> tag to display external web content in
8708 // an isolated frame and process.
8709 // This tag is not present in non Electron environments such as JSDom which
8710 // is often used for testing purposes.
8711 // @see https://electronjs.org/docs/api/webview-tag
8712 webview: true
8713 };
8714
8715 validatePropertiesInDevelopment = function (type, props) {
8716 validateProperties(type, props);
8717 validateProperties$1(type, props);
8718 validateProperties$2(type, props, /* canUseEventSystem */true);
8719 };
8720
8721 // IE 11 parses & normalizes the style attribute as opposed to other
8722 // browsers. It adds spaces and sorts the properties in some
8723 // non-alphabetical order. Handling that would require sorting CSS
8724 // properties in the client & server versions or applying
8725 // `expectedStyle` to a temporary DOM node to read its `style` attribute
8726 // normalized. Since it only affects IE, we're skipping style warnings
8727 // in that browser completely in favor of doing all that work.
8728 // See https://github.com/facebook/react/issues/11807
8729 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
8730
8731 // HTML parsing normalizes CR and CRLF to LF.
8732 // It also can turn \u0000 into \uFFFD inside attributes.
8733 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
8734 // If we have a mismatch, it might be caused by that.
8735 // We will still patch up in this case but not fire the warning.
8736 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
8737 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
8738
8739 normalizeMarkupForTextOrAttribute = function (markup) {
8740 var markupString = typeof markup === 'string' ? markup : '' + markup;
8741 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
8742 };
8743
8744 warnForTextDifference = function (serverText, clientText) {
8745 if (didWarnInvalidHydration) {
8746 return;
8747 }
8748 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
8749 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
8750 if (normalizedServerText === normalizedClientText) {
8751 return;
8752 }
8753 didWarnInvalidHydration = true;
8754 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
8755 };
8756
8757 warnForPropDifference = function (propName, serverValue, clientValue) {
8758 if (didWarnInvalidHydration) {
8759 return;
8760 }
8761 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
8762 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
8763 if (normalizedServerValue === normalizedClientValue) {
8764 return;
8765 }
8766 didWarnInvalidHydration = true;
8767 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
8768 };
8769
8770 warnForExtraAttributes = function (attributeNames) {
8771 if (didWarnInvalidHydration) {
8772 return;
8773 }
8774 didWarnInvalidHydration = true;
8775 var names = [];
8776 attributeNames.forEach(function (name) {
8777 names.push(name);
8778 });
8779 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names);
8780 };
8781
8782 warnForInvalidEventListener = function (registrationName, listener) {
8783 if (listener === false) {
8784 warning$1(false, '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);
8785 } else {
8786 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
8787 }
8788 };
8789
8790 // Parse the HTML and read it back to normalize the HTML string so that it
8791 // can be used for comparison.
8792 normalizeHTML = function (parent, html) {
8793 // We could have created a separate document here to avoid
8794 // re-initializing custom elements if they exist. But this breaks
8795 // how <noscript> is being handled. So we use the same document.
8796 // See the discussion in https://github.com/facebook/react/pull/11157.
8797 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
8798 testElement.innerHTML = html;
8799 return testElement.innerHTML;
8800 };
8801}
8802
8803function ensureListeningTo(rootContainerElement, registrationName) {
8804 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
8805 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
8806 listenTo(registrationName, doc);
8807}
8808
8809function getOwnerDocumentFromRootContainer(rootContainerElement) {
8810 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
8811}
8812
8813function noop() {}
8814
8815function trapClickOnNonInteractiveElement(node) {
8816 // Mobile Safari does not fire properly bubble click events on
8817 // non-interactive elements, which means delegated click listeners do not
8818 // fire. The workaround for this bug involves attaching an empty click
8819 // listener on the target node.
8820 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
8821 // Just set it using the onclick property so that we don't have to manage any
8822 // bookkeeping for it. Not sure if we need to clear it when the listener is
8823 // removed.
8824 // TODO: Only do this for the relevant Safaris maybe?
8825 node.onclick = noop;
8826}
8827
8828function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
8829 for (var propKey in nextProps) {
8830 if (!nextProps.hasOwnProperty(propKey)) {
8831 continue;
8832 }
8833 var nextProp = nextProps[propKey];
8834 if (propKey === STYLE$1) {
8835 {
8836 if (nextProp) {
8837 // Freeze the next style object so that we can assume it won't be
8838 // mutated. We have already warned for this in the past.
8839 Object.freeze(nextProp);
8840 }
8841 }
8842 // Relies on `updateStylesByID` not mutating `styleUpdates`.
8843 setValueForStyles(domElement, nextProp);
8844 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8845 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8846 if (nextHtml != null) {
8847 setInnerHTML(domElement, nextHtml);
8848 }
8849 } else if (propKey === CHILDREN) {
8850 if (typeof nextProp === 'string') {
8851 // Avoid setting initial textContent when the text is empty. In IE11 setting
8852 // textContent on a <textarea> will cause the placeholder to not
8853 // show within the <textarea> until it has been focused and blurred again.
8854 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
8855 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
8856 if (canSetTextContent) {
8857 setTextContent(domElement, nextProp);
8858 }
8859 } else if (typeof nextProp === 'number') {
8860 setTextContent(domElement, '' + nextProp);
8861 }
8862 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
8863 // Noop
8864 } else if (propKey === AUTOFOCUS) {
8865 // We polyfill it separately on the client during commit.
8866 // We could have excluded it in the property list instead of
8867 // adding a special case here, but then it wouldn't be emitted
8868 // on server rendering (but we *do* want to emit it in SSR).
8869 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8870 if (nextProp != null) {
8871 if (true && typeof nextProp !== 'function') {
8872 warnForInvalidEventListener(propKey, nextProp);
8873 }
8874 ensureListeningTo(rootContainerElement, propKey);
8875 }
8876 } else if (nextProp != null) {
8877 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
8878 }
8879 }
8880}
8881
8882function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
8883 // TODO: Handle wasCustomComponentTag
8884 for (var i = 0; i < updatePayload.length; i += 2) {
8885 var propKey = updatePayload[i];
8886 var propValue = updatePayload[i + 1];
8887 if (propKey === STYLE$1) {
8888 setValueForStyles(domElement, propValue);
8889 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8890 setInnerHTML(domElement, propValue);
8891 } else if (propKey === CHILDREN) {
8892 setTextContent(domElement, propValue);
8893 } else {
8894 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
8895 }
8896 }
8897}
8898
8899function createElement(type, props, rootContainerElement, parentNamespace) {
8900 var isCustomComponentTag = void 0;
8901
8902 // We create tags in the namespace of their parent container, except HTML
8903 // tags get no namespace.
8904 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
8905 var domElement = void 0;
8906 var namespaceURI = parentNamespace;
8907 if (namespaceURI === HTML_NAMESPACE) {
8908 namespaceURI = getIntrinsicNamespace(type);
8909 }
8910 if (namespaceURI === HTML_NAMESPACE) {
8911 {
8912 isCustomComponentTag = isCustomComponent(type, props);
8913 // Should this check be gated by parent namespace? Not sure we want to
8914 // allow <SVG> or <mATH>.
8915 !(isCustomComponentTag || type === type.toLowerCase()) ? warning$1(false, '<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type) : void 0;
8916 }
8917
8918 if (type === 'script') {
8919 // Create the script via .innerHTML so its "parser-inserted" flag is
8920 // set to true and it does not execute
8921 var div = ownerDocument.createElement('div');
8922 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
8923 // This is guaranteed to yield a script element.
8924 var firstChild = div.firstChild;
8925 domElement = div.removeChild(firstChild);
8926 } else if (typeof props.is === 'string') {
8927 // $FlowIssue `createElement` should be updated for Web Components
8928 domElement = ownerDocument.createElement(type, { is: props.is });
8929 } else {
8930 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
8931 // See discussion in https://github.com/facebook/react/pull/6896
8932 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
8933 domElement = ownerDocument.createElement(type);
8934 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
8935 // attributes on `select`s needs to be added before `option`s are inserted.
8936 // This prevents:
8937 // - a bug where the `select` does not scroll to the correct option because singular
8938 // `select` elements automatically pick the first item #13222
8939 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
8940 // See https://github.com/facebook/react/issues/13222
8941 // and https://github.com/facebook/react/issues/14239
8942 if (type === 'select') {
8943 var node = domElement;
8944 if (props.multiple) {
8945 node.multiple = true;
8946 } else if (props.size) {
8947 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
8948 // it is possible that no option is selected.
8949 //
8950 // This is only necessary when a select in "single selection mode".
8951 node.size = props.size;
8952 }
8953 }
8954 }
8955 } else {
8956 domElement = ownerDocument.createElementNS(namespaceURI, type);
8957 }
8958
8959 {
8960 if (namespaceURI === HTML_NAMESPACE) {
8961 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
8962 warnedUnknownTags[type] = true;
8963 warning$1(false, 'The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
8964 }
8965 }
8966 }
8967
8968 return domElement;
8969}
8970
8971function createTextNode(text, rootContainerElement) {
8972 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
8973}
8974
8975function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
8976 var isCustomComponentTag = isCustomComponent(tag, rawProps);
8977 {
8978 validatePropertiesInDevelopment(tag, rawProps);
8979 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
8980 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
8981 didWarnShadyDOM = true;
8982 }
8983 }
8984
8985 // TODO: Make sure that we check isMounted before firing any of these events.
8986 var props = void 0;
8987 switch (tag) {
8988 case 'iframe':
8989 case 'object':
8990 case 'embed':
8991 trapBubbledEvent(TOP_LOAD, domElement);
8992 props = rawProps;
8993 break;
8994 case 'video':
8995 case 'audio':
8996 // Create listener for each media event
8997 for (var i = 0; i < mediaEventTypes.length; i++) {
8998 trapBubbledEvent(mediaEventTypes[i], domElement);
8999 }
9000 props = rawProps;
9001 break;
9002 case 'source':
9003 trapBubbledEvent(TOP_ERROR, domElement);
9004 props = rawProps;
9005 break;
9006 case 'img':
9007 case 'image':
9008 case 'link':
9009 trapBubbledEvent(TOP_ERROR, domElement);
9010 trapBubbledEvent(TOP_LOAD, domElement);
9011 props = rawProps;
9012 break;
9013 case 'form':
9014 trapBubbledEvent(TOP_RESET, domElement);
9015 trapBubbledEvent(TOP_SUBMIT, domElement);
9016 props = rawProps;
9017 break;
9018 case 'details':
9019 trapBubbledEvent(TOP_TOGGLE, domElement);
9020 props = rawProps;
9021 break;
9022 case 'input':
9023 initWrapperState(domElement, rawProps);
9024 props = getHostProps(domElement, rawProps);
9025 trapBubbledEvent(TOP_INVALID, domElement);
9026 // For controlled components we always need to ensure we're listening
9027 // to onChange. Even if there is no listener.
9028 ensureListeningTo(rootContainerElement, 'onChange');
9029 break;
9030 case 'option':
9031 validateProps(domElement, rawProps);
9032 props = getHostProps$1(domElement, rawProps);
9033 break;
9034 case 'select':
9035 initWrapperState$1(domElement, rawProps);
9036 props = getHostProps$2(domElement, rawProps);
9037 trapBubbledEvent(TOP_INVALID, domElement);
9038 // For controlled components we always need to ensure we're listening
9039 // to onChange. Even if there is no listener.
9040 ensureListeningTo(rootContainerElement, 'onChange');
9041 break;
9042 case 'textarea':
9043 initWrapperState$2(domElement, rawProps);
9044 props = getHostProps$3(domElement, rawProps);
9045 trapBubbledEvent(TOP_INVALID, domElement);
9046 // For controlled components we always need to ensure we're listening
9047 // to onChange. Even if there is no listener.
9048 ensureListeningTo(rootContainerElement, 'onChange');
9049 break;
9050 default:
9051 props = rawProps;
9052 }
9053
9054 assertValidProps(tag, props);
9055
9056 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
9057
9058 switch (tag) {
9059 case 'input':
9060 // TODO: Make sure we check if this is still unmounted or do any clean
9061 // up necessary since we never stop tracking anymore.
9062 track(domElement);
9063 postMountWrapper(domElement, rawProps, false);
9064 break;
9065 case 'textarea':
9066 // TODO: Make sure we check if this is still unmounted or do any clean
9067 // up necessary since we never stop tracking anymore.
9068 track(domElement);
9069 postMountWrapper$3(domElement, rawProps);
9070 break;
9071 case 'option':
9072 postMountWrapper$1(domElement, rawProps);
9073 break;
9074 case 'select':
9075 postMountWrapper$2(domElement, rawProps);
9076 break;
9077 default:
9078 if (typeof props.onClick === 'function') {
9079 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9080 trapClickOnNonInteractiveElement(domElement);
9081 }
9082 break;
9083 }
9084}
9085
9086// Calculate the diff between the two objects.
9087function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
9088 {
9089 validatePropertiesInDevelopment(tag, nextRawProps);
9090 }
9091
9092 var updatePayload = null;
9093
9094 var lastProps = void 0;
9095 var nextProps = void 0;
9096 switch (tag) {
9097 case 'input':
9098 lastProps = getHostProps(domElement, lastRawProps);
9099 nextProps = getHostProps(domElement, nextRawProps);
9100 updatePayload = [];
9101 break;
9102 case 'option':
9103 lastProps = getHostProps$1(domElement, lastRawProps);
9104 nextProps = getHostProps$1(domElement, nextRawProps);
9105 updatePayload = [];
9106 break;
9107 case 'select':
9108 lastProps = getHostProps$2(domElement, lastRawProps);
9109 nextProps = getHostProps$2(domElement, nextRawProps);
9110 updatePayload = [];
9111 break;
9112 case 'textarea':
9113 lastProps = getHostProps$3(domElement, lastRawProps);
9114 nextProps = getHostProps$3(domElement, nextRawProps);
9115 updatePayload = [];
9116 break;
9117 default:
9118 lastProps = lastRawProps;
9119 nextProps = nextRawProps;
9120 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
9121 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9122 trapClickOnNonInteractiveElement(domElement);
9123 }
9124 break;
9125 }
9126
9127 assertValidProps(tag, nextProps);
9128
9129 var propKey = void 0;
9130 var styleName = void 0;
9131 var styleUpdates = null;
9132 for (propKey in lastProps) {
9133 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
9134 continue;
9135 }
9136 if (propKey === STYLE$1) {
9137 var lastStyle = lastProps[propKey];
9138 for (styleName in lastStyle) {
9139 if (lastStyle.hasOwnProperty(styleName)) {
9140 if (!styleUpdates) {
9141 styleUpdates = {};
9142 }
9143 styleUpdates[styleName] = '';
9144 }
9145 }
9146 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
9147 // Noop. This is handled by the clear text mechanism.
9148 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
9149 // Noop
9150 } else if (propKey === AUTOFOCUS) {
9151 // Noop. It doesn't work on updates anyway.
9152 } else if (registrationNameModules.hasOwnProperty(propKey)) {
9153 // This is a special case. If any listener updates we need to ensure
9154 // that the "current" fiber pointer gets updated so we need a commit
9155 // to update this element.
9156 if (!updatePayload) {
9157 updatePayload = [];
9158 }
9159 } else {
9160 // For all other deleted properties we add it to the queue. We use
9161 // the whitelist in the commit phase instead.
9162 (updatePayload = updatePayload || []).push(propKey, null);
9163 }
9164 }
9165 for (propKey in nextProps) {
9166 var nextProp = nextProps[propKey];
9167 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
9168 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
9169 continue;
9170 }
9171 if (propKey === STYLE$1) {
9172 {
9173 if (nextProp) {
9174 // Freeze the next style object so that we can assume it won't be
9175 // mutated. We have already warned for this in the past.
9176 Object.freeze(nextProp);
9177 }
9178 }
9179 if (lastProp) {
9180 // Unset styles on `lastProp` but not on `nextProp`.
9181 for (styleName in lastProp) {
9182 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
9183 if (!styleUpdates) {
9184 styleUpdates = {};
9185 }
9186 styleUpdates[styleName] = '';
9187 }
9188 }
9189 // Update styles that changed since `lastProp`.
9190 for (styleName in nextProp) {
9191 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
9192 if (!styleUpdates) {
9193 styleUpdates = {};
9194 }
9195 styleUpdates[styleName] = nextProp[styleName];
9196 }
9197 }
9198 } else {
9199 // Relies on `updateStylesByID` not mutating `styleUpdates`.
9200 if (!styleUpdates) {
9201 if (!updatePayload) {
9202 updatePayload = [];
9203 }
9204 updatePayload.push(propKey, styleUpdates);
9205 }
9206 styleUpdates = nextProp;
9207 }
9208 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9209 var nextHtml = nextProp ? nextProp[HTML] : undefined;
9210 var lastHtml = lastProp ? lastProp[HTML] : undefined;
9211 if (nextHtml != null) {
9212 if (lastHtml !== nextHtml) {
9213 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
9214 }
9215 } else {
9216 // TODO: It might be too late to clear this if we have children
9217 // inserted already.
9218 }
9219 } else if (propKey === CHILDREN) {
9220 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
9221 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
9222 }
9223 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
9224 // Noop
9225 } else if (registrationNameModules.hasOwnProperty(propKey)) {
9226 if (nextProp != null) {
9227 // We eagerly listen to this even though we haven't committed yet.
9228 if (true && typeof nextProp !== 'function') {
9229 warnForInvalidEventListener(propKey, nextProp);
9230 }
9231 ensureListeningTo(rootContainerElement, propKey);
9232 }
9233 if (!updatePayload && lastProp !== nextProp) {
9234 // This is a special case. If any listener updates we need to ensure
9235 // that the "current" props pointer gets updated so we need a commit
9236 // to update this element.
9237 updatePayload = [];
9238 }
9239 } else {
9240 // For any other property we always add it to the queue and then we
9241 // filter it out using the whitelist during the commit.
9242 (updatePayload = updatePayload || []).push(propKey, nextProp);
9243 }
9244 }
9245 if (styleUpdates) {
9246 {
9247 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]);
9248 }
9249 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates);
9250 }
9251 return updatePayload;
9252}
9253
9254// Apply the diff.
9255function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
9256 // Update checked *before* name.
9257 // In the middle of an update, it is possible to have multiple checked.
9258 // When a checked radio tries to change name, browser makes another radio's checked false.
9259 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
9260 updateChecked(domElement, nextRawProps);
9261 }
9262
9263 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
9264 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
9265 // Apply the diff.
9266 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
9267
9268 // TODO: Ensure that an update gets scheduled if any of the special props
9269 // changed.
9270 switch (tag) {
9271 case 'input':
9272 // Update the wrapper around inputs *after* updating props. This has to
9273 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
9274 // raise warnings and prevent the new value from being assigned.
9275 updateWrapper(domElement, nextRawProps);
9276 break;
9277 case 'textarea':
9278 updateWrapper$1(domElement, nextRawProps);
9279 break;
9280 case 'select':
9281 // <select> value update needs to occur after <option> children
9282 // reconciliation
9283 postUpdateWrapper(domElement, nextRawProps);
9284 break;
9285 }
9286}
9287
9288function getPossibleStandardName(propName) {
9289 {
9290 var lowerCasedName = propName.toLowerCase();
9291 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
9292 return null;
9293 }
9294 return possibleStandardNames[lowerCasedName] || null;
9295 }
9296 return null;
9297}
9298
9299function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
9300 var isCustomComponentTag = void 0;
9301 var extraAttributeNames = void 0;
9302
9303 {
9304 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
9305 isCustomComponentTag = isCustomComponent(tag, rawProps);
9306 validatePropertiesInDevelopment(tag, rawProps);
9307 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
9308 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
9309 didWarnShadyDOM = true;
9310 }
9311 }
9312
9313 // TODO: Make sure that we check isMounted before firing any of these events.
9314 switch (tag) {
9315 case 'iframe':
9316 case 'object':
9317 case 'embed':
9318 trapBubbledEvent(TOP_LOAD, domElement);
9319 break;
9320 case 'video':
9321 case 'audio':
9322 // Create listener for each media event
9323 for (var i = 0; i < mediaEventTypes.length; i++) {
9324 trapBubbledEvent(mediaEventTypes[i], domElement);
9325 }
9326 break;
9327 case 'source':
9328 trapBubbledEvent(TOP_ERROR, domElement);
9329 break;
9330 case 'img':
9331 case 'image':
9332 case 'link':
9333 trapBubbledEvent(TOP_ERROR, domElement);
9334 trapBubbledEvent(TOP_LOAD, domElement);
9335 break;
9336 case 'form':
9337 trapBubbledEvent(TOP_RESET, domElement);
9338 trapBubbledEvent(TOP_SUBMIT, domElement);
9339 break;
9340 case 'details':
9341 trapBubbledEvent(TOP_TOGGLE, domElement);
9342 break;
9343 case 'input':
9344 initWrapperState(domElement, rawProps);
9345 trapBubbledEvent(TOP_INVALID, domElement);
9346 // For controlled components we always need to ensure we're listening
9347 // to onChange. Even if there is no listener.
9348 ensureListeningTo(rootContainerElement, 'onChange');
9349 break;
9350 case 'option':
9351 validateProps(domElement, rawProps);
9352 break;
9353 case 'select':
9354 initWrapperState$1(domElement, rawProps);
9355 trapBubbledEvent(TOP_INVALID, domElement);
9356 // For controlled components we always need to ensure we're listening
9357 // to onChange. Even if there is no listener.
9358 ensureListeningTo(rootContainerElement, 'onChange');
9359 break;
9360 case 'textarea':
9361 initWrapperState$2(domElement, rawProps);
9362 trapBubbledEvent(TOP_INVALID, domElement);
9363 // For controlled components we always need to ensure we're listening
9364 // to onChange. Even if there is no listener.
9365 ensureListeningTo(rootContainerElement, 'onChange');
9366 break;
9367 }
9368
9369 assertValidProps(tag, rawProps);
9370
9371 {
9372 extraAttributeNames = new Set();
9373 var attributes = domElement.attributes;
9374 for (var _i = 0; _i < attributes.length; _i++) {
9375 var name = attributes[_i].name.toLowerCase();
9376 switch (name) {
9377 // Built-in SSR attribute is whitelisted
9378 case 'data-reactroot':
9379 break;
9380 // Controlled attributes are not validated
9381 // TODO: Only ignore them on controlled tags.
9382 case 'value':
9383 break;
9384 case 'checked':
9385 break;
9386 case 'selected':
9387 break;
9388 default:
9389 // Intentionally use the original name.
9390 // See discussion in https://github.com/facebook/react/pull/10676.
9391 extraAttributeNames.add(attributes[_i].name);
9392 }
9393 }
9394 }
9395
9396 var updatePayload = null;
9397 for (var propKey in rawProps) {
9398 if (!rawProps.hasOwnProperty(propKey)) {
9399 continue;
9400 }
9401 var nextProp = rawProps[propKey];
9402 if (propKey === CHILDREN) {
9403 // For text content children we compare against textContent. This
9404 // might match additional HTML that is hidden when we read it using
9405 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
9406 // satisfies our requirement. Our requirement is not to produce perfect
9407 // HTML and attributes. Ideally we should preserve structure but it's
9408 // ok not to if the visible content is still enough to indicate what
9409 // even listeners these nodes might be wired up to.
9410 // TODO: Warn if there is more than a single textNode as a child.
9411 // TODO: Should we use domElement.firstChild.nodeValue to compare?
9412 if (typeof nextProp === 'string') {
9413 if (domElement.textContent !== nextProp) {
9414 if (true && !suppressHydrationWarning) {
9415 warnForTextDifference(domElement.textContent, nextProp);
9416 }
9417 updatePayload = [CHILDREN, nextProp];
9418 }
9419 } else if (typeof nextProp === 'number') {
9420 if (domElement.textContent !== '' + nextProp) {
9421 if (true && !suppressHydrationWarning) {
9422 warnForTextDifference(domElement.textContent, nextProp);
9423 }
9424 updatePayload = [CHILDREN, '' + nextProp];
9425 }
9426 }
9427 } else if (registrationNameModules.hasOwnProperty(propKey)) {
9428 if (nextProp != null) {
9429 if (true && typeof nextProp !== 'function') {
9430 warnForInvalidEventListener(propKey, nextProp);
9431 }
9432 ensureListeningTo(rootContainerElement, propKey);
9433 }
9434 } else if (true &&
9435 // Convince Flow we've calculated it (it's DEV-only in this method.)
9436 typeof isCustomComponentTag === 'boolean') {
9437 // Validate that the properties correspond to their expected values.
9438 var serverValue = void 0;
9439 var propertyInfo = getPropertyInfo(propKey);
9440 if (suppressHydrationWarning) {
9441 // Don't bother comparing. We're ignoring all these warnings.
9442 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
9443 // Controlled attributes are not validated
9444 // TODO: Only ignore them on controlled tags.
9445 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
9446 // Noop
9447 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9448 var serverHTML = domElement.innerHTML;
9449 var nextHtml = nextProp ? nextProp[HTML] : undefined;
9450 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
9451 if (expectedHTML !== serverHTML) {
9452 warnForPropDifference(propKey, serverHTML, expectedHTML);
9453 }
9454 } else if (propKey === STYLE$1) {
9455 // $FlowFixMe - Should be inferred as not undefined.
9456 extraAttributeNames.delete(propKey);
9457
9458 if (canDiffStyleForHydrationWarning) {
9459 var expectedStyle = createDangerousStringForStyles(nextProp);
9460 serverValue = domElement.getAttribute('style');
9461 if (expectedStyle !== serverValue) {
9462 warnForPropDifference(propKey, serverValue, expectedStyle);
9463 }
9464 }
9465 } else if (isCustomComponentTag) {
9466 // $FlowFixMe - Should be inferred as not undefined.
9467 extraAttributeNames.delete(propKey.toLowerCase());
9468 serverValue = getValueForAttribute(domElement, propKey, nextProp);
9469
9470 if (nextProp !== serverValue) {
9471 warnForPropDifference(propKey, serverValue, nextProp);
9472 }
9473 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
9474 var isMismatchDueToBadCasing = false;
9475 if (propertyInfo !== null) {
9476 // $FlowFixMe - Should be inferred as not undefined.
9477 extraAttributeNames.delete(propertyInfo.attributeName);
9478 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
9479 } else {
9480 var ownNamespace = parentNamespace;
9481 if (ownNamespace === HTML_NAMESPACE) {
9482 ownNamespace = getIntrinsicNamespace(tag);
9483 }
9484 if (ownNamespace === HTML_NAMESPACE) {
9485 // $FlowFixMe - Should be inferred as not undefined.
9486 extraAttributeNames.delete(propKey.toLowerCase());
9487 } else {
9488 var standardName = getPossibleStandardName(propKey);
9489 if (standardName !== null && standardName !== propKey) {
9490 // If an SVG prop is supplied with bad casing, it will
9491 // be successfully parsed from HTML, but will produce a mismatch
9492 // (and would be incorrectly rendered on the client).
9493 // However, we already warn about bad casing elsewhere.
9494 // So we'll skip the misleading extra mismatch warning in this case.
9495 isMismatchDueToBadCasing = true;
9496 // $FlowFixMe - Should be inferred as not undefined.
9497 extraAttributeNames.delete(standardName);
9498 }
9499 // $FlowFixMe - Should be inferred as not undefined.
9500 extraAttributeNames.delete(propKey);
9501 }
9502 serverValue = getValueForAttribute(domElement, propKey, nextProp);
9503 }
9504
9505 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
9506 warnForPropDifference(propKey, serverValue, nextProp);
9507 }
9508 }
9509 }
9510 }
9511
9512 {
9513 // $FlowFixMe - Should be inferred as not undefined.
9514 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
9515 // $FlowFixMe - Should be inferred as not undefined.
9516 warnForExtraAttributes(extraAttributeNames);
9517 }
9518 }
9519
9520 switch (tag) {
9521 case 'input':
9522 // TODO: Make sure we check if this is still unmounted or do any clean
9523 // up necessary since we never stop tracking anymore.
9524 track(domElement);
9525 postMountWrapper(domElement, rawProps, true);
9526 break;
9527 case 'textarea':
9528 // TODO: Make sure we check if this is still unmounted or do any clean
9529 // up necessary since we never stop tracking anymore.
9530 track(domElement);
9531 postMountWrapper$3(domElement, rawProps);
9532 break;
9533 case 'select':
9534 case 'option':
9535 // For input and textarea we current always set the value property at
9536 // post mount to force it to diverge from attributes. However, for
9537 // option and select we don't quite do the same thing and select
9538 // is not resilient to the DOM state changing so we don't do that here.
9539 // TODO: Consider not doing this for input and textarea.
9540 break;
9541 default:
9542 if (typeof rawProps.onClick === 'function') {
9543 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9544 trapClickOnNonInteractiveElement(domElement);
9545 }
9546 break;
9547 }
9548
9549 return updatePayload;
9550}
9551
9552function diffHydratedText(textNode, text) {
9553 var isDifferent = textNode.nodeValue !== text;
9554 return isDifferent;
9555}
9556
9557function warnForUnmatchedText(textNode, text) {
9558 {
9559 warnForTextDifference(textNode.nodeValue, text);
9560 }
9561}
9562
9563function warnForDeletedHydratableElement(parentNode, child) {
9564 {
9565 if (didWarnInvalidHydration) {
9566 return;
9567 }
9568 didWarnInvalidHydration = true;
9569 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
9570 }
9571}
9572
9573function warnForDeletedHydratableText(parentNode, child) {
9574 {
9575 if (didWarnInvalidHydration) {
9576 return;
9577 }
9578 didWarnInvalidHydration = true;
9579 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
9580 }
9581}
9582
9583function warnForInsertedHydratedElement(parentNode, tag, props) {
9584 {
9585 if (didWarnInvalidHydration) {
9586 return;
9587 }
9588 didWarnInvalidHydration = true;
9589 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
9590 }
9591}
9592
9593function warnForInsertedHydratedText(parentNode, text) {
9594 {
9595 if (text === '') {
9596 // We expect to insert empty text nodes since they're not represented in
9597 // the HTML.
9598 // TODO: Remove this special case if we can just avoid inserting empty
9599 // text nodes.
9600 return;
9601 }
9602 if (didWarnInvalidHydration) {
9603 return;
9604 }
9605 didWarnInvalidHydration = true;
9606 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
9607 }
9608}
9609
9610function restoreControlledState$1(domElement, tag, props) {
9611 switch (tag) {
9612 case 'input':
9613 restoreControlledState(domElement, props);
9614 return;
9615 case 'textarea':
9616 restoreControlledState$3(domElement, props);
9617 return;
9618 case 'select':
9619 restoreControlledState$2(domElement, props);
9620 return;
9621 }
9622}
9623
9624function listenToEventResponderEventTypes(eventTypes, element) {
9625 if (enableFlareAPI) {
9626 // Get the listening Set for this element. We use this to track
9627 // what events we're listening to.
9628 var listeningSet = getListeningSetForElement(element);
9629
9630 // Go through each target event type of the event responder
9631 for (var i = 0, length = eventTypes.length; i < length; ++i) {
9632 var eventType = eventTypes[i];
9633 var isPassive = !endsWith(eventType, '_active');
9634 var eventKey = isPassive ? eventType + '_passive' : eventType;
9635 var targetEventType = isPassive ? eventType : eventType.substring(0, eventType.length - 7);
9636 if (!listeningSet.has(eventKey)) {
9637 trapEventForResponderEventSystem(element, targetEventType, isPassive);
9638 listeningSet.add(eventKey);
9639 }
9640 }
9641 }
9642}
9643
9644// We can remove this once the event API is stable and out of a flag
9645if (enableFlareAPI) {
9646 setListenToResponderEventTypes(listenToEventResponderEventTypes);
9647}
9648
9649// TODO: direct imports like some-package/src/* are bad. Fix me.
9650var validateDOMNesting = function () {};
9651var updatedAncestorInfo = function () {};
9652
9653{
9654 // This validation code was written based on the HTML5 parsing spec:
9655 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9656 //
9657 // Note: this does not catch all invalid nesting, nor does it try to (as it's
9658 // not clear what practical benefit doing so provides); instead, we warn only
9659 // for cases where the parser will give a parse tree differing from what React
9660 // intended. For example, <b><div></div></b> is invalid but we don't warn
9661 // because it still parses correctly; we do warn for other cases like nested
9662 // <p> tags where the beginning of the second element implicitly closes the
9663 // first, causing a confusing mess.
9664
9665 // https://html.spec.whatwg.org/multipage/syntax.html#special
9666 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'];
9667
9668 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9669 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
9670
9671 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
9672 // TODO: Distinguish by namespace here -- for <title>, including it here
9673 // errs on the side of fewer warnings
9674 'foreignObject', 'desc', 'title'];
9675
9676 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
9677 var buttonScopeTags = inScopeTags.concat(['button']);
9678
9679 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
9680 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
9681
9682 var emptyAncestorInfo = {
9683 current: null,
9684
9685 formTag: null,
9686 aTagInScope: null,
9687 buttonTagInScope: null,
9688 nobrTagInScope: null,
9689 pTagInButtonScope: null,
9690
9691 listItemTagAutoclosing: null,
9692 dlItemTagAutoclosing: null
9693 };
9694
9695 updatedAncestorInfo = function (oldInfo, tag) {
9696 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
9697 var info = { tag: tag };
9698
9699 if (inScopeTags.indexOf(tag) !== -1) {
9700 ancestorInfo.aTagInScope = null;
9701 ancestorInfo.buttonTagInScope = null;
9702 ancestorInfo.nobrTagInScope = null;
9703 }
9704 if (buttonScopeTags.indexOf(tag) !== -1) {
9705 ancestorInfo.pTagInButtonScope = null;
9706 }
9707
9708 // See rules for 'li', 'dd', 'dt' start tags in
9709 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9710 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
9711 ancestorInfo.listItemTagAutoclosing = null;
9712 ancestorInfo.dlItemTagAutoclosing = null;
9713 }
9714
9715 ancestorInfo.current = info;
9716
9717 if (tag === 'form') {
9718 ancestorInfo.formTag = info;
9719 }
9720 if (tag === 'a') {
9721 ancestorInfo.aTagInScope = info;
9722 }
9723 if (tag === 'button') {
9724 ancestorInfo.buttonTagInScope = info;
9725 }
9726 if (tag === 'nobr') {
9727 ancestorInfo.nobrTagInScope = info;
9728 }
9729 if (tag === 'p') {
9730 ancestorInfo.pTagInButtonScope = info;
9731 }
9732 if (tag === 'li') {
9733 ancestorInfo.listItemTagAutoclosing = info;
9734 }
9735 if (tag === 'dd' || tag === 'dt') {
9736 ancestorInfo.dlItemTagAutoclosing = info;
9737 }
9738
9739 return ancestorInfo;
9740 };
9741
9742 /**
9743 * Returns whether
9744 */
9745 var isTagValidWithParent = function (tag, parentTag) {
9746 // First, let's check if we're in an unusual parsing mode...
9747 switch (parentTag) {
9748 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
9749 case 'select':
9750 return tag === 'option' || tag === 'optgroup' || tag === '#text';
9751 case 'optgroup':
9752 return tag === 'option' || tag === '#text';
9753 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
9754 // but
9755 case 'option':
9756 return tag === '#text';
9757 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
9758 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
9759 // No special behavior since these rules fall back to "in body" mode for
9760 // all except special table nodes which cause bad parsing behavior anyway.
9761
9762 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
9763 case 'tr':
9764 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
9765 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
9766 case 'tbody':
9767 case 'thead':
9768 case 'tfoot':
9769 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
9770 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
9771 case 'colgroup':
9772 return tag === 'col' || tag === 'template';
9773 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
9774 case 'table':
9775 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
9776 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
9777 case 'head':
9778 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
9779 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
9780 case 'html':
9781 return tag === 'head' || tag === 'body' || tag === 'frameset';
9782 case 'frameset':
9783 return tag === 'frame';
9784 case '#document':
9785 return tag === 'html';
9786 }
9787
9788 // Probably in the "in body" parsing mode, so we outlaw only tag combos
9789 // where the parsing rules cause implicit opens or closes to be added.
9790 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9791 switch (tag) {
9792 case 'h1':
9793 case 'h2':
9794 case 'h3':
9795 case 'h4':
9796 case 'h5':
9797 case 'h6':
9798 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
9799
9800 case 'rp':
9801 case 'rt':
9802 return impliedEndTags.indexOf(parentTag) === -1;
9803
9804 case 'body':
9805 case 'caption':
9806 case 'col':
9807 case 'colgroup':
9808 case 'frameset':
9809 case 'frame':
9810 case 'head':
9811 case 'html':
9812 case 'tbody':
9813 case 'td':
9814 case 'tfoot':
9815 case 'th':
9816 case 'thead':
9817 case 'tr':
9818 // These tags are only valid with a few parents that have special child
9819 // parsing rules -- if we're down here, then none of those matched and
9820 // so we allow it only if we don't know what the parent is, as all other
9821 // cases are invalid.
9822 return parentTag == null;
9823 }
9824
9825 return true;
9826 };
9827
9828 /**
9829 * Returns whether
9830 */
9831 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
9832 switch (tag) {
9833 case 'address':
9834 case 'article':
9835 case 'aside':
9836 case 'blockquote':
9837 case 'center':
9838 case 'details':
9839 case 'dialog':
9840 case 'dir':
9841 case 'div':
9842 case 'dl':
9843 case 'fieldset':
9844 case 'figcaption':
9845 case 'figure':
9846 case 'footer':
9847 case 'header':
9848 case 'hgroup':
9849 case 'main':
9850 case 'menu':
9851 case 'nav':
9852 case 'ol':
9853 case 'p':
9854 case 'section':
9855 case 'summary':
9856 case 'ul':
9857 case 'pre':
9858 case 'listing':
9859 case 'table':
9860 case 'hr':
9861 case 'xmp':
9862 case 'h1':
9863 case 'h2':
9864 case 'h3':
9865 case 'h4':
9866 case 'h5':
9867 case 'h6':
9868 return ancestorInfo.pTagInButtonScope;
9869
9870 case 'form':
9871 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
9872
9873 case 'li':
9874 return ancestorInfo.listItemTagAutoclosing;
9875
9876 case 'dd':
9877 case 'dt':
9878 return ancestorInfo.dlItemTagAutoclosing;
9879
9880 case 'button':
9881 return ancestorInfo.buttonTagInScope;
9882
9883 case 'a':
9884 // Spec says something about storing a list of markers, but it sounds
9885 // equivalent to this check.
9886 return ancestorInfo.aTagInScope;
9887
9888 case 'nobr':
9889 return ancestorInfo.nobrTagInScope;
9890 }
9891
9892 return null;
9893 };
9894
9895 var didWarn$1 = {};
9896
9897 validateDOMNesting = function (childTag, childText, ancestorInfo) {
9898 ancestorInfo = ancestorInfo || emptyAncestorInfo;
9899 var parentInfo = ancestorInfo.current;
9900 var parentTag = parentInfo && parentInfo.tag;
9901
9902 if (childText != null) {
9903 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
9904 childTag = '#text';
9905 }
9906
9907 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
9908 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
9909 var invalidParentOrAncestor = invalidParent || invalidAncestor;
9910 if (!invalidParentOrAncestor) {
9911 return;
9912 }
9913
9914 var ancestorTag = invalidParentOrAncestor.tag;
9915 var addendum = getCurrentFiberStackInDev();
9916
9917 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
9918 if (didWarn$1[warnKey]) {
9919 return;
9920 }
9921 didWarn$1[warnKey] = true;
9922
9923 var tagDisplayName = childTag;
9924 var whitespaceInfo = '';
9925 if (childTag === '#text') {
9926 if (/\S/.test(childText)) {
9927 tagDisplayName = 'Text nodes';
9928 } else {
9929 tagDisplayName = 'Whitespace text nodes';
9930 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
9931 }
9932 } else {
9933 tagDisplayName = '<' + childTag + '>';
9934 }
9935
9936 if (invalidParent) {
9937 var info = '';
9938 if (ancestorTag === 'table' && childTag === 'tr') {
9939 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
9940 }
9941 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
9942 } else {
9943 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
9944 }
9945 };
9946}
9947
9948// Renderers that don't support persistence
9949// can re-export everything from this module.
9950
9951function shim() {
9952 (function () {
9953 {
9954 {
9955 throw ReactError(Error('The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.'));
9956 }
9957 }
9958 })();
9959}
9960
9961// Persistence (when unsupported)
9962var supportsPersistence = false;
9963var cloneInstance = shim;
9964var cloneFundamentalInstance = shim;
9965var createContainerChildSet = shim;
9966var appendChildToContainerChildSet = shim;
9967var finalizeContainerChildren = shim;
9968var replaceContainerChildren = shim;
9969var cloneHiddenInstance = shim;
9970var cloneHiddenTextInstance = shim;
9971
9972var SUPPRESS_HYDRATION_WARNING = void 0;
9973{
9974 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
9975}
9976
9977var SUSPENSE_START_DATA = '$';
9978var SUSPENSE_END_DATA = '/$';
9979var SUSPENSE_PENDING_START_DATA = '$?';
9980var SUSPENSE_FALLBACK_START_DATA = '$!';
9981
9982var STYLE = 'style';
9983
9984var eventsEnabled = null;
9985var selectionInformation = null;
9986
9987function shouldAutoFocusHostComponent(type, props) {
9988 switch (type) {
9989 case 'button':
9990 case 'input':
9991 case 'select':
9992 case 'textarea':
9993 return !!props.autoFocus;
9994 }
9995 return false;
9996}
9997
9998function getRootHostContext(rootContainerInstance) {
9999 var type = void 0;
10000 var namespace = void 0;
10001 var nodeType = rootContainerInstance.nodeType;
10002 switch (nodeType) {
10003 case DOCUMENT_NODE:
10004 case DOCUMENT_FRAGMENT_NODE:
10005 {
10006 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
10007 var root = rootContainerInstance.documentElement;
10008 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
10009 break;
10010 }
10011 default:
10012 {
10013 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
10014 var ownNamespace = container.namespaceURI || null;
10015 type = container.tagName;
10016 namespace = getChildNamespace(ownNamespace, type);
10017 break;
10018 }
10019 }
10020 {
10021 var validatedTag = type.toLowerCase();
10022 var _ancestorInfo = updatedAncestorInfo(null, validatedTag);
10023 return { namespace: namespace, ancestorInfo: _ancestorInfo };
10024 }
10025 return namespace;
10026}
10027
10028function getChildHostContext(parentHostContext, type, rootContainerInstance) {
10029 {
10030 var parentHostContextDev = parentHostContext;
10031 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
10032 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
10033 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
10034 }
10035 var parentNamespace = parentHostContext;
10036 return getChildNamespace(parentNamespace, type);
10037}
10038
10039function getPublicInstance(instance) {
10040 return instance;
10041}
10042
10043function prepareForCommit(containerInfo) {
10044 eventsEnabled = isEnabled();
10045 selectionInformation = getSelectionInformation();
10046 setEnabled(false);
10047}
10048
10049function resetAfterCommit(containerInfo) {
10050 restoreSelection(selectionInformation);
10051 selectionInformation = null;
10052 setEnabled(eventsEnabled);
10053 eventsEnabled = null;
10054}
10055
10056function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10057 var parentNamespace = void 0;
10058 {
10059 // TODO: take namespace into account when validating.
10060 var hostContextDev = hostContext;
10061 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
10062 if (typeof props.children === 'string' || typeof props.children === 'number') {
10063 var string = '' + props.children;
10064 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10065 validateDOMNesting(null, string, ownAncestorInfo);
10066 }
10067 parentNamespace = hostContextDev.namespace;
10068 }
10069 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
10070 precacheFiberNode(internalInstanceHandle, domElement);
10071 updateFiberProps(domElement, props);
10072 return domElement;
10073}
10074
10075function appendInitialChild(parentInstance, child) {
10076 parentInstance.appendChild(child);
10077}
10078
10079function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
10080 setInitialProperties(domElement, type, props, rootContainerInstance);
10081 return shouldAutoFocusHostComponent(type, props);
10082}
10083
10084function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
10085 {
10086 var hostContextDev = hostContext;
10087 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
10088 var string = '' + newProps.children;
10089 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10090 validateDOMNesting(null, string, ownAncestorInfo);
10091 }
10092 }
10093 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
10094}
10095
10096function shouldSetTextContent(type, props) {
10097 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;
10098}
10099
10100function shouldDeprioritizeSubtree(type, props) {
10101 return !!props.hidden;
10102}
10103
10104function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
10105 {
10106 var hostContextDev = hostContext;
10107 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
10108 }
10109 var textNode = createTextNode(text, rootContainerInstance);
10110 precacheFiberNode(internalInstanceHandle, textNode);
10111 return textNode;
10112}
10113
10114var isPrimaryRenderer = true;
10115var warnsIfNotActing = true;
10116// This initialization code may run even on server environments
10117// if a component just imports ReactDOM (e.g. for findDOMNode).
10118// Some environments might not have setTimeout or clearTimeout.
10119var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
10120var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
10121var noTimeout = -1;
10122
10123// -------------------
10124// Mutation
10125// -------------------
10126
10127var supportsMutation = true;
10128
10129function commitMount(domElement, type, newProps, internalInstanceHandle) {
10130 // Despite the naming that might imply otherwise, this method only
10131 // fires if there is an `Update` effect scheduled during mounting.
10132 // This happens if `finalizeInitialChildren` returns `true` (which it
10133 // does to implement the `autoFocus` attribute on the client). But
10134 // there are also other cases when this might happen (such as patching
10135 // up text content during hydration mismatch). So we'll check this again.
10136 if (shouldAutoFocusHostComponent(type, newProps)) {
10137 domElement.focus();
10138 }
10139}
10140
10141function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
10142 // Update the props handle so that we know which props are the ones with
10143 // with current event handlers.
10144 updateFiberProps(domElement, newProps);
10145 // Apply the diff to the DOM node.
10146 updateProperties(domElement, updatePayload, type, oldProps, newProps);
10147}
10148
10149function resetTextContent(domElement) {
10150 setTextContent(domElement, '');
10151}
10152
10153function commitTextUpdate(textInstance, oldText, newText) {
10154 textInstance.nodeValue = newText;
10155}
10156
10157function appendChild(parentInstance, child) {
10158 parentInstance.appendChild(child);
10159}
10160
10161function appendChildToContainer(container, child) {
10162 var parentNode = void 0;
10163 if (container.nodeType === COMMENT_NODE) {
10164 parentNode = container.parentNode;
10165 parentNode.insertBefore(child, container);
10166 } else {
10167 parentNode = container;
10168 parentNode.appendChild(child);
10169 }
10170 // This container might be used for a portal.
10171 // If something inside a portal is clicked, that click should bubble
10172 // through the React tree. However, on Mobile Safari the click would
10173 // never bubble through the *DOM* tree unless an ancestor with onclick
10174 // event exists. So we wouldn't see it and dispatch it.
10175 // This is why we ensure that non React root containers have inline onclick
10176 // defined.
10177 // https://github.com/facebook/react/issues/11918
10178 var reactRootContainer = container._reactRootContainer;
10179 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
10180 // TODO: This cast may not be sound for SVG, MathML or custom elements.
10181 trapClickOnNonInteractiveElement(parentNode);
10182 }
10183}
10184
10185function insertBefore(parentInstance, child, beforeChild) {
10186 parentInstance.insertBefore(child, beforeChild);
10187}
10188
10189function insertInContainerBefore(container, child, beforeChild) {
10190 if (container.nodeType === COMMENT_NODE) {
10191 container.parentNode.insertBefore(child, beforeChild);
10192 } else {
10193 container.insertBefore(child, beforeChild);
10194 }
10195}
10196
10197function removeChild(parentInstance, child) {
10198 parentInstance.removeChild(child);
10199}
10200
10201function removeChildFromContainer(container, child) {
10202 if (container.nodeType === COMMENT_NODE) {
10203 container.parentNode.removeChild(child);
10204 } else {
10205 container.removeChild(child);
10206 }
10207}
10208
10209function clearSuspenseBoundary(parentInstance, suspenseInstance) {
10210 var node = suspenseInstance;
10211 // Delete all nodes within this suspense boundary.
10212 // There might be nested nodes so we need to keep track of how
10213 // deep we are and only break out when we're back on top.
10214 var depth = 0;
10215 do {
10216 var nextNode = node.nextSibling;
10217 parentInstance.removeChild(node);
10218 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
10219 var data = nextNode.data;
10220 if (data === SUSPENSE_END_DATA) {
10221 if (depth === 0) {
10222 parentInstance.removeChild(nextNode);
10223 return;
10224 } else {
10225 depth--;
10226 }
10227 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) {
10228 depth++;
10229 }
10230 }
10231 node = nextNode;
10232 } while (node);
10233 // TODO: Warn, we didn't find the end comment boundary.
10234}
10235
10236function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
10237 if (container.nodeType === COMMENT_NODE) {
10238 clearSuspenseBoundary(container.parentNode, suspenseInstance);
10239 } else if (container.nodeType === ELEMENT_NODE) {
10240 clearSuspenseBoundary(container, suspenseInstance);
10241 } else {
10242 // Document nodes should never contain suspense boundaries.
10243 }
10244}
10245
10246function hideInstance(instance) {
10247 // TODO: Does this work for all element types? What about MathML? Should we
10248 // pass host context to this method?
10249 instance = instance;
10250 var style = instance.style;
10251 if (typeof style.setProperty === 'function') {
10252 style.setProperty('display', 'none', 'important');
10253 } else {
10254 style.display = 'none';
10255 }
10256}
10257
10258function hideTextInstance(textInstance) {
10259 textInstance.nodeValue = '';
10260}
10261
10262function unhideInstance(instance, props) {
10263 instance = instance;
10264 var styleProp = props[STYLE];
10265 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
10266 instance.style.display = dangerousStyleValue('display', display);
10267}
10268
10269function unhideTextInstance(textInstance, text) {
10270 textInstance.nodeValue = text;
10271}
10272
10273// -------------------
10274// Hydration
10275// -------------------
10276
10277var supportsHydration = true;
10278
10279function canHydrateInstance(instance, type, props) {
10280 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
10281 return null;
10282 }
10283 // This has now been refined to an element node.
10284 return instance;
10285}
10286
10287function canHydrateTextInstance(instance, text) {
10288 if (text === '' || instance.nodeType !== TEXT_NODE) {
10289 // Empty strings are not parsed by HTML so there won't be a correct match here.
10290 return null;
10291 }
10292 // This has now been refined to a text node.
10293 return instance;
10294}
10295
10296function canHydrateSuspenseInstance(instance) {
10297 if (instance.nodeType !== COMMENT_NODE) {
10298 // Empty strings are not parsed by HTML so there won't be a correct match here.
10299 return null;
10300 }
10301 // This has now been refined to a suspense node.
10302 return instance;
10303}
10304
10305function isSuspenseInstancePending(instance) {
10306 return instance.data === SUSPENSE_PENDING_START_DATA;
10307}
10308
10309function isSuspenseInstanceFallback(instance) {
10310 return instance.data === SUSPENSE_FALLBACK_START_DATA;
10311}
10312
10313function registerSuspenseInstanceRetry(instance, callback) {
10314 instance._reactRetry = callback;
10315}
10316
10317function getNextHydratable(node) {
10318 // Skip non-hydratable nodes.
10319 for (; node != null; node = node.nextSibling) {
10320 var nodeType = node.nodeType;
10321 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
10322 break;
10323 }
10324 if (enableSuspenseServerRenderer) {
10325 if (nodeType === COMMENT_NODE) {
10326 break;
10327 }
10328 var nodeData = node.data;
10329 if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) {
10330 break;
10331 }
10332 }
10333 }
10334 return node;
10335}
10336
10337function getNextHydratableSibling(instance) {
10338 return getNextHydratable(instance.nextSibling);
10339}
10340
10341function getFirstHydratableChild(parentInstance) {
10342 return getNextHydratable(parentInstance.firstChild);
10343}
10344
10345function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10346 precacheFiberNode(internalInstanceHandle, instance);
10347 // TODO: Possibly defer this until the commit phase where all the events
10348 // get attached.
10349 updateFiberProps(instance, props);
10350 var parentNamespace = void 0;
10351 {
10352 var hostContextDev = hostContext;
10353 parentNamespace = hostContextDev.namespace;
10354 }
10355 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
10356}
10357
10358function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
10359 precacheFiberNode(internalInstanceHandle, textInstance);
10360 return diffHydratedText(textInstance, text);
10361}
10362
10363function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
10364 var node = suspenseInstance.nextSibling;
10365 // Skip past all nodes within this suspense boundary.
10366 // There might be nested nodes so we need to keep track of how
10367 // deep we are and only break out when we're back on top.
10368 var depth = 0;
10369 while (node) {
10370 if (node.nodeType === COMMENT_NODE) {
10371 var data = node.data;
10372 if (data === SUSPENSE_END_DATA) {
10373 if (depth === 0) {
10374 return getNextHydratableSibling(node);
10375 } else {
10376 depth--;
10377 }
10378 } else if (data === SUSPENSE_START_DATA) {
10379 depth++;
10380 }
10381 }
10382 node = node.nextSibling;
10383 }
10384 // TODO: Warn, we didn't find the end comment boundary.
10385 return null;
10386}
10387
10388function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
10389 {
10390 warnForUnmatchedText(textInstance, text);
10391 }
10392}
10393
10394function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
10395 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10396 warnForUnmatchedText(textInstance, text);
10397 }
10398}
10399
10400function didNotHydrateContainerInstance(parentContainer, instance) {
10401 {
10402 if (instance.nodeType === ELEMENT_NODE) {
10403 warnForDeletedHydratableElement(parentContainer, instance);
10404 } else if (instance.nodeType === COMMENT_NODE) {
10405 // TODO: warnForDeletedHydratableSuspenseBoundary
10406 } else {
10407 warnForDeletedHydratableText(parentContainer, instance);
10408 }
10409 }
10410}
10411
10412function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
10413 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10414 if (instance.nodeType === ELEMENT_NODE) {
10415 warnForDeletedHydratableElement(parentInstance, instance);
10416 } else if (instance.nodeType === COMMENT_NODE) {
10417 // TODO: warnForDeletedHydratableSuspenseBoundary
10418 } else {
10419 warnForDeletedHydratableText(parentInstance, instance);
10420 }
10421 }
10422}
10423
10424function didNotFindHydratableContainerInstance(parentContainer, type, props) {
10425 {
10426 warnForInsertedHydratedElement(parentContainer, type, props);
10427 }
10428}
10429
10430function didNotFindHydratableContainerTextInstance(parentContainer, text) {
10431 {
10432 warnForInsertedHydratedText(parentContainer, text);
10433 }
10434}
10435
10436
10437
10438function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
10439 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10440 warnForInsertedHydratedElement(parentInstance, type, props);
10441 }
10442}
10443
10444function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
10445 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10446 warnForInsertedHydratedText(parentInstance, text);
10447 }
10448}
10449
10450function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
10451 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10452 // TODO: warnForInsertedHydratedSuspense(parentInstance);
10453 }
10454}
10455
10456function mountResponderInstance(responder, responderInstance, responderProps, responderState, instance, rootContainerInstance) {
10457 // Listen to events
10458 var doc = rootContainerInstance.ownerDocument;
10459 var documentBody = doc.body || doc;
10460 var _ref = responder,
10461 rootEventTypes = _ref.rootEventTypes,
10462 targetEventTypes = _ref.targetEventTypes;
10463
10464 if (targetEventTypes !== null) {
10465 listenToEventResponderEventTypes(targetEventTypes, documentBody);
10466 }
10467 if (rootEventTypes !== null) {
10468 addRootEventTypesForResponderInstance(responderInstance, rootEventTypes);
10469 listenToEventResponderEventTypes(rootEventTypes, documentBody);
10470 }
10471 mountEventResponder(responder, responderInstance, responderProps, responderState);
10472 return responderInstance;
10473}
10474
10475function unmountResponderInstance(responderInstance) {
10476 if (enableFlareAPI) {
10477 // TODO stop listening to targetEventTypes
10478 unmountEventResponder(responderInstance);
10479 }
10480}
10481
10482function getFundamentalComponentInstance(fundamentalInstance) {
10483 if (enableFundamentalAPI) {
10484 var currentFiber = fundamentalInstance.currentFiber,
10485 impl = fundamentalInstance.impl,
10486 _props = fundamentalInstance.props,
10487 state = fundamentalInstance.state;
10488
10489 var instance = impl.getInstance(null, _props, state);
10490 precacheFiberNode(currentFiber, instance);
10491 return instance;
10492 }
10493 // Because of the flag above, this gets around the Flow error;
10494 return null;
10495}
10496
10497function mountFundamentalComponent(fundamentalInstance) {
10498 if (enableFundamentalAPI) {
10499 var impl = fundamentalInstance.impl,
10500 instance = fundamentalInstance.instance,
10501 _props2 = fundamentalInstance.props,
10502 state = fundamentalInstance.state;
10503
10504 var onMount = impl.onMount;
10505 if (onMount !== undefined) {
10506 onMount(null, instance, _props2, state);
10507 }
10508 }
10509}
10510
10511function shouldUpdateFundamentalComponent(fundamentalInstance) {
10512 if (enableFundamentalAPI) {
10513 var impl = fundamentalInstance.impl,
10514 prevProps = fundamentalInstance.prevProps,
10515 _props3 = fundamentalInstance.props,
10516 state = fundamentalInstance.state;
10517
10518 var shouldUpdate = impl.shouldUpdate;
10519 if (shouldUpdate !== undefined) {
10520 return shouldUpdate(null, prevProps, _props3, state);
10521 }
10522 }
10523 return true;
10524}
10525
10526function updateFundamentalComponent(fundamentalInstance) {
10527 if (enableFundamentalAPI) {
10528 var impl = fundamentalInstance.impl,
10529 instance = fundamentalInstance.instance,
10530 prevProps = fundamentalInstance.prevProps,
10531 _props4 = fundamentalInstance.props,
10532 state = fundamentalInstance.state;
10533
10534 var onUpdate = impl.onUpdate;
10535 if (onUpdate !== undefined) {
10536 onUpdate(null, instance, prevProps, _props4, state);
10537 }
10538 }
10539}
10540
10541function unmountFundamentalComponent(fundamentalInstance) {
10542 if (enableFundamentalAPI) {
10543 var impl = fundamentalInstance.impl,
10544 instance = fundamentalInstance.instance,
10545 _props5 = fundamentalInstance.props,
10546 state = fundamentalInstance.state;
10547
10548 var onUnmount = impl.onUnmount;
10549 if (onUnmount !== undefined) {
10550 onUnmount(null, instance, _props5, state);
10551 }
10552 }
10553}
10554
10555// Prefix measurements so that it's possible to filter them.
10556// Longer prefixes are hard to read in DevTools.
10557var reactEmoji = '\u269B';
10558var warningEmoji = '\u26D4';
10559var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
10560
10561// Keep track of current fiber so that we know the path to unwind on pause.
10562// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
10563var currentFiber = null;
10564// If we're in the middle of user code, which fiber and method is it?
10565// Reusing `currentFiber` would be confusing for this because user code fiber
10566// can change during commit phase too, but we don't need to unwind it (since
10567// lifecycles in the commit phase don't resemble a tree).
10568var currentPhase = null;
10569var currentPhaseFiber = null;
10570// Did lifecycle hook schedule an update? This is often a performance problem,
10571// so we will keep track of it, and include it in the report.
10572// Track commits caused by cascading updates.
10573var isCommitting = false;
10574var hasScheduledUpdateInCurrentCommit = false;
10575var hasScheduledUpdateInCurrentPhase = false;
10576var commitCountInCurrentWorkLoop = 0;
10577var effectCountInCurrentCommit = 0;
10578var isWaitingForCallback = false;
10579// During commits, we only show a measurement once per method name
10580// to avoid stretch the commit phase with measurement overhead.
10581var labelsInCurrentCommit = new Set();
10582
10583var formatMarkName = function (markName) {
10584 return reactEmoji + ' ' + markName;
10585};
10586
10587var formatLabel = function (label, warning) {
10588 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
10589 var suffix = warning ? ' Warning: ' + warning : '';
10590 return '' + prefix + label + suffix;
10591};
10592
10593var beginMark = function (markName) {
10594 performance.mark(formatMarkName(markName));
10595};
10596
10597var clearMark = function (markName) {
10598 performance.clearMarks(formatMarkName(markName));
10599};
10600
10601var endMark = function (label, markName, warning) {
10602 var formattedMarkName = formatMarkName(markName);
10603 var formattedLabel = formatLabel(label, warning);
10604 try {
10605 performance.measure(formattedLabel, formattedMarkName);
10606 } catch (err) {}
10607 // If previous mark was missing for some reason, this will throw.
10608 // This could only happen if React crashed in an unexpected place earlier.
10609 // Don't pile on with more errors.
10610
10611 // Clear marks immediately to avoid growing buffer.
10612 performance.clearMarks(formattedMarkName);
10613 performance.clearMeasures(formattedLabel);
10614};
10615
10616var getFiberMarkName = function (label, debugID) {
10617 return label + ' (#' + debugID + ')';
10618};
10619
10620var getFiberLabel = function (componentName, isMounted, phase) {
10621 if (phase === null) {
10622 // These are composite component total time measurements.
10623 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
10624 } else {
10625 // Composite component methods.
10626 return componentName + '.' + phase;
10627 }
10628};
10629
10630var beginFiberMark = function (fiber, phase) {
10631 var componentName = getComponentName(fiber.type) || 'Unknown';
10632 var debugID = fiber._debugID;
10633 var isMounted = fiber.alternate !== null;
10634 var label = getFiberLabel(componentName, isMounted, phase);
10635
10636 if (isCommitting && labelsInCurrentCommit.has(label)) {
10637 // During the commit phase, we don't show duplicate labels because
10638 // there is a fixed overhead for every measurement, and we don't
10639 // want to stretch the commit phase beyond necessary.
10640 return false;
10641 }
10642 labelsInCurrentCommit.add(label);
10643
10644 var markName = getFiberMarkName(label, debugID);
10645 beginMark(markName);
10646 return true;
10647};
10648
10649var clearFiberMark = function (fiber, phase) {
10650 var componentName = getComponentName(fiber.type) || 'Unknown';
10651 var debugID = fiber._debugID;
10652 var isMounted = fiber.alternate !== null;
10653 var label = getFiberLabel(componentName, isMounted, phase);
10654 var markName = getFiberMarkName(label, debugID);
10655 clearMark(markName);
10656};
10657
10658var endFiberMark = function (fiber, phase, warning) {
10659 var componentName = getComponentName(fiber.type) || 'Unknown';
10660 var debugID = fiber._debugID;
10661 var isMounted = fiber.alternate !== null;
10662 var label = getFiberLabel(componentName, isMounted, phase);
10663 var markName = getFiberMarkName(label, debugID);
10664 endMark(label, markName, warning);
10665};
10666
10667var shouldIgnoreFiber = function (fiber) {
10668 // Host components should be skipped in the timeline.
10669 // We could check typeof fiber.type, but does this work with RN?
10670 switch (fiber.tag) {
10671 case HostRoot:
10672 case HostComponent:
10673 case HostText:
10674 case HostPortal:
10675 case Fragment:
10676 case ContextProvider:
10677 case ContextConsumer:
10678 case Mode:
10679 return true;
10680 default:
10681 return false;
10682 }
10683};
10684
10685var clearPendingPhaseMeasurement = function () {
10686 if (currentPhase !== null && currentPhaseFiber !== null) {
10687 clearFiberMark(currentPhaseFiber, currentPhase);
10688 }
10689 currentPhaseFiber = null;
10690 currentPhase = null;
10691 hasScheduledUpdateInCurrentPhase = false;
10692};
10693
10694var pauseTimers = function () {
10695 // Stops all currently active measurements so that they can be resumed
10696 // if we continue in a later deferred loop from the same unit of work.
10697 var fiber = currentFiber;
10698 while (fiber) {
10699 if (fiber._debugIsCurrentlyTiming) {
10700 endFiberMark(fiber, null, null);
10701 }
10702 fiber = fiber.return;
10703 }
10704};
10705
10706var resumeTimersRecursively = function (fiber) {
10707 if (fiber.return !== null) {
10708 resumeTimersRecursively(fiber.return);
10709 }
10710 if (fiber._debugIsCurrentlyTiming) {
10711 beginFiberMark(fiber, null);
10712 }
10713};
10714
10715var resumeTimers = function () {
10716 // Resumes all measurements that were active during the last deferred loop.
10717 if (currentFiber !== null) {
10718 resumeTimersRecursively(currentFiber);
10719 }
10720};
10721
10722function recordEffect() {
10723 if (enableUserTimingAPI) {
10724 effectCountInCurrentCommit++;
10725 }
10726}
10727
10728function recordScheduleUpdate() {
10729 if (enableUserTimingAPI) {
10730 if (isCommitting) {
10731 hasScheduledUpdateInCurrentCommit = true;
10732 }
10733 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
10734 hasScheduledUpdateInCurrentPhase = true;
10735 }
10736 }
10737}
10738
10739function startRequestCallbackTimer() {
10740 if (enableUserTimingAPI) {
10741 if (supportsUserTiming && !isWaitingForCallback) {
10742 isWaitingForCallback = true;
10743 beginMark('(Waiting for async callback...)');
10744 }
10745 }
10746}
10747
10748function stopRequestCallbackTimer(didExpire) {
10749 if (enableUserTimingAPI) {
10750 if (supportsUserTiming) {
10751 isWaitingForCallback = false;
10752 var warning = didExpire ? 'Update expired; will flush synchronously' : null;
10753 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
10754 }
10755 }
10756}
10757
10758function startWorkTimer(fiber) {
10759 if (enableUserTimingAPI) {
10760 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10761 return;
10762 }
10763 // If we pause, this is the fiber to unwind from.
10764 currentFiber = fiber;
10765 if (!beginFiberMark(fiber, null)) {
10766 return;
10767 }
10768 fiber._debugIsCurrentlyTiming = true;
10769 }
10770}
10771
10772function cancelWorkTimer(fiber) {
10773 if (enableUserTimingAPI) {
10774 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10775 return;
10776 }
10777 // Remember we shouldn't complete measurement for this fiber.
10778 // Otherwise flamechart will be deep even for small updates.
10779 fiber._debugIsCurrentlyTiming = false;
10780 clearFiberMark(fiber, null);
10781 }
10782}
10783
10784function stopWorkTimer(fiber) {
10785 if (enableUserTimingAPI) {
10786 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10787 return;
10788 }
10789 // If we pause, its parent is the fiber to unwind from.
10790 currentFiber = fiber.return;
10791 if (!fiber._debugIsCurrentlyTiming) {
10792 return;
10793 }
10794 fiber._debugIsCurrentlyTiming = false;
10795 endFiberMark(fiber, null, null);
10796 }
10797}
10798
10799function stopFailedWorkTimer(fiber) {
10800 if (enableUserTimingAPI) {
10801 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
10802 return;
10803 }
10804 // If we pause, its parent is the fiber to unwind from.
10805 currentFiber = fiber.return;
10806 if (!fiber._debugIsCurrentlyTiming) {
10807 return;
10808 }
10809 fiber._debugIsCurrentlyTiming = false;
10810 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
10811 endFiberMark(fiber, null, warning);
10812 }
10813}
10814
10815function startPhaseTimer(fiber, phase) {
10816 if (enableUserTimingAPI) {
10817 if (!supportsUserTiming) {
10818 return;
10819 }
10820 clearPendingPhaseMeasurement();
10821 if (!beginFiberMark(fiber, phase)) {
10822 return;
10823 }
10824 currentPhaseFiber = fiber;
10825 currentPhase = phase;
10826 }
10827}
10828
10829function stopPhaseTimer() {
10830 if (enableUserTimingAPI) {
10831 if (!supportsUserTiming) {
10832 return;
10833 }
10834 if (currentPhase !== null && currentPhaseFiber !== null) {
10835 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
10836 endFiberMark(currentPhaseFiber, currentPhase, warning);
10837 }
10838 currentPhase = null;
10839 currentPhaseFiber = null;
10840 }
10841}
10842
10843function startWorkLoopTimer(nextUnitOfWork) {
10844 if (enableUserTimingAPI) {
10845 currentFiber = nextUnitOfWork;
10846 if (!supportsUserTiming) {
10847 return;
10848 }
10849 commitCountInCurrentWorkLoop = 0;
10850 // This is top level call.
10851 // Any other measurements are performed within.
10852 beginMark('(React Tree Reconciliation)');
10853 // Resume any measurements that were in progress during the last loop.
10854 resumeTimers();
10855 }
10856}
10857
10858function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
10859 if (enableUserTimingAPI) {
10860 if (!supportsUserTiming) {
10861 return;
10862 }
10863 var warning = null;
10864 if (interruptedBy !== null) {
10865 if (interruptedBy.tag === HostRoot) {
10866 warning = 'A top-level update interrupted the previous render';
10867 } else {
10868 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
10869 warning = 'An update to ' + componentName + ' interrupted the previous render';
10870 }
10871 } else if (commitCountInCurrentWorkLoop > 1) {
10872 warning = 'There were cascading updates';
10873 }
10874 commitCountInCurrentWorkLoop = 0;
10875 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
10876 // Pause any measurements until the next loop.
10877 pauseTimers();
10878 endMark(label, '(React Tree Reconciliation)', warning);
10879 }
10880}
10881
10882function startCommitTimer() {
10883 if (enableUserTimingAPI) {
10884 if (!supportsUserTiming) {
10885 return;
10886 }
10887 isCommitting = true;
10888 hasScheduledUpdateInCurrentCommit = false;
10889 labelsInCurrentCommit.clear();
10890 beginMark('(Committing Changes)');
10891 }
10892}
10893
10894function stopCommitTimer() {
10895 if (enableUserTimingAPI) {
10896 if (!supportsUserTiming) {
10897 return;
10898 }
10899
10900 var warning = null;
10901 if (hasScheduledUpdateInCurrentCommit) {
10902 warning = 'Lifecycle hook scheduled a cascading update';
10903 } else if (commitCountInCurrentWorkLoop > 0) {
10904 warning = 'Caused by a cascading update in earlier commit';
10905 }
10906 hasScheduledUpdateInCurrentCommit = false;
10907 commitCountInCurrentWorkLoop++;
10908 isCommitting = false;
10909 labelsInCurrentCommit.clear();
10910
10911 endMark('(Committing Changes)', '(Committing Changes)', warning);
10912 }
10913}
10914
10915function startCommitSnapshotEffectsTimer() {
10916 if (enableUserTimingAPI) {
10917 if (!supportsUserTiming) {
10918 return;
10919 }
10920 effectCountInCurrentCommit = 0;
10921 beginMark('(Committing Snapshot Effects)');
10922 }
10923}
10924
10925function stopCommitSnapshotEffectsTimer() {
10926 if (enableUserTimingAPI) {
10927 if (!supportsUserTiming) {
10928 return;
10929 }
10930 var count = effectCountInCurrentCommit;
10931 effectCountInCurrentCommit = 0;
10932 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
10933 }
10934}
10935
10936function startCommitHostEffectsTimer() {
10937 if (enableUserTimingAPI) {
10938 if (!supportsUserTiming) {
10939 return;
10940 }
10941 effectCountInCurrentCommit = 0;
10942 beginMark('(Committing Host Effects)');
10943 }
10944}
10945
10946function stopCommitHostEffectsTimer() {
10947 if (enableUserTimingAPI) {
10948 if (!supportsUserTiming) {
10949 return;
10950 }
10951 var count = effectCountInCurrentCommit;
10952 effectCountInCurrentCommit = 0;
10953 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
10954 }
10955}
10956
10957function startCommitLifeCyclesTimer() {
10958 if (enableUserTimingAPI) {
10959 if (!supportsUserTiming) {
10960 return;
10961 }
10962 effectCountInCurrentCommit = 0;
10963 beginMark('(Calling Lifecycle Methods)');
10964 }
10965}
10966
10967function stopCommitLifeCyclesTimer() {
10968 if (enableUserTimingAPI) {
10969 if (!supportsUserTiming) {
10970 return;
10971 }
10972 var count = effectCountInCurrentCommit;
10973 effectCountInCurrentCommit = 0;
10974 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
10975 }
10976}
10977
10978var valueStack = [];
10979
10980var fiberStack = void 0;
10981
10982{
10983 fiberStack = [];
10984}
10985
10986var index = -1;
10987
10988function createCursor(defaultValue) {
10989 return {
10990 current: defaultValue
10991 };
10992}
10993
10994function pop(cursor, fiber) {
10995 if (index < 0) {
10996 {
10997 warningWithoutStack$1(false, 'Unexpected pop.');
10998 }
10999 return;
11000 }
11001
11002 {
11003 if (fiber !== fiberStack[index]) {
11004 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
11005 }
11006 }
11007
11008 cursor.current = valueStack[index];
11009
11010 valueStack[index] = null;
11011
11012 {
11013 fiberStack[index] = null;
11014 }
11015
11016 index--;
11017}
11018
11019function push(cursor, value, fiber) {
11020 index++;
11021
11022 valueStack[index] = cursor.current;
11023
11024 {
11025 fiberStack[index] = fiber;
11026 }
11027
11028 cursor.current = value;
11029}
11030
11031var warnedAboutMissingGetChildContext = void 0;
11032
11033{
11034 warnedAboutMissingGetChildContext = {};
11035}
11036
11037var emptyContextObject = {};
11038{
11039 Object.freeze(emptyContextObject);
11040}
11041
11042// A cursor to the current merged context object on the stack.
11043var contextStackCursor = createCursor(emptyContextObject);
11044// A cursor to a boolean indicating whether the context has changed.
11045var didPerformWorkStackCursor = createCursor(false);
11046// Keep track of the previous context object that was on the stack.
11047// We use this to get access to the parent context after we have already
11048// pushed the next context provider, and now need to merge their contexts.
11049var previousContext = emptyContextObject;
11050
11051function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
11052 if (disableLegacyContext) {
11053 return emptyContextObject;
11054 } else {
11055 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
11056 // If the fiber is a context provider itself, when we read its context
11057 // we may have already pushed its own child context on the stack. A context
11058 // provider should not "see" its own child context. Therefore we read the
11059 // previous (parent) context instead for a context provider.
11060 return previousContext;
11061 }
11062 return contextStackCursor.current;
11063 }
11064}
11065
11066function cacheContext(workInProgress, unmaskedContext, maskedContext) {
11067 if (disableLegacyContext) {
11068 return;
11069 } else {
11070 var instance = workInProgress.stateNode;
11071 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
11072 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
11073 }
11074}
11075
11076function getMaskedContext(workInProgress, unmaskedContext) {
11077 if (disableLegacyContext) {
11078 return emptyContextObject;
11079 } else {
11080 var type = workInProgress.type;
11081 var contextTypes = type.contextTypes;
11082 if (!contextTypes) {
11083 return emptyContextObject;
11084 }
11085
11086 // Avoid recreating masked context unless unmasked context has changed.
11087 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
11088 // This may trigger infinite loops if componentWillReceiveProps calls setState.
11089 var instance = workInProgress.stateNode;
11090 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
11091 return instance.__reactInternalMemoizedMaskedChildContext;
11092 }
11093
11094 var context = {};
11095 for (var key in contextTypes) {
11096 context[key] = unmaskedContext[key];
11097 }
11098
11099 {
11100 var name = getComponentName(type) || 'Unknown';
11101 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
11102 }
11103
11104 // Cache unmasked context so we can avoid recreating masked context unless necessary.
11105 // Context is created before the class component is instantiated so check for instance.
11106 if (instance) {
11107 cacheContext(workInProgress, unmaskedContext, context);
11108 }
11109
11110 return context;
11111 }
11112}
11113
11114function hasContextChanged() {
11115 if (disableLegacyContext) {
11116 return false;
11117 } else {
11118 return didPerformWorkStackCursor.current;
11119 }
11120}
11121
11122function isContextProvider(type) {
11123 if (disableLegacyContext) {
11124 return false;
11125 } else {
11126 var childContextTypes = type.childContextTypes;
11127 return childContextTypes !== null && childContextTypes !== undefined;
11128 }
11129}
11130
11131function popContext(fiber) {
11132 if (disableLegacyContext) {
11133 return;
11134 } else {
11135 pop(didPerformWorkStackCursor, fiber);
11136 pop(contextStackCursor, fiber);
11137 }
11138}
11139
11140function popTopLevelContextObject(fiber) {
11141 if (disableLegacyContext) {
11142 return;
11143 } else {
11144 pop(didPerformWorkStackCursor, fiber);
11145 pop(contextStackCursor, fiber);
11146 }
11147}
11148
11149function pushTopLevelContextObject(fiber, context, didChange) {
11150 if (disableLegacyContext) {
11151 return;
11152 } else {
11153 (function () {
11154 if (!(contextStackCursor.current === emptyContextObject)) {
11155 {
11156 throw ReactError(Error('Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.'));
11157 }
11158 }
11159 })();
11160
11161 push(contextStackCursor, context, fiber);
11162 push(didPerformWorkStackCursor, didChange, fiber);
11163 }
11164}
11165
11166function processChildContext(fiber, type, parentContext) {
11167 if (disableLegacyContext) {
11168 return parentContext;
11169 } else {
11170 var instance = fiber.stateNode;
11171 var childContextTypes = type.childContextTypes;
11172
11173 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
11174 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
11175 if (typeof instance.getChildContext !== 'function') {
11176 {
11177 var componentName = getComponentName(type) || 'Unknown';
11178
11179 if (!warnedAboutMissingGetChildContext[componentName]) {
11180 warnedAboutMissingGetChildContext[componentName] = true;
11181 warningWithoutStack$1(false, '%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);
11182 }
11183 }
11184 return parentContext;
11185 }
11186
11187 var childContext = void 0;
11188 {
11189 setCurrentPhase('getChildContext');
11190 }
11191 startPhaseTimer(fiber, 'getChildContext');
11192 childContext = instance.getChildContext();
11193 stopPhaseTimer();
11194 {
11195 setCurrentPhase(null);
11196 }
11197 for (var contextKey in childContext) {
11198 (function () {
11199 if (!(contextKey in childContextTypes)) {
11200 {
11201 throw ReactError(Error((getComponentName(type) || 'Unknown') + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.'));
11202 }
11203 }
11204 })();
11205 }
11206 {
11207 var name = getComponentName(type) || 'Unknown';
11208 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
11209 // In practice, there is one case in which we won't get a stack. It's when
11210 // somebody calls unstable_renderSubtreeIntoContainer() and we process
11211 // context from the parent component instance. The stack will be missing
11212 // because it's outside of the reconciliation, and so the pointer has not
11213 // been set. This is rare and doesn't matter. We'll also remove that API.
11214 getCurrentFiberStackInDev);
11215 }
11216
11217 return _assign({}, parentContext, childContext);
11218 }
11219}
11220
11221function pushContextProvider(workInProgress) {
11222 if (disableLegacyContext) {
11223 return false;
11224 } else {
11225 var instance = workInProgress.stateNode;
11226 // We push the context as early as possible to ensure stack integrity.
11227 // If the instance does not exist yet, we will push null at first,
11228 // and replace it on the stack later when invalidating the context.
11229 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
11230
11231 // Remember the parent context so we can merge with it later.
11232 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
11233 previousContext = contextStackCursor.current;
11234 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
11235 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
11236
11237 return true;
11238 }
11239}
11240
11241function invalidateContextProvider(workInProgress, type, didChange) {
11242 if (disableLegacyContext) {
11243 return;
11244 } else {
11245 var instance = workInProgress.stateNode;
11246 (function () {
11247 if (!instance) {
11248 {
11249 throw ReactError(Error('Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.'));
11250 }
11251 }
11252 })();
11253
11254 if (didChange) {
11255 // Merge parent and own context.
11256 // Skip this if we're not updating due to sCU.
11257 // This avoids unnecessarily recomputing memoized values.
11258 var mergedContext = processChildContext(workInProgress, type, previousContext);
11259 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
11260
11261 // Replace the old (or empty) context with the new one.
11262 // It is important to unwind the context in the reverse order.
11263 pop(didPerformWorkStackCursor, workInProgress);
11264 pop(contextStackCursor, workInProgress);
11265 // Now push the new context and mark that it has changed.
11266 push(contextStackCursor, mergedContext, workInProgress);
11267 push(didPerformWorkStackCursor, didChange, workInProgress);
11268 } else {
11269 pop(didPerformWorkStackCursor, workInProgress);
11270 push(didPerformWorkStackCursor, didChange, workInProgress);
11271 }
11272 }
11273}
11274
11275function findCurrentUnmaskedContext(fiber) {
11276 if (disableLegacyContext) {
11277 return emptyContextObject;
11278 } else {
11279 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11280 // makes sense elsewhere
11281 (function () {
11282 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
11283 {
11284 throw ReactError(Error('Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.'));
11285 }
11286 }
11287 })();
11288
11289 var node = fiber;
11290 do {
11291 switch (node.tag) {
11292 case HostRoot:
11293 return node.stateNode.context;
11294 case ClassComponent:
11295 {
11296 var Component = node.type;
11297 if (isContextProvider(Component)) {
11298 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11299 }
11300 break;
11301 }
11302 }
11303 node = node.return;
11304 } while (node !== null);
11305 (function () {
11306 {
11307 {
11308 throw ReactError(Error('Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.'));
11309 }
11310 }
11311 })();
11312 }
11313}
11314
11315var LegacyRoot = 0;
11316var BatchedRoot = 1;
11317var ConcurrentRoot = 2;
11318
11319var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
11320
11321var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
11322var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
11323var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
11324var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
11325var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
11326var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
11327var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
11328var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
11329var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
11330var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
11331
11332// Intentionally not named imports because Rollup would use dynamic dispatch for
11333// CommonJS interop named imports.
11334var Scheduler_runWithPriority = unstable_runWithPriority;
11335var Scheduler_scheduleCallback = unstable_scheduleCallback;
11336var Scheduler_cancelCallback = unstable_cancelCallback;
11337var Scheduler_shouldYield = unstable_shouldYield;
11338var Scheduler_requestPaint = unstable_requestPaint;
11339var Scheduler_now = unstable_now;
11340var Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
11341var Scheduler_ImmediatePriority = unstable_ImmediatePriority;
11342var Scheduler_UserBlockingPriority = unstable_UserBlockingPriority;
11343var Scheduler_NormalPriority = unstable_NormalPriority;
11344var Scheduler_LowPriority = unstable_LowPriority;
11345var Scheduler_IdlePriority = unstable_IdlePriority;
11346
11347
11348if (enableSchedulerTracing) {
11349 // Provide explicit error message when production+profiling bundle of e.g.
11350 // react-dom is used with production (non-profiling) bundle of
11351 // scheduler/tracing
11352 (function () {
11353 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
11354 {
11355 throw ReactError(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'));
11356 }
11357 }
11358 })();
11359}
11360
11361var fakeCallbackNode = {};
11362
11363// Except for NoPriority, these correspond to Scheduler priorities. We use
11364// ascending numbers so we can compare them like numbers. They start at 90 to
11365// avoid clashing with Scheduler's priorities.
11366var ImmediatePriority = 99;
11367var UserBlockingPriority$2 = 98;
11368var NormalPriority = 97;
11369var LowPriority = 96;
11370var IdlePriority = 95;
11371// NoPriority is the absence of priority. Also React-only.
11372var NoPriority = 90;
11373
11374var shouldYield = Scheduler_shouldYield;
11375var requestPaint =
11376// Fall back gracefully if we're running an older version of Scheduler.
11377Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
11378
11379var syncQueue = null;
11380var immediateQueueCallbackNode = null;
11381var isFlushingSyncQueue = false;
11382var initialTimeMs = Scheduler_now();
11383
11384// If the initial timestamp is reasonably small, use Scheduler's `now` directly.
11385// This will be the case for modern browsers that support `performance.now`. In
11386// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
11387// timestamp. In that case, subtract the module initialization time to simulate
11388// the behavior of performance.now and keep our times small enough to fit
11389// within 32 bits.
11390// TODO: Consider lifting this into Scheduler.
11391var now = initialTimeMs < 10000 ? Scheduler_now : function () {
11392 return Scheduler_now() - initialTimeMs;
11393};
11394
11395function getCurrentPriorityLevel() {
11396 switch (Scheduler_getCurrentPriorityLevel()) {
11397 case Scheduler_ImmediatePriority:
11398 return ImmediatePriority;
11399 case Scheduler_UserBlockingPriority:
11400 return UserBlockingPriority$2;
11401 case Scheduler_NormalPriority:
11402 return NormalPriority;
11403 case Scheduler_LowPriority:
11404 return LowPriority;
11405 case Scheduler_IdlePriority:
11406 return IdlePriority;
11407 default:
11408 (function () {
11409 {
11410 {
11411 throw ReactError(Error('Unknown priority level.'));
11412 }
11413 }
11414 })();
11415 }
11416}
11417
11418function reactPriorityToSchedulerPriority(reactPriorityLevel) {
11419 switch (reactPriorityLevel) {
11420 case ImmediatePriority:
11421 return Scheduler_ImmediatePriority;
11422 case UserBlockingPriority$2:
11423 return Scheduler_UserBlockingPriority;
11424 case NormalPriority:
11425 return Scheduler_NormalPriority;
11426 case LowPriority:
11427 return Scheduler_LowPriority;
11428 case IdlePriority:
11429 return Scheduler_IdlePriority;
11430 default:
11431 (function () {
11432 {
11433 {
11434 throw ReactError(Error('Unknown priority level.'));
11435 }
11436 }
11437 })();
11438 }
11439}
11440
11441function runWithPriority$2(reactPriorityLevel, fn) {
11442 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11443 return Scheduler_runWithPriority(priorityLevel, fn);
11444}
11445
11446function scheduleCallback(reactPriorityLevel, callback, options) {
11447 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
11448 return Scheduler_scheduleCallback(priorityLevel, callback, options);
11449}
11450
11451function scheduleSyncCallback(callback) {
11452 // Push this callback into an internal queue. We'll flush these either in
11453 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
11454 if (syncQueue === null) {
11455 syncQueue = [callback];
11456 // Flush the queue in the next tick, at the earliest.
11457 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
11458 } else {
11459 // Push onto existing queue. Don't need to schedule a callback because
11460 // we already scheduled one when we created the queue.
11461 syncQueue.push(callback);
11462 }
11463 return fakeCallbackNode;
11464}
11465
11466function cancelCallback(callbackNode) {
11467 if (callbackNode !== fakeCallbackNode) {
11468 Scheduler_cancelCallback(callbackNode);
11469 }
11470}
11471
11472function flushSyncCallbackQueue() {
11473 if (immediateQueueCallbackNode !== null) {
11474 Scheduler_cancelCallback(immediateQueueCallbackNode);
11475 }
11476 flushSyncCallbackQueueImpl();
11477}
11478
11479function flushSyncCallbackQueueImpl() {
11480 if (!isFlushingSyncQueue && syncQueue !== null) {
11481 // Prevent re-entrancy.
11482 isFlushingSyncQueue = true;
11483 var i = 0;
11484 try {
11485 var _isSync = true;
11486 var queue = syncQueue;
11487 runWithPriority$2(ImmediatePriority, function () {
11488 for (; i < queue.length; i++) {
11489 var callback = queue[i];
11490 do {
11491 callback = callback(_isSync);
11492 } while (callback !== null);
11493 }
11494 });
11495 syncQueue = null;
11496 } catch (error) {
11497 // If something throws, leave the remaining callbacks on the queue.
11498 if (syncQueue !== null) {
11499 syncQueue = syncQueue.slice(i + 1);
11500 }
11501 // Resume flushing in the next tick
11502 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
11503 throw error;
11504 } finally {
11505 isFlushingSyncQueue = false;
11506 }
11507 }
11508}
11509
11510var NoMode = 0;
11511var StrictMode = 1;
11512// TODO: Remove BatchedMode and ConcurrentMode by reading from the root
11513// tag instead
11514var BatchedMode = 2;
11515var ConcurrentMode = 4;
11516var ProfileMode = 8;
11517
11518// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
11519// Math.pow(2, 30) - 1
11520// 0b111111111111111111111111111111
11521var MAX_SIGNED_31_BIT_INT = 1073741823;
11522
11523var NoWork = 0;
11524var Never = 1;
11525var Sync = MAX_SIGNED_31_BIT_INT;
11526var Batched = Sync - 1;
11527
11528var UNIT_SIZE = 10;
11529var MAGIC_NUMBER_OFFSET = Batched - 1;
11530
11531// 1 unit of expiration time represents 10ms.
11532function msToExpirationTime(ms) {
11533 // Always add an offset so that we don't clash with the magic number for NoWork.
11534 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
11535}
11536
11537function expirationTimeToMs(expirationTime) {
11538 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
11539}
11540
11541function ceiling(num, precision) {
11542 return ((num / precision | 0) + 1) * precision;
11543}
11544
11545function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
11546 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
11547}
11548
11549// TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
11550// the names to reflect.
11551var LOW_PRIORITY_EXPIRATION = 5000;
11552var LOW_PRIORITY_BATCH_SIZE = 250;
11553
11554function computeAsyncExpiration(currentTime) {
11555 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
11556}
11557
11558function computeSuspenseExpiration(currentTime, timeoutMs) {
11559 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
11560 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
11561}
11562
11563// We intentionally set a higher expiration time for interactive updates in
11564// dev than in production.
11565//
11566// If the main thread is being blocked so long that you hit the expiration,
11567// it's a problem that could be solved with better scheduling.
11568//
11569// People will be more likely to notice this and fix it with the long
11570// expiration time in development.
11571//
11572// In production we opt for better UX at the risk of masking scheduling
11573// problems, by expiring fast.
11574var HIGH_PRIORITY_EXPIRATION = 500;
11575var HIGH_PRIORITY_BATCH_SIZE = 100;
11576
11577function computeInteractiveExpiration(currentTime) {
11578 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
11579}
11580
11581function inferPriorityFromExpirationTime(currentTime, expirationTime) {
11582 if (expirationTime === Sync) {
11583 return ImmediatePriority;
11584 }
11585 if (expirationTime === Never) {
11586 return IdlePriority;
11587 }
11588 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
11589 if (msUntil <= 0) {
11590 return ImmediatePriority;
11591 }
11592 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
11593 return UserBlockingPriority$2;
11594 }
11595 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
11596 return NormalPriority;
11597 }
11598
11599 // TODO: Handle LowPriority
11600
11601 // Assume anything lower has idle priority
11602 return IdlePriority;
11603}
11604
11605/**
11606 * Forked from fbjs/warning:
11607 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
11608 *
11609 * Only change is we use console.warn instead of console.error,
11610 * and do nothing when 'console' is not supported.
11611 * This really simplifies the code.
11612 * ---
11613 * Similar to invariant but only logs a warning if the condition is not met.
11614 * This can be used to log issues in development environments in critical
11615 * paths. Removing the logging code for production environments will keep the
11616 * same logic and follow the same code paths.
11617 */
11618
11619var lowPriorityWarning = function () {};
11620
11621{
11622 var printWarning$1 = function (format) {
11623 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
11624 args[_key - 1] = arguments[_key];
11625 }
11626
11627 var argIndex = 0;
11628 var message = 'Warning: ' + format.replace(/%s/g, function () {
11629 return args[argIndex++];
11630 });
11631 if (typeof console !== 'undefined') {
11632 console.warn(message);
11633 }
11634 try {
11635 // --- Welcome to debugging React ---
11636 // This error was thrown as a convenience so that you can use this stack
11637 // to find the callsite that caused this warning to fire.
11638 throw new Error(message);
11639 } catch (x) {}
11640 };
11641
11642 lowPriorityWarning = function (condition, format) {
11643 if (format === undefined) {
11644 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
11645 }
11646 if (!condition) {
11647 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
11648 args[_key2 - 2] = arguments[_key2];
11649 }
11650
11651 printWarning$1.apply(undefined, [format].concat(args));
11652 }
11653 };
11654}
11655
11656var lowPriorityWarning$1 = lowPriorityWarning;
11657
11658var ReactStrictModeWarnings = {
11659 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
11660 flushPendingUnsafeLifecycleWarnings: function () {},
11661 recordLegacyContextWarning: function (fiber, instance) {},
11662 flushLegacyContextWarning: function () {},
11663 discardPendingWarnings: function () {}
11664};
11665
11666{
11667 var findStrictRoot = function (fiber) {
11668 var maybeStrictRoot = null;
11669
11670 var node = fiber;
11671 while (node !== null) {
11672 if (node.mode & StrictMode) {
11673 maybeStrictRoot = node;
11674 }
11675 node = node.return;
11676 }
11677
11678 return maybeStrictRoot;
11679 };
11680
11681 var setToSortedString = function (set) {
11682 var array = [];
11683 set.forEach(function (value) {
11684 array.push(value);
11685 });
11686 return array.sort().join(', ');
11687 };
11688
11689 var pendingComponentWillMountWarnings = [];
11690 var pendingUNSAFE_ComponentWillMountWarnings = [];
11691 var pendingComponentWillReceivePropsWarnings = [];
11692 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11693 var pendingComponentWillUpdateWarnings = [];
11694 var pendingUNSAFE_ComponentWillUpdateWarnings = [];
11695
11696 // Tracks components we have already warned about.
11697 var didWarnAboutUnsafeLifecycles = new Set();
11698
11699 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
11700 // Dedup strategy: Warn once per component.
11701 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
11702 return;
11703 }
11704
11705 if (typeof instance.componentWillMount === 'function' &&
11706 // Don't warn about react-lifecycles-compat polyfilled components.
11707 instance.componentWillMount.__suppressDeprecationWarning !== true) {
11708 pendingComponentWillMountWarnings.push(fiber);
11709 }
11710
11711 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
11712 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
11713 }
11714
11715 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11716 pendingComponentWillReceivePropsWarnings.push(fiber);
11717 }
11718
11719 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11720 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
11721 }
11722
11723 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11724 pendingComponentWillUpdateWarnings.push(fiber);
11725 }
11726
11727 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
11728 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
11729 }
11730 };
11731
11732 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
11733 // We do an initial pass to gather component names
11734 var componentWillMountUniqueNames = new Set();
11735 if (pendingComponentWillMountWarnings.length > 0) {
11736 pendingComponentWillMountWarnings.forEach(function (fiber) {
11737 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11738 didWarnAboutUnsafeLifecycles.add(fiber.type);
11739 });
11740 pendingComponentWillMountWarnings = [];
11741 }
11742
11743 var UNSAFE_componentWillMountUniqueNames = new Set();
11744 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
11745 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
11746 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
11747 didWarnAboutUnsafeLifecycles.add(fiber.type);
11748 });
11749 pendingUNSAFE_ComponentWillMountWarnings = [];
11750 }
11751
11752 var componentWillReceivePropsUniqueNames = new Set();
11753 if (pendingComponentWillReceivePropsWarnings.length > 0) {
11754 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
11755 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11756 didWarnAboutUnsafeLifecycles.add(fiber.type);
11757 });
11758
11759 pendingComponentWillReceivePropsWarnings = [];
11760 }
11761
11762 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
11763 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
11764 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
11765 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
11766 didWarnAboutUnsafeLifecycles.add(fiber.type);
11767 });
11768
11769 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11770 }
11771
11772 var componentWillUpdateUniqueNames = new Set();
11773 if (pendingComponentWillUpdateWarnings.length > 0) {
11774 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
11775 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11776 didWarnAboutUnsafeLifecycles.add(fiber.type);
11777 });
11778
11779 pendingComponentWillUpdateWarnings = [];
11780 }
11781
11782 var UNSAFE_componentWillUpdateUniqueNames = new Set();
11783 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
11784 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
11785 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
11786 didWarnAboutUnsafeLifecycles.add(fiber.type);
11787 });
11788
11789 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11790 }
11791
11792 // Finally, we flush all the warnings
11793 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
11794 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
11795 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
11796 warningWithoutStack$1(false, 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
11797 }
11798
11799 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
11800 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
11801 warningWithoutStack$1(false, 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
11802 }
11803
11804 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
11805 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
11806 warningWithoutStack$1(false, 'Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
11807 }
11808
11809 if (componentWillMountUniqueNames.size > 0) {
11810 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
11811
11812 lowPriorityWarning$1(false, 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
11813 }
11814
11815 if (componentWillReceivePropsUniqueNames.size > 0) {
11816 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
11817
11818 lowPriorityWarning$1(false, 'componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
11819 }
11820
11821 if (componentWillUpdateUniqueNames.size > 0) {
11822 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
11823
11824 lowPriorityWarning$1(false, 'componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
11825 }
11826 };
11827
11828 var pendingLegacyContextWarning = new Map();
11829
11830 // Tracks components we have already warned about.
11831 var didWarnAboutLegacyContext = new Set();
11832
11833 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
11834 var strictRoot = findStrictRoot(fiber);
11835 if (strictRoot === null) {
11836 warningWithoutStack$1(false, '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.');
11837 return;
11838 }
11839
11840 // Dedup strategy: Warn once per component.
11841 if (didWarnAboutLegacyContext.has(fiber.type)) {
11842 return;
11843 }
11844
11845 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
11846
11847 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
11848 if (warningsForRoot === undefined) {
11849 warningsForRoot = [];
11850 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
11851 }
11852 warningsForRoot.push(fiber);
11853 }
11854 };
11855
11856 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
11857 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
11858 var uniqueNames = new Set();
11859 fiberArray.forEach(function (fiber) {
11860 uniqueNames.add(getComponentName(fiber.type) || 'Component');
11861 didWarnAboutLegacyContext.add(fiber.type);
11862 });
11863
11864 var sortedNames = setToSortedString(uniqueNames);
11865 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
11866
11867 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\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:' + '\nhttps://fb.me/react-legacy-context', strictRootComponentStack, sortedNames);
11868 });
11869 };
11870
11871 ReactStrictModeWarnings.discardPendingWarnings = function () {
11872 pendingComponentWillMountWarnings = [];
11873 pendingUNSAFE_ComponentWillMountWarnings = [];
11874 pendingComponentWillReceivePropsWarnings = [];
11875 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
11876 pendingComponentWillUpdateWarnings = [];
11877 pendingUNSAFE_ComponentWillUpdateWarnings = [];
11878 pendingLegacyContextWarning = new Map();
11879 };
11880}
11881
11882// Resolves type to a family.
11883
11884
11885// Used by React Refresh runtime through DevTools Global Hook.
11886
11887
11888var resolveFamily = null;
11889// $FlowFixMe Flow gets confused by a WeakSet feature check below.
11890var failedBoundaries = null;
11891
11892var setRefreshHandler = function (handler) {
11893 {
11894 resolveFamily = handler;
11895 }
11896};
11897
11898function resolveFunctionForHotReloading(type) {
11899 {
11900 if (resolveFamily === null) {
11901 // Hot reloading is disabled.
11902 return type;
11903 }
11904 var family = resolveFamily(type);
11905 if (family === undefined) {
11906 return type;
11907 }
11908 // Use the latest known implementation.
11909 return family.current;
11910 }
11911}
11912
11913function resolveClassForHotReloading(type) {
11914 // No implementation differences.
11915 return resolveFunctionForHotReloading(type);
11916}
11917
11918function resolveForwardRefForHotReloading(type) {
11919 {
11920 if (resolveFamily === null) {
11921 // Hot reloading is disabled.
11922 return type;
11923 }
11924 var family = resolveFamily(type);
11925 if (family === undefined) {
11926 // Check if we're dealing with a real forwardRef. Don't want to crash early.
11927 if (type !== null && type !== undefined && typeof type.render === 'function') {
11928 // ForwardRef is special because its resolved .type is an object,
11929 // but it's possible that we only have its inner render function in the map.
11930 // If that inner render function is different, we'll build a new forwardRef type.
11931 var currentRender = resolveFunctionForHotReloading(type.render);
11932 if (type.render !== currentRender) {
11933 var syntheticType = {
11934 $$typeof: REACT_FORWARD_REF_TYPE,
11935 render: currentRender
11936 };
11937 if (type.displayName !== undefined) {
11938 syntheticType.displayName = type.displayName;
11939 }
11940 return syntheticType;
11941 }
11942 }
11943 return type;
11944 }
11945 // Use the latest known implementation.
11946 return family.current;
11947 }
11948}
11949
11950function isCompatibleFamilyForHotReloading(fiber, element) {
11951 {
11952 if (resolveFamily === null) {
11953 // Hot reloading is disabled.
11954 return false;
11955 }
11956
11957 var prevType = fiber.elementType;
11958 var nextType = element.type;
11959
11960 // If we got here, we know types aren't === equal.
11961 var needsCompareFamilies = false;
11962
11963 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
11964
11965 switch (fiber.tag) {
11966 case ClassComponent:
11967 {
11968 if (typeof nextType === 'function') {
11969 needsCompareFamilies = true;
11970 }
11971 break;
11972 }
11973 case FunctionComponent:
11974 {
11975 if (typeof nextType === 'function') {
11976 needsCompareFamilies = true;
11977 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11978 // We don't know the inner type yet.
11979 // We're going to assume that the lazy inner type is stable,
11980 // and so it is sufficient to avoid reconciling it away.
11981 // We're not going to unwrap or actually use the new lazy type.
11982 needsCompareFamilies = true;
11983 }
11984 break;
11985 }
11986 case ForwardRef:
11987 {
11988 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
11989 needsCompareFamilies = true;
11990 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
11991 needsCompareFamilies = true;
11992 }
11993 break;
11994 }
11995 case MemoComponent:
11996 case SimpleMemoComponent:
11997 {
11998 if ($$typeofNextType === REACT_MEMO_TYPE) {
11999 // TODO: if it was but can no longer be simple,
12000 // we shouldn't set this.
12001 needsCompareFamilies = true;
12002 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
12003 needsCompareFamilies = true;
12004 }
12005 break;
12006 }
12007 default:
12008 return false;
12009 }
12010
12011 // Check if both types have a family and it's the same one.
12012 if (needsCompareFamilies) {
12013 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
12014 // This means both of them need to be registered to preserve state.
12015 // If we unwrapped and compared the inner types for wrappers instead,
12016 // then we would risk falsely saying two separate memo(Foo)
12017 // calls are equivalent because they wrap the same Foo function.
12018 var prevFamily = resolveFamily(prevType);
12019 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
12020 return true;
12021 }
12022 }
12023 return false;
12024 }
12025}
12026
12027function markFailedErrorBoundaryForHotReloading(fiber) {
12028 {
12029 if (resolveFamily === null) {
12030 // Hot reloading is disabled.
12031 return;
12032 }
12033 if (typeof WeakSet !== 'function') {
12034 return;
12035 }
12036 if (failedBoundaries === null) {
12037 failedBoundaries = new WeakSet();
12038 }
12039 failedBoundaries.add(fiber);
12040 }
12041}
12042
12043var scheduleRefresh = function (root, update) {
12044 {
12045 if (resolveFamily === null) {
12046 // Hot reloading is disabled.
12047 return;
12048 }
12049 var _staleFamilies = update.staleFamilies,
12050 _updatedFamilies = update.updatedFamilies;
12051
12052 flushPassiveEffects();
12053 flushSync(function () {
12054 scheduleFibersWithFamiliesRecursively(root.current, _updatedFamilies, _staleFamilies);
12055 });
12056 }
12057};
12058
12059var scheduleRoot = function (root, element) {
12060 {
12061 if (root.context !== emptyContextObject) {
12062 // Super edge case: root has a legacy _renderSubtree context
12063 // but we don't know the parentComponent so we can't pass it.
12064 // Just ignore. We'll delete this with _renderSubtree code path later.
12065 return;
12066 }
12067 flushPassiveEffects();
12068 updateContainerAtExpirationTime(element, root, null, Sync, null);
12069 }
12070};
12071
12072function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
12073 {
12074 var alternate = fiber.alternate,
12075 child = fiber.child,
12076 sibling = fiber.sibling,
12077 tag = fiber.tag,
12078 type = fiber.type;
12079
12080
12081 var candidateType = null;
12082 switch (tag) {
12083 case FunctionComponent:
12084 case SimpleMemoComponent:
12085 case ClassComponent:
12086 candidateType = type;
12087 break;
12088 case ForwardRef:
12089 candidateType = type.render;
12090 break;
12091 default:
12092 break;
12093 }
12094
12095 if (resolveFamily === null) {
12096 throw new Error('Expected resolveFamily to be set during hot reload.');
12097 }
12098
12099 var needsRender = false;
12100 var needsRemount = false;
12101 if (candidateType !== null) {
12102 var family = resolveFamily(candidateType);
12103 if (family !== undefined) {
12104 if (staleFamilies.has(family)) {
12105 needsRemount = true;
12106 } else if (updatedFamilies.has(family)) {
12107 needsRender = true;
12108 }
12109 }
12110 }
12111 if (failedBoundaries !== null) {
12112 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
12113 needsRemount = true;
12114 }
12115 }
12116
12117 if (needsRemount) {
12118 fiber._debugNeedsRemount = true;
12119 }
12120 if (needsRemount || needsRender) {
12121 scheduleWork(fiber, Sync);
12122 }
12123 if (child !== null && !needsRemount) {
12124 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
12125 }
12126 if (sibling !== null) {
12127 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
12128 }
12129 }
12130}
12131
12132var findHostInstancesForRefresh = function (root, families) {
12133 {
12134 var hostInstances = new Set();
12135 var types = new Set(families.map(function (family) {
12136 return family.current;
12137 }));
12138 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
12139 return hostInstances;
12140 }
12141};
12142
12143function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
12144 {
12145 var child = fiber.child,
12146 sibling = fiber.sibling,
12147 tag = fiber.tag,
12148 type = fiber.type;
12149
12150
12151 var candidateType = null;
12152 switch (tag) {
12153 case FunctionComponent:
12154 case SimpleMemoComponent:
12155 case ClassComponent:
12156 candidateType = type;
12157 break;
12158 case ForwardRef:
12159 candidateType = type.render;
12160 break;
12161 default:
12162 break;
12163 }
12164
12165 var didMatch = false;
12166 if (candidateType !== null) {
12167 if (types.has(candidateType)) {
12168 didMatch = true;
12169 }
12170 }
12171
12172 if (didMatch) {
12173 // We have a match. This only drills down to the closest host components.
12174 // There's no need to search deeper because for the purpose of giving
12175 // visual feedback, "flashing" outermost parent rectangles is sufficient.
12176 findHostInstancesForFiberShallowly(fiber, hostInstances);
12177 } else {
12178 // If there's no match, maybe there will be one further down in the child tree.
12179 if (child !== null) {
12180 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
12181 }
12182 }
12183
12184 if (sibling !== null) {
12185 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
12186 }
12187 }
12188}
12189
12190function findHostInstancesForFiberShallowly(fiber, hostInstances) {
12191 {
12192 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
12193 if (foundHostInstances) {
12194 return;
12195 }
12196 // If we didn't find any host children, fallback to closest host parent.
12197 var node = fiber;
12198 while (true) {
12199 switch (node.tag) {
12200 case HostComponent:
12201 hostInstances.add(node.stateNode);
12202 return;
12203 case HostPortal:
12204 hostInstances.add(node.stateNode.containerInfo);
12205 return;
12206 case HostRoot:
12207 hostInstances.add(node.stateNode.containerInfo);
12208 return;
12209 }
12210 if (node.return === null) {
12211 throw new Error('Expected to reach root first.');
12212 }
12213 node = node.return;
12214 }
12215 }
12216}
12217
12218function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
12219 {
12220 var node = fiber;
12221 var foundHostInstances = false;
12222 while (true) {
12223 if (node.tag === HostComponent) {
12224 // We got a match.
12225 foundHostInstances = true;
12226 hostInstances.add(node.stateNode);
12227 // There may still be more, so keep searching.
12228 } else if (node.child !== null) {
12229 node.child.return = node;
12230 node = node.child;
12231 continue;
12232 }
12233 if (node === fiber) {
12234 return foundHostInstances;
12235 }
12236 while (node.sibling === null) {
12237 if (node.return === null || node.return === fiber) {
12238 return foundHostInstances;
12239 }
12240 node = node.return;
12241 }
12242 node.sibling.return = node.return;
12243 node = node.sibling;
12244 }
12245 }
12246 return false;
12247}
12248
12249function resolveDefaultProps(Component, baseProps) {
12250 if (Component && Component.defaultProps) {
12251 // Resolve default props. Taken from ReactElement
12252 var props = _assign({}, baseProps);
12253 var defaultProps = Component.defaultProps;
12254 for (var propName in defaultProps) {
12255 if (props[propName] === undefined) {
12256 props[propName] = defaultProps[propName];
12257 }
12258 }
12259 return props;
12260 }
12261 return baseProps;
12262}
12263
12264function readLazyComponentType(lazyComponent) {
12265 var status = lazyComponent._status;
12266 var result = lazyComponent._result;
12267 switch (status) {
12268 case Resolved:
12269 {
12270 var Component = result;
12271 return Component;
12272 }
12273 case Rejected:
12274 {
12275 var error = result;
12276 throw error;
12277 }
12278 case Pending:
12279 {
12280 var thenable = result;
12281 throw thenable;
12282 }
12283 default:
12284 {
12285 lazyComponent._status = Pending;
12286 var ctor = lazyComponent._ctor;
12287 var _thenable = ctor();
12288 _thenable.then(function (moduleObject) {
12289 if (lazyComponent._status === Pending) {
12290 var defaultExport = moduleObject.default;
12291 {
12292 if (defaultExport === undefined) {
12293 warning$1(false, '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);
12294 }
12295 }
12296 lazyComponent._status = Resolved;
12297 lazyComponent._result = defaultExport;
12298 }
12299 }, function (error) {
12300 if (lazyComponent._status === Pending) {
12301 lazyComponent._status = Rejected;
12302 lazyComponent._result = error;
12303 }
12304 });
12305 // Handle synchronous thenables.
12306 switch (lazyComponent._status) {
12307 case Resolved:
12308 return lazyComponent._result;
12309 case Rejected:
12310 throw lazyComponent._result;
12311 }
12312 lazyComponent._result = _thenable;
12313 throw _thenable;
12314 }
12315 }
12316}
12317
12318var valueCursor = createCursor(null);
12319
12320var rendererSigil = void 0;
12321{
12322 // Use this to detect multiple renderers using the same context
12323 rendererSigil = {};
12324}
12325
12326var currentlyRenderingFiber = null;
12327var lastContextDependency = null;
12328var lastContextWithAllBitsObserved = null;
12329
12330var isDisallowedContextReadInDEV = false;
12331
12332function resetContextDependencies() {
12333 // This is called right before React yields execution, to ensure `readContext`
12334 // cannot be called outside the render phase.
12335 currentlyRenderingFiber = null;
12336 lastContextDependency = null;
12337 lastContextWithAllBitsObserved = null;
12338 {
12339 isDisallowedContextReadInDEV = false;
12340 }
12341}
12342
12343function enterDisallowedContextReadInDEV() {
12344 {
12345 isDisallowedContextReadInDEV = true;
12346 }
12347}
12348
12349function exitDisallowedContextReadInDEV() {
12350 {
12351 isDisallowedContextReadInDEV = false;
12352 }
12353}
12354
12355function pushProvider(providerFiber, nextValue) {
12356 var context = providerFiber.type._context;
12357
12358 if (isPrimaryRenderer) {
12359 push(valueCursor, context._currentValue, providerFiber);
12360
12361 context._currentValue = nextValue;
12362 {
12363 !(context._currentRenderer === undefined || context._currentRenderer === null || context._currentRenderer === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
12364 context._currentRenderer = rendererSigil;
12365 }
12366 } else {
12367 push(valueCursor, context._currentValue2, providerFiber);
12368
12369 context._currentValue2 = nextValue;
12370 {
12371 !(context._currentRenderer2 === undefined || context._currentRenderer2 === null || context._currentRenderer2 === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
12372 context._currentRenderer2 = rendererSigil;
12373 }
12374 }
12375}
12376
12377function popProvider(providerFiber) {
12378 var currentValue = valueCursor.current;
12379
12380 pop(valueCursor, providerFiber);
12381
12382 var context = providerFiber.type._context;
12383 if (isPrimaryRenderer) {
12384 context._currentValue = currentValue;
12385 } else {
12386 context._currentValue2 = currentValue;
12387 }
12388}
12389
12390function calculateChangedBits(context, newValue, oldValue) {
12391 if (is(oldValue, newValue)) {
12392 // No change
12393 return 0;
12394 } else {
12395 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
12396
12397 {
12398 !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
12399 }
12400 return changedBits | 0;
12401 }
12402}
12403
12404function scheduleWorkOnParentPath(parent, renderExpirationTime) {
12405 // Update the child expiration time of all the ancestors, including
12406 // the alternates.
12407 var node = parent;
12408 while (node !== null) {
12409 var alternate = node.alternate;
12410 if (node.childExpirationTime < renderExpirationTime) {
12411 node.childExpirationTime = renderExpirationTime;
12412 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
12413 alternate.childExpirationTime = renderExpirationTime;
12414 }
12415 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
12416 alternate.childExpirationTime = renderExpirationTime;
12417 } else {
12418 // Neither alternate was updated, which means the rest of the
12419 // ancestor path already has sufficient priority.
12420 break;
12421 }
12422 node = node.return;
12423 }
12424}
12425
12426function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
12427 var fiber = workInProgress.child;
12428 if (fiber !== null) {
12429 // Set the return pointer of the child to the work-in-progress fiber.
12430 fiber.return = workInProgress;
12431 }
12432 while (fiber !== null) {
12433 var nextFiber = void 0;
12434
12435 // Visit this fiber.
12436 var list = fiber.dependencies;
12437 if (list !== null) {
12438 nextFiber = fiber.child;
12439
12440 var dependency = list.firstContext;
12441 while (dependency !== null) {
12442 // Check if the context matches.
12443 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
12444 // Match! Schedule an update on this fiber.
12445
12446 if (fiber.tag === ClassComponent) {
12447 // Schedule a force update on the work-in-progress.
12448 var update = createUpdate(renderExpirationTime, null);
12449 update.tag = ForceUpdate;
12450 // TODO: Because we don't have a work-in-progress, this will add the
12451 // update to the current fiber, too, which means it will persist even if
12452 // this render is thrown away. Since it's a race condition, not sure it's
12453 // worth fixing.
12454 enqueueUpdate(fiber, update);
12455 }
12456
12457 if (fiber.expirationTime < renderExpirationTime) {
12458 fiber.expirationTime = renderExpirationTime;
12459 }
12460 var alternate = fiber.alternate;
12461 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
12462 alternate.expirationTime = renderExpirationTime;
12463 }
12464
12465 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
12466
12467 // Mark the expiration time on the list, too.
12468 if (list.expirationTime < renderExpirationTime) {
12469 list.expirationTime = renderExpirationTime;
12470 }
12471
12472 // Since we already found a match, we can stop traversing the
12473 // dependency list.
12474 break;
12475 }
12476 dependency = dependency.next;
12477 }
12478 } else if (fiber.tag === ContextProvider) {
12479 // Don't scan deeper if this is a matching provider
12480 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
12481 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
12482 // If a dehydrated suspense component is in this subtree, we don't know
12483 // if it will have any context consumers in it. The best we can do is
12484 // mark it as having updates on its children.
12485 if (fiber.expirationTime < renderExpirationTime) {
12486 fiber.expirationTime = renderExpirationTime;
12487 }
12488 var _alternate = fiber.alternate;
12489 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
12490 _alternate.expirationTime = renderExpirationTime;
12491 }
12492 // This is intentionally passing this fiber as the parent
12493 // because we want to schedule this fiber as having work
12494 // on its children. We'll use the childExpirationTime on
12495 // this fiber to indicate that a context has changed.
12496 scheduleWorkOnParentPath(fiber, renderExpirationTime);
12497 nextFiber = fiber.sibling;
12498 } else {
12499 // Traverse down.
12500 nextFiber = fiber.child;
12501 }
12502
12503 if (nextFiber !== null) {
12504 // Set the return pointer of the child to the work-in-progress fiber.
12505 nextFiber.return = fiber;
12506 } else {
12507 // No child. Traverse to next sibling.
12508 nextFiber = fiber;
12509 while (nextFiber !== null) {
12510 if (nextFiber === workInProgress) {
12511 // We're back to the root of this subtree. Exit.
12512 nextFiber = null;
12513 break;
12514 }
12515 var sibling = nextFiber.sibling;
12516 if (sibling !== null) {
12517 // Set the return pointer of the sibling to the work-in-progress fiber.
12518 sibling.return = nextFiber.return;
12519 nextFiber = sibling;
12520 break;
12521 }
12522 // No more siblings. Traverse up.
12523 nextFiber = nextFiber.return;
12524 }
12525 }
12526 fiber = nextFiber;
12527 }
12528}
12529
12530function prepareToReadContext(workInProgress, renderExpirationTime) {
12531 currentlyRenderingFiber = workInProgress;
12532 lastContextDependency = null;
12533 lastContextWithAllBitsObserved = null;
12534
12535 var dependencies = workInProgress.dependencies;
12536 if (dependencies !== null) {
12537 var firstContext = dependencies.firstContext;
12538 if (firstContext !== null) {
12539 if (dependencies.expirationTime >= renderExpirationTime) {
12540 // Context list has a pending update. Mark that this fiber performed work.
12541 markWorkInProgressReceivedUpdate();
12542 }
12543 // Reset the work-in-progress list
12544 dependencies.firstContext = null;
12545 }
12546 }
12547}
12548
12549function readContext(context, observedBits) {
12550 {
12551 // This warning would fire if you read context inside a Hook like useMemo.
12552 // Unlike the class check below, it's not enforced in production for perf.
12553 !!isDisallowedContextReadInDEV ? warning$1(false, '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().') : void 0;
12554 }
12555
12556 if (lastContextWithAllBitsObserved === context) {
12557 // Nothing to do. We already observe everything in this context.
12558 } else if (observedBits === false || observedBits === 0) {
12559 // Do not observe any updates.
12560 } else {
12561 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
12562 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
12563 // Observe all updates.
12564 lastContextWithAllBitsObserved = context;
12565 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
12566 } else {
12567 resolvedObservedBits = observedBits;
12568 }
12569
12570 var contextItem = {
12571 context: context,
12572 observedBits: resolvedObservedBits,
12573 next: null
12574 };
12575
12576 if (lastContextDependency === null) {
12577 (function () {
12578 if (!(currentlyRenderingFiber !== null)) {
12579 {
12580 throw ReactError(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().'));
12581 }
12582 }
12583 })();
12584
12585 // This is the first dependency for this component. Create a new list.
12586 lastContextDependency = contextItem;
12587 currentlyRenderingFiber.dependencies = {
12588 expirationTime: NoWork,
12589 firstContext: contextItem,
12590 responders: null
12591 };
12592 } else {
12593 // Append a new context item.
12594 lastContextDependency = lastContextDependency.next = contextItem;
12595 }
12596 }
12597 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
12598}
12599
12600// UpdateQueue is a linked list of prioritized updates.
12601//
12602// Like fibers, update queues come in pairs: a current queue, which represents
12603// the visible state of the screen, and a work-in-progress queue, which can be
12604// mutated and processed asynchronously before it is committed — a form of
12605// double buffering. If a work-in-progress render is discarded before finishing,
12606// we create a new work-in-progress by cloning the current queue.
12607//
12608// Both queues share a persistent, singly-linked list structure. To schedule an
12609// update, we append it to the end of both queues. Each queue maintains a
12610// pointer to first update in the persistent list that hasn't been processed.
12611// The work-in-progress pointer always has a position equal to or greater than
12612// the current queue, since we always work on that one. The current queue's
12613// pointer is only updated during the commit phase, when we swap in the
12614// work-in-progress.
12615//
12616// For example:
12617//
12618// Current pointer: A - B - C - D - E - F
12619// Work-in-progress pointer: D - E - F
12620// ^
12621// The work-in-progress queue has
12622// processed more updates than current.
12623//
12624// The reason we append to both queues is because otherwise we might drop
12625// updates without ever processing them. For example, if we only add updates to
12626// the work-in-progress queue, some updates could be lost whenever a work-in
12627// -progress render restarts by cloning from current. Similarly, if we only add
12628// updates to the current queue, the updates will be lost whenever an already
12629// in-progress queue commits and swaps with the current queue. However, by
12630// adding to both queues, we guarantee that the update will be part of the next
12631// work-in-progress. (And because the work-in-progress queue becomes the
12632// current queue once it commits, there's no danger of applying the same
12633// update twice.)
12634//
12635// Prioritization
12636// --------------
12637//
12638// Updates are not sorted by priority, but by insertion; new updates are always
12639// appended to the end of the list.
12640//
12641// The priority is still important, though. When processing the update queue
12642// during the render phase, only the updates with sufficient priority are
12643// included in the result. If we skip an update because it has insufficient
12644// priority, it remains in the queue to be processed later, during a lower
12645// priority render. Crucially, all updates subsequent to a skipped update also
12646// remain in the queue *regardless of their priority*. That means high priority
12647// updates are sometimes processed twice, at two separate priorities. We also
12648// keep track of a base state, that represents the state before the first
12649// update in the queue is applied.
12650//
12651// For example:
12652//
12653// Given a base state of '', and the following queue of updates
12654//
12655// A1 - B2 - C1 - D2
12656//
12657// where the number indicates the priority, and the update is applied to the
12658// previous state by appending a letter, React will process these updates as
12659// two separate renders, one per distinct priority level:
12660//
12661// First render, at priority 1:
12662// Base state: ''
12663// Updates: [A1, C1]
12664// Result state: 'AC'
12665//
12666// Second render, at priority 2:
12667// Base state: 'A' <- The base state does not include C1,
12668// because B2 was skipped.
12669// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
12670// Result state: 'ABCD'
12671//
12672// Because we process updates in insertion order, and rebase high priority
12673// updates when preceding updates are skipped, the final result is deterministic
12674// regardless of priority. Intermediate state may vary according to system
12675// resources, but the final state is always the same.
12676
12677var UpdateState = 0;
12678var ReplaceState = 1;
12679var ForceUpdate = 2;
12680var CaptureUpdate = 3;
12681
12682// Global state that is reset at the beginning of calling `processUpdateQueue`.
12683// It should only be read right after calling `processUpdateQueue`, via
12684// `checkHasForceUpdateAfterProcessing`.
12685var hasForceUpdate = false;
12686
12687var didWarnUpdateInsideUpdate = void 0;
12688var currentlyProcessingQueue = void 0;
12689
12690{
12691 didWarnUpdateInsideUpdate = false;
12692 currentlyProcessingQueue = null;
12693
12694}
12695
12696function createUpdateQueue(baseState) {
12697 var queue = {
12698 baseState: baseState,
12699 firstUpdate: null,
12700 lastUpdate: null,
12701 firstCapturedUpdate: null,
12702 lastCapturedUpdate: null,
12703 firstEffect: null,
12704 lastEffect: null,
12705 firstCapturedEffect: null,
12706 lastCapturedEffect: null
12707 };
12708 return queue;
12709}
12710
12711function cloneUpdateQueue(currentQueue) {
12712 var queue = {
12713 baseState: currentQueue.baseState,
12714 firstUpdate: currentQueue.firstUpdate,
12715 lastUpdate: currentQueue.lastUpdate,
12716
12717 // TODO: With resuming, if we bail out and resuse the child tree, we should
12718 // keep these effects.
12719 firstCapturedUpdate: null,
12720 lastCapturedUpdate: null,
12721
12722 firstEffect: null,
12723 lastEffect: null,
12724
12725 firstCapturedEffect: null,
12726 lastCapturedEffect: null
12727 };
12728 return queue;
12729}
12730
12731function createUpdate(expirationTime, suspenseConfig) {
12732 var update = {
12733 expirationTime: expirationTime,
12734 suspenseConfig: suspenseConfig,
12735
12736 tag: UpdateState,
12737 payload: null,
12738 callback: null,
12739
12740 next: null,
12741 nextEffect: null
12742 };
12743 {
12744 update.priority = getCurrentPriorityLevel();
12745 }
12746 return update;
12747}
12748
12749function appendUpdateToQueue(queue, update) {
12750 // Append the update to the end of the list.
12751 if (queue.lastUpdate === null) {
12752 // Queue is empty
12753 queue.firstUpdate = queue.lastUpdate = update;
12754 } else {
12755 queue.lastUpdate.next = update;
12756 queue.lastUpdate = update;
12757 }
12758}
12759
12760function enqueueUpdate(fiber, update) {
12761 // Update queues are created lazily.
12762 var alternate = fiber.alternate;
12763 var queue1 = void 0;
12764 var queue2 = void 0;
12765 if (alternate === null) {
12766 // There's only one fiber.
12767 queue1 = fiber.updateQueue;
12768 queue2 = null;
12769 if (queue1 === null) {
12770 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
12771 }
12772 } else {
12773 // There are two owners.
12774 queue1 = fiber.updateQueue;
12775 queue2 = alternate.updateQueue;
12776 if (queue1 === null) {
12777 if (queue2 === null) {
12778 // Neither fiber has an update queue. Create new ones.
12779 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
12780 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
12781 } else {
12782 // Only one fiber has an update queue. Clone to create a new one.
12783 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
12784 }
12785 } else {
12786 if (queue2 === null) {
12787 // Only one fiber has an update queue. Clone to create a new one.
12788 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
12789 } else {
12790 // Both owners have an update queue.
12791 }
12792 }
12793 }
12794 if (queue2 === null || queue1 === queue2) {
12795 // There's only a single queue.
12796 appendUpdateToQueue(queue1, update);
12797 } else {
12798 // There are two queues. We need to append the update to both queues,
12799 // while accounting for the persistent structure of the list — we don't
12800 // want the same update to be added multiple times.
12801 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
12802 // One of the queues is not empty. We must add the update to both queues.
12803 appendUpdateToQueue(queue1, update);
12804 appendUpdateToQueue(queue2, update);
12805 } else {
12806 // Both queues are non-empty. The last update is the same in both lists,
12807 // because of structural sharing. So, only append to one of the lists.
12808 appendUpdateToQueue(queue1, update);
12809 // But we still need to update the `lastUpdate` pointer of queue2.
12810 queue2.lastUpdate = update;
12811 }
12812 }
12813
12814 {
12815 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
12816 warningWithoutStack$1(false, '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.');
12817 didWarnUpdateInsideUpdate = true;
12818 }
12819 }
12820}
12821
12822function enqueueCapturedUpdate(workInProgress, update) {
12823 // Captured updates go into a separate list, and only on the work-in-
12824 // progress queue.
12825 var workInProgressQueue = workInProgress.updateQueue;
12826 if (workInProgressQueue === null) {
12827 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
12828 } else {
12829 // TODO: I put this here rather than createWorkInProgress so that we don't
12830 // clone the queue unnecessarily. There's probably a better way to
12831 // structure this.
12832 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
12833 }
12834
12835 // Append the update to the end of the list.
12836 if (workInProgressQueue.lastCapturedUpdate === null) {
12837 // This is the first render phase update
12838 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
12839 } else {
12840 workInProgressQueue.lastCapturedUpdate.next = update;
12841 workInProgressQueue.lastCapturedUpdate = update;
12842 }
12843}
12844
12845function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
12846 var current = workInProgress.alternate;
12847 if (current !== null) {
12848 // If the work-in-progress queue is equal to the current queue,
12849 // we need to clone it first.
12850 if (queue === current.updateQueue) {
12851 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
12852 }
12853 }
12854 return queue;
12855}
12856
12857function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
12858 switch (update.tag) {
12859 case ReplaceState:
12860 {
12861 var _payload = update.payload;
12862 if (typeof _payload === 'function') {
12863 // Updater function
12864 {
12865 enterDisallowedContextReadInDEV();
12866 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
12867 _payload.call(instance, prevState, nextProps);
12868 }
12869 }
12870 var nextState = _payload.call(instance, prevState, nextProps);
12871 {
12872 exitDisallowedContextReadInDEV();
12873 }
12874 return nextState;
12875 }
12876 // State object
12877 return _payload;
12878 }
12879 case CaptureUpdate:
12880 {
12881 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
12882 }
12883 // Intentional fallthrough
12884 case UpdateState:
12885 {
12886 var _payload2 = update.payload;
12887 var partialState = void 0;
12888 if (typeof _payload2 === 'function') {
12889 // Updater function
12890 {
12891 enterDisallowedContextReadInDEV();
12892 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
12893 _payload2.call(instance, prevState, nextProps);
12894 }
12895 }
12896 partialState = _payload2.call(instance, prevState, nextProps);
12897 {
12898 exitDisallowedContextReadInDEV();
12899 }
12900 } else {
12901 // Partial state object
12902 partialState = _payload2;
12903 }
12904 if (partialState === null || partialState === undefined) {
12905 // Null and undefined are treated as no-ops.
12906 return prevState;
12907 }
12908 // Merge the partial state and the previous state.
12909 return _assign({}, prevState, partialState);
12910 }
12911 case ForceUpdate:
12912 {
12913 hasForceUpdate = true;
12914 return prevState;
12915 }
12916 }
12917 return prevState;
12918}
12919
12920function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
12921 hasForceUpdate = false;
12922
12923 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
12924
12925 {
12926 currentlyProcessingQueue = queue;
12927 }
12928
12929 // These values may change as we process the queue.
12930 var newBaseState = queue.baseState;
12931 var newFirstUpdate = null;
12932 var newExpirationTime = NoWork;
12933
12934 // Iterate through the list of updates to compute the result.
12935 var update = queue.firstUpdate;
12936 var resultState = newBaseState;
12937 while (update !== null) {
12938 var updateExpirationTime = update.expirationTime;
12939 if (updateExpirationTime < renderExpirationTime) {
12940 // This update does not have sufficient priority. Skip it.
12941 if (newFirstUpdate === null) {
12942 // This is the first skipped update. It will be the first update in
12943 // the new list.
12944 newFirstUpdate = update;
12945 // Since this is the first update that was skipped, the current result
12946 // is the new base state.
12947 newBaseState = resultState;
12948 }
12949 // Since this update will remain in the list, update the remaining
12950 // expiration time.
12951 if (newExpirationTime < updateExpirationTime) {
12952 newExpirationTime = updateExpirationTime;
12953 }
12954 } else {
12955 // This update does have sufficient priority.
12956
12957 // Mark the event time of this update as relevant to this render pass.
12958 // TODO: This should ideally use the true event time of this update rather than
12959 // its priority which is a derived and not reverseable value.
12960 // TODO: We should skip this update if it was already committed but currently
12961 // we have no way of detecting the difference between a committed and suspended
12962 // update here.
12963 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig);
12964
12965 // Process it and compute a new result.
12966 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
12967 var _callback = update.callback;
12968 if (_callback !== null) {
12969 workInProgress.effectTag |= Callback;
12970 // Set this to null, in case it was mutated during an aborted render.
12971 update.nextEffect = null;
12972 if (queue.lastEffect === null) {
12973 queue.firstEffect = queue.lastEffect = update;
12974 } else {
12975 queue.lastEffect.nextEffect = update;
12976 queue.lastEffect = update;
12977 }
12978 }
12979 }
12980 // Continue to the next update.
12981 update = update.next;
12982 }
12983
12984 // Separately, iterate though the list of captured updates.
12985 var newFirstCapturedUpdate = null;
12986 update = queue.firstCapturedUpdate;
12987 while (update !== null) {
12988 var _updateExpirationTime = update.expirationTime;
12989 if (_updateExpirationTime < renderExpirationTime) {
12990 // This update does not have sufficient priority. Skip it.
12991 if (newFirstCapturedUpdate === null) {
12992 // This is the first skipped captured update. It will be the first
12993 // update in the new list.
12994 newFirstCapturedUpdate = update;
12995 // If this is the first update that was skipped, the current result is
12996 // the new base state.
12997 if (newFirstUpdate === null) {
12998 newBaseState = resultState;
12999 }
13000 }
13001 // Since this update will remain in the list, update the remaining
13002 // expiration time.
13003 if (newExpirationTime < _updateExpirationTime) {
13004 newExpirationTime = _updateExpirationTime;
13005 }
13006 } else {
13007 // This update does have sufficient priority. Process it and compute
13008 // a new result.
13009 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
13010 var _callback2 = update.callback;
13011 if (_callback2 !== null) {
13012 workInProgress.effectTag |= Callback;
13013 // Set this to null, in case it was mutated during an aborted render.
13014 update.nextEffect = null;
13015 if (queue.lastCapturedEffect === null) {
13016 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
13017 } else {
13018 queue.lastCapturedEffect.nextEffect = update;
13019 queue.lastCapturedEffect = update;
13020 }
13021 }
13022 }
13023 update = update.next;
13024 }
13025
13026 if (newFirstUpdate === null) {
13027 queue.lastUpdate = null;
13028 }
13029 if (newFirstCapturedUpdate === null) {
13030 queue.lastCapturedUpdate = null;
13031 } else {
13032 workInProgress.effectTag |= Callback;
13033 }
13034 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
13035 // We processed every update, without skipping. That means the new base
13036 // state is the same as the result state.
13037 newBaseState = resultState;
13038 }
13039
13040 queue.baseState = newBaseState;
13041 queue.firstUpdate = newFirstUpdate;
13042 queue.firstCapturedUpdate = newFirstCapturedUpdate;
13043
13044 // Set the remaining expiration time to be whatever is remaining in the queue.
13045 // This should be fine because the only two other things that contribute to
13046 // expiration time are props and context. We're already in the middle of the
13047 // begin phase by the time we start processing the queue, so we've already
13048 // dealt with the props. Context in components that specify
13049 // shouldComponentUpdate is tricky; but we'll have to account for
13050 // that regardless.
13051 workInProgress.expirationTime = newExpirationTime;
13052 workInProgress.memoizedState = resultState;
13053
13054 {
13055 currentlyProcessingQueue = null;
13056 }
13057}
13058
13059function callCallback(callback, context) {
13060 (function () {
13061 if (!(typeof callback === 'function')) {
13062 {
13063 throw ReactError(Error('Invalid argument passed as callback. Expected a function. Instead received: ' + callback));
13064 }
13065 }
13066 })();
13067 callback.call(context);
13068}
13069
13070function resetHasForceUpdateBeforeProcessing() {
13071 hasForceUpdate = false;
13072}
13073
13074function checkHasForceUpdateAfterProcessing() {
13075 return hasForceUpdate;
13076}
13077
13078function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
13079 // If the finished render included captured updates, and there are still
13080 // lower priority updates left over, we need to keep the captured updates
13081 // in the queue so that they are rebased and not dropped once we process the
13082 // queue again at the lower priority.
13083 if (finishedQueue.firstCapturedUpdate !== null) {
13084 // Join the captured update list to the end of the normal list.
13085 if (finishedQueue.lastUpdate !== null) {
13086 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
13087 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
13088 }
13089 // Clear the list of captured updates.
13090 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
13091 }
13092
13093 // Commit the effects
13094 commitUpdateEffects(finishedQueue.firstEffect, instance);
13095 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
13096
13097 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
13098 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
13099}
13100
13101function commitUpdateEffects(effect, instance) {
13102 while (effect !== null) {
13103 var _callback3 = effect.callback;
13104 if (_callback3 !== null) {
13105 effect.callback = null;
13106 callCallback(_callback3, instance);
13107 }
13108 effect = effect.nextEffect;
13109 }
13110}
13111
13112var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
13113
13114
13115function requestCurrentSuspenseConfig() {
13116 return ReactCurrentBatchConfig.suspense;
13117}
13118
13119var fakeInternalInstance = {};
13120var isArray$1 = Array.isArray;
13121
13122// React.Component uses a shared frozen object by default.
13123// We'll use it to determine whether we need to initialize legacy refs.
13124var emptyRefsObject = new React.Component().refs;
13125
13126var didWarnAboutStateAssignmentForComponent = void 0;
13127var didWarnAboutUninitializedState = void 0;
13128var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
13129var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
13130var didWarnAboutUndefinedDerivedState = void 0;
13131var warnOnUndefinedDerivedState = void 0;
13132var warnOnInvalidCallback$1 = void 0;
13133var didWarnAboutDirectlyAssigningPropsToState = void 0;
13134var didWarnAboutContextTypeAndContextTypes = void 0;
13135var didWarnAboutInvalidateContextType = void 0;
13136
13137{
13138 didWarnAboutStateAssignmentForComponent = new Set();
13139 didWarnAboutUninitializedState = new Set();
13140 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
13141 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
13142 didWarnAboutDirectlyAssigningPropsToState = new Set();
13143 didWarnAboutUndefinedDerivedState = new Set();
13144 didWarnAboutContextTypeAndContextTypes = new Set();
13145 didWarnAboutInvalidateContextType = new Set();
13146
13147 var didWarnOnInvalidCallback = new Set();
13148
13149 warnOnInvalidCallback$1 = function (callback, callerName) {
13150 if (callback === null || typeof callback === 'function') {
13151 return;
13152 }
13153 var key = callerName + '_' + callback;
13154 if (!didWarnOnInvalidCallback.has(key)) {
13155 didWarnOnInvalidCallback.add(key);
13156 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
13157 }
13158 };
13159
13160 warnOnUndefinedDerivedState = function (type, partialState) {
13161 if (partialState === undefined) {
13162 var componentName = getComponentName(type) || 'Component';
13163 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
13164 didWarnAboutUndefinedDerivedState.add(componentName);
13165 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
13166 }
13167 }
13168 };
13169
13170 // This is so gross but it's at least non-critical and can be removed if
13171 // it causes problems. This is meant to give a nicer error message for
13172 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
13173 // ...)) which otherwise throws a "_processChildContext is not a function"
13174 // exception.
13175 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
13176 enumerable: false,
13177 value: function () {
13178 (function () {
13179 {
13180 {
13181 throw ReactError(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).'));
13182 }
13183 }
13184 })();
13185 }
13186 });
13187 Object.freeze(fakeInternalInstance);
13188}
13189
13190function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
13191 var prevState = workInProgress.memoizedState;
13192
13193 {
13194 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
13195 // Invoke the function an extra time to help detect side-effects.
13196 getDerivedStateFromProps(nextProps, prevState);
13197 }
13198 }
13199
13200 var partialState = getDerivedStateFromProps(nextProps, prevState);
13201
13202 {
13203 warnOnUndefinedDerivedState(ctor, partialState);
13204 }
13205 // Merge the partial state and the previous state.
13206 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
13207 workInProgress.memoizedState = memoizedState;
13208
13209 // Once the update queue is empty, persist the derived state onto the
13210 // base state.
13211 var updateQueue = workInProgress.updateQueue;
13212 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
13213 updateQueue.baseState = memoizedState;
13214 }
13215}
13216
13217var classComponentUpdater = {
13218 isMounted: isMounted,
13219 enqueueSetState: function (inst, payload, callback) {
13220 var fiber = get(inst);
13221 var currentTime = requestCurrentTime();
13222 var suspenseConfig = requestCurrentSuspenseConfig();
13223 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
13224
13225 var update = createUpdate(expirationTime, suspenseConfig);
13226 update.payload = payload;
13227 if (callback !== undefined && callback !== null) {
13228 {
13229 warnOnInvalidCallback$1(callback, 'setState');
13230 }
13231 update.callback = callback;
13232 }
13233
13234 if (revertPassiveEffectsChange) {
13235 flushPassiveEffects();
13236 }
13237 enqueueUpdate(fiber, update);
13238 scheduleWork(fiber, expirationTime);
13239 },
13240 enqueueReplaceState: function (inst, payload, callback) {
13241 var fiber = get(inst);
13242 var currentTime = requestCurrentTime();
13243 var suspenseConfig = requestCurrentSuspenseConfig();
13244 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
13245
13246 var update = createUpdate(expirationTime, suspenseConfig);
13247 update.tag = ReplaceState;
13248 update.payload = payload;
13249
13250 if (callback !== undefined && callback !== null) {
13251 {
13252 warnOnInvalidCallback$1(callback, 'replaceState');
13253 }
13254 update.callback = callback;
13255 }
13256
13257 if (revertPassiveEffectsChange) {
13258 flushPassiveEffects();
13259 }
13260 enqueueUpdate(fiber, update);
13261 scheduleWork(fiber, expirationTime);
13262 },
13263 enqueueForceUpdate: function (inst, callback) {
13264 var fiber = get(inst);
13265 var currentTime = requestCurrentTime();
13266 var suspenseConfig = requestCurrentSuspenseConfig();
13267 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
13268
13269 var update = createUpdate(expirationTime, suspenseConfig);
13270 update.tag = ForceUpdate;
13271
13272 if (callback !== undefined && callback !== null) {
13273 {
13274 warnOnInvalidCallback$1(callback, 'forceUpdate');
13275 }
13276 update.callback = callback;
13277 }
13278
13279 if (revertPassiveEffectsChange) {
13280 flushPassiveEffects();
13281 }
13282 enqueueUpdate(fiber, update);
13283 scheduleWork(fiber, expirationTime);
13284 }
13285};
13286
13287function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
13288 var instance = workInProgress.stateNode;
13289 if (typeof instance.shouldComponentUpdate === 'function') {
13290 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
13291 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
13292 stopPhaseTimer();
13293
13294 {
13295 !(shouldUpdate !== undefined) ? warningWithoutStack$1(false, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component') : void 0;
13296 }
13297
13298 return shouldUpdate;
13299 }
13300
13301 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
13302 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
13303 }
13304
13305 return true;
13306}
13307
13308function checkClassInstance(workInProgress, ctor, newProps) {
13309 var instance = workInProgress.stateNode;
13310 {
13311 var name = getComponentName(ctor) || 'Component';
13312 var renderPresent = instance.render;
13313
13314 if (!renderPresent) {
13315 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
13316 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
13317 } else {
13318 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
13319 }
13320 }
13321
13322 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
13323 !noGetInitialStateOnES6 ? warningWithoutStack$1(false, '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) : void 0;
13324 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
13325 !noGetDefaultPropsOnES6 ? warningWithoutStack$1(false, '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) : void 0;
13326 var noInstancePropTypes = !instance.propTypes;
13327 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
13328 var noInstanceContextType = !instance.contextType;
13329 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
13330
13331 if (disableLegacyContext) {
13332 if (ctor.childContextTypes) {
13333 warningWithoutStack$1(false, '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name);
13334 }
13335 if (ctor.contextTypes) {
13336 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name);
13337 }
13338 } else {
13339 var noInstanceContextTypes = !instance.contextTypes;
13340 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
13341
13342 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
13343 didWarnAboutContextTypeAndContextTypes.add(ctor);
13344 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
13345 }
13346 }
13347
13348 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
13349 !noComponentShouldUpdate ? warningWithoutStack$1(false, '%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) : void 0;
13350 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
13351 warningWithoutStack$1(false, '%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');
13352 }
13353 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
13354 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
13355 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
13356 !noComponentDidReceiveProps ? warningWithoutStack$1(false, '%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) : void 0;
13357 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
13358 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
13359 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
13360 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
13361 var hasMutatedProps = instance.props !== newProps;
13362 !(instance.props === undefined || !hasMutatedProps) ? warningWithoutStack$1(false, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name) : void 0;
13363 var noInstanceDefaultProps = !instance.defaultProps;
13364 !noInstanceDefaultProps ? warningWithoutStack$1(false, '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) : void 0;
13365
13366 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
13367 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
13368 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
13369 }
13370
13371 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
13372 !noInstanceGetDerivedStateFromProps ? warningWithoutStack$1(false, '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
13373 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
13374 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
13375 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
13376 !noStaticGetSnapshotBeforeUpdate ? warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name) : void 0;
13377 var _state = instance.state;
13378 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
13379 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
13380 }
13381 if (typeof instance.getChildContext === 'function') {
13382 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
13383 }
13384 }
13385}
13386
13387function adoptClassInstance(workInProgress, instance) {
13388 instance.updater = classComponentUpdater;
13389 workInProgress.stateNode = instance;
13390 // The instance needs access to the fiber so that it can schedule updates
13391 set(instance, workInProgress);
13392 {
13393 instance._reactInternalInstance = fakeInternalInstance;
13394 }
13395}
13396
13397function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
13398 var isLegacyContextConsumer = false;
13399 var unmaskedContext = emptyContextObject;
13400 var context = emptyContextObject;
13401 var contextType = ctor.contextType;
13402
13403 {
13404 if ('contextType' in ctor) {
13405 var isValid =
13406 // Allow null for conditional declaration
13407 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
13408
13409 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
13410 didWarnAboutInvalidateContextType.add(ctor);
13411
13412 var addendum = '';
13413 if (contextType === undefined) {
13414 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.';
13415 } else if (typeof contextType !== 'object') {
13416 addendum = ' However, it is set to a ' + typeof contextType + '.';
13417 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
13418 addendum = ' Did you accidentally pass the Context.Provider instead?';
13419 } else if (contextType._context !== undefined) {
13420 // <Context.Consumer>
13421 addendum = ' Did you accidentally pass the Context.Consumer instead?';
13422 } else {
13423 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
13424 }
13425 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
13426 }
13427 }
13428 }
13429
13430 if (typeof contextType === 'object' && contextType !== null) {
13431 context = readContext(contextType);
13432 } else if (!disableLegacyContext) {
13433 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13434 var contextTypes = ctor.contextTypes;
13435 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
13436 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
13437 }
13438
13439 // Instantiate twice to help detect side-effects.
13440 {
13441 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
13442 new ctor(props, context); // eslint-disable-line no-new
13443 }
13444 }
13445
13446 var instance = new ctor(props, context);
13447 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
13448 adoptClassInstance(workInProgress, instance);
13449
13450 {
13451 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
13452 var componentName = getComponentName(ctor) || 'Component';
13453 if (!didWarnAboutUninitializedState.has(componentName)) {
13454 didWarnAboutUninitializedState.add(componentName);
13455 warningWithoutStack$1(false, '`%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);
13456 }
13457 }
13458
13459 // If new component APIs are defined, "unsafe" lifecycles won't be called.
13460 // Warn about these lifecycles if they are present.
13461 // Don't warn about react-lifecycles-compat polyfilled methods though.
13462 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
13463 var foundWillMountName = null;
13464 var foundWillReceivePropsName = null;
13465 var foundWillUpdateName = null;
13466 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
13467 foundWillMountName = 'componentWillMount';
13468 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
13469 foundWillMountName = 'UNSAFE_componentWillMount';
13470 }
13471 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
13472 foundWillReceivePropsName = 'componentWillReceiveProps';
13473 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13474 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
13475 }
13476 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
13477 foundWillUpdateName = 'componentWillUpdate';
13478 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13479 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
13480 }
13481 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
13482 var _componentName = getComponentName(ctor) || 'Component';
13483 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
13484 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
13485 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
13486 warningWithoutStack$1(false, '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-async-component-lifecycle-hooks', _componentName, newApiName, foundWillMountName !== null ? '\n ' + foundWillMountName : '', foundWillReceivePropsName !== null ? '\n ' + foundWillReceivePropsName : '', foundWillUpdateName !== null ? '\n ' + foundWillUpdateName : '');
13487 }
13488 }
13489 }
13490 }
13491
13492 // Cache unmasked context so we can avoid recreating masked context unless necessary.
13493 // ReactFiberContext usually updates this cache but can't for newly-created instances.
13494 if (isLegacyContextConsumer) {
13495 cacheContext(workInProgress, unmaskedContext, context);
13496 }
13497
13498 return instance;
13499}
13500
13501function callComponentWillMount(workInProgress, instance) {
13502 startPhaseTimer(workInProgress, 'componentWillMount');
13503 var oldState = instance.state;
13504
13505 if (typeof instance.componentWillMount === 'function') {
13506 instance.componentWillMount();
13507 }
13508 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13509 instance.UNSAFE_componentWillMount();
13510 }
13511
13512 stopPhaseTimer();
13513
13514 if (oldState !== instance.state) {
13515 {
13516 warningWithoutStack$1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
13517 }
13518 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13519 }
13520}
13521
13522function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
13523 var oldState = instance.state;
13524 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
13525 if (typeof instance.componentWillReceiveProps === 'function') {
13526 instance.componentWillReceiveProps(newProps, nextContext);
13527 }
13528 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13529 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
13530 }
13531 stopPhaseTimer();
13532
13533 if (instance.state !== oldState) {
13534 {
13535 var componentName = getComponentName(workInProgress.type) || 'Component';
13536 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
13537 didWarnAboutStateAssignmentForComponent.add(componentName);
13538 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
13539 }
13540 }
13541 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13542 }
13543}
13544
13545// Invokes the mount life-cycles on a previously never rendered instance.
13546function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13547 {
13548 checkClassInstance(workInProgress, ctor, newProps);
13549 }
13550
13551 var instance = workInProgress.stateNode;
13552 instance.props = newProps;
13553 instance.state = workInProgress.memoizedState;
13554 instance.refs = emptyRefsObject;
13555
13556 var contextType = ctor.contextType;
13557 if (typeof contextType === 'object' && contextType !== null) {
13558 instance.context = readContext(contextType);
13559 } else if (disableLegacyContext) {
13560 instance.context = emptyContextObject;
13561 } else {
13562 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13563 instance.context = getMaskedContext(workInProgress, unmaskedContext);
13564 }
13565
13566 {
13567 if (instance.state === newProps) {
13568 var componentName = getComponentName(ctor) || 'Component';
13569 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
13570 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
13571 warningWithoutStack$1(false, '%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);
13572 }
13573 }
13574
13575 if (workInProgress.mode & StrictMode) {
13576 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
13577 }
13578
13579 if (warnAboutDeprecatedLifecycles) {
13580 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
13581 }
13582 }
13583
13584 var updateQueue = workInProgress.updateQueue;
13585 if (updateQueue !== null) {
13586 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13587 instance.state = workInProgress.memoizedState;
13588 }
13589
13590 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13591 if (typeof getDerivedStateFromProps === 'function') {
13592 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13593 instance.state = workInProgress.memoizedState;
13594 }
13595
13596 // In order to support react-lifecycles-compat polyfilled components,
13597 // Unsafe lifecycles should not be invoked for components using the new APIs.
13598 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13599 callComponentWillMount(workInProgress, instance);
13600 // If we had additional state updates during this life-cycle, let's
13601 // process them now.
13602 updateQueue = workInProgress.updateQueue;
13603 if (updateQueue !== null) {
13604 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13605 instance.state = workInProgress.memoizedState;
13606 }
13607 }
13608
13609 if (typeof instance.componentDidMount === 'function') {
13610 workInProgress.effectTag |= Update;
13611 }
13612}
13613
13614function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
13615 var instance = workInProgress.stateNode;
13616
13617 var oldProps = workInProgress.memoizedProps;
13618 instance.props = oldProps;
13619
13620 var oldContext = instance.context;
13621 var contextType = ctor.contextType;
13622 var nextContext = emptyContextObject;
13623 if (typeof contextType === 'object' && contextType !== null) {
13624 nextContext = readContext(contextType);
13625 } else if (!disableLegacyContext) {
13626 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13627 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
13628 }
13629
13630 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13631 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
13632
13633 // Note: During these life-cycles, instance.props/instance.state are what
13634 // ever the previously attempted to render - not the "current". However,
13635 // during componentDidUpdate we pass the "current" props.
13636
13637 // In order to support react-lifecycles-compat polyfilled components,
13638 // Unsafe lifecycles should not be invoked for components using the new APIs.
13639 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13640 if (oldProps !== newProps || oldContext !== nextContext) {
13641 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13642 }
13643 }
13644
13645 resetHasForceUpdateBeforeProcessing();
13646
13647 var oldState = workInProgress.memoizedState;
13648 var newState = instance.state = oldState;
13649 var updateQueue = workInProgress.updateQueue;
13650 if (updateQueue !== null) {
13651 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13652 newState = workInProgress.memoizedState;
13653 }
13654 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13655 // If an update was already in progress, we should schedule an Update
13656 // effect even though we're bailing out, so that cWU/cDU are called.
13657 if (typeof instance.componentDidMount === 'function') {
13658 workInProgress.effectTag |= Update;
13659 }
13660 return false;
13661 }
13662
13663 if (typeof getDerivedStateFromProps === 'function') {
13664 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13665 newState = workInProgress.memoizedState;
13666 }
13667
13668 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13669
13670 if (shouldUpdate) {
13671 // In order to support react-lifecycles-compat polyfilled components,
13672 // Unsafe lifecycles should not be invoked for components using the new APIs.
13673 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13674 startPhaseTimer(workInProgress, 'componentWillMount');
13675 if (typeof instance.componentWillMount === 'function') {
13676 instance.componentWillMount();
13677 }
13678 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13679 instance.UNSAFE_componentWillMount();
13680 }
13681 stopPhaseTimer();
13682 }
13683 if (typeof instance.componentDidMount === 'function') {
13684 workInProgress.effectTag |= Update;
13685 }
13686 } else {
13687 // If an update was already in progress, we should schedule an Update
13688 // effect even though we're bailing out, so that cWU/cDU are called.
13689 if (typeof instance.componentDidMount === 'function') {
13690 workInProgress.effectTag |= Update;
13691 }
13692
13693 // If shouldComponentUpdate returned false, we should still update the
13694 // memoized state to indicate that this work can be reused.
13695 workInProgress.memoizedProps = newProps;
13696 workInProgress.memoizedState = newState;
13697 }
13698
13699 // Update the existing instance's state, props, and context pointers even
13700 // if shouldComponentUpdate returns false.
13701 instance.props = newProps;
13702 instance.state = newState;
13703 instance.context = nextContext;
13704
13705 return shouldUpdate;
13706}
13707
13708// Invokes the update life-cycles and returns false if it shouldn't rerender.
13709function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
13710 var instance = workInProgress.stateNode;
13711
13712 var oldProps = workInProgress.memoizedProps;
13713 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
13714
13715 var oldContext = instance.context;
13716 var contextType = ctor.contextType;
13717 var nextContext = emptyContextObject;
13718 if (typeof contextType === 'object' && contextType !== null) {
13719 nextContext = readContext(contextType);
13720 } else if (!disableLegacyContext) {
13721 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13722 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13723 }
13724
13725 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13726 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
13727
13728 // Note: During these life-cycles, instance.props/instance.state are what
13729 // ever the previously attempted to render - not the "current". However,
13730 // during componentDidUpdate we pass the "current" props.
13731
13732 // In order to support react-lifecycles-compat polyfilled components,
13733 // Unsafe lifecycles should not be invoked for components using the new APIs.
13734 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13735 if (oldProps !== newProps || oldContext !== nextContext) {
13736 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13737 }
13738 }
13739
13740 resetHasForceUpdateBeforeProcessing();
13741
13742 var oldState = workInProgress.memoizedState;
13743 var newState = instance.state = oldState;
13744 var updateQueue = workInProgress.updateQueue;
13745 if (updateQueue !== null) {
13746 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
13747 newState = workInProgress.memoizedState;
13748 }
13749
13750 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13751 // If an update was already in progress, we should schedule an Update
13752 // effect even though we're bailing out, so that cWU/cDU are called.
13753 if (typeof instance.componentDidUpdate === 'function') {
13754 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13755 workInProgress.effectTag |= Update;
13756 }
13757 }
13758 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13759 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13760 workInProgress.effectTag |= Snapshot;
13761 }
13762 }
13763 return false;
13764 }
13765
13766 if (typeof getDerivedStateFromProps === 'function') {
13767 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13768 newState = workInProgress.memoizedState;
13769 }
13770
13771 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13772
13773 if (shouldUpdate) {
13774 // In order to support react-lifecycles-compat polyfilled components,
13775 // Unsafe lifecycles should not be invoked for components using the new APIs.
13776 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13777 startPhaseTimer(workInProgress, 'componentWillUpdate');
13778 if (typeof instance.componentWillUpdate === 'function') {
13779 instance.componentWillUpdate(newProps, newState, nextContext);
13780 }
13781 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13782 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13783 }
13784 stopPhaseTimer();
13785 }
13786 if (typeof instance.componentDidUpdate === 'function') {
13787 workInProgress.effectTag |= Update;
13788 }
13789 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13790 workInProgress.effectTag |= Snapshot;
13791 }
13792 } else {
13793 // If an update was already in progress, we should schedule an Update
13794 // effect even though we're bailing out, so that cWU/cDU are called.
13795 if (typeof instance.componentDidUpdate === 'function') {
13796 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13797 workInProgress.effectTag |= Update;
13798 }
13799 }
13800 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13801 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13802 workInProgress.effectTag |= Snapshot;
13803 }
13804 }
13805
13806 // If shouldComponentUpdate returned false, we should still update the
13807 // memoized props/state to indicate that this work can be reused.
13808 workInProgress.memoizedProps = newProps;
13809 workInProgress.memoizedState = newState;
13810 }
13811
13812 // Update the existing instance's state, props, and context pointers even
13813 // if shouldComponentUpdate returns false.
13814 instance.props = newProps;
13815 instance.state = newState;
13816 instance.context = nextContext;
13817
13818 return shouldUpdate;
13819}
13820
13821var didWarnAboutMaps = void 0;
13822var didWarnAboutGenerators = void 0;
13823var didWarnAboutStringRefInStrictMode = void 0;
13824var ownerHasKeyUseWarning = void 0;
13825var ownerHasFunctionTypeWarning = void 0;
13826var warnForMissingKey = function (child) {};
13827
13828{
13829 didWarnAboutMaps = false;
13830 didWarnAboutGenerators = false;
13831 didWarnAboutStringRefInStrictMode = {};
13832
13833 /**
13834 * Warn if there's no key explicitly set on dynamic arrays of children or
13835 * object keys are not valid. This allows us to keep track of children between
13836 * updates.
13837 */
13838 ownerHasKeyUseWarning = {};
13839 ownerHasFunctionTypeWarning = {};
13840
13841 warnForMissingKey = function (child) {
13842 if (child === null || typeof child !== 'object') {
13843 return;
13844 }
13845 if (!child._store || child._store.validated || child.key != null) {
13846 return;
13847 }
13848 (function () {
13849 if (!(typeof child._store === 'object')) {
13850 {
13851 throw ReactError(Error('React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.'));
13852 }
13853 }
13854 })();
13855 child._store.validated = true;
13856
13857 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
13858 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
13859 return;
13860 }
13861 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
13862
13863 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
13864 };
13865}
13866
13867var isArray = Array.isArray;
13868
13869function coerceRef(returnFiber, current$$1, element) {
13870 var mixedRef = element.ref;
13871 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
13872 {
13873 if (returnFiber.mode & StrictMode) {
13874 var componentName = getComponentName(returnFiber.type) || 'Component';
13875 if (!didWarnAboutStringRefInStrictMode[componentName]) {
13876 warningWithoutStack$1(false, '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 createRef() instead.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-string-ref', mixedRef, getStackByFiberInDevAndProd(returnFiber));
13877 didWarnAboutStringRefInStrictMode[componentName] = true;
13878 }
13879 }
13880 }
13881
13882 if (element._owner) {
13883 var owner = element._owner;
13884 var inst = void 0;
13885 if (owner) {
13886 var ownerFiber = owner;
13887 (function () {
13888 if (!(ownerFiber.tag === ClassComponent)) {
13889 {
13890 throw ReactError(Error('Function components cannot have refs. Did you mean to use React.forwardRef()?'));
13891 }
13892 }
13893 })();
13894 inst = ownerFiber.stateNode;
13895 }
13896 (function () {
13897 if (!inst) {
13898 {
13899 throw ReactError(Error('Missing owner for string ref ' + mixedRef + '. This error is likely caused by a bug in React. Please file an issue.'));
13900 }
13901 }
13902 })();
13903 var stringRef = '' + mixedRef;
13904 // Check if previous string ref matches new string ref
13905 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
13906 return current$$1.ref;
13907 }
13908 var ref = function (value) {
13909 var refs = inst.refs;
13910 if (refs === emptyRefsObject) {
13911 // This is a lazy pooled frozen object, so we need to initialize.
13912 refs = inst.refs = {};
13913 }
13914 if (value === null) {
13915 delete refs[stringRef];
13916 } else {
13917 refs[stringRef] = value;
13918 }
13919 };
13920 ref._stringRef = stringRef;
13921 return ref;
13922 } else {
13923 (function () {
13924 if (!(typeof mixedRef === 'string')) {
13925 {
13926 throw ReactError(Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.'));
13927 }
13928 }
13929 })();
13930 (function () {
13931 if (!element._owner) {
13932 {
13933 throw ReactError(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.'));
13934 }
13935 }
13936 })();
13937 }
13938 }
13939 return mixedRef;
13940}
13941
13942function throwOnInvalidObjectType(returnFiber, newChild) {
13943 if (returnFiber.type !== 'textarea') {
13944 var addendum = '';
13945 {
13946 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
13947 }
13948 (function () {
13949 {
13950 {
13951 throw ReactError(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));
13952 }
13953 }
13954 })();
13955 }
13956}
13957
13958function warnOnFunctionType() {
13959 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();
13960
13961 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
13962 return;
13963 }
13964 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
13965
13966 warning$1(false, '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.');
13967}
13968
13969// This wrapper function exists because I expect to clone the code in each path
13970// to be able to optimize each path individually by branching early. This needs
13971// a compiler or we can do it manually. Helpers that don't need this branching
13972// live outside of this function.
13973function ChildReconciler(shouldTrackSideEffects) {
13974 function deleteChild(returnFiber, childToDelete) {
13975 if (!shouldTrackSideEffects) {
13976 // Noop.
13977 return;
13978 }
13979 // Deletions are added in reversed order so we add it to the front.
13980 // At this point, the return fiber's effect list is empty except for
13981 // deletions, so we can just append the deletion to the list. The remaining
13982 // effects aren't added until the complete phase. Once we implement
13983 // resuming, this may not be true.
13984 var last = returnFiber.lastEffect;
13985 if (last !== null) {
13986 last.nextEffect = childToDelete;
13987 returnFiber.lastEffect = childToDelete;
13988 } else {
13989 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13990 }
13991 childToDelete.nextEffect = null;
13992 childToDelete.effectTag = Deletion;
13993 }
13994
13995 function deleteRemainingChildren(returnFiber, currentFirstChild) {
13996 if (!shouldTrackSideEffects) {
13997 // Noop.
13998 return null;
13999 }
14000
14001 // TODO: For the shouldClone case, this could be micro-optimized a bit by
14002 // assuming that after the first child we've already added everything.
14003 var childToDelete = currentFirstChild;
14004 while (childToDelete !== null) {
14005 deleteChild(returnFiber, childToDelete);
14006 childToDelete = childToDelete.sibling;
14007 }
14008 return null;
14009 }
14010
14011 function mapRemainingChildren(returnFiber, currentFirstChild) {
14012 // Add the remaining children to a temporary map so that we can find them by
14013 // keys quickly. Implicit (null) keys get added to this set with their index
14014 var existingChildren = new Map();
14015
14016 var existingChild = currentFirstChild;
14017 while (existingChild !== null) {
14018 if (existingChild.key !== null) {
14019 existingChildren.set(existingChild.key, existingChild);
14020 } else {
14021 existingChildren.set(existingChild.index, existingChild);
14022 }
14023 existingChild = existingChild.sibling;
14024 }
14025 return existingChildren;
14026 }
14027
14028 function useFiber(fiber, pendingProps, expirationTime) {
14029 // We currently set sibling to null and index to 0 here because it is easy
14030 // to forget to do before returning it. E.g. for the single child case.
14031 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
14032 clone.index = 0;
14033 clone.sibling = null;
14034 return clone;
14035 }
14036
14037 function placeChild(newFiber, lastPlacedIndex, newIndex) {
14038 newFiber.index = newIndex;
14039 if (!shouldTrackSideEffects) {
14040 // Noop.
14041 return lastPlacedIndex;
14042 }
14043 var current$$1 = newFiber.alternate;
14044 if (current$$1 !== null) {
14045 var oldIndex = current$$1.index;
14046 if (oldIndex < lastPlacedIndex) {
14047 // This is a move.
14048 newFiber.effectTag = Placement;
14049 return lastPlacedIndex;
14050 } else {
14051 // This item can stay in place.
14052 return oldIndex;
14053 }
14054 } else {
14055 // This is an insertion.
14056 newFiber.effectTag = Placement;
14057 return lastPlacedIndex;
14058 }
14059 }
14060
14061 function placeSingleChild(newFiber) {
14062 // This is simpler for the single child case. We only need to do a
14063 // placement for inserting new children.
14064 if (shouldTrackSideEffects && newFiber.alternate === null) {
14065 newFiber.effectTag = Placement;
14066 }
14067 return newFiber;
14068 }
14069
14070 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
14071 if (current$$1 === null || current$$1.tag !== HostText) {
14072 // Insert
14073 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
14074 created.return = returnFiber;
14075 return created;
14076 } else {
14077 // Update
14078 var existing = useFiber(current$$1, textContent, expirationTime);
14079 existing.return = returnFiber;
14080 return existing;
14081 }
14082 }
14083
14084 function updateElement(returnFiber, current$$1, element, expirationTime) {
14085 if (current$$1 !== null && (current$$1.elementType === element.type || (
14086 // Keep this check inline so it only runs on the false path:
14087 isCompatibleFamilyForHotReloading(current$$1, element)))) {
14088 // Move based on index
14089 var existing = useFiber(current$$1, element.props, expirationTime);
14090 existing.ref = coerceRef(returnFiber, current$$1, element);
14091 existing.return = returnFiber;
14092 {
14093 existing._debugSource = element._source;
14094 existing._debugOwner = element._owner;
14095 }
14096 return existing;
14097 } else {
14098 // Insert
14099 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
14100 created.ref = coerceRef(returnFiber, current$$1, element);
14101 created.return = returnFiber;
14102 return created;
14103 }
14104 }
14105
14106 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
14107 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
14108 // Insert
14109 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
14110 created.return = returnFiber;
14111 return created;
14112 } else {
14113 // Update
14114 var existing = useFiber(current$$1, portal.children || [], expirationTime);
14115 existing.return = returnFiber;
14116 return existing;
14117 }
14118 }
14119
14120 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
14121 if (current$$1 === null || current$$1.tag !== Fragment) {
14122 // Insert
14123 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
14124 created.return = returnFiber;
14125 return created;
14126 } else {
14127 // Update
14128 var existing = useFiber(current$$1, fragment, expirationTime);
14129 existing.return = returnFiber;
14130 return existing;
14131 }
14132 }
14133
14134 function createChild(returnFiber, newChild, expirationTime) {
14135 if (typeof newChild === 'string' || typeof newChild === 'number') {
14136 // Text nodes don't have keys. If the previous node is implicitly keyed
14137 // we can continue to replace it without aborting even if it is not a text
14138 // node.
14139 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
14140 created.return = returnFiber;
14141 return created;
14142 }
14143
14144 if (typeof newChild === 'object' && newChild !== null) {
14145 switch (newChild.$$typeof) {
14146 case REACT_ELEMENT_TYPE:
14147 {
14148 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
14149 _created.ref = coerceRef(returnFiber, null, newChild);
14150 _created.return = returnFiber;
14151 return _created;
14152 }
14153 case REACT_PORTAL_TYPE:
14154 {
14155 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
14156 _created2.return = returnFiber;
14157 return _created2;
14158 }
14159 }
14160
14161 if (isArray(newChild) || getIteratorFn(newChild)) {
14162 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
14163 _created3.return = returnFiber;
14164 return _created3;
14165 }
14166
14167 throwOnInvalidObjectType(returnFiber, newChild);
14168 }
14169
14170 {
14171 if (typeof newChild === 'function') {
14172 warnOnFunctionType();
14173 }
14174 }
14175
14176 return null;
14177 }
14178
14179 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
14180 // Update the fiber if the keys match, otherwise return null.
14181
14182 var key = oldFiber !== null ? oldFiber.key : null;
14183
14184 if (typeof newChild === 'string' || typeof newChild === 'number') {
14185 // Text nodes don't have keys. If the previous node is implicitly keyed
14186 // we can continue to replace it without aborting even if it is not a text
14187 // node.
14188 if (key !== null) {
14189 return null;
14190 }
14191 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
14192 }
14193
14194 if (typeof newChild === 'object' && newChild !== null) {
14195 switch (newChild.$$typeof) {
14196 case REACT_ELEMENT_TYPE:
14197 {
14198 if (newChild.key === key) {
14199 if (newChild.type === REACT_FRAGMENT_TYPE) {
14200 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
14201 }
14202 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
14203 } else {
14204 return null;
14205 }
14206 }
14207 case REACT_PORTAL_TYPE:
14208 {
14209 if (newChild.key === key) {
14210 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
14211 } else {
14212 return null;
14213 }
14214 }
14215 }
14216
14217 if (isArray(newChild) || getIteratorFn(newChild)) {
14218 if (key !== null) {
14219 return null;
14220 }
14221
14222 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
14223 }
14224
14225 throwOnInvalidObjectType(returnFiber, newChild);
14226 }
14227
14228 {
14229 if (typeof newChild === 'function') {
14230 warnOnFunctionType();
14231 }
14232 }
14233
14234 return null;
14235 }
14236
14237 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
14238 if (typeof newChild === 'string' || typeof newChild === 'number') {
14239 // Text nodes don't have keys, so we neither have to check the old nor
14240 // new node for the key. If both are text nodes, they match.
14241 var matchedFiber = existingChildren.get(newIdx) || null;
14242 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
14243 }
14244
14245 if (typeof newChild === 'object' && newChild !== null) {
14246 switch (newChild.$$typeof) {
14247 case REACT_ELEMENT_TYPE:
14248 {
14249 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
14250 if (newChild.type === REACT_FRAGMENT_TYPE) {
14251 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
14252 }
14253 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
14254 }
14255 case REACT_PORTAL_TYPE:
14256 {
14257 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
14258 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
14259 }
14260 }
14261
14262 if (isArray(newChild) || getIteratorFn(newChild)) {
14263 var _matchedFiber3 = existingChildren.get(newIdx) || null;
14264 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
14265 }
14266
14267 throwOnInvalidObjectType(returnFiber, newChild);
14268 }
14269
14270 {
14271 if (typeof newChild === 'function') {
14272 warnOnFunctionType();
14273 }
14274 }
14275
14276 return null;
14277 }
14278
14279 /**
14280 * Warns if there is a duplicate or missing key
14281 */
14282 function warnOnInvalidKey(child, knownKeys) {
14283 {
14284 if (typeof child !== 'object' || child === null) {
14285 return knownKeys;
14286 }
14287 switch (child.$$typeof) {
14288 case REACT_ELEMENT_TYPE:
14289 case REACT_PORTAL_TYPE:
14290 warnForMissingKey(child);
14291 var key = child.key;
14292 if (typeof key !== 'string') {
14293 break;
14294 }
14295 if (knownKeys === null) {
14296 knownKeys = new Set();
14297 knownKeys.add(key);
14298 break;
14299 }
14300 if (!knownKeys.has(key)) {
14301 knownKeys.add(key);
14302 break;
14303 }
14304 warning$1(false, '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);
14305 break;
14306 default:
14307 break;
14308 }
14309 }
14310 return knownKeys;
14311 }
14312
14313 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
14314 // This algorithm can't optimize by searching from both ends since we
14315 // don't have backpointers on fibers. I'm trying to see how far we can get
14316 // with that model. If it ends up not being worth the tradeoffs, we can
14317 // add it later.
14318
14319 // Even with a two ended optimization, we'd want to optimize for the case
14320 // where there are few changes and brute force the comparison instead of
14321 // going for the Map. It'd like to explore hitting that path first in
14322 // forward-only mode and only go for the Map once we notice that we need
14323 // lots of look ahead. This doesn't handle reversal as well as two ended
14324 // search but that's unusual. Besides, for the two ended optimization to
14325 // work on Iterables, we'd need to copy the whole set.
14326
14327 // In this first iteration, we'll just live with hitting the bad case
14328 // (adding everything to a Map) in for every insert/move.
14329
14330 // If you change this code, also update reconcileChildrenIterator() which
14331 // uses the same algorithm.
14332
14333 {
14334 // First, validate keys.
14335 var knownKeys = null;
14336 for (var i = 0; i < newChildren.length; i++) {
14337 var child = newChildren[i];
14338 knownKeys = warnOnInvalidKey(child, knownKeys);
14339 }
14340 }
14341
14342 var resultingFirstChild = null;
14343 var previousNewFiber = null;
14344
14345 var oldFiber = currentFirstChild;
14346 var lastPlacedIndex = 0;
14347 var newIdx = 0;
14348 var nextOldFiber = null;
14349 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
14350 if (oldFiber.index > newIdx) {
14351 nextOldFiber = oldFiber;
14352 oldFiber = null;
14353 } else {
14354 nextOldFiber = oldFiber.sibling;
14355 }
14356 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
14357 if (newFiber === null) {
14358 // TODO: This breaks on empty slots like null children. That's
14359 // unfortunate because it triggers the slow path all the time. We need
14360 // a better way to communicate whether this was a miss or null,
14361 // boolean, undefined, etc.
14362 if (oldFiber === null) {
14363 oldFiber = nextOldFiber;
14364 }
14365 break;
14366 }
14367 if (shouldTrackSideEffects) {
14368 if (oldFiber && newFiber.alternate === null) {
14369 // We matched the slot, but we didn't reuse the existing fiber, so we
14370 // need to delete the existing child.
14371 deleteChild(returnFiber, oldFiber);
14372 }
14373 }
14374 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14375 if (previousNewFiber === null) {
14376 // TODO: Move out of the loop. This only happens for the first run.
14377 resultingFirstChild = newFiber;
14378 } else {
14379 // TODO: Defer siblings if we're not at the right index for this slot.
14380 // I.e. if we had null values before, then we want to defer this
14381 // for each null value. However, we also don't want to call updateSlot
14382 // with the previous one.
14383 previousNewFiber.sibling = newFiber;
14384 }
14385 previousNewFiber = newFiber;
14386 oldFiber = nextOldFiber;
14387 }
14388
14389 if (newIdx === newChildren.length) {
14390 // We've reached the end of the new children. We can delete the rest.
14391 deleteRemainingChildren(returnFiber, oldFiber);
14392 return resultingFirstChild;
14393 }
14394
14395 if (oldFiber === null) {
14396 // If we don't have any more existing children we can choose a fast path
14397 // since the rest will all be insertions.
14398 for (; newIdx < newChildren.length; newIdx++) {
14399 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
14400 if (_newFiber === null) {
14401 continue;
14402 }
14403 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
14404 if (previousNewFiber === null) {
14405 // TODO: Move out of the loop. This only happens for the first run.
14406 resultingFirstChild = _newFiber;
14407 } else {
14408 previousNewFiber.sibling = _newFiber;
14409 }
14410 previousNewFiber = _newFiber;
14411 }
14412 return resultingFirstChild;
14413 }
14414
14415 // Add all children to a key map for quick lookups.
14416 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
14417
14418 // Keep scanning and use the map to restore deleted items as moves.
14419 for (; newIdx < newChildren.length; newIdx++) {
14420 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
14421 if (_newFiber2 !== null) {
14422 if (shouldTrackSideEffects) {
14423 if (_newFiber2.alternate !== null) {
14424 // The new fiber is a work in progress, but if there exists a
14425 // current, that means that we reused the fiber. We need to delete
14426 // it from the child list so that we don't add it to the deletion
14427 // list.
14428 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
14429 }
14430 }
14431 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
14432 if (previousNewFiber === null) {
14433 resultingFirstChild = _newFiber2;
14434 } else {
14435 previousNewFiber.sibling = _newFiber2;
14436 }
14437 previousNewFiber = _newFiber2;
14438 }
14439 }
14440
14441 if (shouldTrackSideEffects) {
14442 // Any existing children that weren't consumed above were deleted. We need
14443 // to add them to the deletion list.
14444 existingChildren.forEach(function (child) {
14445 return deleteChild(returnFiber, child);
14446 });
14447 }
14448
14449 return resultingFirstChild;
14450 }
14451
14452 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
14453 // This is the same implementation as reconcileChildrenArray(),
14454 // but using the iterator instead.
14455
14456 var iteratorFn = getIteratorFn(newChildrenIterable);
14457 (function () {
14458 if (!(typeof iteratorFn === 'function')) {
14459 {
14460 throw ReactError(Error('An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.'));
14461 }
14462 }
14463 })();
14464
14465 {
14466 // We don't support rendering Generators because it's a mutation.
14467 // See https://github.com/facebook/react/issues/12995
14468 if (typeof Symbol === 'function' &&
14469 // $FlowFixMe Flow doesn't know about toStringTag
14470 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
14471 !didWarnAboutGenerators ? warning$1(false, '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.') : void 0;
14472 didWarnAboutGenerators = true;
14473 }
14474
14475 // Warn about using Maps as children
14476 if (newChildrenIterable.entries === iteratorFn) {
14477 !didWarnAboutMaps ? warning$1(false, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.') : void 0;
14478 didWarnAboutMaps = true;
14479 }
14480
14481 // First, validate keys.
14482 // We'll get a different iterator later for the main pass.
14483 var _newChildren = iteratorFn.call(newChildrenIterable);
14484 if (_newChildren) {
14485 var knownKeys = null;
14486 var _step = _newChildren.next();
14487 for (; !_step.done; _step = _newChildren.next()) {
14488 var child = _step.value;
14489 knownKeys = warnOnInvalidKey(child, knownKeys);
14490 }
14491 }
14492 }
14493
14494 var newChildren = iteratorFn.call(newChildrenIterable);
14495 (function () {
14496 if (!(newChildren != null)) {
14497 {
14498 throw ReactError(Error('An iterable object provided no iterator.'));
14499 }
14500 }
14501 })();
14502
14503 var resultingFirstChild = null;
14504 var previousNewFiber = null;
14505
14506 var oldFiber = currentFirstChild;
14507 var lastPlacedIndex = 0;
14508 var newIdx = 0;
14509 var nextOldFiber = null;
14510
14511 var step = newChildren.next();
14512 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
14513 if (oldFiber.index > newIdx) {
14514 nextOldFiber = oldFiber;
14515 oldFiber = null;
14516 } else {
14517 nextOldFiber = oldFiber.sibling;
14518 }
14519 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
14520 if (newFiber === null) {
14521 // TODO: This breaks on empty slots like null children. That's
14522 // unfortunate because it triggers the slow path all the time. We need
14523 // a better way to communicate whether this was a miss or null,
14524 // boolean, undefined, etc.
14525 if (oldFiber === null) {
14526 oldFiber = nextOldFiber;
14527 }
14528 break;
14529 }
14530 if (shouldTrackSideEffects) {
14531 if (oldFiber && newFiber.alternate === null) {
14532 // We matched the slot, but we didn't reuse the existing fiber, so we
14533 // need to delete the existing child.
14534 deleteChild(returnFiber, oldFiber);
14535 }
14536 }
14537 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
14538 if (previousNewFiber === null) {
14539 // TODO: Move out of the loop. This only happens for the first run.
14540 resultingFirstChild = newFiber;
14541 } else {
14542 // TODO: Defer siblings if we're not at the right index for this slot.
14543 // I.e. if we had null values before, then we want to defer this
14544 // for each null value. However, we also don't want to call updateSlot
14545 // with the previous one.
14546 previousNewFiber.sibling = newFiber;
14547 }
14548 previousNewFiber = newFiber;
14549 oldFiber = nextOldFiber;
14550 }
14551
14552 if (step.done) {
14553 // We've reached the end of the new children. We can delete the rest.
14554 deleteRemainingChildren(returnFiber, oldFiber);
14555 return resultingFirstChild;
14556 }
14557
14558 if (oldFiber === null) {
14559 // If we don't have any more existing children we can choose a fast path
14560 // since the rest will all be insertions.
14561 for (; !step.done; newIdx++, step = newChildren.next()) {
14562 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
14563 if (_newFiber3 === null) {
14564 continue;
14565 }
14566 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
14567 if (previousNewFiber === null) {
14568 // TODO: Move out of the loop. This only happens for the first run.
14569 resultingFirstChild = _newFiber3;
14570 } else {
14571 previousNewFiber.sibling = _newFiber3;
14572 }
14573 previousNewFiber = _newFiber3;
14574 }
14575 return resultingFirstChild;
14576 }
14577
14578 // Add all children to a key map for quick lookups.
14579 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
14580
14581 // Keep scanning and use the map to restore deleted items as moves.
14582 for (; !step.done; newIdx++, step = newChildren.next()) {
14583 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
14584 if (_newFiber4 !== null) {
14585 if (shouldTrackSideEffects) {
14586 if (_newFiber4.alternate !== null) {
14587 // The new fiber is a work in progress, but if there exists a
14588 // current, that means that we reused the fiber. We need to delete
14589 // it from the child list so that we don't add it to the deletion
14590 // list.
14591 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
14592 }
14593 }
14594 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
14595 if (previousNewFiber === null) {
14596 resultingFirstChild = _newFiber4;
14597 } else {
14598 previousNewFiber.sibling = _newFiber4;
14599 }
14600 previousNewFiber = _newFiber4;
14601 }
14602 }
14603
14604 if (shouldTrackSideEffects) {
14605 // Any existing children that weren't consumed above were deleted. We need
14606 // to add them to the deletion list.
14607 existingChildren.forEach(function (child) {
14608 return deleteChild(returnFiber, child);
14609 });
14610 }
14611
14612 return resultingFirstChild;
14613 }
14614
14615 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
14616 // There's no need to check for keys on text nodes since we don't have a
14617 // way to define them.
14618 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
14619 // We already have an existing node so let's just update it and delete
14620 // the rest.
14621 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
14622 var existing = useFiber(currentFirstChild, textContent, expirationTime);
14623 existing.return = returnFiber;
14624 return existing;
14625 }
14626 // The existing first child is not a text node so we need to create one
14627 // and delete the existing ones.
14628 deleteRemainingChildren(returnFiber, currentFirstChild);
14629 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
14630 created.return = returnFiber;
14631 return created;
14632 }
14633
14634 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
14635 var key = element.key;
14636 var child = currentFirstChild;
14637 while (child !== null) {
14638 // TODO: If key === null and child.key === null, then this only applies to
14639 // the first item in the list.
14640 if (child.key === key) {
14641 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type || (
14642 // Keep this check inline so it only runs on the false path:
14643 isCompatibleFamilyForHotReloading(child, element))) {
14644 deleteRemainingChildren(returnFiber, child.sibling);
14645 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
14646 existing.ref = coerceRef(returnFiber, child, element);
14647 existing.return = returnFiber;
14648 {
14649 existing._debugSource = element._source;
14650 existing._debugOwner = element._owner;
14651 }
14652 return existing;
14653 } else {
14654 deleteRemainingChildren(returnFiber, child);
14655 break;
14656 }
14657 } else {
14658 deleteChild(returnFiber, child);
14659 }
14660 child = child.sibling;
14661 }
14662
14663 if (element.type === REACT_FRAGMENT_TYPE) {
14664 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
14665 created.return = returnFiber;
14666 return created;
14667 } else {
14668 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
14669 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
14670 _created4.return = returnFiber;
14671 return _created4;
14672 }
14673 }
14674
14675 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
14676 var key = portal.key;
14677 var child = currentFirstChild;
14678 while (child !== null) {
14679 // TODO: If key === null and child.key === null, then this only applies to
14680 // the first item in the list.
14681 if (child.key === key) {
14682 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
14683 deleteRemainingChildren(returnFiber, child.sibling);
14684 var existing = useFiber(child, portal.children || [], expirationTime);
14685 existing.return = returnFiber;
14686 return existing;
14687 } else {
14688 deleteRemainingChildren(returnFiber, child);
14689 break;
14690 }
14691 } else {
14692 deleteChild(returnFiber, child);
14693 }
14694 child = child.sibling;
14695 }
14696
14697 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
14698 created.return = returnFiber;
14699 return created;
14700 }
14701
14702 // This API will tag the children with the side-effect of the reconciliation
14703 // itself. They will be added to the side-effect list as we pass through the
14704 // children and the parent.
14705 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
14706 // This function is not recursive.
14707 // If the top level item is an array, we treat it as a set of children,
14708 // not as a fragment. Nested arrays on the other hand will be treated as
14709 // fragment nodes. Recursion happens at the normal flow.
14710
14711 // Handle top level unkeyed fragments as if they were arrays.
14712 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14713 // We treat the ambiguous cases above the same.
14714 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
14715 if (isUnkeyedTopLevelFragment) {
14716 newChild = newChild.props.children;
14717 }
14718
14719 // Handle object types
14720 var isObject = typeof newChild === 'object' && newChild !== null;
14721
14722 if (isObject) {
14723 switch (newChild.$$typeof) {
14724 case REACT_ELEMENT_TYPE:
14725 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
14726 case REACT_PORTAL_TYPE:
14727 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
14728 }
14729 }
14730
14731 if (typeof newChild === 'string' || typeof newChild === 'number') {
14732 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
14733 }
14734
14735 if (isArray(newChild)) {
14736 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
14737 }
14738
14739 if (getIteratorFn(newChild)) {
14740 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
14741 }
14742
14743 if (isObject) {
14744 throwOnInvalidObjectType(returnFiber, newChild);
14745 }
14746
14747 {
14748 if (typeof newChild === 'function') {
14749 warnOnFunctionType();
14750 }
14751 }
14752 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
14753 // If the new child is undefined, and the return fiber is a composite
14754 // component, throw an error. If Fiber return types are disabled,
14755 // we already threw above.
14756 switch (returnFiber.tag) {
14757 case ClassComponent:
14758 {
14759 {
14760 var instance = returnFiber.stateNode;
14761 if (instance.render._isMockFunction) {
14762 // We allow auto-mocks to proceed as if they're returning null.
14763 break;
14764 }
14765 }
14766 }
14767 // Intentionally fall through to the next case, which handles both
14768 // functions and classes
14769 // eslint-disable-next-lined no-fallthrough
14770 case FunctionComponent:
14771 {
14772 var Component = returnFiber.type;
14773 (function () {
14774 {
14775 {
14776 throw ReactError(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.'));
14777 }
14778 }
14779 })();
14780 }
14781 }
14782 }
14783
14784 // Remaining cases are all treated as empty.
14785 return deleteRemainingChildren(returnFiber, currentFirstChild);
14786 }
14787
14788 return reconcileChildFibers;
14789}
14790
14791var reconcileChildFibers = ChildReconciler(true);
14792var mountChildFibers = ChildReconciler(false);
14793
14794function cloneChildFibers(current$$1, workInProgress) {
14795 (function () {
14796 if (!(current$$1 === null || workInProgress.child === current$$1.child)) {
14797 {
14798 throw ReactError(Error('Resuming work not yet implemented.'));
14799 }
14800 }
14801 })();
14802
14803 if (workInProgress.child === null) {
14804 return;
14805 }
14806
14807 var currentChild = workInProgress.child;
14808 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
14809 workInProgress.child = newChild;
14810
14811 newChild.return = workInProgress;
14812 while (currentChild.sibling !== null) {
14813 currentChild = currentChild.sibling;
14814 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
14815 newChild.return = workInProgress;
14816 }
14817 newChild.sibling = null;
14818}
14819
14820// Reset a workInProgress child set to prepare it for a second pass.
14821function resetChildFibers(workInProgress, renderExpirationTime) {
14822 var child = workInProgress.child;
14823 while (child !== null) {
14824 resetWorkInProgress(child, renderExpirationTime);
14825 child = child.sibling;
14826 }
14827}
14828
14829var NO_CONTEXT = {};
14830
14831var contextStackCursor$1 = createCursor(NO_CONTEXT);
14832var contextFiberStackCursor = createCursor(NO_CONTEXT);
14833var rootInstanceStackCursor = createCursor(NO_CONTEXT);
14834
14835function requiredContext(c) {
14836 (function () {
14837 if (!(c !== NO_CONTEXT)) {
14838 {
14839 throw ReactError(Error('Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.'));
14840 }
14841 }
14842 })();
14843 return c;
14844}
14845
14846function getRootHostContainer() {
14847 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14848 return rootInstance;
14849}
14850
14851function pushHostContainer(fiber, nextRootInstance) {
14852 // Push current root instance onto the stack;
14853 // This allows us to reset root when portals are popped.
14854 push(rootInstanceStackCursor, nextRootInstance, fiber);
14855 // Track the context and the Fiber that provided it.
14856 // This enables us to pop only Fibers that provide unique contexts.
14857 push(contextFiberStackCursor, fiber, fiber);
14858
14859 // Finally, we need to push the host context to the stack.
14860 // However, we can't just call getRootHostContext() and push it because
14861 // we'd have a different number of entries on the stack depending on
14862 // whether getRootHostContext() throws somewhere in renderer code or not.
14863 // So we push an empty value first. This lets us safely unwind on errors.
14864 push(contextStackCursor$1, NO_CONTEXT, fiber);
14865 var nextRootContext = getRootHostContext(nextRootInstance);
14866 // Now that we know this function doesn't throw, replace it.
14867 pop(contextStackCursor$1, fiber);
14868 push(contextStackCursor$1, nextRootContext, fiber);
14869}
14870
14871function popHostContainer(fiber) {
14872 pop(contextStackCursor$1, fiber);
14873 pop(contextFiberStackCursor, fiber);
14874 pop(rootInstanceStackCursor, fiber);
14875}
14876
14877function getHostContext() {
14878 var context = requiredContext(contextStackCursor$1.current);
14879 return context;
14880}
14881
14882function pushHostContext(fiber) {
14883 var rootInstance = requiredContext(rootInstanceStackCursor.current);
14884 var context = requiredContext(contextStackCursor$1.current);
14885 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
14886
14887 // Don't push this Fiber's context unless it's unique.
14888 if (context === nextContext) {
14889 return;
14890 }
14891
14892 // Track the context and the Fiber that provided it.
14893 // This enables us to pop only Fibers that provide unique contexts.
14894 push(contextFiberStackCursor, fiber, fiber);
14895 push(contextStackCursor$1, nextContext, fiber);
14896}
14897
14898function popHostContext(fiber) {
14899 // Do not pop unless this Fiber provided the current context.
14900 // pushHostContext() only pushes Fibers that provide unique contexts.
14901 if (contextFiberStackCursor.current !== fiber) {
14902 return;
14903 }
14904
14905 pop(contextStackCursor$1, fiber);
14906 pop(contextFiberStackCursor, fiber);
14907}
14908
14909var DefaultSuspenseContext = 0;
14910
14911// The Suspense Context is split into two parts. The lower bits is
14912// inherited deeply down the subtree. The upper bits only affect
14913// this immediate suspense boundary and gets reset each new
14914// boundary or suspense list.
14915var SubtreeSuspenseContextMask = 1;
14916
14917// Subtree Flags:
14918
14919// InvisibleParentSuspenseContext indicates that one of our parent Suspense
14920// boundaries is not currently showing visible main content.
14921// Either because it is already showing a fallback or is not mounted at all.
14922// We can use this to determine if it is desirable to trigger a fallback at
14923// the parent. If not, then we might need to trigger undesirable boundaries
14924// and/or suspend the commit to avoid hiding the parent content.
14925var InvisibleParentSuspenseContext = 1;
14926
14927// Shallow Flags:
14928
14929// ForceSuspenseFallback can be used by SuspenseList to force newly added
14930// items into their fallback state during one of the render passes.
14931var ForceSuspenseFallback = 2;
14932
14933var suspenseStackCursor = createCursor(DefaultSuspenseContext);
14934
14935function hasSuspenseContext(parentContext, flag) {
14936 return (parentContext & flag) !== 0;
14937}
14938
14939function setDefaultShallowSuspenseContext(parentContext) {
14940 return parentContext & SubtreeSuspenseContextMask;
14941}
14942
14943function setShallowSuspenseContext(parentContext, shallowContext) {
14944 return parentContext & SubtreeSuspenseContextMask | shallowContext;
14945}
14946
14947function addSubtreeSuspenseContext(parentContext, subtreeContext) {
14948 return parentContext | subtreeContext;
14949}
14950
14951function pushSuspenseContext(fiber, newContext) {
14952 push(suspenseStackCursor, newContext, fiber);
14953}
14954
14955function popSuspenseContext(fiber) {
14956 pop(suspenseStackCursor, fiber);
14957}
14958
14959// TODO: This is now an empty object. Should we switch this to a boolean?
14960// Alternatively we can make this use an effect tag similar to SuspenseList.
14961
14962
14963function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
14964 // If it was the primary children that just suspended, capture and render the
14965 var nextState = workInProgress.memoizedState;
14966 if (nextState !== null) {
14967 return false;
14968 }
14969 var props = workInProgress.memoizedProps;
14970 // In order to capture, the Suspense component must have a fallback prop.
14971 if (props.fallback === undefined) {
14972 return false;
14973 }
14974 // Regular boundaries always capture.
14975 if (props.unstable_avoidThisFallback !== true) {
14976 return true;
14977 }
14978 // If it's a boundary we should avoid, then we prefer to bubble up to the
14979 // parent boundary if it is currently invisible.
14980 if (hasInvisibleParent) {
14981 return false;
14982 }
14983 // If the parent is not able to handle it, we must handle it.
14984 return true;
14985}
14986
14987function findFirstSuspended(row) {
14988 var node = row;
14989 while (node !== null) {
14990 if (node.tag === SuspenseComponent) {
14991 var state = node.memoizedState;
14992 if (state !== null) {
14993 return node;
14994 }
14995 } else if (node.tag === SuspenseListComponent &&
14996 // revealOrder undefined can't be trusted because it don't
14997 // keep track of whether it suspended or not.
14998 node.memoizedProps.revealOrder !== undefined) {
14999 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
15000 if (didSuspend) {
15001 return node;
15002 }
15003 } else if (node.child !== null) {
15004 node.child.return = node;
15005 node = node.child;
15006 continue;
15007 }
15008 if (node === row) {
15009 return null;
15010 }
15011 while (node.sibling === null) {
15012 if (node.return === null || node.return === row) {
15013 return null;
15014 }
15015 node = node.return;
15016 }
15017 node.sibling.return = node.return;
15018 node = node.sibling;
15019 }
15020 return null;
15021}
15022
15023var NoEffect$1 = /* */0;
15024var UnmountSnapshot = /* */2;
15025var UnmountMutation = /* */4;
15026var MountMutation = /* */8;
15027var UnmountLayout = /* */16;
15028var MountLayout = /* */32;
15029var MountPassive = /* */64;
15030var UnmountPassive = /* */128;
15031
15032var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
15033
15034
15035var didWarnAboutMismatchedHooksForComponent = void 0;
15036{
15037 didWarnAboutMismatchedHooksForComponent = new Set();
15038}
15039
15040// These are set right before calling the component.
15041var renderExpirationTime$1 = NoWork;
15042// The work-in-progress fiber. I've named it differently to distinguish it from
15043// the work-in-progress hook.
15044var currentlyRenderingFiber$1 = null;
15045
15046// Hooks are stored as a linked list on the fiber's memoizedState field. The
15047// current hook list is the list that belongs to the current fiber. The
15048// work-in-progress hook list is a new list that will be added to the
15049// work-in-progress fiber.
15050var currentHook = null;
15051var nextCurrentHook = null;
15052var firstWorkInProgressHook = null;
15053var workInProgressHook = null;
15054var nextWorkInProgressHook = null;
15055
15056var remainingExpirationTime = NoWork;
15057var componentUpdateQueue = null;
15058var sideEffectTag = 0;
15059
15060// Updates scheduled during render will trigger an immediate re-render at the
15061// end of the current pass. We can't store these updates on the normal queue,
15062// because if the work is aborted, they should be discarded. Because this is
15063// a relatively rare case, we also don't want to add an additional field to
15064// either the hook or queue object types. So we store them in a lazily create
15065// map of queue -> render-phase updates, which are discarded once the component
15066// completes without re-rendering.
15067
15068// Whether an update was scheduled during the currently executing render pass.
15069var didScheduleRenderPhaseUpdate = false;
15070// Lazily created map of render-phase updates
15071var renderPhaseUpdates = null;
15072// Counter to prevent infinite loops.
15073var numberOfReRenders = 0;
15074var RE_RENDER_LIMIT = 25;
15075
15076// In DEV, this is the name of the currently executing primitive hook
15077var currentHookNameInDev = null;
15078
15079// In DEV, this list ensures that hooks are called in the same order between renders.
15080// The list stores the order of hooks used during the initial render (mount).
15081// Subsequent renders (updates) reference this list.
15082var hookTypesDev = null;
15083var hookTypesUpdateIndexDev = -1;
15084
15085// In DEV, this tracks whether currently rendering component needs to ignore
15086// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
15087// When true, such Hooks will always be "remounted". Only used during hot reload.
15088var ignorePreviousDependencies = false;
15089
15090function mountHookTypesDev() {
15091 {
15092 var hookName = currentHookNameInDev;
15093
15094 if (hookTypesDev === null) {
15095 hookTypesDev = [hookName];
15096 } else {
15097 hookTypesDev.push(hookName);
15098 }
15099 }
15100}
15101
15102function updateHookTypesDev() {
15103 {
15104 var hookName = currentHookNameInDev;
15105
15106 if (hookTypesDev !== null) {
15107 hookTypesUpdateIndexDev++;
15108 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
15109 warnOnHookMismatchInDev(hookName);
15110 }
15111 }
15112 }
15113}
15114
15115function checkDepsAreArrayDev(deps) {
15116 {
15117 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
15118 // Verify deps, but only on mount to avoid extra checks.
15119 // It's unlikely their type would change as usually you define them inline.
15120 warning$1(false, '%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);
15121 }
15122 }
15123}
15124
15125function warnOnHookMismatchInDev(currentHookName) {
15126 {
15127 var componentName = getComponentName(currentlyRenderingFiber$1.type);
15128 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
15129 didWarnAboutMismatchedHooksForComponent.add(componentName);
15130
15131 if (hookTypesDev !== null) {
15132 var table = '';
15133
15134 var secondColumnStart = 30;
15135
15136 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
15137 var oldHookName = hookTypesDev[i];
15138 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
15139
15140 var row = i + 1 + '. ' + oldHookName;
15141
15142 // Extra space so second column lines up
15143 // lol @ IE not supporting String#repeat
15144 while (row.length < secondColumnStart) {
15145 row += ' ';
15146 }
15147
15148 row += newHookName + '\n';
15149
15150 table += row;
15151 }
15152
15153 warning$1(false, '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);
15154 }
15155 }
15156 }
15157}
15158
15159function throwInvalidHookError() {
15160 (function () {
15161 {
15162 {
15163 throw ReactError(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.'));
15164 }
15165 }
15166 })();
15167}
15168
15169function areHookInputsEqual(nextDeps, prevDeps) {
15170 {
15171 if (ignorePreviousDependencies) {
15172 // Only true when this component is being hot reloaded.
15173 return false;
15174 }
15175 }
15176
15177 if (prevDeps === null) {
15178 {
15179 warning$1(false, '%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);
15180 }
15181 return false;
15182 }
15183
15184 {
15185 // Don't bother comparing lengths in prod because these arrays should be
15186 // passed inline.
15187 if (nextDeps.length !== prevDeps.length) {
15188 warning$1(false, '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(', ') + ']');
15189 }
15190 }
15191 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
15192 if (is(nextDeps[i], prevDeps[i])) {
15193 continue;
15194 }
15195 return false;
15196 }
15197 return true;
15198}
15199
15200function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
15201 renderExpirationTime$1 = nextRenderExpirationTime;
15202 currentlyRenderingFiber$1 = workInProgress;
15203 nextCurrentHook = current !== null ? current.memoizedState : null;
15204
15205 {
15206 hookTypesDev = current !== null ? current._debugHookTypes : null;
15207 hookTypesUpdateIndexDev = -1;
15208 // Used for hot reloading:
15209 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
15210 }
15211
15212 // The following should have already been reset
15213 // currentHook = null;
15214 // workInProgressHook = null;
15215
15216 // remainingExpirationTime = NoWork;
15217 // componentUpdateQueue = null;
15218
15219 // didScheduleRenderPhaseUpdate = false;
15220 // renderPhaseUpdates = null;
15221 // numberOfReRenders = 0;
15222 // sideEffectTag = 0;
15223
15224 // TODO Warn if no hooks are used at all during mount, then some are used during update.
15225 // Currently we will identify the update render as a mount because nextCurrentHook === null.
15226 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
15227
15228 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
15229 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
15230 // so nextCurrentHook would be null during updates and mounts.
15231 {
15232 if (nextCurrentHook !== null) {
15233 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
15234 } else if (hookTypesDev !== null) {
15235 // This dispatcher handles an edge case where a component is updating,
15236 // but no stateful hooks have been used.
15237 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
15238 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
15239 // This dispatcher does that.
15240 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
15241 } else {
15242 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
15243 }
15244 }
15245
15246 var children = Component(props, refOrContext);
15247
15248 if (didScheduleRenderPhaseUpdate) {
15249 do {
15250 didScheduleRenderPhaseUpdate = false;
15251 numberOfReRenders += 1;
15252
15253 // Start over from the beginning of the list
15254 nextCurrentHook = current !== null ? current.memoizedState : null;
15255 nextWorkInProgressHook = firstWorkInProgressHook;
15256
15257 currentHook = null;
15258 workInProgressHook = null;
15259 componentUpdateQueue = null;
15260
15261 {
15262 // Also validate hook order for cascading updates.
15263 hookTypesUpdateIndexDev = -1;
15264 }
15265
15266 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
15267
15268 children = Component(props, refOrContext);
15269 } while (didScheduleRenderPhaseUpdate);
15270
15271 renderPhaseUpdates = null;
15272 numberOfReRenders = 0;
15273 }
15274
15275 // We can assume the previous dispatcher is always this one, since we set it
15276 // at the beginning of the render phase and there's no re-entrancy.
15277 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15278
15279 var renderedWork = currentlyRenderingFiber$1;
15280
15281 renderedWork.memoizedState = firstWorkInProgressHook;
15282 renderedWork.expirationTime = remainingExpirationTime;
15283 renderedWork.updateQueue = componentUpdateQueue;
15284 renderedWork.effectTag |= sideEffectTag;
15285
15286 {
15287 renderedWork._debugHookTypes = hookTypesDev;
15288 }
15289
15290 // This check uses currentHook so that it works the same in DEV and prod bundles.
15291 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
15292 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
15293
15294 renderExpirationTime$1 = NoWork;
15295 currentlyRenderingFiber$1 = null;
15296
15297 currentHook = null;
15298 nextCurrentHook = null;
15299 firstWorkInProgressHook = null;
15300 workInProgressHook = null;
15301 nextWorkInProgressHook = null;
15302
15303 {
15304 currentHookNameInDev = null;
15305 hookTypesDev = null;
15306 hookTypesUpdateIndexDev = -1;
15307 }
15308
15309 remainingExpirationTime = NoWork;
15310 componentUpdateQueue = null;
15311 sideEffectTag = 0;
15312
15313 // These were reset above
15314 // didScheduleRenderPhaseUpdate = false;
15315 // renderPhaseUpdates = null;
15316 // numberOfReRenders = 0;
15317
15318 (function () {
15319 if (!!didRenderTooFewHooks) {
15320 {
15321 throw ReactError(Error('Rendered fewer hooks than expected. This may be caused by an accidental early return statement.'));
15322 }
15323 }
15324 })();
15325
15326 return children;
15327}
15328
15329function bailoutHooks(current, workInProgress, expirationTime) {
15330 workInProgress.updateQueue = current.updateQueue;
15331 workInProgress.effectTag &= ~(Passive | Update);
15332 if (current.expirationTime <= expirationTime) {
15333 current.expirationTime = NoWork;
15334 }
15335}
15336
15337function resetHooks() {
15338 // We can assume the previous dispatcher is always this one, since we set it
15339 // at the beginning of the render phase and there's no re-entrancy.
15340 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
15341
15342 // This is used to reset the state of this module when a component throws.
15343 // It's also called inside mountIndeterminateComponent if we determine the
15344 // component is a module-style component.
15345 renderExpirationTime$1 = NoWork;
15346 currentlyRenderingFiber$1 = null;
15347
15348 currentHook = null;
15349 nextCurrentHook = null;
15350 firstWorkInProgressHook = null;
15351 workInProgressHook = null;
15352 nextWorkInProgressHook = null;
15353
15354 {
15355 hookTypesDev = null;
15356 hookTypesUpdateIndexDev = -1;
15357
15358 currentHookNameInDev = null;
15359 }
15360
15361 remainingExpirationTime = NoWork;
15362 componentUpdateQueue = null;
15363 sideEffectTag = 0;
15364
15365 didScheduleRenderPhaseUpdate = false;
15366 renderPhaseUpdates = null;
15367 numberOfReRenders = 0;
15368}
15369
15370function mountWorkInProgressHook() {
15371 var hook = {
15372 memoizedState: null,
15373
15374 baseState: null,
15375 queue: null,
15376 baseUpdate: null,
15377
15378 next: null
15379 };
15380
15381 if (workInProgressHook === null) {
15382 // This is the first hook in the list
15383 firstWorkInProgressHook = workInProgressHook = hook;
15384 } else {
15385 // Append to the end of the list
15386 workInProgressHook = workInProgressHook.next = hook;
15387 }
15388 return workInProgressHook;
15389}
15390
15391function updateWorkInProgressHook() {
15392 // This function is used both for updates and for re-renders triggered by a
15393 // render phase update. It assumes there is either a current hook we can
15394 // clone, or a work-in-progress hook from a previous render pass that we can
15395 // use as a base. When we reach the end of the base list, we must switch to
15396 // the dispatcher used for mounts.
15397 if (nextWorkInProgressHook !== null) {
15398 // There's already a work-in-progress. Reuse it.
15399 workInProgressHook = nextWorkInProgressHook;
15400 nextWorkInProgressHook = workInProgressHook.next;
15401
15402 currentHook = nextCurrentHook;
15403 nextCurrentHook = currentHook !== null ? currentHook.next : null;
15404 } else {
15405 // Clone from the current hook.
15406 (function () {
15407 if (!(nextCurrentHook !== null)) {
15408 {
15409 throw ReactError(Error('Rendered more hooks than during the previous render.'));
15410 }
15411 }
15412 })();
15413 currentHook = nextCurrentHook;
15414
15415 var newHook = {
15416 memoizedState: currentHook.memoizedState,
15417
15418 baseState: currentHook.baseState,
15419 queue: currentHook.queue,
15420 baseUpdate: currentHook.baseUpdate,
15421
15422 next: null
15423 };
15424
15425 if (workInProgressHook === null) {
15426 // This is the first hook in the list.
15427 workInProgressHook = firstWorkInProgressHook = newHook;
15428 } else {
15429 // Append to the end of the list.
15430 workInProgressHook = workInProgressHook.next = newHook;
15431 }
15432 nextCurrentHook = currentHook.next;
15433 }
15434 return workInProgressHook;
15435}
15436
15437function createFunctionComponentUpdateQueue() {
15438 return {
15439 lastEffect: null
15440 };
15441}
15442
15443function basicStateReducer(state, action) {
15444 return typeof action === 'function' ? action(state) : action;
15445}
15446
15447function mountReducer(reducer, initialArg, init) {
15448 var hook = mountWorkInProgressHook();
15449 var initialState = void 0;
15450 if (init !== undefined) {
15451 initialState = init(initialArg);
15452 } else {
15453 initialState = initialArg;
15454 }
15455 hook.memoizedState = hook.baseState = initialState;
15456 var queue = hook.queue = {
15457 last: null,
15458 dispatch: null,
15459 lastRenderedReducer: reducer,
15460 lastRenderedState: initialState
15461 };
15462 var dispatch = queue.dispatch = dispatchAction.bind(null,
15463 // Flow doesn't know this is non-null, but we do.
15464 currentlyRenderingFiber$1, queue);
15465 return [hook.memoizedState, dispatch];
15466}
15467
15468function updateReducer(reducer, initialArg, init) {
15469 var hook = updateWorkInProgressHook();
15470 var queue = hook.queue;
15471 (function () {
15472 if (!(queue !== null)) {
15473 {
15474 throw ReactError(Error('Should have a queue. This is likely a bug in React. Please file an issue.'));
15475 }
15476 }
15477 })();
15478
15479 queue.lastRenderedReducer = reducer;
15480
15481 if (numberOfReRenders > 0) {
15482 // This is a re-render. Apply the new render phase updates to the previous
15483 var _dispatch = queue.dispatch;
15484 if (renderPhaseUpdates !== null) {
15485 // Render phase updates are stored in a map of queue -> linked list
15486 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
15487 if (firstRenderPhaseUpdate !== undefined) {
15488 renderPhaseUpdates.delete(queue);
15489 var newState = hook.memoizedState;
15490 var update = firstRenderPhaseUpdate;
15491 do {
15492 // Process this render phase update. We don't have to check the
15493 // priority because it will always be the same as the current
15494 // render's.
15495 var _action = update.action;
15496 newState = reducer(newState, _action);
15497 update = update.next;
15498 } while (update !== null);
15499
15500 // Mark that the fiber performed work, but only if the new state is
15501 // different from the current state.
15502 if (!is(newState, hook.memoizedState)) {
15503 markWorkInProgressReceivedUpdate();
15504 }
15505
15506 hook.memoizedState = newState;
15507 // Don't persist the state accumulated from the render phase updates to
15508 // the base state unless the queue is empty.
15509 // TODO: Not sure if this is the desired semantics, but it's what we
15510 // do for gDSFP. I can't remember why.
15511 if (hook.baseUpdate === queue.last) {
15512 hook.baseState = newState;
15513 }
15514
15515 queue.lastRenderedState = newState;
15516
15517 return [newState, _dispatch];
15518 }
15519 }
15520 return [hook.memoizedState, _dispatch];
15521 }
15522
15523 // The last update in the entire queue
15524 var last = queue.last;
15525 // The last update that is part of the base state.
15526 var baseUpdate = hook.baseUpdate;
15527 var baseState = hook.baseState;
15528
15529 // Find the first unprocessed update.
15530 var first = void 0;
15531 if (baseUpdate !== null) {
15532 if (last !== null) {
15533 // For the first update, the queue is a circular linked list where
15534 // `queue.last.next = queue.first`. Once the first update commits, and
15535 // the `baseUpdate` is no longer empty, we can unravel the list.
15536 last.next = null;
15537 }
15538 first = baseUpdate.next;
15539 } else {
15540 first = last !== null ? last.next : null;
15541 }
15542 if (first !== null) {
15543 var _newState = baseState;
15544 var newBaseState = null;
15545 var newBaseUpdate = null;
15546 var prevUpdate = baseUpdate;
15547 var _update = first;
15548 var didSkip = false;
15549 do {
15550 var updateExpirationTime = _update.expirationTime;
15551 if (updateExpirationTime < renderExpirationTime$1) {
15552 // Priority is insufficient. Skip this update. If this is the first
15553 // skipped update, the previous update/state is the new base
15554 // update/state.
15555 if (!didSkip) {
15556 didSkip = true;
15557 newBaseUpdate = prevUpdate;
15558 newBaseState = _newState;
15559 }
15560 // Update the remaining priority in the queue.
15561 if (updateExpirationTime > remainingExpirationTime) {
15562 remainingExpirationTime = updateExpirationTime;
15563 }
15564 } else {
15565 // This update does have sufficient priority.
15566
15567 // Mark the event time of this update as relevant to this render pass.
15568 // TODO: This should ideally use the true event time of this update rather than
15569 // its priority which is a derived and not reverseable value.
15570 // TODO: We should skip this update if it was already committed but currently
15571 // we have no way of detecting the difference between a committed and suspended
15572 // update here.
15573 markRenderEventTimeAndConfig(updateExpirationTime, _update.suspenseConfig);
15574
15575 // Process this update.
15576 if (_update.eagerReducer === reducer) {
15577 // If this update was processed eagerly, and its reducer matches the
15578 // current reducer, we can use the eagerly computed state.
15579 _newState = _update.eagerState;
15580 } else {
15581 var _action2 = _update.action;
15582 _newState = reducer(_newState, _action2);
15583 }
15584 }
15585 prevUpdate = _update;
15586 _update = _update.next;
15587 } while (_update !== null && _update !== first);
15588
15589 if (!didSkip) {
15590 newBaseUpdate = prevUpdate;
15591 newBaseState = _newState;
15592 }
15593
15594 // Mark that the fiber performed work, but only if the new state is
15595 // different from the current state.
15596 if (!is(_newState, hook.memoizedState)) {
15597 markWorkInProgressReceivedUpdate();
15598 }
15599
15600 hook.memoizedState = _newState;
15601 hook.baseUpdate = newBaseUpdate;
15602 hook.baseState = newBaseState;
15603
15604 queue.lastRenderedState = _newState;
15605 }
15606
15607 var dispatch = queue.dispatch;
15608 return [hook.memoizedState, dispatch];
15609}
15610
15611function mountState(initialState) {
15612 var hook = mountWorkInProgressHook();
15613 if (typeof initialState === 'function') {
15614 initialState = initialState();
15615 }
15616 hook.memoizedState = hook.baseState = initialState;
15617 var queue = hook.queue = {
15618 last: null,
15619 dispatch: null,
15620 lastRenderedReducer: basicStateReducer,
15621 lastRenderedState: initialState
15622 };
15623 var dispatch = queue.dispatch = dispatchAction.bind(null,
15624 // Flow doesn't know this is non-null, but we do.
15625 currentlyRenderingFiber$1, queue);
15626 return [hook.memoizedState, dispatch];
15627}
15628
15629function updateState(initialState) {
15630 return updateReducer(basicStateReducer, initialState);
15631}
15632
15633function pushEffect(tag, create, destroy, deps) {
15634 var effect = {
15635 tag: tag,
15636 create: create,
15637 destroy: destroy,
15638 deps: deps,
15639 // Circular
15640 next: null
15641 };
15642 if (componentUpdateQueue === null) {
15643 componentUpdateQueue = createFunctionComponentUpdateQueue();
15644 componentUpdateQueue.lastEffect = effect.next = effect;
15645 } else {
15646 var _lastEffect = componentUpdateQueue.lastEffect;
15647 if (_lastEffect === null) {
15648 componentUpdateQueue.lastEffect = effect.next = effect;
15649 } else {
15650 var firstEffect = _lastEffect.next;
15651 _lastEffect.next = effect;
15652 effect.next = firstEffect;
15653 componentUpdateQueue.lastEffect = effect;
15654 }
15655 }
15656 return effect;
15657}
15658
15659function mountRef(initialValue) {
15660 var hook = mountWorkInProgressHook();
15661 var ref = { current: initialValue };
15662 {
15663 Object.seal(ref);
15664 }
15665 hook.memoizedState = ref;
15666 return ref;
15667}
15668
15669function updateRef(initialValue) {
15670 var hook = updateWorkInProgressHook();
15671 return hook.memoizedState;
15672}
15673
15674function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15675 var hook = mountWorkInProgressHook();
15676 var nextDeps = deps === undefined ? null : deps;
15677 sideEffectTag |= fiberEffectTag;
15678 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
15679}
15680
15681function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
15682 var hook = updateWorkInProgressHook();
15683 var nextDeps = deps === undefined ? null : deps;
15684 var destroy = undefined;
15685
15686 if (currentHook !== null) {
15687 var prevEffect = currentHook.memoizedState;
15688 destroy = prevEffect.destroy;
15689 if (nextDeps !== null) {
15690 var prevDeps = prevEffect.deps;
15691 if (areHookInputsEqual(nextDeps, prevDeps)) {
15692 pushEffect(NoEffect$1, create, destroy, nextDeps);
15693 return;
15694 }
15695 }
15696 }
15697
15698 sideEffectTag |= fiberEffectTag;
15699 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
15700}
15701
15702function mountEffect(create, deps) {
15703 {
15704 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15705 if ('undefined' !== typeof jest) {
15706 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15707 }
15708 }
15709 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
15710}
15711
15712function updateEffect(create, deps) {
15713 {
15714 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15715 if ('undefined' !== typeof jest) {
15716 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
15717 }
15718 }
15719 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
15720}
15721
15722function mountLayoutEffect(create, deps) {
15723 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
15724}
15725
15726function updateLayoutEffect(create, deps) {
15727 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
15728}
15729
15730function imperativeHandleEffect(create, ref) {
15731 if (typeof ref === 'function') {
15732 var refCallback = ref;
15733 var _inst = create();
15734 refCallback(_inst);
15735 return function () {
15736 refCallback(null);
15737 };
15738 } else if (ref !== null && ref !== undefined) {
15739 var refObject = ref;
15740 {
15741 !refObject.hasOwnProperty('current') ? warning$1(false, '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(', ') + '}') : void 0;
15742 }
15743 var _inst2 = create();
15744 refObject.current = _inst2;
15745 return function () {
15746 refObject.current = null;
15747 };
15748 }
15749}
15750
15751function mountImperativeHandle(ref, create, deps) {
15752 {
15753 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
15754 }
15755
15756 // TODO: If deps are provided, should we skip comparing the ref itself?
15757 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15758
15759 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15760}
15761
15762function updateImperativeHandle(ref, create, deps) {
15763 {
15764 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
15765 }
15766
15767 // TODO: If deps are provided, should we skip comparing the ref itself?
15768 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
15769
15770 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
15771}
15772
15773function mountDebugValue(value, formatterFn) {
15774 // This hook is normally a no-op.
15775 // The react-debug-hooks package injects its own implementation
15776 // so that e.g. DevTools can display custom hook values.
15777}
15778
15779var updateDebugValue = mountDebugValue;
15780
15781function mountCallback(callback, deps) {
15782 var hook = mountWorkInProgressHook();
15783 var nextDeps = deps === undefined ? null : deps;
15784 hook.memoizedState = [callback, nextDeps];
15785 return callback;
15786}
15787
15788function updateCallback(callback, deps) {
15789 var hook = updateWorkInProgressHook();
15790 var nextDeps = deps === undefined ? null : deps;
15791 var prevState = hook.memoizedState;
15792 if (prevState !== null) {
15793 if (nextDeps !== null) {
15794 var prevDeps = prevState[1];
15795 if (areHookInputsEqual(nextDeps, prevDeps)) {
15796 return prevState[0];
15797 }
15798 }
15799 }
15800 hook.memoizedState = [callback, nextDeps];
15801 return callback;
15802}
15803
15804function mountMemo(nextCreate, deps) {
15805 var hook = mountWorkInProgressHook();
15806 var nextDeps = deps === undefined ? null : deps;
15807 var nextValue = nextCreate();
15808 hook.memoizedState = [nextValue, nextDeps];
15809 return nextValue;
15810}
15811
15812function updateMemo(nextCreate, deps) {
15813 var hook = updateWorkInProgressHook();
15814 var nextDeps = deps === undefined ? null : deps;
15815 var prevState = hook.memoizedState;
15816 if (prevState !== null) {
15817 // Assume these are defined. If they're not, areHookInputsEqual will warn.
15818 if (nextDeps !== null) {
15819 var prevDeps = prevState[1];
15820 if (areHookInputsEqual(nextDeps, prevDeps)) {
15821 return prevState[0];
15822 }
15823 }
15824 }
15825 var nextValue = nextCreate();
15826 hook.memoizedState = [nextValue, nextDeps];
15827 return nextValue;
15828}
15829
15830function dispatchAction(fiber, queue, action) {
15831 (function () {
15832 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
15833 {
15834 throw ReactError(Error('Too many re-renders. React limits the number of renders to prevent an infinite loop.'));
15835 }
15836 }
15837 })();
15838
15839 {
15840 !(arguments.length <= 3) ? warning$1(false, "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().') : void 0;
15841 }
15842
15843 var alternate = fiber.alternate;
15844 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
15845 // This is a render phase update. Stash it in a lazily-created map of
15846 // queue -> linked list of updates. After this render pass, we'll restart
15847 // and apply the stashed updates on top of the work-in-progress hook.
15848 didScheduleRenderPhaseUpdate = true;
15849 var update = {
15850 expirationTime: renderExpirationTime$1,
15851 suspenseConfig: null,
15852 action: action,
15853 eagerReducer: null,
15854 eagerState: null,
15855 next: null
15856 };
15857 {
15858 update.priority = getCurrentPriorityLevel();
15859 }
15860 if (renderPhaseUpdates === null) {
15861 renderPhaseUpdates = new Map();
15862 }
15863 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
15864 if (firstRenderPhaseUpdate === undefined) {
15865 renderPhaseUpdates.set(queue, update);
15866 } else {
15867 // Append the update to the end of the list.
15868 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
15869 while (lastRenderPhaseUpdate.next !== null) {
15870 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
15871 }
15872 lastRenderPhaseUpdate.next = update;
15873 }
15874 } else {
15875 if (revertPassiveEffectsChange) {
15876 flushPassiveEffects();
15877 }
15878
15879 var currentTime = requestCurrentTime();
15880 var _suspenseConfig = requestCurrentSuspenseConfig();
15881 var _expirationTime = computeExpirationForFiber(currentTime, fiber, _suspenseConfig);
15882
15883 var _update2 = {
15884 expirationTime: _expirationTime,
15885 suspenseConfig: _suspenseConfig,
15886 action: action,
15887 eagerReducer: null,
15888 eagerState: null,
15889 next: null
15890 };
15891
15892 {
15893 _update2.priority = getCurrentPriorityLevel();
15894 }
15895
15896 // Append the update to the end of the list.
15897 var _last = queue.last;
15898 if (_last === null) {
15899 // This is the first update. Create a circular list.
15900 _update2.next = _update2;
15901 } else {
15902 var first = _last.next;
15903 if (first !== null) {
15904 // Still circular.
15905 _update2.next = first;
15906 }
15907 _last.next = _update2;
15908 }
15909 queue.last = _update2;
15910
15911 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
15912 // The queue is currently empty, which means we can eagerly compute the
15913 // next state before entering the render phase. If the new state is the
15914 // same as the current state, we may be able to bail out entirely.
15915 var _lastRenderedReducer = queue.lastRenderedReducer;
15916 if (_lastRenderedReducer !== null) {
15917 var prevDispatcher = void 0;
15918 {
15919 prevDispatcher = ReactCurrentDispatcher$1.current;
15920 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
15921 }
15922 try {
15923 var currentState = queue.lastRenderedState;
15924 var _eagerState = _lastRenderedReducer(currentState, action);
15925 // Stash the eagerly computed state, and the reducer used to compute
15926 // it, on the update object. If the reducer hasn't changed by the
15927 // time we enter the render phase, then the eager state can be used
15928 // without calling the reducer again.
15929 _update2.eagerReducer = _lastRenderedReducer;
15930 _update2.eagerState = _eagerState;
15931 if (is(_eagerState, currentState)) {
15932 // Fast path. We can bail out without scheduling React to re-render.
15933 // It's still possible that we'll need to rebase this update later,
15934 // if the component re-renders for a different reason and by that
15935 // time the reducer has changed.
15936 return;
15937 }
15938 } catch (error) {
15939 // Suppress the error. It will throw again in the render phase.
15940 } finally {
15941 {
15942 ReactCurrentDispatcher$1.current = prevDispatcher;
15943 }
15944 }
15945 }
15946 }
15947 {
15948 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15949 if ('undefined' !== typeof jest) {
15950 warnIfNotScopedWithMatchingAct(fiber);
15951 warnIfNotCurrentlyActingUpdatesInDev(fiber);
15952 }
15953 }
15954 scheduleWork(fiber, _expirationTime);
15955 }
15956}
15957
15958var ContextOnlyDispatcher = {
15959 readContext: readContext,
15960
15961 useCallback: throwInvalidHookError,
15962 useContext: throwInvalidHookError,
15963 useEffect: throwInvalidHookError,
15964 useImperativeHandle: throwInvalidHookError,
15965 useLayoutEffect: throwInvalidHookError,
15966 useMemo: throwInvalidHookError,
15967 useReducer: throwInvalidHookError,
15968 useRef: throwInvalidHookError,
15969 useState: throwInvalidHookError,
15970 useDebugValue: throwInvalidHookError,
15971 useResponder: throwInvalidHookError
15972};
15973
15974var HooksDispatcherOnMountInDEV = null;
15975var HooksDispatcherOnMountWithHookTypesInDEV = null;
15976var HooksDispatcherOnUpdateInDEV = null;
15977var InvalidNestedHooksDispatcherOnMountInDEV = null;
15978var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
15979
15980{
15981 var warnInvalidContextAccess = function () {
15982 warning$1(false, '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().');
15983 };
15984
15985 var warnInvalidHookAccess = function () {
15986 warning$1(false, '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');
15987 };
15988
15989 HooksDispatcherOnMountInDEV = {
15990 readContext: function (context, observedBits) {
15991 return readContext(context, observedBits);
15992 },
15993 useCallback: function (callback, deps) {
15994 currentHookNameInDev = 'useCallback';
15995 mountHookTypesDev();
15996 checkDepsAreArrayDev(deps);
15997 return mountCallback(callback, deps);
15998 },
15999 useContext: function (context, observedBits) {
16000 currentHookNameInDev = 'useContext';
16001 mountHookTypesDev();
16002 return readContext(context, observedBits);
16003 },
16004 useEffect: function (create, deps) {
16005 currentHookNameInDev = 'useEffect';
16006 mountHookTypesDev();
16007 checkDepsAreArrayDev(deps);
16008 return mountEffect(create, deps);
16009 },
16010 useImperativeHandle: function (ref, create, deps) {
16011 currentHookNameInDev = 'useImperativeHandle';
16012 mountHookTypesDev();
16013 checkDepsAreArrayDev(deps);
16014 return mountImperativeHandle(ref, create, deps);
16015 },
16016 useLayoutEffect: function (create, deps) {
16017 currentHookNameInDev = 'useLayoutEffect';
16018 mountHookTypesDev();
16019 checkDepsAreArrayDev(deps);
16020 return mountLayoutEffect(create, deps);
16021 },
16022 useMemo: function (create, deps) {
16023 currentHookNameInDev = 'useMemo';
16024 mountHookTypesDev();
16025 checkDepsAreArrayDev(deps);
16026 var prevDispatcher = ReactCurrentDispatcher$1.current;
16027 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16028 try {
16029 return mountMemo(create, deps);
16030 } finally {
16031 ReactCurrentDispatcher$1.current = prevDispatcher;
16032 }
16033 },
16034 useReducer: function (reducer, initialArg, init) {
16035 currentHookNameInDev = 'useReducer';
16036 mountHookTypesDev();
16037 var prevDispatcher = ReactCurrentDispatcher$1.current;
16038 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16039 try {
16040 return mountReducer(reducer, initialArg, init);
16041 } finally {
16042 ReactCurrentDispatcher$1.current = prevDispatcher;
16043 }
16044 },
16045 useRef: function (initialValue) {
16046 currentHookNameInDev = 'useRef';
16047 mountHookTypesDev();
16048 return mountRef(initialValue);
16049 },
16050 useState: function (initialState) {
16051 currentHookNameInDev = 'useState';
16052 mountHookTypesDev();
16053 var prevDispatcher = ReactCurrentDispatcher$1.current;
16054 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16055 try {
16056 return mountState(initialState);
16057 } finally {
16058 ReactCurrentDispatcher$1.current = prevDispatcher;
16059 }
16060 },
16061 useDebugValue: function (value, formatterFn) {
16062 currentHookNameInDev = 'useDebugValue';
16063 mountHookTypesDev();
16064 return mountDebugValue(value, formatterFn);
16065 },
16066 useResponder: function (responder, props) {
16067 currentHookNameInDev = 'useResponder';
16068 mountHookTypesDev();
16069 return createResponderListener(responder, props);
16070 }
16071 };
16072
16073 HooksDispatcherOnMountWithHookTypesInDEV = {
16074 readContext: function (context, observedBits) {
16075 return readContext(context, observedBits);
16076 },
16077 useCallback: function (callback, deps) {
16078 currentHookNameInDev = 'useCallback';
16079 updateHookTypesDev();
16080 return mountCallback(callback, deps);
16081 },
16082 useContext: function (context, observedBits) {
16083 currentHookNameInDev = 'useContext';
16084 updateHookTypesDev();
16085 return readContext(context, observedBits);
16086 },
16087 useEffect: function (create, deps) {
16088 currentHookNameInDev = 'useEffect';
16089 updateHookTypesDev();
16090 return mountEffect(create, deps);
16091 },
16092 useImperativeHandle: function (ref, create, deps) {
16093 currentHookNameInDev = 'useImperativeHandle';
16094 updateHookTypesDev();
16095 return mountImperativeHandle(ref, create, deps);
16096 },
16097 useLayoutEffect: function (create, deps) {
16098 currentHookNameInDev = 'useLayoutEffect';
16099 updateHookTypesDev();
16100 return mountLayoutEffect(create, deps);
16101 },
16102 useMemo: function (create, deps) {
16103 currentHookNameInDev = 'useMemo';
16104 updateHookTypesDev();
16105 var prevDispatcher = ReactCurrentDispatcher$1.current;
16106 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16107 try {
16108 return mountMemo(create, deps);
16109 } finally {
16110 ReactCurrentDispatcher$1.current = prevDispatcher;
16111 }
16112 },
16113 useReducer: function (reducer, initialArg, init) {
16114 currentHookNameInDev = 'useReducer';
16115 updateHookTypesDev();
16116 var prevDispatcher = ReactCurrentDispatcher$1.current;
16117 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16118 try {
16119 return mountReducer(reducer, initialArg, init);
16120 } finally {
16121 ReactCurrentDispatcher$1.current = prevDispatcher;
16122 }
16123 },
16124 useRef: function (initialValue) {
16125 currentHookNameInDev = 'useRef';
16126 updateHookTypesDev();
16127 return mountRef(initialValue);
16128 },
16129 useState: function (initialState) {
16130 currentHookNameInDev = 'useState';
16131 updateHookTypesDev();
16132 var prevDispatcher = ReactCurrentDispatcher$1.current;
16133 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16134 try {
16135 return mountState(initialState);
16136 } finally {
16137 ReactCurrentDispatcher$1.current = prevDispatcher;
16138 }
16139 },
16140 useDebugValue: function (value, formatterFn) {
16141 currentHookNameInDev = 'useDebugValue';
16142 updateHookTypesDev();
16143 return mountDebugValue(value, formatterFn);
16144 },
16145 useResponder: function (responder, props) {
16146 currentHookNameInDev = 'useResponder';
16147 updateHookTypesDev();
16148 return createResponderListener(responder, props);
16149 }
16150 };
16151
16152 HooksDispatcherOnUpdateInDEV = {
16153 readContext: function (context, observedBits) {
16154 return readContext(context, observedBits);
16155 },
16156 useCallback: function (callback, deps) {
16157 currentHookNameInDev = 'useCallback';
16158 updateHookTypesDev();
16159 return updateCallback(callback, deps);
16160 },
16161 useContext: function (context, observedBits) {
16162 currentHookNameInDev = 'useContext';
16163 updateHookTypesDev();
16164 return readContext(context, observedBits);
16165 },
16166 useEffect: function (create, deps) {
16167 currentHookNameInDev = 'useEffect';
16168 updateHookTypesDev();
16169 return updateEffect(create, deps);
16170 },
16171 useImperativeHandle: function (ref, create, deps) {
16172 currentHookNameInDev = 'useImperativeHandle';
16173 updateHookTypesDev();
16174 return updateImperativeHandle(ref, create, deps);
16175 },
16176 useLayoutEffect: function (create, deps) {
16177 currentHookNameInDev = 'useLayoutEffect';
16178 updateHookTypesDev();
16179 return updateLayoutEffect(create, deps);
16180 },
16181 useMemo: function (create, deps) {
16182 currentHookNameInDev = 'useMemo';
16183 updateHookTypesDev();
16184 var prevDispatcher = ReactCurrentDispatcher$1.current;
16185 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16186 try {
16187 return updateMemo(create, deps);
16188 } finally {
16189 ReactCurrentDispatcher$1.current = prevDispatcher;
16190 }
16191 },
16192 useReducer: function (reducer, initialArg, init) {
16193 currentHookNameInDev = 'useReducer';
16194 updateHookTypesDev();
16195 var prevDispatcher = ReactCurrentDispatcher$1.current;
16196 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16197 try {
16198 return updateReducer(reducer, initialArg, init);
16199 } finally {
16200 ReactCurrentDispatcher$1.current = prevDispatcher;
16201 }
16202 },
16203 useRef: function (initialValue) {
16204 currentHookNameInDev = 'useRef';
16205 updateHookTypesDev();
16206 return updateRef(initialValue);
16207 },
16208 useState: function (initialState) {
16209 currentHookNameInDev = 'useState';
16210 updateHookTypesDev();
16211 var prevDispatcher = ReactCurrentDispatcher$1.current;
16212 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16213 try {
16214 return updateState(initialState);
16215 } finally {
16216 ReactCurrentDispatcher$1.current = prevDispatcher;
16217 }
16218 },
16219 useDebugValue: function (value, formatterFn) {
16220 currentHookNameInDev = 'useDebugValue';
16221 updateHookTypesDev();
16222 return updateDebugValue(value, formatterFn);
16223 },
16224 useResponder: function (responder, props) {
16225 currentHookNameInDev = 'useResponder';
16226 updateHookTypesDev();
16227 return createResponderListener(responder, props);
16228 }
16229 };
16230
16231 InvalidNestedHooksDispatcherOnMountInDEV = {
16232 readContext: function (context, observedBits) {
16233 warnInvalidContextAccess();
16234 return readContext(context, observedBits);
16235 },
16236 useCallback: function (callback, deps) {
16237 currentHookNameInDev = 'useCallback';
16238 warnInvalidHookAccess();
16239 mountHookTypesDev();
16240 return mountCallback(callback, deps);
16241 },
16242 useContext: function (context, observedBits) {
16243 currentHookNameInDev = 'useContext';
16244 warnInvalidHookAccess();
16245 mountHookTypesDev();
16246 return readContext(context, observedBits);
16247 },
16248 useEffect: function (create, deps) {
16249 currentHookNameInDev = 'useEffect';
16250 warnInvalidHookAccess();
16251 mountHookTypesDev();
16252 return mountEffect(create, deps);
16253 },
16254 useImperativeHandle: function (ref, create, deps) {
16255 currentHookNameInDev = 'useImperativeHandle';
16256 warnInvalidHookAccess();
16257 mountHookTypesDev();
16258 return mountImperativeHandle(ref, create, deps);
16259 },
16260 useLayoutEffect: function (create, deps) {
16261 currentHookNameInDev = 'useLayoutEffect';
16262 warnInvalidHookAccess();
16263 mountHookTypesDev();
16264 return mountLayoutEffect(create, deps);
16265 },
16266 useMemo: function (create, deps) {
16267 currentHookNameInDev = 'useMemo';
16268 warnInvalidHookAccess();
16269 mountHookTypesDev();
16270 var prevDispatcher = ReactCurrentDispatcher$1.current;
16271 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16272 try {
16273 return mountMemo(create, deps);
16274 } finally {
16275 ReactCurrentDispatcher$1.current = prevDispatcher;
16276 }
16277 },
16278 useReducer: function (reducer, initialArg, init) {
16279 currentHookNameInDev = 'useReducer';
16280 warnInvalidHookAccess();
16281 mountHookTypesDev();
16282 var prevDispatcher = ReactCurrentDispatcher$1.current;
16283 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16284 try {
16285 return mountReducer(reducer, initialArg, init);
16286 } finally {
16287 ReactCurrentDispatcher$1.current = prevDispatcher;
16288 }
16289 },
16290 useRef: function (initialValue) {
16291 currentHookNameInDev = 'useRef';
16292 warnInvalidHookAccess();
16293 mountHookTypesDev();
16294 return mountRef(initialValue);
16295 },
16296 useState: function (initialState) {
16297 currentHookNameInDev = 'useState';
16298 warnInvalidHookAccess();
16299 mountHookTypesDev();
16300 var prevDispatcher = ReactCurrentDispatcher$1.current;
16301 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
16302 try {
16303 return mountState(initialState);
16304 } finally {
16305 ReactCurrentDispatcher$1.current = prevDispatcher;
16306 }
16307 },
16308 useDebugValue: function (value, formatterFn) {
16309 currentHookNameInDev = 'useDebugValue';
16310 warnInvalidHookAccess();
16311 mountHookTypesDev();
16312 return mountDebugValue(value, formatterFn);
16313 },
16314 useResponder: function (responder, props) {
16315 currentHookNameInDev = 'useResponder';
16316 warnInvalidHookAccess();
16317 mountHookTypesDev();
16318 return createResponderListener(responder, props);
16319 }
16320 };
16321
16322 InvalidNestedHooksDispatcherOnUpdateInDEV = {
16323 readContext: function (context, observedBits) {
16324 warnInvalidContextAccess();
16325 return readContext(context, observedBits);
16326 },
16327 useCallback: function (callback, deps) {
16328 currentHookNameInDev = 'useCallback';
16329 warnInvalidHookAccess();
16330 updateHookTypesDev();
16331 return updateCallback(callback, deps);
16332 },
16333 useContext: function (context, observedBits) {
16334 currentHookNameInDev = 'useContext';
16335 warnInvalidHookAccess();
16336 updateHookTypesDev();
16337 return readContext(context, observedBits);
16338 },
16339 useEffect: function (create, deps) {
16340 currentHookNameInDev = 'useEffect';
16341 warnInvalidHookAccess();
16342 updateHookTypesDev();
16343 return updateEffect(create, deps);
16344 },
16345 useImperativeHandle: function (ref, create, deps) {
16346 currentHookNameInDev = 'useImperativeHandle';
16347 warnInvalidHookAccess();
16348 updateHookTypesDev();
16349 return updateImperativeHandle(ref, create, deps);
16350 },
16351 useLayoutEffect: function (create, deps) {
16352 currentHookNameInDev = 'useLayoutEffect';
16353 warnInvalidHookAccess();
16354 updateHookTypesDev();
16355 return updateLayoutEffect(create, deps);
16356 },
16357 useMemo: function (create, deps) {
16358 currentHookNameInDev = 'useMemo';
16359 warnInvalidHookAccess();
16360 updateHookTypesDev();
16361 var prevDispatcher = ReactCurrentDispatcher$1.current;
16362 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16363 try {
16364 return updateMemo(create, deps);
16365 } finally {
16366 ReactCurrentDispatcher$1.current = prevDispatcher;
16367 }
16368 },
16369 useReducer: function (reducer, initialArg, init) {
16370 currentHookNameInDev = 'useReducer';
16371 warnInvalidHookAccess();
16372 updateHookTypesDev();
16373 var prevDispatcher = ReactCurrentDispatcher$1.current;
16374 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16375 try {
16376 return updateReducer(reducer, initialArg, init);
16377 } finally {
16378 ReactCurrentDispatcher$1.current = prevDispatcher;
16379 }
16380 },
16381 useRef: function (initialValue) {
16382 currentHookNameInDev = 'useRef';
16383 warnInvalidHookAccess();
16384 updateHookTypesDev();
16385 return updateRef(initialValue);
16386 },
16387 useState: function (initialState) {
16388 currentHookNameInDev = 'useState';
16389 warnInvalidHookAccess();
16390 updateHookTypesDev();
16391 var prevDispatcher = ReactCurrentDispatcher$1.current;
16392 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
16393 try {
16394 return updateState(initialState);
16395 } finally {
16396 ReactCurrentDispatcher$1.current = prevDispatcher;
16397 }
16398 },
16399 useDebugValue: function (value, formatterFn) {
16400 currentHookNameInDev = 'useDebugValue';
16401 warnInvalidHookAccess();
16402 updateHookTypesDev();
16403 return updateDebugValue(value, formatterFn);
16404 },
16405 useResponder: function (responder, props) {
16406 currentHookNameInDev = 'useResponder';
16407 warnInvalidHookAccess();
16408 updateHookTypesDev();
16409 return createResponderListener(responder, props);
16410 }
16411 };
16412}
16413
16414// Intentionally not named imports because Rollup would use dynamic dispatch for
16415// CommonJS interop named imports.
16416var now$1 = unstable_now;
16417
16418
16419var commitTime = 0;
16420var profilerStartTime = -1;
16421
16422function getCommitTime() {
16423 return commitTime;
16424}
16425
16426function recordCommitTime() {
16427 if (!enableProfilerTimer) {
16428 return;
16429 }
16430 commitTime = now$1();
16431}
16432
16433function startProfilerTimer(fiber) {
16434 if (!enableProfilerTimer) {
16435 return;
16436 }
16437
16438 profilerStartTime = now$1();
16439
16440 if (fiber.actualStartTime < 0) {
16441 fiber.actualStartTime = now$1();
16442 }
16443}
16444
16445function stopProfilerTimerIfRunning(fiber) {
16446 if (!enableProfilerTimer) {
16447 return;
16448 }
16449 profilerStartTime = -1;
16450}
16451
16452function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
16453 if (!enableProfilerTimer) {
16454 return;
16455 }
16456
16457 if (profilerStartTime >= 0) {
16458 var elapsedTime = now$1() - profilerStartTime;
16459 fiber.actualDuration += elapsedTime;
16460 if (overrideBaseTime) {
16461 fiber.selfBaseDuration = elapsedTime;
16462 }
16463 profilerStartTime = -1;
16464 }
16465}
16466
16467// The deepest Fiber on the stack involved in a hydration context.
16468// This may have been an insertion or a hydration.
16469var hydrationParentFiber = null;
16470var nextHydratableInstance = null;
16471var isHydrating = false;
16472
16473function enterHydrationState(fiber) {
16474 if (!supportsHydration) {
16475 return false;
16476 }
16477
16478 var parentInstance = fiber.stateNode.containerInfo;
16479 nextHydratableInstance = getFirstHydratableChild(parentInstance);
16480 hydrationParentFiber = fiber;
16481 isHydrating = true;
16482 return true;
16483}
16484
16485function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
16486 if (!supportsHydration) {
16487 return false;
16488 }
16489
16490 var suspenseInstance = fiber.stateNode;
16491 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
16492 popToNextHostParent(fiber);
16493 isHydrating = true;
16494 return true;
16495}
16496
16497function deleteHydratableInstance(returnFiber, instance) {
16498 {
16499 switch (returnFiber.tag) {
16500 case HostRoot:
16501 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
16502 break;
16503 case HostComponent:
16504 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
16505 break;
16506 }
16507 }
16508
16509 var childToDelete = createFiberFromHostInstanceForDeletion();
16510 childToDelete.stateNode = instance;
16511 childToDelete.return = returnFiber;
16512 childToDelete.effectTag = Deletion;
16513
16514 // This might seem like it belongs on progressedFirstDeletion. However,
16515 // these children are not part of the reconciliation list of children.
16516 // Even if we abort and rereconcile the children, that will try to hydrate
16517 // again and the nodes are still in the host tree so these will be
16518 // recreated.
16519 if (returnFiber.lastEffect !== null) {
16520 returnFiber.lastEffect.nextEffect = childToDelete;
16521 returnFiber.lastEffect = childToDelete;
16522 } else {
16523 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
16524 }
16525}
16526
16527function insertNonHydratedInstance(returnFiber, fiber) {
16528 fiber.effectTag |= Placement;
16529 {
16530 switch (returnFiber.tag) {
16531 case HostRoot:
16532 {
16533 var parentContainer = returnFiber.stateNode.containerInfo;
16534 switch (fiber.tag) {
16535 case HostComponent:
16536 var type = fiber.type;
16537 var props = fiber.pendingProps;
16538 didNotFindHydratableContainerInstance(parentContainer, type, props);
16539 break;
16540 case HostText:
16541 var text = fiber.pendingProps;
16542 didNotFindHydratableContainerTextInstance(parentContainer, text);
16543 break;
16544 case SuspenseComponent:
16545
16546 break;
16547 }
16548 break;
16549 }
16550 case HostComponent:
16551 {
16552 var parentType = returnFiber.type;
16553 var parentProps = returnFiber.memoizedProps;
16554 var parentInstance = returnFiber.stateNode;
16555 switch (fiber.tag) {
16556 case HostComponent:
16557 var _type = fiber.type;
16558 var _props = fiber.pendingProps;
16559 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
16560 break;
16561 case HostText:
16562 var _text = fiber.pendingProps;
16563 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
16564 break;
16565 case SuspenseComponent:
16566 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
16567 break;
16568 }
16569 break;
16570 }
16571 default:
16572 return;
16573 }
16574 }
16575}
16576
16577function tryHydrate(fiber, nextInstance) {
16578 switch (fiber.tag) {
16579 case HostComponent:
16580 {
16581 var type = fiber.type;
16582 var props = fiber.pendingProps;
16583 var instance = canHydrateInstance(nextInstance, type, props);
16584 if (instance !== null) {
16585 fiber.stateNode = instance;
16586 return true;
16587 }
16588 return false;
16589 }
16590 case HostText:
16591 {
16592 var text = fiber.pendingProps;
16593 var textInstance = canHydrateTextInstance(nextInstance, text);
16594 if (textInstance !== null) {
16595 fiber.stateNode = textInstance;
16596 return true;
16597 }
16598 return false;
16599 }
16600 case SuspenseComponent:
16601 {
16602 if (enableSuspenseServerRenderer) {
16603 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
16604 if (suspenseInstance !== null) {
16605 // Downgrade the tag to a dehydrated component until we've hydrated it.
16606 fiber.tag = DehydratedSuspenseComponent;
16607 fiber.stateNode = suspenseInstance;
16608 return true;
16609 }
16610 }
16611 return false;
16612 }
16613 default:
16614 return false;
16615 }
16616}
16617
16618function tryToClaimNextHydratableInstance(fiber) {
16619 if (!isHydrating) {
16620 return;
16621 }
16622 var nextInstance = nextHydratableInstance;
16623 if (!nextInstance) {
16624 // Nothing to hydrate. Make it an insertion.
16625 insertNonHydratedInstance(hydrationParentFiber, fiber);
16626 isHydrating = false;
16627 hydrationParentFiber = fiber;
16628 return;
16629 }
16630 var firstAttemptedInstance = nextInstance;
16631 if (!tryHydrate(fiber, nextInstance)) {
16632 // If we can't hydrate this instance let's try the next one.
16633 // We use this as a heuristic. It's based on intuition and not data so it
16634 // might be flawed or unnecessary.
16635 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
16636 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
16637 // Nothing to hydrate. Make it an insertion.
16638 insertNonHydratedInstance(hydrationParentFiber, fiber);
16639 isHydrating = false;
16640 hydrationParentFiber = fiber;
16641 return;
16642 }
16643 // We matched the next one, we'll now assume that the first one was
16644 // superfluous and we'll delete it. Since we can't eagerly delete it
16645 // we'll have to schedule a deletion. To do that, this node needs a dummy
16646 // fiber associated with it.
16647 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
16648 }
16649 hydrationParentFiber = fiber;
16650 nextHydratableInstance = getFirstHydratableChild(nextInstance);
16651}
16652
16653function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
16654 if (!supportsHydration) {
16655 (function () {
16656 {
16657 {
16658 throw ReactError(Error('Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
16659 }
16660 }
16661 })();
16662 }
16663
16664 var instance = fiber.stateNode;
16665 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
16666 // TODO: Type this specific to this type of component.
16667 fiber.updateQueue = updatePayload;
16668 // If the update payload indicates that there is a change or if there
16669 // is a new ref we mark this as an update.
16670 if (updatePayload !== null) {
16671 return true;
16672 }
16673 return false;
16674}
16675
16676function prepareToHydrateHostTextInstance(fiber) {
16677 if (!supportsHydration) {
16678 (function () {
16679 {
16680 {
16681 throw ReactError(Error('Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
16682 }
16683 }
16684 })();
16685 }
16686
16687 var textInstance = fiber.stateNode;
16688 var textContent = fiber.memoizedProps;
16689 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
16690 {
16691 if (shouldUpdate) {
16692 // We assume that prepareToHydrateHostTextInstance is called in a context where the
16693 // hydration parent is the parent host component of this host text.
16694 var returnFiber = hydrationParentFiber;
16695 if (returnFiber !== null) {
16696 switch (returnFiber.tag) {
16697 case HostRoot:
16698 {
16699 var parentContainer = returnFiber.stateNode.containerInfo;
16700 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
16701 break;
16702 }
16703 case HostComponent:
16704 {
16705 var parentType = returnFiber.type;
16706 var parentProps = returnFiber.memoizedProps;
16707 var parentInstance = returnFiber.stateNode;
16708 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
16709 break;
16710 }
16711 }
16712 }
16713 }
16714 }
16715 return shouldUpdate;
16716}
16717
16718function skipPastDehydratedSuspenseInstance(fiber) {
16719 if (!supportsHydration) {
16720 (function () {
16721 {
16722 {
16723 throw ReactError(Error('Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
16724 }
16725 }
16726 })();
16727 }
16728 var suspenseInstance = fiber.stateNode;
16729 (function () {
16730 if (!suspenseInstance) {
16731 {
16732 throw ReactError(Error('Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.'));
16733 }
16734 }
16735 })();
16736 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
16737}
16738
16739function popToNextHostParent(fiber) {
16740 var parent = fiber.return;
16741 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
16742 parent = parent.return;
16743 }
16744 hydrationParentFiber = parent;
16745}
16746
16747function popHydrationState(fiber) {
16748 if (!supportsHydration) {
16749 return false;
16750 }
16751 if (fiber !== hydrationParentFiber) {
16752 // We're deeper than the current hydration context, inside an inserted
16753 // tree.
16754 return false;
16755 }
16756 if (!isHydrating) {
16757 // If we're not currently hydrating but we're in a hydration context, then
16758 // we were an insertion and now need to pop up reenter hydration of our
16759 // siblings.
16760 popToNextHostParent(fiber);
16761 isHydrating = true;
16762 return false;
16763 }
16764
16765 var type = fiber.type;
16766
16767 // If we have any remaining hydratable nodes, we need to delete them now.
16768 // We only do this deeper than head and body since they tend to have random
16769 // other nodes in them. We also ignore components with pure text content in
16770 // side of them.
16771 // TODO: Better heuristic.
16772 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
16773 var nextInstance = nextHydratableInstance;
16774 while (nextInstance) {
16775 deleteHydratableInstance(fiber, nextInstance);
16776 nextInstance = getNextHydratableSibling(nextInstance);
16777 }
16778 }
16779
16780 popToNextHostParent(fiber);
16781 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
16782 return true;
16783}
16784
16785function resetHydrationState() {
16786 if (!supportsHydration) {
16787 return;
16788 }
16789
16790 hydrationParentFiber = null;
16791 nextHydratableInstance = null;
16792 isHydrating = false;
16793}
16794
16795var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
16796
16797var didReceiveUpdate = false;
16798
16799var didWarnAboutBadClass = void 0;
16800var didWarnAboutModulePatternComponent = void 0;
16801var didWarnAboutContextTypeOnFunctionComponent = void 0;
16802var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
16803var didWarnAboutFunctionRefs = void 0;
16804var didWarnAboutReassigningProps = void 0;
16805var didWarnAboutMaxDuration = void 0;
16806var didWarnAboutRevealOrder = void 0;
16807var didWarnAboutTailOptions = void 0;
16808var didWarnAboutDefaultPropsOnFunctionComponent = void 0;
16809
16810{
16811 didWarnAboutBadClass = {};
16812 didWarnAboutModulePatternComponent = {};
16813 didWarnAboutContextTypeOnFunctionComponent = {};
16814 didWarnAboutGetDerivedStateOnFunctionComponent = {};
16815 didWarnAboutFunctionRefs = {};
16816 didWarnAboutReassigningProps = false;
16817 didWarnAboutMaxDuration = false;
16818 didWarnAboutRevealOrder = {};
16819 didWarnAboutTailOptions = {};
16820 didWarnAboutDefaultPropsOnFunctionComponent = {};
16821}
16822
16823function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
16824 if (current$$1 === null) {
16825 // If this is a fresh new component that hasn't been rendered yet, we
16826 // won't update its child set by applying minimal side-effects. Instead,
16827 // we will add them all to the child before it gets rendered. That means
16828 // we can optimize this reconciliation pass by not tracking side-effects.
16829 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16830 } else {
16831 // If the current child is the same as the work in progress, it means that
16832 // we haven't yet started any work on these children. Therefore, we use
16833 // the clone algorithm to create a copy of all the current children.
16834
16835 // If we had any progressed work already, that is invalid at this point so
16836 // let's throw it out.
16837 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
16838 }
16839}
16840
16841function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
16842 // This function is fork of reconcileChildren. It's used in cases where we
16843 // want to reconcile without matching against the existing set. This has the
16844 // effect of all current children being unmounted; even if the type and key
16845 // are the same, the old child is unmounted and a new child is created.
16846 //
16847 // To do this, we're going to go through the reconcile algorithm twice. In
16848 // the first pass, we schedule a deletion for all the current children by
16849 // passing null.
16850 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
16851 // In the second pass, we mount the new children. The trick here is that we
16852 // pass null in place of where we usually pass the current child set. This has
16853 // the effect of remounting all children regardless of whether their their
16854 // identity matches.
16855 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
16856}
16857
16858function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
16859 // TODO: current can be non-null here even if the component
16860 // hasn't yet mounted. This happens after the first render suspends.
16861 // We'll need to figure out if this is fine or can cause issues.
16862
16863 {
16864 if (workInProgress.type !== workInProgress.elementType) {
16865 // Lazy component props can't be validated in createElement
16866 // because they're only guaranteed to be resolved here.
16867 var innerPropTypes = Component.propTypes;
16868 if (innerPropTypes) {
16869 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
16870 'prop', getComponentName(Component), getCurrentFiberStackInDev);
16871 }
16872 }
16873 }
16874
16875 var render = Component.render;
16876 var ref = workInProgress.ref;
16877
16878 // The rest is a fork of updateFunctionComponent
16879 var nextChildren = void 0;
16880 prepareToReadContext(workInProgress, renderExpirationTime);
16881 {
16882 ReactCurrentOwner$3.current = workInProgress;
16883 setCurrentPhase('render');
16884 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
16885 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16886 // Only double-render components with Hooks
16887 if (workInProgress.memoizedState !== null) {
16888 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
16889 }
16890 }
16891 setCurrentPhase(null);
16892 }
16893
16894 if (current$$1 !== null && !didReceiveUpdate) {
16895 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
16896 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
16897 }
16898
16899 // React DevTools reads this flag.
16900 workInProgress.effectTag |= PerformedWork;
16901 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
16902 return workInProgress.child;
16903}
16904
16905function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
16906 if (current$$1 === null) {
16907 var type = Component.type;
16908 if (isSimpleFunctionComponent(type) && Component.compare === null &&
16909 // SimpleMemoComponent codepath doesn't resolve outer props either.
16910 Component.defaultProps === undefined) {
16911 var resolvedType = type;
16912 {
16913 resolvedType = resolveFunctionForHotReloading(type);
16914 }
16915 // If this is a plain function component without default props,
16916 // and with only the default shallow comparison, we upgrade it
16917 // to a SimpleMemoComponent to allow fast path updates.
16918 workInProgress.tag = SimpleMemoComponent;
16919 workInProgress.type = resolvedType;
16920 {
16921 validateFunctionComponentInDev(workInProgress, type);
16922 }
16923 return updateSimpleMemoComponent(current$$1, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
16924 }
16925 {
16926 var innerPropTypes = type.propTypes;
16927 if (innerPropTypes) {
16928 // Inner memo component props aren't currently validated in createElement.
16929 // We could move it there, but we'd still need this for lazy code path.
16930 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
16931 'prop', getComponentName(type), getCurrentFiberStackInDev);
16932 }
16933 }
16934 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
16935 child.ref = workInProgress.ref;
16936 child.return = workInProgress;
16937 workInProgress.child = child;
16938 return child;
16939 }
16940 {
16941 var _type = Component.type;
16942 var _innerPropTypes = _type.propTypes;
16943 if (_innerPropTypes) {
16944 // Inner memo component props aren't currently validated in createElement.
16945 // We could move it there, but we'd still need this for lazy code path.
16946 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
16947 'prop', getComponentName(_type), getCurrentFiberStackInDev);
16948 }
16949 }
16950 var currentChild = current$$1.child; // This is always exactly one child
16951 if (updateExpirationTime < renderExpirationTime) {
16952 // This will be the props with resolved defaultProps,
16953 // unlike current.memoizedProps which will be the unresolved ones.
16954 var prevProps = currentChild.memoizedProps;
16955 // Default to shallow comparison
16956 var compare = Component.compare;
16957 compare = compare !== null ? compare : shallowEqual;
16958 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
16959 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
16960 }
16961 }
16962 // React DevTools reads this flag.
16963 workInProgress.effectTag |= PerformedWork;
16964 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
16965 newChild.ref = workInProgress.ref;
16966 newChild.return = workInProgress;
16967 workInProgress.child = newChild;
16968 return newChild;
16969}
16970
16971function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
16972 // TODO: current can be non-null here even if the component
16973 // hasn't yet mounted. This happens when the inner render suspends.
16974 // We'll need to figure out if this is fine or can cause issues.
16975
16976 {
16977 if (workInProgress.type !== workInProgress.elementType) {
16978 // Lazy component props can't be validated in createElement
16979 // because they're only guaranteed to be resolved here.
16980 var outerMemoType = workInProgress.elementType;
16981 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
16982 // We warn when you define propTypes on lazy()
16983 // so let's just skip over it to find memo() outer wrapper.
16984 // Inner props for memo are validated later.
16985 outerMemoType = refineResolvedLazyComponent(outerMemoType);
16986 }
16987 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
16988 if (outerPropTypes) {
16989 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
16990 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
16991 }
16992 // Inner propTypes will be validated in the function component path.
16993 }
16994 }
16995 if (current$$1 !== null) {
16996 var prevProps = current$$1.memoizedProps;
16997 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref && (
16998 // Prevent bailout if the implementation changed due to hot reload:
16999 workInProgress.type === current$$1.type)) {
17000 didReceiveUpdate = false;
17001 if (updateExpirationTime < renderExpirationTime) {
17002 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
17003 }
17004 }
17005 }
17006 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
17007}
17008
17009function updateFragment(current$$1, workInProgress, renderExpirationTime) {
17010 var nextChildren = workInProgress.pendingProps;
17011 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17012 return workInProgress.child;
17013}
17014
17015function updateMode(current$$1, workInProgress, renderExpirationTime) {
17016 var nextChildren = workInProgress.pendingProps.children;
17017 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17018 return workInProgress.child;
17019}
17020
17021function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
17022 if (enableProfilerTimer) {
17023 workInProgress.effectTag |= Update;
17024 }
17025 var nextProps = workInProgress.pendingProps;
17026 var nextChildren = nextProps.children;
17027 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17028 return workInProgress.child;
17029}
17030
17031function markRef(current$$1, workInProgress) {
17032 var ref = workInProgress.ref;
17033 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
17034 // Schedule a Ref effect
17035 workInProgress.effectTag |= Ref;
17036 }
17037}
17038
17039function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
17040 {
17041 if (workInProgress.type !== workInProgress.elementType) {
17042 // Lazy component props can't be validated in createElement
17043 // because they're only guaranteed to be resolved here.
17044 var innerPropTypes = Component.propTypes;
17045 if (innerPropTypes) {
17046 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
17047 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17048 }
17049 }
17050 }
17051
17052 var context = void 0;
17053 if (!disableLegacyContext) {
17054 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
17055 context = getMaskedContext(workInProgress, unmaskedContext);
17056 }
17057
17058 var nextChildren = void 0;
17059 prepareToReadContext(workInProgress, renderExpirationTime);
17060 {
17061 ReactCurrentOwner$3.current = workInProgress;
17062 setCurrentPhase('render');
17063 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
17064 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
17065 // Only double-render components with Hooks
17066 if (workInProgress.memoizedState !== null) {
17067 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
17068 }
17069 }
17070 setCurrentPhase(null);
17071 }
17072
17073 if (current$$1 !== null && !didReceiveUpdate) {
17074 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
17075 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
17076 }
17077
17078 // React DevTools reads this flag.
17079 workInProgress.effectTag |= PerformedWork;
17080 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17081 return workInProgress.child;
17082}
17083
17084function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
17085 {
17086 if (workInProgress.type !== workInProgress.elementType) {
17087 // Lazy component props can't be validated in createElement
17088 // because they're only guaranteed to be resolved here.
17089 var innerPropTypes = Component.propTypes;
17090 if (innerPropTypes) {
17091 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
17092 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17093 }
17094 }
17095 }
17096
17097 // Push context providers early to prevent context stack mismatches.
17098 // During mounting we don't know the child context yet as the instance doesn't exist.
17099 // We will invalidate the child context in finishClassComponent() right after rendering.
17100 var hasContext = void 0;
17101 if (isContextProvider(Component)) {
17102 hasContext = true;
17103 pushContextProvider(workInProgress);
17104 } else {
17105 hasContext = false;
17106 }
17107 prepareToReadContext(workInProgress, renderExpirationTime);
17108
17109 var instance = workInProgress.stateNode;
17110 var shouldUpdate = void 0;
17111 if (instance === null) {
17112 if (current$$1 !== null) {
17113 // An class component without an instance only mounts if it suspended
17114 // inside a non- concurrent tree, in an inconsistent state. We want to
17115 // tree it like a new mount, even though an empty version of it already
17116 // committed. Disconnect the alternate pointers.
17117 current$$1.alternate = null;
17118 workInProgress.alternate = null;
17119 // Since this is conceptually a new fiber, schedule a Placement effect
17120 workInProgress.effectTag |= Placement;
17121 }
17122 // In the initial pass we might need to construct the instance.
17123 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17124 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17125 shouldUpdate = true;
17126 } else if (current$$1 === null) {
17127 // In a resume, we'll already have an instance we can reuse.
17128 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17129 } else {
17130 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
17131 }
17132 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
17133 {
17134 var inst = workInProgress.stateNode;
17135 if (inst.props !== nextProps) {
17136 !didWarnAboutReassigningProps ? warning$1(false, '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') : void 0;
17137 didWarnAboutReassigningProps = true;
17138 }
17139 }
17140 return nextUnitOfWork;
17141}
17142
17143function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
17144 // Refs should update even if shouldComponentUpdate returns false
17145 markRef(current$$1, workInProgress);
17146
17147 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
17148
17149 if (!shouldUpdate && !didCaptureError) {
17150 // Context providers should defer to sCU for rendering
17151 if (hasContext) {
17152 invalidateContextProvider(workInProgress, Component, false);
17153 }
17154
17155 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
17156 }
17157
17158 var instance = workInProgress.stateNode;
17159
17160 // Rerender
17161 ReactCurrentOwner$3.current = workInProgress;
17162 var nextChildren = void 0;
17163 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
17164 // If we captured an error, but getDerivedStateFrom catch is not defined,
17165 // unmount all the children. componentDidCatch will schedule an update to
17166 // re-render a fallback. This is temporary until we migrate everyone to
17167 // the new API.
17168 // TODO: Warn in a future release.
17169 nextChildren = null;
17170
17171 if (enableProfilerTimer) {
17172 stopProfilerTimerIfRunning(workInProgress);
17173 }
17174 } else {
17175 {
17176 setCurrentPhase('render');
17177 nextChildren = instance.render();
17178 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
17179 instance.render();
17180 }
17181 setCurrentPhase(null);
17182 }
17183 }
17184
17185 // React DevTools reads this flag.
17186 workInProgress.effectTag |= PerformedWork;
17187 if (current$$1 !== null && didCaptureError) {
17188 // If we're recovering from an error, reconcile without reusing any of
17189 // the existing children. Conceptually, the normal children and the children
17190 // that are shown on error are two different sets, so we shouldn't reuse
17191 // normal children even if their identities match.
17192 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
17193 } else {
17194 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17195 }
17196
17197 // Memoize state using the values we just used to render.
17198 // TODO: Restructure so we never read values from the instance.
17199 workInProgress.memoizedState = instance.state;
17200
17201 // The context might have changed so we need to recalculate it.
17202 if (hasContext) {
17203 invalidateContextProvider(workInProgress, Component, true);
17204 }
17205
17206 return workInProgress.child;
17207}
17208
17209function pushHostRootContext(workInProgress) {
17210 var root = workInProgress.stateNode;
17211 if (root.pendingContext) {
17212 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
17213 } else if (root.context) {
17214 // Should always be set
17215 pushTopLevelContextObject(workInProgress, root.context, false);
17216 }
17217 pushHostContainer(workInProgress, root.containerInfo);
17218}
17219
17220function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
17221 pushHostRootContext(workInProgress);
17222 var updateQueue = workInProgress.updateQueue;
17223 (function () {
17224 if (!(updateQueue !== null)) {
17225 {
17226 throw ReactError(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.'));
17227 }
17228 }
17229 })();
17230 var nextProps = workInProgress.pendingProps;
17231 var prevState = workInProgress.memoizedState;
17232 var prevChildren = prevState !== null ? prevState.element : null;
17233 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
17234 var nextState = workInProgress.memoizedState;
17235 // Caution: React DevTools currently depends on this property
17236 // being called "element".
17237 var nextChildren = nextState.element;
17238 if (nextChildren === prevChildren) {
17239 // If the state is the same as before, that's a bailout because we had
17240 // no work that expires at this time.
17241 resetHydrationState();
17242 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
17243 }
17244 var root = workInProgress.stateNode;
17245 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
17246 // If we don't have any current children this might be the first pass.
17247 // We always try to hydrate. If this isn't a hydration pass there won't
17248 // be any children to hydrate which is effectively the same thing as
17249 // not hydrating.
17250
17251 // This is a bit of a hack. We track the host root as a placement to
17252 // know that we're currently in a mounting state. That way isMounted
17253 // works as expected. We must reset this before committing.
17254 // TODO: Delete this when we delete isMounted and findDOMNode.
17255 workInProgress.effectTag |= Placement;
17256
17257 // Ensure that children mount into this root without tracking
17258 // side-effects. This ensures that we don't store Placement effects on
17259 // nodes that will be hydrated.
17260 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
17261 } else {
17262 // Otherwise reset hydration state in case we aborted and resumed another
17263 // root.
17264 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17265 resetHydrationState();
17266 }
17267 return workInProgress.child;
17268}
17269
17270function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
17271 pushHostContext(workInProgress);
17272
17273 if (current$$1 === null) {
17274 tryToClaimNextHydratableInstance(workInProgress);
17275 }
17276
17277 var type = workInProgress.type;
17278 var nextProps = workInProgress.pendingProps;
17279 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
17280
17281 var nextChildren = nextProps.children;
17282 var isDirectTextChild = shouldSetTextContent(type, nextProps);
17283
17284 if (isDirectTextChild) {
17285 // We special case a direct text child of a host node. This is a common
17286 // case. We won't handle it as a reified child. We will instead handle
17287 // this in the host environment that also have access to this prop. That
17288 // avoids allocating another HostText fiber and traversing it.
17289 nextChildren = null;
17290 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
17291 // If we're switching from a direct text child to a normal child, or to
17292 // empty, we need to schedule the text content to be reset.
17293 workInProgress.effectTag |= ContentReset;
17294 }
17295
17296 markRef(current$$1, workInProgress);
17297
17298 // Check the host config to see if the children are offscreen/hidden.
17299 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
17300 if (enableSchedulerTracing) {
17301 markSpawnedWork(Never);
17302 }
17303 // Schedule this fiber to re-render at offscreen priority. Then bailout.
17304 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
17305 return null;
17306 }
17307
17308 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
17309 return workInProgress.child;
17310}
17311
17312function updateHostText(current$$1, workInProgress) {
17313 if (current$$1 === null) {
17314 tryToClaimNextHydratableInstance(workInProgress);
17315 }
17316 // Nothing to do here. This is terminal. We'll do the completion step
17317 // immediately after.
17318 return null;
17319}
17320
17321function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
17322 if (_current !== null) {
17323 // An lazy component only mounts if it suspended inside a non-
17324 // concurrent tree, in an inconsistent state. We want to treat it like
17325 // a new mount, even though an empty version of it already committed.
17326 // Disconnect the alternate pointers.
17327 _current.alternate = null;
17328 workInProgress.alternate = null;
17329 // Since this is conceptually a new fiber, schedule a Placement effect
17330 workInProgress.effectTag |= Placement;
17331 }
17332
17333 var props = workInProgress.pendingProps;
17334 // We can't start a User Timing measurement with correct label yet.
17335 // Cancel and resume right after we know the tag.
17336 cancelWorkTimer(workInProgress);
17337 var Component = readLazyComponentType(elementType);
17338 // Store the unwrapped component in the type.
17339 workInProgress.type = Component;
17340 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
17341 startWorkTimer(workInProgress);
17342 var resolvedProps = resolveDefaultProps(Component, props);
17343 var child = void 0;
17344 switch (resolvedTag) {
17345 case FunctionComponent:
17346 {
17347 {
17348 validateFunctionComponentInDev(workInProgress, Component);
17349 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
17350 }
17351 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17352 break;
17353 }
17354 case ClassComponent:
17355 {
17356 {
17357 workInProgress.type = Component = resolveClassForHotReloading(Component);
17358 }
17359 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17360 break;
17361 }
17362 case ForwardRef:
17363 {
17364 {
17365 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
17366 }
17367 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
17368 break;
17369 }
17370 case MemoComponent:
17371 {
17372 {
17373 if (workInProgress.type !== workInProgress.elementType) {
17374 var outerPropTypes = Component.propTypes;
17375 if (outerPropTypes) {
17376 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
17377 'prop', getComponentName(Component), getCurrentFiberStackInDev);
17378 }
17379 }
17380 }
17381 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
17382 updateExpirationTime, renderExpirationTime);
17383 break;
17384 }
17385 default:
17386 {
17387 var hint = '';
17388 {
17389 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
17390 hint = ' Did you wrap a component in React.lazy() more than once?';
17391 }
17392 }
17393 // This message intentionally doesn't mention ForwardRef or MemoComponent
17394 // because the fact that it's a separate type of work is an
17395 // implementation detail.
17396 (function () {
17397 {
17398 {
17399 throw ReactError(Error('Element type is invalid. Received a promise that resolves to: ' + Component + '. Lazy element type must resolve to a class or function.' + hint));
17400 }
17401 }
17402 })();
17403 }
17404 }
17405 return child;
17406}
17407
17408function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
17409 if (_current !== null) {
17410 // An incomplete component only mounts if it suspended inside a non-
17411 // concurrent tree, in an inconsistent state. We want to treat it like
17412 // a new mount, even though an empty version of it already committed.
17413 // Disconnect the alternate pointers.
17414 _current.alternate = null;
17415 workInProgress.alternate = null;
17416 // Since this is conceptually a new fiber, schedule a Placement effect
17417 workInProgress.effectTag |= Placement;
17418 }
17419
17420 // Promote the fiber to a class and try rendering again.
17421 workInProgress.tag = ClassComponent;
17422
17423 // The rest of this function is a fork of `updateClassComponent`
17424
17425 // Push context providers early to prevent context stack mismatches.
17426 // During mounting we don't know the child context yet as the instance doesn't exist.
17427 // We will invalidate the child context in finishClassComponent() right after rendering.
17428 var hasContext = void 0;
17429 if (isContextProvider(Component)) {
17430 hasContext = true;
17431 pushContextProvider(workInProgress);
17432 } else {
17433 hasContext = false;
17434 }
17435 prepareToReadContext(workInProgress, renderExpirationTime);
17436
17437 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17438 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
17439
17440 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17441}
17442
17443function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
17444 if (_current !== null) {
17445 // An indeterminate component only mounts if it suspended inside a non-
17446 // concurrent tree, in an inconsistent state. We want to treat it like
17447 // a new mount, even though an empty version of it already committed.
17448 // Disconnect the alternate pointers.
17449 _current.alternate = null;
17450 workInProgress.alternate = null;
17451 // Since this is conceptually a new fiber, schedule a Placement effect
17452 workInProgress.effectTag |= Placement;
17453 }
17454
17455 var props = workInProgress.pendingProps;
17456 var context = void 0;
17457 if (!disableLegacyContext) {
17458 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
17459 context = getMaskedContext(workInProgress, unmaskedContext);
17460 }
17461
17462 prepareToReadContext(workInProgress, renderExpirationTime);
17463 var value = void 0;
17464
17465 {
17466 if (Component.prototype && typeof Component.prototype.render === 'function') {
17467 var componentName = getComponentName(Component) || 'Unknown';
17468
17469 if (!didWarnAboutBadClass[componentName]) {
17470 warningWithoutStack$1(false, "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
17471 didWarnAboutBadClass[componentName] = true;
17472 }
17473 }
17474
17475 if (workInProgress.mode & StrictMode) {
17476 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
17477 }
17478
17479 ReactCurrentOwner$3.current = workInProgress;
17480 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17481 }
17482 // React DevTools reads this flag.
17483 workInProgress.effectTag |= PerformedWork;
17484
17485 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
17486 {
17487 var _componentName = getComponentName(Component) || 'Unknown';
17488 if (!didWarnAboutModulePatternComponent[_componentName]) {
17489 warningWithoutStack$1(false, '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);
17490 didWarnAboutModulePatternComponent[_componentName] = true;
17491 }
17492 }
17493
17494 // Proceed under the assumption that this is a class instance
17495 workInProgress.tag = ClassComponent;
17496
17497 // Throw out any hooks that were used.
17498 resetHooks();
17499
17500 // Push context providers early to prevent context stack mismatches.
17501 // During mounting we don't know the child context yet as the instance doesn't exist.
17502 // We will invalidate the child context in finishClassComponent() right after rendering.
17503 var hasContext = false;
17504 if (isContextProvider(Component)) {
17505 hasContext = true;
17506 pushContextProvider(workInProgress);
17507 } else {
17508 hasContext = false;
17509 }
17510
17511 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
17512
17513 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
17514 if (typeof getDerivedStateFromProps === 'function') {
17515 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
17516 }
17517
17518 adoptClassInstance(workInProgress, value);
17519 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
17520 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
17521 } else {
17522 // Proceed under the assumption that this is a function component
17523 workInProgress.tag = FunctionComponent;
17524 {
17525 if (disableLegacyContext && Component.contextTypes) {
17526 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown');
17527 }
17528
17529 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
17530 // Only double-render components with Hooks
17531 if (workInProgress.memoizedState !== null) {
17532 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
17533 }
17534 }
17535 }
17536 reconcileChildren(null, workInProgress, value, renderExpirationTime);
17537 {
17538 validateFunctionComponentInDev(workInProgress, Component);
17539 }
17540 return workInProgress.child;
17541 }
17542}
17543
17544function validateFunctionComponentInDev(workInProgress, Component) {
17545 if (Component) {
17546 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
17547 }
17548 if (workInProgress.ref !== null) {
17549 var info = '';
17550 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
17551 if (ownerName) {
17552 info += '\n\nCheck the render method of `' + ownerName + '`.';
17553 }
17554
17555 var warningKey = ownerName || workInProgress._debugID || '';
17556 var debugSource = workInProgress._debugSource;
17557 if (debugSource) {
17558 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
17559 }
17560 if (!didWarnAboutFunctionRefs[warningKey]) {
17561 didWarnAboutFunctionRefs[warningKey] = true;
17562 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
17563 }
17564 }
17565
17566 if (warnAboutDefaultPropsOnFunctionComponents && Component.defaultProps !== undefined) {
17567 var componentName = getComponentName(Component) || 'Unknown';
17568
17569 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
17570 warningWithoutStack$1(false, '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
17571 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
17572 }
17573 }
17574
17575 if (typeof Component.getDerivedStateFromProps === 'function') {
17576 var _componentName2 = getComponentName(Component) || 'Unknown';
17577
17578 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
17579 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', _componentName2);
17580 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
17581 }
17582 }
17583
17584 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
17585 var _componentName3 = getComponentName(Component) || 'Unknown';
17586
17587 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
17588 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName3);
17589 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
17590 }
17591 }
17592}
17593
17594// TODO: This is now an empty object. Should we just make it a boolean?
17595var SUSPENDED_MARKER = {};
17596
17597function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) {
17598 // If the context is telling us that we should show a fallback, and we're not
17599 // already showing content, then we should show the fallback instead.
17600 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current$$1 === null || current$$1.memoizedState !== null);
17601}
17602
17603function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
17604 var mode = workInProgress.mode;
17605 var nextProps = workInProgress.pendingProps;
17606
17607 // This is used by DevTools to force a boundary to suspend.
17608 {
17609 if (shouldSuspend(workInProgress)) {
17610 workInProgress.effectTag |= DidCapture;
17611 }
17612 }
17613
17614 var suspenseContext = suspenseStackCursor.current;
17615
17616 var nextState = null;
17617 var nextDidTimeout = false;
17618
17619 if ((workInProgress.effectTag & DidCapture) !== NoEffect || shouldRemainOnFallback(suspenseContext, current$$1, workInProgress)) {
17620 // Something in this boundary's subtree already suspended. Switch to
17621 // rendering the fallback children.
17622 nextState = SUSPENDED_MARKER;
17623 nextDidTimeout = true;
17624 workInProgress.effectTag &= ~DidCapture;
17625 } else {
17626 // Attempting the main content
17627 if (current$$1 === null || current$$1.memoizedState !== null) {
17628 // This is a new mount or this boundary is already showing a fallback state.
17629 // Mark this subtree context as having at least one invisible parent that could
17630 // handle the fallback state.
17631 // Boundaries without fallbacks or should be avoided are not considered since
17632 // they cannot handle preferred fallback states.
17633 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
17634 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
17635 }
17636 }
17637 }
17638
17639 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
17640
17641 pushSuspenseContext(workInProgress, suspenseContext);
17642
17643 {
17644 if ('maxDuration' in nextProps) {
17645 if (!didWarnAboutMaxDuration) {
17646 didWarnAboutMaxDuration = true;
17647 warning$1(false, 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
17648 }
17649 }
17650 }
17651
17652 // This next part is a bit confusing. If the children timeout, we switch to
17653 // showing the fallback children in place of the "primary" children.
17654 // However, we don't want to delete the primary children because then their
17655 // state will be lost (both the React state and the host state, e.g.
17656 // uncontrolled form inputs). Instead we keep them mounted and hide them.
17657 // Both the fallback children AND the primary children are rendered at the
17658 // same time. Once the primary children are un-suspended, we can delete
17659 // the fallback children — don't need to preserve their state.
17660 //
17661 // The two sets of children are siblings in the host environment, but
17662 // semantically, for purposes of reconciliation, they are two separate sets.
17663 // So we store them using two fragment fibers.
17664 //
17665 // However, we want to avoid allocating extra fibers for every placeholder.
17666 // They're only necessary when the children time out, because that's the
17667 // only time when both sets are mounted.
17668 //
17669 // So, the extra fragment fibers are only used if the children time out.
17670 // Otherwise, we render the primary children directly. This requires some
17671 // custom reconciliation logic to preserve the state of the primary
17672 // children. It's essentially a very basic form of re-parenting.
17673
17674 // `child` points to the child fiber. In the normal case, this is the first
17675 // fiber of the primary children set. In the timed-out case, it's a
17676 // a fragment fiber containing the primary children.
17677 var child = void 0;
17678 // `next` points to the next fiber React should render. In the normal case,
17679 // it's the same as `child`: the first fiber of the primary children set.
17680 // In the timed-out case, it's a fragment fiber containing the *fallback*
17681 // children -- we skip over the primary children entirely.
17682 var next = void 0;
17683 if (current$$1 === null) {
17684 if (enableSuspenseServerRenderer) {
17685 // If we're currently hydrating, try to hydrate this boundary.
17686 // But only if this has a fallback.
17687 if (nextProps.fallback !== undefined) {
17688 tryToClaimNextHydratableInstance(workInProgress);
17689 // This could've changed the tag if this was a dehydrated suspense component.
17690 if (workInProgress.tag === DehydratedSuspenseComponent) {
17691 popSuspenseContext(workInProgress);
17692 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
17693 }
17694 }
17695 }
17696
17697 // This is the initial mount. This branch is pretty simple because there's
17698 // no previous state that needs to be preserved.
17699 if (nextDidTimeout) {
17700 // Mount separate fragments for primary and fallback children.
17701 var nextFallbackChildren = nextProps.fallback;
17702 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
17703 primaryChildFragment.return = workInProgress;
17704
17705 if ((workInProgress.mode & BatchedMode) === NoMode) {
17706 // Outside of batched mode, we commit the effects from the
17707 var progressedState = workInProgress.memoizedState;
17708 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
17709 primaryChildFragment.child = progressedPrimaryChild;
17710 var progressedChild = progressedPrimaryChild;
17711 while (progressedChild !== null) {
17712 progressedChild.return = primaryChildFragment;
17713 progressedChild = progressedChild.sibling;
17714 }
17715 }
17716
17717 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
17718 fallbackChildFragment.return = workInProgress;
17719 primaryChildFragment.sibling = fallbackChildFragment;
17720 child = primaryChildFragment;
17721 // Skip the primary children, and continue working on the
17722 // fallback children.
17723 next = fallbackChildFragment;
17724 } else {
17725 // Mount the primary children without an intermediate fragment fiber.
17726 var nextPrimaryChildren = nextProps.children;
17727 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
17728 }
17729 } else {
17730 // This is an update. This branch is more complicated because we need to
17731 // ensure the state of the primary children is preserved.
17732 var prevState = current$$1.memoizedState;
17733 var prevDidTimeout = prevState !== null;
17734 if (prevDidTimeout) {
17735 // The current tree already timed out. That means each child set is
17736 var currentPrimaryChildFragment = current$$1.child;
17737 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
17738 if (nextDidTimeout) {
17739 // Still timed out. Reuse the current primary children by cloning
17740 // its fragment. We're going to skip over these entirely.
17741 var _nextFallbackChildren = nextProps.fallback;
17742 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
17743 _primaryChildFragment.return = workInProgress;
17744
17745 if ((workInProgress.mode & BatchedMode) === NoMode) {
17746 // Outside of batched mode, we commit the effects from the
17747 var _progressedState = workInProgress.memoizedState;
17748 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
17749 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
17750 _primaryChildFragment.child = _progressedPrimaryChild;
17751 var _progressedChild = _progressedPrimaryChild;
17752 while (_progressedChild !== null) {
17753 _progressedChild.return = _primaryChildFragment;
17754 _progressedChild = _progressedChild.sibling;
17755 }
17756 }
17757 }
17758
17759 // Because primaryChildFragment is a new fiber that we're inserting as the
17760 // parent of a new tree, we need to set its treeBaseDuration.
17761 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
17762 // treeBaseDuration is the sum of all the child tree base durations.
17763 var treeBaseDuration = 0;
17764 var hiddenChild = _primaryChildFragment.child;
17765 while (hiddenChild !== null) {
17766 treeBaseDuration += hiddenChild.treeBaseDuration;
17767 hiddenChild = hiddenChild.sibling;
17768 }
17769 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
17770 }
17771
17772 // Clone the fallback child fragment, too. These we'll continue
17773 // working on.
17774 var _fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
17775 _fallbackChildFragment.return = workInProgress;
17776 _primaryChildFragment.sibling = _fallbackChildFragment;
17777 child = _primaryChildFragment;
17778 _primaryChildFragment.childExpirationTime = NoWork;
17779 // Skip the primary children, and continue working on the
17780 // fallback children.
17781 next = _fallbackChildFragment;
17782 } else {
17783 // No longer suspended. Switch back to showing the primary children,
17784 // and remove the intermediate fragment fiber.
17785 var _nextPrimaryChildren = nextProps.children;
17786 var currentPrimaryChild = currentPrimaryChildFragment.child;
17787 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
17788
17789 // If this render doesn't suspend, we need to delete the fallback
17790 // children. Wait until the complete phase, after we've confirmed the
17791 // fallback is no longer needed.
17792 // TODO: Would it be better to store the fallback fragment on
17793 // the stateNode?
17794
17795 // Continue rendering the children, like we normally do.
17796 child = next = primaryChild;
17797 }
17798 } else {
17799 // The current tree has not already timed out. That means the primary
17800 // children are not wrapped in a fragment fiber.
17801 var _currentPrimaryChild = current$$1.child;
17802 if (nextDidTimeout) {
17803 // Timed out. Wrap the children in a fragment fiber to keep them
17804 // separate from the fallback children.
17805 var _nextFallbackChildren2 = nextProps.fallback;
17806 var _primaryChildFragment2 = createFiberFromFragment(
17807 // It shouldn't matter what the pending props are because we aren't
17808 // going to render this fragment.
17809 null, mode, NoWork, null);
17810 _primaryChildFragment2.return = workInProgress;
17811 _primaryChildFragment2.child = _currentPrimaryChild;
17812 if (_currentPrimaryChild !== null) {
17813 _currentPrimaryChild.return = _primaryChildFragment2;
17814 }
17815
17816 // Even though we're creating a new fiber, there are no new children,
17817 // because we're reusing an already mounted tree. So we don't need to
17818 // schedule a placement.
17819 // primaryChildFragment.effectTag |= Placement;
17820
17821 if ((workInProgress.mode & BatchedMode) === NoMode) {
17822 // Outside of batched mode, we commit the effects from the
17823 var _progressedState2 = workInProgress.memoizedState;
17824 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
17825 _primaryChildFragment2.child = _progressedPrimaryChild2;
17826 var _progressedChild2 = _progressedPrimaryChild2;
17827 while (_progressedChild2 !== null) {
17828 _progressedChild2.return = _primaryChildFragment2;
17829 _progressedChild2 = _progressedChild2.sibling;
17830 }
17831 }
17832
17833 // Because primaryChildFragment is a new fiber that we're inserting as the
17834 // parent of a new tree, we need to set its treeBaseDuration.
17835 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
17836 // treeBaseDuration is the sum of all the child tree base durations.
17837 var _treeBaseDuration = 0;
17838 var _hiddenChild = _primaryChildFragment2.child;
17839 while (_hiddenChild !== null) {
17840 _treeBaseDuration += _hiddenChild.treeBaseDuration;
17841 _hiddenChild = _hiddenChild.sibling;
17842 }
17843 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
17844 }
17845
17846 // Create a fragment from the fallback children, too.
17847 var _fallbackChildFragment2 = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
17848 _fallbackChildFragment2.return = workInProgress;
17849 _primaryChildFragment2.sibling = _fallbackChildFragment2;
17850 _fallbackChildFragment2.effectTag |= Placement;
17851 child = _primaryChildFragment2;
17852 _primaryChildFragment2.childExpirationTime = NoWork;
17853 // Skip the primary children, and continue working on the
17854 // fallback children.
17855 next = _fallbackChildFragment2;
17856 } else {
17857 // Still haven't timed out. Continue rendering the children, like we
17858 // normally do.
17859 var _nextPrimaryChildren2 = nextProps.children;
17860 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
17861 }
17862 }
17863 workInProgress.stateNode = current$$1.stateNode;
17864 }
17865
17866 workInProgress.memoizedState = nextState;
17867 workInProgress.child = child;
17868 return next;
17869}
17870
17871function retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime) {
17872 // Detach from the current dehydrated boundary.
17873 current$$1.alternate = null;
17874 workInProgress.alternate = null;
17875
17876 // Insert a deletion in the effect list.
17877 var returnFiber = workInProgress.return;
17878 (function () {
17879 if (!(returnFiber !== null)) {
17880 {
17881 throw ReactError(Error('Suspense boundaries are never on the root. This is probably a bug in React.'));
17882 }
17883 }
17884 })();
17885 var last = returnFiber.lastEffect;
17886 if (last !== null) {
17887 last.nextEffect = current$$1;
17888 returnFiber.lastEffect = current$$1;
17889 } else {
17890 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
17891 }
17892 current$$1.nextEffect = null;
17893 current$$1.effectTag = Deletion;
17894
17895 popSuspenseContext(workInProgress);
17896
17897 // Upgrade this work in progress to a real Suspense component.
17898 workInProgress.tag = SuspenseComponent;
17899 workInProgress.stateNode = null;
17900 workInProgress.memoizedState = null;
17901 // This is now an insertion.
17902 workInProgress.effectTag |= Placement;
17903 // Retry as a real Suspense component.
17904 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
17905}
17906
17907function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
17908 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
17909 var suspenseInstance = workInProgress.stateNode;
17910 if (current$$1 === null) {
17911 // During the first pass, we'll bail out and not drill into the children.
17912 // Instead, we'll leave the content in place and try to hydrate it later.
17913 if (isSuspenseInstanceFallback(suspenseInstance)) {
17914 // This is a client-only boundary. Since we won't get any content from the server
17915 // for this, we need to schedule that at a higher priority based on when it would
17916 // have timed out. In theory we could render it in this pass but it would have the
17917 // wrong priority associated with it and will prevent hydration of parent path.
17918 // Instead, we'll leave work left on it to render it in a separate commit.
17919
17920 // TODO This time should be the time at which the server rendered response that is
17921 // a parent to this boundary was displayed. However, since we currently don't have
17922 // a protocol to transfer that time, we'll just estimate it by using the current
17923 // time. This will mean that Suspense timeouts are slightly shifted to later than
17924 // they should be.
17925 var serverDisplayTime = requestCurrentTime();
17926 // Schedule a normal pri update to render this content.
17927 workInProgress.expirationTime = computeAsyncExpiration(serverDisplayTime);
17928 } else {
17929 // We'll continue hydrating the rest at offscreen priority since we'll already
17930 // be showing the right content coming from the server, it is no rush.
17931 workInProgress.expirationTime = Never;
17932 }
17933 return null;
17934 }
17935 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
17936 // Something suspended. Leave the existing children in place.
17937 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
17938 workInProgress.child = null;
17939 return null;
17940 }
17941 if (isSuspenseInstanceFallback(suspenseInstance)) {
17942 // This boundary is in a permanent fallback state. In this case, we'll never
17943 // get an update and we'll never be able to hydrate the final content. Let's just try the
17944 // client side render instead.
17945 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
17946 }
17947 // We use childExpirationTime to indicate that a child might depend on context, so if
17948 // any context has changed, we need to treat is as if the input might have changed.
17949 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
17950 if (didReceiveUpdate || hasContextChanged$$1) {
17951 // This boundary has changed since the first render. This means that we are now unable to
17952 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
17953 // during this render we can't. Instead, we're going to delete the whole subtree and
17954 // instead inject a new real Suspense boundary to take its place, which may render content
17955 // or fallback. The real Suspense boundary will suspend for a while so we have some time
17956 // to ensure it can produce real content, but all state and pending events will be lost.
17957 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
17958 } else if (isSuspenseInstancePending(suspenseInstance)) {
17959 // This component is still pending more data from the server, so we can't hydrate its
17960 // content. We treat it as if this component suspended itself. It might seem as if
17961 // we could just try to render it client-side instead. However, this will perform a
17962 // lot of unnecessary work and is unlikely to complete since it often will suspend
17963 // on missing data anyway. Additionally, the server might be able to render more
17964 // than we can on the client yet. In that case we'd end up with more fallback states
17965 // on the client than if we just leave it alone. If the server times out or errors
17966 // these should update this boundary to the permanent Fallback state instead.
17967 // Mark it as having captured (i.e. suspended).
17968 workInProgress.effectTag |= DidCapture;
17969 // Leave the children in place. I.e. empty.
17970 workInProgress.child = null;
17971 // Register a callback to retry this boundary once the server has sent the result.
17972 registerSuspenseInstanceRetry(suspenseInstance, retryTimedOutBoundary.bind(null, current$$1));
17973 return null;
17974 } else {
17975 // This is the first attempt.
17976 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
17977 var nextProps = workInProgress.pendingProps;
17978 var nextChildren = nextProps.children;
17979 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
17980 return workInProgress.child;
17981 }
17982}
17983
17984function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
17985 // Mark any Suspense boundaries with fallbacks as having work to do.
17986 // If they were previously forced into fallbacks, they may now be able
17987 // to unblock.
17988 var node = firstChild;
17989 while (node !== null) {
17990 if (node.tag === SuspenseComponent) {
17991 var state = node.memoizedState;
17992 if (state !== null) {
17993 if (node.expirationTime < renderExpirationTime) {
17994 node.expirationTime = renderExpirationTime;
17995 }
17996 var alternate = node.alternate;
17997 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
17998 alternate.expirationTime = renderExpirationTime;
17999 }
18000 scheduleWorkOnParentPath(node.return, renderExpirationTime);
18001 }
18002 } else if (node.child !== null) {
18003 node.child.return = node;
18004 node = node.child;
18005 continue;
18006 }
18007 if (node === workInProgress) {
18008 return;
18009 }
18010 while (node.sibling === null) {
18011 if (node.return === null || node.return === workInProgress) {
18012 return;
18013 }
18014 node = node.return;
18015 }
18016 node.sibling.return = node.return;
18017 node = node.sibling;
18018 }
18019}
18020
18021function findLastContentRow(firstChild) {
18022 // This is going to find the last row among these children that is already
18023 // showing content on the screen, as opposed to being in fallback state or
18024 // new. If a row has multiple Suspense boundaries, any of them being in the
18025 // fallback state, counts as the whole row being in a fallback state.
18026 // Note that the "rows" will be workInProgress, but any nested children
18027 // will still be current since we haven't rendered them yet. The mounted
18028 // order may not be the same as the new order. We use the new order.
18029 var row = firstChild;
18030 var lastContentRow = null;
18031 while (row !== null) {
18032 var currentRow = row.alternate;
18033 // New rows can't be content rows.
18034 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18035 lastContentRow = row;
18036 }
18037 row = row.sibling;
18038 }
18039 return lastContentRow;
18040}
18041
18042function validateRevealOrder(revealOrder) {
18043 {
18044 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
18045 didWarnAboutRevealOrder[revealOrder] = true;
18046 if (typeof revealOrder === 'string') {
18047 switch (revealOrder.toLowerCase()) {
18048 case 'together':
18049 case 'forwards':
18050 case 'backwards':
18051 {
18052 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
18053 break;
18054 }
18055 case 'forward':
18056 case 'backward':
18057 {
18058 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
18059 break;
18060 }
18061 default:
18062 warning$1(false, '"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18063 break;
18064 }
18065 } else {
18066 warning$1(false, '%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
18067 }
18068 }
18069 }
18070}
18071
18072function validateTailOptions(tailMode, revealOrder) {
18073 {
18074 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
18075 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
18076 didWarnAboutTailOptions[tailMode] = true;
18077 warning$1(false, '"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
18078 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
18079 didWarnAboutTailOptions[tailMode] = true;
18080 warning$1(false, '<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
18081 }
18082 }
18083 }
18084}
18085
18086function validateSuspenseListNestedChild(childSlot, index) {
18087 {
18088 var isArray = Array.isArray(childSlot);
18089 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
18090 if (isArray || isIterable) {
18091 var type = isArray ? 'array' : 'iterable';
18092 warning$1(false, '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);
18093 return false;
18094 }
18095 }
18096 return true;
18097}
18098
18099function validateSuspenseListChildren(children, revealOrder) {
18100 {
18101 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
18102 if (Array.isArray(children)) {
18103 for (var i = 0; i < children.length; i++) {
18104 if (!validateSuspenseListNestedChild(children[i], i)) {
18105 return;
18106 }
18107 }
18108 } else {
18109 var iteratorFn = getIteratorFn(children);
18110 if (typeof iteratorFn === 'function') {
18111 var childrenIterator = iteratorFn.call(children);
18112 if (childrenIterator) {
18113 var step = childrenIterator.next();
18114 var _i = 0;
18115 for (; !step.done; step = childrenIterator.next()) {
18116 if (!validateSuspenseListNestedChild(step.value, _i)) {
18117 return;
18118 }
18119 _i++;
18120 }
18121 }
18122 } else {
18123 warning$1(false, '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);
18124 }
18125 }
18126 }
18127 }
18128}
18129
18130function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
18131 var renderState = workInProgress.memoizedState;
18132 if (renderState === null) {
18133 workInProgress.memoizedState = {
18134 isBackwards: isBackwards,
18135 rendering: null,
18136 last: lastContentRow,
18137 tail: tail,
18138 tailExpiration: 0,
18139 tailMode: tailMode
18140 };
18141 } else {
18142 // We can reuse the existing object from previous renders.
18143 renderState.isBackwards = isBackwards;
18144 renderState.rendering = null;
18145 renderState.last = lastContentRow;
18146 renderState.tail = tail;
18147 renderState.tailExpiration = 0;
18148 renderState.tailMode = tailMode;
18149 }
18150}
18151
18152// This can end up rendering this component multiple passes.
18153// The first pass splits the children fibers into two sets. A head and tail.
18154// We first render the head. If anything is in fallback state, we do another
18155// pass through beginWork to rerender all children (including the tail) with
18156// the force suspend context. If the first render didn't have anything in
18157// in fallback state. Then we render each row in the tail one-by-one.
18158// That happens in the completeWork phase without going back to beginWork.
18159function updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime) {
18160 var nextProps = workInProgress.pendingProps;
18161 var revealOrder = nextProps.revealOrder;
18162 var tailMode = nextProps.tail;
18163 var newChildren = nextProps.children;
18164
18165 validateRevealOrder(revealOrder);
18166 validateTailOptions(tailMode, revealOrder);
18167 validateSuspenseListChildren(newChildren, revealOrder);
18168
18169 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
18170
18171 var suspenseContext = suspenseStackCursor.current;
18172
18173 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
18174 if (shouldForceFallback) {
18175 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
18176 workInProgress.effectTag |= DidCapture;
18177 } else {
18178 var didSuspendBefore = current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect;
18179 if (didSuspendBefore) {
18180 // If we previously forced a fallback, we need to schedule work
18181 // on any nested boundaries to let them know to try to render
18182 // again. This is the same as context updating.
18183 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
18184 }
18185 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
18186 }
18187 pushSuspenseContext(workInProgress, suspenseContext);
18188
18189 if ((workInProgress.mode & BatchedMode) === NoMode) {
18190 // Outside of batched mode, SuspenseList doesn't work so we just
18191 // use make it a noop by treating it as the default revealOrder.
18192 workInProgress.memoizedState = null;
18193 } else {
18194 switch (revealOrder) {
18195 case 'forwards':
18196 {
18197 var lastContentRow = findLastContentRow(workInProgress.child);
18198 var tail = void 0;
18199 if (lastContentRow === null) {
18200 // The whole list is part of the tail.
18201 // TODO: We could fast path by just rendering the tail now.
18202 tail = workInProgress.child;
18203 workInProgress.child = null;
18204 } else {
18205 // Disconnect the tail rows after the content row.
18206 // We're going to render them separately later.
18207 tail = lastContentRow.sibling;
18208 lastContentRow.sibling = null;
18209 }
18210 initSuspenseListRenderState(workInProgress, false, // isBackwards
18211 tail, lastContentRow, tailMode);
18212 break;
18213 }
18214 case 'backwards':
18215 {
18216 // We're going to find the first row that has existing content.
18217 // At the same time we're going to reverse the list of everything
18218 // we pass in the meantime. That's going to be our tail in reverse
18219 // order.
18220 var _tail = null;
18221 var row = workInProgress.child;
18222 workInProgress.child = null;
18223 while (row !== null) {
18224 var currentRow = row.alternate;
18225 // New rows can't be content rows.
18226 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
18227 // This is the beginning of the main content.
18228 workInProgress.child = row;
18229 break;
18230 }
18231 var nextRow = row.sibling;
18232 row.sibling = _tail;
18233 _tail = row;
18234 row = nextRow;
18235 }
18236 // TODO: If workInProgress.child is null, we can continue on the tail immediately.
18237 initSuspenseListRenderState(workInProgress, true, // isBackwards
18238 _tail, null, // last
18239 tailMode);
18240 break;
18241 }
18242 case 'together':
18243 {
18244 initSuspenseListRenderState(workInProgress, false, // isBackwards
18245 null, // tail
18246 null, // last
18247 undefined);
18248 break;
18249 }
18250 default:
18251 {
18252 // The default reveal order is the same as not having
18253 // a boundary.
18254 workInProgress.memoizedState = null;
18255 }
18256 }
18257 }
18258 return workInProgress.child;
18259}
18260
18261function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
18262 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18263 var nextChildren = workInProgress.pendingProps;
18264 if (current$$1 === null) {
18265 // Portals are special because we don't append the children during mount
18266 // but at commit. Therefore we need to track insertions which the normal
18267 // flow doesn't do during mount. This doesn't happen at the root because
18268 // the root always starts with a "current" with a null child.
18269 // TODO: Consider unifying this with how the root works.
18270 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
18271 } else {
18272 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18273 }
18274 return workInProgress.child;
18275}
18276
18277function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
18278 var providerType = workInProgress.type;
18279 var context = providerType._context;
18280
18281 var newProps = workInProgress.pendingProps;
18282 var oldProps = workInProgress.memoizedProps;
18283
18284 var newValue = newProps.value;
18285
18286 {
18287 var providerPropTypes = workInProgress.type.propTypes;
18288
18289 if (providerPropTypes) {
18290 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
18291 }
18292 }
18293
18294 pushProvider(workInProgress, newValue);
18295
18296 if (oldProps !== null) {
18297 var oldValue = oldProps.value;
18298 var changedBits = calculateChangedBits(context, newValue, oldValue);
18299 if (changedBits === 0) {
18300 // No change. Bailout early if children are the same.
18301 if (oldProps.children === newProps.children && !hasContextChanged()) {
18302 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18303 }
18304 } else {
18305 // The context value changed. Search for matching consumers and schedule
18306 // them to update.
18307 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
18308 }
18309 }
18310
18311 var newChildren = newProps.children;
18312 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
18313 return workInProgress.child;
18314}
18315
18316var hasWarnedAboutUsingContextAsConsumer = false;
18317
18318function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
18319 var context = workInProgress.type;
18320 // The logic below for Context differs depending on PROD or DEV mode. In
18321 // DEV mode, we create a separate object for Context.Consumer that acts
18322 // like a proxy to Context. This proxy object adds unnecessary code in PROD
18323 // so we use the old behaviour (Context.Consumer references Context) to
18324 // reduce size and overhead. The separate object references context via
18325 // a property called "_context", which also gives us the ability to check
18326 // in DEV mode if this property exists or not and warn if it does not.
18327 {
18328 if (context._context === undefined) {
18329 // This may be because it's a Context (rather than a Consumer).
18330 // Or it may be because it's older React where they're the same thing.
18331 // We only want to warn if we're sure it's a new React.
18332 if (context !== context.Consumer) {
18333 if (!hasWarnedAboutUsingContextAsConsumer) {
18334 hasWarnedAboutUsingContextAsConsumer = true;
18335 warning$1(false, 'Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
18336 }
18337 }
18338 } else {
18339 context = context._context;
18340 }
18341 }
18342 var newProps = workInProgress.pendingProps;
18343 var render = newProps.children;
18344
18345 {
18346 !(typeof render === 'function') ? warningWithoutStack$1(false, '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.') : void 0;
18347 }
18348
18349 prepareToReadContext(workInProgress, renderExpirationTime);
18350 var newValue = readContext(context, newProps.unstable_observedBits);
18351 var newChildren = void 0;
18352 {
18353 ReactCurrentOwner$3.current = workInProgress;
18354 setCurrentPhase('render');
18355 newChildren = render(newValue);
18356 setCurrentPhase(null);
18357 }
18358
18359 // React DevTools reads this flag.
18360 workInProgress.effectTag |= PerformedWork;
18361 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
18362 return workInProgress.child;
18363}
18364
18365function updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime) {
18366 var fundamentalImpl = workInProgress.type.impl;
18367 if (fundamentalImpl.reconcileChildren === false) {
18368 return null;
18369 }
18370 var nextProps = workInProgress.pendingProps;
18371 var nextChildren = nextProps.children;
18372
18373 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18374 return workInProgress.child;
18375}
18376
18377function markWorkInProgressReceivedUpdate() {
18378 didReceiveUpdate = true;
18379}
18380
18381function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
18382 cancelWorkTimer(workInProgress);
18383
18384 if (current$$1 !== null) {
18385 // Reuse previous dependencies
18386 workInProgress.dependencies = current$$1.dependencies;
18387 }
18388
18389 if (enableProfilerTimer) {
18390 // Don't update "base" render times for bailouts.
18391 stopProfilerTimerIfRunning(workInProgress);
18392 }
18393
18394 // Check if the children have any pending work.
18395 var childExpirationTime = workInProgress.childExpirationTime;
18396 if (childExpirationTime < renderExpirationTime) {
18397 // The children don't have any work either. We can skip them.
18398 // TODO: Once we add back resuming, we should check if the children are
18399 // a work-in-progress set. If so, we need to transfer their effects.
18400 return null;
18401 } else {
18402 // This fiber doesn't have work, but its subtree does. Clone the child
18403 // fibers and continue.
18404 cloneChildFibers(current$$1, workInProgress);
18405 return workInProgress.child;
18406 }
18407}
18408
18409function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) {
18410 {
18411 var returnFiber = oldWorkInProgress.return;
18412 if (returnFiber === null) {
18413 throw new Error('Cannot swap the root fiber.');
18414 }
18415
18416 // Disconnect from the old current.
18417 // It will get deleted.
18418 current$$1.alternate = null;
18419 oldWorkInProgress.alternate = null;
18420
18421 // Connect to the new tree.
18422 newWorkInProgress.index = oldWorkInProgress.index;
18423 newWorkInProgress.sibling = oldWorkInProgress.sibling;
18424 newWorkInProgress.return = oldWorkInProgress.return;
18425 newWorkInProgress.ref = oldWorkInProgress.ref;
18426
18427 // Replace the child/sibling pointers above it.
18428 if (oldWorkInProgress === returnFiber.child) {
18429 returnFiber.child = newWorkInProgress;
18430 } else {
18431 var prevSibling = returnFiber.child;
18432 if (prevSibling === null) {
18433 throw new Error('Expected parent to have a child.');
18434 }
18435 while (prevSibling.sibling !== oldWorkInProgress) {
18436 prevSibling = prevSibling.sibling;
18437 if (prevSibling === null) {
18438 throw new Error('Expected to find the previous sibling.');
18439 }
18440 }
18441 prevSibling.sibling = newWorkInProgress;
18442 }
18443
18444 // Delete the old fiber and place the new one.
18445 // Since the old fiber is disconnected, we have to schedule it manually.
18446 var last = returnFiber.lastEffect;
18447 if (last !== null) {
18448 last.nextEffect = current$$1;
18449 returnFiber.lastEffect = current$$1;
18450 } else {
18451 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
18452 }
18453 current$$1.nextEffect = null;
18454 current$$1.effectTag = Deletion;
18455
18456 newWorkInProgress.effectTag |= Placement;
18457
18458 // Restart work from the new fiber.
18459 return newWorkInProgress;
18460 }
18461}
18462
18463function beginWork$1(current$$1, workInProgress, renderExpirationTime) {
18464 var updateExpirationTime = workInProgress.expirationTime;
18465
18466 {
18467 if (workInProgress._debugNeedsRemount && current$$1 !== null) {
18468 // This will restart the begin phase with a new fiber.
18469 return remountFiber(current$$1, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
18470 }
18471 }
18472
18473 if (current$$1 !== null) {
18474 var oldProps = current$$1.memoizedProps;
18475 var newProps = workInProgress.pendingProps;
18476
18477 if (oldProps !== newProps || hasContextChanged() || (
18478 // Force a re-render if the implementation changed due to hot reload:
18479 workInProgress.type !== current$$1.type)) {
18480 // If props or context changed, mark the fiber as having performed work.
18481 // This may be unset if the props are determined to be equal later (memo).
18482 didReceiveUpdate = true;
18483 } else if (updateExpirationTime < renderExpirationTime) {
18484 didReceiveUpdate = false;
18485 // This fiber does not have any pending work. Bailout without entering
18486 // the begin phase. There's still some bookkeeping we that needs to be done
18487 // in this optimized path, mostly pushing stuff onto the stack.
18488 switch (workInProgress.tag) {
18489 case HostRoot:
18490 pushHostRootContext(workInProgress);
18491 resetHydrationState();
18492 break;
18493 case HostComponent:
18494 pushHostContext(workInProgress);
18495 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
18496 if (enableSchedulerTracing) {
18497 markSpawnedWork(Never);
18498 }
18499 // Schedule this fiber to re-render at offscreen priority. Then bailout.
18500 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
18501 return null;
18502 }
18503 break;
18504 case ClassComponent:
18505 {
18506 var Component = workInProgress.type;
18507 if (isContextProvider(Component)) {
18508 pushContextProvider(workInProgress);
18509 }
18510 break;
18511 }
18512 case HostPortal:
18513 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
18514 break;
18515 case ContextProvider:
18516 {
18517 var newValue = workInProgress.memoizedProps.value;
18518 pushProvider(workInProgress, newValue);
18519 break;
18520 }
18521 case Profiler:
18522 if (enableProfilerTimer) {
18523 workInProgress.effectTag |= Update;
18524 }
18525 break;
18526 case SuspenseComponent:
18527 {
18528 var state = workInProgress.memoizedState;
18529 var didTimeout = state !== null;
18530 if (didTimeout) {
18531 // If this boundary is currently timed out, we need to decide
18532 // whether to retry the primary children, or to skip over it and
18533 // go straight to the fallback. Check the priority of the primary
18534 var primaryChildFragment = workInProgress.child;
18535 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
18536 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
18537 // The primary children have pending work. Use the normal path
18538 // to attempt to render the primary children again.
18539 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
18540 } else {
18541 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18542 // The primary children do not have pending work with sufficient
18543 // priority. Bailout.
18544 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18545 if (child !== null) {
18546 // The fallback children have pending work. Skip over the
18547 // primary children and work on the fallback.
18548 return child.sibling;
18549 } else {
18550 return null;
18551 }
18552 }
18553 } else {
18554 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18555 }
18556 break;
18557 }
18558 case DehydratedSuspenseComponent:
18559 {
18560 if (enableSuspenseServerRenderer) {
18561 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
18562 // We know that this component will suspend again because if it has
18563 // been unsuspended it has committed as a regular Suspense component.
18564 // If it needs to be retried, it should have work scheduled on it.
18565 workInProgress.effectTag |= DidCapture;
18566 }
18567 break;
18568 }
18569 case SuspenseListComponent:
18570 {
18571 var didSuspendBefore = (current$$1.effectTag & DidCapture) !== NoEffect;
18572
18573 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
18574
18575 if (didSuspendBefore) {
18576 if (hasChildWork) {
18577 // If something was in fallback state last time, and we have all the
18578 // same children then we're still in progressive loading state.
18579 // Something might get unblocked by state updates or retries in the
18580 // tree which will affect the tail. So we need to use the normal
18581 // path to compute the correct tail.
18582 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
18583 }
18584 // If none of the children had any work, that means that none of
18585 // them got retried so they'll still be blocked in the same way
18586 // as before. We can fast bail out.
18587 workInProgress.effectTag |= DidCapture;
18588 }
18589
18590 // If nothing suspended before and we're rendering the same children,
18591 // then the tail doesn't matter. Anything new that suspends will work
18592 // in the "together" mode, so we can continue from the state we had.
18593 var renderState = workInProgress.memoizedState;
18594 if (renderState !== null) {
18595 // Reset to the "together" mode in case we've started a different
18596 // update in the past but didn't complete it.
18597 renderState.rendering = null;
18598 renderState.tail = null;
18599 }
18600 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
18601
18602 if (hasChildWork) {
18603 break;
18604 } else {
18605 // If none of the children had any work, that means that none of
18606 // them got retried so they'll still be blocked in the same way
18607 // as before. We can fast bail out.
18608 return null;
18609 }
18610 }
18611 }
18612 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18613 }
18614 } else {
18615 didReceiveUpdate = false;
18616 }
18617
18618 // Before entering the begin phase, clear the expiration time.
18619 workInProgress.expirationTime = NoWork;
18620
18621 switch (workInProgress.tag) {
18622 case IndeterminateComponent:
18623 {
18624 return mountIndeterminateComponent(current$$1, workInProgress, workInProgress.type, renderExpirationTime);
18625 }
18626 case LazyComponent:
18627 {
18628 var elementType = workInProgress.elementType;
18629 return mountLazyComponent(current$$1, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
18630 }
18631 case FunctionComponent:
18632 {
18633 var _Component = workInProgress.type;
18634 var unresolvedProps = workInProgress.pendingProps;
18635 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
18636 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
18637 }
18638 case ClassComponent:
18639 {
18640 var _Component2 = workInProgress.type;
18641 var _unresolvedProps = workInProgress.pendingProps;
18642 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
18643 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
18644 }
18645 case HostRoot:
18646 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
18647 case HostComponent:
18648 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
18649 case HostText:
18650 return updateHostText(current$$1, workInProgress);
18651 case SuspenseComponent:
18652 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
18653 case HostPortal:
18654 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
18655 case ForwardRef:
18656 {
18657 var type = workInProgress.type;
18658 var _unresolvedProps2 = workInProgress.pendingProps;
18659 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
18660 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
18661 }
18662 case Fragment:
18663 return updateFragment(current$$1, workInProgress, renderExpirationTime);
18664 case Mode:
18665 return updateMode(current$$1, workInProgress, renderExpirationTime);
18666 case Profiler:
18667 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
18668 case ContextProvider:
18669 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
18670 case ContextConsumer:
18671 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
18672 case MemoComponent:
18673 {
18674 var _type2 = workInProgress.type;
18675 var _unresolvedProps3 = workInProgress.pendingProps;
18676 // Resolve outer props first, then resolve inner props.
18677 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
18678 {
18679 if (workInProgress.type !== workInProgress.elementType) {
18680 var outerPropTypes = _type2.propTypes;
18681 if (outerPropTypes) {
18682 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
18683 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
18684 }
18685 }
18686 }
18687 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
18688 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
18689 }
18690 case SimpleMemoComponent:
18691 {
18692 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
18693 }
18694 case IncompleteClassComponent:
18695 {
18696 var _Component3 = workInProgress.type;
18697 var _unresolvedProps4 = workInProgress.pendingProps;
18698 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
18699 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
18700 }
18701 case DehydratedSuspenseComponent:
18702 {
18703 if (enableSuspenseServerRenderer) {
18704 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
18705 }
18706 break;
18707 }
18708 case SuspenseListComponent:
18709 {
18710 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
18711 }
18712 case FundamentalComponent:
18713 {
18714 if (enableFundamentalAPI) {
18715 return updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime);
18716 }
18717 break;
18718 }
18719 }
18720 (function () {
18721 {
18722 {
18723 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
18724 }
18725 }
18726 })();
18727}
18728
18729function createFundamentalStateInstance(currentFiber, props, impl, state) {
18730 return {
18731 currentFiber: currentFiber,
18732 impl: impl,
18733 instance: null,
18734 prevProps: null,
18735 props: props,
18736 state: state
18737 };
18738}
18739
18740var emptyObject = {};
18741var isArray$2 = Array.isArray;
18742
18743function markUpdate(workInProgress) {
18744 // Tag the fiber with an update effect. This turns a Placement into
18745 // a PlacementAndUpdate.
18746 workInProgress.effectTag |= Update;
18747}
18748
18749function markRef$1(workInProgress) {
18750 workInProgress.effectTag |= Ref;
18751}
18752
18753var appendAllChildren = void 0;
18754var updateHostContainer = void 0;
18755var updateHostComponent$1 = void 0;
18756var updateHostText$1 = void 0;
18757if (supportsMutation) {
18758 // Mutation mode
18759
18760 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
18761 // We only have the top Fiber that was created but we need recurse down its
18762 // children to find all the terminal nodes.
18763 var node = workInProgress.child;
18764 while (node !== null) {
18765 if (node.tag === HostComponent || node.tag === HostText) {
18766 appendInitialChild(parent, node.stateNode);
18767 } else if (node.tag === FundamentalComponent) {
18768 appendInitialChild(parent, node.stateNode.instance);
18769 } else if (node.tag === HostPortal) {
18770 // If we have a portal child, then we don't want to traverse
18771 // down its children. Instead, we'll get insertions from each child in
18772 // the portal directly.
18773 } else if (node.child !== null) {
18774 node.child.return = node;
18775 node = node.child;
18776 continue;
18777 }
18778 if (node === workInProgress) {
18779 return;
18780 }
18781 while (node.sibling === null) {
18782 if (node.return === null || node.return === workInProgress) {
18783 return;
18784 }
18785 node = node.return;
18786 }
18787 node.sibling.return = node.return;
18788 node = node.sibling;
18789 }
18790 };
18791
18792 updateHostContainer = function (workInProgress) {
18793 // Noop
18794 };
18795 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
18796 // If we have an alternate, that means this is an update and we need to
18797 // schedule a side-effect to do the updates.
18798 var oldProps = current.memoizedProps;
18799 if (oldProps === newProps) {
18800 // In mutation mode, this is sufficient for a bailout because
18801 // we won't touch this node even if children changed.
18802 return;
18803 }
18804
18805 // If we get updated because one of our children updated, we don't
18806 // have newProps so we'll have to reuse them.
18807 // TODO: Split the update API as separate for the props vs. children.
18808 // Even better would be if children weren't special cased at all tho.
18809 var instance = workInProgress.stateNode;
18810 var currentHostContext = getHostContext();
18811 // TODO: Experiencing an error where oldProps is null. Suggests a host
18812 // component is hitting the resume path. Figure out why. Possibly
18813 // related to `hidden`.
18814 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
18815 // TODO: Type this specific to this type of component.
18816 workInProgress.updateQueue = updatePayload;
18817 // If the update payload indicates that there is a change or if there
18818 // is a new ref we mark this as an update. All the work is done in commitWork.
18819 if (updatePayload) {
18820 markUpdate(workInProgress);
18821 }
18822 };
18823 updateHostText$1 = function (current, workInProgress, oldText, newText) {
18824 // If the text differs, mark it as an update. All the work in done in commitWork.
18825 if (oldText !== newText) {
18826 markUpdate(workInProgress);
18827 }
18828 };
18829} else if (supportsPersistence) {
18830 // Persistent host tree mode
18831
18832 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
18833 // We only have the top Fiber that was created but we need recurse down its
18834 // children to find all the terminal nodes.
18835 var node = workInProgress.child;
18836 while (node !== null) {
18837 // eslint-disable-next-line no-labels
18838 branches: if (node.tag === HostComponent) {
18839 var instance = node.stateNode;
18840 if (needsVisibilityToggle && isHidden) {
18841 // This child is inside a timed out tree. Hide it.
18842 var props = node.memoizedProps;
18843 var type = node.type;
18844 instance = cloneHiddenInstance(instance, type, props, node);
18845 }
18846 appendInitialChild(parent, instance);
18847 } else if (node.tag === HostText) {
18848 var _instance = node.stateNode;
18849 if (needsVisibilityToggle && isHidden) {
18850 // This child is inside a timed out tree. Hide it.
18851 var text = node.memoizedProps;
18852 _instance = cloneHiddenTextInstance(_instance, text, node);
18853 }
18854 appendInitialChild(parent, _instance);
18855 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
18856 var _instance2 = node.stateNode.instance;
18857 if (needsVisibilityToggle && isHidden) {
18858 // This child is inside a timed out tree. Hide it.
18859 var _props = node.memoizedProps;
18860 var _type = node.type;
18861 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
18862 }
18863 appendInitialChild(parent, _instance2);
18864 } else if (node.tag === HostPortal) {
18865 // If we have a portal child, then we don't want to traverse
18866 // down its children. Instead, we'll get insertions from each child in
18867 // the portal directly.
18868 } else if (node.tag === SuspenseComponent) {
18869 if ((node.effectTag & Update) !== NoEffect) {
18870 // Need to toggle the visibility of the primary children.
18871 var newIsHidden = node.memoizedState !== null;
18872 if (newIsHidden) {
18873 var primaryChildParent = node.child;
18874 if (primaryChildParent !== null) {
18875 if (primaryChildParent.child !== null) {
18876 primaryChildParent.child.return = primaryChildParent;
18877 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
18878 }
18879 var fallbackChildParent = primaryChildParent.sibling;
18880 if (fallbackChildParent !== null) {
18881 fallbackChildParent.return = node;
18882 node = fallbackChildParent;
18883 continue;
18884 }
18885 }
18886 }
18887 }
18888 if (node.child !== null) {
18889 // Continue traversing like normal
18890 node.child.return = node;
18891 node = node.child;
18892 continue;
18893 }
18894 } else if (node.child !== null) {
18895 node.child.return = node;
18896 node = node.child;
18897 continue;
18898 }
18899 // $FlowFixMe This is correct but Flow is confused by the labeled break.
18900 node = node;
18901 if (node === workInProgress) {
18902 return;
18903 }
18904 while (node.sibling === null) {
18905 if (node.return === null || node.return === workInProgress) {
18906 return;
18907 }
18908 node = node.return;
18909 }
18910 node.sibling.return = node.return;
18911 node = node.sibling;
18912 }
18913 };
18914
18915 // An unfortunate fork of appendAllChildren because we have two different parent types.
18916 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
18917 // We only have the top Fiber that was created but we need recurse down its
18918 // children to find all the terminal nodes.
18919 var node = workInProgress.child;
18920 while (node !== null) {
18921 // eslint-disable-next-line no-labels
18922 branches: if (node.tag === HostComponent) {
18923 var instance = node.stateNode;
18924 if (needsVisibilityToggle && isHidden) {
18925 // This child is inside a timed out tree. Hide it.
18926 var props = node.memoizedProps;
18927 var type = node.type;
18928 instance = cloneHiddenInstance(instance, type, props, node);
18929 }
18930 appendChildToContainerChildSet(containerChildSet, instance);
18931 } else if (node.tag === HostText) {
18932 var _instance3 = node.stateNode;
18933 if (needsVisibilityToggle && isHidden) {
18934 // This child is inside a timed out tree. Hide it.
18935 var text = node.memoizedProps;
18936 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
18937 }
18938 appendChildToContainerChildSet(containerChildSet, _instance3);
18939 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
18940 var _instance4 = node.stateNode.instance;
18941 if (needsVisibilityToggle && isHidden) {
18942 // This child is inside a timed out tree. Hide it.
18943 var _props2 = node.memoizedProps;
18944 var _type2 = node.type;
18945 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
18946 }
18947 appendChildToContainerChildSet(containerChildSet, _instance4);
18948 } else if (node.tag === HostPortal) {
18949 // If we have a portal child, then we don't want to traverse
18950 // down its children. Instead, we'll get insertions from each child in
18951 // the portal directly.
18952 } else if (node.tag === SuspenseComponent) {
18953 if ((node.effectTag & Update) !== NoEffect) {
18954 // Need to toggle the visibility of the primary children.
18955 var newIsHidden = node.memoizedState !== null;
18956 if (newIsHidden) {
18957 var primaryChildParent = node.child;
18958 if (primaryChildParent !== null) {
18959 if (primaryChildParent.child !== null) {
18960 primaryChildParent.child.return = primaryChildParent;
18961 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
18962 }
18963 var fallbackChildParent = primaryChildParent.sibling;
18964 if (fallbackChildParent !== null) {
18965 fallbackChildParent.return = node;
18966 node = fallbackChildParent;
18967 continue;
18968 }
18969 }
18970 }
18971 }
18972 if (node.child !== null) {
18973 // Continue traversing like normal
18974 node.child.return = node;
18975 node = node.child;
18976 continue;
18977 }
18978 } else if (node.child !== null) {
18979 node.child.return = node;
18980 node = node.child;
18981 continue;
18982 }
18983 // $FlowFixMe This is correct but Flow is confused by the labeled break.
18984 node = node;
18985 if (node === workInProgress) {
18986 return;
18987 }
18988 while (node.sibling === null) {
18989 if (node.return === null || node.return === workInProgress) {
18990 return;
18991 }
18992 node = node.return;
18993 }
18994 node.sibling.return = node.return;
18995 node = node.sibling;
18996 }
18997 };
18998 updateHostContainer = function (workInProgress) {
18999 var portalOrRoot = workInProgress.stateNode;
19000 var childrenUnchanged = workInProgress.firstEffect === null;
19001 if (childrenUnchanged) {
19002 // No changes, just reuse the existing instance.
19003 } else {
19004 var container = portalOrRoot.containerInfo;
19005 var newChildSet = createContainerChildSet(container);
19006 // If children might have changed, we have to add them all to the set.
19007 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
19008 portalOrRoot.pendingChildren = newChildSet;
19009 // Schedule an update on the container to swap out the container.
19010 markUpdate(workInProgress);
19011 finalizeContainerChildren(container, newChildSet);
19012 }
19013 };
19014 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
19015 var currentInstance = current.stateNode;
19016 var oldProps = current.memoizedProps;
19017 // If there are no effects associated with this node, then none of our children had any updates.
19018 // This guarantees that we can reuse all of them.
19019 var childrenUnchanged = workInProgress.firstEffect === null;
19020 if (childrenUnchanged && oldProps === newProps) {
19021 // No changes, just reuse the existing instance.
19022 // Note that this might release a previous clone.
19023 workInProgress.stateNode = currentInstance;
19024 return;
19025 }
19026 var recyclableInstance = workInProgress.stateNode;
19027 var currentHostContext = getHostContext();
19028 var updatePayload = null;
19029 if (oldProps !== newProps) {
19030 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
19031 }
19032 if (childrenUnchanged && updatePayload === null) {
19033 // No changes, just reuse the existing instance.
19034 // Note that this might release a previous clone.
19035 workInProgress.stateNode = currentInstance;
19036 return;
19037 }
19038 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
19039 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
19040 markUpdate(workInProgress);
19041 }
19042 workInProgress.stateNode = newInstance;
19043 if (childrenUnchanged) {
19044 // If there are no other effects in this tree, we need to flag this node as having one.
19045 // Even though we're not going to use it for anything.
19046 // Otherwise parents won't know that there are new children to propagate upwards.
19047 markUpdate(workInProgress);
19048 } else {
19049 // If children might have changed, we have to add them all to the set.
19050 appendAllChildren(newInstance, workInProgress, false, false);
19051 }
19052 };
19053 updateHostText$1 = function (current, workInProgress, oldText, newText) {
19054 if (oldText !== newText) {
19055 // If the text content differs, we'll create a new text instance for it.
19056 var rootContainerInstance = getRootHostContainer();
19057 var currentHostContext = getHostContext();
19058 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
19059 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
19060 // This lets the parents know that at least one of their children has changed.
19061 markUpdate(workInProgress);
19062 }
19063 };
19064} else {
19065 // No host operations
19066 updateHostContainer = function (workInProgress) {
19067 // Noop
19068 };
19069 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
19070 // Noop
19071 };
19072 updateHostText$1 = function (current, workInProgress, oldText, newText) {
19073 // Noop
19074 };
19075}
19076
19077function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
19078 switch (renderState.tailMode) {
19079 case 'hidden':
19080 {
19081 // Any insertions at the end of the tail list after this point
19082 // should be invisible. If there are already mounted boundaries
19083 // anything before them are not considered for collapsing.
19084 // Therefore we need to go through the whole tail to find if
19085 // there are any.
19086 var tailNode = renderState.tail;
19087 var lastTailNode = null;
19088 while (tailNode !== null) {
19089 if (tailNode.alternate !== null) {
19090 lastTailNode = tailNode;
19091 }
19092 tailNode = tailNode.sibling;
19093 }
19094 // Next we're simply going to delete all insertions after the
19095 // last rendered item.
19096 if (lastTailNode === null) {
19097 // All remaining items in the tail are insertions.
19098 renderState.tail = null;
19099 } else {
19100 // Detach the insertion after the last node that was already
19101 // inserted.
19102 lastTailNode.sibling = null;
19103 }
19104 break;
19105 }
19106 case 'collapsed':
19107 {
19108 // Any insertions at the end of the tail list after this point
19109 // should be invisible. If there are already mounted boundaries
19110 // anything before them are not considered for collapsing.
19111 // Therefore we need to go through the whole tail to find if
19112 // there are any.
19113 var _tailNode = renderState.tail;
19114 var _lastTailNode = null;
19115 while (_tailNode !== null) {
19116 if (_tailNode.alternate !== null) {
19117 _lastTailNode = _tailNode;
19118 }
19119 _tailNode = _tailNode.sibling;
19120 }
19121 // Next we're simply going to delete all insertions after the
19122 // last rendered item.
19123 if (_lastTailNode === null) {
19124 // All remaining items in the tail are insertions.
19125 if (!hasRenderedATailFallback && renderState.tail !== null) {
19126 // We suspended during the head. We want to show at least one
19127 // row at the tail. So we'll keep on and cut off the rest.
19128 renderState.tail.sibling = null;
19129 } else {
19130 renderState.tail = null;
19131 }
19132 } else {
19133 // Detach the insertion after the last node that was already
19134 // inserted.
19135 _lastTailNode.sibling = null;
19136 }
19137 break;
19138 }
19139 }
19140}
19141
19142function completeWork(current, workInProgress, renderExpirationTime) {
19143 var newProps = workInProgress.pendingProps;
19144
19145 switch (workInProgress.tag) {
19146 case IndeterminateComponent:
19147 break;
19148 case LazyComponent:
19149 break;
19150 case SimpleMemoComponent:
19151 case FunctionComponent:
19152 break;
19153 case ClassComponent:
19154 {
19155 var Component = workInProgress.type;
19156 if (isContextProvider(Component)) {
19157 popContext(workInProgress);
19158 }
19159 break;
19160 }
19161 case HostRoot:
19162 {
19163 popHostContainer(workInProgress);
19164 popTopLevelContextObject(workInProgress);
19165 var fiberRoot = workInProgress.stateNode;
19166 if (fiberRoot.pendingContext) {
19167 fiberRoot.context = fiberRoot.pendingContext;
19168 fiberRoot.pendingContext = null;
19169 }
19170 if (current === null || current.child === null) {
19171 // If we hydrated, pop so that we can delete any remaining children
19172 // that weren't hydrated.
19173 popHydrationState(workInProgress);
19174 // This resets the hacky state to fix isMounted before committing.
19175 // TODO: Delete this when we delete isMounted and findDOMNode.
19176 workInProgress.effectTag &= ~Placement;
19177 }
19178 updateHostContainer(workInProgress);
19179 break;
19180 }
19181 case HostComponent:
19182 {
19183 popHostContext(workInProgress);
19184 var rootContainerInstance = getRootHostContainer();
19185 var type = workInProgress.type;
19186 if (current !== null && workInProgress.stateNode != null) {
19187 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
19188
19189 if (enableFlareAPI) {
19190 var prevListeners = current.memoizedProps.listeners;
19191 var nextListeners = newProps.listeners;
19192 var instance = workInProgress.stateNode;
19193 if (prevListeners !== nextListeners) {
19194 updateEventListeners(nextListeners, instance, rootContainerInstance, workInProgress);
19195 }
19196 }
19197
19198 if (current.ref !== workInProgress.ref) {
19199 markRef$1(workInProgress);
19200 }
19201 } else {
19202 if (!newProps) {
19203 (function () {
19204 if (!(workInProgress.stateNode !== null)) {
19205 {
19206 throw ReactError(Error('We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.'));
19207 }
19208 }
19209 })();
19210 // This can happen when we abort work.
19211 break;
19212 }
19213
19214 var currentHostContext = getHostContext();
19215 // TODO: Move createInstance to beginWork and keep it on a context
19216 // "stack" as the parent. Then append children as we go in beginWork
19217 // or completeWork depending on we want to add then top->down or
19218 // bottom->up. Top->down is faster in IE11.
19219 var wasHydrated = popHydrationState(workInProgress);
19220 if (wasHydrated) {
19221 // TODO: Move this and createInstance step into the beginPhase
19222 // to consolidate.
19223 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
19224 // If changes to the hydrated node needs to be applied at the
19225 // commit-phase we mark this as such.
19226 markUpdate(workInProgress);
19227 }
19228 } else {
19229 var _instance5 = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
19230
19231 appendAllChildren(_instance5, workInProgress, false, false);
19232
19233 if (enableFlareAPI) {
19234 var listeners = newProps.listeners;
19235 if (listeners != null) {
19236 updateEventListeners(listeners, _instance5, rootContainerInstance, workInProgress);
19237 }
19238 }
19239
19240 // Certain renderers require commit-time effects for initial mount.
19241 // (eg DOM renderer supports auto-focus for certain elements).
19242 // Make sure such renderers get scheduled for later work.
19243 if (finalizeInitialChildren(_instance5, type, newProps, rootContainerInstance, currentHostContext)) {
19244 markUpdate(workInProgress);
19245 }
19246 workInProgress.stateNode = _instance5;
19247 }
19248
19249 if (workInProgress.ref !== null) {
19250 // If there is a ref on a host node we need to schedule a callback
19251 markRef$1(workInProgress);
19252 }
19253 }
19254 break;
19255 }
19256 case HostText:
19257 {
19258 var newText = newProps;
19259 if (current && workInProgress.stateNode != null) {
19260 var oldText = current.memoizedProps;
19261 // If we have an alternate, that means this is an update and we need
19262 // to schedule a side-effect to do the updates.
19263 updateHostText$1(current, workInProgress, oldText, newText);
19264 } else {
19265 if (typeof newText !== 'string') {
19266 (function () {
19267 if (!(workInProgress.stateNode !== null)) {
19268 {
19269 throw ReactError(Error('We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.'));
19270 }
19271 }
19272 })();
19273 // This can happen when we abort work.
19274 }
19275 var _rootContainerInstance = getRootHostContainer();
19276 var _currentHostContext = getHostContext();
19277 var _wasHydrated = popHydrationState(workInProgress);
19278 if (_wasHydrated) {
19279 if (prepareToHydrateHostTextInstance(workInProgress)) {
19280 markUpdate(workInProgress);
19281 }
19282 } else {
19283 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
19284 }
19285 }
19286 break;
19287 }
19288 case ForwardRef:
19289 break;
19290 case SuspenseComponent:
19291 {
19292 popSuspenseContext(workInProgress);
19293 var nextState = workInProgress.memoizedState;
19294 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
19295 // Something suspended. Re-render with the fallback children.
19296 workInProgress.expirationTime = renderExpirationTime;
19297 // Do not reset the effect list.
19298 return workInProgress;
19299 }
19300
19301 var nextDidTimeout = nextState !== null;
19302 var prevDidTimeout = false;
19303 if (current === null) {
19304 // In cases where we didn't find a suitable hydration boundary we never
19305 // downgraded this to a DehydratedSuspenseComponent, but we still need to
19306 // pop the hydration state since we might be inside the insertion tree.
19307 popHydrationState(workInProgress);
19308 } else {
19309 var prevState = current.memoizedState;
19310 prevDidTimeout = prevState !== null;
19311 if (!nextDidTimeout && prevState !== null) {
19312 // We just switched from the fallback to the normal children.
19313 // Delete the fallback.
19314 // TODO: Would it be better to store the fallback fragment on
19315 var currentFallbackChild = current.child.sibling;
19316 if (currentFallbackChild !== null) {
19317 // Deletions go at the beginning of the return fiber's effect list
19318 var first = workInProgress.firstEffect;
19319 if (first !== null) {
19320 workInProgress.firstEffect = currentFallbackChild;
19321 currentFallbackChild.nextEffect = first;
19322 } else {
19323 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
19324 currentFallbackChild.nextEffect = null;
19325 }
19326 currentFallbackChild.effectTag = Deletion;
19327 }
19328 }
19329 }
19330
19331 if (nextDidTimeout && !prevDidTimeout) {
19332 // If this subtreee is running in batched mode we can suspend,
19333 // otherwise we won't suspend.
19334 // TODO: This will still suspend a synchronous tree if anything
19335 // in the concurrent tree already suspended during this render.
19336 // This is a known bug.
19337 if ((workInProgress.mode & BatchedMode) !== NoMode) {
19338 // TODO: Move this back to throwException because this is too late
19339 // if this is a large tree which is common for initial loads. We
19340 // don't know if we should restart a render or not until we get
19341 // this marker, and this is too late.
19342 // If this render already had a ping or lower pri updates,
19343 // and this is the first time we know we're going to suspend we
19344 // should be able to immediately restart from within throwException.
19345 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
19346 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
19347 // If this was in an invisible tree or a new render, then showing
19348 // this boundary is ok.
19349 renderDidSuspend();
19350 } else {
19351 // Otherwise, we're going to have to hide content so we should
19352 // suspend for longer if possible.
19353 renderDidSuspendDelayIfPossible();
19354 }
19355 }
19356 }
19357
19358 if (supportsPersistence) {
19359 // TODO: Only schedule updates if not prevDidTimeout.
19360 if (nextDidTimeout) {
19361 // If this boundary just timed out, schedule an effect to attach a
19362 // retry listener to the proimse. This flag is also used to hide the
19363 // primary children.
19364 workInProgress.effectTag |= Update;
19365 }
19366 }
19367 if (supportsMutation) {
19368 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
19369 if (nextDidTimeout || prevDidTimeout) {
19370 // If this boundary just timed out, schedule an effect to attach a
19371 // retry listener to the proimse. This flag is also used to hide the
19372 // primary children. In mutation mode, we also need the flag to
19373 // *unhide* children that were previously hidden, so check if the
19374 // is currently timed out, too.
19375 workInProgress.effectTag |= Update;
19376 }
19377 }
19378 if (enableSuspenseCallback && workInProgress.updateQueue !== null && workInProgress.memoizedProps.suspenseCallback != null) {
19379 // Always notify the callback
19380 workInProgress.effectTag |= Update;
19381 }
19382 break;
19383 }
19384 case Fragment:
19385 break;
19386 case Mode:
19387 break;
19388 case Profiler:
19389 break;
19390 case HostPortal:
19391 popHostContainer(workInProgress);
19392 updateHostContainer(workInProgress);
19393 break;
19394 case ContextProvider:
19395 // Pop provider fiber
19396 popProvider(workInProgress);
19397 break;
19398 case ContextConsumer:
19399 break;
19400 case MemoComponent:
19401 break;
19402 case IncompleteClassComponent:
19403 {
19404 // Same as class component case. I put it down here so that the tags are
19405 // sequential to ensure this switch is compiled to a jump table.
19406 var _Component = workInProgress.type;
19407 if (isContextProvider(_Component)) {
19408 popContext(workInProgress);
19409 }
19410 break;
19411 }
19412 case DehydratedSuspenseComponent:
19413 {
19414 if (enableSuspenseServerRenderer) {
19415 popSuspenseContext(workInProgress);
19416 if (current === null) {
19417 var _wasHydrated2 = popHydrationState(workInProgress);
19418 (function () {
19419 if (!_wasHydrated2) {
19420 {
19421 throw ReactError(Error('A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.'));
19422 }
19423 }
19424 })();
19425 if (enableSchedulerTracing) {
19426 markSpawnedWork(Never);
19427 }
19428 skipPastDehydratedSuspenseInstance(workInProgress);
19429 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
19430 // This boundary did not suspend so it's now hydrated.
19431 // To handle any future suspense cases, we're going to now upgrade it
19432 // to a Suspense component. We detach it from the existing current fiber.
19433 current.alternate = null;
19434 workInProgress.alternate = null;
19435 workInProgress.tag = SuspenseComponent;
19436 workInProgress.memoizedState = null;
19437 workInProgress.stateNode = null;
19438 }
19439 }
19440 break;
19441 }
19442 case SuspenseListComponent:
19443 {
19444 popSuspenseContext(workInProgress);
19445
19446 var renderState = workInProgress.memoizedState;
19447
19448 if (renderState === null) {
19449 // We're running in the default, "independent" mode. We don't do anything
19450 // in this mode.
19451 break;
19452 }
19453
19454 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
19455
19456 var renderedTail = renderState.rendering;
19457 if (renderedTail === null) {
19458 // We just rendered the head.
19459 if (!didSuspendAlready) {
19460 // This is the first pass. We need to figure out if anything is still
19461 // suspended in the rendered set.
19462
19463 // If new content unsuspended, but there's still some content that
19464 // didn't. Then we need to do a second pass that forces everything
19465 // to keep showing their fallbacks.
19466
19467 // We might be suspended if something in this render pass suspended, or
19468 // something in the previous committed pass suspended. Otherwise,
19469 // there's no chance so we can skip the expensive call to
19470 // findFirstSuspended.
19471 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
19472 if (!cannotBeSuspended) {
19473 var row = workInProgress.child;
19474 while (row !== null) {
19475 var suspended = findFirstSuspended(row);
19476 if (suspended !== null) {
19477 didSuspendAlready = true;
19478 workInProgress.effectTag |= DidCapture;
19479 cutOffTailIfNeeded(renderState, false);
19480
19481 // If this is a newly suspended tree, it might not get committed as
19482 // part of the second pass. In that case nothing will subscribe to
19483 // its thennables. Instead, we'll transfer its thennables to the
19484 // SuspenseList so that it can retry if they resolve.
19485 // There might be multiple of these in the list but since we're
19486 // going to wait for all of them anyway, it doesn't really matter
19487 // which ones gets to ping. In theory we could get clever and keep
19488 // track of how many dependencies remain but it gets tricky because
19489 // in the meantime, we can add/remove/change items and dependencies.
19490 // We might bail out of the loop before finding any but that
19491 // doesn't matter since that means that the other boundaries that
19492 // we did find already has their listeners attached.
19493 var newThennables = suspended.updateQueue;
19494 if (newThennables !== null) {
19495 workInProgress.updateQueue = newThennables;
19496 workInProgress.effectTag |= Update;
19497 }
19498
19499 // Rerender the whole list, but this time, we'll force fallbacks
19500 // to stay in place.
19501 // Reset the effect list before doing the second pass since that's now invalid.
19502 workInProgress.firstEffect = workInProgress.lastEffect = null;
19503 // Reset the child fibers to their original state.
19504 resetChildFibers(workInProgress, renderExpirationTime);
19505
19506 // Set up the Suspense Context to force suspense and immediately
19507 // rerender the children.
19508 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
19509 return workInProgress.child;
19510 }
19511 row = row.sibling;
19512 }
19513 }
19514 } else {
19515 cutOffTailIfNeeded(renderState, false);
19516 }
19517 // Next we're going to render the tail.
19518 } else {
19519 // Append the rendered row to the child list.
19520 if (!didSuspendAlready) {
19521 var _suspended = findFirstSuspended(renderedTail);
19522 if (_suspended !== null) {
19523 workInProgress.effectTag |= DidCapture;
19524 didSuspendAlready = true;
19525 cutOffTailIfNeeded(renderState, true);
19526 // This might have been modified.
19527 if (renderState.tail === null && renderState.tailMode === 'hidden') {
19528 // We need to delete the row we just rendered.
19529 // Ensure we transfer the update queue to the parent.
19530 var _newThennables = _suspended.updateQueue;
19531 if (_newThennables !== null) {
19532 workInProgress.updateQueue = _newThennables;
19533 workInProgress.effectTag |= Update;
19534 }
19535 // Reset the effect list to what it w as before we rendered this
19536 // child. The nested children have already appended themselves.
19537 var lastEffect = workInProgress.lastEffect = renderState.lastEffect;
19538 // Remove any effects that were appended after this point.
19539 if (lastEffect !== null) {
19540 lastEffect.nextEffect = null;
19541 }
19542 // We're done.
19543 return null;
19544 }
19545 } else if (now() > renderState.tailExpiration && renderExpirationTime > Never) {
19546 // We have now passed our CPU deadline and we'll just give up further
19547 // attempts to render the main content and only render fallbacks.
19548 // The assumption is that this is usually faster.
19549 workInProgress.effectTag |= DidCapture;
19550 didSuspendAlready = true;
19551
19552 cutOffTailIfNeeded(renderState, false);
19553
19554 // Since nothing actually suspended, there will nothing to ping this
19555 // to get it started back up to attempt the next item. If we can show
19556 // them, then they really have the same priority as this render.
19557 // So we'll pick it back up the very next render pass once we've had
19558 // an opportunity to yield for paint.
19559
19560 var nextPriority = renderExpirationTime - 1;
19561 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
19562 if (enableSchedulerTracing) {
19563 markSpawnedWork(nextPriority);
19564 }
19565 }
19566 }
19567 if (renderState.isBackwards) {
19568 // The effect list of the backwards tail will have been added
19569 // to the end. This breaks the guarantee that life-cycles fire in
19570 // sibling order but that isn't a strong guarantee promised by React.
19571 // Especially since these might also just pop in during future commits.
19572 // Append to the beginning of the list.
19573 renderedTail.sibling = workInProgress.child;
19574 workInProgress.child = renderedTail;
19575 } else {
19576 var previousSibling = renderState.last;
19577 if (previousSibling !== null) {
19578 previousSibling.sibling = renderedTail;
19579 } else {
19580 workInProgress.child = renderedTail;
19581 }
19582 renderState.last = renderedTail;
19583 }
19584 }
19585
19586 if (renderState.tail !== null) {
19587 // We still have tail rows to render.
19588 if (renderState.tailExpiration === 0) {
19589 // Heuristic for how long we're willing to spend rendering rows
19590 // until we just give up and show what we have so far.
19591 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
19592 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
19593 }
19594 // Pop a row.
19595 var next = renderState.tail;
19596 renderState.rendering = next;
19597 renderState.tail = next.sibling;
19598 renderState.lastEffect = workInProgress.lastEffect;
19599 next.sibling = null;
19600
19601 // Restore the context.
19602 // TODO: We can probably just avoid popping it instead and only
19603 // setting it the first time we go from not suspended to suspended.
19604 var suspenseContext = suspenseStackCursor.current;
19605 if (didSuspendAlready) {
19606 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19607 } else {
19608 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19609 }
19610 pushSuspenseContext(workInProgress, suspenseContext);
19611 // Do a pass over the next row.
19612 return next;
19613 }
19614 break;
19615 }
19616 case FundamentalComponent:
19617 {
19618 if (enableFundamentalAPI) {
19619 var fundamentalImpl = workInProgress.type.impl;
19620 var fundamentalInstance = workInProgress.stateNode;
19621
19622 if (fundamentalInstance === null) {
19623 var getInitialState = fundamentalImpl.getInitialState;
19624 var fundamentalState = void 0;
19625 if (getInitialState !== undefined) {
19626 fundamentalState = getInitialState(newProps);
19627 }
19628 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(workInProgress, newProps, fundamentalImpl, fundamentalState || {});
19629 var _instance6 = getFundamentalComponentInstance(fundamentalInstance);
19630 fundamentalInstance.instance = _instance6;
19631 if (fundamentalImpl.reconcileChildren === false) {
19632 return null;
19633 }
19634 appendAllChildren(_instance6, workInProgress, false, false);
19635 mountFundamentalComponent(fundamentalInstance);
19636 } else {
19637 // We fire update in commit phase
19638 var prevProps = fundamentalInstance.props;
19639 fundamentalInstance.prevProps = prevProps;
19640 fundamentalInstance.props = newProps;
19641 fundamentalInstance.currentFiber = workInProgress;
19642 if (supportsPersistence) {
19643 var _instance7 = cloneFundamentalInstance(fundamentalInstance);
19644 fundamentalInstance.instance = _instance7;
19645 appendAllChildren(_instance7, workInProgress, false, false);
19646 }
19647 var shouldUpdate = shouldUpdateFundamentalComponent(fundamentalInstance);
19648 if (shouldUpdate) {
19649 markUpdate(workInProgress);
19650 }
19651 }
19652 }
19653 break;
19654 }
19655 default:
19656 (function () {
19657 {
19658 {
19659 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
19660 }
19661 }
19662 })();
19663 }
19664
19665 return null;
19666}
19667
19668function mountEventResponder$1(responder, responderProps, instance, rootContainerInstance, fiber, respondersMap) {
19669 var responderState = emptyObject;
19670 var getInitialState = responder.getInitialState;
19671 if (getInitialState !== null) {
19672 responderState = getInitialState(responderProps);
19673 }
19674 var responderInstance = createResponderInstance(responder, responderProps, responderState, instance, fiber);
19675 mountResponderInstance(responder, responderInstance, responderProps, responderState, instance, rootContainerInstance);
19676 respondersMap.set(responder, responderInstance);
19677}
19678
19679function updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance) {
19680 var responder = void 0;
19681 var props = void 0;
19682
19683 if (listener) {
19684 responder = listener.responder;
19685 props = listener.props;
19686 }
19687 (function () {
19688 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
19689 {
19690 throw ReactError(Error('An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponer().'));
19691 }
19692 }
19693 })();
19694 var listenerProps = props;
19695 if (visistedResponders.has(responder)) {
19696 // show warning
19697 {
19698 warning$1(false, 'Duplicate event responder "%s" found in event listeners. ' + 'Event listeners passed to elements cannot use the same event responder more than once.', responder.displayName);
19699 }
19700 return;
19701 }
19702 visistedResponders.add(responder);
19703 var responderInstance = respondersMap.get(responder);
19704
19705 if (responderInstance === undefined) {
19706 // Mount
19707 mountEventResponder$1(responder, listenerProps, instance, rootContainerInstance, fiber, respondersMap);
19708 } else {
19709 // Update
19710 responderInstance.props = listenerProps;
19711 responderInstance.fiber = fiber;
19712 }
19713}
19714
19715function updateEventListeners(listeners, instance, rootContainerInstance, fiber) {
19716 var visistedResponders = new Set();
19717 var dependencies = fiber.dependencies;
19718 if (listeners != null) {
19719 if (dependencies === null) {
19720 dependencies = fiber.dependencies = {
19721 expirationTime: NoWork,
19722 firstContext: null,
19723 responders: new Map()
19724 };
19725 }
19726 var respondersMap = dependencies.responders;
19727 if (respondersMap === null) {
19728 respondersMap = new Map();
19729 }
19730 if (isArray$2(listeners)) {
19731 for (var i = 0, length = listeners.length; i < length; i++) {
19732 var listener = listeners[i];
19733 updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
19734 }
19735 } else {
19736 updateEventListener(listeners, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
19737 }
19738 }
19739 if (dependencies !== null) {
19740 var _respondersMap = dependencies.responders;
19741 if (_respondersMap !== null) {
19742 // Unmount
19743 var mountedResponders = Array.from(_respondersMap.keys());
19744 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
19745 var mountedResponder = mountedResponders[_i];
19746 if (!visistedResponders.has(mountedResponder)) {
19747 var responderInstance = _respondersMap.get(mountedResponder);
19748 unmountResponderInstance(responderInstance);
19749 _respondersMap.delete(mountedResponder);
19750 }
19751 }
19752 }
19753 }
19754}
19755
19756function unwindWork(workInProgress, renderExpirationTime) {
19757 switch (workInProgress.tag) {
19758 case ClassComponent:
19759 {
19760 var Component = workInProgress.type;
19761 if (isContextProvider(Component)) {
19762 popContext(workInProgress);
19763 }
19764 var effectTag = workInProgress.effectTag;
19765 if (effectTag & ShouldCapture) {
19766 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
19767 return workInProgress;
19768 }
19769 return null;
19770 }
19771 case HostRoot:
19772 {
19773 popHostContainer(workInProgress);
19774 popTopLevelContextObject(workInProgress);
19775 var _effectTag = workInProgress.effectTag;
19776 (function () {
19777 if (!((_effectTag & DidCapture) === NoEffect)) {
19778 {
19779 throw ReactError(Error('The root failed to unmount after an error. This is likely a bug in React. Please file an issue.'));
19780 }
19781 }
19782 })();
19783 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
19784 return workInProgress;
19785 }
19786 case HostComponent:
19787 {
19788 // TODO: popHydrationState
19789 popHostContext(workInProgress);
19790 return null;
19791 }
19792 case SuspenseComponent:
19793 {
19794 popSuspenseContext(workInProgress);
19795 var _effectTag2 = workInProgress.effectTag;
19796 if (_effectTag2 & ShouldCapture) {
19797 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
19798 // Captured a suspense effect. Re-render the boundary.
19799 return workInProgress;
19800 }
19801 return null;
19802 }
19803 case DehydratedSuspenseComponent:
19804 {
19805 if (enableSuspenseServerRenderer) {
19806 // TODO: popHydrationState
19807 popSuspenseContext(workInProgress);
19808 var _effectTag3 = workInProgress.effectTag;
19809 if (_effectTag3 & ShouldCapture) {
19810 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
19811 // Captured a suspense effect. Re-render the boundary.
19812 return workInProgress;
19813 }
19814 }
19815 return null;
19816 }
19817 case SuspenseListComponent:
19818 {
19819 popSuspenseContext(workInProgress);
19820 // SuspenseList doesn't actually catch anything. It should've been
19821 // caught by a nested boundary. If not, it should bubble through.
19822 return null;
19823 }
19824 case HostPortal:
19825 popHostContainer(workInProgress);
19826 return null;
19827 case ContextProvider:
19828 popProvider(workInProgress);
19829 return null;
19830 default:
19831 return null;
19832 }
19833}
19834
19835function unwindInterruptedWork(interruptedWork) {
19836 switch (interruptedWork.tag) {
19837 case ClassComponent:
19838 {
19839 var childContextTypes = interruptedWork.type.childContextTypes;
19840 if (childContextTypes !== null && childContextTypes !== undefined) {
19841 popContext(interruptedWork);
19842 }
19843 break;
19844 }
19845 case HostRoot:
19846 {
19847 popHostContainer(interruptedWork);
19848 popTopLevelContextObject(interruptedWork);
19849 break;
19850 }
19851 case HostComponent:
19852 {
19853 popHostContext(interruptedWork);
19854 break;
19855 }
19856 case HostPortal:
19857 popHostContainer(interruptedWork);
19858 break;
19859 case SuspenseComponent:
19860 popSuspenseContext(interruptedWork);
19861 break;
19862 case DehydratedSuspenseComponent:
19863 if (enableSuspenseServerRenderer) {
19864 // TODO: popHydrationState
19865 popSuspenseContext(interruptedWork);
19866 }
19867 break;
19868 case SuspenseListComponent:
19869 popSuspenseContext(interruptedWork);
19870 break;
19871 case ContextProvider:
19872 popProvider(interruptedWork);
19873 break;
19874 default:
19875 break;
19876 }
19877}
19878
19879function createCapturedValue(value, source) {
19880 // If the value is an error, call this function immediately after it is thrown
19881 // so the stack is accurate.
19882 return {
19883 value: value,
19884 source: source,
19885 stack: getStackByFiberInDevAndProd(source)
19886 };
19887}
19888
19889// This module is forked in different environments.
19890// By default, return `true` to log errors to the console.
19891// Forks can return `false` if this isn't desirable.
19892function showErrorDialog(capturedError) {
19893 return true;
19894}
19895
19896function logCapturedError(capturedError) {
19897 var logError = showErrorDialog(capturedError);
19898
19899 // Allow injected showErrorDialog() to prevent default console.error logging.
19900 // This enables renderers like ReactNative to better manage redbox behavior.
19901 if (logError === false) {
19902 return;
19903 }
19904
19905 var error = capturedError.error;
19906 {
19907 var componentName = capturedError.componentName,
19908 componentStack = capturedError.componentStack,
19909 errorBoundaryName = capturedError.errorBoundaryName,
19910 errorBoundaryFound = capturedError.errorBoundaryFound,
19911 willRetry = capturedError.willRetry;
19912
19913 // Browsers support silencing uncaught errors by calling
19914 // `preventDefault()` in window `error` handler.
19915 // We record this information as an expando on the error.
19916
19917 if (error != null && error._suppressLogging) {
19918 if (errorBoundaryFound && willRetry) {
19919 // The error is recoverable and was silenced.
19920 // Ignore it and don't print the stack addendum.
19921 // This is handy for testing error boundaries without noise.
19922 return;
19923 }
19924 // The error is fatal. Since the silencing might have
19925 // been accidental, we'll surface it anyway.
19926 // However, the browser would have silenced the original error
19927 // so we'll print it first, and then print the stack addendum.
19928 console.error(error);
19929 // For a more detailed description of this block, see:
19930 // https://github.com/facebook/react/pull/13384
19931 }
19932
19933 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
19934
19935 var errorBoundaryMessage = void 0;
19936 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
19937 if (errorBoundaryFound && errorBoundaryName) {
19938 if (willRetry) {
19939 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
19940 } else {
19941 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
19942 }
19943 } else {
19944 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.';
19945 }
19946 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
19947
19948 // In development, we provide our own message with just the component stack.
19949 // We don't include the original error message and JS stack because the browser
19950 // has already printed it. Even if the application swallows the error, it is still
19951 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
19952 console.error(combinedMessage);
19953 }
19954}
19955
19956var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
19957{
19958 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
19959}
19960
19961var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
19962
19963function logError(boundary, errorInfo) {
19964 var source = errorInfo.source;
19965 var stack = errorInfo.stack;
19966 if (stack === null && source !== null) {
19967 stack = getStackByFiberInDevAndProd(source);
19968 }
19969
19970 var capturedError = {
19971 componentName: source !== null ? getComponentName(source.type) : null,
19972 componentStack: stack !== null ? stack : '',
19973 error: errorInfo.value,
19974 errorBoundary: null,
19975 errorBoundaryName: null,
19976 errorBoundaryFound: false,
19977 willRetry: false
19978 };
19979
19980 if (boundary !== null && boundary.tag === ClassComponent) {
19981 capturedError.errorBoundary = boundary.stateNode;
19982 capturedError.errorBoundaryName = getComponentName(boundary.type);
19983 capturedError.errorBoundaryFound = true;
19984 capturedError.willRetry = true;
19985 }
19986
19987 try {
19988 logCapturedError(capturedError);
19989 } catch (e) {
19990 // This method must not throw, or React internal state will get messed up.
19991 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
19992 // we want to report this error outside of the normal stack as a last resort.
19993 // https://github.com/facebook/react/issues/13188
19994 setTimeout(function () {
19995 throw e;
19996 });
19997 }
19998}
19999
20000var callComponentWillUnmountWithTimer = function (current$$1, instance) {
20001 startPhaseTimer(current$$1, 'componentWillUnmount');
20002 instance.props = current$$1.memoizedProps;
20003 instance.state = current$$1.memoizedState;
20004 instance.componentWillUnmount();
20005 stopPhaseTimer();
20006};
20007
20008// Capture errors so they don't interrupt unmounting.
20009function safelyCallComponentWillUnmount(current$$1, instance) {
20010 {
20011 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
20012 if (hasCaughtError()) {
20013 var unmountError = clearCaughtError();
20014 captureCommitPhaseError(current$$1, unmountError);
20015 }
20016 }
20017}
20018
20019function safelyDetachRef(current$$1) {
20020 var ref = current$$1.ref;
20021 if (ref !== null) {
20022 if (typeof ref === 'function') {
20023 {
20024 invokeGuardedCallback(null, ref, null, null);
20025 if (hasCaughtError()) {
20026 var refError = clearCaughtError();
20027 captureCommitPhaseError(current$$1, refError);
20028 }
20029 }
20030 } else {
20031 ref.current = null;
20032 }
20033 }
20034}
20035
20036function safelyCallDestroy(current$$1, destroy) {
20037 {
20038 invokeGuardedCallback(null, destroy, null);
20039 if (hasCaughtError()) {
20040 var error = clearCaughtError();
20041 captureCommitPhaseError(current$$1, error);
20042 }
20043 }
20044}
20045
20046function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
20047 switch (finishedWork.tag) {
20048 case FunctionComponent:
20049 case ForwardRef:
20050 case SimpleMemoComponent:
20051 {
20052 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
20053 return;
20054 }
20055 case ClassComponent:
20056 {
20057 if (finishedWork.effectTag & Snapshot) {
20058 if (current$$1 !== null) {
20059 var prevProps = current$$1.memoizedProps;
20060 var prevState = current$$1.memoizedState;
20061 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
20062 var instance = finishedWork.stateNode;
20063 // We could update instance props and state here,
20064 // but instead we rely on them being set during last render.
20065 // TODO: revisit this when we implement resuming.
20066 {
20067 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20068 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, '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') : void 0;
20069 !(instance.state === finishedWork.memoizedState) ? warning$1(false, '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') : void 0;
20070 }
20071 }
20072 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
20073 {
20074 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
20075 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
20076 didWarnSet.add(finishedWork.type);
20077 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
20078 }
20079 }
20080 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
20081 stopPhaseTimer();
20082 }
20083 }
20084 return;
20085 }
20086 case HostRoot:
20087 case HostComponent:
20088 case HostText:
20089 case HostPortal:
20090 case IncompleteClassComponent:
20091 // Nothing to do for these component types
20092 return;
20093 default:
20094 {
20095 (function () {
20096 {
20097 {
20098 throw ReactError(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.'));
20099 }
20100 }
20101 })();
20102 }
20103 }
20104}
20105
20106function commitHookEffectList(unmountTag, mountTag, finishedWork) {
20107 var updateQueue = finishedWork.updateQueue;
20108 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
20109 if (lastEffect !== null) {
20110 var firstEffect = lastEffect.next;
20111 var effect = firstEffect;
20112 do {
20113 if ((effect.tag & unmountTag) !== NoEffect$1) {
20114 // Unmount
20115 var destroy = effect.destroy;
20116 effect.destroy = undefined;
20117 if (destroy !== undefined) {
20118 destroy();
20119 }
20120 }
20121 if ((effect.tag & mountTag) !== NoEffect$1) {
20122 // Mount
20123 var create = effect.create;
20124 effect.destroy = create();
20125
20126 {
20127 var _destroy = effect.destroy;
20128 if (_destroy !== undefined && typeof _destroy !== 'function') {
20129 var addendum = void 0;
20130 if (_destroy === null) {
20131 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
20132 } else if (typeof _destroy.then === 'function') {
20133 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';
20134 } else {
20135 addendum = ' You returned: ' + _destroy;
20136 }
20137 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
20138 }
20139 }
20140 }
20141 effect = effect.next;
20142 } while (effect !== firstEffect);
20143 }
20144}
20145
20146function commitPassiveHookEffects(finishedWork) {
20147 if ((finishedWork.effectTag & Passive) !== NoEffect) {
20148 switch (finishedWork.tag) {
20149 case FunctionComponent:
20150 case ForwardRef:
20151 case SimpleMemoComponent:
20152 {
20153 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
20154 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
20155 break;
20156 }
20157 default:
20158 break;
20159 }
20160 }
20161}
20162
20163function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
20164 switch (finishedWork.tag) {
20165 case FunctionComponent:
20166 case ForwardRef:
20167 case SimpleMemoComponent:
20168 {
20169 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
20170 break;
20171 }
20172 case ClassComponent:
20173 {
20174 var instance = finishedWork.stateNode;
20175 if (finishedWork.effectTag & Update) {
20176 if (current$$1 === null) {
20177 startPhaseTimer(finishedWork, 'componentDidMount');
20178 // We could update instance props and state here,
20179 // but instead we rely on them being set during last render.
20180 // TODO: revisit this when we implement resuming.
20181 {
20182 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20183 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, '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') : void 0;
20184 !(instance.state === finishedWork.memoizedState) ? warning$1(false, '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') : void 0;
20185 }
20186 }
20187 instance.componentDidMount();
20188 stopPhaseTimer();
20189 } else {
20190 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
20191 var prevState = current$$1.memoizedState;
20192 startPhaseTimer(finishedWork, 'componentDidUpdate');
20193 // We could update instance props and state here,
20194 // but instead we rely on them being set during last render.
20195 // TODO: revisit this when we implement resuming.
20196 {
20197 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20198 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, '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') : void 0;
20199 !(instance.state === finishedWork.memoizedState) ? warning$1(false, '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') : void 0;
20200 }
20201 }
20202 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
20203 stopPhaseTimer();
20204 }
20205 }
20206 var updateQueue = finishedWork.updateQueue;
20207 if (updateQueue !== null) {
20208 {
20209 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
20210 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, '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') : void 0;
20211 !(instance.state === finishedWork.memoizedState) ? warning$1(false, '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') : void 0;
20212 }
20213 }
20214 // We could update instance props and state here,
20215 // but instead we rely on them being set during last render.
20216 // TODO: revisit this when we implement resuming.
20217 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
20218 }
20219 return;
20220 }
20221 case HostRoot:
20222 {
20223 var _updateQueue = finishedWork.updateQueue;
20224 if (_updateQueue !== null) {
20225 var _instance = null;
20226 if (finishedWork.child !== null) {
20227 switch (finishedWork.child.tag) {
20228 case HostComponent:
20229 _instance = getPublicInstance(finishedWork.child.stateNode);
20230 break;
20231 case ClassComponent:
20232 _instance = finishedWork.child.stateNode;
20233 break;
20234 }
20235 }
20236 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
20237 }
20238 return;
20239 }
20240 case HostComponent:
20241 {
20242 var _instance2 = finishedWork.stateNode;
20243
20244 // Renderers may schedule work to be done after host components are mounted
20245 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
20246 // These effects should only be committed when components are first mounted,
20247 // aka when there is no current/alternate.
20248 if (current$$1 === null && finishedWork.effectTag & Update) {
20249 var type = finishedWork.type;
20250 var props = finishedWork.memoizedProps;
20251 commitMount(_instance2, type, props, finishedWork);
20252 }
20253
20254 return;
20255 }
20256 case HostText:
20257 {
20258 // We have no life-cycles associated with text.
20259 return;
20260 }
20261 case HostPortal:
20262 {
20263 // We have no life-cycles associated with portals.
20264 return;
20265 }
20266 case Profiler:
20267 {
20268 if (enableProfilerTimer) {
20269 var onRender = finishedWork.memoizedProps.onRender;
20270
20271 if (typeof onRender === 'function') {
20272 if (enableSchedulerTracing) {
20273 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
20274 } else {
20275 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
20276 }
20277 }
20278 }
20279 return;
20280 }
20281 case SuspenseComponent:
20282 case SuspenseListComponent:
20283 case IncompleteClassComponent:
20284 case FundamentalComponent:
20285 return;
20286 default:
20287 {
20288 (function () {
20289 {
20290 {
20291 throw ReactError(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.'));
20292 }
20293 }
20294 })();
20295 }
20296 }
20297}
20298
20299function hideOrUnhideAllChildren(finishedWork, isHidden) {
20300 if (supportsMutation) {
20301 // We only have the top Fiber that was inserted but we need to recurse down its
20302 var node = finishedWork;
20303 while (true) {
20304 if (node.tag === HostComponent) {
20305 var instance = node.stateNode;
20306 if (isHidden) {
20307 hideInstance(instance);
20308 } else {
20309 unhideInstance(node.stateNode, node.memoizedProps);
20310 }
20311 } else if (node.tag === HostText) {
20312 var _instance3 = node.stateNode;
20313 if (isHidden) {
20314 hideTextInstance(_instance3);
20315 } else {
20316 unhideTextInstance(_instance3, node.memoizedProps);
20317 }
20318 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
20319 // Found a nested Suspense component that timed out. Skip over the
20320 var fallbackChildFragment = node.child.sibling;
20321 fallbackChildFragment.return = node;
20322 node = fallbackChildFragment;
20323 continue;
20324 } else if (node.child !== null) {
20325 node.child.return = node;
20326 node = node.child;
20327 continue;
20328 }
20329 if (node === finishedWork) {
20330 return;
20331 }
20332 while (node.sibling === null) {
20333 if (node.return === null || node.return === finishedWork) {
20334 return;
20335 }
20336 node = node.return;
20337 }
20338 node.sibling.return = node.return;
20339 node = node.sibling;
20340 }
20341 }
20342}
20343
20344function commitAttachRef(finishedWork) {
20345 var ref = finishedWork.ref;
20346 if (ref !== null) {
20347 var instance = finishedWork.stateNode;
20348 var instanceToUse = void 0;
20349 switch (finishedWork.tag) {
20350 case HostComponent:
20351 instanceToUse = getPublicInstance(instance);
20352 break;
20353 default:
20354 instanceToUse = instance;
20355 }
20356 if (typeof ref === 'function') {
20357 ref(instanceToUse);
20358 } else {
20359 {
20360 if (!ref.hasOwnProperty('current')) {
20361 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
20362 }
20363 }
20364
20365 ref.current = instanceToUse;
20366 }
20367 }
20368}
20369
20370function commitDetachRef(current$$1) {
20371 var currentRef = current$$1.ref;
20372 if (currentRef !== null) {
20373 if (typeof currentRef === 'function') {
20374 currentRef(null);
20375 } else {
20376 currentRef.current = null;
20377 }
20378 }
20379}
20380
20381// User-originating errors (lifecycles and refs) should not interrupt
20382// deletion, so don't let them throw. Host-originating errors should
20383// interrupt deletion, so it's okay
20384function commitUnmount(current$$1, renderPriorityLevel) {
20385 onCommitUnmount(current$$1);
20386
20387 switch (current$$1.tag) {
20388 case FunctionComponent:
20389 case ForwardRef:
20390 case MemoComponent:
20391 case SimpleMemoComponent:
20392 {
20393 var updateQueue = current$$1.updateQueue;
20394 if (updateQueue !== null) {
20395 var lastEffect = updateQueue.lastEffect;
20396 if (lastEffect !== null) {
20397 var firstEffect = lastEffect.next;
20398
20399 // When the owner fiber is deleted, the destroy function of a passive
20400 // effect hook is called during the synchronous commit phase. This is
20401 // a concession to implementation complexity. Calling it in the
20402 // passive effect phase (like they usually are, when dependencies
20403 // change during an update) would require either traversing the
20404 // children of the deleted fiber again, or including unmount effects
20405 // as part of the fiber effect list.
20406 //
20407 // Because this is during the sync commit phase, we need to change
20408 // the priority.
20409 //
20410 // TODO: Reconsider this implementation trade off.
20411 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
20412 runWithPriority$2(priorityLevel, function () {
20413 var effect = firstEffect;
20414 do {
20415 var destroy = effect.destroy;
20416 if (destroy !== undefined) {
20417 safelyCallDestroy(current$$1, destroy);
20418 }
20419 effect = effect.next;
20420 } while (effect !== firstEffect);
20421 });
20422 }
20423 }
20424 break;
20425 }
20426 case ClassComponent:
20427 {
20428 safelyDetachRef(current$$1);
20429 var instance = current$$1.stateNode;
20430 if (typeof instance.componentWillUnmount === 'function') {
20431 safelyCallComponentWillUnmount(current$$1, instance);
20432 }
20433 return;
20434 }
20435 case HostComponent:
20436 {
20437 if (enableFlareAPI) {
20438 var dependencies = current$$1.dependencies;
20439
20440 if (dependencies !== null) {
20441 var respondersMap = dependencies.responders;
20442 if (respondersMap !== null) {
20443 var responderInstances = Array.from(respondersMap.values());
20444 for (var i = 0, length = responderInstances.length; i < length; i++) {
20445 var responderInstance = responderInstances[i];
20446 unmountResponderInstance(responderInstance);
20447 }
20448 dependencies.responders = null;
20449 }
20450 }
20451 }
20452 safelyDetachRef(current$$1);
20453 return;
20454 }
20455 case HostPortal:
20456 {
20457 // TODO: this is recursive.
20458 // We are also not using this parent because
20459 // the portal will get pushed immediately.
20460 if (supportsMutation) {
20461 unmountHostComponents(current$$1, renderPriorityLevel);
20462 } else if (supportsPersistence) {
20463 emptyPortalContainer(current$$1);
20464 }
20465 return;
20466 }
20467 case FundamentalComponent:
20468 {
20469 if (enableFundamentalAPI) {
20470 var fundamentalInstance = current$$1.stateNode;
20471 if (fundamentalInstance !== null) {
20472 unmountFundamentalComponent(fundamentalInstance);
20473 current$$1.stateNode = null;
20474 }
20475 }
20476 }
20477 }
20478}
20479
20480function commitNestedUnmounts(root, renderPriorityLevel) {
20481 // While we're inside a removed host node we don't want to call
20482 // removeChild on the inner nodes because they're removed by the top
20483 // call anyway. We also want to call componentWillUnmount on all
20484 // composites before this host node is removed from the tree. Therefore
20485 var node = root;
20486 while (true) {
20487 commitUnmount(node, renderPriorityLevel);
20488 // Visit children because they may contain more composite or host nodes.
20489 // Skip portals because commitUnmount() currently visits them recursively.
20490 if (node.child !== null && (
20491 // If we use mutation we drill down into portals using commitUnmount above.
20492 // If we don't use mutation we drill down into portals here instead.
20493 !supportsMutation || node.tag !== HostPortal)) {
20494 node.child.return = node;
20495 node = node.child;
20496 continue;
20497 }
20498 if (node === root) {
20499 return;
20500 }
20501 while (node.sibling === null) {
20502 if (node.return === null || node.return === root) {
20503 return;
20504 }
20505 node = node.return;
20506 }
20507 node.sibling.return = node.return;
20508 node = node.sibling;
20509 }
20510}
20511
20512function detachFiber(current$$1) {
20513 // Cut off the return pointers to disconnect it from the tree. Ideally, we
20514 // should clear the child pointer of the parent alternate to let this
20515 // get GC:ed but we don't know which for sure which parent is the current
20516 // one so we'll settle for GC:ing the subtree of this child. This child
20517 // itself will be GC:ed when the parent updates the next time.
20518 current$$1.return = null;
20519 current$$1.child = null;
20520 current$$1.memoizedState = null;
20521 current$$1.updateQueue = null;
20522 current$$1.dependencies = null;
20523 var alternate = current$$1.alternate;
20524 if (alternate !== null) {
20525 alternate.return = null;
20526 alternate.child = null;
20527 alternate.memoizedState = null;
20528 alternate.updateQueue = null;
20529 alternate.dependencies = null;
20530 }
20531}
20532
20533function emptyPortalContainer(current$$1) {
20534 if (!supportsPersistence) {
20535 return;
20536 }
20537
20538 var portal = current$$1.stateNode;
20539 var containerInfo = portal.containerInfo;
20540
20541 var emptyChildSet = createContainerChildSet(containerInfo);
20542 replaceContainerChildren(containerInfo, emptyChildSet);
20543}
20544
20545function commitContainer(finishedWork) {
20546 if (!supportsPersistence) {
20547 return;
20548 }
20549
20550 switch (finishedWork.tag) {
20551 case ClassComponent:
20552 case HostComponent:
20553 case HostText:
20554 case FundamentalComponent:
20555 {
20556 return;
20557 }
20558 case HostRoot:
20559 case HostPortal:
20560 {
20561 var portalOrRoot = finishedWork.stateNode;
20562 var containerInfo = portalOrRoot.containerInfo,
20563 _pendingChildren = portalOrRoot.pendingChildren;
20564
20565 replaceContainerChildren(containerInfo, _pendingChildren);
20566 return;
20567 }
20568 default:
20569 {
20570 (function () {
20571 {
20572 {
20573 throw ReactError(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.'));
20574 }
20575 }
20576 })();
20577 }
20578 }
20579}
20580
20581function getHostParentFiber(fiber) {
20582 var parent = fiber.return;
20583 while (parent !== null) {
20584 if (isHostParent(parent)) {
20585 return parent;
20586 }
20587 parent = parent.return;
20588 }
20589 (function () {
20590 {
20591 {
20592 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
20593 }
20594 }
20595 })();
20596}
20597
20598function isHostParent(fiber) {
20599 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
20600}
20601
20602function getHostSibling(fiber) {
20603 // We're going to search forward into the tree until we find a sibling host
20604 // node. Unfortunately, if multiple insertions are done in a row we have to
20605 // search past them. This leads to exponential search for the next sibling.
20606 var node = fiber;
20607 siblings: while (true) {
20608 // If we didn't find anything, let's try the next sibling.
20609 while (node.sibling === null) {
20610 if (node.return === null || isHostParent(node.return)) {
20611 // If we pop out of the root or hit the parent the fiber we are the
20612 // last sibling.
20613 return null;
20614 }
20615 node = node.return;
20616 }
20617 node.sibling.return = node.return;
20618 node = node.sibling;
20619 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
20620 // If it is not host node and, we might have a host node inside it.
20621 // Try to search down until we find one.
20622 if (node.effectTag & Placement) {
20623 // If we don't have a child, try the siblings instead.
20624 continue siblings;
20625 }
20626 // If we don't have a child, try the siblings instead.
20627 // We also skip portals because they are not part of this host tree.
20628 if (node.child === null || node.tag === HostPortal) {
20629 continue siblings;
20630 } else {
20631 node.child.return = node;
20632 node = node.child;
20633 }
20634 }
20635 // Check if this host node is stable or about to be placed.
20636 if (!(node.effectTag & Placement)) {
20637 // Found it!
20638 return node.stateNode;
20639 }
20640 }
20641}
20642
20643function commitPlacement(finishedWork) {
20644 if (!supportsMutation) {
20645 return;
20646 }
20647
20648 // Recursively insert all host nodes into the parent.
20649 var parentFiber = getHostParentFiber(finishedWork);
20650
20651 // Note: these two variables *must* always be updated together.
20652 var parent = void 0;
20653 var isContainer = void 0;
20654 var parentStateNode = parentFiber.stateNode;
20655 switch (parentFiber.tag) {
20656 case HostComponent:
20657 parent = parentStateNode;
20658 isContainer = false;
20659 break;
20660 case HostRoot:
20661 parent = parentStateNode.containerInfo;
20662 isContainer = true;
20663 break;
20664 case HostPortal:
20665 parent = parentStateNode.containerInfo;
20666 isContainer = true;
20667 break;
20668 case FundamentalComponent:
20669 if (enableFundamentalAPI) {
20670 parent = parentStateNode.instance;
20671 isContainer = false;
20672 }
20673 // eslint-disable-next-line-no-fallthrough
20674 default:
20675 (function () {
20676 {
20677 {
20678 throw ReactError(Error('Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.'));
20679 }
20680 }
20681 })();
20682 }
20683 if (parentFiber.effectTag & ContentReset) {
20684 // Reset the text content of the parent before doing any insertions
20685 resetTextContent(parent);
20686 // Clear ContentReset from the effect tag
20687 parentFiber.effectTag &= ~ContentReset;
20688 }
20689
20690 var before = getHostSibling(finishedWork);
20691 // We only have the top Fiber that was inserted but we need to recurse down its
20692 // children to find all the terminal nodes.
20693 var node = finishedWork;
20694 while (true) {
20695 var isHost = node.tag === HostComponent || node.tag === HostText;
20696 if (isHost || node.tag === FundamentalComponent) {
20697 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
20698 if (before) {
20699 if (isContainer) {
20700 insertInContainerBefore(parent, stateNode, before);
20701 } else {
20702 insertBefore(parent, stateNode, before);
20703 }
20704 } else {
20705 if (isContainer) {
20706 appendChildToContainer(parent, stateNode);
20707 } else {
20708 appendChild(parent, stateNode);
20709 }
20710 }
20711 } else if (node.tag === HostPortal) {
20712 // If the insertion itself is a portal, then we don't want to traverse
20713 // down its children. Instead, we'll get insertions from each child in
20714 // the portal directly.
20715 } else if (node.child !== null) {
20716 node.child.return = node;
20717 node = node.child;
20718 continue;
20719 }
20720 if (node === finishedWork) {
20721 return;
20722 }
20723 while (node.sibling === null) {
20724 if (node.return === null || node.return === finishedWork) {
20725 return;
20726 }
20727 node = node.return;
20728 }
20729 node.sibling.return = node.return;
20730 node = node.sibling;
20731 }
20732}
20733
20734function unmountHostComponents(current$$1, renderPriorityLevel) {
20735 // We only have the top Fiber that was deleted but we need to recurse down its
20736 var node = current$$1;
20737
20738 // Each iteration, currentParent is populated with node's host parent if not
20739 // currentParentIsValid.
20740 var currentParentIsValid = false;
20741
20742 // Note: these two variables *must* always be updated together.
20743 var currentParent = void 0;
20744 var currentParentIsContainer = void 0;
20745
20746 while (true) {
20747 if (!currentParentIsValid) {
20748 var parent = node.return;
20749 findParent: while (true) {
20750 (function () {
20751 if (!(parent !== null)) {
20752 {
20753 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
20754 }
20755 }
20756 })();
20757 var parentStateNode = parent.stateNode;
20758 switch (parent.tag) {
20759 case HostComponent:
20760 currentParent = parentStateNode;
20761 currentParentIsContainer = false;
20762 break findParent;
20763 case HostRoot:
20764 currentParent = parentStateNode.containerInfo;
20765 currentParentIsContainer = true;
20766 break findParent;
20767 case HostPortal:
20768 currentParent = parentStateNode.containerInfo;
20769 currentParentIsContainer = true;
20770 break findParent;
20771 case FundamentalComponent:
20772 if (enableFundamentalAPI) {
20773 currentParent = parentStateNode.instance;
20774 currentParentIsContainer = false;
20775 }
20776 }
20777 parent = parent.return;
20778 }
20779 currentParentIsValid = true;
20780 }
20781
20782 if (node.tag === HostComponent || node.tag === HostText) {
20783 commitNestedUnmounts(node, renderPriorityLevel);
20784 // After all the children have unmounted, it is now safe to remove the
20785 // node from the tree.
20786 if (currentParentIsContainer) {
20787 removeChildFromContainer(currentParent, node.stateNode);
20788 } else {
20789 removeChild(currentParent, node.stateNode);
20790 }
20791 // Don't visit children because we already visited them.
20792 } else if (node.tag === FundamentalComponent) {
20793 var fundamentalNode = node.stateNode.instance;
20794 commitNestedUnmounts(node, renderPriorityLevel);
20795 // After all the children have unmounted, it is now safe to remove the
20796 // node from the tree.
20797 if (currentParentIsContainer) {
20798 removeChildFromContainer(currentParent, fundamentalNode);
20799 } else {
20800 removeChild(currentParent, fundamentalNode);
20801 }
20802 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
20803 // Delete the dehydrated suspense boundary and all of its content.
20804 if (currentParentIsContainer) {
20805 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
20806 } else {
20807 clearSuspenseBoundary(currentParent, node.stateNode);
20808 }
20809 } else if (node.tag === HostPortal) {
20810 if (node.child !== null) {
20811 // When we go into a portal, it becomes the parent to remove from.
20812 // We will reassign it back when we pop the portal on the way up.
20813 currentParent = node.stateNode.containerInfo;
20814 currentParentIsContainer = true;
20815 // Visit children because portals might contain host components.
20816 node.child.return = node;
20817 node = node.child;
20818 continue;
20819 }
20820 } else {
20821 commitUnmount(node, renderPriorityLevel);
20822 // Visit children because we may find more host components below.
20823 if (node.child !== null) {
20824 node.child.return = node;
20825 node = node.child;
20826 continue;
20827 }
20828 }
20829 if (node === current$$1) {
20830 return;
20831 }
20832 while (node.sibling === null) {
20833 if (node.return === null || node.return === current$$1) {
20834 return;
20835 }
20836 node = node.return;
20837 if (node.tag === HostPortal) {
20838 // When we go out of the portal, we need to restore the parent.
20839 // Since we don't keep a stack of them, we will search for it.
20840 currentParentIsValid = false;
20841 }
20842 }
20843 node.sibling.return = node.return;
20844 node = node.sibling;
20845 }
20846}
20847
20848function commitDeletion(current$$1, renderPriorityLevel) {
20849 if (supportsMutation) {
20850 // Recursively delete all host nodes from the parent.
20851 // Detach refs and call componentWillUnmount() on the whole subtree.
20852 unmountHostComponents(current$$1, renderPriorityLevel);
20853 } else {
20854 // Detach refs and call componentWillUnmount() on the whole subtree.
20855 commitNestedUnmounts(current$$1, renderPriorityLevel);
20856 }
20857 detachFiber(current$$1);
20858}
20859
20860function commitWork(current$$1, finishedWork) {
20861 if (!supportsMutation) {
20862 switch (finishedWork.tag) {
20863 case FunctionComponent:
20864 case ForwardRef:
20865 case MemoComponent:
20866 case SimpleMemoComponent:
20867 {
20868 // Note: We currently never use MountMutation, but useLayout uses
20869 // UnmountMutation.
20870 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
20871 return;
20872 }
20873 case Profiler:
20874 {
20875 return;
20876 }
20877 case SuspenseComponent:
20878 {
20879 commitSuspenseComponent(finishedWork);
20880 attachSuspenseRetryListeners(finishedWork);
20881 return;
20882 }
20883 case SuspenseListComponent:
20884 {
20885 attachSuspenseRetryListeners(finishedWork);
20886 return;
20887 }
20888 }
20889
20890 commitContainer(finishedWork);
20891 return;
20892 }
20893
20894 switch (finishedWork.tag) {
20895 case FunctionComponent:
20896 case ForwardRef:
20897 case MemoComponent:
20898 case SimpleMemoComponent:
20899 {
20900 // Note: We currently never use MountMutation, but useLayout uses
20901 // UnmountMutation.
20902 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
20903 return;
20904 }
20905 case ClassComponent:
20906 {
20907 return;
20908 }
20909 case HostComponent:
20910 {
20911 var instance = finishedWork.stateNode;
20912 if (instance != null) {
20913 // Commit the work prepared earlier.
20914 var newProps = finishedWork.memoizedProps;
20915 // For hydration we reuse the update path but we treat the oldProps
20916 // as the newProps. The updatePayload will contain the real change in
20917 // this case.
20918 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
20919 var type = finishedWork.type;
20920 // TODO: Type the updateQueue to be specific to host components.
20921 var updatePayload = finishedWork.updateQueue;
20922 finishedWork.updateQueue = null;
20923 if (updatePayload !== null) {
20924 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
20925 }
20926 }
20927 return;
20928 }
20929 case HostText:
20930 {
20931 (function () {
20932 if (!(finishedWork.stateNode !== null)) {
20933 {
20934 throw ReactError(Error('This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.'));
20935 }
20936 }
20937 })();
20938 var textInstance = finishedWork.stateNode;
20939 var newText = finishedWork.memoizedProps;
20940 // For hydration we reuse the update path but we treat the oldProps
20941 // as the newProps. The updatePayload will contain the real change in
20942 // this case.
20943 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
20944 commitTextUpdate(textInstance, oldText, newText);
20945 return;
20946 }
20947 case HostRoot:
20948 {
20949 return;
20950 }
20951 case Profiler:
20952 {
20953 return;
20954 }
20955 case SuspenseComponent:
20956 {
20957 commitSuspenseComponent(finishedWork);
20958 attachSuspenseRetryListeners(finishedWork);
20959 return;
20960 }
20961 case SuspenseListComponent:
20962 {
20963 attachSuspenseRetryListeners(finishedWork);
20964 return;
20965 }
20966 case IncompleteClassComponent:
20967 {
20968 return;
20969 }
20970 case FundamentalComponent:
20971 {
20972 if (enableFundamentalAPI) {
20973 var fundamentalInstance = finishedWork.stateNode;
20974 updateFundamentalComponent(fundamentalInstance);
20975 }
20976 return;
20977 }
20978 default:
20979 {
20980 (function () {
20981 {
20982 {
20983 throw ReactError(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.'));
20984 }
20985 }
20986 })();
20987 }
20988 }
20989}
20990
20991function commitSuspenseComponent(finishedWork) {
20992 var newState = finishedWork.memoizedState;
20993
20994 var newDidTimeout = void 0;
20995 var primaryChildParent = finishedWork;
20996 if (newState === null) {
20997 newDidTimeout = false;
20998 } else {
20999 newDidTimeout = true;
21000 primaryChildParent = finishedWork.child;
21001 markCommitTimeOfFallback();
21002 }
21003
21004 if (supportsMutation && primaryChildParent !== null) {
21005 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
21006 }
21007
21008 if (enableSuspenseCallback && newState !== null) {
21009 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
21010 if (typeof suspenseCallback === 'function') {
21011 var thenables = finishedWork.updateQueue;
21012 if (thenables !== null) {
21013 suspenseCallback(new Set(thenables));
21014 }
21015 } else {
21016 if (suspenseCallback !== undefined) {
21017 warning$1(false, 'Unexpected type for suspenseCallback.');
21018 }
21019 }
21020 }
21021}
21022
21023function attachSuspenseRetryListeners(finishedWork) {
21024 // If this boundary just timed out, then it will have a set of thenables.
21025 // For each thenable, attach a listener so that when it resolves, React
21026 var thenables = finishedWork.updateQueue;
21027 if (thenables !== null) {
21028 finishedWork.updateQueue = null;
21029 var retryCache = finishedWork.stateNode;
21030 if (retryCache === null) {
21031 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
21032 }
21033 thenables.forEach(function (thenable) {
21034 // Memoize using the boundary fiber to prevent redundant listeners.
21035 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
21036 if (!retryCache.has(thenable)) {
21037 if (enableSchedulerTracing) {
21038 retry = unstable_wrap(retry);
21039 }
21040 retryCache.add(thenable);
21041 thenable.then(retry, retry);
21042 }
21043 });
21044 }
21045}
21046
21047function commitResetTextContent(current$$1) {
21048 if (!supportsMutation) {
21049 return;
21050 }
21051 resetTextContent(current$$1.stateNode);
21052}
21053
21054var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
21055var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
21056
21057function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
21058 var update = createUpdate(expirationTime, null);
21059 // Unmount the root by rendering null.
21060 update.tag = CaptureUpdate;
21061 // Caution: React DevTools currently depends on this property
21062 // being called "element".
21063 update.payload = { element: null };
21064 var error = errorInfo.value;
21065 update.callback = function () {
21066 onUncaughtError(error);
21067 logError(fiber, errorInfo);
21068 };
21069 return update;
21070}
21071
21072function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
21073 var update = createUpdate(expirationTime, null);
21074 update.tag = CaptureUpdate;
21075 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
21076 if (typeof getDerivedStateFromError === 'function') {
21077 var error = errorInfo.value;
21078 update.payload = function () {
21079 logError(fiber, errorInfo);
21080 return getDerivedStateFromError(error);
21081 };
21082 }
21083
21084 var inst = fiber.stateNode;
21085 if (inst !== null && typeof inst.componentDidCatch === 'function') {
21086 update.callback = function callback() {
21087 {
21088 markFailedErrorBoundaryForHotReloading(fiber);
21089 }
21090 if (typeof getDerivedStateFromError !== 'function') {
21091 // To preserve the preexisting retry behavior of error boundaries,
21092 // we keep track of which ones already failed during this batch.
21093 // This gets reset before we yield back to the browser.
21094 // TODO: Warn in strict mode if getDerivedStateFromError is
21095 // not defined.
21096 markLegacyErrorBoundaryAsFailed(this);
21097
21098 // Only log here if componentDidCatch is the only error boundary method defined
21099 logError(fiber, errorInfo);
21100 }
21101 var error = errorInfo.value;
21102 var stack = errorInfo.stack;
21103 this.componentDidCatch(error, {
21104 componentStack: stack !== null ? stack : ''
21105 });
21106 {
21107 if (typeof getDerivedStateFromError !== 'function') {
21108 // If componentDidCatch is the only error boundary method defined,
21109 // then it needs to call setState to recover from errors.
21110 // If no state update is scheduled then the boundary will swallow the error.
21111 !(fiber.expirationTime === Sync) ? warningWithoutStack$1(false, '%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') : void 0;
21112 }
21113 }
21114 };
21115 } else {
21116 update.callback = function () {
21117 markFailedErrorBoundaryForHotReloading(fiber);
21118 };
21119 }
21120 return update;
21121}
21122
21123function attachPingListener(root, renderExpirationTime, thenable) {
21124 // Attach a listener to the promise to "ping" the root and retry. But
21125 // only if one does not already exist for the current render expiration
21126 // time (which acts like a "thread ID" here).
21127 var pingCache = root.pingCache;
21128 var threadIDs = void 0;
21129 if (pingCache === null) {
21130 pingCache = root.pingCache = new PossiblyWeakMap$1();
21131 threadIDs = new Set();
21132 pingCache.set(thenable, threadIDs);
21133 } else {
21134 threadIDs = pingCache.get(thenable);
21135 if (threadIDs === undefined) {
21136 threadIDs = new Set();
21137 pingCache.set(thenable, threadIDs);
21138 }
21139 }
21140 if (!threadIDs.has(renderExpirationTime)) {
21141 // Memoize using the thread ID to prevent redundant listeners.
21142 threadIDs.add(renderExpirationTime);
21143 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
21144 if (enableSchedulerTracing) {
21145 ping = unstable_wrap(ping);
21146 }
21147 thenable.then(ping, ping);
21148 }
21149}
21150
21151function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
21152 // The source fiber did not complete.
21153 sourceFiber.effectTag |= Incomplete;
21154 // Its effect list is no longer valid.
21155 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
21156
21157 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
21158 // This is a thenable.
21159 var thenable = value;
21160
21161 checkForWrongSuspensePriorityInDEV(sourceFiber);
21162
21163 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext);
21164
21165 // Schedule the nearest Suspense to re-render the timed out view.
21166 var _workInProgress = returnFiber;
21167 do {
21168 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
21169 // Found the nearest boundary.
21170
21171 // Stash the promise on the boundary fiber. If the boundary times out, we'll
21172 var thenables = _workInProgress.updateQueue;
21173 if (thenables === null) {
21174 var updateQueue = new Set();
21175 updateQueue.add(thenable);
21176 _workInProgress.updateQueue = updateQueue;
21177 } else {
21178 thenables.add(thenable);
21179 }
21180
21181 // If the boundary is outside of batched mode, we should *not*
21182 // suspend the commit. Pretend as if the suspended component rendered
21183 // null and keep rendering. In the commit phase, we'll schedule a
21184 // subsequent synchronous update to re-render the Suspense.
21185 //
21186 // Note: It doesn't matter whether the component that suspended was
21187 // inside a batched mode tree. If the Suspense is outside of it, we
21188 // should *not* suspend the commit.
21189 if ((_workInProgress.mode & BatchedMode) === NoMode) {
21190 _workInProgress.effectTag |= DidCapture;
21191
21192 // We're going to commit this fiber even though it didn't complete.
21193 // But we shouldn't call any lifecycle methods or callbacks. Remove
21194 // all lifecycle effect tags.
21195 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
21196
21197 if (sourceFiber.tag === ClassComponent) {
21198 var currentSourceFiber = sourceFiber.alternate;
21199 if (currentSourceFiber === null) {
21200 // This is a new mount. Change the tag so it's not mistaken for a
21201 // completed class component. For example, we should not call
21202 // componentWillUnmount if it is deleted.
21203 sourceFiber.tag = IncompleteClassComponent;
21204 } else {
21205 // When we try rendering again, we should not reuse the current fiber,
21206 // since it's known to be in an inconsistent state. Use a force update to
21207 // prevent a bail out.
21208 var update = createUpdate(Sync, null);
21209 update.tag = ForceUpdate;
21210 enqueueUpdate(sourceFiber, update);
21211 }
21212 }
21213
21214 // The source fiber did not complete. Mark it with Sync priority to
21215 // indicate that it still has pending work.
21216 sourceFiber.expirationTime = Sync;
21217
21218 // Exit without suspending.
21219 return;
21220 }
21221
21222 // Confirmed that the boundary is in a concurrent mode tree. Continue
21223 // with the normal suspend path.
21224 //
21225 // After this we'll use a set of heuristics to determine whether this
21226 // render pass will run to completion or restart or "suspend" the commit.
21227 // The actual logic for this is spread out in different places.
21228 //
21229 // This first principle is that if we're going to suspend when we complete
21230 // a root, then we should also restart if we get an update or ping that
21231 // might unsuspend it, and vice versa. The only reason to suspend is
21232 // because you think you might want to restart before committing. However,
21233 // it doesn't make sense to restart only while in the period we're suspended.
21234 //
21235 // Restarting too aggressively is also not good because it starves out any
21236 // intermediate loading state. So we use heuristics to determine when.
21237
21238 // Suspense Heuristics
21239 //
21240 // If nothing threw a Promise or all the same fallbacks are already showing,
21241 // then don't suspend/restart.
21242 //
21243 // If this is an initial render of a new tree of Suspense boundaries and
21244 // those trigger a fallback, then don't suspend/restart. We want to ensure
21245 // that we can show the initial loading state as quickly as possible.
21246 //
21247 // If we hit a "Delayed" case, such as when we'd switch from content back into
21248 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
21249 // this case. If none is defined, JND is used instead.
21250 //
21251 // If we're already showing a fallback and it gets "retried", allowing us to show
21252 // another level, but there's still an inner boundary that would show a fallback,
21253 // then we suspend/restart for 500ms since the last time we showed a fallback
21254 // anywhere in the tree. This effectively throttles progressive loading into a
21255 // consistent train of commits. This also gives us an opportunity to restart to
21256 // get to the completed state slightly earlier.
21257 //
21258 // If there's ambiguity due to batching it's resolved in preference of:
21259 // 1) "delayed", 2) "initial render", 3) "retry".
21260 //
21261 // We want to ensure that a "busy" state doesn't get force committed. We want to
21262 // ensure that new initial loading states can commit as soon as possible.
21263
21264 attachPingListener(root, renderExpirationTime, thenable);
21265
21266 _workInProgress.effectTag |= ShouldCapture;
21267 _workInProgress.expirationTime = renderExpirationTime;
21268
21269 return;
21270 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
21271 attachPingListener(root, renderExpirationTime, thenable);
21272
21273 // Since we already have a current fiber, we can eagerly add a retry listener.
21274 var retryCache = _workInProgress.memoizedState;
21275 if (retryCache === null) {
21276 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
21277 var current$$1 = _workInProgress.alternate;
21278 (function () {
21279 if (!current$$1) {
21280 {
21281 throw ReactError(Error('A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.'));
21282 }
21283 }
21284 })();
21285 current$$1.memoizedState = retryCache;
21286 }
21287 // Memoize using the boundary fiber to prevent redundant listeners.
21288 if (!retryCache.has(thenable)) {
21289 retryCache.add(thenable);
21290 var retry = resolveRetryThenable.bind(null, _workInProgress, thenable);
21291 if (enableSchedulerTracing) {
21292 retry = unstable_wrap(retry);
21293 }
21294 thenable.then(retry, retry);
21295 }
21296 _workInProgress.effectTag |= ShouldCapture;
21297 _workInProgress.expirationTime = renderExpirationTime;
21298 return;
21299 }
21300 // This boundary already captured during this render. Continue to the next
21301 // boundary.
21302 _workInProgress = _workInProgress.return;
21303 } while (_workInProgress !== null);
21304 // No boundary was found. Fallthrough to error mode.
21305 // TODO: Use invariant so the message is stripped in prod?
21306 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));
21307 }
21308
21309 // We didn't find a boundary that could handle this type of exception. Start
21310 // over and traverse parent path again, this time treating the exception
21311 // as an error.
21312 renderDidError();
21313 value = createCapturedValue(value, sourceFiber);
21314 var workInProgress = returnFiber;
21315 do {
21316 switch (workInProgress.tag) {
21317 case HostRoot:
21318 {
21319 var _errorInfo = value;
21320 workInProgress.effectTag |= ShouldCapture;
21321 workInProgress.expirationTime = renderExpirationTime;
21322 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
21323 enqueueCapturedUpdate(workInProgress, _update);
21324 return;
21325 }
21326 case ClassComponent:
21327 // Capture and retry
21328 var errorInfo = value;
21329 var ctor = workInProgress.type;
21330 var instance = workInProgress.stateNode;
21331 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
21332 workInProgress.effectTag |= ShouldCapture;
21333 workInProgress.expirationTime = renderExpirationTime;
21334 // Schedule the error boundary to re-render using updated state
21335 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
21336 enqueueCapturedUpdate(workInProgress, _update2);
21337 return;
21338 }
21339 break;
21340 default:
21341 break;
21342 }
21343 workInProgress = workInProgress.return;
21344 } while (workInProgress !== null);
21345}
21346
21347// The scheduler is imported here *only* to detect whether it's been mocked
21348// DEV stuff
21349var ceil = Math.ceil;
21350
21351var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
21352var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
21353var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
21354
21355
21356var NoContext = /* */0;
21357var BatchedContext = /* */1;
21358var EventContext = /* */2;
21359var DiscreteEventContext = /* */4;
21360var LegacyUnbatchedContext = /* */8;
21361var RenderContext = /* */16;
21362var CommitContext = /* */32;
21363
21364var RootIncomplete = 0;
21365var RootErrored = 1;
21366var RootSuspended = 2;
21367var RootSuspendedWithDelay = 3;
21368var RootCompleted = 4;
21369
21370// Describes where we are in the React execution stack
21371var executionContext = NoContext;
21372// The root we're working on
21373var workInProgressRoot = null;
21374// The fiber we're working on
21375var workInProgress = null;
21376// The expiration time we're rendering
21377var renderExpirationTime = NoWork;
21378// Whether to root completed, errored, suspended, etc.
21379var workInProgressRootExitStatus = RootIncomplete;
21380// Most recent event time among processed updates during this render.
21381// This is conceptually a time stamp but expressed in terms of an ExpirationTime
21382// because we deal mostly with expiration times in the hot path, so this avoids
21383// the conversion happening in the hot path.
21384var workInProgressRootLatestProcessedExpirationTime = Sync;
21385var workInProgressRootLatestSuspenseTimeout = Sync;
21386var workInProgressRootCanSuspendUsingConfig = null;
21387// If we're pinged while rendering we don't always restart immediately.
21388// This flag determines if it might be worthwhile to restart if an opportunity
21389// happens latere.
21390var workInProgressRootHasPendingPing = false;
21391// The most recent time we committed a fallback. This lets us ensure a train
21392// model where we don't commit new loading states in too quick succession.
21393var globalMostRecentFallbackTime = 0;
21394var FALLBACK_THROTTLE_MS = 500;
21395
21396var nextEffect = null;
21397var hasUncaughtError = false;
21398var firstUncaughtError = null;
21399var legacyErrorBoundariesThatAlreadyFailed = null;
21400
21401var rootDoesHavePassiveEffects = false;
21402var rootWithPendingPassiveEffects = null;
21403var pendingPassiveEffectsRenderPriority = NoPriority;
21404var pendingPassiveEffectsExpirationTime = NoWork;
21405
21406var rootsWithPendingDiscreteUpdates = null;
21407
21408// Use these to prevent an infinite loop of nested updates
21409var NESTED_UPDATE_LIMIT = 50;
21410var nestedUpdateCount = 0;
21411var rootWithNestedUpdates = null;
21412
21413var NESTED_PASSIVE_UPDATE_LIMIT = 50;
21414var nestedPassiveUpdateCount = 0;
21415
21416var interruptedBy = null;
21417
21418// Marks the need to reschedule pending interactions at these expiration times
21419// during the commit phase. This enables them to be traced across components
21420// that spawn new work during render. E.g. hidden boundaries, suspended SSR
21421// hydration or SuspenseList.
21422var spawnedWorkDuringRender = null;
21423
21424// Expiration times are computed by adding to the current time (the start
21425// time). However, if two updates are scheduled within the same event, we
21426// should treat their start times as simultaneous, even if the actual clock
21427// time has advanced between the first and second call.
21428
21429// In other words, because expiration times determine how updates are batched,
21430// we want all updates of like priority that occur within the same event to
21431// receive the same expiration time. Otherwise we get tearing.
21432var currentEventTime = NoWork;
21433
21434function requestCurrentTime() {
21435 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21436 // We're inside React, so it's fine to read the actual time.
21437 return msToExpirationTime(now());
21438 }
21439 // We're not inside React, so we may be in the middle of a browser event.
21440 if (currentEventTime !== NoWork) {
21441 // Use the same start time for all updates until we enter React again.
21442 return currentEventTime;
21443 }
21444 // This is the first update since React yielded. Compute a new start time.
21445 currentEventTime = msToExpirationTime(now());
21446 return currentEventTime;
21447}
21448
21449function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
21450 var mode = fiber.mode;
21451 if ((mode & BatchedMode) === NoMode) {
21452 return Sync;
21453 }
21454
21455 var priorityLevel = getCurrentPriorityLevel();
21456 if ((mode & ConcurrentMode) === NoMode) {
21457 return priorityLevel === ImmediatePriority ? Sync : Batched;
21458 }
21459
21460 if ((executionContext & RenderContext) !== NoContext) {
21461 // Use whatever time we're already rendering
21462 return renderExpirationTime;
21463 }
21464
21465 var expirationTime = void 0;
21466 if (suspenseConfig !== null) {
21467 // Compute an expiration time based on the Suspense timeout.
21468 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
21469 } else {
21470 // Compute an expiration time based on the Scheduler priority.
21471 switch (priorityLevel) {
21472 case ImmediatePriority:
21473 expirationTime = Sync;
21474 break;
21475 case UserBlockingPriority$2:
21476 // TODO: Rename this to computeUserBlockingExpiration
21477 expirationTime = computeInteractiveExpiration(currentTime);
21478 break;
21479 case NormalPriority:
21480 case LowPriority:
21481 // TODO: Handle LowPriority
21482 // TODO: Rename this to... something better.
21483 expirationTime = computeAsyncExpiration(currentTime);
21484 break;
21485 case IdlePriority:
21486 expirationTime = Never;
21487 break;
21488 default:
21489 (function () {
21490 {
21491 {
21492 throw ReactError(Error('Expected a valid priority level'));
21493 }
21494 }
21495 })();
21496 }
21497 }
21498
21499 // If we're in the middle of rendering a tree, do not update at the same
21500 // expiration time that is already rendering.
21501 // TODO: We shouldn't have to do this if the update is on a different root.
21502 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
21503 // the root when we check for this condition.
21504 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
21505 // This is a trick to move this update into a separate batch
21506 expirationTime -= 1;
21507 }
21508
21509 return expirationTime;
21510}
21511
21512var lastUniqueAsyncExpiration = NoWork;
21513function computeUniqueAsyncExpiration() {
21514 var currentTime = requestCurrentTime();
21515 var result = computeAsyncExpiration(currentTime);
21516 if (result <= lastUniqueAsyncExpiration) {
21517 // Since we assume the current time monotonically increases, we only hit
21518 // this branch when computeUniqueAsyncExpiration is fired multiple times
21519 // within a 200ms window (or whatever the async bucket size is).
21520 result -= 1;
21521 }
21522 lastUniqueAsyncExpiration = result;
21523 return result;
21524}
21525
21526function scheduleUpdateOnFiber(fiber, expirationTime) {
21527 checkForNestedUpdates();
21528 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
21529
21530 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
21531 if (root === null) {
21532 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
21533 return;
21534 }
21535
21536 root.pingTime = NoWork;
21537
21538 checkForInterruption(fiber, expirationTime);
21539 recordScheduleUpdate();
21540
21541 // TODO: computeExpirationForFiber also reads the priority. Pass the
21542 // priority as an argument to that function and this one.
21543 var priorityLevel = getCurrentPriorityLevel();
21544
21545 if (expirationTime === Sync) {
21546 if (
21547 // Check if we're inside unbatchedUpdates
21548 (executionContext & LegacyUnbatchedContext) !== NoContext &&
21549 // Check if we're not already rendering
21550 (executionContext & (RenderContext | CommitContext)) === NoContext) {
21551 // Register pending interactions on the root to avoid losing traced interaction data.
21552 schedulePendingInteractions(root, expirationTime);
21553
21554 // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
21555 // root inside of batchedUpdates should be synchronous, but layout updates
21556 // should be deferred until the end of the batch.
21557 var callback = renderRoot(root, Sync, true);
21558 while (callback !== null) {
21559 callback = callback(true);
21560 }
21561 } else {
21562 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
21563 if (executionContext === NoContext) {
21564 // Flush the synchronous work now, wnless we're already working or inside
21565 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
21566 // scheduleCallbackForFiber to preserve the ability to schedule a callback
21567 // without immediately flushing it. We only do this for user-initiated
21568 // updates, to preserve historical behavior of sync mode.
21569 flushSyncCallbackQueue();
21570 }
21571 }
21572 } else {
21573 scheduleCallbackForRoot(root, priorityLevel, expirationTime);
21574 }
21575
21576 if ((executionContext & DiscreteEventContext) !== NoContext && (
21577 // Only updates at user-blocking priority or greater are considered
21578 // discrete, even inside a discrete event.
21579 priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority)) {
21580 // This is the result of a discrete event. Track the lowest priority
21581 // discrete update per root so we can flush them early, if needed.
21582 if (rootsWithPendingDiscreteUpdates === null) {
21583 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
21584 } else {
21585 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
21586 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
21587 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
21588 }
21589 }
21590 }
21591}
21592var scheduleWork = scheduleUpdateOnFiber;
21593
21594// This is split into a separate function so we can mark a fiber with pending
21595// work without treating it as a typical update that originates from an event;
21596// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
21597// on a fiber.
21598function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
21599 // Update the source fiber's expiration time
21600 if (fiber.expirationTime < expirationTime) {
21601 fiber.expirationTime = expirationTime;
21602 }
21603 var alternate = fiber.alternate;
21604 if (alternate !== null && alternate.expirationTime < expirationTime) {
21605 alternate.expirationTime = expirationTime;
21606 }
21607 // Walk the parent path to the root and update the child expiration time.
21608 var node = fiber.return;
21609 var root = null;
21610 if (node === null && fiber.tag === HostRoot) {
21611 root = fiber.stateNode;
21612 } else {
21613 while (node !== null) {
21614 alternate = node.alternate;
21615 if (node.childExpirationTime < expirationTime) {
21616 node.childExpirationTime = expirationTime;
21617 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21618 alternate.childExpirationTime = expirationTime;
21619 }
21620 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
21621 alternate.childExpirationTime = expirationTime;
21622 }
21623 if (node.return === null && node.tag === HostRoot) {
21624 root = node.stateNode;
21625 break;
21626 }
21627 node = node.return;
21628 }
21629 }
21630
21631 if (root !== null) {
21632 // Update the first and last pending expiration times in this root
21633 var firstPendingTime = root.firstPendingTime;
21634 if (expirationTime > firstPendingTime) {
21635 root.firstPendingTime = expirationTime;
21636 }
21637 var lastPendingTime = root.lastPendingTime;
21638 if (lastPendingTime === NoWork || expirationTime < lastPendingTime) {
21639 root.lastPendingTime = expirationTime;
21640 }
21641 }
21642
21643 return root;
21644}
21645
21646// Use this function, along with runRootCallback, to ensure that only a single
21647// callback per root is scheduled. It's still possible to call renderRoot
21648// directly, but scheduling via this function helps avoid excessive callbacks.
21649// It works by storing the callback node and expiration time on the root. When a
21650// new callback comes in, it compares the expiration time to determine if it
21651// should cancel the previous one. It also relies on commitRoot scheduling a
21652// callback to render the next level, because that means we don't need a
21653// separate callback per expiration time.
21654function scheduleCallbackForRoot(root, priorityLevel, expirationTime) {
21655 var existingCallbackExpirationTime = root.callbackExpirationTime;
21656 if (existingCallbackExpirationTime < expirationTime) {
21657 // New callback has higher priority than the existing one.
21658 var existingCallbackNode = root.callbackNode;
21659 if (existingCallbackNode !== null) {
21660 cancelCallback(existingCallbackNode);
21661 }
21662 root.callbackExpirationTime = expirationTime;
21663
21664 if (expirationTime === Sync) {
21665 // Sync React callbacks are scheduled on a special internal queue
21666 root.callbackNode = scheduleSyncCallback(runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)));
21667 } else {
21668 var options = null;
21669 if (!disableSchedulerTimeoutBasedOnReactExpirationTime && expirationTime !== Never) {
21670 var timeout = expirationTimeToMs(expirationTime) - now();
21671 options = { timeout: timeout };
21672 }
21673
21674 root.callbackNode = scheduleCallback(priorityLevel, runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)), options);
21675 if (enableUserTimingAPI && expirationTime !== Sync && (executionContext & (RenderContext | CommitContext)) === NoContext) {
21676 // Scheduled an async callback, and we're not already working. Add an
21677 // entry to the flamegraph that shows we're waiting for a callback
21678 // to fire.
21679 startRequestCallbackTimer();
21680 }
21681 }
21682 }
21683
21684 // Associate the current interactions with this new root+priority.
21685 schedulePendingInteractions(root, expirationTime);
21686}
21687
21688function runRootCallback(root, callback, isSync) {
21689 var prevCallbackNode = root.callbackNode;
21690 var continuation = null;
21691 try {
21692 continuation = callback(isSync);
21693 if (continuation !== null) {
21694 return runRootCallback.bind(null, root, continuation);
21695 } else {
21696 return null;
21697 }
21698 } finally {
21699 // If the callback exits without returning a continuation, remove the
21700 // corresponding callback node from the root. Unless the callback node
21701 // has changed, which implies that it was already cancelled by a high
21702 // priority update.
21703 if (continuation === null && prevCallbackNode === root.callbackNode) {
21704 root.callbackNode = null;
21705 root.callbackExpirationTime = NoWork;
21706 }
21707 }
21708}
21709
21710function flushRoot(root, expirationTime) {
21711 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21712 (function () {
21713 {
21714 {
21715 throw ReactError(Error('work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.'));
21716 }
21717 }
21718 })();
21719 }
21720 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
21721 flushSyncCallbackQueue();
21722}
21723
21724function flushDiscreteUpdates() {
21725 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
21726 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
21727 // those two cases. Need to fix this before exposing flushDiscreteUpdates
21728 // as a public API.
21729 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {
21730 if (true && (executionContext & RenderContext) !== NoContext) {
21731 warning$1(false, 'unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');
21732 }
21733 // We're already rendering, so we can't synchronously flush pending work.
21734 // This is probably a nested event dispatch triggered by a lifecycle/effect,
21735 // like `el.focus()`. Exit.
21736 return;
21737 }
21738 flushPendingDiscreteUpdates();
21739 if (!revertPassiveEffectsChange) {
21740 // If the discrete updates scheduled passive effects, flush them now so that
21741 // they fire before the next serial event.
21742 flushPassiveEffects();
21743 }
21744}
21745
21746function resolveLocksOnRoot(root, expirationTime) {
21747 var firstBatch = root.firstBatch;
21748 if (firstBatch !== null && firstBatch._defer && firstBatch._expirationTime >= expirationTime) {
21749 scheduleCallback(NormalPriority, function () {
21750 firstBatch._onComplete();
21751 return null;
21752 });
21753 return true;
21754 } else {
21755 return false;
21756 }
21757}
21758
21759
21760
21761
21762
21763function flushPendingDiscreteUpdates() {
21764 if (rootsWithPendingDiscreteUpdates !== null) {
21765 // For each root with pending discrete updates, schedule a callback to
21766 // immediately flush them.
21767 var roots = rootsWithPendingDiscreteUpdates;
21768 rootsWithPendingDiscreteUpdates = null;
21769 roots.forEach(function (expirationTime, root) {
21770 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
21771 });
21772 // Now flush the immediate queue.
21773 flushSyncCallbackQueue();
21774 }
21775}
21776
21777function batchedUpdates$1(fn, a) {
21778 var prevExecutionContext = executionContext;
21779 executionContext |= BatchedContext;
21780 try {
21781 return fn(a);
21782 } finally {
21783 executionContext = prevExecutionContext;
21784 if (executionContext === NoContext) {
21785 // Flush the immediate callbacks that were scheduled during this batch
21786 flushSyncCallbackQueue();
21787 }
21788 }
21789}
21790
21791function batchedEventUpdates$1(fn, a) {
21792 var prevExecutionContext = executionContext;
21793 executionContext |= EventContext;
21794 try {
21795 return fn(a);
21796 } finally {
21797 executionContext = prevExecutionContext;
21798 if (executionContext === NoContext) {
21799 // Flush the immediate callbacks that were scheduled during this batch
21800 flushSyncCallbackQueue();
21801 }
21802 }
21803}
21804
21805function discreteUpdates$1(fn, a, b, c) {
21806 var prevExecutionContext = executionContext;
21807 executionContext |= DiscreteEventContext;
21808 try {
21809 // Should this
21810 return runWithPriority$2(UserBlockingPriority$2, fn.bind(null, a, b, c));
21811 } finally {
21812 executionContext = prevExecutionContext;
21813 if (executionContext === NoContext) {
21814 // Flush the immediate callbacks that were scheduled during this batch
21815 flushSyncCallbackQueue();
21816 }
21817 }
21818}
21819
21820function unbatchedUpdates(fn, a) {
21821 var prevExecutionContext = executionContext;
21822 executionContext &= ~BatchedContext;
21823 executionContext |= LegacyUnbatchedContext;
21824 try {
21825 return fn(a);
21826 } finally {
21827 executionContext = prevExecutionContext;
21828 if (executionContext === NoContext) {
21829 // Flush the immediate callbacks that were scheduled during this batch
21830 flushSyncCallbackQueue();
21831 }
21832 }
21833}
21834
21835function flushSync(fn, a) {
21836 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
21837 (function () {
21838 {
21839 {
21840 throw ReactError(Error('flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.'));
21841 }
21842 }
21843 })();
21844 }
21845 var prevExecutionContext = executionContext;
21846 executionContext |= BatchedContext;
21847 try {
21848 return runWithPriority$2(ImmediatePriority, fn.bind(null, a));
21849 } finally {
21850 executionContext = prevExecutionContext;
21851 // Flush the immediate callbacks that were scheduled during this batch.
21852 // Note that this will happen even if batchedUpdates is higher up
21853 // the stack.
21854 flushSyncCallbackQueue();
21855 }
21856}
21857
21858function flushControlled(fn) {
21859 var prevExecutionContext = executionContext;
21860 executionContext |= BatchedContext;
21861 try {
21862 runWithPriority$2(ImmediatePriority, fn);
21863 } finally {
21864 executionContext = prevExecutionContext;
21865 if (executionContext === NoContext) {
21866 // Flush the immediate callbacks that were scheduled during this batch
21867 flushSyncCallbackQueue();
21868 }
21869 }
21870}
21871
21872function prepareFreshStack(root, expirationTime) {
21873 root.finishedWork = null;
21874 root.finishedExpirationTime = NoWork;
21875
21876 var timeoutHandle = root.timeoutHandle;
21877 if (timeoutHandle !== noTimeout) {
21878 // The root previous suspended and scheduled a timeout to commit a fallback
21879 // state. Now that we have additional work, cancel the timeout.
21880 root.timeoutHandle = noTimeout;
21881 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
21882 cancelTimeout(timeoutHandle);
21883 }
21884
21885 if (workInProgress !== null) {
21886 var interruptedWork = workInProgress.return;
21887 while (interruptedWork !== null) {
21888 unwindInterruptedWork(interruptedWork);
21889 interruptedWork = interruptedWork.return;
21890 }
21891 }
21892 workInProgressRoot = root;
21893 workInProgress = createWorkInProgress(root.current, null, expirationTime);
21894 renderExpirationTime = expirationTime;
21895 workInProgressRootExitStatus = RootIncomplete;
21896 workInProgressRootLatestProcessedExpirationTime = Sync;
21897 workInProgressRootLatestSuspenseTimeout = Sync;
21898 workInProgressRootCanSuspendUsingConfig = null;
21899 workInProgressRootHasPendingPing = false;
21900
21901 if (enableSchedulerTracing) {
21902 spawnedWorkDuringRender = null;
21903 }
21904
21905 {
21906 ReactStrictModeWarnings.discardPendingWarnings();
21907 componentsThatTriggeredHighPriSuspend = null;
21908 }
21909}
21910
21911function renderRoot(root, expirationTime, isSync) {
21912 (function () {
21913 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
21914 {
21915 throw ReactError(Error('Should not already be working.'));
21916 }
21917 }
21918 })();
21919
21920 if (enableUserTimingAPI && expirationTime !== Sync) {
21921 var didExpire = isSync;
21922 stopRequestCallbackTimer(didExpire);
21923 }
21924
21925 if (root.firstPendingTime < expirationTime) {
21926 // If there's no work left at this expiration time, exit immediately. This
21927 // happens when multiple callbacks are scheduled for a single root, but an
21928 // earlier callback flushes the work of a later one.
21929 return null;
21930 }
21931
21932 if (isSync && root.finishedExpirationTime === expirationTime) {
21933 // There's already a pending commit at this expiration time.
21934 // TODO: This is poorly factored. This case only exists for the
21935 // batch.commit() API.
21936 return commitRoot.bind(null, root);
21937 }
21938
21939 flushPassiveEffects();
21940
21941 // If the root or expiration time have changed, throw out the existing stack
21942 // and prepare a fresh one. Otherwise we'll continue where we left off.
21943 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
21944 prepareFreshStack(root, expirationTime);
21945 startWorkOnPendingInteractions(root, expirationTime);
21946 } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
21947 // We could've received an update at a lower priority while we yielded.
21948 // We're suspended in a delayed state. Once we complete this render we're
21949 // just going to try to recover at the last pending time anyway so we might
21950 // as well start doing that eagerly.
21951 // Ideally we should be able to do this even for retries but we don't yet
21952 // know if we're going to process an update which wants to commit earlier,
21953 // and this path happens very early so it would happen too often. Instead,
21954 // for that case, we'll wait until we complete.
21955 if (workInProgressRootHasPendingPing) {
21956 // We have a ping at this expiration. Let's restart to see if we get unblocked.
21957 prepareFreshStack(root, expirationTime);
21958 } else {
21959 var lastPendingTime = root.lastPendingTime;
21960 if (lastPendingTime < expirationTime) {
21961 // There's lower priority work. It might be unsuspended. Try rendering
21962 // at that level immediately, while preserving the position in the queue.
21963 return renderRoot.bind(null, root, lastPendingTime);
21964 }
21965 }
21966 }
21967
21968 // If we have a work-in-progress fiber, it means there's still work to do
21969 // in this root.
21970 if (workInProgress !== null) {
21971 var prevExecutionContext = executionContext;
21972 executionContext |= RenderContext;
21973 var prevDispatcher = ReactCurrentDispatcher.current;
21974 if (prevDispatcher === null) {
21975 // The React isomorphic package does not include a default dispatcher.
21976 // Instead the first renderer will lazily attach one, in order to give
21977 // nicer error messages.
21978 prevDispatcher = ContextOnlyDispatcher;
21979 }
21980 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
21981 var prevInteractions = null;
21982 if (enableSchedulerTracing) {
21983 prevInteractions = __interactionsRef.current;
21984 __interactionsRef.current = root.memoizedInteractions;
21985 }
21986
21987 startWorkLoopTimer(workInProgress);
21988
21989 // TODO: Fork renderRoot into renderRootSync and renderRootAsync
21990 if (isSync) {
21991 if (expirationTime !== Sync) {
21992 // An async update expired. There may be other expired updates on
21993 // this root. We should render all the expired work in a
21994 // single batch.
21995 var currentTime = requestCurrentTime();
21996 if (currentTime < expirationTime) {
21997 // Restart at the current time.
21998 executionContext = prevExecutionContext;
21999 resetContextDependencies();
22000 ReactCurrentDispatcher.current = prevDispatcher;
22001 if (enableSchedulerTracing) {
22002 __interactionsRef.current = prevInteractions;
22003 }
22004 return renderRoot.bind(null, root, currentTime);
22005 }
22006 }
22007 } else {
22008 // Since we know we're in a React event, we can clear the current
22009 // event time. The next update will compute a new event time.
22010 currentEventTime = NoWork;
22011 }
22012
22013 do {
22014 try {
22015 if (isSync) {
22016 workLoopSync();
22017 } else {
22018 workLoop();
22019 }
22020 break;
22021 } catch (thrownValue) {
22022 // Reset module-level state that was set during the render phase.
22023 resetContextDependencies();
22024 resetHooks();
22025
22026 var sourceFiber = workInProgress;
22027 if (sourceFiber === null || sourceFiber.return === null) {
22028 // Expected to be working on a non-root fiber. This is a fatal error
22029 // because there's no ancestor that can handle it; the root is
22030 // supposed to capture all errors that weren't caught by an error
22031 // boundary.
22032 prepareFreshStack(root, expirationTime);
22033 executionContext = prevExecutionContext;
22034 throw thrownValue;
22035 }
22036
22037 if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {
22038 // Record the time spent rendering before an error was thrown. This
22039 // avoids inaccurate Profiler durations in the case of a
22040 // suspended render.
22041 stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);
22042 }
22043
22044 var returnFiber = sourceFiber.return;
22045 throwException(root, returnFiber, sourceFiber, thrownValue, renderExpirationTime);
22046 workInProgress = completeUnitOfWork(sourceFiber);
22047 }
22048 } while (true);
22049
22050 executionContext = prevExecutionContext;
22051 resetContextDependencies();
22052 ReactCurrentDispatcher.current = prevDispatcher;
22053 if (enableSchedulerTracing) {
22054 __interactionsRef.current = prevInteractions;
22055 }
22056
22057 if (workInProgress !== null) {
22058 // There's still work left over. Return a continuation.
22059 stopInterruptedWorkLoopTimer();
22060 if (expirationTime !== Sync) {
22061 startRequestCallbackTimer();
22062 }
22063 return renderRoot.bind(null, root, expirationTime);
22064 }
22065 }
22066
22067 // We now have a consistent tree. The next step is either to commit it, or, if
22068 // something suspended, wait to commit it after a timeout.
22069 stopFinishedWorkLoopTimer();
22070
22071 root.finishedWork = root.current.alternate;
22072 root.finishedExpirationTime = expirationTime;
22073
22074 var isLocked = resolveLocksOnRoot(root, expirationTime);
22075 if (isLocked) {
22076 // This root has a lock that prevents it from committing. Exit. If we begin
22077 // work on the root again, without any intervening updates, it will finish
22078 // without doing additional work.
22079 return null;
22080 }
22081
22082 // Set this to null to indicate there's no in-progress render.
22083 workInProgressRoot = null;
22084
22085 switch (workInProgressRootExitStatus) {
22086 case RootIncomplete:
22087 {
22088 (function () {
22089 {
22090 {
22091 throw ReactError(Error('Should have a work-in-progress.'));
22092 }
22093 }
22094 })();
22095 }
22096 // Flow knows about invariant, so it complains if I add a break statement,
22097 // but eslint doesn't know about invariant, so it complains if I do.
22098 // eslint-disable-next-line no-fallthrough
22099 case RootErrored:
22100 {
22101 // An error was thrown. First check if there is lower priority work
22102 // scheduled on this root.
22103 var _lastPendingTime = root.lastPendingTime;
22104 if (_lastPendingTime < expirationTime) {
22105 // There's lower priority work. Before raising the error, try rendering
22106 // at the lower priority to see if it fixes it. Use a continuation to
22107 // maintain the existing priority and position in the queue.
22108 return renderRoot.bind(null, root, _lastPendingTime);
22109 }
22110 if (!isSync) {
22111 // If we're rendering asynchronously, it's possible the error was
22112 // caused by tearing due to a mutation during an event. Try rendering
22113 // one more time without yiedling to events.
22114 prepareFreshStack(root, expirationTime);
22115 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
22116 return null;
22117 }
22118 // If we're already rendering synchronously, commit the root in its
22119 // errored state.
22120 return commitRoot.bind(null, root);
22121 }
22122 case RootSuspended:
22123 {
22124 flushSuspensePriorityWarningInDEV();
22125
22126 // We have an acceptable loading state. We need to figure out if we should
22127 // immediately commit it or wait a bit.
22128
22129 // If we have processed new updates during this render, we may now have a
22130 // new loading state ready. We want to ensure that we commit that as soon as
22131 // possible.
22132 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
22133 if (hasNotProcessedNewUpdates && !isSync &&
22134 // do not delay if we're inside an act() scope
22135 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
22136 // If we have not processed any new updates during this pass, then this is
22137 // either a retry of an existing fallback state or a hidden tree.
22138 // Hidden trees shouldn't be batched with other work and after that's
22139 // fixed it can only be a retry.
22140 // We're going to throttle committing retries so that we don't show too
22141 // many loading states too quickly.
22142 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
22143 // Don't bother with a very short suspense time.
22144 if (msUntilTimeout > 10) {
22145 if (workInProgressRootHasPendingPing) {
22146 // This render was pinged but we didn't get to restart earlier so try
22147 // restarting now instead.
22148 prepareFreshStack(root, expirationTime);
22149 return renderRoot.bind(null, root, expirationTime);
22150 }
22151 var _lastPendingTime2 = root.lastPendingTime;
22152 if (_lastPendingTime2 < expirationTime) {
22153 // There's lower priority work. It might be unsuspended. Try rendering
22154 // at that level.
22155 return renderRoot.bind(null, root, _lastPendingTime2);
22156 }
22157 // The render is suspended, it hasn't timed out, and there's no lower
22158 // priority work to do. Instead of committing the fallback
22159 // immediately, wait for more data to arrive.
22160 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
22161 return null;
22162 }
22163 }
22164 // The work expired. Commit immediately.
22165 return commitRoot.bind(null, root);
22166 }
22167 case RootSuspendedWithDelay:
22168 {
22169 flushSuspensePriorityWarningInDEV();
22170
22171 if (!isSync &&
22172 // do not delay if we're inside an act() scope
22173 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
22174 // We're suspended in a state that should be avoided. We'll try to avoid committing
22175 // it for as long as the timeouts let us.
22176 if (workInProgressRootHasPendingPing) {
22177 // This render was pinged but we didn't get to restart earlier so try
22178 // restarting now instead.
22179 prepareFreshStack(root, expirationTime);
22180 return renderRoot.bind(null, root, expirationTime);
22181 }
22182 var _lastPendingTime3 = root.lastPendingTime;
22183 if (_lastPendingTime3 < expirationTime) {
22184 // There's lower priority work. It might be unsuspended. Try rendering
22185 // at that level immediately.
22186 return renderRoot.bind(null, root, _lastPendingTime3);
22187 }
22188
22189 var _msUntilTimeout = void 0;
22190 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
22191 // We have processed a suspense config whose expiration time we can use as
22192 // the timeout.
22193 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
22194 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
22195 // This should never normally happen because only new updates cause
22196 // delayed states, so we should have processed something. However,
22197 // this could also happen in an offscreen tree.
22198 _msUntilTimeout = 0;
22199 } else {
22200 // If we don't have a suspense config, we're going to use a heuristic to
22201 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
22202 var currentTimeMs = now();
22203 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
22204 var timeElapsed = currentTimeMs - eventTimeMs;
22205 if (timeElapsed < 0) {
22206 // We get this wrong some time since we estimate the time.
22207 timeElapsed = 0;
22208 }
22209
22210 _msUntilTimeout = jnd(timeElapsed) - timeElapsed;
22211
22212 // Clamp the timeout to the expiration time.
22213 // TODO: Once the event time is exact instead of inferred from expiration time
22214 // we don't need this.
22215 if (timeUntilExpirationMs < _msUntilTimeout) {
22216 _msUntilTimeout = timeUntilExpirationMs;
22217 }
22218 }
22219
22220 // Don't bother with a very short suspense time.
22221 if (_msUntilTimeout > 10) {
22222 // The render is suspended, it hasn't timed out, and there's no lower
22223 // priority work to do. Instead of committing the fallback
22224 // immediately, wait for more data to arrive.
22225 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
22226 return null;
22227 }
22228 }
22229 // The work expired. Commit immediately.
22230 return commitRoot.bind(null, root);
22231 }
22232 case RootCompleted:
22233 {
22234 // The work completed. Ready to commit.
22235 if (!isSync &&
22236 // do not delay if we're inside an act() scope
22237 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
22238 // If we have exceeded the minimum loading delay, which probably
22239 // means we have shown a spinner already, we might have to suspend
22240 // a bit longer to ensure that the spinner is shown for enough time.
22241 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
22242 if (_msUntilTimeout2 > 10) {
22243 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
22244 return null;
22245 }
22246 }
22247 return commitRoot.bind(null, root);
22248 }
22249 default:
22250 {
22251 (function () {
22252 {
22253 {
22254 throw ReactError(Error('Unknown root exit status.'));
22255 }
22256 }
22257 })();
22258 }
22259 }
22260}
22261
22262function markCommitTimeOfFallback() {
22263 globalMostRecentFallbackTime = now();
22264}
22265
22266function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
22267 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Never) {
22268 workInProgressRootLatestProcessedExpirationTime = expirationTime;
22269 }
22270 if (suspenseConfig !== null) {
22271 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Never) {
22272 workInProgressRootLatestSuspenseTimeout = expirationTime;
22273 // Most of the time we only have one config and getting wrong is not bad.
22274 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
22275 }
22276 }
22277}
22278
22279function renderDidSuspend() {
22280 if (workInProgressRootExitStatus === RootIncomplete) {
22281 workInProgressRootExitStatus = RootSuspended;
22282 }
22283}
22284
22285function renderDidSuspendDelayIfPossible() {
22286 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
22287 workInProgressRootExitStatus = RootSuspendedWithDelay;
22288 }
22289}
22290
22291function renderDidError() {
22292 if (workInProgressRootExitStatus !== RootCompleted) {
22293 workInProgressRootExitStatus = RootErrored;
22294 }
22295}
22296
22297// Called during render to determine if anything has suspended.
22298// Returns false if we're not sure.
22299function renderHasNotSuspendedYet() {
22300 // If something errored or completed, we can't really be sure,
22301 // so those are false.
22302 return workInProgressRootExitStatus === RootIncomplete;
22303}
22304
22305function inferTimeFromExpirationTime(expirationTime) {
22306 // We don't know exactly when the update was scheduled, but we can infer an
22307 // approximate start time from the expiration time.
22308 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22309 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
22310}
22311
22312function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
22313 // We don't know exactly when the update was scheduled, but we can infer an
22314 // approximate start time from the expiration time by subtracting the timeout
22315 // that was added to the event time.
22316 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
22317 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
22318}
22319
22320function workLoopSync() {
22321 // Already timed out, so perform work without checking if we need to yield.
22322 while (workInProgress !== null) {
22323 workInProgress = performUnitOfWork(workInProgress);
22324 }
22325}
22326
22327function workLoop() {
22328 // Perform work until Scheduler asks us to yield
22329 while (workInProgress !== null && !shouldYield()) {
22330 workInProgress = performUnitOfWork(workInProgress);
22331 }
22332}
22333
22334function performUnitOfWork(unitOfWork) {
22335 // The current, flushed, state of this fiber is the alternate. Ideally
22336 // nothing should rely on this, but relying on it here means that we don't
22337 // need an additional field on the work in progress.
22338 var current$$1 = unitOfWork.alternate;
22339
22340 startWorkTimer(unitOfWork);
22341 setCurrentFiber(unitOfWork);
22342
22343 var next = void 0;
22344 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
22345 startProfilerTimer(unitOfWork);
22346 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
22347 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
22348 } else {
22349 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
22350 }
22351
22352 resetCurrentFiber();
22353 unitOfWork.memoizedProps = unitOfWork.pendingProps;
22354 if (next === null) {
22355 // If this doesn't spawn new work, complete the current work.
22356 next = completeUnitOfWork(unitOfWork);
22357 }
22358
22359 ReactCurrentOwner$2.current = null;
22360 return next;
22361}
22362
22363function completeUnitOfWork(unitOfWork) {
22364 // Attempt to complete the current unit of work, then move to the next
22365 // sibling. If there are no more siblings, return to the parent fiber.
22366 workInProgress = unitOfWork;
22367 do {
22368 // The current, flushed, state of this fiber is the alternate. Ideally
22369 // nothing should rely on this, but relying on it here means that we don't
22370 // need an additional field on the work in progress.
22371 var current$$1 = workInProgress.alternate;
22372 var returnFiber = workInProgress.return;
22373
22374 // Check if the work completed or if something threw.
22375 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
22376 setCurrentFiber(workInProgress);
22377 var next = void 0;
22378 if (!enableProfilerTimer || (workInProgress.mode & ProfileMode) === NoMode) {
22379 next = completeWork(current$$1, workInProgress, renderExpirationTime);
22380 } else {
22381 startProfilerTimer(workInProgress);
22382 next = completeWork(current$$1, workInProgress, renderExpirationTime);
22383 // Update render duration assuming we didn't error.
22384 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
22385 }
22386 stopWorkTimer(workInProgress);
22387 resetCurrentFiber();
22388 resetChildExpirationTime(workInProgress);
22389
22390 if (next !== null) {
22391 // Completing this fiber spawned new work. Work on that next.
22392 return next;
22393 }
22394
22395 if (returnFiber !== null &&
22396 // Do not append effects to parents if a sibling failed to complete
22397 (returnFiber.effectTag & Incomplete) === NoEffect) {
22398 // Append all the effects of the subtree and this fiber onto the effect
22399 // list of the parent. The completion order of the children affects the
22400 // side-effect order.
22401 if (returnFiber.firstEffect === null) {
22402 returnFiber.firstEffect = workInProgress.firstEffect;
22403 }
22404 if (workInProgress.lastEffect !== null) {
22405 if (returnFiber.lastEffect !== null) {
22406 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
22407 }
22408 returnFiber.lastEffect = workInProgress.lastEffect;
22409 }
22410
22411 // If this fiber had side-effects, we append it AFTER the children's
22412 // side-effects. We can perform certain side-effects earlier if needed,
22413 // by doing multiple passes over the effect list. We don't want to
22414 // schedule our own side-effect on our own list because if end up
22415 // reusing children we'll schedule this effect onto itself since we're
22416 // at the end.
22417 var effectTag = workInProgress.effectTag;
22418
22419 // Skip both NoWork and PerformedWork tags when creating the effect
22420 // list. PerformedWork effect is read by React DevTools but shouldn't be
22421 // committed.
22422 if (effectTag > PerformedWork) {
22423 if (returnFiber.lastEffect !== null) {
22424 returnFiber.lastEffect.nextEffect = workInProgress;
22425 } else {
22426 returnFiber.firstEffect = workInProgress;
22427 }
22428 returnFiber.lastEffect = workInProgress;
22429 }
22430 }
22431 } else {
22432 // This fiber did not complete because something threw. Pop values off
22433 // the stack without entering the complete phase. If this is a boundary,
22434 // capture values if possible.
22435 var _next = unwindWork(workInProgress, renderExpirationTime);
22436
22437 // Because this fiber did not complete, don't reset its expiration time.
22438
22439 if (enableProfilerTimer && (workInProgress.mode & ProfileMode) !== NoMode) {
22440 // Record the render duration for the fiber that errored.
22441 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
22442
22443 // Include the time spent working on failed children before continuing.
22444 var actualDuration = workInProgress.actualDuration;
22445 var child = workInProgress.child;
22446 while (child !== null) {
22447 actualDuration += child.actualDuration;
22448 child = child.sibling;
22449 }
22450 workInProgress.actualDuration = actualDuration;
22451 }
22452
22453 if (_next !== null) {
22454 // If completing this work spawned new work, do that next. We'll come
22455 // back here again.
22456 // Since we're restarting, remove anything that is not a host effect
22457 // from the effect tag.
22458 // TODO: The name stopFailedWorkTimer is misleading because Suspense
22459 // also captures and restarts.
22460 stopFailedWorkTimer(workInProgress);
22461 _next.effectTag &= HostEffectMask;
22462 return _next;
22463 }
22464 stopWorkTimer(workInProgress);
22465
22466 if (returnFiber !== null) {
22467 // Mark the parent fiber as incomplete and clear its effect list.
22468 returnFiber.firstEffect = returnFiber.lastEffect = null;
22469 returnFiber.effectTag |= Incomplete;
22470 }
22471 }
22472
22473 var siblingFiber = workInProgress.sibling;
22474 if (siblingFiber !== null) {
22475 // If there is more work to do in this returnFiber, do that next.
22476 return siblingFiber;
22477 }
22478 // Otherwise, return to the parent
22479 workInProgress = returnFiber;
22480 } while (workInProgress !== null);
22481
22482 // We've reached the root.
22483 if (workInProgressRootExitStatus === RootIncomplete) {
22484 workInProgressRootExitStatus = RootCompleted;
22485 }
22486 return null;
22487}
22488
22489function resetChildExpirationTime(completedWork) {
22490 if (renderExpirationTime !== Never && completedWork.childExpirationTime === Never) {
22491 // The children of this component are hidden. Don't bubble their
22492 // expiration times.
22493 return;
22494 }
22495
22496 var newChildExpirationTime = NoWork;
22497
22498 // Bubble up the earliest expiration time.
22499 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
22500 // In profiling mode, resetChildExpirationTime is also used to reset
22501 // profiler durations.
22502 var actualDuration = completedWork.actualDuration;
22503 var treeBaseDuration = completedWork.selfBaseDuration;
22504
22505 // When a fiber is cloned, its actualDuration is reset to 0. This value will
22506 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
22507 // When work is done, it should bubble to the parent's actualDuration. If
22508 // the fiber has not been cloned though, (meaning no work was done), then
22509 // this value will reflect the amount of time spent working on a previous
22510 // render. In that case it should not bubble. We determine whether it was
22511 // cloned by comparing the child pointer.
22512 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
22513
22514 var child = completedWork.child;
22515 while (child !== null) {
22516 var childUpdateExpirationTime = child.expirationTime;
22517 var childChildExpirationTime = child.childExpirationTime;
22518 if (childUpdateExpirationTime > newChildExpirationTime) {
22519 newChildExpirationTime = childUpdateExpirationTime;
22520 }
22521 if (childChildExpirationTime > newChildExpirationTime) {
22522 newChildExpirationTime = childChildExpirationTime;
22523 }
22524 if (shouldBubbleActualDurations) {
22525 actualDuration += child.actualDuration;
22526 }
22527 treeBaseDuration += child.treeBaseDuration;
22528 child = child.sibling;
22529 }
22530 completedWork.actualDuration = actualDuration;
22531 completedWork.treeBaseDuration = treeBaseDuration;
22532 } else {
22533 var _child = completedWork.child;
22534 while (_child !== null) {
22535 var _childUpdateExpirationTime = _child.expirationTime;
22536 var _childChildExpirationTime = _child.childExpirationTime;
22537 if (_childUpdateExpirationTime > newChildExpirationTime) {
22538 newChildExpirationTime = _childUpdateExpirationTime;
22539 }
22540 if (_childChildExpirationTime > newChildExpirationTime) {
22541 newChildExpirationTime = _childChildExpirationTime;
22542 }
22543 _child = _child.sibling;
22544 }
22545 }
22546
22547 completedWork.childExpirationTime = newChildExpirationTime;
22548}
22549
22550function commitRoot(root) {
22551 var renderPriorityLevel = getCurrentPriorityLevel();
22552 runWithPriority$2(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
22553 // If there are passive effects, schedule a callback to flush them. This goes
22554 // outside commitRootImpl so that it inherits the priority of the render.
22555 if (rootWithPendingPassiveEffects !== null) {
22556 scheduleCallback(NormalPriority, function () {
22557 flushPassiveEffects();
22558 return null;
22559 });
22560 }
22561 return null;
22562}
22563
22564function commitRootImpl(root, renderPriorityLevel) {
22565 flushPassiveEffects();
22566 flushRenderPhaseStrictModeWarningsInDEV();
22567
22568 (function () {
22569 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22570 {
22571 throw ReactError(Error('Should not already be working.'));
22572 }
22573 }
22574 })();
22575
22576 var finishedWork = root.finishedWork;
22577 var expirationTime = root.finishedExpirationTime;
22578 if (finishedWork === null) {
22579 return null;
22580 }
22581 root.finishedWork = null;
22582 root.finishedExpirationTime = NoWork;
22583
22584 (function () {
22585 if (!(finishedWork !== root.current)) {
22586 {
22587 throw ReactError(Error('Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.'));
22588 }
22589 }
22590 })();
22591
22592 // commitRoot never returns a continuation; it always finishes synchronously.
22593 // So we can clear these now to allow a new callback to be scheduled.
22594 root.callbackNode = null;
22595 root.callbackExpirationTime = NoWork;
22596
22597 startCommitTimer();
22598
22599 // Update the first and last pending times on this root. The new first
22600 // pending time is whatever is left on the root fiber.
22601 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
22602 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
22603 var firstPendingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
22604 root.firstPendingTime = firstPendingTimeBeforeCommit;
22605 if (firstPendingTimeBeforeCommit < root.lastPendingTime) {
22606 // This usually means we've finished all the work, but it can also happen
22607 // when something gets downprioritized during render, like a hidden tree.
22608 root.lastPendingTime = firstPendingTimeBeforeCommit;
22609 }
22610
22611 if (root === workInProgressRoot) {
22612 // We can reset these now that they are finished.
22613 workInProgressRoot = null;
22614 workInProgress = null;
22615 renderExpirationTime = NoWork;
22616 } else {}
22617 // This indicates that the last root we worked on is not the same one that
22618 // we're committing now. This most commonly happens when a suspended root
22619 // times out.
22620
22621
22622 // Get the list of effects.
22623 var firstEffect = void 0;
22624 if (finishedWork.effectTag > PerformedWork) {
22625 // A fiber's effect list consists only of its children, not itself. So if
22626 // the root has an effect, we need to add it to the end of the list. The
22627 // resulting list is the set that would belong to the root's parent, if it
22628 // had one; that is, all the effects in the tree including the root.
22629 if (finishedWork.lastEffect !== null) {
22630 finishedWork.lastEffect.nextEffect = finishedWork;
22631 firstEffect = finishedWork.firstEffect;
22632 } else {
22633 firstEffect = finishedWork;
22634 }
22635 } else {
22636 // There is no effect on the root.
22637 firstEffect = finishedWork.firstEffect;
22638 }
22639
22640 if (firstEffect !== null) {
22641 var prevExecutionContext = executionContext;
22642 executionContext |= CommitContext;
22643 var prevInteractions = null;
22644 if (enableSchedulerTracing) {
22645 prevInteractions = __interactionsRef.current;
22646 __interactionsRef.current = root.memoizedInteractions;
22647 }
22648
22649 // Reset this to null before calling lifecycles
22650 ReactCurrentOwner$2.current = null;
22651
22652 // The commit phase is broken into several sub-phases. We do a separate pass
22653 // of the effect list for each phase: all mutation effects come before all
22654 // layout effects, and so on.
22655
22656 // The first phase a "before mutation" phase. We use this phase to read the
22657 // state of the host tree right before we mutate it. This is where
22658 // getSnapshotBeforeUpdate is called.
22659 startCommitSnapshotEffectsTimer();
22660 prepareForCommit(root.containerInfo);
22661 nextEffect = firstEffect;
22662 do {
22663 {
22664 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
22665 if (hasCaughtError()) {
22666 (function () {
22667 if (!(nextEffect !== null)) {
22668 {
22669 throw ReactError(Error('Should be working on an effect.'));
22670 }
22671 }
22672 })();
22673 var error = clearCaughtError();
22674 captureCommitPhaseError(nextEffect, error);
22675 nextEffect = nextEffect.nextEffect;
22676 }
22677 }
22678 } while (nextEffect !== null);
22679 stopCommitSnapshotEffectsTimer();
22680
22681 if (enableProfilerTimer) {
22682 // Mark the current commit time to be shared by all Profilers in this
22683 // batch. This enables them to be grouped later.
22684 recordCommitTime();
22685 }
22686
22687 // The next phase is the mutation phase, where we mutate the host tree.
22688 startCommitHostEffectsTimer();
22689 nextEffect = firstEffect;
22690 do {
22691 {
22692 invokeGuardedCallback(null, commitMutationEffects, null, renderPriorityLevel);
22693 if (hasCaughtError()) {
22694 (function () {
22695 if (!(nextEffect !== null)) {
22696 {
22697 throw ReactError(Error('Should be working on an effect.'));
22698 }
22699 }
22700 })();
22701 var _error = clearCaughtError();
22702 captureCommitPhaseError(nextEffect, _error);
22703 nextEffect = nextEffect.nextEffect;
22704 }
22705 }
22706 } while (nextEffect !== null);
22707 stopCommitHostEffectsTimer();
22708 resetAfterCommit(root.containerInfo);
22709
22710 // The work-in-progress tree is now the current tree. This must come after
22711 // the mutation phase, so that the previous tree is still current during
22712 // componentWillUnmount, but before the layout phase, so that the finished
22713 // work is current during componentDidMount/Update.
22714 root.current = finishedWork;
22715
22716 // The next phase is the layout phase, where we call effects that read
22717 // the host tree after it's been mutated. The idiomatic use case for this is
22718 // layout, but class component lifecycles also fire here for legacy reasons.
22719 startCommitLifeCyclesTimer();
22720 nextEffect = firstEffect;
22721 do {
22722 {
22723 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
22724 if (hasCaughtError()) {
22725 (function () {
22726 if (!(nextEffect !== null)) {
22727 {
22728 throw ReactError(Error('Should be working on an effect.'));
22729 }
22730 }
22731 })();
22732 var _error2 = clearCaughtError();
22733 captureCommitPhaseError(nextEffect, _error2);
22734 nextEffect = nextEffect.nextEffect;
22735 }
22736 }
22737 } while (nextEffect !== null);
22738 stopCommitLifeCyclesTimer();
22739
22740 nextEffect = null;
22741
22742 // Tell Scheduler to yield at the end of the frame, so the browser has an
22743 // opportunity to paint.
22744 requestPaint();
22745
22746 if (enableSchedulerTracing) {
22747 __interactionsRef.current = prevInteractions;
22748 }
22749 executionContext = prevExecutionContext;
22750 } else {
22751 // No effects.
22752 root.current = finishedWork;
22753 // Measure these anyway so the flamegraph explicitly shows that there were
22754 // no effects.
22755 // TODO: Maybe there's a better way to report this.
22756 startCommitSnapshotEffectsTimer();
22757 stopCommitSnapshotEffectsTimer();
22758 if (enableProfilerTimer) {
22759 recordCommitTime();
22760 }
22761 startCommitHostEffectsTimer();
22762 stopCommitHostEffectsTimer();
22763 startCommitLifeCyclesTimer();
22764 stopCommitLifeCyclesTimer();
22765 }
22766
22767 stopCommitTimer();
22768
22769 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
22770
22771 if (rootDoesHavePassiveEffects) {
22772 // This commit has passive effects. Stash a reference to them. But don't
22773 // schedule a callback until after flushing layout work.
22774 rootDoesHavePassiveEffects = false;
22775 rootWithPendingPassiveEffects = root;
22776 pendingPassiveEffectsExpirationTime = expirationTime;
22777 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
22778 } else {
22779 // We are done with the effect chain at this point so let's clear the
22780 // nextEffect pointers to assist with GC. If we have passive effects, we'll
22781 // clear this in flushPassiveEffects.
22782 nextEffect = firstEffect;
22783 while (nextEffect !== null) {
22784 var nextNextEffect = nextEffect.nextEffect;
22785 nextEffect.nextEffect = null;
22786 nextEffect = nextNextEffect;
22787 }
22788 }
22789
22790 // Check if there's remaining work on this root
22791 var remainingExpirationTime = root.firstPendingTime;
22792 if (remainingExpirationTime !== NoWork) {
22793 var currentTime = requestCurrentTime();
22794 var priorityLevel = inferPriorityFromExpirationTime(currentTime, remainingExpirationTime);
22795
22796 if (enableSchedulerTracing) {
22797 if (spawnedWorkDuringRender !== null) {
22798 var expirationTimes = spawnedWorkDuringRender;
22799 spawnedWorkDuringRender = null;
22800 for (var i = 0; i < expirationTimes.length; i++) {
22801 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
22802 }
22803 }
22804 }
22805
22806 scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);
22807 } else {
22808 // If there's no remaining work, we can clear the set of already failed
22809 // error boundaries.
22810 legacyErrorBoundariesThatAlreadyFailed = null;
22811 }
22812
22813 if (enableSchedulerTracing) {
22814 if (!rootDidHavePassiveEffects) {
22815 // If there are no passive effects, then we can complete the pending interactions.
22816 // Otherwise, we'll wait until after the passive effects are flushed.
22817 // Wait to do this until after remaining work has been scheduled,
22818 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
22819 finishPendingInteractions(root, expirationTime);
22820 }
22821 }
22822
22823 onCommitRoot(finishedWork.stateNode, expirationTime);
22824
22825 if (remainingExpirationTime === Sync) {
22826 // Count the number of times the root synchronously re-renders without
22827 // finishing. If there are too many, it indicates an infinite update loop.
22828 if (root === rootWithNestedUpdates) {
22829 nestedUpdateCount++;
22830 } else {
22831 nestedUpdateCount = 0;
22832 rootWithNestedUpdates = root;
22833 }
22834 } else {
22835 nestedUpdateCount = 0;
22836 }
22837
22838 if (hasUncaughtError) {
22839 hasUncaughtError = false;
22840 var _error3 = firstUncaughtError;
22841 firstUncaughtError = null;
22842 throw _error3;
22843 }
22844
22845 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
22846 // This is a legacy edge case. We just committed the initial mount of
22847 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
22848 // synchronously, but layout updates should be deferred until the end
22849 // of the batch.
22850 return null;
22851 }
22852
22853 // If layout work was scheduled, flush it now.
22854 flushSyncCallbackQueue();
22855 return null;
22856}
22857
22858function commitBeforeMutationEffects() {
22859 while (nextEffect !== null) {
22860 if ((nextEffect.effectTag & Snapshot) !== NoEffect) {
22861 setCurrentFiber(nextEffect);
22862 recordEffect();
22863
22864 var current$$1 = nextEffect.alternate;
22865 commitBeforeMutationLifeCycles(current$$1, nextEffect);
22866
22867 resetCurrentFiber();
22868 }
22869 nextEffect = nextEffect.nextEffect;
22870 }
22871}
22872
22873function commitMutationEffects(renderPriorityLevel) {
22874 // TODO: Should probably move the bulk of this function to commitWork.
22875 while (nextEffect !== null) {
22876 setCurrentFiber(nextEffect);
22877
22878 var effectTag = nextEffect.effectTag;
22879
22880 if (effectTag & ContentReset) {
22881 commitResetTextContent(nextEffect);
22882 }
22883
22884 if (effectTag & Ref) {
22885 var current$$1 = nextEffect.alternate;
22886 if (current$$1 !== null) {
22887 commitDetachRef(current$$1);
22888 }
22889 }
22890
22891 // The following switch statement is only concerned about placement,
22892 // updates, and deletions. To avoid needing to add a case for every possible
22893 // bitmap value, we remove the secondary effects from the effect tag and
22894 // switch on that value.
22895 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
22896 switch (primaryEffectTag) {
22897 case Placement:
22898 {
22899 commitPlacement(nextEffect);
22900 // Clear the "placement" from effect tag so that we know that this is
22901 // inserted, before any life-cycles like componentDidMount gets called.
22902 // TODO: findDOMNode doesn't rely on this any more but isMounted does
22903 // and isMounted is deprecated anyway so we should be able to kill this.
22904 nextEffect.effectTag &= ~Placement;
22905 break;
22906 }
22907 case PlacementAndUpdate:
22908 {
22909 // Placement
22910 commitPlacement(nextEffect);
22911 // Clear the "placement" from effect tag so that we know that this is
22912 // inserted, before any life-cycles like componentDidMount gets called.
22913 nextEffect.effectTag &= ~Placement;
22914
22915 // Update
22916 var _current = nextEffect.alternate;
22917 commitWork(_current, nextEffect);
22918 break;
22919 }
22920 case Update:
22921 {
22922 var _current2 = nextEffect.alternate;
22923 commitWork(_current2, nextEffect);
22924 break;
22925 }
22926 case Deletion:
22927 {
22928 commitDeletion(nextEffect, renderPriorityLevel);
22929 break;
22930 }
22931 }
22932
22933 // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
22934 recordEffect();
22935
22936 resetCurrentFiber();
22937 nextEffect = nextEffect.nextEffect;
22938 }
22939}
22940
22941function commitLayoutEffects(root, committedExpirationTime) {
22942 // TODO: Should probably move the bulk of this function to commitWork.
22943 while (nextEffect !== null) {
22944 setCurrentFiber(nextEffect);
22945
22946 var effectTag = nextEffect.effectTag;
22947
22948 if (effectTag & (Update | Callback)) {
22949 recordEffect();
22950 var current$$1 = nextEffect.alternate;
22951 commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime);
22952 }
22953
22954 if (effectTag & Ref) {
22955 recordEffect();
22956 commitAttachRef(nextEffect);
22957 }
22958
22959 if (effectTag & Passive) {
22960 rootDoesHavePassiveEffects = true;
22961 }
22962
22963 resetCurrentFiber();
22964 nextEffect = nextEffect.nextEffect;
22965 }
22966}
22967
22968function flushPassiveEffects() {
22969 if (rootWithPendingPassiveEffects === null) {
22970 return false;
22971 }
22972 var root = rootWithPendingPassiveEffects;
22973 var expirationTime = pendingPassiveEffectsExpirationTime;
22974 var renderPriorityLevel = pendingPassiveEffectsRenderPriority;
22975 rootWithPendingPassiveEffects = null;
22976 pendingPassiveEffectsExpirationTime = NoWork;
22977 pendingPassiveEffectsRenderPriority = NoPriority;
22978 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
22979 return runWithPriority$2(priorityLevel, flushPassiveEffectsImpl.bind(null, root, expirationTime));
22980}
22981
22982function flushPassiveEffectsImpl(root, expirationTime) {
22983 var prevInteractions = null;
22984 if (enableSchedulerTracing) {
22985 prevInteractions = __interactionsRef.current;
22986 __interactionsRef.current = root.memoizedInteractions;
22987 }
22988
22989 (function () {
22990 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
22991 {
22992 throw ReactError(Error('Cannot flush passive effects while already rendering.'));
22993 }
22994 }
22995 })();
22996 var prevExecutionContext = executionContext;
22997 executionContext |= CommitContext;
22998
22999 // Note: This currently assumes there are no passive effects on the root
23000 // fiber, because the root is not part of its own effect list. This could
23001 // change in the future.
23002 var effect = root.current.firstEffect;
23003 while (effect !== null) {
23004 {
23005 setCurrentFiber(effect);
23006 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
23007 if (hasCaughtError()) {
23008 (function () {
23009 if (!(effect !== null)) {
23010 {
23011 throw ReactError(Error('Should be working on an effect.'));
23012 }
23013 }
23014 })();
23015 var error = clearCaughtError();
23016 captureCommitPhaseError(effect, error);
23017 }
23018 resetCurrentFiber();
23019 }
23020 var nextNextEffect = effect.nextEffect;
23021 // Remove nextEffect pointer to assist GC
23022 effect.nextEffect = null;
23023 effect = nextNextEffect;
23024 }
23025
23026 if (enableSchedulerTracing) {
23027 __interactionsRef.current = prevInteractions;
23028 finishPendingInteractions(root, expirationTime);
23029 }
23030
23031 executionContext = prevExecutionContext;
23032 flushSyncCallbackQueue();
23033
23034 // If additional passive effects were scheduled, increment a counter. If this
23035 // exceeds the limit, we'll fire a warning.
23036 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
23037
23038 return true;
23039}
23040
23041function isAlreadyFailedLegacyErrorBoundary(instance) {
23042 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
23043}
23044
23045function markLegacyErrorBoundaryAsFailed(instance) {
23046 if (legacyErrorBoundariesThatAlreadyFailed === null) {
23047 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
23048 } else {
23049 legacyErrorBoundariesThatAlreadyFailed.add(instance);
23050 }
23051}
23052
23053function prepareToThrowUncaughtError(error) {
23054 if (!hasUncaughtError) {
23055 hasUncaughtError = true;
23056 firstUncaughtError = error;
23057 }
23058}
23059var onUncaughtError = prepareToThrowUncaughtError;
23060
23061function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
23062 var errorInfo = createCapturedValue(error, sourceFiber);
23063 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
23064 enqueueUpdate(rootFiber, update);
23065 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
23066 if (root !== null) {
23067 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
23068 }
23069}
23070
23071function captureCommitPhaseError(sourceFiber, error) {
23072 if (sourceFiber.tag === HostRoot) {
23073 // Error was thrown at the root. There is no parent, so the root
23074 // itself should capture it.
23075 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
23076 return;
23077 }
23078
23079 var fiber = sourceFiber.return;
23080 while (fiber !== null) {
23081 if (fiber.tag === HostRoot) {
23082 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
23083 return;
23084 } else if (fiber.tag === ClassComponent) {
23085 var ctor = fiber.type;
23086 var instance = fiber.stateNode;
23087 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
23088 var errorInfo = createCapturedValue(error, sourceFiber);
23089 var update = createClassErrorUpdate(fiber, errorInfo,
23090 // TODO: This is always sync
23091 Sync);
23092 enqueueUpdate(fiber, update);
23093 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
23094 if (root !== null) {
23095 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
23096 }
23097 return;
23098 }
23099 }
23100 fiber = fiber.return;
23101 }
23102}
23103
23104function pingSuspendedRoot(root, thenable, suspendedTime) {
23105 var pingCache = root.pingCache;
23106 if (pingCache !== null) {
23107 // The thenable resolved, so we no longer need to memoize, because it will
23108 // never be thrown again.
23109 pingCache.delete(thenable);
23110 }
23111
23112 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
23113 // Received a ping at the same priority level at which we're currently
23114 // rendering. We might want to restart this render. This should mirror
23115 // the logic of whether or not a root suspends once it completes.
23116
23117 // TODO: If we're rendering sync either due to Sync, Batched or expired,
23118 // we should probably never restart.
23119
23120 // If we're suspended with delay, we'll always suspend so we can always
23121 // restart. If we're suspended without any updates, it might be a retry.
23122 // If it's early in the retry we can restart. We can't know for sure
23123 // whether we'll eventually process an update during this render pass,
23124 // but it's somewhat unlikely that we get to a ping before that, since
23125 // getting to the root most update is usually very fast.
23126 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
23127 // Restart from the root. Don't need to schedule a ping because
23128 // we're already working on this tree.
23129 prepareFreshStack(root, renderExpirationTime);
23130 } else {
23131 // Even though we can't restart right now, we might get an
23132 // opportunity later. So we mark this render as having a ping.
23133 workInProgressRootHasPendingPing = true;
23134 }
23135 return;
23136 }
23137
23138 var lastPendingTime = root.lastPendingTime;
23139 if (lastPendingTime < suspendedTime) {
23140 // The root is no longer suspended at this time.
23141 return;
23142 }
23143
23144 var pingTime = root.pingTime;
23145 if (pingTime !== NoWork && pingTime < suspendedTime) {
23146 // There's already a lower priority ping scheduled.
23147 return;
23148 }
23149
23150 // Mark the time at which this ping was scheduled.
23151 root.pingTime = suspendedTime;
23152
23153 if (root.finishedExpirationTime === suspendedTime) {
23154 // If there's a pending fallback waiting to commit, throw it away.
23155 root.finishedExpirationTime = NoWork;
23156 root.finishedWork = null;
23157 }
23158
23159 var currentTime = requestCurrentTime();
23160 var priorityLevel = inferPriorityFromExpirationTime(currentTime, suspendedTime);
23161 scheduleCallbackForRoot(root, priorityLevel, suspendedTime);
23162}
23163
23164function retryTimedOutBoundary(boundaryFiber) {
23165 // The boundary fiber (a Suspense component or SuspenseList component)
23166 // previously was rendered in its fallback state. One of the promises that
23167 // suspended it has resolved, which means at least part of the tree was
23168 // likely unblocked. Try rendering again, at a new expiration time.
23169 var currentTime = requestCurrentTime();
23170 var suspenseConfig = null; // Retries don't carry over the already committed update.
23171 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
23172 // TODO: Special case idle priority?
23173 var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);
23174 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
23175 if (root !== null) {
23176 scheduleCallbackForRoot(root, priorityLevel, retryTime);
23177 }
23178}
23179
23180function resolveRetryThenable(boundaryFiber, thenable) {
23181 var retryCache = void 0;
23182 if (enableSuspenseServerRenderer) {
23183 switch (boundaryFiber.tag) {
23184 case SuspenseComponent:
23185 retryCache = boundaryFiber.stateNode;
23186 break;
23187 case DehydratedSuspenseComponent:
23188 retryCache = boundaryFiber.memoizedState;
23189 break;
23190 default:
23191 (function () {
23192 {
23193 {
23194 throw ReactError(Error('Pinged unknown suspense boundary type. This is probably a bug in React.'));
23195 }
23196 }
23197 })();
23198 }
23199 } else {
23200 retryCache = boundaryFiber.stateNode;
23201 }
23202
23203 if (retryCache !== null) {
23204 // The thenable resolved, so we no longer need to memoize, because it will
23205 // never be thrown again.
23206 retryCache.delete(thenable);
23207 }
23208
23209 retryTimedOutBoundary(boundaryFiber);
23210}
23211
23212// Computes the next Just Noticeable Difference (JND) boundary.
23213// The theory is that a person can't tell the difference between small differences in time.
23214// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
23215// difference in the experience. However, waiting for longer might mean that we can avoid
23216// showing an intermediate loading state. The longer we have already waited, the harder it
23217// is to tell small differences in time. Therefore, the longer we've already waited,
23218// the longer we can wait additionally. At some point we have to give up though.
23219// We pick a train model where the next boundary commits at a consistent schedule.
23220// These particular numbers are vague estimates. We expect to adjust them based on research.
23221function jnd(timeElapsed) {
23222 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
23223}
23224
23225function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
23226 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
23227 if (busyMinDurationMs <= 0) {
23228 return 0;
23229 }
23230 var busyDelayMs = suspenseConfig.busyDelayMs | 0;
23231
23232 // Compute the time until this render pass would expire.
23233 var currentTimeMs = now();
23234 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
23235 var timeElapsed = currentTimeMs - eventTimeMs;
23236 if (timeElapsed <= busyDelayMs) {
23237 // If we haven't yet waited longer than the initial delay, we don't
23238 // have to wait any additional time.
23239 return 0;
23240 }
23241 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed;
23242 // This is the value that is passed to `setTimeout`.
23243 return msUntilTimeout;
23244}
23245
23246function checkForNestedUpdates() {
23247 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
23248 nestedUpdateCount = 0;
23249 rootWithNestedUpdates = null;
23250 (function () {
23251 {
23252 {
23253 throw ReactError(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.'));
23254 }
23255 }
23256 })();
23257 }
23258
23259 {
23260 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
23261 nestedPassiveUpdateCount = 0;
23262 warning$1(false, '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.');
23263 }
23264 }
23265}
23266
23267function flushRenderPhaseStrictModeWarningsInDEV() {
23268 {
23269 ReactStrictModeWarnings.flushLegacyContextWarning();
23270
23271 if (warnAboutDeprecatedLifecycles) {
23272 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
23273 }
23274 }
23275}
23276
23277function stopFinishedWorkLoopTimer() {
23278 var didCompleteRoot = true;
23279 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23280 interruptedBy = null;
23281}
23282
23283function stopInterruptedWorkLoopTimer() {
23284 // TODO: Track which fiber caused the interruption.
23285 var didCompleteRoot = false;
23286 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
23287 interruptedBy = null;
23288}
23289
23290function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
23291 if (enableUserTimingAPI && workInProgressRoot !== null && updateExpirationTime > renderExpirationTime) {
23292 interruptedBy = fiberThatReceivedUpdate;
23293 }
23294}
23295
23296var didWarnStateUpdateForUnmountedComponent = null;
23297function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
23298 {
23299 var tag = fiber.tag;
23300 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
23301 // Only warn for user-defined components, not internal ones like Suspense.
23302 return;
23303 }
23304 // We show the whole stack but dedupe on the top component's name because
23305 // the problematic code almost always lies inside that component.
23306 var componentName = getComponentName(fiber.type) || 'ReactComponent';
23307 if (didWarnStateUpdateForUnmountedComponent !== null) {
23308 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
23309 return;
23310 }
23311 didWarnStateUpdateForUnmountedComponent.add(componentName);
23312 } else {
23313 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
23314 }
23315 warningWithoutStack$1(false, "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));
23316 }
23317}
23318
23319var beginWork$$1 = void 0;
23320if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
23321 var dummyFiber = null;
23322 beginWork$$1 = function (current$$1, unitOfWork, expirationTime) {
23323 // If a component throws an error, we replay it again in a synchronously
23324 // dispatched event, so that the debugger will treat it as an uncaught
23325 // error See ReactErrorUtils for more information.
23326
23327 // Before entering the begin phase, copy the work-in-progress onto a dummy
23328 // fiber. If beginWork throws, we'll use this to reset the state.
23329 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
23330 try {
23331 return beginWork$1(current$$1, unitOfWork, expirationTime);
23332 } catch (originalError) {
23333 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
23334 // Don't replay promises. Treat everything else like an error.
23335 throw originalError;
23336 }
23337
23338 // Keep this code in sync with renderRoot; any changes here must have
23339 // corresponding changes there.
23340 resetContextDependencies();
23341 resetHooks();
23342
23343 // Unwind the failed stack frame
23344 unwindInterruptedWork(unitOfWork);
23345
23346 // Restore the original properties of the fiber.
23347 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
23348
23349 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
23350 // Reset the profiler timer.
23351 startProfilerTimer(unitOfWork);
23352 }
23353
23354 // Run beginWork again.
23355 invokeGuardedCallback(null, beginWork$1, null, current$$1, unitOfWork, expirationTime);
23356
23357 if (hasCaughtError()) {
23358 var replayError = clearCaughtError();
23359 // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
23360 // Rethrow this error instead of the original one.
23361 throw replayError;
23362 } else {
23363 // This branch is reachable if the render phase is impure.
23364 throw originalError;
23365 }
23366 }
23367 };
23368} else {
23369 beginWork$$1 = beginWork$1;
23370}
23371
23372var didWarnAboutUpdateInRender = false;
23373var didWarnAboutUpdateInGetChildContext = false;
23374function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
23375 {
23376 if (fiber.tag === ClassComponent) {
23377 switch (phase) {
23378 case 'getChildContext':
23379 if (didWarnAboutUpdateInGetChildContext) {
23380 return;
23381 }
23382 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
23383 didWarnAboutUpdateInGetChildContext = true;
23384 break;
23385 case 'render':
23386 if (didWarnAboutUpdateInRender) {
23387 return;
23388 }
23389 warningWithoutStack$1(false, 'Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure function of ' + 'props and state.');
23390 didWarnAboutUpdateInRender = true;
23391 break;
23392 }
23393 }
23394 }
23395}
23396
23397// a 'shared' variable that changes when act() opens/closes in tests.
23398var IsThisRendererActing = { current: false };
23399
23400function warnIfNotScopedWithMatchingAct(fiber) {
23401 {
23402 if (warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
23403 warningWithoutStack$1(false, "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));
23404 }
23405 }
23406}
23407
23408function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
23409 {
23410 if (warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23411 warningWithoutStack$1(false, '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
23416function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
23417 {
23418 if (warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
23419 warningWithoutStack$1(false, '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
23424var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV;
23425
23426// In tests, we want to enforce a mocked scheduler.
23427var didWarnAboutUnmockedScheduler = false;
23428// TODO Before we release concurrent mode, revisit this and decide whether a mocked
23429// scheduler is the actual recommendation. The alternative could be a testing build,
23430// a new lib, or whatever; we dunno just yet. This message is for early adopters
23431// to get their tests right.
23432
23433function warnIfUnmockedScheduler(fiber) {
23434 {
23435 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
23436 if (fiber.mode & BatchedMode || fiber.mode & ConcurrentMode) {
23437 didWarnAboutUnmockedScheduler = true;
23438 warningWithoutStack$1(false, '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');
23439 } else if (warnAboutUnmockedScheduler === true) {
23440 didWarnAboutUnmockedScheduler = true;
23441 warningWithoutStack$1(false, 'Starting from React v17, the "scheduler" module will need 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');
23442 }
23443 }
23444 }
23445}
23446
23447var componentsThatTriggeredHighPriSuspend = null;
23448function checkForWrongSuspensePriorityInDEV(sourceFiber) {
23449 {
23450 var currentPriorityLevel = getCurrentPriorityLevel();
23451 if ((sourceFiber.mode & ConcurrentMode) !== NoEffect && (currentPriorityLevel === UserBlockingPriority$2 || currentPriorityLevel === ImmediatePriority)) {
23452 var workInProgressNode = sourceFiber;
23453 while (workInProgressNode !== null) {
23454 // Add the component that triggered the suspense
23455 var current$$1 = workInProgressNode.alternate;
23456 if (current$$1 !== null) {
23457 // TODO: warn component that triggers the high priority
23458 // suspend is the HostRoot
23459 switch (workInProgressNode.tag) {
23460 case ClassComponent:
23461 // Loop through the component's update queue and see whether the component
23462 // has triggered any high priority updates
23463 var updateQueue = current$$1.updateQueue;
23464 if (updateQueue !== null) {
23465 var update = updateQueue.firstUpdate;
23466 while (update !== null) {
23467 var priorityLevel = update.priority;
23468 if (priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority) {
23469 if (componentsThatTriggeredHighPriSuspend === null) {
23470 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
23471 } else {
23472 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
23473 }
23474 break;
23475 }
23476 update = update.next;
23477 }
23478 }
23479 break;
23480 case FunctionComponent:
23481 case ForwardRef:
23482 case SimpleMemoComponent:
23483 if (workInProgressNode.memoizedState !== null && workInProgressNode.memoizedState.baseUpdate !== null) {
23484 var _update = workInProgressNode.memoizedState.baseUpdate;
23485 // Loop through the functional component's memoized state to see whether
23486 // the component has triggered any high pri updates
23487 while (_update !== null) {
23488 var priority = _update.priority;
23489 if (priority === UserBlockingPriority$2 || priority === ImmediatePriority) {
23490 if (componentsThatTriggeredHighPriSuspend === null) {
23491 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
23492 } else {
23493 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
23494 }
23495 break;
23496 }
23497 if (_update.next === workInProgressNode.memoizedState.baseUpdate) {
23498 break;
23499 }
23500 _update = _update.next;
23501 }
23502 }
23503 break;
23504 default:
23505 break;
23506 }
23507 }
23508 workInProgressNode = workInProgressNode.return;
23509 }
23510 }
23511 }
23512}
23513
23514function flushSuspensePriorityWarningInDEV() {
23515 {
23516 if (componentsThatTriggeredHighPriSuspend !== null) {
23517 var componentNames = [];
23518 componentsThatTriggeredHighPriSuspend.forEach(function (name) {
23519 return componentNames.push(name);
23520 });
23521 componentsThatTriggeredHighPriSuspend = null;
23522
23523 if (componentNames.length > 0) {
23524 warningWithoutStack$1(false, '%s triggered a user-blocking update that suspended.' + '\n\n' + 'The fix is to split the update into multiple parts: a user-blocking ' + 'update to provide immediate feedback, and another update that ' + 'triggers the bulk of the changes.' + '\n\n' + 'Refer to the documentation for useSuspenseTransition to learn how ' + 'to implement this pattern.',
23525 // TODO: Add link to React docs with more information, once it exists
23526 componentNames.sort().join(', '));
23527 }
23528 }
23529 }
23530}
23531
23532function computeThreadID(root, expirationTime) {
23533 // Interaction threads are unique per root and expiration time.
23534 return expirationTime * 1000 + root.interactionThreadID;
23535}
23536
23537function markSpawnedWork(expirationTime) {
23538 if (!enableSchedulerTracing) {
23539 return;
23540 }
23541 if (spawnedWorkDuringRender === null) {
23542 spawnedWorkDuringRender = [expirationTime];
23543 } else {
23544 spawnedWorkDuringRender.push(expirationTime);
23545 }
23546}
23547
23548function scheduleInteractions(root, expirationTime, interactions) {
23549 if (!enableSchedulerTracing) {
23550 return;
23551 }
23552
23553 if (interactions.size > 0) {
23554 var pendingInteractionMap = root.pendingInteractionMap;
23555 var pendingInteractions = pendingInteractionMap.get(expirationTime);
23556 if (pendingInteractions != null) {
23557 interactions.forEach(function (interaction) {
23558 if (!pendingInteractions.has(interaction)) {
23559 // Update the pending async work count for previously unscheduled interaction.
23560 interaction.__count++;
23561 }
23562
23563 pendingInteractions.add(interaction);
23564 });
23565 } else {
23566 pendingInteractionMap.set(expirationTime, new Set(interactions));
23567
23568 // Update the pending async work count for the current interactions.
23569 interactions.forEach(function (interaction) {
23570 interaction.__count++;
23571 });
23572 }
23573
23574 var subscriber = __subscriberRef.current;
23575 if (subscriber !== null) {
23576 var threadID = computeThreadID(root, expirationTime);
23577 subscriber.onWorkScheduled(interactions, threadID);
23578 }
23579 }
23580}
23581
23582function schedulePendingInteractions(root, expirationTime) {
23583 // This is called when work is scheduled on a root.
23584 // It associates the current interactions with the newly-scheduled expiration.
23585 // They will be restored when that expiration is later committed.
23586 if (!enableSchedulerTracing) {
23587 return;
23588 }
23589
23590 scheduleInteractions(root, expirationTime, __interactionsRef.current);
23591}
23592
23593function startWorkOnPendingInteractions(root, expirationTime) {
23594 // This is called when new work is started on a root.
23595 if (!enableSchedulerTracing) {
23596 return;
23597 }
23598
23599 // Determine which interactions this batch of work currently includes, So that
23600 // we can accurately attribute time spent working on it, And so that cascading
23601 // work triggered during the render phase will be associated with it.
23602 var interactions = new Set();
23603 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23604 if (scheduledExpirationTime >= expirationTime) {
23605 scheduledInteractions.forEach(function (interaction) {
23606 return interactions.add(interaction);
23607 });
23608 }
23609 });
23610
23611 // Store the current set of interactions on the FiberRoot for a few reasons:
23612 // We can re-use it in hot functions like renderRoot() without having to
23613 // recalculate it. We will also use it in commitWork() to pass to any Profiler
23614 // onRender() hooks. This also provides DevTools with a way to access it when
23615 // the onCommitRoot() hook is called.
23616 root.memoizedInteractions = interactions;
23617
23618 if (interactions.size > 0) {
23619 var subscriber = __subscriberRef.current;
23620 if (subscriber !== null) {
23621 var threadID = computeThreadID(root, expirationTime);
23622 try {
23623 subscriber.onWorkStarted(interactions, threadID);
23624 } catch (error) {
23625 // If the subscriber throws, rethrow it in a separate task
23626 scheduleCallback(ImmediatePriority, function () {
23627 throw error;
23628 });
23629 }
23630 }
23631 }
23632}
23633
23634function finishPendingInteractions(root, committedExpirationTime) {
23635 if (!enableSchedulerTracing) {
23636 return;
23637 }
23638
23639 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
23640
23641 var subscriber = void 0;
23642
23643 try {
23644 subscriber = __subscriberRef.current;
23645 if (subscriber !== null && root.memoizedInteractions.size > 0) {
23646 var threadID = computeThreadID(root, committedExpirationTime);
23647 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
23648 }
23649 } catch (error) {
23650 // If the subscriber throws, rethrow it in a separate task
23651 scheduleCallback(ImmediatePriority, function () {
23652 throw error;
23653 });
23654 } finally {
23655 // Clear completed interactions from the pending Map.
23656 // Unless the render was suspended or cascading work was scheduled,
23657 // In which case– leave pending interactions until the subsequent render.
23658 var pendingInteractionMap = root.pendingInteractionMap;
23659 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
23660 // Only decrement the pending interaction count if we're done.
23661 // If there's still work at the current priority,
23662 // That indicates that we are waiting for suspense data.
23663 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
23664 pendingInteractionMap.delete(scheduledExpirationTime);
23665
23666 scheduledInteractions.forEach(function (interaction) {
23667 interaction.__count--;
23668
23669 if (subscriber !== null && interaction.__count === 0) {
23670 try {
23671 subscriber.onInteractionScheduledWorkCompleted(interaction);
23672 } catch (error) {
23673 // If the subscriber throws, rethrow it in a separate task
23674 scheduleCallback(ImmediatePriority, function () {
23675 throw error;
23676 });
23677 }
23678 }
23679 });
23680 }
23681 });
23682 }
23683}
23684
23685var onCommitFiberRoot = null;
23686var onCommitFiberUnmount = null;
23687var hasLoggedError = false;
23688
23689var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
23690
23691function injectInternals(internals) {
23692 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
23693 // No DevTools
23694 return false;
23695 }
23696 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
23697 if (hook.isDisabled) {
23698 // This isn't a real property on the hook, but it can be set to opt out
23699 // of DevTools integration and associated warnings and logs.
23700 // https://github.com/facebook/react/issues/3877
23701 return true;
23702 }
23703 if (!hook.supportsFiber) {
23704 {
23705 warningWithoutStack$1(false, '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');
23706 }
23707 // DevTools exists, even though it doesn't support Fiber.
23708 return true;
23709 }
23710 try {
23711 var rendererID = hook.inject(internals);
23712 // We have successfully injected, so now it is safe to set up hooks.
23713 onCommitFiberRoot = function (root, expirationTime) {
23714 try {
23715 var didError = (root.current.effectTag & DidCapture) === DidCapture;
23716 if (enableProfilerTimer) {
23717 var currentTime = requestCurrentTime();
23718 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
23719 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
23720 } else {
23721 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
23722 }
23723 } catch (err) {
23724 if (true && !hasLoggedError) {
23725 hasLoggedError = true;
23726 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
23727 }
23728 }
23729 };
23730 onCommitFiberUnmount = function (fiber) {
23731 try {
23732 hook.onCommitFiberUnmount(rendererID, fiber);
23733 } catch (err) {
23734 if (true && !hasLoggedError) {
23735 hasLoggedError = true;
23736 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
23737 }
23738 }
23739 };
23740 } catch (err) {
23741 // Catch all errors because it is unsafe to throw during initialization.
23742 {
23743 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
23744 }
23745 }
23746 // DevTools exists
23747 return true;
23748}
23749
23750function onCommitRoot(root, expirationTime) {
23751 if (typeof onCommitFiberRoot === 'function') {
23752 onCommitFiberRoot(root, expirationTime);
23753 }
23754}
23755
23756function onCommitUnmount(fiber) {
23757 if (typeof onCommitFiberUnmount === 'function') {
23758 onCommitFiberUnmount(fiber);
23759 }
23760}
23761
23762var hasBadMapPolyfill = void 0;
23763
23764{
23765 hasBadMapPolyfill = false;
23766 try {
23767 var nonExtensibleObject = Object.preventExtensions({});
23768 var testMap = new Map([[nonExtensibleObject, null]]);
23769 var testSet = new Set([nonExtensibleObject]);
23770 // This is necessary for Rollup to not consider these unused.
23771 // https://github.com/rollup/rollup/issues/1771
23772 // TODO: we can remove these if Rollup fixes the bug.
23773 testMap.set(0, 0);
23774 testSet.add(0);
23775 } catch (e) {
23776 // TODO: Consider warning about bad polyfills
23777 hasBadMapPolyfill = true;
23778 }
23779}
23780
23781// A Fiber is work on a Component that needs to be done or was done. There can
23782// be more than one per component.
23783
23784
23785var debugCounter = void 0;
23786
23787{
23788 debugCounter = 1;
23789}
23790
23791function FiberNode(tag, pendingProps, key, mode) {
23792 // Instance
23793 this.tag = tag;
23794 this.key = key;
23795 this.elementType = null;
23796 this.type = null;
23797 this.stateNode = null;
23798
23799 // Fiber
23800 this.return = null;
23801 this.child = null;
23802 this.sibling = null;
23803 this.index = 0;
23804
23805 this.ref = null;
23806
23807 this.pendingProps = pendingProps;
23808 this.memoizedProps = null;
23809 this.updateQueue = null;
23810 this.memoizedState = null;
23811 this.dependencies = null;
23812
23813 this.mode = mode;
23814
23815 // Effects
23816 this.effectTag = NoEffect;
23817 this.nextEffect = null;
23818
23819 this.firstEffect = null;
23820 this.lastEffect = null;
23821
23822 this.expirationTime = NoWork;
23823 this.childExpirationTime = NoWork;
23824
23825 this.alternate = null;
23826
23827 if (enableProfilerTimer) {
23828 // Note: The following is done to avoid a v8 performance cliff.
23829 //
23830 // Initializing the fields below to smis and later updating them with
23831 // double values will cause Fibers to end up having separate shapes.
23832 // This behavior/bug has something to do with Object.preventExtension().
23833 // Fortunately this only impacts DEV builds.
23834 // Unfortunately it makes React unusably slow for some applications.
23835 // To work around this, initialize the fields below with doubles.
23836 //
23837 // Learn more about this here:
23838 // https://github.com/facebook/react/issues/14365
23839 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
23840 this.actualDuration = Number.NaN;
23841 this.actualStartTime = Number.NaN;
23842 this.selfBaseDuration = Number.NaN;
23843 this.treeBaseDuration = Number.NaN;
23844
23845 // It's okay to replace the initial doubles with smis after initialization.
23846 // This won't trigger the performance cliff mentioned above,
23847 // and it simplifies other profiler code (including DevTools).
23848 this.actualDuration = 0;
23849 this.actualStartTime = -1;
23850 this.selfBaseDuration = 0;
23851 this.treeBaseDuration = 0;
23852 }
23853
23854 {
23855 this._debugID = debugCounter++;
23856 this._debugSource = null;
23857 this._debugOwner = null;
23858 this._debugIsCurrentlyTiming = false;
23859 this._debugNeedsRemount = false;
23860 this._debugHookTypes = null;
23861 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
23862 Object.preventExtensions(this);
23863 }
23864 }
23865}
23866
23867// This is a constructor function, rather than a POJO constructor, still
23868// please ensure we do the following:
23869// 1) Nobody should add any instance methods on this. Instance methods can be
23870// more difficult to predict when they get optimized and they are almost
23871// never inlined properly in static compilers.
23872// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
23873// always know when it is a fiber.
23874// 3) We might want to experiment with using numeric keys since they are easier
23875// to optimize in a non-JIT environment.
23876// 4) We can easily go from a constructor to a createFiber object literal if that
23877// is faster.
23878// 5) It should be easy to port this to a C struct and keep a C implementation
23879// compatible.
23880var createFiber = function (tag, pendingProps, key, mode) {
23881 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
23882 return new FiberNode(tag, pendingProps, key, mode);
23883};
23884
23885function shouldConstruct(Component) {
23886 var prototype = Component.prototype;
23887 return !!(prototype && prototype.isReactComponent);
23888}
23889
23890function isSimpleFunctionComponent(type) {
23891 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
23892}
23893
23894function resolveLazyComponentTag(Component) {
23895 if (typeof Component === 'function') {
23896 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
23897 } else if (Component !== undefined && Component !== null) {
23898 var $$typeof = Component.$$typeof;
23899 if ($$typeof === REACT_FORWARD_REF_TYPE) {
23900 return ForwardRef;
23901 }
23902 if ($$typeof === REACT_MEMO_TYPE) {
23903 return MemoComponent;
23904 }
23905 }
23906 return IndeterminateComponent;
23907}
23908
23909// This is used to create an alternate fiber to do work on.
23910function createWorkInProgress(current, pendingProps, expirationTime) {
23911 var workInProgress = current.alternate;
23912 if (workInProgress === null) {
23913 // We use a double buffering pooling technique because we know that we'll
23914 // only ever need at most two versions of a tree. We pool the "other" unused
23915 // node that we're free to reuse. This is lazily created to avoid allocating
23916 // extra objects for things that are never updated. It also allow us to
23917 // reclaim the extra memory if needed.
23918 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
23919 workInProgress.elementType = current.elementType;
23920 workInProgress.type = current.type;
23921 workInProgress.stateNode = current.stateNode;
23922
23923 {
23924 // DEV-only fields
23925 workInProgress._debugID = current._debugID;
23926 workInProgress._debugSource = current._debugSource;
23927 workInProgress._debugOwner = current._debugOwner;
23928 workInProgress._debugHookTypes = current._debugHookTypes;
23929 }
23930
23931 workInProgress.alternate = current;
23932 current.alternate = workInProgress;
23933 } else {
23934 workInProgress.pendingProps = pendingProps;
23935
23936 // We already have an alternate.
23937 // Reset the effect tag.
23938 workInProgress.effectTag = NoEffect;
23939
23940 // The effect list is no longer valid.
23941 workInProgress.nextEffect = null;
23942 workInProgress.firstEffect = null;
23943 workInProgress.lastEffect = null;
23944
23945 if (enableProfilerTimer) {
23946 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
23947 // This prevents time from endlessly accumulating in new commits.
23948 // This has the downside of resetting values for different priority renders,
23949 // But works for yielding (the common case) and should support resuming.
23950 workInProgress.actualDuration = 0;
23951 workInProgress.actualStartTime = -1;
23952 }
23953 }
23954
23955 workInProgress.childExpirationTime = current.childExpirationTime;
23956 workInProgress.expirationTime = current.expirationTime;
23957
23958 workInProgress.child = current.child;
23959 workInProgress.memoizedProps = current.memoizedProps;
23960 workInProgress.memoizedState = current.memoizedState;
23961 workInProgress.updateQueue = current.updateQueue;
23962
23963 // Clone the dependencies object. This is mutated during the render phase, so
23964 // it cannot be shared with the current fiber.
23965 var currentDependencies = current.dependencies;
23966 workInProgress.dependencies = currentDependencies === null ? null : {
23967 expirationTime: currentDependencies.expirationTime,
23968 firstContext: currentDependencies.firstContext,
23969 responders: currentDependencies.responders
23970 };
23971
23972 // These will be overridden during the parent's reconciliation
23973 workInProgress.sibling = current.sibling;
23974 workInProgress.index = current.index;
23975 workInProgress.ref = current.ref;
23976
23977 if (enableProfilerTimer) {
23978 workInProgress.selfBaseDuration = current.selfBaseDuration;
23979 workInProgress.treeBaseDuration = current.treeBaseDuration;
23980 }
23981
23982 {
23983 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
23984 switch (workInProgress.tag) {
23985 case IndeterminateComponent:
23986 case FunctionComponent:
23987 case SimpleMemoComponent:
23988 workInProgress.type = resolveFunctionForHotReloading(current.type);
23989 break;
23990 case ClassComponent:
23991 workInProgress.type = resolveClassForHotReloading(current.type);
23992 break;
23993 case ForwardRef:
23994 workInProgress.type = resolveForwardRefForHotReloading(current.type);
23995 break;
23996 default:
23997 break;
23998 }
23999 }
24000
24001 return workInProgress;
24002}
24003
24004// Used to reuse a Fiber for a second pass.
24005function resetWorkInProgress(workInProgress, renderExpirationTime) {
24006 // This resets the Fiber to what createFiber or createWorkInProgress would
24007 // have set the values to before during the first pass. Ideally this wouldn't
24008 // be necessary but unfortunately many code paths reads from the workInProgress
24009 // when they should be reading from current and writing to workInProgress.
24010
24011 // We assume pendingProps, index, key, ref, return are still untouched to
24012 // avoid doing another reconciliation.
24013
24014 // Reset the effect tag but keep any Placement tags, since that's something
24015 // that child fiber is setting, not the reconciliation.
24016 workInProgress.effectTag &= Placement;
24017
24018 // The effect list is no longer valid.
24019 workInProgress.nextEffect = null;
24020 workInProgress.firstEffect = null;
24021 workInProgress.lastEffect = null;
24022
24023 var current = workInProgress.alternate;
24024 if (current === null) {
24025 // Reset to createFiber's initial values.
24026 workInProgress.childExpirationTime = NoWork;
24027 workInProgress.expirationTime = renderExpirationTime;
24028
24029 workInProgress.child = null;
24030 workInProgress.memoizedProps = null;
24031 workInProgress.memoizedState = null;
24032 workInProgress.updateQueue = null;
24033
24034 workInProgress.dependencies = null;
24035
24036 if (enableProfilerTimer) {
24037 // Note: We don't reset the actualTime counts. It's useful to accumulate
24038 // actual time across multiple render passes.
24039 workInProgress.selfBaseDuration = 0;
24040 workInProgress.treeBaseDuration = 0;
24041 }
24042 } else {
24043 // Reset to the cloned values that createWorkInProgress would've.
24044 workInProgress.childExpirationTime = current.childExpirationTime;
24045 workInProgress.expirationTime = current.expirationTime;
24046
24047 workInProgress.child = current.child;
24048 workInProgress.memoizedProps = current.memoizedProps;
24049 workInProgress.memoizedState = current.memoizedState;
24050 workInProgress.updateQueue = current.updateQueue;
24051
24052 // Clone the dependencies object. This is mutated during the render phase, so
24053 // it cannot be shared with the current fiber.
24054 var currentDependencies = current.dependencies;
24055 workInProgress.dependencies = currentDependencies === null ? null : {
24056 expirationTime: currentDependencies.expirationTime,
24057 firstContext: currentDependencies.firstContext,
24058 responders: currentDependencies.responders
24059 };
24060
24061 if (enableProfilerTimer) {
24062 // Note: We don't reset the actualTime counts. It's useful to accumulate
24063 // actual time across multiple render passes.
24064 workInProgress.selfBaseDuration = current.selfBaseDuration;
24065 workInProgress.treeBaseDuration = current.treeBaseDuration;
24066 }
24067 }
24068
24069 return workInProgress;
24070}
24071
24072function createHostRootFiber(tag) {
24073 var mode = void 0;
24074 if (tag === ConcurrentRoot) {
24075 mode = ConcurrentMode | BatchedMode | StrictMode;
24076 } else if (tag === BatchedRoot) {
24077 mode = BatchedMode | StrictMode;
24078 } else {
24079 mode = NoMode;
24080 }
24081
24082 if (enableProfilerTimer && isDevToolsPresent) {
24083 // Always collect profile timings when DevTools are present.
24084 // This enables DevTools to start capturing timing at any point–
24085 // Without some nodes in the tree having empty base times.
24086 mode |= ProfileMode;
24087 }
24088
24089 return createFiber(HostRoot, null, null, mode);
24090}
24091
24092function createFiberFromTypeAndProps(type, // React$ElementType
24093key, pendingProps, owner, mode, expirationTime) {
24094 var fiber = void 0;
24095
24096 var fiberTag = IndeterminateComponent;
24097 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
24098 var resolvedType = type;
24099 if (typeof type === 'function') {
24100 if (shouldConstruct(type)) {
24101 fiberTag = ClassComponent;
24102 {
24103 resolvedType = resolveClassForHotReloading(resolvedType);
24104 }
24105 } else {
24106 {
24107 resolvedType = resolveFunctionForHotReloading(resolvedType);
24108 }
24109 }
24110 } else if (typeof type === 'string') {
24111 fiberTag = HostComponent;
24112 } else {
24113 getTag: switch (type) {
24114 case REACT_FRAGMENT_TYPE:
24115 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
24116 case REACT_CONCURRENT_MODE_TYPE:
24117 fiberTag = Mode;
24118 mode |= ConcurrentMode | BatchedMode | StrictMode;
24119 break;
24120 case REACT_STRICT_MODE_TYPE:
24121 fiberTag = Mode;
24122 mode |= StrictMode;
24123 break;
24124 case REACT_PROFILER_TYPE:
24125 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
24126 case REACT_SUSPENSE_TYPE:
24127 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
24128 case REACT_SUSPENSE_LIST_TYPE:
24129 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
24130 default:
24131 {
24132 if (typeof type === 'object' && type !== null) {
24133 switch (type.$$typeof) {
24134 case REACT_PROVIDER_TYPE:
24135 fiberTag = ContextProvider;
24136 break getTag;
24137 case REACT_CONTEXT_TYPE:
24138 // This is a consumer
24139 fiberTag = ContextConsumer;
24140 break getTag;
24141 case REACT_FORWARD_REF_TYPE:
24142 fiberTag = ForwardRef;
24143 {
24144 resolvedType = resolveForwardRefForHotReloading(resolvedType);
24145 }
24146 break getTag;
24147 case REACT_MEMO_TYPE:
24148 fiberTag = MemoComponent;
24149 break getTag;
24150 case REACT_LAZY_TYPE:
24151 fiberTag = LazyComponent;
24152 resolvedType = null;
24153 break getTag;
24154 case REACT_FUNDAMENTAL_TYPE:
24155 if (enableFundamentalAPI) {
24156 return createFiberFromFundamental(type, pendingProps, mode, expirationTime, key);
24157 }
24158 break;
24159 }
24160 }
24161 var info = '';
24162 {
24163 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
24164 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.';
24165 }
24166 var ownerName = owner ? getComponentName(owner.type) : null;
24167 if (ownerName) {
24168 info += '\n\nCheck the render method of `' + ownerName + '`.';
24169 }
24170 }
24171 (function () {
24172 {
24173 {
24174 throw ReactError(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));
24175 }
24176 }
24177 })();
24178 }
24179 }
24180 }
24181
24182 fiber = createFiber(fiberTag, pendingProps, key, mode);
24183 fiber.elementType = type;
24184 fiber.type = resolvedType;
24185 fiber.expirationTime = expirationTime;
24186
24187 return fiber;
24188}
24189
24190function createFiberFromElement(element, mode, expirationTime) {
24191 var owner = null;
24192 {
24193 owner = element._owner;
24194 }
24195 var type = element.type;
24196 var key = element.key;
24197 var pendingProps = element.props;
24198 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
24199 {
24200 fiber._debugSource = element._source;
24201 fiber._debugOwner = element._owner;
24202 }
24203 return fiber;
24204}
24205
24206function createFiberFromFragment(elements, mode, expirationTime, key) {
24207 var fiber = createFiber(Fragment, elements, key, mode);
24208 fiber.expirationTime = expirationTime;
24209 return fiber;
24210}
24211
24212function createFiberFromFundamental(fundamentalComponent, pendingProps, mode, expirationTime, key) {
24213 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
24214 fiber.elementType = fundamentalComponent;
24215 fiber.type = fundamentalComponent;
24216 fiber.expirationTime = expirationTime;
24217 return fiber;
24218}
24219
24220function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
24221 {
24222 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
24223 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
24224 }
24225 }
24226
24227 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
24228 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
24229 fiber.elementType = REACT_PROFILER_TYPE;
24230 fiber.type = REACT_PROFILER_TYPE;
24231 fiber.expirationTime = expirationTime;
24232
24233 return fiber;
24234}
24235
24236function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
24237 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
24238
24239 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
24240 // This needs to be fixed in getComponentName so that it relies on the tag
24241 // instead.
24242 fiber.type = REACT_SUSPENSE_TYPE;
24243 fiber.elementType = REACT_SUSPENSE_TYPE;
24244
24245 fiber.expirationTime = expirationTime;
24246 return fiber;
24247}
24248
24249function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
24250 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
24251 {
24252 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
24253 // This needs to be fixed in getComponentName so that it relies on the tag
24254 // instead.
24255 fiber.type = REACT_SUSPENSE_LIST_TYPE;
24256 }
24257 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
24258 fiber.expirationTime = expirationTime;
24259 return fiber;
24260}
24261
24262function createFiberFromText(content, mode, expirationTime) {
24263 var fiber = createFiber(HostText, content, null, mode);
24264 fiber.expirationTime = expirationTime;
24265 return fiber;
24266}
24267
24268function createFiberFromHostInstanceForDeletion() {
24269 var fiber = createFiber(HostComponent, null, null, NoMode);
24270 // TODO: These should not need a type.
24271 fiber.elementType = 'DELETED';
24272 fiber.type = 'DELETED';
24273 return fiber;
24274}
24275
24276function createFiberFromPortal(portal, mode, expirationTime) {
24277 var pendingProps = portal.children !== null ? portal.children : [];
24278 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
24279 fiber.expirationTime = expirationTime;
24280 fiber.stateNode = {
24281 containerInfo: portal.containerInfo,
24282 pendingChildren: null, // Used by persistent updates
24283 implementation: portal.implementation
24284 };
24285 return fiber;
24286}
24287
24288// Used for stashing WIP properties to replay failed work in DEV.
24289function assignFiberPropertiesInDEV(target, source) {
24290 if (target === null) {
24291 // This Fiber's initial properties will always be overwritten.
24292 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
24293 target = createFiber(IndeterminateComponent, null, null, NoMode);
24294 }
24295
24296 // This is intentionally written as a list of all properties.
24297 // We tried to use Object.assign() instead but this is called in
24298 // the hottest path, and Object.assign() was too slow:
24299 // https://github.com/facebook/react/issues/12502
24300 // This code is DEV-only so size is not a concern.
24301
24302 target.tag = source.tag;
24303 target.key = source.key;
24304 target.elementType = source.elementType;
24305 target.type = source.type;
24306 target.stateNode = source.stateNode;
24307 target.return = source.return;
24308 target.child = source.child;
24309 target.sibling = source.sibling;
24310 target.index = source.index;
24311 target.ref = source.ref;
24312 target.pendingProps = source.pendingProps;
24313 target.memoizedProps = source.memoizedProps;
24314 target.updateQueue = source.updateQueue;
24315 target.memoizedState = source.memoizedState;
24316 target.dependencies = source.dependencies;
24317 target.mode = source.mode;
24318 target.effectTag = source.effectTag;
24319 target.nextEffect = source.nextEffect;
24320 target.firstEffect = source.firstEffect;
24321 target.lastEffect = source.lastEffect;
24322 target.expirationTime = source.expirationTime;
24323 target.childExpirationTime = source.childExpirationTime;
24324 target.alternate = source.alternate;
24325 if (enableProfilerTimer) {
24326 target.actualDuration = source.actualDuration;
24327 target.actualStartTime = source.actualStartTime;
24328 target.selfBaseDuration = source.selfBaseDuration;
24329 target.treeBaseDuration = source.treeBaseDuration;
24330 }
24331 target._debugID = source._debugID;
24332 target._debugSource = source._debugSource;
24333 target._debugOwner = source._debugOwner;
24334 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
24335 target._debugNeedsRemount = source._debugNeedsRemount;
24336 target._debugHookTypes = source._debugHookTypes;
24337 return target;
24338}
24339
24340// TODO: This should be lifted into the renderer.
24341
24342
24343// The following attributes are only used by interaction tracing builds.
24344// They enable interactions to be associated with their async work,
24345// And expose interaction metadata to the React DevTools Profiler plugin.
24346// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
24347
24348
24349// Exported FiberRoot type includes all properties,
24350// To avoid requiring potentially error-prone :any casts throughout the project.
24351// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
24352// The types are defined separately within this file to ensure they stay in sync.
24353// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
24354
24355
24356function FiberRootNode(containerInfo, tag, hydrate) {
24357 this.tag = tag;
24358 this.current = null;
24359 this.containerInfo = containerInfo;
24360 this.pendingChildren = null;
24361 this.pingCache = null;
24362 this.finishedExpirationTime = NoWork;
24363 this.finishedWork = null;
24364 this.timeoutHandle = noTimeout;
24365 this.context = null;
24366 this.pendingContext = null;
24367 this.hydrate = hydrate;
24368 this.firstBatch = null;
24369 this.callbackNode = null;
24370 this.callbackExpirationTime = NoWork;
24371 this.firstPendingTime = NoWork;
24372 this.lastPendingTime = NoWork;
24373 this.pingTime = NoWork;
24374
24375 if (enableSchedulerTracing) {
24376 this.interactionThreadID = unstable_getThreadID();
24377 this.memoizedInteractions = new Set();
24378 this.pendingInteractionMap = new Map();
24379 }
24380}
24381
24382function createFiberRoot(containerInfo, tag, hydrate) {
24383 var root = new FiberRootNode(containerInfo, tag, hydrate);
24384
24385 // Cyclic construction. This cheats the type system right now because
24386 // stateNode is any.
24387 var uninitializedFiber = createHostRootFiber(tag);
24388 root.current = uninitializedFiber;
24389 uninitializedFiber.stateNode = root;
24390
24391 return root;
24392}
24393
24394// This lets us hook into Fiber to debug what it's doing.
24395// See https://github.com/facebook/react/pull/8033.
24396// This is not part of the public API, not even for React DevTools.
24397// You may only inject a debugTool if you work on React Fiber itself.
24398var ReactFiberInstrumentation = {
24399 debugTool: null
24400};
24401
24402var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
24403
24404// 0 is PROD, 1 is DEV.
24405// Might add PROFILE later.
24406
24407
24408var didWarnAboutNestedUpdates = void 0;
24409var didWarnAboutFindNodeInStrictMode = void 0;
24410
24411{
24412 didWarnAboutNestedUpdates = false;
24413 didWarnAboutFindNodeInStrictMode = {};
24414}
24415
24416function getContextForSubtree(parentComponent) {
24417 if (!parentComponent) {
24418 return emptyContextObject;
24419 }
24420
24421 var fiber = get(parentComponent);
24422 var parentContext = findCurrentUnmaskedContext(fiber);
24423
24424 if (fiber.tag === ClassComponent) {
24425 var Component = fiber.type;
24426 if (isContextProvider(Component)) {
24427 return processChildContext(fiber, Component, parentContext);
24428 }
24429 }
24430
24431 return parentContext;
24432}
24433
24434function scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback) {
24435 {
24436 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
24437 didWarnAboutNestedUpdates = true;
24438 warningWithoutStack$1(false, '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');
24439 }
24440 }
24441
24442 var update = createUpdate(expirationTime, suspenseConfig);
24443 // Caution: React DevTools currently depends on this property
24444 // being called "element".
24445 update.payload = { element: element };
24446
24447 callback = callback === undefined ? null : callback;
24448 if (callback !== null) {
24449 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
24450 update.callback = callback;
24451 }
24452
24453 if (revertPassiveEffectsChange) {
24454 flushPassiveEffects();
24455 }
24456 enqueueUpdate(current$$1, update);
24457 scheduleWork(current$$1, expirationTime);
24458
24459 return expirationTime;
24460}
24461
24462function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback) {
24463 // TODO: If this is a nested container, this won't be the root.
24464 var current$$1 = container.current;
24465
24466 {
24467 if (ReactFiberInstrumentation_1.debugTool) {
24468 if (current$$1.alternate === null) {
24469 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
24470 } else if (element === null) {
24471 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
24472 } else {
24473 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
24474 }
24475 }
24476 }
24477
24478 var context = getContextForSubtree(parentComponent);
24479 if (container.context === null) {
24480 container.context = context;
24481 } else {
24482 container.pendingContext = context;
24483 }
24484
24485 return scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback);
24486}
24487
24488function findHostInstance(component) {
24489 var fiber = get(component);
24490 if (fiber === undefined) {
24491 if (typeof component.render === 'function') {
24492 (function () {
24493 {
24494 {
24495 throw ReactError(Error('Unable to find node on an unmounted component.'));
24496 }
24497 }
24498 })();
24499 } else {
24500 (function () {
24501 {
24502 {
24503 throw ReactError(Error('Argument appears to not be a ReactComponent. Keys: ' + Object.keys(component)));
24504 }
24505 }
24506 })();
24507 }
24508 }
24509 var hostFiber = findCurrentHostFiber(fiber);
24510 if (hostFiber === null) {
24511 return null;
24512 }
24513 return hostFiber.stateNode;
24514}
24515
24516function findHostInstanceWithWarning(component, methodName) {
24517 {
24518 var fiber = get(component);
24519 if (fiber === undefined) {
24520 if (typeof component.render === 'function') {
24521 (function () {
24522 {
24523 {
24524 throw ReactError(Error('Unable to find node on an unmounted component.'));
24525 }
24526 }
24527 })();
24528 } else {
24529 (function () {
24530 {
24531 {
24532 throw ReactError(Error('Argument appears to not be a ReactComponent. Keys: ' + Object.keys(component)));
24533 }
24534 }
24535 })();
24536 }
24537 }
24538 var hostFiber = findCurrentHostFiber(fiber);
24539 if (hostFiber === null) {
24540 return null;
24541 }
24542 if (hostFiber.mode & StrictMode) {
24543 var componentName = getComponentName(fiber.type) || 'Component';
24544 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
24545 didWarnAboutFindNodeInStrictMode[componentName] = true;
24546 if (fiber.mode & StrictMode) {
24547 warningWithoutStack$1(false, '%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.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-find-node', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));
24548 } else {
24549 warningWithoutStack$1(false, '%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.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-find-node', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));
24550 }
24551 }
24552 }
24553 return hostFiber.stateNode;
24554 }
24555 return findHostInstance(component);
24556}
24557
24558function createContainer(containerInfo, tag, hydrate) {
24559 return createFiberRoot(containerInfo, tag, hydrate);
24560}
24561
24562function updateContainer(element, container, parentComponent, callback) {
24563 var current$$1 = container.current;
24564 var currentTime = requestCurrentTime();
24565 {
24566 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
24567 if ('undefined' !== typeof jest) {
24568 warnIfUnmockedScheduler(current$$1);
24569 warnIfNotScopedWithMatchingAct(current$$1);
24570 }
24571 }
24572 var suspenseConfig = requestCurrentSuspenseConfig();
24573 var expirationTime = computeExpirationForFiber(currentTime, current$$1, suspenseConfig);
24574 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback);
24575}
24576
24577function getPublicRootInstance(container) {
24578 var containerFiber = container.current;
24579 if (!containerFiber.child) {
24580 return null;
24581 }
24582 switch (containerFiber.child.tag) {
24583 case HostComponent:
24584 return getPublicInstance(containerFiber.child.stateNode);
24585 default:
24586 return containerFiber.child.stateNode;
24587 }
24588}
24589
24590function findHostInstanceWithNoPortals(fiber) {
24591 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
24592 if (hostFiber === null) {
24593 return null;
24594 }
24595 if (hostFiber.tag === FundamentalComponent) {
24596 return hostFiber.stateNode.instance;
24597 }
24598 return hostFiber.stateNode;
24599}
24600
24601var shouldSuspendImpl = function (fiber) {
24602 return false;
24603};
24604
24605function shouldSuspend(fiber) {
24606 return shouldSuspendImpl(fiber);
24607}
24608
24609var overrideHookState = null;
24610var overrideProps = null;
24611var scheduleUpdate = null;
24612var setSuspenseHandler = null;
24613
24614{
24615 var copyWithSetImpl = function (obj, path, idx, value) {
24616 if (idx >= path.length) {
24617 return value;
24618 }
24619 var key = path[idx];
24620 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
24621 // $FlowFixMe number or string is fine here
24622 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
24623 return updated;
24624 };
24625
24626 var copyWithSet = function (obj, path, value) {
24627 return copyWithSetImpl(obj, path, 0, value);
24628 };
24629
24630 // Support DevTools editable values for useState and useReducer.
24631 overrideHookState = function (fiber, id, path, value) {
24632 // For now, the "id" of stateful hooks is just the stateful hook index.
24633 // This may change in the future with e.g. nested hooks.
24634 var currentHook = fiber.memoizedState;
24635 while (currentHook !== null && id > 0) {
24636 currentHook = currentHook.next;
24637 id--;
24638 }
24639 if (currentHook !== null) {
24640 if (revertPassiveEffectsChange) {
24641 flushPassiveEffects();
24642 }
24643
24644 var newState = copyWithSet(currentHook.memoizedState, path, value);
24645 currentHook.memoizedState = newState;
24646 currentHook.baseState = newState;
24647
24648 // We aren't actually adding an update to the queue,
24649 // because there is no update we can add for useReducer hooks that won't trigger an error.
24650 // (There's no appropriate action type for DevTools overrides.)
24651 // As a result though, React will see the scheduled update as a noop and bailout.
24652 // Shallow cloning props works as a workaround for now to bypass the bailout check.
24653 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
24654
24655 scheduleWork(fiber, Sync);
24656 }
24657 };
24658
24659 // Support DevTools props for function components, forwardRef, memo, host components, etc.
24660 overrideProps = function (fiber, path, value) {
24661 if (revertPassiveEffectsChange) {
24662 flushPassiveEffects();
24663 }
24664 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
24665 if (fiber.alternate) {
24666 fiber.alternate.pendingProps = fiber.pendingProps;
24667 }
24668 scheduleWork(fiber, Sync);
24669 };
24670
24671 scheduleUpdate = function (fiber) {
24672 if (revertPassiveEffectsChange) {
24673 flushPassiveEffects();
24674 }
24675 scheduleWork(fiber, Sync);
24676 };
24677
24678 setSuspenseHandler = function (newShouldSuspendImpl) {
24679 shouldSuspendImpl = newShouldSuspendImpl;
24680 };
24681}
24682
24683function injectIntoDevTools(devToolsConfig) {
24684 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
24685 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
24686
24687
24688 return injectInternals(_assign({}, devToolsConfig, {
24689 overrideHookState: overrideHookState,
24690 overrideProps: overrideProps,
24691 setSuspenseHandler: setSuspenseHandler,
24692 scheduleUpdate: scheduleUpdate,
24693 currentDispatcherRef: ReactCurrentDispatcher,
24694 findHostInstanceByFiber: function (fiber) {
24695 var hostFiber = findCurrentHostFiber(fiber);
24696 if (hostFiber === null) {
24697 return null;
24698 }
24699 return hostFiber.stateNode;
24700 },
24701 findFiberByHostInstance: function (instance) {
24702 if (!findFiberByHostInstance) {
24703 // Might not be implemented by the renderer.
24704 return null;
24705 }
24706 return findFiberByHostInstance(instance);
24707 },
24708
24709 // React Refresh
24710 findHostInstancesForRefresh: findHostInstancesForRefresh,
24711 scheduleRefresh: scheduleRefresh,
24712 scheduleRoot: scheduleRoot,
24713 setRefreshHandler: setRefreshHandler,
24714 // Enables DevTools to append owner stacks to error messages in DEV mode.
24715 getCurrentFiber: function () {
24716 return current;
24717 }
24718 }));
24719}
24720
24721// This file intentionally does *not* have the Flow annotation.
24722// Don't add it. See `./inline-typed.js` for an explanation.
24723
24724function createPortal$1(children, containerInfo,
24725// TODO: figure out the API for cross-renderer implementation.
24726implementation) {
24727 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
24728
24729 return {
24730 // This tag allow us to uniquely identify this as a React Portal
24731 $$typeof: REACT_PORTAL_TYPE,
24732 key: key == null ? null : '' + key,
24733 children: children,
24734 containerInfo: containerInfo,
24735 implementation: implementation
24736 };
24737}
24738
24739// TODO: this is special because it gets imported during build.
24740
24741var ReactVersion = '16.9.0';
24742
24743// TODO: This type is shared between the reconciler and ReactDOM, but will
24744// eventually be lifted out to the renderer.
24745
24746var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
24747
24748var topLevelUpdateWarnings = void 0;
24749var warnOnInvalidCallback = void 0;
24750var didWarnAboutUnstableCreatePortal = false;
24751
24752{
24753 if (typeof Map !== 'function' ||
24754 // $FlowIssue Flow incorrectly thinks Map has no prototype
24755 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
24756 // $FlowIssue Flow incorrectly thinks Set has no prototype
24757 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
24758 warningWithoutStack$1(false, 'React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
24759 }
24760
24761 topLevelUpdateWarnings = function (container) {
24762 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
24763 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
24764 if (hostInstance) {
24765 !(hostInstance.parentNode === container) ? warningWithoutStack$1(false, '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.') : void 0;
24766 }
24767 }
24768
24769 var isRootRenderedBySomeReact = !!container._reactRootContainer;
24770 var rootEl = getReactRootElementInContainer(container);
24771 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
24772
24773 !(!hasNonRootReactChild || isRootRenderedBySomeReact) ? warningWithoutStack$1(false, '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.') : void 0;
24774
24775 !(container.nodeType !== ELEMENT_NODE || !container.tagName || container.tagName.toUpperCase() !== 'BODY') ? warningWithoutStack$1(false, '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.') : void 0;
24776 };
24777
24778 warnOnInvalidCallback = function (callback, callerName) {
24779 !(callback === null || typeof callback === 'function') ? warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback) : void 0;
24780 };
24781}
24782
24783setRestoreImplementation(restoreControlledState$1);
24784
24785function ReactBatch(root) {
24786 var expirationTime = computeUniqueAsyncExpiration();
24787 this._expirationTime = expirationTime;
24788 this._root = root;
24789 this._next = null;
24790 this._callbacks = null;
24791 this._didComplete = false;
24792 this._hasChildren = false;
24793 this._children = null;
24794 this._defer = true;
24795}
24796ReactBatch.prototype.render = function (children) {
24797 var _this = this;
24798
24799 (function () {
24800 if (!_this._defer) {
24801 {
24802 throw ReactError(Error('batch.render: Cannot render a batch that already committed.'));
24803 }
24804 }
24805 })();
24806 this._hasChildren = true;
24807 this._children = children;
24808 var internalRoot = this._root._internalRoot;
24809 var expirationTime = this._expirationTime;
24810 var work = new ReactWork();
24811 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, null, work._onCommit);
24812 return work;
24813};
24814ReactBatch.prototype.then = function (onComplete) {
24815 if (this._didComplete) {
24816 onComplete();
24817 return;
24818 }
24819 var callbacks = this._callbacks;
24820 if (callbacks === null) {
24821 callbacks = this._callbacks = [];
24822 }
24823 callbacks.push(onComplete);
24824};
24825ReactBatch.prototype.commit = function () {
24826 var _this2 = this;
24827
24828 var internalRoot = this._root._internalRoot;
24829 var firstBatch = internalRoot.firstBatch;
24830 (function () {
24831 if (!(_this2._defer && firstBatch !== null)) {
24832 {
24833 throw ReactError(Error('batch.commit: Cannot commit a batch multiple times.'));
24834 }
24835 }
24836 })();
24837
24838 if (!this._hasChildren) {
24839 // This batch is empty. Return.
24840 this._next = null;
24841 this._defer = false;
24842 return;
24843 }
24844
24845 var expirationTime = this._expirationTime;
24846
24847 // Ensure this is the first batch in the list.
24848 if (firstBatch !== this) {
24849 // This batch is not the earliest batch. We need to move it to the front.
24850 // Update its expiration time to be the expiration time of the earliest
24851 // batch, so that we can flush it without flushing the other batches.
24852 if (this._hasChildren) {
24853 expirationTime = this._expirationTime = firstBatch._expirationTime;
24854 // Rendering this batch again ensures its children will be the final state
24855 // when we flush (updates are processed in insertion order: last
24856 // update wins).
24857 // TODO: This forces a restart. Should we print a warning?
24858 this.render(this._children);
24859 }
24860
24861 // Remove the batch from the list.
24862 var previous = null;
24863 var batch = firstBatch;
24864 while (batch !== this) {
24865 previous = batch;
24866 batch = batch._next;
24867 }
24868 (function () {
24869 if (!(previous !== null)) {
24870 {
24871 throw ReactError(Error('batch.commit: Cannot commit a batch multiple times.'));
24872 }
24873 }
24874 })();
24875 previous._next = batch._next;
24876
24877 // Add it to the front.
24878 this._next = firstBatch;
24879 firstBatch = internalRoot.firstBatch = this;
24880 }
24881
24882 // Synchronously flush all the work up to this batch's expiration time.
24883 this._defer = false;
24884 flushRoot(internalRoot, expirationTime);
24885
24886 // Pop the batch from the list.
24887 var next = this._next;
24888 this._next = null;
24889 firstBatch = internalRoot.firstBatch = next;
24890
24891 // Append the next earliest batch's children to the update queue.
24892 if (firstBatch !== null && firstBatch._hasChildren) {
24893 firstBatch.render(firstBatch._children);
24894 }
24895};
24896ReactBatch.prototype._onComplete = function () {
24897 if (this._didComplete) {
24898 return;
24899 }
24900 this._didComplete = true;
24901 var callbacks = this._callbacks;
24902 if (callbacks === null) {
24903 return;
24904 }
24905 // TODO: Error handling.
24906 for (var i = 0; i < callbacks.length; i++) {
24907 var _callback = callbacks[i];
24908 _callback();
24909 }
24910};
24911
24912function ReactWork() {
24913 this._callbacks = null;
24914 this._didCommit = false;
24915 // TODO: Avoid need to bind by replacing callbacks in the update queue with
24916 // list of Work objects.
24917 this._onCommit = this._onCommit.bind(this);
24918}
24919ReactWork.prototype.then = function (onCommit) {
24920 if (this._didCommit) {
24921 onCommit();
24922 return;
24923 }
24924 var callbacks = this._callbacks;
24925 if (callbacks === null) {
24926 callbacks = this._callbacks = [];
24927 }
24928 callbacks.push(onCommit);
24929};
24930ReactWork.prototype._onCommit = function () {
24931 if (this._didCommit) {
24932 return;
24933 }
24934 this._didCommit = true;
24935 var callbacks = this._callbacks;
24936 if (callbacks === null) {
24937 return;
24938 }
24939 // TODO: Error handling.
24940 for (var i = 0; i < callbacks.length; i++) {
24941 var _callback2 = callbacks[i];
24942 (function () {
24943 if (!(typeof _callback2 === 'function')) {
24944 {
24945 throw ReactError(Error('Invalid argument passed as callback. Expected a function. Instead received: ' + _callback2));
24946 }
24947 }
24948 })();
24949 _callback2();
24950 }
24951};
24952
24953function ReactSyncRoot(container, tag, hydrate) {
24954 // Tag is either LegacyRoot or Concurrent Root
24955 var root = createContainer(container, tag, hydrate);
24956 this._internalRoot = root;
24957}
24958
24959function ReactRoot(container, hydrate) {
24960 var root = createContainer(container, ConcurrentRoot, hydrate);
24961 this._internalRoot = root;
24962}
24963
24964ReactRoot.prototype.render = ReactSyncRoot.prototype.render = function (children, callback) {
24965 var root = this._internalRoot;
24966 var work = new ReactWork();
24967 callback = callback === undefined ? null : callback;
24968 {
24969 warnOnInvalidCallback(callback, 'render');
24970 }
24971 if (callback !== null) {
24972 work.then(callback);
24973 }
24974 updateContainer(children, root, null, work._onCommit);
24975 return work;
24976};
24977
24978ReactRoot.prototype.unmount = ReactSyncRoot.prototype.unmount = function (callback) {
24979 var root = this._internalRoot;
24980 var work = new ReactWork();
24981 callback = callback === undefined ? null : callback;
24982 {
24983 warnOnInvalidCallback(callback, 'render');
24984 }
24985 if (callback !== null) {
24986 work.then(callback);
24987 }
24988 updateContainer(null, root, null, work._onCommit);
24989 return work;
24990};
24991
24992// Sync roots cannot create batches. Only concurrent ones.
24993ReactRoot.prototype.createBatch = function () {
24994 var batch = new ReactBatch(this);
24995 var expirationTime = batch._expirationTime;
24996
24997 var internalRoot = this._internalRoot;
24998 var firstBatch = internalRoot.firstBatch;
24999 if (firstBatch === null) {
25000 internalRoot.firstBatch = batch;
25001 batch._next = null;
25002 } else {
25003 // Insert sorted by expiration time then insertion order
25004 var insertAfter = null;
25005 var insertBefore = firstBatch;
25006 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
25007 insertAfter = insertBefore;
25008 insertBefore = insertBefore._next;
25009 }
25010 batch._next = insertBefore;
25011 if (insertAfter !== null) {
25012 insertAfter._next = batch;
25013 }
25014 }
25015
25016 return batch;
25017};
25018
25019/**
25020 * True if the supplied DOM node is a valid node element.
25021 *
25022 * @param {?DOMElement} node The candidate DOM node.
25023 * @return {boolean} True if the DOM is a valid DOM node.
25024 * @internal
25025 */
25026function isValidContainer(node) {
25027 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 '));
25028}
25029
25030function getReactRootElementInContainer(container) {
25031 if (!container) {
25032 return null;
25033 }
25034
25035 if (container.nodeType === DOCUMENT_NODE) {
25036 return container.documentElement;
25037 } else {
25038 return container.firstChild;
25039 }
25040}
25041
25042function shouldHydrateDueToLegacyHeuristic(container) {
25043 var rootElement = getReactRootElementInContainer(container);
25044 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
25045}
25046
25047setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);
25048
25049var warnedAboutHydrateAPI = false;
25050
25051function legacyCreateRootFromDOMContainer(container, forceHydrate) {
25052 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
25053 // First clear any existing content.
25054 if (!shouldHydrate) {
25055 var warned = false;
25056 var rootSibling = void 0;
25057 while (rootSibling = container.lastChild) {
25058 {
25059 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
25060 warned = true;
25061 warningWithoutStack$1(false, '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.');
25062 }
25063 }
25064 container.removeChild(rootSibling);
25065 }
25066 }
25067 {
25068 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
25069 warnedAboutHydrateAPI = true;
25070 lowPriorityWarning$1(false, '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.');
25071 }
25072 }
25073
25074 // Legacy roots are not batched.
25075 return new ReactSyncRoot(container, LegacyRoot, shouldHydrate);
25076}
25077
25078function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
25079 {
25080 topLevelUpdateWarnings(container);
25081 warnOnInvalidCallback(callback === undefined ? null : callback, 'render');
25082 }
25083
25084 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
25085 // member of intersection type." Whyyyyyy.
25086 var root = container._reactRootContainer;
25087 var fiberRoot = void 0;
25088 if (!root) {
25089 // Initial mount
25090 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
25091 fiberRoot = root._internalRoot;
25092 if (typeof callback === 'function') {
25093 var originalCallback = callback;
25094 callback = function () {
25095 var instance = getPublicRootInstance(fiberRoot);
25096 originalCallback.call(instance);
25097 };
25098 }
25099 // Initial mount should not be batched.
25100 unbatchedUpdates(function () {
25101 updateContainer(children, fiberRoot, parentComponent, callback);
25102 });
25103 } else {
25104 fiberRoot = root._internalRoot;
25105 if (typeof callback === 'function') {
25106 var _originalCallback = callback;
25107 callback = function () {
25108 var instance = getPublicRootInstance(fiberRoot);
25109 _originalCallback.call(instance);
25110 };
25111 }
25112 // Update
25113 updateContainer(children, fiberRoot, parentComponent, callback);
25114 }
25115 return getPublicRootInstance(fiberRoot);
25116}
25117
25118function createPortal$$1(children, container) {
25119 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
25120
25121 (function () {
25122 if (!isValidContainer(container)) {
25123 {
25124 throw ReactError(Error('Target container is not a DOM element.'));
25125 }
25126 }
25127 })();
25128 // TODO: pass ReactDOM portal implementation as third argument
25129 return createPortal$1(children, container, null, key);
25130}
25131
25132var ReactDOM = {
25133 createPortal: createPortal$$1,
25134
25135 findDOMNode: function (componentOrElement) {
25136 {
25137 var owner = ReactCurrentOwner.current;
25138 if (owner !== null && owner.stateNode !== null) {
25139 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
25140 !warnedAboutRefsInRender ? warningWithoutStack$1(false, '%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') : void 0;
25141 owner.stateNode._warnedAboutRefsInRender = true;
25142 }
25143 }
25144 if (componentOrElement == null) {
25145 return null;
25146 }
25147 if (componentOrElement.nodeType === ELEMENT_NODE) {
25148 return componentOrElement;
25149 }
25150 {
25151 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
25152 }
25153 return findHostInstance(componentOrElement);
25154 },
25155 hydrate: function (element, container, callback) {
25156 (function () {
25157 if (!isValidContainer(container)) {
25158 {
25159 throw ReactError(Error('Target container is not a DOM element.'));
25160 }
25161 }
25162 })();
25163 {
25164 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
25165 }
25166 // TODO: throw or warn if we couldn't hydrate?
25167 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
25168 },
25169 render: function (element, container, callback) {
25170 (function () {
25171 if (!isValidContainer(container)) {
25172 {
25173 throw ReactError(Error('Target container is not a DOM element.'));
25174 }
25175 }
25176 })();
25177 {
25178 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call root.render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
25179 }
25180 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
25181 },
25182 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
25183 (function () {
25184 if (!isValidContainer(containerNode)) {
25185 {
25186 throw ReactError(Error('Target container is not a DOM element.'));
25187 }
25188 }
25189 })();
25190 (function () {
25191 if (!(parentComponent != null && has(parentComponent))) {
25192 {
25193 throw ReactError(Error('parentComponent must be a valid React Component'));
25194 }
25195 }
25196 })();
25197 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
25198 },
25199 unmountComponentAtNode: function (container) {
25200 (function () {
25201 if (!isValidContainer(container)) {
25202 {
25203 throw ReactError(Error('unmountComponentAtNode(...): Target container is not a DOM element.'));
25204 }
25205 }
25206 })();
25207
25208 {
25209 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. Did you mean to call root.unmount()?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
25210 }
25211
25212 if (container._reactRootContainer) {
25213 {
25214 var rootEl = getReactRootElementInContainer(container);
25215 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
25216 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
25217 }
25218
25219 // Unmount should not be batched.
25220 unbatchedUpdates(function () {
25221 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
25222 container._reactRootContainer = null;
25223 });
25224 });
25225 // If you call unmountComponentAtNode twice in quick succession, you'll
25226 // get `true` twice. That's probably fine?
25227 return true;
25228 } else {
25229 {
25230 var _rootEl = getReactRootElementInContainer(container);
25231 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
25232
25233 // Check if the container itself is a React root node.
25234 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
25235
25236 !!hasNonRootReactChild ? warningWithoutStack$1(false, "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.') : void 0;
25237 }
25238
25239 return false;
25240 }
25241 },
25242
25243
25244 // Temporary alias since we already shipped React 16 RC with it.
25245 // TODO: remove in React 17.
25246 unstable_createPortal: function () {
25247 if (!didWarnAboutUnstableCreatePortal) {
25248 didWarnAboutUnstableCreatePortal = true;
25249 lowPriorityWarning$1(false, '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.');
25250 }
25251 return createPortal$$1.apply(undefined, arguments);
25252 },
25253
25254
25255 unstable_batchedUpdates: batchedUpdates$1,
25256
25257 // TODO remove this legacy method, unstable_discreteUpdates replaces it
25258 unstable_interactiveUpdates: function (fn, a, b, c) {
25259 flushDiscreteUpdates();
25260 return discreteUpdates$1(fn, a, b, c);
25261 },
25262
25263 unstable_discreteUpdates: discreteUpdates$1,
25264 unstable_flushDiscreteUpdates: flushDiscreteUpdates,
25265
25266 flushSync: flushSync,
25267
25268 unstable_createRoot: createRoot,
25269 unstable_createSyncRoot: createSyncRoot,
25270 unstable_flushControlled: flushControlled,
25271
25272 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
25273 // Keep in sync with ReactDOMUnstableNativeDependencies.js
25274 // ReactTestUtils.js, and ReactTestUtilsAct.js. This is an array for better minification.
25275 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch, flushPassiveEffects, IsThisRendererActing]
25276 }
25277};
25278
25279function createRoot(container, options) {
25280 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
25281 (function () {
25282 if (!isValidContainer(container)) {
25283 {
25284 throw ReactError(Error(functionName + '(...): Target container is not a DOM element.'));
25285 }
25286 }
25287 })();
25288 warnIfReactDOMContainerInDEV(container);
25289 var hydrate = options != null && options.hydrate === true;
25290 return new ReactRoot(container, hydrate);
25291}
25292
25293function createSyncRoot(container, options) {
25294 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
25295 (function () {
25296 if (!isValidContainer(container)) {
25297 {
25298 throw ReactError(Error(functionName + '(...): Target container is not a DOM element.'));
25299 }
25300 }
25301 })();
25302 warnIfReactDOMContainerInDEV(container);
25303 var hydrate = options != null && options.hydrate === true;
25304 return new ReactSyncRoot(container, BatchedRoot, hydrate);
25305}
25306
25307function warnIfReactDOMContainerInDEV(container) {
25308 {
25309 !!container._reactRootContainer ? warningWithoutStack$1(false, 'You are calling ReactDOM.%s() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
25310 container._reactHasBeenPassedToCreateRootDEV = true;
25311 }
25312}
25313
25314if (enableStableConcurrentModeAPIs) {
25315 ReactDOM.createRoot = createRoot;
25316 ReactDOM.createSyncRoot = createSyncRoot;
25317}
25318
25319var foundDevTools = injectIntoDevTools({
25320 findFiberByHostInstance: getClosestInstanceFromNode,
25321 bundleType: 1,
25322 version: ReactVersion,
25323 rendererPackageName: 'react-dom'
25324});
25325
25326{
25327 if (!foundDevTools && canUseDOM && window.top === window.self) {
25328 // If we're in Chrome or Firefox, provide a download link if not installed.
25329 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
25330 var protocol = window.location.protocol;
25331 // Don't warn in exotic cases like chrome-extension://.
25332 if (/^(https?|file):$/.test(protocol)) {
25333 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');
25334 }
25335 }
25336 }
25337}
25338
25339
25340
25341var ReactDOM$2 = Object.freeze({
25342 default: ReactDOM
25343});
25344
25345var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
25346
25347// TODO: decide on the top-level export form.
25348// This is hacky but makes it work with both Rollup and Jest.
25349var reactDom = ReactDOM$3.default || ReactDOM$3;
25350
25351return reactDom;
25352
25353})));