UNPKG

778 kBJavaScriptView Raw
1/** @license React v16.8.2
2 * react-dom.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18var React = require('react');
19var _assign = require('object-assign');
20var checkPropTypes = require('prop-types/checkPropTypes');
21var scheduler = require('scheduler');
22var tracing = require('scheduler/tracing');
23
24/**
25 * Use invariant() to assert state which your program assumes to be true.
26 *
27 * Provide sprintf-style format (only %s is supported) and arguments
28 * to provide information about what broke and what you were
29 * expecting.
30 *
31 * The invariant message will be stripped in production, but the invariant
32 * will remain to ensure logic does not differ in production.
33 */
34
35var validateFormat = function () {};
36
37{
38 validateFormat = function (format) {
39 if (format === undefined) {
40 throw new Error('invariant requires an error message argument');
41 }
42 };
43}
44
45function invariant(condition, format, a, b, c, d, e, f) {
46 validateFormat(format);
47
48 if (!condition) {
49 var error = void 0;
50 if (format === undefined) {
51 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
52 } else {
53 var args = [a, b, c, d, e, f];
54 var argIndex = 0;
55 error = new Error(format.replace(/%s/g, function () {
56 return args[argIndex++];
57 }));
58 error.name = 'Invariant Violation';
59 }
60
61 error.framesToPop = 1; // we don't care about invariant's own frame
62 throw error;
63 }
64}
65
66// Relying on the `invariant()` implementation lets us
67// preserve the format and params in the www builds.
68
69!React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0;
70
71var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
72 var funcArgs = Array.prototype.slice.call(arguments, 3);
73 try {
74 func.apply(context, funcArgs);
75 } catch (error) {
76 this.onError(error);
77 }
78};
79
80{
81 // In DEV mode, we swap out invokeGuardedCallback for a special version
82 // that plays more nicely with the browser's DevTools. The idea is to preserve
83 // "Pause on exceptions" behavior. Because React wraps all user-provided
84 // functions in invokeGuardedCallback, and the production version of
85 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
86 // like caught exceptions, and the DevTools won't pause unless the developer
87 // takes the extra step of enabling pause on caught exceptions. This is
88 // unintuitive, though, because even though React has caught the error, from
89 // the developer's perspective, the error is uncaught.
90 //
91 // To preserve the expected "Pause on exceptions" behavior, we don't use a
92 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
93 // DOM node, and call the user-provided callback from inside an event handler
94 // for that fake event. If the callback throws, the error is "captured" using
95 // a global event handler. But because the error happens in a different
96 // event loop context, it does not interrupt the normal program flow.
97 // Effectively, this gives us try-catch behavior without actually using
98 // try-catch. Neat!
99
100 // Check that the browser supports the APIs we need to implement our special
101 // DEV version of invokeGuardedCallback
102 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
103 var fakeNode = document.createElement('react');
104
105 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
106 // If document doesn't exist we know for sure we will crash in this method
107 // when we call document.createEvent(). However this can cause confusing
108 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
109 // So we preemptively throw with a better message instead.
110 !(typeof document !== 'undefined') ? invariant(false, '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.') : void 0;
111 var evt = document.createEvent('Event');
112
113 // Keeps track of whether the user-provided callback threw an error. We
114 // set this to true at the beginning, then set it to false right after
115 // calling the function. If the function errors, `didError` will never be
116 // set to false. This strategy works even if the browser is flaky and
117 // fails to call our global error handler, because it doesn't rely on
118 // the error event at all.
119 var didError = true;
120
121 // Keeps track of the value of window.event so that we can reset it
122 // during the callback to let user code access window.event in the
123 // browsers that support it.
124 var windowEvent = window.event;
125
126 // Keeps track of the descriptor of window.event to restore it after event
127 // dispatching: https://github.com/facebook/react/issues/13688
128 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
129
130 // Create an event handler for our fake event. We will synchronously
131 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
132 // call the user-provided callback.
133 var funcArgs = Array.prototype.slice.call(arguments, 3);
134 function callCallback() {
135 // We immediately remove the callback from event listeners so that
136 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
137 // nested call would trigger the fake event handlers of any call higher
138 // in the stack.
139 fakeNode.removeEventListener(evtType, callCallback, false);
140
141 // We check for window.hasOwnProperty('event') to prevent the
142 // window.event assignment in both IE <= 10 as they throw an error
143 // "Member not found" in strict mode, and in Firefox which does not
144 // support window.event.
145 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
146 window.event = windowEvent;
147 }
148
149 func.apply(context, funcArgs);
150 didError = false;
151 }
152
153 // Create a global error event handler. We use this to capture the value
154 // that was thrown. It's possible that this error handler will fire more
155 // than once; for example, if non-React code also calls `dispatchEvent`
156 // and a handler for that event throws. We should be resilient to most of
157 // those cases. Even if our error event handler fires more than once, the
158 // last error event is always used. If the callback actually does error,
159 // we know that the last error event is the correct one, because it's not
160 // possible for anything else to have happened in between our callback
161 // erroring and the code that follows the `dispatchEvent` call below. If
162 // the callback doesn't error, but the error event was fired, we know to
163 // ignore it because `didError` will be false, as described above.
164 var error = void 0;
165 // Use this to track whether the error event is ever called.
166 var didSetError = false;
167 var isCrossOriginError = false;
168
169 function handleWindowError(event) {
170 error = event.error;
171 didSetError = true;
172 if (error === null && event.colno === 0 && event.lineno === 0) {
173 isCrossOriginError = true;
174 }
175 if (event.defaultPrevented) {
176 // Some other error handler has prevented default.
177 // Browsers silence the error report if this happens.
178 // We'll remember this to later decide whether to log it or not.
179 if (error != null && typeof error === 'object') {
180 try {
181 error._suppressLogging = true;
182 } catch (inner) {
183 // Ignore.
184 }
185 }
186 }
187 }
188
189 // Create a fake event type.
190 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
191
192 // Attach our event handlers
193 window.addEventListener('error', handleWindowError);
194 fakeNode.addEventListener(evtType, callCallback, false);
195
196 // Synchronously dispatch our fake event. If the user-provided function
197 // errors, it will trigger our global error handler.
198 evt.initEvent(evtType, false, false);
199 fakeNode.dispatchEvent(evt);
200
201 if (windowEventDescriptor) {
202 Object.defineProperty(window, 'event', windowEventDescriptor);
203 }
204
205 if (didError) {
206 if (!didSetError) {
207 // The callback errored, but the error event never fired.
208 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.');
209 } else if (isCrossOriginError) {
210 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.');
211 }
212 this.onError(error);
213 }
214
215 // Remove our event listeners
216 window.removeEventListener('error', handleWindowError);
217 };
218
219 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
220 }
221}
222
223var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
224
225// Used by Fiber to simulate a try-catch.
226var hasError = false;
227var caughtError = null;
228
229// Used by event system to capture/rethrow the first error.
230var hasRethrowError = false;
231var rethrowError = null;
232
233var reporter = {
234 onError: function (error) {
235 hasError = true;
236 caughtError = error;
237 }
238};
239
240/**
241 * Call a function while guarding against errors that happens within it.
242 * Returns an error if it throws, otherwise null.
243 *
244 * In production, this is implemented using a try-catch. The reason we don't
245 * use a try-catch directly is so that we can swap out a different
246 * implementation in DEV mode.
247 *
248 * @param {String} name of the guard to use for logging or debugging
249 * @param {Function} func The function to invoke
250 * @param {*} context The context to use when calling the function
251 * @param {...*} args Arguments for function
252 */
253function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
254 hasError = false;
255 caughtError = null;
256 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
257}
258
259/**
260 * Same as invokeGuardedCallback, but instead of returning an error, it stores
261 * it in a global so it can be rethrown by `rethrowCaughtError` later.
262 * TODO: See if caughtError and rethrowError can be unified.
263 *
264 * @param {String} name of the guard to use for logging or debugging
265 * @param {Function} func The function to invoke
266 * @param {*} context The context to use when calling the function
267 * @param {...*} args Arguments for function
268 */
269function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
270 invokeGuardedCallback.apply(this, arguments);
271 if (hasError) {
272 var error = clearCaughtError();
273 if (!hasRethrowError) {
274 hasRethrowError = true;
275 rethrowError = error;
276 }
277 }
278}
279
280/**
281 * During execution of guarded functions we will capture the first error which
282 * we will rethrow to be handled by the top level error handler.
283 */
284function rethrowCaughtError() {
285 if (hasRethrowError) {
286 var error = rethrowError;
287 hasRethrowError = false;
288 rethrowError = null;
289 throw error;
290 }
291}
292
293function hasCaughtError() {
294 return hasError;
295}
296
297function clearCaughtError() {
298 if (hasError) {
299 var error = caughtError;
300 hasError = false;
301 caughtError = null;
302 return error;
303 } else {
304 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
305 }
306}
307
308/**
309 * Injectable ordering of event plugins.
310 */
311var eventPluginOrder = null;
312
313/**
314 * Injectable mapping from names to event plugin modules.
315 */
316var namesToPlugins = {};
317
318/**
319 * Recomputes the plugin list using the injected plugins and plugin ordering.
320 *
321 * @private
322 */
323function recomputePluginOrdering() {
324 if (!eventPluginOrder) {
325 // Wait until an `eventPluginOrder` is injected.
326 return;
327 }
328 for (var pluginName in namesToPlugins) {
329 var pluginModule = namesToPlugins[pluginName];
330 var pluginIndex = eventPluginOrder.indexOf(pluginName);
331 !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
332 if (plugins[pluginIndex]) {
333 continue;
334 }
335 !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
336 plugins[pluginIndex] = pluginModule;
337 var publishedEvents = pluginModule.eventTypes;
338 for (var eventName in publishedEvents) {
339 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
340 }
341 }
342}
343
344/**
345 * Publishes an event so that it can be dispatched by the supplied plugin.
346 *
347 * @param {object} dispatchConfig Dispatch configuration for the event.
348 * @param {object} PluginModule Plugin publishing the event.
349 * @return {boolean} True if the event was successfully published.
350 * @private
351 */
352function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
353 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
354 eventNameDispatchConfigs[eventName] = dispatchConfig;
355
356 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
357 if (phasedRegistrationNames) {
358 for (var phaseName in phasedRegistrationNames) {
359 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
360 var phasedRegistrationName = phasedRegistrationNames[phaseName];
361 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
362 }
363 }
364 return true;
365 } else if (dispatchConfig.registrationName) {
366 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
367 return true;
368 }
369 return false;
370}
371
372/**
373 * Publishes a registration name that is used to identify dispatched events.
374 *
375 * @param {string} registrationName Registration name to add.
376 * @param {object} PluginModule Plugin publishing the event.
377 * @private
378 */
379function publishRegistrationName(registrationName, pluginModule, eventName) {
380 !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
381 registrationNameModules[registrationName] = pluginModule;
382 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
383
384 {
385 var lowerCasedName = registrationName.toLowerCase();
386 possibleRegistrationNames[lowerCasedName] = registrationName;
387
388 if (registrationName === 'onDoubleClick') {
389 possibleRegistrationNames.ondblclick = registrationName;
390 }
391 }
392}
393
394/**
395 * Registers plugins so that they can extract and dispatch events.
396 *
397 * @see {EventPluginHub}
398 */
399
400/**
401 * Ordered list of injected plugins.
402 */
403var plugins = [];
404
405/**
406 * Mapping from event name to dispatch config
407 */
408var eventNameDispatchConfigs = {};
409
410/**
411 * Mapping from registration name to plugin module
412 */
413var registrationNameModules = {};
414
415/**
416 * Mapping from registration name to event name
417 */
418var registrationNameDependencies = {};
419
420/**
421 * Mapping from lowercase registration names to the properly cased version,
422 * used to warn in the case of missing event handlers. Available
423 * only in true.
424 * @type {Object}
425 */
426var possibleRegistrationNames = {};
427// Trust the developer to only use possibleRegistrationNames in true
428
429/**
430 * Injects an ordering of plugins (by plugin name). This allows the ordering
431 * to be decoupled from injection of the actual plugins so that ordering is
432 * always deterministic regardless of packaging, on-the-fly injection, etc.
433 *
434 * @param {array} InjectedEventPluginOrder
435 * @internal
436 * @see {EventPluginHub.injection.injectEventPluginOrder}
437 */
438function injectEventPluginOrder(injectedEventPluginOrder) {
439 !!eventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0;
440 // Clone the ordering so it cannot be dynamically mutated.
441 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
442 recomputePluginOrdering();
443}
444
445/**
446 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
447 * in the ordering injected by `injectEventPluginOrder`.
448 *
449 * Plugins can be injected as part of page initialization or on-the-fly.
450 *
451 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
452 * @internal
453 * @see {EventPluginHub.injection.injectEventPluginsByName}
454 */
455function injectEventPluginsByName(injectedNamesToPlugins) {
456 var isOrderingDirty = false;
457 for (var pluginName in injectedNamesToPlugins) {
458 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
459 continue;
460 }
461 var pluginModule = injectedNamesToPlugins[pluginName];
462 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
463 !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
464 namesToPlugins[pluginName] = pluginModule;
465 isOrderingDirty = true;
466 }
467 }
468 if (isOrderingDirty) {
469 recomputePluginOrdering();
470 }
471}
472
473/**
474 * Similar to invariant but only logs a warning if the condition is not met.
475 * This can be used to log issues in development environments in critical
476 * paths. Removing the logging code for production environments will keep the
477 * same logic and follow the same code paths.
478 */
479
480var warningWithoutStack = function () {};
481
482{
483 warningWithoutStack = function (condition, format) {
484 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
485 args[_key - 2] = arguments[_key];
486 }
487
488 if (format === undefined) {
489 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
490 }
491 if (args.length > 8) {
492 // Check before the condition to catch violations early.
493 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
494 }
495 if (condition) {
496 return;
497 }
498 if (typeof console !== 'undefined') {
499 var argsWithFormat = args.map(function (item) {
500 return '' + item;
501 });
502 argsWithFormat.unshift('Warning: ' + format);
503
504 // We intentionally don't use spread (or .apply) directly because it
505 // breaks IE9: https://github.com/facebook/react/issues/13610
506 Function.prototype.apply.call(console.error, console, argsWithFormat);
507 }
508 try {
509 // --- Welcome to debugging React ---
510 // This error was thrown as a convenience so that you can use this stack
511 // to find the callsite that caused this warning to fire.
512 var argIndex = 0;
513 var message = 'Warning: ' + format.replace(/%s/g, function () {
514 return args[argIndex++];
515 });
516 throw new Error(message);
517 } catch (x) {}
518 };
519}
520
521var warningWithoutStack$1 = warningWithoutStack;
522
523var getFiberCurrentPropsFromNode = null;
524var getInstanceFromNode = null;
525var getNodeFromInstance = null;
526
527function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
528 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
529 getInstanceFromNode = getInstanceFromNodeImpl;
530 getNodeFromInstance = getNodeFromInstanceImpl;
531 {
532 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
533 }
534}
535
536var validateEventDispatches = void 0;
537{
538 validateEventDispatches = function (event) {
539 var dispatchListeners = event._dispatchListeners;
540 var dispatchInstances = event._dispatchInstances;
541
542 var listenersIsArr = Array.isArray(dispatchListeners);
543 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
544
545 var instancesIsArr = Array.isArray(dispatchInstances);
546 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
547
548 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
549 };
550}
551
552/**
553 * Dispatch the event to the listener.
554 * @param {SyntheticEvent} event SyntheticEvent to handle
555 * @param {function} listener Application-level callback
556 * @param {*} inst Internal component instance
557 */
558function executeDispatch(event, listener, inst) {
559 var type = event.type || 'unknown-event';
560 event.currentTarget = getNodeFromInstance(inst);
561 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
562 event.currentTarget = null;
563}
564
565/**
566 * Standard/simple iteration through an event's collected dispatches.
567 */
568function executeDispatchesInOrder(event) {
569 var dispatchListeners = event._dispatchListeners;
570 var dispatchInstances = event._dispatchInstances;
571 {
572 validateEventDispatches(event);
573 }
574 if (Array.isArray(dispatchListeners)) {
575 for (var i = 0; i < dispatchListeners.length; i++) {
576 if (event.isPropagationStopped()) {
577 break;
578 }
579 // Listeners and Instances are two parallel arrays that are always in sync.
580 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
581 }
582 } else if (dispatchListeners) {
583 executeDispatch(event, dispatchListeners, dispatchInstances);
584 }
585 event._dispatchListeners = null;
586 event._dispatchInstances = null;
587}
588
589/**
590 * @see executeDispatchesInOrderStopAtTrueImpl
591 */
592
593
594/**
595 * Execution of a "direct" dispatch - there must be at most one dispatch
596 * accumulated on the event or it is considered an error. It doesn't really make
597 * sense for an event with multiple dispatches (bubbled) to keep track of the
598 * return values at each dispatch execution, but it does tend to make sense when
599 * dealing with "direct" dispatches.
600 *
601 * @return {*} The return value of executing the single dispatch.
602 */
603
604
605/**
606 * @param {SyntheticEvent} event
607 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
608 */
609
610/**
611 * Accumulates items that must not be null or undefined into the first one. This
612 * is used to conserve memory by avoiding array allocations, and thus sacrifices
613 * API cleanness. Since `current` can be null before being passed in and not
614 * null after this function, make sure to assign it back to `current`:
615 *
616 * `a = accumulateInto(a, b);`
617 *
618 * This API should be sparingly used. Try `accumulate` for something cleaner.
619 *
620 * @return {*|array<*>} An accumulation of items.
621 */
622
623function accumulateInto(current, next) {
624 !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
625
626 if (current == null) {
627 return next;
628 }
629
630 // Both are not empty. Warning: Never call x.concat(y) when you are not
631 // certain that x is an Array (x could be a string with concat method).
632 if (Array.isArray(current)) {
633 if (Array.isArray(next)) {
634 current.push.apply(current, next);
635 return current;
636 }
637 current.push(next);
638 return current;
639 }
640
641 if (Array.isArray(next)) {
642 // A bit too dangerous to mutate `next`.
643 return [current].concat(next);
644 }
645
646 return [current, next];
647}
648
649/**
650 * @param {array} arr an "accumulation" of items which is either an Array or
651 * a single item. Useful when paired with the `accumulate` module. This is a
652 * simple utility that allows us to reason about a collection of items, but
653 * handling the case when there is exactly one item (and we do not need to
654 * allocate an array).
655 * @param {function} cb Callback invoked with each element or a collection.
656 * @param {?} [scope] Scope used as `this` in a callback.
657 */
658function forEachAccumulated(arr, cb, scope) {
659 if (Array.isArray(arr)) {
660 arr.forEach(cb, scope);
661 } else if (arr) {
662 cb.call(scope, arr);
663 }
664}
665
666/**
667 * Internal queue of events that have accumulated their dispatches and are
668 * waiting to have their dispatches executed.
669 */
670var eventQueue = null;
671
672/**
673 * Dispatches an event and releases it back into the pool, unless persistent.
674 *
675 * @param {?object} event Synthetic event to be dispatched.
676 * @private
677 */
678var executeDispatchesAndRelease = function (event) {
679 if (event) {
680 executeDispatchesInOrder(event);
681
682 if (!event.isPersistent()) {
683 event.constructor.release(event);
684 }
685 }
686};
687var executeDispatchesAndReleaseTopLevel = function (e) {
688 return executeDispatchesAndRelease(e);
689};
690
691function isInteractive(tag) {
692 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
693}
694
695function shouldPreventMouseEvent(name, type, props) {
696 switch (name) {
697 case 'onClick':
698 case 'onClickCapture':
699 case 'onDoubleClick':
700 case 'onDoubleClickCapture':
701 case 'onMouseDown':
702 case 'onMouseDownCapture':
703 case 'onMouseMove':
704 case 'onMouseMoveCapture':
705 case 'onMouseUp':
706 case 'onMouseUpCapture':
707 return !!(props.disabled && isInteractive(type));
708 default:
709 return false;
710 }
711}
712
713/**
714 * This is a unified interface for event plugins to be installed and configured.
715 *
716 * Event plugins can implement the following properties:
717 *
718 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
719 * Required. When a top-level event is fired, this method is expected to
720 * extract synthetic events that will in turn be queued and dispatched.
721 *
722 * `eventTypes` {object}
723 * Optional, plugins that fire events must publish a mapping of registration
724 * names that are used to register listeners. Values of this mapping must
725 * be objects that contain `registrationName` or `phasedRegistrationNames`.
726 *
727 * `executeDispatch` {function(object, function, string)}
728 * Optional, allows plugins to override how an event gets dispatched. By
729 * default, the listener is simply invoked.
730 *
731 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
732 *
733 * @public
734 */
735
736/**
737 * Methods for injecting dependencies.
738 */
739var injection = {
740 /**
741 * @param {array} InjectedEventPluginOrder
742 * @public
743 */
744 injectEventPluginOrder: injectEventPluginOrder,
745
746 /**
747 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
748 */
749 injectEventPluginsByName: injectEventPluginsByName
750};
751
752/**
753 * @param {object} inst The instance, which is the source of events.
754 * @param {string} registrationName Name of listener (e.g. `onClick`).
755 * @return {?function} The stored callback.
756 */
757function getListener(inst, registrationName) {
758 var listener = void 0;
759
760 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
761 // live here; needs to be moved to a better place soon
762 var stateNode = inst.stateNode;
763 if (!stateNode) {
764 // Work in progress (ex: onload events in incremental mode).
765 return null;
766 }
767 var props = getFiberCurrentPropsFromNode(stateNode);
768 if (!props) {
769 // Work in progress.
770 return null;
771 }
772 listener = props[registrationName];
773 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
774 return null;
775 }
776 !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;
777 return listener;
778}
779
780/**
781 * Allows registered plugins an opportunity to extract events from top-level
782 * native browser events.
783 *
784 * @return {*} An accumulation of synthetic events.
785 * @internal
786 */
787function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
788 var events = null;
789 for (var i = 0; i < plugins.length; i++) {
790 // Not every plugin in the ordering may be loaded at runtime.
791 var possiblePlugin = plugins[i];
792 if (possiblePlugin) {
793 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
794 if (extractedEvents) {
795 events = accumulateInto(events, extractedEvents);
796 }
797 }
798 }
799 return events;
800}
801
802function runEventsInBatch(events) {
803 if (events !== null) {
804 eventQueue = accumulateInto(eventQueue, events);
805 }
806
807 // Set `eventQueue` to null before processing it so that we can tell if more
808 // events get enqueued while processing.
809 var processingEventQueue = eventQueue;
810 eventQueue = null;
811
812 if (!processingEventQueue) {
813 return;
814 }
815
816 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
817 !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
818 // This would be a good time to rethrow if any of the event handlers threw.
819 rethrowCaughtError();
820}
821
822function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
823 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
824 runEventsInBatch(events);
825}
826
827var FunctionComponent = 0;
828var ClassComponent = 1;
829var IndeterminateComponent = 2; // Before we know whether it is function or class
830var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
831var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
832var HostComponent = 5;
833var HostText = 6;
834var Fragment = 7;
835var Mode = 8;
836var ContextConsumer = 9;
837var ContextProvider = 10;
838var ForwardRef = 11;
839var Profiler = 12;
840var SuspenseComponent = 13;
841var MemoComponent = 14;
842var SimpleMemoComponent = 15;
843var LazyComponent = 16;
844var IncompleteClassComponent = 17;
845var DehydratedSuspenseComponent = 18;
846
847var randomKey = Math.random().toString(36).slice(2);
848var internalInstanceKey = '__reactInternalInstance$' + randomKey;
849var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
850
851function precacheFiberNode(hostInst, node) {
852 node[internalInstanceKey] = hostInst;
853}
854
855/**
856 * Given a DOM node, return the closest ReactDOMComponent or
857 * ReactDOMTextComponent instance ancestor.
858 */
859function getClosestInstanceFromNode(node) {
860 if (node[internalInstanceKey]) {
861 return node[internalInstanceKey];
862 }
863
864 while (!node[internalInstanceKey]) {
865 if (node.parentNode) {
866 node = node.parentNode;
867 } else {
868 // Top of the tree. This node must not be part of a React tree (or is
869 // unmounted, potentially).
870 return null;
871 }
872 }
873
874 var inst = node[internalInstanceKey];
875 if (inst.tag === HostComponent || inst.tag === HostText) {
876 // In Fiber, this will always be the deepest root.
877 return inst;
878 }
879
880 return null;
881}
882
883/**
884 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
885 * instance, or null if the node was not rendered by this React.
886 */
887function getInstanceFromNode$1(node) {
888 var inst = node[internalInstanceKey];
889 if (inst) {
890 if (inst.tag === HostComponent || inst.tag === HostText) {
891 return inst;
892 } else {
893 return null;
894 }
895 }
896 return null;
897}
898
899/**
900 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
901 * DOM node.
902 */
903function getNodeFromInstance$1(inst) {
904 if (inst.tag === HostComponent || inst.tag === HostText) {
905 // In Fiber this, is just the state node right now. We assume it will be
906 // a host component or host text.
907 return inst.stateNode;
908 }
909
910 // Without this first invariant, passing a non-DOM-component triggers the next
911 // invariant for a missing parent, which is super confusing.
912 invariant(false, 'getNodeFromInstance: Invalid argument.');
913}
914
915function getFiberCurrentPropsFromNode$1(node) {
916 return node[internalEventHandlersKey] || null;
917}
918
919function updateFiberProps(node, props) {
920 node[internalEventHandlersKey] = props;
921}
922
923function getParent(inst) {
924 do {
925 inst = inst.return;
926 // TODO: If this is a HostRoot we might want to bail out.
927 // That is depending on if we want nested subtrees (layers) to bubble
928 // events to their parent. We could also go through parentNode on the
929 // host node but that wouldn't work for React Native and doesn't let us
930 // do the portal feature.
931 } while (inst && inst.tag !== HostComponent);
932 if (inst) {
933 return inst;
934 }
935 return null;
936}
937
938/**
939 * Return the lowest common ancestor of A and B, or null if they are in
940 * different trees.
941 */
942function getLowestCommonAncestor(instA, instB) {
943 var depthA = 0;
944 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
945 depthA++;
946 }
947 var depthB = 0;
948 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
949 depthB++;
950 }
951
952 // If A is deeper, crawl up.
953 while (depthA - depthB > 0) {
954 instA = getParent(instA);
955 depthA--;
956 }
957
958 // If B is deeper, crawl up.
959 while (depthB - depthA > 0) {
960 instB = getParent(instB);
961 depthB--;
962 }
963
964 // Walk in lockstep until we find a match.
965 var depth = depthA;
966 while (depth--) {
967 if (instA === instB || instA === instB.alternate) {
968 return instA;
969 }
970 instA = getParent(instA);
971 instB = getParent(instB);
972 }
973 return null;
974}
975
976/**
977 * Return if A is an ancestor of B.
978 */
979
980
981/**
982 * Return the parent instance of the passed-in instance.
983 */
984
985
986/**
987 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
988 */
989function traverseTwoPhase(inst, fn, arg) {
990 var path = [];
991 while (inst) {
992 path.push(inst);
993 inst = getParent(inst);
994 }
995 var i = void 0;
996 for (i = path.length; i-- > 0;) {
997 fn(path[i], 'captured', arg);
998 }
999 for (i = 0; i < path.length; i++) {
1000 fn(path[i], 'bubbled', arg);
1001 }
1002}
1003
1004/**
1005 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
1006 * should would receive a `mouseEnter` or `mouseLeave` event.
1007 *
1008 * Does not invoke the callback on the nearest common ancestor because nothing
1009 * "entered" or "left" that element.
1010 */
1011function traverseEnterLeave(from, to, fn, argFrom, argTo) {
1012 var common = from && to ? getLowestCommonAncestor(from, to) : null;
1013 var pathFrom = [];
1014 while (true) {
1015 if (!from) {
1016 break;
1017 }
1018 if (from === common) {
1019 break;
1020 }
1021 var alternate = from.alternate;
1022 if (alternate !== null && alternate === common) {
1023 break;
1024 }
1025 pathFrom.push(from);
1026 from = getParent(from);
1027 }
1028 var pathTo = [];
1029 while (true) {
1030 if (!to) {
1031 break;
1032 }
1033 if (to === common) {
1034 break;
1035 }
1036 var _alternate = to.alternate;
1037 if (_alternate !== null && _alternate === common) {
1038 break;
1039 }
1040 pathTo.push(to);
1041 to = getParent(to);
1042 }
1043 for (var i = 0; i < pathFrom.length; i++) {
1044 fn(pathFrom[i], 'bubbled', argFrom);
1045 }
1046 for (var _i = pathTo.length; _i-- > 0;) {
1047 fn(pathTo[_i], 'captured', argTo);
1048 }
1049}
1050
1051/**
1052 * Some event types have a notion of different registration names for different
1053 * "phases" of propagation. This finds listeners by a given phase.
1054 */
1055function listenerAtPhase(inst, event, propagationPhase) {
1056 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
1057 return getListener(inst, registrationName);
1058}
1059
1060/**
1061 * A small set of propagation patterns, each of which will accept a small amount
1062 * of information, and generate a set of "dispatch ready event objects" - which
1063 * are sets of events that have already been annotated with a set of dispatched
1064 * listener functions/ids. The API is designed this way to discourage these
1065 * propagation strategies from actually executing the dispatches, since we
1066 * always want to collect the entire set of dispatches before executing even a
1067 * single one.
1068 */
1069
1070/**
1071 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
1072 * here, allows us to not have to bind or create functions for each event.
1073 * Mutating the event's members allows us to not have to create a wrapping
1074 * "dispatch" object that pairs the event with the listener.
1075 */
1076function accumulateDirectionalDispatches(inst, phase, event) {
1077 {
1078 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
1079 }
1080 var listener = listenerAtPhase(inst, event, phase);
1081 if (listener) {
1082 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1083 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1084 }
1085}
1086
1087/**
1088 * Collect dispatches (must be entirely collected before dispatching - see unit
1089 * tests). Lazily allocate the array to conserve memory. We must loop through
1090 * each event and perform the traversal for each one. We cannot perform a
1091 * single traversal for the entire collection of events because each event may
1092 * have a different target.
1093 */
1094function accumulateTwoPhaseDispatchesSingle(event) {
1095 if (event && event.dispatchConfig.phasedRegistrationNames) {
1096 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
1097 }
1098}
1099
1100/**
1101 * Accumulates without regard to direction, does not look for phased
1102 * registration names. Same as `accumulateDirectDispatchesSingle` but without
1103 * requiring that the `dispatchMarker` be the same as the dispatched ID.
1104 */
1105function accumulateDispatches(inst, ignoredDirection, event) {
1106 if (inst && event && event.dispatchConfig.registrationName) {
1107 var registrationName = event.dispatchConfig.registrationName;
1108 var listener = getListener(inst, registrationName);
1109 if (listener) {
1110 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
1111 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
1112 }
1113 }
1114}
1115
1116/**
1117 * Accumulates dispatches on an `SyntheticEvent`, but only for the
1118 * `dispatchMarker`.
1119 * @param {SyntheticEvent} event
1120 */
1121function accumulateDirectDispatchesSingle(event) {
1122 if (event && event.dispatchConfig.registrationName) {
1123 accumulateDispatches(event._targetInst, null, event);
1124 }
1125}
1126
1127function accumulateTwoPhaseDispatches(events) {
1128 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
1129}
1130
1131
1132
1133function accumulateEnterLeaveDispatches(leave, enter, from, to) {
1134 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
1135}
1136
1137function accumulateDirectDispatches(events) {
1138 forEachAccumulated(events, accumulateDirectDispatchesSingle);
1139}
1140
1141var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
1142
1143// Do not uses the below two methods directly!
1144// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
1145// (It is the only module that is allowed to access these methods.)
1146
1147function unsafeCastStringToDOMTopLevelType(topLevelType) {
1148 return topLevelType;
1149}
1150
1151function unsafeCastDOMTopLevelTypeToString(topLevelType) {
1152 return topLevelType;
1153}
1154
1155/**
1156 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
1157 *
1158 * @param {string} styleProp
1159 * @param {string} eventName
1160 * @returns {object}
1161 */
1162function makePrefixMap(styleProp, eventName) {
1163 var prefixes = {};
1164
1165 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
1166 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
1167 prefixes['Moz' + styleProp] = 'moz' + eventName;
1168
1169 return prefixes;
1170}
1171
1172/**
1173 * A list of event names to a configurable list of vendor prefixes.
1174 */
1175var vendorPrefixes = {
1176 animationend: makePrefixMap('Animation', 'AnimationEnd'),
1177 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
1178 animationstart: makePrefixMap('Animation', 'AnimationStart'),
1179 transitionend: makePrefixMap('Transition', 'TransitionEnd')
1180};
1181
1182/**
1183 * Event names that have already been detected and prefixed (if applicable).
1184 */
1185var prefixedEventNames = {};
1186
1187/**
1188 * Element to check for prefixes on.
1189 */
1190var style = {};
1191
1192/**
1193 * Bootstrap if a DOM exists.
1194 */
1195if (canUseDOM) {
1196 style = document.createElement('div').style;
1197
1198 // On some platforms, in particular some releases of Android 4.x,
1199 // the un-prefixed "animation" and "transition" properties are defined on the
1200 // style object but the events that fire will still be prefixed, so we need
1201 // to check if the un-prefixed events are usable, and if not remove them from the map.
1202 if (!('AnimationEvent' in window)) {
1203 delete vendorPrefixes.animationend.animation;
1204 delete vendorPrefixes.animationiteration.animation;
1205 delete vendorPrefixes.animationstart.animation;
1206 }
1207
1208 // Same as above
1209 if (!('TransitionEvent' in window)) {
1210 delete vendorPrefixes.transitionend.transition;
1211 }
1212}
1213
1214/**
1215 * Attempts to determine the correct vendor prefixed event name.
1216 *
1217 * @param {string} eventName
1218 * @returns {string}
1219 */
1220function getVendorPrefixedEventName(eventName) {
1221 if (prefixedEventNames[eventName]) {
1222 return prefixedEventNames[eventName];
1223 } else if (!vendorPrefixes[eventName]) {
1224 return eventName;
1225 }
1226
1227 var prefixMap = vendorPrefixes[eventName];
1228
1229 for (var styleProp in prefixMap) {
1230 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
1231 return prefixedEventNames[eventName] = prefixMap[styleProp];
1232 }
1233 }
1234
1235 return eventName;
1236}
1237
1238/**
1239 * To identify top level events in ReactDOM, we use constants defined by this
1240 * module. This is the only module that uses the unsafe* methods to express
1241 * that the constants actually correspond to the browser event names. This lets
1242 * us save some bundle size by avoiding a top level type -> event name map.
1243 * The rest of ReactDOM code should import top level types from this file.
1244 */
1245var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
1246var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
1247var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
1248var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
1249var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
1250var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
1251var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
1252var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
1253var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
1254var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
1255var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
1256var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
1257var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
1258var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
1259var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
1260var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
1261var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
1262var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
1263var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
1264var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
1265var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
1266var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
1267var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
1268var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
1269var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
1270var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
1271var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
1272var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
1273var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
1274var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
1275var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
1276var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
1277var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
1278var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
1279var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
1280var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
1281var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
1282var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
1283var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
1284var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
1285var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
1286var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
1287var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
1288var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
1289var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
1290var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
1291var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
1292var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
1293var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
1294var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
1295var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
1296var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
1297var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
1298var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
1299var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
1300
1301
1302var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
1303var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
1304var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
1305var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
1306var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
1307var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
1308var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
1309var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
1310var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
1311var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
1312var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
1313var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
1314var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
1315var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
1316var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
1317var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
1318var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
1319var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
1320var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
1321var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
1322var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
1323var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
1324var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
1325var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
1326var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');
1327
1328// List of events that need to be individually attached to media elements.
1329// Note that events in this list will *not* be listened to at the top level
1330// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
1331var 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];
1332
1333function getRawEventName(topLevelType) {
1334 return unsafeCastDOMTopLevelTypeToString(topLevelType);
1335}
1336
1337/**
1338 * These variables store information about text content of a target node,
1339 * allowing comparison of content before and after a given event.
1340 *
1341 * Identify the node where selection currently begins, then observe
1342 * both its text content and its current position in the DOM. Since the
1343 * browser may natively replace the target node during composition, we can
1344 * use its position to find its replacement.
1345 *
1346 *
1347 */
1348
1349var root = null;
1350var startText = null;
1351var fallbackText = null;
1352
1353function initialize(nativeEventTarget) {
1354 root = nativeEventTarget;
1355 startText = getText();
1356 return true;
1357}
1358
1359function reset() {
1360 root = null;
1361 startText = null;
1362 fallbackText = null;
1363}
1364
1365function getData() {
1366 if (fallbackText) {
1367 return fallbackText;
1368 }
1369
1370 var start = void 0;
1371 var startValue = startText;
1372 var startLength = startValue.length;
1373 var end = void 0;
1374 var endValue = getText();
1375 var endLength = endValue.length;
1376
1377 for (start = 0; start < startLength; start++) {
1378 if (startValue[start] !== endValue[start]) {
1379 break;
1380 }
1381 }
1382
1383 var minEnd = startLength - start;
1384 for (end = 1; end <= minEnd; end++) {
1385 if (startValue[startLength - end] !== endValue[endLength - end]) {
1386 break;
1387 }
1388 }
1389
1390 var sliceTail = end > 1 ? 1 - end : undefined;
1391 fallbackText = endValue.slice(start, sliceTail);
1392 return fallbackText;
1393}
1394
1395function getText() {
1396 if ('value' in root) {
1397 return root.value;
1398 }
1399 return root.textContent;
1400}
1401
1402/* eslint valid-typeof: 0 */
1403
1404var EVENT_POOL_SIZE = 10;
1405
1406/**
1407 * @interface Event
1408 * @see http://www.w3.org/TR/DOM-Level-3-Events/
1409 */
1410var EventInterface = {
1411 type: null,
1412 target: null,
1413 // currentTarget is set when dispatching; no use in copying it here
1414 currentTarget: function () {
1415 return null;
1416 },
1417 eventPhase: null,
1418 bubbles: null,
1419 cancelable: null,
1420 timeStamp: function (event) {
1421 return event.timeStamp || Date.now();
1422 },
1423 defaultPrevented: null,
1424 isTrusted: null
1425};
1426
1427function functionThatReturnsTrue() {
1428 return true;
1429}
1430
1431function functionThatReturnsFalse() {
1432 return false;
1433}
1434
1435/**
1436 * Synthetic events are dispatched by event plugins, typically in response to a
1437 * top-level event delegation handler.
1438 *
1439 * These systems should generally use pooling to reduce the frequency of garbage
1440 * collection. The system should check `isPersistent` to determine whether the
1441 * event should be released into the pool after being dispatched. Users that
1442 * need a persisted event should invoke `persist`.
1443 *
1444 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
1445 * normalizing browser quirks. Subclasses do not necessarily have to implement a
1446 * DOM interface; custom application-specific events can also subclass this.
1447 *
1448 * @param {object} dispatchConfig Configuration used to dispatch this event.
1449 * @param {*} targetInst Marker identifying the event target.
1450 * @param {object} nativeEvent Native browser event.
1451 * @param {DOMEventTarget} nativeEventTarget Target node.
1452 */
1453function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
1454 {
1455 // these have a getter/setter for warnings
1456 delete this.nativeEvent;
1457 delete this.preventDefault;
1458 delete this.stopPropagation;
1459 delete this.isDefaultPrevented;
1460 delete this.isPropagationStopped;
1461 }
1462
1463 this.dispatchConfig = dispatchConfig;
1464 this._targetInst = targetInst;
1465 this.nativeEvent = nativeEvent;
1466
1467 var Interface = this.constructor.Interface;
1468 for (var propName in Interface) {
1469 if (!Interface.hasOwnProperty(propName)) {
1470 continue;
1471 }
1472 {
1473 delete this[propName]; // this has a getter/setter for warnings
1474 }
1475 var normalize = Interface[propName];
1476 if (normalize) {
1477 this[propName] = normalize(nativeEvent);
1478 } else {
1479 if (propName === 'target') {
1480 this.target = nativeEventTarget;
1481 } else {
1482 this[propName] = nativeEvent[propName];
1483 }
1484 }
1485 }
1486
1487 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
1488 if (defaultPrevented) {
1489 this.isDefaultPrevented = functionThatReturnsTrue;
1490 } else {
1491 this.isDefaultPrevented = functionThatReturnsFalse;
1492 }
1493 this.isPropagationStopped = functionThatReturnsFalse;
1494 return this;
1495}
1496
1497_assign(SyntheticEvent.prototype, {
1498 preventDefault: function () {
1499 this.defaultPrevented = true;
1500 var event = this.nativeEvent;
1501 if (!event) {
1502 return;
1503 }
1504
1505 if (event.preventDefault) {
1506 event.preventDefault();
1507 } else if (typeof event.returnValue !== 'unknown') {
1508 event.returnValue = false;
1509 }
1510 this.isDefaultPrevented = functionThatReturnsTrue;
1511 },
1512
1513 stopPropagation: function () {
1514 var event = this.nativeEvent;
1515 if (!event) {
1516 return;
1517 }
1518
1519 if (event.stopPropagation) {
1520 event.stopPropagation();
1521 } else if (typeof event.cancelBubble !== 'unknown') {
1522 // The ChangeEventPlugin registers a "propertychange" event for
1523 // IE. This event does not support bubbling or cancelling, and
1524 // any references to cancelBubble throw "Member not found". A
1525 // typeof check of "unknown" circumvents this issue (and is also
1526 // IE specific).
1527 event.cancelBubble = true;
1528 }
1529
1530 this.isPropagationStopped = functionThatReturnsTrue;
1531 },
1532
1533 /**
1534 * We release all dispatched `SyntheticEvent`s after each event loop, adding
1535 * them back into the pool. This allows a way to hold onto a reference that
1536 * won't be added back into the pool.
1537 */
1538 persist: function () {
1539 this.isPersistent = functionThatReturnsTrue;
1540 },
1541
1542 /**
1543 * Checks if this event should be released back into the pool.
1544 *
1545 * @return {boolean} True if this should not be released, false otherwise.
1546 */
1547 isPersistent: functionThatReturnsFalse,
1548
1549 /**
1550 * `PooledClass` looks for `destructor` on each instance it releases.
1551 */
1552 destructor: function () {
1553 var Interface = this.constructor.Interface;
1554 for (var propName in Interface) {
1555 {
1556 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
1557 }
1558 }
1559 this.dispatchConfig = null;
1560 this._targetInst = null;
1561 this.nativeEvent = null;
1562 this.isDefaultPrevented = functionThatReturnsFalse;
1563 this.isPropagationStopped = functionThatReturnsFalse;
1564 this._dispatchListeners = null;
1565 this._dispatchInstances = null;
1566 {
1567 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
1568 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
1569 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
1570 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
1571 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
1572 }
1573 }
1574});
1575
1576SyntheticEvent.Interface = EventInterface;
1577
1578/**
1579 * Helper to reduce boilerplate when creating subclasses.
1580 */
1581SyntheticEvent.extend = function (Interface) {
1582 var Super = this;
1583
1584 var E = function () {};
1585 E.prototype = Super.prototype;
1586 var prototype = new E();
1587
1588 function Class() {
1589 return Super.apply(this, arguments);
1590 }
1591 _assign(prototype, Class.prototype);
1592 Class.prototype = prototype;
1593 Class.prototype.constructor = Class;
1594
1595 Class.Interface = _assign({}, Super.Interface, Interface);
1596 Class.extend = Super.extend;
1597 addEventPoolingTo(Class);
1598
1599 return Class;
1600};
1601
1602addEventPoolingTo(SyntheticEvent);
1603
1604/**
1605 * Helper to nullify syntheticEvent instance properties when destructing
1606 *
1607 * @param {String} propName
1608 * @param {?object} getVal
1609 * @return {object} defineProperty object
1610 */
1611function getPooledWarningPropertyDefinition(propName, getVal) {
1612 var isFunction = typeof getVal === 'function';
1613 return {
1614 configurable: true,
1615 set: set,
1616 get: get
1617 };
1618
1619 function set(val) {
1620 var action = isFunction ? 'setting the method' : 'setting the property';
1621 warn(action, 'This is effectively a no-op');
1622 return val;
1623 }
1624
1625 function get() {
1626 var action = isFunction ? 'accessing the method' : 'accessing the property';
1627 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
1628 warn(action, result);
1629 return getVal;
1630 }
1631
1632 function warn(action, result) {
1633 var warningCondition = false;
1634 !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;
1635 }
1636}
1637
1638function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
1639 var EventConstructor = this;
1640 if (EventConstructor.eventPool.length) {
1641 var instance = EventConstructor.eventPool.pop();
1642 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
1643 return instance;
1644 }
1645 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
1646}
1647
1648function releasePooledEvent(event) {
1649 var EventConstructor = this;
1650 !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
1651 event.destructor();
1652 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
1653 EventConstructor.eventPool.push(event);
1654 }
1655}
1656
1657function addEventPoolingTo(EventConstructor) {
1658 EventConstructor.eventPool = [];
1659 EventConstructor.getPooled = getPooledEvent;
1660 EventConstructor.release = releasePooledEvent;
1661}
1662
1663/**
1664 * @interface Event
1665 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
1666 */
1667var SyntheticCompositionEvent = SyntheticEvent.extend({
1668 data: null
1669});
1670
1671/**
1672 * @interface Event
1673 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
1674 * /#events-inputevents
1675 */
1676var SyntheticInputEvent = SyntheticEvent.extend({
1677 data: null
1678});
1679
1680var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
1681var START_KEYCODE = 229;
1682
1683var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
1684
1685var documentMode = null;
1686if (canUseDOM && 'documentMode' in document) {
1687 documentMode = document.documentMode;
1688}
1689
1690// Webkit offers a very useful `textInput` event that can be used to
1691// directly represent `beforeInput`. The IE `textinput` event is not as
1692// useful, so we don't use it.
1693var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode;
1694
1695// In IE9+, we have access to composition events, but the data supplied
1696// by the native compositionend event may be incorrect. Japanese ideographic
1697// spaces, for instance (\u3000) are not recorded correctly.
1698var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
1699
1700var SPACEBAR_CODE = 32;
1701var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
1702
1703// Events and their corresponding property names.
1704var eventTypes = {
1705 beforeInput: {
1706 phasedRegistrationNames: {
1707 bubbled: 'onBeforeInput',
1708 captured: 'onBeforeInputCapture'
1709 },
1710 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
1711 },
1712 compositionEnd: {
1713 phasedRegistrationNames: {
1714 bubbled: 'onCompositionEnd',
1715 captured: 'onCompositionEndCapture'
1716 },
1717 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1718 },
1719 compositionStart: {
1720 phasedRegistrationNames: {
1721 bubbled: 'onCompositionStart',
1722 captured: 'onCompositionStartCapture'
1723 },
1724 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1725 },
1726 compositionUpdate: {
1727 phasedRegistrationNames: {
1728 bubbled: 'onCompositionUpdate',
1729 captured: 'onCompositionUpdateCapture'
1730 },
1731 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
1732 }
1733};
1734
1735// Track whether we've ever handled a keypress on the space key.
1736var hasSpaceKeypress = false;
1737
1738/**
1739 * Return whether a native keypress event is assumed to be a command.
1740 * This is required because Firefox fires `keypress` events for key commands
1741 * (cut, copy, select-all, etc.) even though no character is inserted.
1742 */
1743function isKeypressCommand(nativeEvent) {
1744 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
1745 // ctrlKey && altKey is equivalent to AltGr, and is not a command.
1746 !(nativeEvent.ctrlKey && nativeEvent.altKey);
1747}
1748
1749/**
1750 * Translate native top level events into event types.
1751 *
1752 * @param {string} topLevelType
1753 * @return {object}
1754 */
1755function getCompositionEventType(topLevelType) {
1756 switch (topLevelType) {
1757 case TOP_COMPOSITION_START:
1758 return eventTypes.compositionStart;
1759 case TOP_COMPOSITION_END:
1760 return eventTypes.compositionEnd;
1761 case TOP_COMPOSITION_UPDATE:
1762 return eventTypes.compositionUpdate;
1763 }
1764}
1765
1766/**
1767 * Does our fallback best-guess model think this event signifies that
1768 * composition has begun?
1769 *
1770 * @param {string} topLevelType
1771 * @param {object} nativeEvent
1772 * @return {boolean}
1773 */
1774function isFallbackCompositionStart(topLevelType, nativeEvent) {
1775 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
1776}
1777
1778/**
1779 * Does our fallback mode think that this event is the end of composition?
1780 *
1781 * @param {string} topLevelType
1782 * @param {object} nativeEvent
1783 * @return {boolean}
1784 */
1785function isFallbackCompositionEnd(topLevelType, nativeEvent) {
1786 switch (topLevelType) {
1787 case TOP_KEY_UP:
1788 // Command keys insert or clear IME input.
1789 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
1790 case TOP_KEY_DOWN:
1791 // Expect IME keyCode on each keydown. If we get any other
1792 // code we must have exited earlier.
1793 return nativeEvent.keyCode !== START_KEYCODE;
1794 case TOP_KEY_PRESS:
1795 case TOP_MOUSE_DOWN:
1796 case TOP_BLUR:
1797 // Events are not possible without cancelling IME.
1798 return true;
1799 default:
1800 return false;
1801 }
1802}
1803
1804/**
1805 * Google Input Tools provides composition data via a CustomEvent,
1806 * with the `data` property populated in the `detail` object. If this
1807 * is available on the event object, use it. If not, this is a plain
1808 * composition event and we have nothing special to extract.
1809 *
1810 * @param {object} nativeEvent
1811 * @return {?string}
1812 */
1813function getDataFromCustomEvent(nativeEvent) {
1814 var detail = nativeEvent.detail;
1815 if (typeof detail === 'object' && 'data' in detail) {
1816 return detail.data;
1817 }
1818 return null;
1819}
1820
1821/**
1822 * Check if a composition event was triggered by Korean IME.
1823 * Our fallback mode does not work well with IE's Korean IME,
1824 * so just use native composition events when Korean IME is used.
1825 * Although CompositionEvent.locale property is deprecated,
1826 * it is available in IE, where our fallback mode is enabled.
1827 *
1828 * @param {object} nativeEvent
1829 * @return {boolean}
1830 */
1831function isUsingKoreanIME(nativeEvent) {
1832 return nativeEvent.locale === 'ko';
1833}
1834
1835// Track the current IME composition status, if any.
1836var isComposing = false;
1837
1838/**
1839 * @return {?object} A SyntheticCompositionEvent.
1840 */
1841function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
1842 var eventType = void 0;
1843 var fallbackData = void 0;
1844
1845 if (canUseCompositionEvent) {
1846 eventType = getCompositionEventType(topLevelType);
1847 } else if (!isComposing) {
1848 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
1849 eventType = eventTypes.compositionStart;
1850 }
1851 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1852 eventType = eventTypes.compositionEnd;
1853 }
1854
1855 if (!eventType) {
1856 return null;
1857 }
1858
1859 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
1860 // The current composition is stored statically and must not be
1861 // overwritten while composition continues.
1862 if (!isComposing && eventType === eventTypes.compositionStart) {
1863 isComposing = initialize(nativeEventTarget);
1864 } else if (eventType === eventTypes.compositionEnd) {
1865 if (isComposing) {
1866 fallbackData = getData();
1867 }
1868 }
1869 }
1870
1871 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
1872
1873 if (fallbackData) {
1874 // Inject data generated from fallback path into the synthetic event.
1875 // This matches the property of native CompositionEventInterface.
1876 event.data = fallbackData;
1877 } else {
1878 var customData = getDataFromCustomEvent(nativeEvent);
1879 if (customData !== null) {
1880 event.data = customData;
1881 }
1882 }
1883
1884 accumulateTwoPhaseDispatches(event);
1885 return event;
1886}
1887
1888/**
1889 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
1890 * @param {object} nativeEvent Native browser event.
1891 * @return {?string} The string corresponding to this `beforeInput` event.
1892 */
1893function getNativeBeforeInputChars(topLevelType, nativeEvent) {
1894 switch (topLevelType) {
1895 case TOP_COMPOSITION_END:
1896 return getDataFromCustomEvent(nativeEvent);
1897 case TOP_KEY_PRESS:
1898 /**
1899 * If native `textInput` events are available, our goal is to make
1900 * use of them. However, there is a special case: the spacebar key.
1901 * In Webkit, preventing default on a spacebar `textInput` event
1902 * cancels character insertion, but it *also* causes the browser
1903 * to fall back to its default spacebar behavior of scrolling the
1904 * page.
1905 *
1906 * Tracking at:
1907 * https://code.google.com/p/chromium/issues/detail?id=355103
1908 *
1909 * To avoid this issue, use the keypress event as if no `textInput`
1910 * event is available.
1911 */
1912 var which = nativeEvent.which;
1913 if (which !== SPACEBAR_CODE) {
1914 return null;
1915 }
1916
1917 hasSpaceKeypress = true;
1918 return SPACEBAR_CHAR;
1919
1920 case TOP_TEXT_INPUT:
1921 // Record the characters to be added to the DOM.
1922 var chars = nativeEvent.data;
1923
1924 // If it's a spacebar character, assume that we have already handled
1925 // it at the keypress level and bail immediately. Android Chrome
1926 // doesn't give us keycodes, so we need to ignore it.
1927 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
1928 return null;
1929 }
1930
1931 return chars;
1932
1933 default:
1934 // For other native event types, do nothing.
1935 return null;
1936 }
1937}
1938
1939/**
1940 * For browsers that do not provide the `textInput` event, extract the
1941 * appropriate string to use for SyntheticInputEvent.
1942 *
1943 * @param {number} topLevelType Number from `TopLevelEventTypes`.
1944 * @param {object} nativeEvent Native browser event.
1945 * @return {?string} The fallback string for this `beforeInput` event.
1946 */
1947function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
1948 // If we are currently composing (IME) and using a fallback to do so,
1949 // try to extract the composed characters from the fallback object.
1950 // If composition event is available, we extract a string only at
1951 // compositionevent, otherwise extract it at fallback events.
1952 if (isComposing) {
1953 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
1954 var chars = getData();
1955 reset();
1956 isComposing = false;
1957 return chars;
1958 }
1959 return null;
1960 }
1961
1962 switch (topLevelType) {
1963 case TOP_PASTE:
1964 // If a paste event occurs after a keypress, throw out the input
1965 // chars. Paste events should not lead to BeforeInput events.
1966 return null;
1967 case TOP_KEY_PRESS:
1968 /**
1969 * As of v27, Firefox may fire keypress events even when no character
1970 * will be inserted. A few possibilities:
1971 *
1972 * - `which` is `0`. Arrow keys, Esc key, etc.
1973 *
1974 * - `which` is the pressed key code, but no char is available.
1975 * Ex: 'AltGr + d` in Polish. There is no modified character for
1976 * this key combination and no character is inserted into the
1977 * document, but FF fires the keypress for char code `100` anyway.
1978 * No `input` event will occur.
1979 *
1980 * - `which` is the pressed key code, but a command combination is
1981 * being used. Ex: `Cmd+C`. No character is inserted, and no
1982 * `input` event will occur.
1983 */
1984 if (!isKeypressCommand(nativeEvent)) {
1985 // IE fires the `keypress` event when a user types an emoji via
1986 // Touch keyboard of Windows. In such a case, the `char` property
1987 // holds an emoji character like `\uD83D\uDE0A`. Because its length
1988 // is 2, the property `which` does not represent an emoji correctly.
1989 // In such a case, we directly return the `char` property instead of
1990 // using `which`.
1991 if (nativeEvent.char && nativeEvent.char.length > 1) {
1992 return nativeEvent.char;
1993 } else if (nativeEvent.which) {
1994 return String.fromCharCode(nativeEvent.which);
1995 }
1996 }
1997 return null;
1998 case TOP_COMPOSITION_END:
1999 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
2000 default:
2001 return null;
2002 }
2003}
2004
2005/**
2006 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
2007 * `textInput` or fallback behavior.
2008 *
2009 * @return {?object} A SyntheticInputEvent.
2010 */
2011function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2012 var chars = void 0;
2013
2014 if (canUseTextInputEvent) {
2015 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
2016 } else {
2017 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
2018 }
2019
2020 // If no characters are being inserted, no BeforeInput event should
2021 // be fired.
2022 if (!chars) {
2023 return null;
2024 }
2025
2026 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
2027
2028 event.data = chars;
2029 accumulateTwoPhaseDispatches(event);
2030 return event;
2031}
2032
2033/**
2034 * Create an `onBeforeInput` event to match
2035 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
2036 *
2037 * This event plugin is based on the native `textInput` event
2038 * available in Chrome, Safari, Opera, and IE. This event fires after
2039 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
2040 *
2041 * `beforeInput` is spec'd but not implemented in any browsers, and
2042 * the `input` event does not provide any useful information about what has
2043 * actually been added, contrary to the spec. Thus, `textInput` is the best
2044 * available event to identify the characters that have actually been inserted
2045 * into the target node.
2046 *
2047 * This plugin is also responsible for emitting `composition` events, thus
2048 * allowing us to share composition fallback code for both `beforeInput` and
2049 * `composition` event types.
2050 */
2051var BeforeInputEventPlugin = {
2052 eventTypes: eventTypes,
2053
2054 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
2055 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2056
2057 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
2058
2059 if (composition === null) {
2060 return beforeInput;
2061 }
2062
2063 if (beforeInput === null) {
2064 return composition;
2065 }
2066
2067 return [composition, beforeInput];
2068 }
2069};
2070
2071// Use to restore controlled state after a change event has fired.
2072
2073var restoreImpl = null;
2074var restoreTarget = null;
2075var restoreQueue = null;
2076
2077function restoreStateOfTarget(target) {
2078 // We perform this translation at the end of the event loop so that we
2079 // always receive the correct fiber here
2080 var internalInstance = getInstanceFromNode(target);
2081 if (!internalInstance) {
2082 // Unmounted
2083 return;
2084 }
2085 !(typeof restoreImpl === 'function') ? invariant(false, '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.') : void 0;
2086 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
2087 restoreImpl(internalInstance.stateNode, internalInstance.type, props);
2088}
2089
2090function setRestoreImplementation(impl) {
2091 restoreImpl = impl;
2092}
2093
2094function enqueueStateRestore(target) {
2095 if (restoreTarget) {
2096 if (restoreQueue) {
2097 restoreQueue.push(target);
2098 } else {
2099 restoreQueue = [target];
2100 }
2101 } else {
2102 restoreTarget = target;
2103 }
2104}
2105
2106function needsStateRestore() {
2107 return restoreTarget !== null || restoreQueue !== null;
2108}
2109
2110function restoreStateIfNeeded() {
2111 if (!restoreTarget) {
2112 return;
2113 }
2114 var target = restoreTarget;
2115 var queuedTargets = restoreQueue;
2116 restoreTarget = null;
2117 restoreQueue = null;
2118
2119 restoreStateOfTarget(target);
2120 if (queuedTargets) {
2121 for (var i = 0; i < queuedTargets.length; i++) {
2122 restoreStateOfTarget(queuedTargets[i]);
2123 }
2124 }
2125}
2126
2127// Used as a way to call batchedUpdates when we don't have a reference to
2128// the renderer. Such as when we're dispatching events or if third party
2129// libraries need to call batchedUpdates. Eventually, this API will go away when
2130// everything is batched by default. We'll then have a similar API to opt-out of
2131// scheduled work and instead do synchronous work.
2132
2133// Defaults
2134var _batchedUpdatesImpl = function (fn, bookkeeping) {
2135 return fn(bookkeeping);
2136};
2137var _interactiveUpdatesImpl = function (fn, a, b) {
2138 return fn(a, b);
2139};
2140var _flushInteractiveUpdatesImpl = function () {};
2141
2142var isBatching = false;
2143function batchedUpdates(fn, bookkeeping) {
2144 if (isBatching) {
2145 // If we are currently inside another batch, we need to wait until it
2146 // fully completes before restoring state.
2147 return fn(bookkeeping);
2148 }
2149 isBatching = true;
2150 try {
2151 return _batchedUpdatesImpl(fn, bookkeeping);
2152 } finally {
2153 // Here we wait until all updates have propagated, which is important
2154 // when using controlled components within layers:
2155 // https://github.com/facebook/react/issues/1698
2156 // Then we restore state of any controlled component.
2157 isBatching = false;
2158 var controlledComponentsHavePendingUpdates = needsStateRestore();
2159 if (controlledComponentsHavePendingUpdates) {
2160 // If a controlled event was fired, we may need to restore the state of
2161 // the DOM node back to the controlled value. This is necessary when React
2162 // bails out of the update without touching the DOM.
2163 _flushInteractiveUpdatesImpl();
2164 restoreStateIfNeeded();
2165 }
2166 }
2167}
2168
2169function interactiveUpdates(fn, a, b) {
2170 return _interactiveUpdatesImpl(fn, a, b);
2171}
2172
2173
2174
2175function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) {
2176 _batchedUpdatesImpl = batchedUpdatesImpl;
2177 _interactiveUpdatesImpl = interactiveUpdatesImpl;
2178 _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl;
2179}
2180
2181/**
2182 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
2183 */
2184var supportedInputTypes = {
2185 color: true,
2186 date: true,
2187 datetime: true,
2188 'datetime-local': true,
2189 email: true,
2190 month: true,
2191 number: true,
2192 password: true,
2193 range: true,
2194 search: true,
2195 tel: true,
2196 text: true,
2197 time: true,
2198 url: true,
2199 week: true
2200};
2201
2202function isTextInputElement(elem) {
2203 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
2204
2205 if (nodeName === 'input') {
2206 return !!supportedInputTypes[elem.type];
2207 }
2208
2209 if (nodeName === 'textarea') {
2210 return true;
2211 }
2212
2213 return false;
2214}
2215
2216/**
2217 * HTML nodeType values that represent the type of the node
2218 */
2219
2220var ELEMENT_NODE = 1;
2221var TEXT_NODE = 3;
2222var COMMENT_NODE = 8;
2223var DOCUMENT_NODE = 9;
2224var DOCUMENT_FRAGMENT_NODE = 11;
2225
2226/**
2227 * Gets the target node from a native browser event by accounting for
2228 * inconsistencies in browser DOM APIs.
2229 *
2230 * @param {object} nativeEvent Native browser event.
2231 * @return {DOMEventTarget} Target node.
2232 */
2233function getEventTarget(nativeEvent) {
2234 // Fallback to nativeEvent.srcElement for IE9
2235 // https://github.com/facebook/react/issues/12506
2236 var target = nativeEvent.target || nativeEvent.srcElement || window;
2237
2238 // Normalize SVG <use> element events #4963
2239 if (target.correspondingUseElement) {
2240 target = target.correspondingUseElement;
2241 }
2242
2243 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
2244 // @see http://www.quirksmode.org/js/events_properties.html
2245 return target.nodeType === TEXT_NODE ? target.parentNode : target;
2246}
2247
2248/**
2249 * Checks if an event is supported in the current execution environment.
2250 *
2251 * NOTE: This will not work correctly for non-generic events such as `change`,
2252 * `reset`, `load`, `error`, and `select`.
2253 *
2254 * Borrows from Modernizr.
2255 *
2256 * @param {string} eventNameSuffix Event name, e.g. "click".
2257 * @return {boolean} True if the event is supported.
2258 * @internal
2259 * @license Modernizr 3.0.0pre (Custom Build) | MIT
2260 */
2261function isEventSupported(eventNameSuffix) {
2262 if (!canUseDOM) {
2263 return false;
2264 }
2265
2266 var eventName = 'on' + eventNameSuffix;
2267 var isSupported = eventName in document;
2268
2269 if (!isSupported) {
2270 var element = document.createElement('div');
2271 element.setAttribute(eventName, 'return;');
2272 isSupported = typeof element[eventName] === 'function';
2273 }
2274
2275 return isSupported;
2276}
2277
2278function isCheckable(elem) {
2279 var type = elem.type;
2280 var nodeName = elem.nodeName;
2281 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2282}
2283
2284function getTracker(node) {
2285 return node._valueTracker;
2286}
2287
2288function detachTracker(node) {
2289 node._valueTracker = null;
2290}
2291
2292function getValueFromNode(node) {
2293 var value = '';
2294 if (!node) {
2295 return value;
2296 }
2297
2298 if (isCheckable(node)) {
2299 value = node.checked ? 'true' : 'false';
2300 } else {
2301 value = node.value;
2302 }
2303
2304 return value;
2305}
2306
2307function trackValueOnNode(node) {
2308 var valueField = isCheckable(node) ? 'checked' : 'value';
2309 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2310
2311 var currentValue = '' + node[valueField];
2312
2313 // if someone has already defined a value or Safari, then bail
2314 // and don't track value will cause over reporting of changes,
2315 // but it's better then a hard failure
2316 // (needed for certain tests that spyOn input values and Safari)
2317 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2318 return;
2319 }
2320 var get = descriptor.get,
2321 set = descriptor.set;
2322
2323 Object.defineProperty(node, valueField, {
2324 configurable: true,
2325 get: function () {
2326 return get.call(this);
2327 },
2328 set: function (value) {
2329 currentValue = '' + value;
2330 set.call(this, value);
2331 }
2332 });
2333 // We could've passed this the first time
2334 // but it triggers a bug in IE11 and Edge 14/15.
2335 // Calling defineProperty() again should be equivalent.
2336 // https://github.com/facebook/react/issues/11768
2337 Object.defineProperty(node, valueField, {
2338 enumerable: descriptor.enumerable
2339 });
2340
2341 var tracker = {
2342 getValue: function () {
2343 return currentValue;
2344 },
2345 setValue: function (value) {
2346 currentValue = '' + value;
2347 },
2348 stopTracking: function () {
2349 detachTracker(node);
2350 delete node[valueField];
2351 }
2352 };
2353 return tracker;
2354}
2355
2356function track(node) {
2357 if (getTracker(node)) {
2358 return;
2359 }
2360
2361 // TODO: Once it's just Fiber we can move this to node._wrapperState
2362 node._valueTracker = trackValueOnNode(node);
2363}
2364
2365function updateValueIfChanged(node) {
2366 if (!node) {
2367 return false;
2368 }
2369
2370 var tracker = getTracker(node);
2371 // if there is no tracker at this point it's unlikely
2372 // that trying again will succeed
2373 if (!tracker) {
2374 return true;
2375 }
2376
2377 var lastValue = tracker.getValue();
2378 var nextValue = getValueFromNode(node);
2379 if (nextValue !== lastValue) {
2380 tracker.setValue(nextValue);
2381 return true;
2382 }
2383 return false;
2384}
2385
2386var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2387
2388// Prevent newer renderers from RTE when used with older react package versions.
2389// Current owner and dispatcher used to share the same ref,
2390// but PR #14548 split them out to better support the react-debug-tools package.
2391if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
2392 ReactSharedInternals.ReactCurrentDispatcher = {
2393 current: null
2394 };
2395}
2396
2397var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
2398
2399var describeComponentFrame = function (name, source, ownerName) {
2400 var sourceInfo = '';
2401 if (source) {
2402 var path = source.fileName;
2403 var fileName = path.replace(BEFORE_SLASH_RE, '');
2404 {
2405 // In DEV, include code for a common special case:
2406 // prefer "folder/index.js" instead of just "index.js".
2407 if (/^index\./.test(fileName)) {
2408 var match = path.match(BEFORE_SLASH_RE);
2409 if (match) {
2410 var pathBeforeSlash = match[1];
2411 if (pathBeforeSlash) {
2412 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
2413 fileName = folderName + '/' + fileName;
2414 }
2415 }
2416 }
2417 }
2418 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
2419 } else if (ownerName) {
2420 sourceInfo = ' (created by ' + ownerName + ')';
2421 }
2422 return '\n in ' + (name || 'Unknown') + sourceInfo;
2423};
2424
2425// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
2426// nor polyfill, then a plain number is used for performance.
2427var hasSymbol = typeof Symbol === 'function' && Symbol.for;
2428
2429var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
2430var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
2431var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
2432var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
2433var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
2434var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
2435var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
2436
2437var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
2438var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
2439var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
2440var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
2441var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
2442
2443var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
2444var FAUX_ITERATOR_SYMBOL = '@@iterator';
2445
2446function getIteratorFn(maybeIterable) {
2447 if (maybeIterable === null || typeof maybeIterable !== 'object') {
2448 return null;
2449 }
2450 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
2451 if (typeof maybeIterator === 'function') {
2452 return maybeIterator;
2453 }
2454 return null;
2455}
2456
2457var Pending = 0;
2458var Resolved = 1;
2459var Rejected = 2;
2460
2461function refineResolvedLazyComponent(lazyComponent) {
2462 return lazyComponent._status === Resolved ? lazyComponent._result : null;
2463}
2464
2465function getWrappedName(outerType, innerType, wrapperName) {
2466 var functionName = innerType.displayName || innerType.name || '';
2467 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
2468}
2469
2470function getComponentName(type) {
2471 if (type == null) {
2472 // Host root, text node or just invalid type.
2473 return null;
2474 }
2475 {
2476 if (typeof type.tag === 'number') {
2477 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
2478 }
2479 }
2480 if (typeof type === 'function') {
2481 return type.displayName || type.name || null;
2482 }
2483 if (typeof type === 'string') {
2484 return type;
2485 }
2486 switch (type) {
2487 case REACT_CONCURRENT_MODE_TYPE:
2488 return 'ConcurrentMode';
2489 case REACT_FRAGMENT_TYPE:
2490 return 'Fragment';
2491 case REACT_PORTAL_TYPE:
2492 return 'Portal';
2493 case REACT_PROFILER_TYPE:
2494 return 'Profiler';
2495 case REACT_STRICT_MODE_TYPE:
2496 return 'StrictMode';
2497 case REACT_SUSPENSE_TYPE:
2498 return 'Suspense';
2499 }
2500 if (typeof type === 'object') {
2501 switch (type.$$typeof) {
2502 case REACT_CONTEXT_TYPE:
2503 return 'Context.Consumer';
2504 case REACT_PROVIDER_TYPE:
2505 return 'Context.Provider';
2506 case REACT_FORWARD_REF_TYPE:
2507 return getWrappedName(type, type.render, 'ForwardRef');
2508 case REACT_MEMO_TYPE:
2509 return getComponentName(type.type);
2510 case REACT_LAZY_TYPE:
2511 {
2512 var thenable = type;
2513 var resolvedThenable = refineResolvedLazyComponent(thenable);
2514 if (resolvedThenable) {
2515 return getComponentName(resolvedThenable);
2516 }
2517 }
2518 }
2519 }
2520 return null;
2521}
2522
2523var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2524
2525function describeFiber(fiber) {
2526 switch (fiber.tag) {
2527 case HostRoot:
2528 case HostPortal:
2529 case HostText:
2530 case Fragment:
2531 case ContextProvider:
2532 case ContextConsumer:
2533 return '';
2534 default:
2535 var owner = fiber._debugOwner;
2536 var source = fiber._debugSource;
2537 var name = getComponentName(fiber.type);
2538 var ownerName = null;
2539 if (owner) {
2540 ownerName = getComponentName(owner.type);
2541 }
2542 return describeComponentFrame(name, source, ownerName);
2543 }
2544}
2545
2546function getStackByFiberInDevAndProd(workInProgress) {
2547 var info = '';
2548 var node = workInProgress;
2549 do {
2550 info += describeFiber(node);
2551 node = node.return;
2552 } while (node);
2553 return info;
2554}
2555
2556var current = null;
2557var phase = null;
2558
2559function getCurrentFiberOwnerNameInDevOrNull() {
2560 {
2561 if (current === null) {
2562 return null;
2563 }
2564 var owner = current._debugOwner;
2565 if (owner !== null && typeof owner !== 'undefined') {
2566 return getComponentName(owner.type);
2567 }
2568 }
2569 return null;
2570}
2571
2572function getCurrentFiberStackInDev() {
2573 {
2574 if (current === null) {
2575 return '';
2576 }
2577 // Safe because if current fiber exists, we are reconciling,
2578 // and it is guaranteed to be the work-in-progress version.
2579 return getStackByFiberInDevAndProd(current);
2580 }
2581 return '';
2582}
2583
2584function resetCurrentFiber() {
2585 {
2586 ReactDebugCurrentFrame.getCurrentStack = null;
2587 current = null;
2588 phase = null;
2589 }
2590}
2591
2592function setCurrentFiber(fiber) {
2593 {
2594 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
2595 current = fiber;
2596 phase = null;
2597 }
2598}
2599
2600function setCurrentPhase(lifeCyclePhase) {
2601 {
2602 phase = lifeCyclePhase;
2603 }
2604}
2605
2606/**
2607 * Similar to invariant but only logs a warning if the condition is not met.
2608 * This can be used to log issues in development environments in critical
2609 * paths. Removing the logging code for production environments will keep the
2610 * same logic and follow the same code paths.
2611 */
2612
2613var warning = warningWithoutStack$1;
2614
2615{
2616 warning = function (condition, format) {
2617 if (condition) {
2618 return;
2619 }
2620 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2621 var stack = ReactDebugCurrentFrame.getStackAddendum();
2622 // eslint-disable-next-line react-internal/warning-and-invariant-args
2623
2624 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
2625 args[_key - 2] = arguments[_key];
2626 }
2627
2628 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
2629 };
2630}
2631
2632var warning$1 = warning;
2633
2634// A reserved attribute.
2635// It is handled by React separately and shouldn't be written to the DOM.
2636var RESERVED = 0;
2637
2638// A simple string attribute.
2639// Attributes that aren't in the whitelist are presumed to have this type.
2640var STRING = 1;
2641
2642// A string attribute that accepts booleans in React. In HTML, these are called
2643// "enumerated" attributes with "true" and "false" as possible values.
2644// When true, it should be set to a "true" string.
2645// When false, it should be set to a "false" string.
2646var BOOLEANISH_STRING = 2;
2647
2648// A real boolean attribute.
2649// When true, it should be present (set either to an empty string or its name).
2650// When false, it should be omitted.
2651var BOOLEAN = 3;
2652
2653// An attribute that can be used as a flag as well as with a value.
2654// When true, it should be present (set either to an empty string or its name).
2655// When false, it should be omitted.
2656// For any other value, should be present with that value.
2657var OVERLOADED_BOOLEAN = 4;
2658
2659// An attribute that must be numeric or parse as a numeric.
2660// When falsy, it should be removed.
2661var NUMERIC = 5;
2662
2663// An attribute that must be positive numeric or parse as a positive numeric.
2664// When falsy, it should be removed.
2665var POSITIVE_NUMERIC = 6;
2666
2667/* eslint-disable max-len */
2668var 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';
2669/* eslint-enable max-len */
2670var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
2671
2672
2673var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
2674var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
2675
2676var hasOwnProperty = Object.prototype.hasOwnProperty;
2677var illegalAttributeNameCache = {};
2678var validatedAttributeNameCache = {};
2679
2680function isAttributeNameSafe(attributeName) {
2681 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
2682 return true;
2683 }
2684 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
2685 return false;
2686 }
2687 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2688 validatedAttributeNameCache[attributeName] = true;
2689 return true;
2690 }
2691 illegalAttributeNameCache[attributeName] = true;
2692 {
2693 warning$1(false, 'Invalid attribute name: `%s`', attributeName);
2694 }
2695 return false;
2696}
2697
2698function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2699 if (propertyInfo !== null) {
2700 return propertyInfo.type === RESERVED;
2701 }
2702 if (isCustomComponentTag) {
2703 return false;
2704 }
2705 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2706 return true;
2707 }
2708 return false;
2709}
2710
2711function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2712 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2713 return false;
2714 }
2715 switch (typeof value) {
2716 case 'function':
2717 // $FlowIssue symbol is perfectly valid here
2718 case 'symbol':
2719 // eslint-disable-line
2720 return true;
2721 case 'boolean':
2722 {
2723 if (isCustomComponentTag) {
2724 return false;
2725 }
2726 if (propertyInfo !== null) {
2727 return !propertyInfo.acceptsBooleans;
2728 } else {
2729 var prefix = name.toLowerCase().slice(0, 5);
2730 return prefix !== 'data-' && prefix !== 'aria-';
2731 }
2732 }
2733 default:
2734 return false;
2735 }
2736}
2737
2738function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2739 if (value === null || typeof value === 'undefined') {
2740 return true;
2741 }
2742 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2743 return true;
2744 }
2745 if (isCustomComponentTag) {
2746 return false;
2747 }
2748 if (propertyInfo !== null) {
2749 switch (propertyInfo.type) {
2750 case BOOLEAN:
2751 return !value;
2752 case OVERLOADED_BOOLEAN:
2753 return value === false;
2754 case NUMERIC:
2755 return isNaN(value);
2756 case POSITIVE_NUMERIC:
2757 return isNaN(value) || value < 1;
2758 }
2759 }
2760 return false;
2761}
2762
2763function getPropertyInfo(name) {
2764 return properties.hasOwnProperty(name) ? properties[name] : null;
2765}
2766
2767function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
2768 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2769 this.attributeName = attributeName;
2770 this.attributeNamespace = attributeNamespace;
2771 this.mustUseProperty = mustUseProperty;
2772 this.propertyName = name;
2773 this.type = type;
2774}
2775
2776// When adding attributes to this list, be sure to also add them to
2777// the `possibleStandardNames` module to ensure casing and incorrect
2778// name warnings.
2779var properties = {};
2780
2781// These props are reserved by React. They shouldn't be written to the DOM.
2782['children', 'dangerouslySetInnerHTML',
2783// TODO: This prevents the assignment of defaultValue to regular
2784// elements (not just inputs). Now that ReactDOMInput assigns to the
2785// defaultValue property -- do we need this?
2786'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
2787 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
2788 name, // attributeName
2789 null);
2790} // attributeNamespace
2791);
2792
2793// A few React string attributes have a different name.
2794// This is a mapping from React prop names to the attribute names.
2795[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
2796 var name = _ref[0],
2797 attributeName = _ref[1];
2798
2799 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2800 attributeName, // attributeName
2801 null);
2802} // attributeNamespace
2803);
2804
2805// These are "enumerated" HTML attributes that accept "true" and "false".
2806// In React, we let users pass `true` and `false` even though technically
2807// these aren't boolean attributes (they are coerced to strings).
2808['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
2809 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2810 name.toLowerCase(), // attributeName
2811 null);
2812} // attributeNamespace
2813);
2814
2815// These are "enumerated" SVG attributes that accept "true" and "false".
2816// In React, we let users pass `true` and `false` even though technically
2817// these aren't boolean attributes (they are coerced to strings).
2818// Since these are SVG attributes, their attribute names are case-sensitive.
2819['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
2820 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2821 name, // attributeName
2822 null);
2823} // attributeNamespace
2824);
2825
2826// These are HTML boolean attributes.
2827['allowFullScreen', 'async',
2828// Note: there is a special case that prevents it from being written to the DOM
2829// on the client side because the browsers are inconsistent. Instead we call focus().
2830'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
2831// Microdata
2832'itemScope'].forEach(function (name) {
2833 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
2834 name.toLowerCase(), // attributeName
2835 null);
2836} // attributeNamespace
2837);
2838
2839// These are the few React props that we set as DOM properties
2840// rather than attributes. These are all booleans.
2841['checked',
2842// Note: `option.selected` is not updated if `select.multiple` is
2843// disabled with `removeAttribute`. We have special logic for handling this.
2844'multiple', 'muted', 'selected'].forEach(function (name) {
2845 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
2846 name, // attributeName
2847 null);
2848} // attributeNamespace
2849);
2850
2851// These are HTML attributes that are "overloaded booleans": they behave like
2852// booleans, but can also accept a string value.
2853['capture', 'download'].forEach(function (name) {
2854 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
2855 name, // attributeName
2856 null);
2857} // attributeNamespace
2858);
2859
2860// These are HTML attributes that must be positive numbers.
2861['cols', 'rows', 'size', 'span'].forEach(function (name) {
2862 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
2863 name, // attributeName
2864 null);
2865} // attributeNamespace
2866);
2867
2868// These are HTML attributes that must be numbers.
2869['rowSpan', 'start'].forEach(function (name) {
2870 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
2871 name.toLowerCase(), // attributeName
2872 null);
2873} // attributeNamespace
2874);
2875
2876var CAMELIZE = /[\-\:]([a-z])/g;
2877var capitalize = function (token) {
2878 return token[1].toUpperCase();
2879};
2880
2881// This is a list of all SVG attributes that need special casing, namespacing,
2882// or boolean value assignment. Regular attributes that just accept strings
2883// and have the same names are omitted, just like in the HTML whitelist.
2884// Some of these attributes can be hard to find. This list was created by
2885// scrapping the MDN documentation.
2886['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) {
2887 var name = attributeName.replace(CAMELIZE, capitalize);
2888 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2889 attributeName, null);
2890} // attributeNamespace
2891);
2892
2893// String SVG attributes with the xlink namespace.
2894['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
2895 var name = attributeName.replace(CAMELIZE, capitalize);
2896 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2897 attributeName, 'http://www.w3.org/1999/xlink');
2898});
2899
2900// String SVG attributes with the xml namespace.
2901['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
2902 var name = attributeName.replace(CAMELIZE, capitalize);
2903 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2904 attributeName, 'http://www.w3.org/XML/1998/namespace');
2905});
2906
2907// These attribute exists both in HTML and SVG.
2908// The attribute name is case-sensitive in SVG so we can't just use
2909// the React name like we do for attributes that exist only in HTML.
2910['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
2911 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
2912 attributeName.toLowerCase(), // attributeName
2913 null);
2914} // attributeNamespace
2915);
2916
2917/**
2918 * Get the value for a property on a node. Only used in DEV for SSR validation.
2919 * The "expected" argument is used as a hint of what the expected value is.
2920 * Some properties have multiple equivalent values.
2921 */
2922function getValueForProperty(node, name, expected, propertyInfo) {
2923 {
2924 if (propertyInfo.mustUseProperty) {
2925 var propertyName = propertyInfo.propertyName;
2926
2927 return node[propertyName];
2928 } else {
2929 var attributeName = propertyInfo.attributeName;
2930
2931 var stringValue = null;
2932
2933 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
2934 if (node.hasAttribute(attributeName)) {
2935 var value = node.getAttribute(attributeName);
2936 if (value === '') {
2937 return true;
2938 }
2939 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2940 return value;
2941 }
2942 if (value === '' + expected) {
2943 return expected;
2944 }
2945 return value;
2946 }
2947 } else if (node.hasAttribute(attributeName)) {
2948 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2949 // We had an attribute but shouldn't have had one, so read it
2950 // for the error message.
2951 return node.getAttribute(attributeName);
2952 }
2953 if (propertyInfo.type === BOOLEAN) {
2954 // If this was a boolean, it doesn't matter what the value is
2955 // the fact that we have it is the same as the expected.
2956 return expected;
2957 }
2958 // Even if this property uses a namespace we use getAttribute
2959 // because we assume its namespaced name is the same as our config.
2960 // To use getAttributeNS we need the local name which we don't have
2961 // in our config atm.
2962 stringValue = node.getAttribute(attributeName);
2963 }
2964
2965 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2966 return stringValue === null ? expected : stringValue;
2967 } else if (stringValue === '' + expected) {
2968 return expected;
2969 } else {
2970 return stringValue;
2971 }
2972 }
2973 }
2974}
2975
2976/**
2977 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2978 * The third argument is used as a hint of what the expected value is. Some
2979 * attributes have multiple equivalent values.
2980 */
2981function getValueForAttribute(node, name, expected) {
2982 {
2983 if (!isAttributeNameSafe(name)) {
2984 return;
2985 }
2986 if (!node.hasAttribute(name)) {
2987 return expected === undefined ? undefined : null;
2988 }
2989 var value = node.getAttribute(name);
2990 if (value === '' + expected) {
2991 return expected;
2992 }
2993 return value;
2994 }
2995}
2996
2997/**
2998 * Sets the value for a property on a node.
2999 *
3000 * @param {DOMElement} node
3001 * @param {string} name
3002 * @param {*} value
3003 */
3004function setValueForProperty(node, name, value, isCustomComponentTag) {
3005 var propertyInfo = getPropertyInfo(name);
3006 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
3007 return;
3008 }
3009 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
3010 value = null;
3011 }
3012 // If the prop isn't in the special list, treat it as a simple attribute.
3013 if (isCustomComponentTag || propertyInfo === null) {
3014 if (isAttributeNameSafe(name)) {
3015 var _attributeName = name;
3016 if (value === null) {
3017 node.removeAttribute(_attributeName);
3018 } else {
3019 node.setAttribute(_attributeName, '' + value);
3020 }
3021 }
3022 return;
3023 }
3024 var mustUseProperty = propertyInfo.mustUseProperty;
3025
3026 if (mustUseProperty) {
3027 var propertyName = propertyInfo.propertyName;
3028
3029 if (value === null) {
3030 var type = propertyInfo.type;
3031
3032 node[propertyName] = type === BOOLEAN ? false : '';
3033 } else {
3034 // Contrary to `setAttribute`, object properties are properly
3035 // `toString`ed by IE8/9.
3036 node[propertyName] = value;
3037 }
3038 return;
3039 }
3040 // The rest are treated as attributes with special cases.
3041 var attributeName = propertyInfo.attributeName,
3042 attributeNamespace = propertyInfo.attributeNamespace;
3043
3044 if (value === null) {
3045 node.removeAttribute(attributeName);
3046 } else {
3047 var _type = propertyInfo.type;
3048
3049 var attributeValue = void 0;
3050 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
3051 attributeValue = '';
3052 } else {
3053 // `setAttribute` with objects becomes only `[object]` in IE8/9,
3054 // ('' + value) makes it output the correct toString()-value.
3055 attributeValue = '' + value;
3056 }
3057 if (attributeNamespace) {
3058 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
3059 } else {
3060 node.setAttribute(attributeName, attributeValue);
3061 }
3062 }
3063}
3064
3065// Flow does not allow string concatenation of most non-string types. To work
3066// around this limitation, we use an opaque type that can only be obtained by
3067// passing the value through getToStringValue first.
3068function toString(value) {
3069 return '' + value;
3070}
3071
3072function getToStringValue(value) {
3073 switch (typeof value) {
3074 case 'boolean':
3075 case 'number':
3076 case 'object':
3077 case 'string':
3078 case 'undefined':
3079 return value;
3080 default:
3081 // function, symbol are assigned as empty strings
3082 return '';
3083 }
3084}
3085
3086var ReactDebugCurrentFrame$1 = null;
3087
3088var ReactControlledValuePropTypes = {
3089 checkPropTypes: null
3090};
3091
3092{
3093 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
3094
3095 var hasReadOnlyValue = {
3096 button: true,
3097 checkbox: true,
3098 image: true,
3099 hidden: true,
3100 radio: true,
3101 reset: true,
3102 submit: true
3103 };
3104
3105 var propTypes = {
3106 value: function (props, propName, componentName) {
3107 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) {
3108 return null;
3109 }
3110 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`.');
3111 },
3112 checked: function (props, propName, componentName) {
3113 if (props.onChange || props.readOnly || props.disabled || props[propName] == null) {
3114 return null;
3115 }
3116 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`.');
3117 }
3118 };
3119
3120 /**
3121 * Provide a linked `value` attribute for controlled forms. You should not use
3122 * this outside of the ReactDOM controlled form components.
3123 */
3124 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
3125 checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum);
3126 };
3127}
3128
3129var enableUserTimingAPI = true;
3130
3131// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
3132var debugRenderPhaseSideEffects = false;
3133
3134// In some cases, StrictMode should also double-render lifecycles.
3135// This can be confusing for tests though,
3136// And it can be bad for performance in production.
3137// This feature flag can be used to control the behavior:
3138var debugRenderPhaseSideEffectsForStrictMode = true;
3139
3140// To preserve the "Pause on caught exceptions" behavior of the debugger, we
3141// replay the begin phase of a failed component inside invokeGuardedCallback.
3142var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
3143
3144// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
3145var warnAboutDeprecatedLifecycles = false;
3146
3147// Gather advanced timing metrics for Profiler subtrees.
3148var enableProfilerTimer = true;
3149
3150// Trace which interactions trigger each commit.
3151var enableSchedulerTracing = true;
3152
3153// Only used in www builds.
3154var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
3155
3156// Only used in www builds.
3157
3158
3159// Only used in www builds.
3160
3161
3162// React Fire: prevent the value and checked attributes from syncing
3163// with their related DOM properties
3164var disableInputAttributeSyncing = false;
3165
3166// These APIs will no longer be "unstable" in the upcoming 16.7 release,
3167// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
3168var enableStableConcurrentModeAPIs = false;
3169
3170var warnAboutShorthandPropertyCollision = false;
3171
3172// TODO: direct imports like some-package/src/* are bad. Fix me.
3173var didWarnValueDefaultValue = false;
3174var didWarnCheckedDefaultChecked = false;
3175var didWarnControlledToUncontrolled = false;
3176var didWarnUncontrolledToControlled = false;
3177
3178function isControlled(props) {
3179 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
3180 return usesChecked ? props.checked != null : props.value != null;
3181}
3182
3183/**
3184 * Implements an <input> host component that allows setting these optional
3185 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
3186 *
3187 * If `checked` or `value` are not supplied (or null/undefined), user actions
3188 * that affect the checked state or value will trigger updates to the element.
3189 *
3190 * If they are supplied (and not null/undefined), the rendered element will not
3191 * trigger updates to the element. Instead, the props must change in order for
3192 * the rendered element to be updated.
3193 *
3194 * The rendered element will be initialized as unchecked (or `defaultChecked`)
3195 * with an empty value (or `defaultValue`).
3196 *
3197 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
3198 */
3199
3200function getHostProps(element, props) {
3201 var node = element;
3202 var checked = props.checked;
3203
3204 var hostProps = _assign({}, props, {
3205 defaultChecked: undefined,
3206 defaultValue: undefined,
3207 value: undefined,
3208 checked: checked != null ? checked : node._wrapperState.initialChecked
3209 });
3210
3211 return hostProps;
3212}
3213
3214function initWrapperState(element, props) {
3215 {
3216 ReactControlledValuePropTypes.checkPropTypes('input', props);
3217
3218 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
3219 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);
3220 didWarnCheckedDefaultChecked = true;
3221 }
3222 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
3223 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);
3224 didWarnValueDefaultValue = true;
3225 }
3226 }
3227
3228 var node = element;
3229 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
3230
3231 node._wrapperState = {
3232 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
3233 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
3234 controlled: isControlled(props)
3235 };
3236}
3237
3238function updateChecked(element, props) {
3239 var node = element;
3240 var checked = props.checked;
3241 if (checked != null) {
3242 setValueForProperty(node, 'checked', checked, false);
3243 }
3244}
3245
3246function updateWrapper(element, props) {
3247 var node = element;
3248 {
3249 var _controlled = isControlled(props);
3250
3251 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
3252 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);
3253 didWarnUncontrolledToControlled = true;
3254 }
3255 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
3256 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);
3257 didWarnControlledToUncontrolled = true;
3258 }
3259 }
3260
3261 updateChecked(element, props);
3262
3263 var value = getToStringValue(props.value);
3264 var type = props.type;
3265
3266 if (value != null) {
3267 if (type === 'number') {
3268 if (value === 0 && node.value === '' ||
3269 // We explicitly want to coerce to number here if possible.
3270 // eslint-disable-next-line
3271 node.value != value) {
3272 node.value = toString(value);
3273 }
3274 } else if (node.value !== toString(value)) {
3275 node.value = toString(value);
3276 }
3277 } else if (type === 'submit' || type === 'reset') {
3278 // Submit/reset inputs need the attribute removed completely to avoid
3279 // blank-text buttons.
3280 node.removeAttribute('value');
3281 return;
3282 }
3283
3284 if (disableInputAttributeSyncing) {
3285 // When not syncing the value attribute, React only assigns a new value
3286 // whenever the defaultValue React prop has changed. When not present,
3287 // React does nothing
3288 if (props.hasOwnProperty('defaultValue')) {
3289 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3290 }
3291 } else {
3292 // When syncing the value attribute, the value comes from a cascade of
3293 // properties:
3294 // 1. The value React property
3295 // 2. The defaultValue React property
3296 // 3. Otherwise there should be no change
3297 if (props.hasOwnProperty('value')) {
3298 setDefaultValue(node, props.type, value);
3299 } else if (props.hasOwnProperty('defaultValue')) {
3300 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
3301 }
3302 }
3303
3304 if (disableInputAttributeSyncing) {
3305 // When not syncing the checked attribute, the attribute is directly
3306 // controllable from the defaultValue React property. It needs to be
3307 // updated as new props come in.
3308 if (props.defaultChecked == null) {
3309 node.removeAttribute('checked');
3310 } else {
3311 node.defaultChecked = !!props.defaultChecked;
3312 }
3313 } else {
3314 // When syncing the checked attribute, it only changes when it needs
3315 // to be removed, such as transitioning from a checkbox into a text input
3316 if (props.checked == null && props.defaultChecked != null) {
3317 node.defaultChecked = !!props.defaultChecked;
3318 }
3319 }
3320}
3321
3322function postMountWrapper(element, props, isHydrating) {
3323 var node = element;
3324
3325 // Do not assign value if it is already set. This prevents user text input
3326 // from being lost during SSR hydration.
3327 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
3328 var type = props.type;
3329 var isButton = type === 'submit' || type === 'reset';
3330
3331 // Avoid setting value attribute on submit/reset inputs as it overrides the
3332 // default value provided by the browser. See: #12872
3333 if (isButton && (props.value === undefined || props.value === null)) {
3334 return;
3335 }
3336
3337 var _initialValue = toString(node._wrapperState.initialValue);
3338
3339 // Do not assign value if it is already set. This prevents user text input
3340 // from being lost during SSR hydration.
3341 if (!isHydrating) {
3342 if (disableInputAttributeSyncing) {
3343 var value = getToStringValue(props.value);
3344
3345 // When not syncing the value attribute, the value property points
3346 // directly to the React prop. Only assign it if it exists.
3347 if (value != null) {
3348 // Always assign on buttons so that it is possible to assign an
3349 // empty string to clear button text.
3350 //
3351 // Otherwise, do not re-assign the value property if is empty. This
3352 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
3353 // prematurely marking required inputs as invalid. Equality is compared
3354 // to the current value in case the browser provided value is not an
3355 // empty string.
3356 if (isButton || value !== node.value) {
3357 node.value = toString(value);
3358 }
3359 }
3360 } else {
3361 // When syncing the value attribute, the value property should use
3362 // the wrapperState._initialValue property. This uses:
3363 //
3364 // 1. The value React property when present
3365 // 2. The defaultValue React property when present
3366 // 3. An empty string
3367 if (_initialValue !== node.value) {
3368 node.value = _initialValue;
3369 }
3370 }
3371 }
3372
3373 if (disableInputAttributeSyncing) {
3374 // When not syncing the value attribute, assign the value attribute
3375 // directly from the defaultValue React property (when present)
3376 var defaultValue = getToStringValue(props.defaultValue);
3377 if (defaultValue != null) {
3378 node.defaultValue = toString(defaultValue);
3379 }
3380 } else {
3381 // Otherwise, the value attribute is synchronized to the property,
3382 // so we assign defaultValue to the same thing as the value property
3383 // assignment step above.
3384 node.defaultValue = _initialValue;
3385 }
3386 }
3387
3388 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
3389 // this is needed to work around a chrome bug where setting defaultChecked
3390 // will sometimes influence the value of checked (even after detachment).
3391 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
3392 // We need to temporarily unset name to avoid disrupting radio button groups.
3393 var name = node.name;
3394 if (name !== '') {
3395 node.name = '';
3396 }
3397
3398 if (disableInputAttributeSyncing) {
3399 // When not syncing the checked attribute, the checked property
3400 // never gets assigned. It must be manually set. We don't want
3401 // to do this when hydrating so that existing user input isn't
3402 // modified
3403 if (!isHydrating) {
3404 updateChecked(element, props);
3405 }
3406
3407 // Only assign the checked attribute if it is defined. This saves
3408 // a DOM write when controlling the checked attribute isn't needed
3409 // (text inputs, submit/reset)
3410 if (props.hasOwnProperty('defaultChecked')) {
3411 node.defaultChecked = !node.defaultChecked;
3412 node.defaultChecked = !!props.defaultChecked;
3413 }
3414 } else {
3415 // When syncing the checked attribute, both the checked property and
3416 // attribute are assigned at the same time using defaultChecked. This uses:
3417 //
3418 // 1. The checked React property when present
3419 // 2. The defaultChecked React property when present
3420 // 3. Otherwise, false
3421 node.defaultChecked = !node.defaultChecked;
3422 node.defaultChecked = !!node._wrapperState.initialChecked;
3423 }
3424
3425 if (name !== '') {
3426 node.name = name;
3427 }
3428}
3429
3430function restoreControlledState(element, props) {
3431 var node = element;
3432 updateWrapper(node, props);
3433 updateNamedCousins(node, props);
3434}
3435
3436function updateNamedCousins(rootNode, props) {
3437 var name = props.name;
3438 if (props.type === 'radio' && name != null) {
3439 var queryRoot = rootNode;
3440
3441 while (queryRoot.parentNode) {
3442 queryRoot = queryRoot.parentNode;
3443 }
3444
3445 // If `rootNode.form` was non-null, then we could try `form.elements`,
3446 // but that sometimes behaves strangely in IE8. We could also try using
3447 // `form.getElementsByName`, but that will only return direct children
3448 // and won't include inputs that use the HTML5 `form=` attribute. Since
3449 // the input might not even be in a form. It might not even be in the
3450 // document. Let's just use the local `querySelectorAll` to ensure we don't
3451 // miss anything.
3452 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3453
3454 for (var i = 0; i < group.length; i++) {
3455 var otherNode = group[i];
3456 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3457 continue;
3458 }
3459 // This will throw if radio buttons rendered by different copies of React
3460 // and the same name are rendered into the same form (same as #1939).
3461 // That's probably okay; we don't support it just as we don't support
3462 // mixing React radio buttons with non-React ones.
3463 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3464 !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
3465
3466 // We need update the tracked value on the named cousin since the value
3467 // was changed but the input saw no event or value set
3468 updateValueIfChanged(otherNode);
3469
3470 // If this is a controlled radio button group, forcing the input that
3471 // was previously checked to update will cause it to be come re-checked
3472 // as appropriate.
3473 updateWrapper(otherNode, otherProps);
3474 }
3475 }
3476}
3477
3478// In Chrome, assigning defaultValue to certain input types triggers input validation.
3479// For number inputs, the display value loses trailing decimal points. For email inputs,
3480// Chrome raises "The specified value <x> is not a valid email address".
3481//
3482// Here we check to see if the defaultValue has actually changed, avoiding these problems
3483// when the user is inputting text
3484//
3485// https://github.com/facebook/react/issues/7253
3486function setDefaultValue(node, type, value) {
3487 if (
3488 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3489 type !== 'number' || node.ownerDocument.activeElement !== node) {
3490 if (value == null) {
3491 node.defaultValue = toString(node._wrapperState.initialValue);
3492 } else if (node.defaultValue !== toString(value)) {
3493 node.defaultValue = toString(value);
3494 }
3495 }
3496}
3497
3498var eventTypes$1 = {
3499 change: {
3500 phasedRegistrationNames: {
3501 bubbled: 'onChange',
3502 captured: 'onChangeCapture'
3503 },
3504 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
3505 }
3506};
3507
3508function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
3509 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
3510 event.type = 'change';
3511 // Flag this event loop as needing state restore.
3512 enqueueStateRestore(target);
3513 accumulateTwoPhaseDispatches(event);
3514 return event;
3515}
3516/**
3517 * For IE shims
3518 */
3519var activeElement = null;
3520var activeElementInst = null;
3521
3522/**
3523 * SECTION: handle `change` event
3524 */
3525function shouldUseChangeEvent(elem) {
3526 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
3527 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
3528}
3529
3530function manualDispatchChangeEvent(nativeEvent) {
3531 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
3532
3533 // If change and propertychange bubbled, we'd just bind to it like all the
3534 // other events and have it go through ReactBrowserEventEmitter. Since it
3535 // doesn't, we manually listen for the events and so we have to enqueue and
3536 // process the abstract event manually.
3537 //
3538 // Batching is necessary here in order to ensure that all event handlers run
3539 // before the next rerender (including event handlers attached to ancestor
3540 // elements instead of directly on the input). Without this, controlled
3541 // components don't work properly in conjunction with event bubbling because
3542 // the component is rerendered and the value reverted before all the event
3543 // handlers can run. See https://github.com/facebook/react/issues/708.
3544 batchedUpdates(runEventInBatch, event);
3545}
3546
3547function runEventInBatch(event) {
3548 runEventsInBatch(event);
3549}
3550
3551function getInstIfValueChanged(targetInst) {
3552 var targetNode = getNodeFromInstance$1(targetInst);
3553 if (updateValueIfChanged(targetNode)) {
3554 return targetInst;
3555 }
3556}
3557
3558function getTargetInstForChangeEvent(topLevelType, targetInst) {
3559 if (topLevelType === TOP_CHANGE) {
3560 return targetInst;
3561 }
3562}
3563
3564/**
3565 * SECTION: handle `input` event
3566 */
3567var isInputEventSupported = false;
3568if (canUseDOM) {
3569 // IE9 claims to support the input event but fails to trigger it when
3570 // deleting text, so we ignore its input events.
3571 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
3572}
3573
3574/**
3575 * (For IE <=9) Starts tracking propertychange events on the passed-in element
3576 * and override the value property so that we can distinguish user events from
3577 * value changes in JS.
3578 */
3579function startWatchingForValueChange(target, targetInst) {
3580 activeElement = target;
3581 activeElementInst = targetInst;
3582 activeElement.attachEvent('onpropertychange', handlePropertyChange);
3583}
3584
3585/**
3586 * (For IE <=9) Removes the event listeners from the currently-tracked element,
3587 * if any exists.
3588 */
3589function stopWatchingForValueChange() {
3590 if (!activeElement) {
3591 return;
3592 }
3593 activeElement.detachEvent('onpropertychange', handlePropertyChange);
3594 activeElement = null;
3595 activeElementInst = null;
3596}
3597
3598/**
3599 * (For IE <=9) Handles a propertychange event, sending a `change` event if
3600 * the value of the active element has changed.
3601 */
3602function handlePropertyChange(nativeEvent) {
3603 if (nativeEvent.propertyName !== 'value') {
3604 return;
3605 }
3606 if (getInstIfValueChanged(activeElementInst)) {
3607 manualDispatchChangeEvent(nativeEvent);
3608 }
3609}
3610
3611function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
3612 if (topLevelType === TOP_FOCUS) {
3613 // In IE9, propertychange fires for most input events but is buggy and
3614 // doesn't fire when text is deleted, but conveniently, selectionchange
3615 // appears to fire in all of the remaining cases so we catch those and
3616 // forward the event if the value has changed
3617 // In either case, we don't want to call the event handler if the value
3618 // is changed from JS so we redefine a setter for `.value` that updates
3619 // our activeElementValue variable, allowing us to ignore those changes
3620 //
3621 // stopWatching() should be a noop here but we call it just in case we
3622 // missed a blur event somehow.
3623 stopWatchingForValueChange();
3624 startWatchingForValueChange(target, targetInst);
3625 } else if (topLevelType === TOP_BLUR) {
3626 stopWatchingForValueChange();
3627 }
3628}
3629
3630// For IE8 and IE9.
3631function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
3632 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
3633 // On the selectionchange event, the target is just document which isn't
3634 // helpful for us so just check activeElement instead.
3635 //
3636 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
3637 // propertychange on the first input event after setting `value` from a
3638 // script and fires only keydown, keypress, keyup. Catching keyup usually
3639 // gets it and catching keydown lets us fire an event for the first
3640 // keystroke if user does a key repeat (it'll be a little delayed: right
3641 // before the second keystroke). Other input methods (e.g., paste) seem to
3642 // fire selectionchange normally.
3643 return getInstIfValueChanged(activeElementInst);
3644 }
3645}
3646
3647/**
3648 * SECTION: handle `click` event
3649 */
3650function shouldUseClickEvent(elem) {
3651 // Use the `click` event to detect changes to checkbox and radio inputs.
3652 // This approach works across all browsers, whereas `change` does not fire
3653 // until `blur` in IE8.
3654 var nodeName = elem.nodeName;
3655 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
3656}
3657
3658function getTargetInstForClickEvent(topLevelType, targetInst) {
3659 if (topLevelType === TOP_CLICK) {
3660 return getInstIfValueChanged(targetInst);
3661 }
3662}
3663
3664function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
3665 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
3666 return getInstIfValueChanged(targetInst);
3667 }
3668}
3669
3670function handleControlledInputBlur(node) {
3671 var state = node._wrapperState;
3672
3673 if (!state || !state.controlled || node.type !== 'number') {
3674 return;
3675 }
3676
3677 if (!disableInputAttributeSyncing) {
3678 // If controlled, assign the value attribute to the current value on blur
3679 setDefaultValue(node, 'number', node.value);
3680 }
3681}
3682
3683/**
3684 * This plugin creates an `onChange` event that normalizes change events
3685 * across form elements. This event fires at a time when it's possible to
3686 * change the element's value without seeing a flicker.
3687 *
3688 * Supported elements are:
3689 * - input (see `isTextInputElement`)
3690 * - textarea
3691 * - select
3692 */
3693var ChangeEventPlugin = {
3694 eventTypes: eventTypes$1,
3695
3696 _isInputEventSupported: isInputEventSupported,
3697
3698 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3699 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
3700
3701 var getTargetInstFunc = void 0,
3702 handleEventFunc = void 0;
3703 if (shouldUseChangeEvent(targetNode)) {
3704 getTargetInstFunc = getTargetInstForChangeEvent;
3705 } else if (isTextInputElement(targetNode)) {
3706 if (isInputEventSupported) {
3707 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
3708 } else {
3709 getTargetInstFunc = getTargetInstForInputEventPolyfill;
3710 handleEventFunc = handleEventsForInputEventPolyfill;
3711 }
3712 } else if (shouldUseClickEvent(targetNode)) {
3713 getTargetInstFunc = getTargetInstForClickEvent;
3714 }
3715
3716 if (getTargetInstFunc) {
3717 var inst = getTargetInstFunc(topLevelType, targetInst);
3718 if (inst) {
3719 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
3720 return event;
3721 }
3722 }
3723
3724 if (handleEventFunc) {
3725 handleEventFunc(topLevelType, targetNode, targetInst);
3726 }
3727
3728 // When blurring, set the value attribute for number inputs
3729 if (topLevelType === TOP_BLUR) {
3730 handleControlledInputBlur(targetNode);
3731 }
3732 }
3733};
3734
3735/**
3736 * Module that is injectable into `EventPluginHub`, that specifies a
3737 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
3738 * plugins, without having to package every one of them. This is better than
3739 * having plugins be ordered in the same order that they are injected because
3740 * that ordering would be influenced by the packaging order.
3741 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
3742 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
3743 */
3744var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
3745
3746var SyntheticUIEvent = SyntheticEvent.extend({
3747 view: null,
3748 detail: null
3749});
3750
3751var modifierKeyToProp = {
3752 Alt: 'altKey',
3753 Control: 'ctrlKey',
3754 Meta: 'metaKey',
3755 Shift: 'shiftKey'
3756};
3757
3758// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
3759// getModifierState. If getModifierState is not supported, we map it to a set of
3760// modifier keys exposed by the event. In this case, Lock-keys are not supported.
3761/**
3762 * Translation from modifier key to the associated property in the event.
3763 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
3764 */
3765
3766function modifierStateGetter(keyArg) {
3767 var syntheticEvent = this;
3768 var nativeEvent = syntheticEvent.nativeEvent;
3769 if (nativeEvent.getModifierState) {
3770 return nativeEvent.getModifierState(keyArg);
3771 }
3772 var keyProp = modifierKeyToProp[keyArg];
3773 return keyProp ? !!nativeEvent[keyProp] : false;
3774}
3775
3776function getEventModifierState(nativeEvent) {
3777 return modifierStateGetter;
3778}
3779
3780var previousScreenX = 0;
3781var previousScreenY = 0;
3782// Use flags to signal movementX/Y has already been set
3783var isMovementXSet = false;
3784var isMovementYSet = false;
3785
3786/**
3787 * @interface MouseEvent
3788 * @see http://www.w3.org/TR/DOM-Level-3-Events/
3789 */
3790var SyntheticMouseEvent = SyntheticUIEvent.extend({
3791 screenX: null,
3792 screenY: null,
3793 clientX: null,
3794 clientY: null,
3795 pageX: null,
3796 pageY: null,
3797 ctrlKey: null,
3798 shiftKey: null,
3799 altKey: null,
3800 metaKey: null,
3801 getModifierState: getEventModifierState,
3802 button: null,
3803 buttons: null,
3804 relatedTarget: function (event) {
3805 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
3806 },
3807 movementX: function (event) {
3808 if ('movementX' in event) {
3809 return event.movementX;
3810 }
3811
3812 var screenX = previousScreenX;
3813 previousScreenX = event.screenX;
3814
3815 if (!isMovementXSet) {
3816 isMovementXSet = true;
3817 return 0;
3818 }
3819
3820 return event.type === 'mousemove' ? event.screenX - screenX : 0;
3821 },
3822 movementY: function (event) {
3823 if ('movementY' in event) {
3824 return event.movementY;
3825 }
3826
3827 var screenY = previousScreenY;
3828 previousScreenY = event.screenY;
3829
3830 if (!isMovementYSet) {
3831 isMovementYSet = true;
3832 return 0;
3833 }
3834
3835 return event.type === 'mousemove' ? event.screenY - screenY : 0;
3836 }
3837});
3838
3839/**
3840 * @interface PointerEvent
3841 * @see http://www.w3.org/TR/pointerevents/
3842 */
3843var SyntheticPointerEvent = SyntheticMouseEvent.extend({
3844 pointerId: null,
3845 width: null,
3846 height: null,
3847 pressure: null,
3848 tangentialPressure: null,
3849 tiltX: null,
3850 tiltY: null,
3851 twist: null,
3852 pointerType: null,
3853 isPrimary: null
3854});
3855
3856var eventTypes$2 = {
3857 mouseEnter: {
3858 registrationName: 'onMouseEnter',
3859 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3860 },
3861 mouseLeave: {
3862 registrationName: 'onMouseLeave',
3863 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
3864 },
3865 pointerEnter: {
3866 registrationName: 'onPointerEnter',
3867 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3868 },
3869 pointerLeave: {
3870 registrationName: 'onPointerLeave',
3871 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
3872 }
3873};
3874
3875var EnterLeaveEventPlugin = {
3876 eventTypes: eventTypes$2,
3877
3878 /**
3879 * For almost every interaction we care about, there will be both a top-level
3880 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
3881 * we do not extract duplicate events. However, moving the mouse into the
3882 * browser from outside will not fire a `mouseout` event. In this case, we use
3883 * the `mouseover` top-level event.
3884 */
3885 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
3886 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
3887 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
3888
3889 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
3890 return null;
3891 }
3892
3893 if (!isOutEvent && !isOverEvent) {
3894 // Must not be a mouse or pointer in or out - ignoring.
3895 return null;
3896 }
3897
3898 var win = void 0;
3899 if (nativeEventTarget.window === nativeEventTarget) {
3900 // `nativeEventTarget` is probably a window object.
3901 win = nativeEventTarget;
3902 } else {
3903 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
3904 var doc = nativeEventTarget.ownerDocument;
3905 if (doc) {
3906 win = doc.defaultView || doc.parentWindow;
3907 } else {
3908 win = window;
3909 }
3910 }
3911
3912 var from = void 0;
3913 var to = void 0;
3914 if (isOutEvent) {
3915 from = targetInst;
3916 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
3917 to = related ? getClosestInstanceFromNode(related) : null;
3918 } else {
3919 // Moving to a node from outside the window.
3920 from = null;
3921 to = targetInst;
3922 }
3923
3924 if (from === to) {
3925 // Nothing pertains to our managed components.
3926 return null;
3927 }
3928
3929 var eventInterface = void 0,
3930 leaveEventType = void 0,
3931 enterEventType = void 0,
3932 eventTypePrefix = void 0;
3933
3934 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
3935 eventInterface = SyntheticMouseEvent;
3936 leaveEventType = eventTypes$2.mouseLeave;
3937 enterEventType = eventTypes$2.mouseEnter;
3938 eventTypePrefix = 'mouse';
3939 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
3940 eventInterface = SyntheticPointerEvent;
3941 leaveEventType = eventTypes$2.pointerLeave;
3942 enterEventType = eventTypes$2.pointerEnter;
3943 eventTypePrefix = 'pointer';
3944 }
3945
3946 var fromNode = from == null ? win : getNodeFromInstance$1(from);
3947 var toNode = to == null ? win : getNodeFromInstance$1(to);
3948
3949 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
3950 leave.type = eventTypePrefix + 'leave';
3951 leave.target = fromNode;
3952 leave.relatedTarget = toNode;
3953
3954 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
3955 enter.type = eventTypePrefix + 'enter';
3956 enter.target = toNode;
3957 enter.relatedTarget = fromNode;
3958
3959 accumulateEnterLeaveDispatches(leave, enter, from, to);
3960
3961 return [leave, enter];
3962 }
3963};
3964
3965/**
3966 * inlined Object.is polyfill to avoid requiring consumers ship their own
3967 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3968 */
3969function is(x, y) {
3970 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
3971 ;
3972}
3973
3974var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
3975
3976/**
3977 * Performs equality by iterating through keys on an object and returning false
3978 * when any key has values which are not strictly equal between the arguments.
3979 * Returns true when the values of all keys are strictly equal.
3980 */
3981function shallowEqual(objA, objB) {
3982 if (is(objA, objB)) {
3983 return true;
3984 }
3985
3986 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3987 return false;
3988 }
3989
3990 var keysA = Object.keys(objA);
3991 var keysB = Object.keys(objB);
3992
3993 if (keysA.length !== keysB.length) {
3994 return false;
3995 }
3996
3997 // Test for A's keys different from B.
3998 for (var i = 0; i < keysA.length; i++) {
3999 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
4000 return false;
4001 }
4002 }
4003
4004 return true;
4005}
4006
4007/**
4008 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4009 * instance (key) and the internal representation (value). This allows public
4010 * methods to accept the user facing instance as an argument and map them back
4011 * to internal methods.
4012 *
4013 * Note that this module is currently shared and assumed to be stateless.
4014 * If this becomes an actual Map, that will break.
4015 */
4016
4017/**
4018 * This API should be called `delete` but we'd have to make sure to always
4019 * transform these to strings for IE support. When this transform is fully
4020 * supported we can rename it.
4021 */
4022
4023
4024function get(key) {
4025 return key._reactInternalFiber;
4026}
4027
4028function has(key) {
4029 return key._reactInternalFiber !== undefined;
4030}
4031
4032function set(key, value) {
4033 key._reactInternalFiber = value;
4034}
4035
4036// Don't change these two values. They're used by React Dev Tools.
4037var NoEffect = /* */0;
4038var PerformedWork = /* */1;
4039
4040// You can change the rest (and add more).
4041var Placement = /* */2;
4042var Update = /* */4;
4043var PlacementAndUpdate = /* */6;
4044var Deletion = /* */8;
4045var ContentReset = /* */16;
4046var Callback = /* */32;
4047var DidCapture = /* */64;
4048var Ref = /* */128;
4049var Snapshot = /* */256;
4050var Passive = /* */512;
4051
4052// Passive & Update & Callback & Ref & Snapshot
4053var LifecycleEffectMask = /* */932;
4054
4055// Union of all host effects
4056var HostEffectMask = /* */1023;
4057
4058var Incomplete = /* */1024;
4059var ShouldCapture = /* */2048;
4060
4061var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
4062
4063var MOUNTING = 1;
4064var MOUNTED = 2;
4065var UNMOUNTED = 3;
4066
4067function isFiberMountedImpl(fiber) {
4068 var node = fiber;
4069 if (!fiber.alternate) {
4070 // If there is no alternate, this might be a new tree that isn't inserted
4071 // yet. If it is, then it will have a pending insertion effect on it.
4072 if ((node.effectTag & Placement) !== NoEffect) {
4073 return MOUNTING;
4074 }
4075 while (node.return) {
4076 node = node.return;
4077 if ((node.effectTag & Placement) !== NoEffect) {
4078 return MOUNTING;
4079 }
4080 }
4081 } else {
4082 while (node.return) {
4083 node = node.return;
4084 }
4085 }
4086 if (node.tag === HostRoot) {
4087 // TODO: Check if this was a nested HostRoot when used with
4088 // renderContainerIntoSubtree.
4089 return MOUNTED;
4090 }
4091 // If we didn't hit the root, that means that we're in an disconnected tree
4092 // that has been unmounted.
4093 return UNMOUNTED;
4094}
4095
4096function isFiberMounted(fiber) {
4097 return isFiberMountedImpl(fiber) === MOUNTED;
4098}
4099
4100function isMounted(component) {
4101 {
4102 var owner = ReactCurrentOwner$1.current;
4103 if (owner !== null && owner.tag === ClassComponent) {
4104 var ownerFiber = owner;
4105 var instance = ownerFiber.stateNode;
4106 !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;
4107 instance._warnedAboutRefsInRender = true;
4108 }
4109 }
4110
4111 var fiber = get(component);
4112 if (!fiber) {
4113 return false;
4114 }
4115 return isFiberMountedImpl(fiber) === MOUNTED;
4116}
4117
4118function assertIsMounted(fiber) {
4119 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4120}
4121
4122function findCurrentFiberUsingSlowPath(fiber) {
4123 var alternate = fiber.alternate;
4124 if (!alternate) {
4125 // If there is no alternate, then we only need to check if it is mounted.
4126 var state = isFiberMountedImpl(fiber);
4127 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4128 if (state === MOUNTING) {
4129 return null;
4130 }
4131 return fiber;
4132 }
4133 // If we have two possible branches, we'll walk backwards up to the root
4134 // to see what path the root points to. On the way we may hit one of the
4135 // special cases and we'll deal with them.
4136 var a = fiber;
4137 var b = alternate;
4138 while (true) {
4139 var parentA = a.return;
4140 var parentB = parentA ? parentA.alternate : null;
4141 if (!parentA || !parentB) {
4142 // We're at the root.
4143 break;
4144 }
4145
4146 // If both copies of the parent fiber point to the same child, we can
4147 // assume that the child is current. This happens when we bailout on low
4148 // priority: the bailed out fiber's child reuses the current child.
4149 if (parentA.child === parentB.child) {
4150 var child = parentA.child;
4151 while (child) {
4152 if (child === a) {
4153 // We've determined that A is the current branch.
4154 assertIsMounted(parentA);
4155 return fiber;
4156 }
4157 if (child === b) {
4158 // We've determined that B is the current branch.
4159 assertIsMounted(parentA);
4160 return alternate;
4161 }
4162 child = child.sibling;
4163 }
4164 // We should never have an alternate for any mounting node. So the only
4165 // way this could possibly happen is if this was unmounted, if at all.
4166 invariant(false, 'Unable to find node on an unmounted component.');
4167 }
4168
4169 if (a.return !== b.return) {
4170 // The return pointer of A and the return pointer of B point to different
4171 // fibers. We assume that return pointers never criss-cross, so A must
4172 // belong to the child set of A.return, and B must belong to the child
4173 // set of B.return.
4174 a = parentA;
4175 b = parentB;
4176 } else {
4177 // The return pointers point to the same fiber. We'll have to use the
4178 // default, slow path: scan the child sets of each parent alternate to see
4179 // which child belongs to which set.
4180 //
4181 // Search parent A's child set
4182 var didFindChild = false;
4183 var _child = parentA.child;
4184 while (_child) {
4185 if (_child === a) {
4186 didFindChild = true;
4187 a = parentA;
4188 b = parentB;
4189 break;
4190 }
4191 if (_child === b) {
4192 didFindChild = true;
4193 b = parentA;
4194 a = parentB;
4195 break;
4196 }
4197 _child = _child.sibling;
4198 }
4199 if (!didFindChild) {
4200 // Search parent B's child set
4201 _child = parentB.child;
4202 while (_child) {
4203 if (_child === a) {
4204 didFindChild = true;
4205 a = parentB;
4206 b = parentA;
4207 break;
4208 }
4209 if (_child === b) {
4210 didFindChild = true;
4211 b = parentB;
4212 a = parentA;
4213 break;
4214 }
4215 _child = _child.sibling;
4216 }
4217 !didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;
4218 }
4219 }
4220
4221 !(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;
4222 }
4223 // If the root is not a host container, we're in a disconnected tree. I.e.
4224 // unmounted.
4225 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
4226 if (a.stateNode.current === a) {
4227 // We've determined that A is the current branch.
4228 return fiber;
4229 }
4230 // Otherwise B has to be current branch.
4231 return alternate;
4232}
4233
4234function findCurrentHostFiber(parent) {
4235 var currentParent = findCurrentFiberUsingSlowPath(parent);
4236 if (!currentParent) {
4237 return null;
4238 }
4239
4240 // Next we'll drill down this component to find the first HostComponent/Text.
4241 var node = currentParent;
4242 while (true) {
4243 if (node.tag === HostComponent || node.tag === HostText) {
4244 return node;
4245 } else if (node.child) {
4246 node.child.return = node;
4247 node = node.child;
4248 continue;
4249 }
4250 if (node === currentParent) {
4251 return null;
4252 }
4253 while (!node.sibling) {
4254 if (!node.return || node.return === currentParent) {
4255 return null;
4256 }
4257 node = node.return;
4258 }
4259 node.sibling.return = node.return;
4260 node = node.sibling;
4261 }
4262 // Flow needs the return null here, but ESLint complains about it.
4263 // eslint-disable-next-line no-unreachable
4264 return null;
4265}
4266
4267function findCurrentHostFiberWithNoPortals(parent) {
4268 var currentParent = findCurrentFiberUsingSlowPath(parent);
4269 if (!currentParent) {
4270 return null;
4271 }
4272
4273 // Next we'll drill down this component to find the first HostComponent/Text.
4274 var node = currentParent;
4275 while (true) {
4276 if (node.tag === HostComponent || node.tag === HostText) {
4277 return node;
4278 } else if (node.child && node.tag !== HostPortal) {
4279 node.child.return = node;
4280 node = node.child;
4281 continue;
4282 }
4283 if (node === currentParent) {
4284 return null;
4285 }
4286 while (!node.sibling) {
4287 if (!node.return || node.return === currentParent) {
4288 return null;
4289 }
4290 node = node.return;
4291 }
4292 node.sibling.return = node.return;
4293 node = node.sibling;
4294 }
4295 // Flow needs the return null here, but ESLint complains about it.
4296 // eslint-disable-next-line no-unreachable
4297 return null;
4298}
4299
4300function addEventBubbleListener(element, eventType, listener) {
4301 element.addEventListener(eventType, listener, false);
4302}
4303
4304function addEventCaptureListener(element, eventType, listener) {
4305 element.addEventListener(eventType, listener, true);
4306}
4307
4308/**
4309 * @interface Event
4310 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
4311 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
4312 */
4313var SyntheticAnimationEvent = SyntheticEvent.extend({
4314 animationName: null,
4315 elapsedTime: null,
4316 pseudoElement: null
4317});
4318
4319/**
4320 * @interface Event
4321 * @see http://www.w3.org/TR/clipboard-apis/
4322 */
4323var SyntheticClipboardEvent = SyntheticEvent.extend({
4324 clipboardData: function (event) {
4325 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
4326 }
4327});
4328
4329/**
4330 * @interface FocusEvent
4331 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4332 */
4333var SyntheticFocusEvent = SyntheticUIEvent.extend({
4334 relatedTarget: null
4335});
4336
4337/**
4338 * `charCode` represents the actual "character code" and is safe to use with
4339 * `String.fromCharCode`. As such, only keys that correspond to printable
4340 * characters produce a valid `charCode`, the only exception to this is Enter.
4341 * The Tab-key is considered non-printable and does not have a `charCode`,
4342 * presumably because it does not produce a tab-character in browsers.
4343 *
4344 * @param {object} nativeEvent Native browser event.
4345 * @return {number} Normalized `charCode` property.
4346 */
4347function getEventCharCode(nativeEvent) {
4348 var charCode = void 0;
4349 var keyCode = nativeEvent.keyCode;
4350
4351 if ('charCode' in nativeEvent) {
4352 charCode = nativeEvent.charCode;
4353
4354 // FF does not set `charCode` for the Enter-key, check against `keyCode`.
4355 if (charCode === 0 && keyCode === 13) {
4356 charCode = 13;
4357 }
4358 } else {
4359 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
4360 charCode = keyCode;
4361 }
4362
4363 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
4364 // report Enter as charCode 10 when ctrl is pressed.
4365 if (charCode === 10) {
4366 charCode = 13;
4367 }
4368
4369 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
4370 // Must not discard the (non-)printable Enter-key.
4371 if (charCode >= 32 || charCode === 13) {
4372 return charCode;
4373 }
4374
4375 return 0;
4376}
4377
4378/**
4379 * Normalization of deprecated HTML5 `key` values
4380 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4381 */
4382var normalizeKey = {
4383 Esc: 'Escape',
4384 Spacebar: ' ',
4385 Left: 'ArrowLeft',
4386 Up: 'ArrowUp',
4387 Right: 'ArrowRight',
4388 Down: 'ArrowDown',
4389 Del: 'Delete',
4390 Win: 'OS',
4391 Menu: 'ContextMenu',
4392 Apps: 'ContextMenu',
4393 Scroll: 'ScrollLock',
4394 MozPrintableKey: 'Unidentified'
4395};
4396
4397/**
4398 * Translation from legacy `keyCode` to HTML5 `key`
4399 * Only special keys supported, all others depend on keyboard layout or browser
4400 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
4401 */
4402var translateToKey = {
4403 '8': 'Backspace',
4404 '9': 'Tab',
4405 '12': 'Clear',
4406 '13': 'Enter',
4407 '16': 'Shift',
4408 '17': 'Control',
4409 '18': 'Alt',
4410 '19': 'Pause',
4411 '20': 'CapsLock',
4412 '27': 'Escape',
4413 '32': ' ',
4414 '33': 'PageUp',
4415 '34': 'PageDown',
4416 '35': 'End',
4417 '36': 'Home',
4418 '37': 'ArrowLeft',
4419 '38': 'ArrowUp',
4420 '39': 'ArrowRight',
4421 '40': 'ArrowDown',
4422 '45': 'Insert',
4423 '46': 'Delete',
4424 '112': 'F1',
4425 '113': 'F2',
4426 '114': 'F3',
4427 '115': 'F4',
4428 '116': 'F5',
4429 '117': 'F6',
4430 '118': 'F7',
4431 '119': 'F8',
4432 '120': 'F9',
4433 '121': 'F10',
4434 '122': 'F11',
4435 '123': 'F12',
4436 '144': 'NumLock',
4437 '145': 'ScrollLock',
4438 '224': 'Meta'
4439};
4440
4441/**
4442 * @param {object} nativeEvent Native browser event.
4443 * @return {string} Normalized `key` property.
4444 */
4445function getEventKey(nativeEvent) {
4446 if (nativeEvent.key) {
4447 // Normalize inconsistent values reported by browsers due to
4448 // implementations of a working draft specification.
4449
4450 // FireFox implements `key` but returns `MozPrintableKey` for all
4451 // printable characters (normalized to `Unidentified`), ignore it.
4452 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
4453 if (key !== 'Unidentified') {
4454 return key;
4455 }
4456 }
4457
4458 // Browser does not implement `key`, polyfill as much of it as we can.
4459 if (nativeEvent.type === 'keypress') {
4460 var charCode = getEventCharCode(nativeEvent);
4461
4462 // The enter-key is technically both printable and non-printable and can
4463 // thus be captured by `keypress`, no other non-printable key should.
4464 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
4465 }
4466 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
4467 // While user keyboard layout determines the actual meaning of each
4468 // `keyCode` value, almost all function keys have a universal value.
4469 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
4470 }
4471 return '';
4472}
4473
4474/**
4475 * @interface KeyboardEvent
4476 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4477 */
4478var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
4479 key: getEventKey,
4480 location: null,
4481 ctrlKey: null,
4482 shiftKey: null,
4483 altKey: null,
4484 metaKey: null,
4485 repeat: null,
4486 locale: null,
4487 getModifierState: getEventModifierState,
4488 // Legacy Interface
4489 charCode: function (event) {
4490 // `charCode` is the result of a KeyPress event and represents the value of
4491 // the actual printable character.
4492
4493 // KeyPress is deprecated, but its replacement is not yet final and not
4494 // implemented in any major browser. Only KeyPress has charCode.
4495 if (event.type === 'keypress') {
4496 return getEventCharCode(event);
4497 }
4498 return 0;
4499 },
4500 keyCode: function (event) {
4501 // `keyCode` is the result of a KeyDown/Up event and represents the value of
4502 // physical keyboard key.
4503
4504 // The actual meaning of the value depends on the users' keyboard layout
4505 // which cannot be detected. Assuming that it is a US keyboard layout
4506 // provides a surprisingly accurate mapping for US and European users.
4507 // Due to this, it is left to the user to implement at this time.
4508 if (event.type === 'keydown' || event.type === 'keyup') {
4509 return event.keyCode;
4510 }
4511 return 0;
4512 },
4513 which: function (event) {
4514 // `which` is an alias for either `keyCode` or `charCode` depending on the
4515 // type of the event.
4516 if (event.type === 'keypress') {
4517 return getEventCharCode(event);
4518 }
4519 if (event.type === 'keydown' || event.type === 'keyup') {
4520 return event.keyCode;
4521 }
4522 return 0;
4523 }
4524});
4525
4526/**
4527 * @interface DragEvent
4528 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4529 */
4530var SyntheticDragEvent = SyntheticMouseEvent.extend({
4531 dataTransfer: null
4532});
4533
4534/**
4535 * @interface TouchEvent
4536 * @see http://www.w3.org/TR/touch-events/
4537 */
4538var SyntheticTouchEvent = SyntheticUIEvent.extend({
4539 touches: null,
4540 targetTouches: null,
4541 changedTouches: null,
4542 altKey: null,
4543 metaKey: null,
4544 ctrlKey: null,
4545 shiftKey: null,
4546 getModifierState: getEventModifierState
4547});
4548
4549/**
4550 * @interface Event
4551 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
4552 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
4553 */
4554var SyntheticTransitionEvent = SyntheticEvent.extend({
4555 propertyName: null,
4556 elapsedTime: null,
4557 pseudoElement: null
4558});
4559
4560/**
4561 * @interface WheelEvent
4562 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4563 */
4564var SyntheticWheelEvent = SyntheticMouseEvent.extend({
4565 deltaX: function (event) {
4566 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
4567 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
4568 },
4569 deltaY: function (event) {
4570 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
4571 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
4572 'wheelDelta' in event ? -event.wheelDelta : 0;
4573 },
4574
4575 deltaZ: null,
4576
4577 // Browsers without "deltaMode" is reporting in raw wheel delta where one
4578 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
4579 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
4580 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
4581 deltaMode: null
4582});
4583
4584/**
4585 * Turns
4586 * ['abort', ...]
4587 * into
4588 * eventTypes = {
4589 * 'abort': {
4590 * phasedRegistrationNames: {
4591 * bubbled: 'onAbort',
4592 * captured: 'onAbortCapture',
4593 * },
4594 * dependencies: [TOP_ABORT],
4595 * },
4596 * ...
4597 * };
4598 * topLevelEventsToDispatchConfig = new Map([
4599 * [TOP_ABORT, { sameConfig }],
4600 * ]);
4601 */
4602
4603var interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_AUX_CLICK, 'auxClick'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']];
4604var nonInteractiveEventTypeNames = [[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_DRAG, 'drag'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_LOAD_START, 'loadStart'], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_PLAYING, 'playing'], [TOP_POINTER_MOVE, 'pointerMove'], [TOP_POINTER_OUT, 'pointerOut'], [TOP_POINTER_OVER, 'pointerOver'], [TOP_PROGRESS, 'progress'], [TOP_SCROLL, 'scroll'], [TOP_SEEKING, 'seeking'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']];
4605
4606var eventTypes$4 = {};
4607var topLevelEventsToDispatchConfig = {};
4608
4609function addEventTypeNameToConfig(_ref, isInteractive) {
4610 var topEvent = _ref[0],
4611 event = _ref[1];
4612
4613 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
4614 var onEvent = 'on' + capitalizedEvent;
4615
4616 var type = {
4617 phasedRegistrationNames: {
4618 bubbled: onEvent,
4619 captured: onEvent + 'Capture'
4620 },
4621 dependencies: [topEvent],
4622 isInteractive: isInteractive
4623 };
4624 eventTypes$4[event] = type;
4625 topLevelEventsToDispatchConfig[topEvent] = type;
4626}
4627
4628interactiveEventTypeNames.forEach(function (eventTuple) {
4629 addEventTypeNameToConfig(eventTuple, true);
4630});
4631nonInteractiveEventTypeNames.forEach(function (eventTuple) {
4632 addEventTypeNameToConfig(eventTuple, false);
4633});
4634
4635// Only used in DEV for exhaustiveness validation.
4636var 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];
4637
4638var SimpleEventPlugin = {
4639 eventTypes: eventTypes$4,
4640
4641 isInteractiveTopLevelEventType: function (topLevelType) {
4642 var config = topLevelEventsToDispatchConfig[topLevelType];
4643 return config !== undefined && config.isInteractive === true;
4644 },
4645
4646
4647 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
4648 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
4649 if (!dispatchConfig) {
4650 return null;
4651 }
4652 var EventConstructor = void 0;
4653 switch (topLevelType) {
4654 case TOP_KEY_PRESS:
4655 // Firefox creates a keypress event for function keys too. This removes
4656 // the unwanted keypress events. Enter is however both printable and
4657 // non-printable. One would expect Tab to be as well (but it isn't).
4658 if (getEventCharCode(nativeEvent) === 0) {
4659 return null;
4660 }
4661 /* falls through */
4662 case TOP_KEY_DOWN:
4663 case TOP_KEY_UP:
4664 EventConstructor = SyntheticKeyboardEvent;
4665 break;
4666 case TOP_BLUR:
4667 case TOP_FOCUS:
4668 EventConstructor = SyntheticFocusEvent;
4669 break;
4670 case TOP_CLICK:
4671 // Firefox creates a click event on right mouse clicks. This removes the
4672 // unwanted click events.
4673 if (nativeEvent.button === 2) {
4674 return null;
4675 }
4676 /* falls through */
4677 case TOP_AUX_CLICK:
4678 case TOP_DOUBLE_CLICK:
4679 case TOP_MOUSE_DOWN:
4680 case TOP_MOUSE_MOVE:
4681 case TOP_MOUSE_UP:
4682 // TODO: Disabled elements should not respond to mouse events
4683 /* falls through */
4684 case TOP_MOUSE_OUT:
4685 case TOP_MOUSE_OVER:
4686 case TOP_CONTEXT_MENU:
4687 EventConstructor = SyntheticMouseEvent;
4688 break;
4689 case TOP_DRAG:
4690 case TOP_DRAG_END:
4691 case TOP_DRAG_ENTER:
4692 case TOP_DRAG_EXIT:
4693 case TOP_DRAG_LEAVE:
4694 case TOP_DRAG_OVER:
4695 case TOP_DRAG_START:
4696 case TOP_DROP:
4697 EventConstructor = SyntheticDragEvent;
4698 break;
4699 case TOP_TOUCH_CANCEL:
4700 case TOP_TOUCH_END:
4701 case TOP_TOUCH_MOVE:
4702 case TOP_TOUCH_START:
4703 EventConstructor = SyntheticTouchEvent;
4704 break;
4705 case TOP_ANIMATION_END:
4706 case TOP_ANIMATION_ITERATION:
4707 case TOP_ANIMATION_START:
4708 EventConstructor = SyntheticAnimationEvent;
4709 break;
4710 case TOP_TRANSITION_END:
4711 EventConstructor = SyntheticTransitionEvent;
4712 break;
4713 case TOP_SCROLL:
4714 EventConstructor = SyntheticUIEvent;
4715 break;
4716 case TOP_WHEEL:
4717 EventConstructor = SyntheticWheelEvent;
4718 break;
4719 case TOP_COPY:
4720 case TOP_CUT:
4721 case TOP_PASTE:
4722 EventConstructor = SyntheticClipboardEvent;
4723 break;
4724 case TOP_GOT_POINTER_CAPTURE:
4725 case TOP_LOST_POINTER_CAPTURE:
4726 case TOP_POINTER_CANCEL:
4727 case TOP_POINTER_DOWN:
4728 case TOP_POINTER_MOVE:
4729 case TOP_POINTER_OUT:
4730 case TOP_POINTER_OVER:
4731 case TOP_POINTER_UP:
4732 EventConstructor = SyntheticPointerEvent;
4733 break;
4734 default:
4735 {
4736 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
4737 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
4738 }
4739 }
4740 // HTML Events
4741 // @see http://www.w3.org/TR/html5/index.html#events-0
4742 EventConstructor = SyntheticEvent;
4743 break;
4744 }
4745 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
4746 accumulateTwoPhaseDispatches(event);
4747 return event;
4748 }
4749};
4750
4751var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;
4752
4753
4754var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
4755var callbackBookkeepingPool = [];
4756
4757/**
4758 * Find the deepest React component completely containing the root of the
4759 * passed-in instance (for use when entire React trees are nested within each
4760 * other). If React trees are not nested, returns null.
4761 */
4762function findRootContainerNode(inst) {
4763 // TODO: It may be a good idea to cache this to prevent unnecessary DOM
4764 // traversal, but caching is difficult to do correctly without using a
4765 // mutation observer to listen for all DOM changes.
4766 while (inst.return) {
4767 inst = inst.return;
4768 }
4769 if (inst.tag !== HostRoot) {
4770 // This can happen if we're in a detached tree.
4771 return null;
4772 }
4773 return inst.stateNode.containerInfo;
4774}
4775
4776// Used to store ancestor hierarchy in top level callback
4777function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
4778 if (callbackBookkeepingPool.length) {
4779 var instance = callbackBookkeepingPool.pop();
4780 instance.topLevelType = topLevelType;
4781 instance.nativeEvent = nativeEvent;
4782 instance.targetInst = targetInst;
4783 return instance;
4784 }
4785 return {
4786 topLevelType: topLevelType,
4787 nativeEvent: nativeEvent,
4788 targetInst: targetInst,
4789 ancestors: []
4790 };
4791}
4792
4793function releaseTopLevelCallbackBookKeeping(instance) {
4794 instance.topLevelType = null;
4795 instance.nativeEvent = null;
4796 instance.targetInst = null;
4797 instance.ancestors.length = 0;
4798 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
4799 callbackBookkeepingPool.push(instance);
4800 }
4801}
4802
4803function handleTopLevel(bookKeeping) {
4804 var targetInst = bookKeeping.targetInst;
4805
4806 // Loop through the hierarchy, in case there's any nested components.
4807 // It's important that we build the array of ancestors before calling any
4808 // event handlers, because event handlers can modify the DOM, leading to
4809 // inconsistencies with ReactMount's node cache. See #1105.
4810 var ancestor = targetInst;
4811 do {
4812 if (!ancestor) {
4813 bookKeeping.ancestors.push(ancestor);
4814 break;
4815 }
4816 var root = findRootContainerNode(ancestor);
4817 if (!root) {
4818 break;
4819 }
4820 bookKeeping.ancestors.push(ancestor);
4821 ancestor = getClosestInstanceFromNode(root);
4822 } while (ancestor);
4823
4824 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
4825 targetInst = bookKeeping.ancestors[i];
4826 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
4827 }
4828}
4829
4830// TODO: can we stop exporting these?
4831var _enabled = true;
4832
4833function setEnabled(enabled) {
4834 _enabled = !!enabled;
4835}
4836
4837function isEnabled() {
4838 return _enabled;
4839}
4840
4841/**
4842 * Traps top-level events by using event bubbling.
4843 *
4844 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4845 * @param {object} element Element on which to attach listener.
4846 * @return {?object} An object with a remove function which will forcefully
4847 * remove the listener.
4848 * @internal
4849 */
4850function trapBubbledEvent(topLevelType, element) {
4851 if (!element) {
4852 return null;
4853 }
4854 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4855
4856 addEventBubbleListener(element, getRawEventName(topLevelType),
4857 // Check if interactive and wrap in interactiveUpdates
4858 dispatch.bind(null, topLevelType));
4859}
4860
4861/**
4862 * Traps a top-level event by using event capturing.
4863 *
4864 * @param {number} topLevelType Number from `TopLevelEventTypes`.
4865 * @param {object} element Element on which to attach listener.
4866 * @return {?object} An object with a remove function which will forcefully
4867 * remove the listener.
4868 * @internal
4869 */
4870function trapCapturedEvent(topLevelType, element) {
4871 if (!element) {
4872 return null;
4873 }
4874 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
4875
4876 addEventCaptureListener(element, getRawEventName(topLevelType),
4877 // Check if interactive and wrap in interactiveUpdates
4878 dispatch.bind(null, topLevelType));
4879}
4880
4881function dispatchInteractiveEvent(topLevelType, nativeEvent) {
4882 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
4883}
4884
4885function dispatchEvent(topLevelType, nativeEvent) {
4886 if (!_enabled) {
4887 return;
4888 }
4889
4890 var nativeEventTarget = getEventTarget(nativeEvent);
4891 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
4892 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
4893 // If we get an event (ex: img onload) before committing that
4894 // component's mount, ignore it for now (that is, treat it as if it was an
4895 // event on a non-React tree). We might also consider queueing events and
4896 // dispatching them after the mount.
4897 targetInst = null;
4898 }
4899
4900 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
4901
4902 try {
4903 // Event queue being processed in the same cycle allows
4904 // `preventDefault`.
4905 batchedUpdates(handleTopLevel, bookKeeping);
4906 } finally {
4907 releaseTopLevelCallbackBookKeeping(bookKeeping);
4908 }
4909}
4910
4911/**
4912 * Summary of `ReactBrowserEventEmitter` event handling:
4913 *
4914 * - Top-level delegation is used to trap most native browser events. This
4915 * may only occur in the main thread and is the responsibility of
4916 * ReactDOMEventListener, which is injected and can therefore support
4917 * pluggable event sources. This is the only work that occurs in the main
4918 * thread.
4919 *
4920 * - We normalize and de-duplicate events to account for browser quirks. This
4921 * may be done in the worker thread.
4922 *
4923 * - Forward these native events (with the associated top-level type used to
4924 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
4925 * to extract any synthetic events.
4926 *
4927 * - The `EventPluginHub` will then process each event by annotating them with
4928 * "dispatches", a sequence of listeners and IDs that care about that event.
4929 *
4930 * - The `EventPluginHub` then dispatches the events.
4931 *
4932 * Overview of React and the event system:
4933 *
4934 * +------------+ .
4935 * | DOM | .
4936 * +------------+ .
4937 * | .
4938 * v .
4939 * +------------+ .
4940 * | ReactEvent | .
4941 * | Listener | .
4942 * +------------+ . +-----------+
4943 * | . +--------+|SimpleEvent|
4944 * | . | |Plugin |
4945 * +-----|------+ . v +-----------+
4946 * | | | . +--------------+ +------------+
4947 * | +-----------.--->|EventPluginHub| | Event |
4948 * | | . | | +-----------+ | Propagators|
4949 * | ReactEvent | . | | |TapEvent | |------------|
4950 * | Emitter | . | |<---+|Plugin | |other plugin|
4951 * | | . | | +-----------+ | utilities |
4952 * | +-----------.--->| | +------------+
4953 * | | | . +--------------+
4954 * +-----|------+ . ^ +-----------+
4955 * | . | |Enter/Leave|
4956 * + . +-------+|Plugin |
4957 * +-------------+ . +-----------+
4958 * | application | .
4959 * |-------------| .
4960 * | | .
4961 * | | .
4962 * +-------------+ .
4963 * .
4964 * React Core . General Purpose Event Plugin System
4965 */
4966
4967var alreadyListeningTo = {};
4968var reactTopListenersCounter = 0;
4969
4970/**
4971 * To ensure no conflicts with other potential React instances on the page
4972 */
4973var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
4974
4975function getListeningForDocument(mountAt) {
4976 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
4977 // directly.
4978 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
4979 mountAt[topListenersIDKey] = reactTopListenersCounter++;
4980 alreadyListeningTo[mountAt[topListenersIDKey]] = {};
4981 }
4982 return alreadyListeningTo[mountAt[topListenersIDKey]];
4983}
4984
4985/**
4986 * We listen for bubbled touch events on the document object.
4987 *
4988 * Firefox v8.01 (and possibly others) exhibited strange behavior when
4989 * mounting `onmousemove` events at some node that was not the document
4990 * element. The symptoms were that if your mouse is not moving over something
4991 * contained within that mount point (for example on the background) the
4992 * top-level listeners for `onmousemove` won't be called. However, if you
4993 * register the `mousemove` on the document object, then it will of course
4994 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
4995 * top-level listeners to the document object only, at least for these
4996 * movement types of events and possibly all events.
4997 *
4998 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
4999 *
5000 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
5001 * they bubble to document.
5002 *
5003 * @param {string} registrationName Name of listener (e.g. `onClick`).
5004 * @param {object} mountAt Container where to mount the listener
5005 */
5006function listenTo(registrationName, mountAt) {
5007 var isListening = getListeningForDocument(mountAt);
5008 var dependencies = registrationNameDependencies[registrationName];
5009
5010 for (var i = 0; i < dependencies.length; i++) {
5011 var dependency = dependencies[i];
5012 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5013 switch (dependency) {
5014 case TOP_SCROLL:
5015 trapCapturedEvent(TOP_SCROLL, mountAt);
5016 break;
5017 case TOP_FOCUS:
5018 case TOP_BLUR:
5019 trapCapturedEvent(TOP_FOCUS, mountAt);
5020 trapCapturedEvent(TOP_BLUR, mountAt);
5021 // We set the flag for a single dependency later in this function,
5022 // but this ensures we mark both as attached rather than just one.
5023 isListening[TOP_BLUR] = true;
5024 isListening[TOP_FOCUS] = true;
5025 break;
5026 case TOP_CANCEL:
5027 case TOP_CLOSE:
5028 if (isEventSupported(getRawEventName(dependency))) {
5029 trapCapturedEvent(dependency, mountAt);
5030 }
5031 break;
5032 case TOP_INVALID:
5033 case TOP_SUBMIT:
5034 case TOP_RESET:
5035 // We listen to them on the target DOM elements.
5036 // Some of them bubble so we don't want them to fire twice.
5037 break;
5038 default:
5039 // By default, listen on the top level to all non-media events.
5040 // Media events don't bubble so adding the listener wouldn't do anything.
5041 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
5042 if (!isMediaEvent) {
5043 trapBubbledEvent(dependency, mountAt);
5044 }
5045 break;
5046 }
5047 isListening[dependency] = true;
5048 }
5049 }
5050}
5051
5052function isListeningToAllDependencies(registrationName, mountAt) {
5053 var isListening = getListeningForDocument(mountAt);
5054 var dependencies = registrationNameDependencies[registrationName];
5055 for (var i = 0; i < dependencies.length; i++) {
5056 var dependency = dependencies[i];
5057 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
5058 return false;
5059 }
5060 }
5061 return true;
5062}
5063
5064function getActiveElement(doc) {
5065 doc = doc || (typeof document !== 'undefined' ? document : undefined);
5066 if (typeof doc === 'undefined') {
5067 return null;
5068 }
5069 try {
5070 return doc.activeElement || doc.body;
5071 } catch (e) {
5072 return doc.body;
5073 }
5074}
5075
5076/**
5077 * Given any node return the first leaf node without children.
5078 *
5079 * @param {DOMElement|DOMTextNode} node
5080 * @return {DOMElement|DOMTextNode}
5081 */
5082function getLeafNode(node) {
5083 while (node && node.firstChild) {
5084 node = node.firstChild;
5085 }
5086 return node;
5087}
5088
5089/**
5090 * Get the next sibling within a container. This will walk up the
5091 * DOM if a node's siblings have been exhausted.
5092 *
5093 * @param {DOMElement|DOMTextNode} node
5094 * @return {?DOMElement|DOMTextNode}
5095 */
5096function getSiblingNode(node) {
5097 while (node) {
5098 if (node.nextSibling) {
5099 return node.nextSibling;
5100 }
5101 node = node.parentNode;
5102 }
5103}
5104
5105/**
5106 * Get object describing the nodes which contain characters at offset.
5107 *
5108 * @param {DOMElement|DOMTextNode} root
5109 * @param {number} offset
5110 * @return {?object}
5111 */
5112function getNodeForCharacterOffset(root, offset) {
5113 var node = getLeafNode(root);
5114 var nodeStart = 0;
5115 var nodeEnd = 0;
5116
5117 while (node) {
5118 if (node.nodeType === TEXT_NODE) {
5119 nodeEnd = nodeStart + node.textContent.length;
5120
5121 if (nodeStart <= offset && nodeEnd >= offset) {
5122 return {
5123 node: node,
5124 offset: offset - nodeStart
5125 };
5126 }
5127
5128 nodeStart = nodeEnd;
5129 }
5130
5131 node = getLeafNode(getSiblingNode(node));
5132 }
5133}
5134
5135/**
5136 * @param {DOMElement} outerNode
5137 * @return {?object}
5138 */
5139function getOffsets(outerNode) {
5140 var ownerDocument = outerNode.ownerDocument;
5141
5142 var win = ownerDocument && ownerDocument.defaultView || window;
5143 var selection = win.getSelection && win.getSelection();
5144
5145 if (!selection || selection.rangeCount === 0) {
5146 return null;
5147 }
5148
5149 var anchorNode = selection.anchorNode,
5150 anchorOffset = selection.anchorOffset,
5151 focusNode = selection.focusNode,
5152 focusOffset = selection.focusOffset;
5153
5154 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
5155 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
5156 // expose properties, triggering a "Permission denied error" if any of its
5157 // properties are accessed. The only seemingly possible way to avoid erroring
5158 // is to access a property that typically works for non-anonymous divs and
5159 // catch any error that may otherwise arise. See
5160 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
5161
5162 try {
5163 /* eslint-disable no-unused-expressions */
5164 anchorNode.nodeType;
5165 focusNode.nodeType;
5166 /* eslint-enable no-unused-expressions */
5167 } catch (e) {
5168 return null;
5169 }
5170
5171 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
5172}
5173
5174/**
5175 * Returns {start, end} where `start` is the character/codepoint index of
5176 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
5177 * `end` is the index of (focusNode, focusOffset).
5178 *
5179 * Returns null if you pass in garbage input but we should probably just crash.
5180 *
5181 * Exported only for testing.
5182 */
5183function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
5184 var length = 0;
5185 var start = -1;
5186 var end = -1;
5187 var indexWithinAnchor = 0;
5188 var indexWithinFocus = 0;
5189 var node = outerNode;
5190 var parentNode = null;
5191
5192 outer: while (true) {
5193 var next = null;
5194
5195 while (true) {
5196 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
5197 start = length + anchorOffset;
5198 }
5199 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
5200 end = length + focusOffset;
5201 }
5202
5203 if (node.nodeType === TEXT_NODE) {
5204 length += node.nodeValue.length;
5205 }
5206
5207 if ((next = node.firstChild) === null) {
5208 break;
5209 }
5210 // Moving from `node` to its first child `next`.
5211 parentNode = node;
5212 node = next;
5213 }
5214
5215 while (true) {
5216 if (node === outerNode) {
5217 // If `outerNode` has children, this is always the second time visiting
5218 // it. If it has no children, this is still the first loop, and the only
5219 // valid selection is anchorNode and focusNode both equal to this node
5220 // and both offsets 0, in which case we will have handled above.
5221 break outer;
5222 }
5223 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
5224 start = length;
5225 }
5226 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
5227 end = length;
5228 }
5229 if ((next = node.nextSibling) !== null) {
5230 break;
5231 }
5232 node = parentNode;
5233 parentNode = node.parentNode;
5234 }
5235
5236 // Moving from `node` to its next sibling `next`.
5237 node = next;
5238 }
5239
5240 if (start === -1 || end === -1) {
5241 // This should never happen. (Would happen if the anchor/focus nodes aren't
5242 // actually inside the passed-in node.)
5243 return null;
5244 }
5245
5246 return {
5247 start: start,
5248 end: end
5249 };
5250}
5251
5252/**
5253 * In modern non-IE browsers, we can support both forward and backward
5254 * selections.
5255 *
5256 * Note: IE10+ supports the Selection object, but it does not support
5257 * the `extend` method, which means that even in modern IE, it's not possible
5258 * to programmatically create a backward selection. Thus, for all IE
5259 * versions, we use the old IE API to create our selections.
5260 *
5261 * @param {DOMElement|DOMTextNode} node
5262 * @param {object} offsets
5263 */
5264function setOffsets(node, offsets) {
5265 var doc = node.ownerDocument || document;
5266 var win = doc && doc.defaultView || window;
5267
5268 // Edge fails with "Object expected" in some scenarios.
5269 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
5270 // fails when pasting 100+ items)
5271 if (!win.getSelection) {
5272 return;
5273 }
5274
5275 var selection = win.getSelection();
5276 var length = node.textContent.length;
5277 var start = Math.min(offsets.start, length);
5278 var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
5279
5280 // IE 11 uses modern selection, but doesn't support the extend method.
5281 // Flip backward selections, so we can set with a single range.
5282 if (!selection.extend && start > end) {
5283 var temp = end;
5284 end = start;
5285 start = temp;
5286 }
5287
5288 var startMarker = getNodeForCharacterOffset(node, start);
5289 var endMarker = getNodeForCharacterOffset(node, end);
5290
5291 if (startMarker && endMarker) {
5292 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
5293 return;
5294 }
5295 var range = doc.createRange();
5296 range.setStart(startMarker.node, startMarker.offset);
5297 selection.removeAllRanges();
5298
5299 if (start > end) {
5300 selection.addRange(range);
5301 selection.extend(endMarker.node, endMarker.offset);
5302 } else {
5303 range.setEnd(endMarker.node, endMarker.offset);
5304 selection.addRange(range);
5305 }
5306 }
5307}
5308
5309function isTextNode(node) {
5310 return node && node.nodeType === TEXT_NODE;
5311}
5312
5313function containsNode(outerNode, innerNode) {
5314 if (!outerNode || !innerNode) {
5315 return false;
5316 } else if (outerNode === innerNode) {
5317 return true;
5318 } else if (isTextNode(outerNode)) {
5319 return false;
5320 } else if (isTextNode(innerNode)) {
5321 return containsNode(outerNode, innerNode.parentNode);
5322 } else if ('contains' in outerNode) {
5323 return outerNode.contains(innerNode);
5324 } else if (outerNode.compareDocumentPosition) {
5325 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
5326 } else {
5327 return false;
5328 }
5329}
5330
5331function isInDocument(node) {
5332 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
5333}
5334
5335function getActiveElementDeep() {
5336 var win = window;
5337 var element = getActiveElement();
5338 while (element instanceof win.HTMLIFrameElement) {
5339 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
5340 // to throw, e.g. if it has a cross-origin src attribute
5341 try {
5342 win = element.contentDocument.defaultView;
5343 } catch (e) {
5344 return element;
5345 }
5346 element = getActiveElement(win.document);
5347 }
5348 return element;
5349}
5350
5351/**
5352 * @ReactInputSelection: React input selection module. Based on Selection.js,
5353 * but modified to be suitable for react and has a couple of bug fixes (doesn't
5354 * assume buttons have range selections allowed).
5355 * Input selection module for React.
5356 */
5357
5358/**
5359 * @hasSelectionCapabilities: we get the element types that support selection
5360 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
5361 * and `selectionEnd` rows.
5362 */
5363function hasSelectionCapabilities(elem) {
5364 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
5365 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
5366}
5367
5368function getSelectionInformation() {
5369 var focusedElem = getActiveElementDeep();
5370 return {
5371 focusedElem: focusedElem,
5372 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
5373 };
5374}
5375
5376/**
5377 * @restoreSelection: If any selection information was potentially lost,
5378 * restore it. This is useful when performing operations that could remove dom
5379 * nodes and place them back in, resulting in focus being lost.
5380 */
5381function restoreSelection(priorSelectionInformation) {
5382 var curFocusedElem = getActiveElementDeep();
5383 var priorFocusedElem = priorSelectionInformation.focusedElem;
5384 var priorSelectionRange = priorSelectionInformation.selectionRange;
5385 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
5386 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
5387 setSelection(priorFocusedElem, priorSelectionRange);
5388 }
5389
5390 // Focusing a node can change the scroll position, which is undesirable
5391 var ancestors = [];
5392 var ancestor = priorFocusedElem;
5393 while (ancestor = ancestor.parentNode) {
5394 if (ancestor.nodeType === ELEMENT_NODE) {
5395 ancestors.push({
5396 element: ancestor,
5397 left: ancestor.scrollLeft,
5398 top: ancestor.scrollTop
5399 });
5400 }
5401 }
5402
5403 if (typeof priorFocusedElem.focus === 'function') {
5404 priorFocusedElem.focus();
5405 }
5406
5407 for (var i = 0; i < ancestors.length; i++) {
5408 var info = ancestors[i];
5409 info.element.scrollLeft = info.left;
5410 info.element.scrollTop = info.top;
5411 }
5412 }
5413}
5414
5415/**
5416 * @getSelection: Gets the selection bounds of a focused textarea, input or
5417 * contentEditable node.
5418 * -@input: Look up selection bounds of this input
5419 * -@return {start: selectionStart, end: selectionEnd}
5420 */
5421function getSelection$1(input) {
5422 var selection = void 0;
5423
5424 if ('selectionStart' in input) {
5425 // Modern browser with input or textarea.
5426 selection = {
5427 start: input.selectionStart,
5428 end: input.selectionEnd
5429 };
5430 } else {
5431 // Content editable or old IE textarea.
5432 selection = getOffsets(input);
5433 }
5434
5435 return selection || { start: 0, end: 0 };
5436}
5437
5438/**
5439 * @setSelection: Sets the selection bounds of a textarea or input and focuses
5440 * the input.
5441 * -@input Set selection bounds of this input or textarea
5442 * -@offsets Object of same form that is returned from get*
5443 */
5444function setSelection(input, offsets) {
5445 var start = offsets.start,
5446 end = offsets.end;
5447
5448 if (end === undefined) {
5449 end = start;
5450 }
5451
5452 if ('selectionStart' in input) {
5453 input.selectionStart = start;
5454 input.selectionEnd = Math.min(end, input.value.length);
5455 } else {
5456 setOffsets(input, offsets);
5457 }
5458}
5459
5460var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
5461
5462var eventTypes$3 = {
5463 select: {
5464 phasedRegistrationNames: {
5465 bubbled: 'onSelect',
5466 captured: 'onSelectCapture'
5467 },
5468 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]
5469 }
5470};
5471
5472var activeElement$1 = null;
5473var activeElementInst$1 = null;
5474var lastSelection = null;
5475var mouseDown = false;
5476
5477/**
5478 * Get an object which is a unique representation of the current selection.
5479 *
5480 * The return value will not be consistent across nodes or browsers, but
5481 * two identical selections on the same node will return identical objects.
5482 *
5483 * @param {DOMElement} node
5484 * @return {object}
5485 */
5486function getSelection(node) {
5487 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
5488 return {
5489 start: node.selectionStart,
5490 end: node.selectionEnd
5491 };
5492 } else {
5493 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
5494 var selection = win.getSelection();
5495 return {
5496 anchorNode: selection.anchorNode,
5497 anchorOffset: selection.anchorOffset,
5498 focusNode: selection.focusNode,
5499 focusOffset: selection.focusOffset
5500 };
5501 }
5502}
5503
5504/**
5505 * Get document associated with the event target.
5506 *
5507 * @param {object} nativeEventTarget
5508 * @return {Document}
5509 */
5510function getEventTargetDocument(eventTarget) {
5511 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
5512}
5513
5514/**
5515 * Poll selection to see whether it's changed.
5516 *
5517 * @param {object} nativeEvent
5518 * @param {object} nativeEventTarget
5519 * @return {?SyntheticEvent}
5520 */
5521function constructSelectEvent(nativeEvent, nativeEventTarget) {
5522 // Ensure we have the right element, and that the user is not dragging a
5523 // selection (this matches native `select` event behavior). In HTML5, select
5524 // fires only on input and textarea thus if there's no focused element we
5525 // won't dispatch.
5526 var doc = getEventTargetDocument(nativeEventTarget);
5527
5528 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
5529 return null;
5530 }
5531
5532 // Only fire when selection has actually changed.
5533 var currentSelection = getSelection(activeElement$1);
5534 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
5535 lastSelection = currentSelection;
5536
5537 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
5538
5539 syntheticEvent.type = 'select';
5540 syntheticEvent.target = activeElement$1;
5541
5542 accumulateTwoPhaseDispatches(syntheticEvent);
5543
5544 return syntheticEvent;
5545 }
5546
5547 return null;
5548}
5549
5550/**
5551 * This plugin creates an `onSelect` event that normalizes select events
5552 * across form elements.
5553 *
5554 * Supported elements are:
5555 * - input (see `isTextInputElement`)
5556 * - textarea
5557 * - contentEditable
5558 *
5559 * This differs from native browser implementations in the following ways:
5560 * - Fires on contentEditable fields as well as inputs.
5561 * - Fires for collapsed selection.
5562 * - Fires after user input.
5563 */
5564var SelectEventPlugin = {
5565 eventTypes: eventTypes$3,
5566
5567 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
5568 var doc = getEventTargetDocument(nativeEventTarget);
5569 // Track whether all listeners exists for this plugin. If none exist, we do
5570 // not extract events. See #3639.
5571 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
5572 return null;
5573 }
5574
5575 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
5576
5577 switch (topLevelType) {
5578 // Track the input node that has focus.
5579 case TOP_FOCUS:
5580 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
5581 activeElement$1 = targetNode;
5582 activeElementInst$1 = targetInst;
5583 lastSelection = null;
5584 }
5585 break;
5586 case TOP_BLUR:
5587 activeElement$1 = null;
5588 activeElementInst$1 = null;
5589 lastSelection = null;
5590 break;
5591 // Don't fire the event while the user is dragging. This matches the
5592 // semantics of the native select event.
5593 case TOP_MOUSE_DOWN:
5594 mouseDown = true;
5595 break;
5596 case TOP_CONTEXT_MENU:
5597 case TOP_MOUSE_UP:
5598 case TOP_DRAG_END:
5599 mouseDown = false;
5600 return constructSelectEvent(nativeEvent, nativeEventTarget);
5601 // Chrome and IE fire non-standard event when selection is changed (and
5602 // sometimes when it hasn't). IE's event fires out of order with respect
5603 // to key and input events on deletion, so we discard it.
5604 //
5605 // Firefox doesn't support selectionchange, so check selection status
5606 // after each key entry. The selection changes after keydown and before
5607 // keyup, but we check on keydown as well in the case of holding down a
5608 // key, when multiple keydown events are fired but only one keyup is.
5609 // This is also our approach for IE handling, for the reason above.
5610 case TOP_SELECTION_CHANGE:
5611 if (skipSelectionChangeEvent) {
5612 break;
5613 }
5614 // falls through
5615 case TOP_KEY_DOWN:
5616 case TOP_KEY_UP:
5617 return constructSelectEvent(nativeEvent, nativeEventTarget);
5618 }
5619
5620 return null;
5621 }
5622};
5623
5624/**
5625 * Inject modules for resolving DOM hierarchy and plugin ordering.
5626 */
5627injection.injectEventPluginOrder(DOMEventPluginOrder);
5628setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
5629
5630/**
5631 * Some important event plugins included by default (without having to require
5632 * them).
5633 */
5634injection.injectEventPluginsByName({
5635 SimpleEventPlugin: SimpleEventPlugin,
5636 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
5637 ChangeEventPlugin: ChangeEventPlugin,
5638 SelectEventPlugin: SelectEventPlugin,
5639 BeforeInputEventPlugin: BeforeInputEventPlugin
5640});
5641
5642var didWarnSelectedSetOnOption = false;
5643var didWarnInvalidChild = false;
5644
5645function flattenChildren(children) {
5646 var content = '';
5647
5648 // Flatten children. We'll warn if they are invalid
5649 // during validateProps() which runs for hydration too.
5650 // Note that this would throw on non-element objects.
5651 // Elements are stringified (which is normally irrelevant
5652 // but matters for <fbt>).
5653 React.Children.forEach(children, function (child) {
5654 if (child == null) {
5655 return;
5656 }
5657 content += child;
5658 // Note: we don't warn about invalid children here.
5659 // Instead, this is done separately below so that
5660 // it happens during the hydration codepath too.
5661 });
5662
5663 return content;
5664}
5665
5666/**
5667 * Implements an <option> host component that warns when `selected` is set.
5668 */
5669
5670function validateProps(element, props) {
5671 {
5672 // This mirrors the codepath above, but runs for hydration too.
5673 // Warn about invalid children here so that client and hydration are consistent.
5674 // TODO: this seems like it could cause a DEV-only throw for hydration
5675 // if children contains a non-element object. We should try to avoid that.
5676 if (typeof props.children === 'object' && props.children !== null) {
5677 React.Children.forEach(props.children, function (child) {
5678 if (child == null) {
5679 return;
5680 }
5681 if (typeof child === 'string' || typeof child === 'number') {
5682 return;
5683 }
5684 if (typeof child.type !== 'string') {
5685 return;
5686 }
5687 if (!didWarnInvalidChild) {
5688 didWarnInvalidChild = true;
5689 warning$1(false, 'Only strings and numbers are supported as <option> children.');
5690 }
5691 });
5692 }
5693
5694 // TODO: Remove support for `selected` in <option>.
5695 if (props.selected != null && !didWarnSelectedSetOnOption) {
5696 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
5697 didWarnSelectedSetOnOption = true;
5698 }
5699 }
5700}
5701
5702function postMountWrapper$1(element, props) {
5703 // value="" should make a value attribute (#6219)
5704 if (props.value != null) {
5705 element.setAttribute('value', toString(getToStringValue(props.value)));
5706 }
5707}
5708
5709function getHostProps$1(element, props) {
5710 var hostProps = _assign({ children: undefined }, props);
5711 var content = flattenChildren(props.children);
5712
5713 if (content) {
5714 hostProps.children = content;
5715 }
5716
5717 return hostProps;
5718}
5719
5720// TODO: direct imports like some-package/src/* are bad. Fix me.
5721var didWarnValueDefaultValue$1 = void 0;
5722
5723{
5724 didWarnValueDefaultValue$1 = false;
5725}
5726
5727function getDeclarationErrorAddendum() {
5728 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
5729 if (ownerName) {
5730 return '\n\nCheck the render method of `' + ownerName + '`.';
5731 }
5732 return '';
5733}
5734
5735var valuePropNames = ['value', 'defaultValue'];
5736
5737/**
5738 * Validation function for `value` and `defaultValue`.
5739 */
5740function checkSelectPropTypes(props) {
5741 ReactControlledValuePropTypes.checkPropTypes('select', props);
5742
5743 for (var i = 0; i < valuePropNames.length; i++) {
5744 var propName = valuePropNames[i];
5745 if (props[propName] == null) {
5746 continue;
5747 }
5748 var isArray = Array.isArray(props[propName]);
5749 if (props.multiple && !isArray) {
5750 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
5751 } else if (!props.multiple && isArray) {
5752 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
5753 }
5754 }
5755}
5756
5757function updateOptions(node, multiple, propValue, setDefaultSelected) {
5758 var options = node.options;
5759
5760 if (multiple) {
5761 var selectedValues = propValue;
5762 var selectedValue = {};
5763 for (var i = 0; i < selectedValues.length; i++) {
5764 // Prefix to avoid chaos with special keys.
5765 selectedValue['$' + selectedValues[i]] = true;
5766 }
5767 for (var _i = 0; _i < options.length; _i++) {
5768 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
5769 if (options[_i].selected !== selected) {
5770 options[_i].selected = selected;
5771 }
5772 if (selected && setDefaultSelected) {
5773 options[_i].defaultSelected = true;
5774 }
5775 }
5776 } else {
5777 // Do not set `select.value` as exact behavior isn't consistent across all
5778 // browsers for all cases.
5779 var _selectedValue = toString(getToStringValue(propValue));
5780 var defaultSelected = null;
5781 for (var _i2 = 0; _i2 < options.length; _i2++) {
5782 if (options[_i2].value === _selectedValue) {
5783 options[_i2].selected = true;
5784 if (setDefaultSelected) {
5785 options[_i2].defaultSelected = true;
5786 }
5787 return;
5788 }
5789 if (defaultSelected === null && !options[_i2].disabled) {
5790 defaultSelected = options[_i2];
5791 }
5792 }
5793 if (defaultSelected !== null) {
5794 defaultSelected.selected = true;
5795 }
5796 }
5797}
5798
5799/**
5800 * Implements a <select> host component that allows optionally setting the
5801 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
5802 * stringable. If `multiple` is true, the prop must be an array of stringables.
5803 *
5804 * If `value` is not supplied (or null/undefined), user actions that change the
5805 * selected option will trigger updates to the rendered options.
5806 *
5807 * If it is supplied (and not null/undefined), the rendered options will not
5808 * update in response to user actions. Instead, the `value` prop must change in
5809 * order for the rendered options to update.
5810 *
5811 * If `defaultValue` is provided, any options with the supplied values will be
5812 * selected.
5813 */
5814
5815function getHostProps$2(element, props) {
5816 return _assign({}, props, {
5817 value: undefined
5818 });
5819}
5820
5821function initWrapperState$1(element, props) {
5822 var node = element;
5823 {
5824 checkSelectPropTypes(props);
5825 }
5826
5827 node._wrapperState = {
5828 wasMultiple: !!props.multiple
5829 };
5830
5831 {
5832 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
5833 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');
5834 didWarnValueDefaultValue$1 = true;
5835 }
5836 }
5837}
5838
5839function postMountWrapper$2(element, props) {
5840 var node = element;
5841 node.multiple = !!props.multiple;
5842 var value = props.value;
5843 if (value != null) {
5844 updateOptions(node, !!props.multiple, value, false);
5845 } else if (props.defaultValue != null) {
5846 updateOptions(node, !!props.multiple, props.defaultValue, true);
5847 }
5848}
5849
5850function postUpdateWrapper(element, props) {
5851 var node = element;
5852 var wasMultiple = node._wrapperState.wasMultiple;
5853 node._wrapperState.wasMultiple = !!props.multiple;
5854
5855 var value = props.value;
5856 if (value != null) {
5857 updateOptions(node, !!props.multiple, value, false);
5858 } else if (wasMultiple !== !!props.multiple) {
5859 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
5860 if (props.defaultValue != null) {
5861 updateOptions(node, !!props.multiple, props.defaultValue, true);
5862 } else {
5863 // Revert the select back to its default unselected state.
5864 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
5865 }
5866 }
5867}
5868
5869function restoreControlledState$2(element, props) {
5870 var node = element;
5871 var value = props.value;
5872
5873 if (value != null) {
5874 updateOptions(node, !!props.multiple, value, false);
5875 }
5876}
5877
5878var didWarnValDefaultVal = false;
5879
5880/**
5881 * Implements a <textarea> host component that allows setting `value`, and
5882 * `defaultValue`. This differs from the traditional DOM API because value is
5883 * usually set as PCDATA children.
5884 *
5885 * If `value` is not supplied (or null/undefined), user actions that affect the
5886 * value will trigger updates to the element.
5887 *
5888 * If `value` is supplied (and not null/undefined), the rendered element will
5889 * not trigger updates to the element. Instead, the `value` prop must change in
5890 * order for the rendered element to be updated.
5891 *
5892 * The rendered element will be initialized with an empty value, the prop
5893 * `defaultValue` if specified, or the children content (deprecated).
5894 */
5895
5896function getHostProps$3(element, props) {
5897 var node = element;
5898 !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0;
5899
5900 // Always set children to the same thing. In IE9, the selection range will
5901 // get reset if `textContent` is mutated. We could add a check in setTextContent
5902 // to only set the value if/when the value differs from the node value (which would
5903 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
5904 // solution. The value can be a boolean or object so that's why it's forced
5905 // to be a string.
5906 var hostProps = _assign({}, props, {
5907 value: undefined,
5908 defaultValue: undefined,
5909 children: toString(node._wrapperState.initialValue)
5910 });
5911
5912 return hostProps;
5913}
5914
5915function initWrapperState$2(element, props) {
5916 var node = element;
5917 {
5918 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
5919 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
5920 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');
5921 didWarnValDefaultVal = true;
5922 }
5923 }
5924
5925 var initialValue = props.value;
5926
5927 // Only bother fetching default value if we're going to use it
5928 if (initialValue == null) {
5929 var defaultValue = props.defaultValue;
5930 // TODO (yungsters): Remove support for children content in <textarea>.
5931 var children = props.children;
5932 if (children != null) {
5933 {
5934 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
5935 }
5936 !(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0;
5937 if (Array.isArray(children)) {
5938 !(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0;
5939 children = children[0];
5940 }
5941
5942 defaultValue = children;
5943 }
5944 if (defaultValue == null) {
5945 defaultValue = '';
5946 }
5947 initialValue = defaultValue;
5948 }
5949
5950 node._wrapperState = {
5951 initialValue: getToStringValue(initialValue)
5952 };
5953}
5954
5955function updateWrapper$1(element, props) {
5956 var node = element;
5957 var value = getToStringValue(props.value);
5958 var defaultValue = getToStringValue(props.defaultValue);
5959 if (value != null) {
5960 // Cast `value` to a string to ensure the value is set correctly. While
5961 // browsers typically do this as necessary, jsdom doesn't.
5962 var newValue = toString(value);
5963 // To avoid side effects (such as losing text selection), only set value if changed
5964 if (newValue !== node.value) {
5965 node.value = newValue;
5966 }
5967 if (props.defaultValue == null && node.defaultValue !== newValue) {
5968 node.defaultValue = newValue;
5969 }
5970 }
5971 if (defaultValue != null) {
5972 node.defaultValue = toString(defaultValue);
5973 }
5974}
5975
5976function postMountWrapper$3(element, props) {
5977 var node = element;
5978 // This is in postMount because we need access to the DOM node, which is not
5979 // available until after the component has mounted.
5980 var textContent = node.textContent;
5981
5982 // Only set node.value if textContent is equal to the expected
5983 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
5984 // will populate textContent as well.
5985 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
5986 if (textContent === node._wrapperState.initialValue) {
5987 node.value = textContent;
5988 }
5989}
5990
5991function restoreControlledState$3(element, props) {
5992 // DOM component is still mounted; update
5993 updateWrapper$1(element, props);
5994}
5995
5996var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
5997var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
5998var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
5999
6000var Namespaces = {
6001 html: HTML_NAMESPACE$1,
6002 mathml: MATH_NAMESPACE,
6003 svg: SVG_NAMESPACE
6004};
6005
6006// Assumes there is no parent namespace.
6007function getIntrinsicNamespace(type) {
6008 switch (type) {
6009 case 'svg':
6010 return SVG_NAMESPACE;
6011 case 'math':
6012 return MATH_NAMESPACE;
6013 default:
6014 return HTML_NAMESPACE$1;
6015 }
6016}
6017
6018function getChildNamespace(parentNamespace, type) {
6019 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
6020 // No (or default) parent namespace: potential entry point.
6021 return getIntrinsicNamespace(type);
6022 }
6023 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
6024 // We're leaving SVG.
6025 return HTML_NAMESPACE$1;
6026 }
6027 // By default, pass namespace below.
6028 return parentNamespace;
6029}
6030
6031/* globals MSApp */
6032
6033/**
6034 * Create a function which has 'unsafe' privileges (required by windows8 apps)
6035 */
6036var createMicrosoftUnsafeLocalFunction = function (func) {
6037 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
6038 return function (arg0, arg1, arg2, arg3) {
6039 MSApp.execUnsafeLocalFunction(function () {
6040 return func(arg0, arg1, arg2, arg3);
6041 });
6042 };
6043 } else {
6044 return func;
6045 }
6046};
6047
6048// SVG temp container for IE lacking innerHTML
6049var reusableSVGContainer = void 0;
6050
6051/**
6052 * Set the innerHTML property of a node
6053 *
6054 * @param {DOMElement} node
6055 * @param {string} html
6056 * @internal
6057 */
6058var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
6059 // IE does not have innerHTML for SVG nodes, so instead we inject the
6060 // new markup in a temp node and then move the child nodes across into
6061 // the target node
6062
6063 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) {
6064 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
6065 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
6066 var svgNode = reusableSVGContainer.firstChild;
6067 while (node.firstChild) {
6068 node.removeChild(node.firstChild);
6069 }
6070 while (svgNode.firstChild) {
6071 node.appendChild(svgNode.firstChild);
6072 }
6073 } else {
6074 node.innerHTML = html;
6075 }
6076});
6077
6078/**
6079 * Set the textContent property of a node. For text updates, it's faster
6080 * to set the `nodeValue` of the Text node directly instead of using
6081 * `.textContent` which will remove the existing node and create a new one.
6082 *
6083 * @param {DOMElement} node
6084 * @param {string} text
6085 * @internal
6086 */
6087var setTextContent = function (node, text) {
6088 if (text) {
6089 var firstChild = node.firstChild;
6090
6091 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
6092 firstChild.nodeValue = text;
6093 return;
6094 }
6095 }
6096 node.textContent = text;
6097};
6098
6099// List derived from Gecko source code:
6100// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
6101var shorthandToLonghand = {
6102 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
6103 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
6104 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
6105 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6106 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
6107 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
6108 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
6109 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
6110 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
6111 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
6112 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
6113 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
6114 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
6115 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
6116 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
6117 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6118 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
6119 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
6120 columns: ['columnCount', 'columnWidth'],
6121 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
6122 flexFlow: ['flexDirection', 'flexWrap'],
6123 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
6124 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
6125 gap: ['columnGap', 'rowGap'],
6126 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6127 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
6128 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
6129 gridColumnGap: ['columnGap'],
6130 gridGap: ['columnGap', 'rowGap'],
6131 gridRow: ['gridRowEnd', 'gridRowStart'],
6132 gridRowGap: ['rowGap'],
6133 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6134 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
6135 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
6136 marker: ['markerEnd', 'markerMid', 'markerStart'],
6137 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
6138 maskPosition: ['maskPositionX', 'maskPositionY'],
6139 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
6140 overflow: ['overflowX', 'overflowY'],
6141 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
6142 placeContent: ['alignContent', 'justifyContent'],
6143 placeItems: ['alignItems', 'justifyItems'],
6144 placeSelf: ['alignSelf', 'justifySelf'],
6145 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
6146 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
6147 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
6148 wordWrap: ['overflowWrap']
6149};
6150
6151/**
6152 * CSS properties which accept numbers but are not in units of "px".
6153 */
6154var isUnitlessNumber = {
6155 animationIterationCount: true,
6156 borderImageOutset: true,
6157 borderImageSlice: true,
6158 borderImageWidth: true,
6159 boxFlex: true,
6160 boxFlexGroup: true,
6161 boxOrdinalGroup: true,
6162 columnCount: true,
6163 columns: true,
6164 flex: true,
6165 flexGrow: true,
6166 flexPositive: true,
6167 flexShrink: true,
6168 flexNegative: true,
6169 flexOrder: true,
6170 gridArea: true,
6171 gridRow: true,
6172 gridRowEnd: true,
6173 gridRowSpan: true,
6174 gridRowStart: true,
6175 gridColumn: true,
6176 gridColumnEnd: true,
6177 gridColumnSpan: true,
6178 gridColumnStart: true,
6179 fontWeight: true,
6180 lineClamp: true,
6181 lineHeight: true,
6182 opacity: true,
6183 order: true,
6184 orphans: true,
6185 tabSize: true,
6186 widows: true,
6187 zIndex: true,
6188 zoom: true,
6189
6190 // SVG-related properties
6191 fillOpacity: true,
6192 floodOpacity: true,
6193 stopOpacity: true,
6194 strokeDasharray: true,
6195 strokeDashoffset: true,
6196 strokeMiterlimit: true,
6197 strokeOpacity: true,
6198 strokeWidth: true
6199};
6200
6201/**
6202 * @param {string} prefix vendor-specific prefix, eg: Webkit
6203 * @param {string} key style name, eg: transitionDuration
6204 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
6205 * WebkitTransitionDuration
6206 */
6207function prefixKey(prefix, key) {
6208 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
6209}
6210
6211/**
6212 * Support style names that may come passed in prefixed by adding permutations
6213 * of vendor prefixes.
6214 */
6215var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
6216
6217// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
6218// infinite loop, because it iterates over the newly added props too.
6219Object.keys(isUnitlessNumber).forEach(function (prop) {
6220 prefixes.forEach(function (prefix) {
6221 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
6222 });
6223});
6224
6225/**
6226 * Convert a value into the proper css writable value. The style name `name`
6227 * should be logical (no hyphens), as specified
6228 * in `CSSProperty.isUnitlessNumber`.
6229 *
6230 * @param {string} name CSS property name such as `topMargin`.
6231 * @param {*} value CSS property value such as `10px`.
6232 * @return {string} Normalized style value with dimensions applied.
6233 */
6234function dangerousStyleValue(name, value, isCustomProperty) {
6235 // Note that we've removed escapeTextForBrowser() calls here since the
6236 // whole string will be escaped when the attribute is injected into
6237 // the markup. If you provide unsafe user data here they can inject
6238 // arbitrary CSS which may be problematic (I couldn't repro this):
6239 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
6240 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
6241 // This is not an XSS hole but instead a potential CSS injection issue
6242 // which has lead to a greater discussion about how we're going to
6243 // trust URLs moving forward. See #2115901
6244
6245 var isEmpty = value == null || typeof value === 'boolean' || value === '';
6246 if (isEmpty) {
6247 return '';
6248 }
6249
6250 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
6251 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
6252 }
6253
6254 return ('' + value).trim();
6255}
6256
6257var uppercasePattern = /([A-Z])/g;
6258var msPattern = /^ms-/;
6259
6260/**
6261 * Hyphenates a camelcased CSS property name, for example:
6262 *
6263 * > hyphenateStyleName('backgroundColor')
6264 * < "background-color"
6265 * > hyphenateStyleName('MozTransition')
6266 * < "-moz-transition"
6267 * > hyphenateStyleName('msTransition')
6268 * < "-ms-transition"
6269 *
6270 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
6271 * is converted to `-ms-`.
6272 */
6273function hyphenateStyleName(name) {
6274 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
6275}
6276
6277var warnValidStyle = function () {};
6278
6279{
6280 // 'msTransform' is correct, but the other prefixes should be capitalized
6281 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
6282 var msPattern$1 = /^-ms-/;
6283 var hyphenPattern = /-(.)/g;
6284
6285 // style values shouldn't contain a semicolon
6286 var badStyleValueWithSemicolonPattern = /;\s*$/;
6287
6288 var warnedStyleNames = {};
6289 var warnedStyleValues = {};
6290 var warnedForNaNValue = false;
6291 var warnedForInfinityValue = false;
6292
6293 var camelize = function (string) {
6294 return string.replace(hyphenPattern, function (_, character) {
6295 return character.toUpperCase();
6296 });
6297 };
6298
6299 var warnHyphenatedStyleName = function (name) {
6300 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6301 return;
6302 }
6303
6304 warnedStyleNames[name] = true;
6305 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name,
6306 // As Andi Smith suggests
6307 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
6308 // is converted to lowercase `ms`.
6309 camelize(name.replace(msPattern$1, 'ms-')));
6310 };
6311
6312 var warnBadVendoredStyleName = function (name) {
6313 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6314 return;
6315 }
6316
6317 warnedStyleNames[name] = true;
6318 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
6319 };
6320
6321 var warnStyleValueWithSemicolon = function (name, value) {
6322 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
6323 return;
6324 }
6325
6326 warnedStyleValues[value] = true;
6327 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
6328 };
6329
6330 var warnStyleValueIsNaN = function (name, value) {
6331 if (warnedForNaNValue) {
6332 return;
6333 }
6334
6335 warnedForNaNValue = true;
6336 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name);
6337 };
6338
6339 var warnStyleValueIsInfinity = function (name, value) {
6340 if (warnedForInfinityValue) {
6341 return;
6342 }
6343
6344 warnedForInfinityValue = true;
6345 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name);
6346 };
6347
6348 warnValidStyle = function (name, value) {
6349 if (name.indexOf('-') > -1) {
6350 warnHyphenatedStyleName(name);
6351 } else if (badVendoredStyleNamePattern.test(name)) {
6352 warnBadVendoredStyleName(name);
6353 } else if (badStyleValueWithSemicolonPattern.test(value)) {
6354 warnStyleValueWithSemicolon(name, value);
6355 }
6356
6357 if (typeof value === 'number') {
6358 if (isNaN(value)) {
6359 warnStyleValueIsNaN(name, value);
6360 } else if (!isFinite(value)) {
6361 warnStyleValueIsInfinity(name, value);
6362 }
6363 }
6364 };
6365}
6366
6367var warnValidStyle$1 = warnValidStyle;
6368
6369/**
6370 * Operations for dealing with CSS properties.
6371 */
6372
6373/**
6374 * This creates a string that is expected to be equivalent to the style
6375 * attribute generated by server-side rendering. It by-passes warnings and
6376 * security checks so it's not safe to use this value for anything other than
6377 * comparison. It is only used in DEV for SSR validation.
6378 */
6379function createDangerousStringForStyles(styles) {
6380 {
6381 var serialized = '';
6382 var delimiter = '';
6383 for (var styleName in styles) {
6384 if (!styles.hasOwnProperty(styleName)) {
6385 continue;
6386 }
6387 var styleValue = styles[styleName];
6388 if (styleValue != null) {
6389 var isCustomProperty = styleName.indexOf('--') === 0;
6390 serialized += delimiter + hyphenateStyleName(styleName) + ':';
6391 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
6392
6393 delimiter = ';';
6394 }
6395 }
6396 return serialized || null;
6397 }
6398}
6399
6400/**
6401 * Sets the value for multiple styles on a node. If a value is specified as
6402 * '' (empty string), the corresponding style property will be unset.
6403 *
6404 * @param {DOMElement} node
6405 * @param {object} styles
6406 */
6407function setValueForStyles(node, styles) {
6408 var style = node.style;
6409 for (var styleName in styles) {
6410 if (!styles.hasOwnProperty(styleName)) {
6411 continue;
6412 }
6413 var isCustomProperty = styleName.indexOf('--') === 0;
6414 {
6415 if (!isCustomProperty) {
6416 warnValidStyle$1(styleName, styles[styleName]);
6417 }
6418 }
6419 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
6420 if (styleName === 'float') {
6421 styleName = 'cssFloat';
6422 }
6423 if (isCustomProperty) {
6424 style.setProperty(styleName, styleValue);
6425 } else {
6426 style[styleName] = styleValue;
6427 }
6428 }
6429}
6430
6431function isValueEmpty(value) {
6432 return value == null || typeof value === 'boolean' || value === '';
6433}
6434
6435/**
6436 * Given {color: 'red', overflow: 'hidden'} returns {
6437 * color: 'color',
6438 * overflowX: 'overflow',
6439 * overflowY: 'overflow',
6440 * }. This can be read as "the overflowY property was set by the overflow
6441 * shorthand". That is, the values are the property that each was derived from.
6442 */
6443function expandShorthandMap(styles) {
6444 var expanded = {};
6445 for (var key in styles) {
6446 var longhands = shorthandToLonghand[key] || [key];
6447 for (var i = 0; i < longhands.length; i++) {
6448 expanded[longhands[i]] = key;
6449 }
6450 }
6451 return expanded;
6452}
6453
6454/**
6455 * When mixing shorthand and longhand property names, we warn during updates if
6456 * we expect an incorrect result to occur. In particular, we warn for:
6457 *
6458 * Updating a shorthand property (longhand gets overwritten):
6459 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
6460 * becomes .style.font = 'baz'
6461 * Removing a shorthand property (longhand gets lost too):
6462 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
6463 * becomes .style.font = ''
6464 * Removing a longhand property (should revert to shorthand; doesn't):
6465 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
6466 * becomes .style.fontVariant = ''
6467 */
6468function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
6469 if (!warnAboutShorthandPropertyCollision) {
6470 return;
6471 }
6472
6473 if (!nextStyles) {
6474 return;
6475 }
6476
6477 var expandedUpdates = expandShorthandMap(styleUpdates);
6478 var expandedStyles = expandShorthandMap(nextStyles);
6479 var warnedAbout = {};
6480 for (var key in expandedUpdates) {
6481 var originalKey = expandedUpdates[key];
6482 var correctOriginalKey = expandedStyles[key];
6483 if (correctOriginalKey && originalKey !== correctOriginalKey) {
6484 var warningKey = originalKey + ',' + correctOriginalKey;
6485 if (warnedAbout[warningKey]) {
6486 continue;
6487 }
6488 warnedAbout[warningKey] = true;
6489 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);
6490 }
6491 }
6492}
6493
6494// For HTML, certain tags should omit their close tag. We keep a whitelist for
6495// those special-case tags.
6496
6497var omittedCloseTags = {
6498 area: true,
6499 base: true,
6500 br: true,
6501 col: true,
6502 embed: true,
6503 hr: true,
6504 img: true,
6505 input: true,
6506 keygen: true,
6507 link: true,
6508 meta: true,
6509 param: true,
6510 source: true,
6511 track: true,
6512 wbr: true
6513 // NOTE: menuitem's close tag should be omitted, but that causes problems.
6514};
6515
6516// For HTML, certain tags cannot have children. This has the same purpose as
6517// `omittedCloseTags` except that `menuitem` should still have its closing tag.
6518
6519var voidElementTags = _assign({
6520 menuitem: true
6521}, omittedCloseTags);
6522
6523// TODO: We can remove this if we add invariantWithStack()
6524// or add stack by default to invariants where possible.
6525var HTML$1 = '__html';
6526
6527var ReactDebugCurrentFrame$2 = null;
6528{
6529 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
6530}
6531
6532function assertValidProps(tag, props) {
6533 if (!props) {
6534 return;
6535 }
6536 // Note the use of `==` which checks for null or undefined.
6537 if (voidElementTags[tag]) {
6538 !(props.children == null && props.dangerouslySetInnerHTML == null) ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', tag, ReactDebugCurrentFrame$2.getStackAddendum()) : void 0;
6539 }
6540 if (props.dangerouslySetInnerHTML != null) {
6541 !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0;
6542 !(typeof props.dangerouslySetInnerHTML === 'object' && HTML$1 in props.dangerouslySetInnerHTML) ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : void 0;
6543 }
6544 {
6545 !(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;
6546 }
6547 !(props.style == null || typeof props.style === 'object') ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', ReactDebugCurrentFrame$2.getStackAddendum()) : void 0;
6548}
6549
6550function isCustomComponent(tagName, props) {
6551 if (tagName.indexOf('-') === -1) {
6552 return typeof props.is === 'string';
6553 }
6554 switch (tagName) {
6555 // These are reserved SVG and MathML elements.
6556 // We don't mind this whitelist too much because we expect it to never grow.
6557 // The alternative is to track the namespace in a few places which is convoluted.
6558 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
6559 case 'annotation-xml':
6560 case 'color-profile':
6561 case 'font-face':
6562 case 'font-face-src':
6563 case 'font-face-uri':
6564 case 'font-face-format':
6565 case 'font-face-name':
6566 case 'missing-glyph':
6567 return false;
6568 default:
6569 return true;
6570 }
6571}
6572
6573// When adding attributes to the HTML or SVG whitelist, be sure to
6574// also add them to this module to ensure casing and incorrect name
6575// warnings.
6576var possibleStandardNames = {
6577 // HTML
6578 accept: 'accept',
6579 acceptcharset: 'acceptCharset',
6580 'accept-charset': 'acceptCharset',
6581 accesskey: 'accessKey',
6582 action: 'action',
6583 allowfullscreen: 'allowFullScreen',
6584 alt: 'alt',
6585 as: 'as',
6586 async: 'async',
6587 autocapitalize: 'autoCapitalize',
6588 autocomplete: 'autoComplete',
6589 autocorrect: 'autoCorrect',
6590 autofocus: 'autoFocus',
6591 autoplay: 'autoPlay',
6592 autosave: 'autoSave',
6593 capture: 'capture',
6594 cellpadding: 'cellPadding',
6595 cellspacing: 'cellSpacing',
6596 challenge: 'challenge',
6597 charset: 'charSet',
6598 checked: 'checked',
6599 children: 'children',
6600 cite: 'cite',
6601 class: 'className',
6602 classid: 'classID',
6603 classname: 'className',
6604 cols: 'cols',
6605 colspan: 'colSpan',
6606 content: 'content',
6607 contenteditable: 'contentEditable',
6608 contextmenu: 'contextMenu',
6609 controls: 'controls',
6610 controlslist: 'controlsList',
6611 coords: 'coords',
6612 crossorigin: 'crossOrigin',
6613 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
6614 data: 'data',
6615 datetime: 'dateTime',
6616 default: 'default',
6617 defaultchecked: 'defaultChecked',
6618 defaultvalue: 'defaultValue',
6619 defer: 'defer',
6620 dir: 'dir',
6621 disabled: 'disabled',
6622 download: 'download',
6623 draggable: 'draggable',
6624 enctype: 'encType',
6625 for: 'htmlFor',
6626 form: 'form',
6627 formmethod: 'formMethod',
6628 formaction: 'formAction',
6629 formenctype: 'formEncType',
6630 formnovalidate: 'formNoValidate',
6631 formtarget: 'formTarget',
6632 frameborder: 'frameBorder',
6633 headers: 'headers',
6634 height: 'height',
6635 hidden: 'hidden',
6636 high: 'high',
6637 href: 'href',
6638 hreflang: 'hrefLang',
6639 htmlfor: 'htmlFor',
6640 httpequiv: 'httpEquiv',
6641 'http-equiv': 'httpEquiv',
6642 icon: 'icon',
6643 id: 'id',
6644 innerhtml: 'innerHTML',
6645 inputmode: 'inputMode',
6646 integrity: 'integrity',
6647 is: 'is',
6648 itemid: 'itemID',
6649 itemprop: 'itemProp',
6650 itemref: 'itemRef',
6651 itemscope: 'itemScope',
6652 itemtype: 'itemType',
6653 keyparams: 'keyParams',
6654 keytype: 'keyType',
6655 kind: 'kind',
6656 label: 'label',
6657 lang: 'lang',
6658 list: 'list',
6659 loop: 'loop',
6660 low: 'low',
6661 manifest: 'manifest',
6662 marginwidth: 'marginWidth',
6663 marginheight: 'marginHeight',
6664 max: 'max',
6665 maxlength: 'maxLength',
6666 media: 'media',
6667 mediagroup: 'mediaGroup',
6668 method: 'method',
6669 min: 'min',
6670 minlength: 'minLength',
6671 multiple: 'multiple',
6672 muted: 'muted',
6673 name: 'name',
6674 nomodule: 'noModule',
6675 nonce: 'nonce',
6676 novalidate: 'noValidate',
6677 open: 'open',
6678 optimum: 'optimum',
6679 pattern: 'pattern',
6680 placeholder: 'placeholder',
6681 playsinline: 'playsInline',
6682 poster: 'poster',
6683 preload: 'preload',
6684 profile: 'profile',
6685 radiogroup: 'radioGroup',
6686 readonly: 'readOnly',
6687 referrerpolicy: 'referrerPolicy',
6688 rel: 'rel',
6689 required: 'required',
6690 reversed: 'reversed',
6691 role: 'role',
6692 rows: 'rows',
6693 rowspan: 'rowSpan',
6694 sandbox: 'sandbox',
6695 scope: 'scope',
6696 scoped: 'scoped',
6697 scrolling: 'scrolling',
6698 seamless: 'seamless',
6699 selected: 'selected',
6700 shape: 'shape',
6701 size: 'size',
6702 sizes: 'sizes',
6703 span: 'span',
6704 spellcheck: 'spellCheck',
6705 src: 'src',
6706 srcdoc: 'srcDoc',
6707 srclang: 'srcLang',
6708 srcset: 'srcSet',
6709 start: 'start',
6710 step: 'step',
6711 style: 'style',
6712 summary: 'summary',
6713 tabindex: 'tabIndex',
6714 target: 'target',
6715 title: 'title',
6716 type: 'type',
6717 usemap: 'useMap',
6718 value: 'value',
6719 width: 'width',
6720 wmode: 'wmode',
6721 wrap: 'wrap',
6722
6723 // SVG
6724 about: 'about',
6725 accentheight: 'accentHeight',
6726 'accent-height': 'accentHeight',
6727 accumulate: 'accumulate',
6728 additive: 'additive',
6729 alignmentbaseline: 'alignmentBaseline',
6730 'alignment-baseline': 'alignmentBaseline',
6731 allowreorder: 'allowReorder',
6732 alphabetic: 'alphabetic',
6733 amplitude: 'amplitude',
6734 arabicform: 'arabicForm',
6735 'arabic-form': 'arabicForm',
6736 ascent: 'ascent',
6737 attributename: 'attributeName',
6738 attributetype: 'attributeType',
6739 autoreverse: 'autoReverse',
6740 azimuth: 'azimuth',
6741 basefrequency: 'baseFrequency',
6742 baselineshift: 'baselineShift',
6743 'baseline-shift': 'baselineShift',
6744 baseprofile: 'baseProfile',
6745 bbox: 'bbox',
6746 begin: 'begin',
6747 bias: 'bias',
6748 by: 'by',
6749 calcmode: 'calcMode',
6750 capheight: 'capHeight',
6751 'cap-height': 'capHeight',
6752 clip: 'clip',
6753 clippath: 'clipPath',
6754 'clip-path': 'clipPath',
6755 clippathunits: 'clipPathUnits',
6756 cliprule: 'clipRule',
6757 'clip-rule': 'clipRule',
6758 color: 'color',
6759 colorinterpolation: 'colorInterpolation',
6760 'color-interpolation': 'colorInterpolation',
6761 colorinterpolationfilters: 'colorInterpolationFilters',
6762 'color-interpolation-filters': 'colorInterpolationFilters',
6763 colorprofile: 'colorProfile',
6764 'color-profile': 'colorProfile',
6765 colorrendering: 'colorRendering',
6766 'color-rendering': 'colorRendering',
6767 contentscripttype: 'contentScriptType',
6768 contentstyletype: 'contentStyleType',
6769 cursor: 'cursor',
6770 cx: 'cx',
6771 cy: 'cy',
6772 d: 'd',
6773 datatype: 'datatype',
6774 decelerate: 'decelerate',
6775 descent: 'descent',
6776 diffuseconstant: 'diffuseConstant',
6777 direction: 'direction',
6778 display: 'display',
6779 divisor: 'divisor',
6780 dominantbaseline: 'dominantBaseline',
6781 'dominant-baseline': 'dominantBaseline',
6782 dur: 'dur',
6783 dx: 'dx',
6784 dy: 'dy',
6785 edgemode: 'edgeMode',
6786 elevation: 'elevation',
6787 enablebackground: 'enableBackground',
6788 'enable-background': 'enableBackground',
6789 end: 'end',
6790 exponent: 'exponent',
6791 externalresourcesrequired: 'externalResourcesRequired',
6792 fill: 'fill',
6793 fillopacity: 'fillOpacity',
6794 'fill-opacity': 'fillOpacity',
6795 fillrule: 'fillRule',
6796 'fill-rule': 'fillRule',
6797 filter: 'filter',
6798 filterres: 'filterRes',
6799 filterunits: 'filterUnits',
6800 floodopacity: 'floodOpacity',
6801 'flood-opacity': 'floodOpacity',
6802 floodcolor: 'floodColor',
6803 'flood-color': 'floodColor',
6804 focusable: 'focusable',
6805 fontfamily: 'fontFamily',
6806 'font-family': 'fontFamily',
6807 fontsize: 'fontSize',
6808 'font-size': 'fontSize',
6809 fontsizeadjust: 'fontSizeAdjust',
6810 'font-size-adjust': 'fontSizeAdjust',
6811 fontstretch: 'fontStretch',
6812 'font-stretch': 'fontStretch',
6813 fontstyle: 'fontStyle',
6814 'font-style': 'fontStyle',
6815 fontvariant: 'fontVariant',
6816 'font-variant': 'fontVariant',
6817 fontweight: 'fontWeight',
6818 'font-weight': 'fontWeight',
6819 format: 'format',
6820 from: 'from',
6821 fx: 'fx',
6822 fy: 'fy',
6823 g1: 'g1',
6824 g2: 'g2',
6825 glyphname: 'glyphName',
6826 'glyph-name': 'glyphName',
6827 glyphorientationhorizontal: 'glyphOrientationHorizontal',
6828 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
6829 glyphorientationvertical: 'glyphOrientationVertical',
6830 'glyph-orientation-vertical': 'glyphOrientationVertical',
6831 glyphref: 'glyphRef',
6832 gradienttransform: 'gradientTransform',
6833 gradientunits: 'gradientUnits',
6834 hanging: 'hanging',
6835 horizadvx: 'horizAdvX',
6836 'horiz-adv-x': 'horizAdvX',
6837 horizoriginx: 'horizOriginX',
6838 'horiz-origin-x': 'horizOriginX',
6839 ideographic: 'ideographic',
6840 imagerendering: 'imageRendering',
6841 'image-rendering': 'imageRendering',
6842 in2: 'in2',
6843 in: 'in',
6844 inlist: 'inlist',
6845 intercept: 'intercept',
6846 k1: 'k1',
6847 k2: 'k2',
6848 k3: 'k3',
6849 k4: 'k4',
6850 k: 'k',
6851 kernelmatrix: 'kernelMatrix',
6852 kernelunitlength: 'kernelUnitLength',
6853 kerning: 'kerning',
6854 keypoints: 'keyPoints',
6855 keysplines: 'keySplines',
6856 keytimes: 'keyTimes',
6857 lengthadjust: 'lengthAdjust',
6858 letterspacing: 'letterSpacing',
6859 'letter-spacing': 'letterSpacing',
6860 lightingcolor: 'lightingColor',
6861 'lighting-color': 'lightingColor',
6862 limitingconeangle: 'limitingConeAngle',
6863 local: 'local',
6864 markerend: 'markerEnd',
6865 'marker-end': 'markerEnd',
6866 markerheight: 'markerHeight',
6867 markermid: 'markerMid',
6868 'marker-mid': 'markerMid',
6869 markerstart: 'markerStart',
6870 'marker-start': 'markerStart',
6871 markerunits: 'markerUnits',
6872 markerwidth: 'markerWidth',
6873 mask: 'mask',
6874 maskcontentunits: 'maskContentUnits',
6875 maskunits: 'maskUnits',
6876 mathematical: 'mathematical',
6877 mode: 'mode',
6878 numoctaves: 'numOctaves',
6879 offset: 'offset',
6880 opacity: 'opacity',
6881 operator: 'operator',
6882 order: 'order',
6883 orient: 'orient',
6884 orientation: 'orientation',
6885 origin: 'origin',
6886 overflow: 'overflow',
6887 overlineposition: 'overlinePosition',
6888 'overline-position': 'overlinePosition',
6889 overlinethickness: 'overlineThickness',
6890 'overline-thickness': 'overlineThickness',
6891 paintorder: 'paintOrder',
6892 'paint-order': 'paintOrder',
6893 panose1: 'panose1',
6894 'panose-1': 'panose1',
6895 pathlength: 'pathLength',
6896 patterncontentunits: 'patternContentUnits',
6897 patterntransform: 'patternTransform',
6898 patternunits: 'patternUnits',
6899 pointerevents: 'pointerEvents',
6900 'pointer-events': 'pointerEvents',
6901 points: 'points',
6902 pointsatx: 'pointsAtX',
6903 pointsaty: 'pointsAtY',
6904 pointsatz: 'pointsAtZ',
6905 prefix: 'prefix',
6906 preservealpha: 'preserveAlpha',
6907 preserveaspectratio: 'preserveAspectRatio',
6908 primitiveunits: 'primitiveUnits',
6909 property: 'property',
6910 r: 'r',
6911 radius: 'radius',
6912 refx: 'refX',
6913 refy: 'refY',
6914 renderingintent: 'renderingIntent',
6915 'rendering-intent': 'renderingIntent',
6916 repeatcount: 'repeatCount',
6917 repeatdur: 'repeatDur',
6918 requiredextensions: 'requiredExtensions',
6919 requiredfeatures: 'requiredFeatures',
6920 resource: 'resource',
6921 restart: 'restart',
6922 result: 'result',
6923 results: 'results',
6924 rotate: 'rotate',
6925 rx: 'rx',
6926 ry: 'ry',
6927 scale: 'scale',
6928 security: 'security',
6929 seed: 'seed',
6930 shaperendering: 'shapeRendering',
6931 'shape-rendering': 'shapeRendering',
6932 slope: 'slope',
6933 spacing: 'spacing',
6934 specularconstant: 'specularConstant',
6935 specularexponent: 'specularExponent',
6936 speed: 'speed',
6937 spreadmethod: 'spreadMethod',
6938 startoffset: 'startOffset',
6939 stddeviation: 'stdDeviation',
6940 stemh: 'stemh',
6941 stemv: 'stemv',
6942 stitchtiles: 'stitchTiles',
6943 stopcolor: 'stopColor',
6944 'stop-color': 'stopColor',
6945 stopopacity: 'stopOpacity',
6946 'stop-opacity': 'stopOpacity',
6947 strikethroughposition: 'strikethroughPosition',
6948 'strikethrough-position': 'strikethroughPosition',
6949 strikethroughthickness: 'strikethroughThickness',
6950 'strikethrough-thickness': 'strikethroughThickness',
6951 string: 'string',
6952 stroke: 'stroke',
6953 strokedasharray: 'strokeDasharray',
6954 'stroke-dasharray': 'strokeDasharray',
6955 strokedashoffset: 'strokeDashoffset',
6956 'stroke-dashoffset': 'strokeDashoffset',
6957 strokelinecap: 'strokeLinecap',
6958 'stroke-linecap': 'strokeLinecap',
6959 strokelinejoin: 'strokeLinejoin',
6960 'stroke-linejoin': 'strokeLinejoin',
6961 strokemiterlimit: 'strokeMiterlimit',
6962 'stroke-miterlimit': 'strokeMiterlimit',
6963 strokewidth: 'strokeWidth',
6964 'stroke-width': 'strokeWidth',
6965 strokeopacity: 'strokeOpacity',
6966 'stroke-opacity': 'strokeOpacity',
6967 suppresscontenteditablewarning: 'suppressContentEditableWarning',
6968 suppresshydrationwarning: 'suppressHydrationWarning',
6969 surfacescale: 'surfaceScale',
6970 systemlanguage: 'systemLanguage',
6971 tablevalues: 'tableValues',
6972 targetx: 'targetX',
6973 targety: 'targetY',
6974 textanchor: 'textAnchor',
6975 'text-anchor': 'textAnchor',
6976 textdecoration: 'textDecoration',
6977 'text-decoration': 'textDecoration',
6978 textlength: 'textLength',
6979 textrendering: 'textRendering',
6980 'text-rendering': 'textRendering',
6981 to: 'to',
6982 transform: 'transform',
6983 typeof: 'typeof',
6984 u1: 'u1',
6985 u2: 'u2',
6986 underlineposition: 'underlinePosition',
6987 'underline-position': 'underlinePosition',
6988 underlinethickness: 'underlineThickness',
6989 'underline-thickness': 'underlineThickness',
6990 unicode: 'unicode',
6991 unicodebidi: 'unicodeBidi',
6992 'unicode-bidi': 'unicodeBidi',
6993 unicoderange: 'unicodeRange',
6994 'unicode-range': 'unicodeRange',
6995 unitsperem: 'unitsPerEm',
6996 'units-per-em': 'unitsPerEm',
6997 unselectable: 'unselectable',
6998 valphabetic: 'vAlphabetic',
6999 'v-alphabetic': 'vAlphabetic',
7000 values: 'values',
7001 vectoreffect: 'vectorEffect',
7002 'vector-effect': 'vectorEffect',
7003 version: 'version',
7004 vertadvy: 'vertAdvY',
7005 'vert-adv-y': 'vertAdvY',
7006 vertoriginx: 'vertOriginX',
7007 'vert-origin-x': 'vertOriginX',
7008 vertoriginy: 'vertOriginY',
7009 'vert-origin-y': 'vertOriginY',
7010 vhanging: 'vHanging',
7011 'v-hanging': 'vHanging',
7012 videographic: 'vIdeographic',
7013 'v-ideographic': 'vIdeographic',
7014 viewbox: 'viewBox',
7015 viewtarget: 'viewTarget',
7016 visibility: 'visibility',
7017 vmathematical: 'vMathematical',
7018 'v-mathematical': 'vMathematical',
7019 vocab: 'vocab',
7020 widths: 'widths',
7021 wordspacing: 'wordSpacing',
7022 'word-spacing': 'wordSpacing',
7023 writingmode: 'writingMode',
7024 'writing-mode': 'writingMode',
7025 x1: 'x1',
7026 x2: 'x2',
7027 x: 'x',
7028 xchannelselector: 'xChannelSelector',
7029 xheight: 'xHeight',
7030 'x-height': 'xHeight',
7031 xlinkactuate: 'xlinkActuate',
7032 'xlink:actuate': 'xlinkActuate',
7033 xlinkarcrole: 'xlinkArcrole',
7034 'xlink:arcrole': 'xlinkArcrole',
7035 xlinkhref: 'xlinkHref',
7036 'xlink:href': 'xlinkHref',
7037 xlinkrole: 'xlinkRole',
7038 'xlink:role': 'xlinkRole',
7039 xlinkshow: 'xlinkShow',
7040 'xlink:show': 'xlinkShow',
7041 xlinktitle: 'xlinkTitle',
7042 'xlink:title': 'xlinkTitle',
7043 xlinktype: 'xlinkType',
7044 'xlink:type': 'xlinkType',
7045 xmlbase: 'xmlBase',
7046 'xml:base': 'xmlBase',
7047 xmllang: 'xmlLang',
7048 'xml:lang': 'xmlLang',
7049 xmlns: 'xmlns',
7050 'xml:space': 'xmlSpace',
7051 xmlnsxlink: 'xmlnsXlink',
7052 'xmlns:xlink': 'xmlnsXlink',
7053 xmlspace: 'xmlSpace',
7054 y1: 'y1',
7055 y2: 'y2',
7056 y: 'y',
7057 ychannelselector: 'yChannelSelector',
7058 z: 'z',
7059 zoomandpan: 'zoomAndPan'
7060};
7061
7062var ariaProperties = {
7063 'aria-current': 0, // state
7064 'aria-details': 0,
7065 'aria-disabled': 0, // state
7066 'aria-hidden': 0, // state
7067 'aria-invalid': 0, // state
7068 'aria-keyshortcuts': 0,
7069 'aria-label': 0,
7070 'aria-roledescription': 0,
7071 // Widget Attributes
7072 'aria-autocomplete': 0,
7073 'aria-checked': 0,
7074 'aria-expanded': 0,
7075 'aria-haspopup': 0,
7076 'aria-level': 0,
7077 'aria-modal': 0,
7078 'aria-multiline': 0,
7079 'aria-multiselectable': 0,
7080 'aria-orientation': 0,
7081 'aria-placeholder': 0,
7082 'aria-pressed': 0,
7083 'aria-readonly': 0,
7084 'aria-required': 0,
7085 'aria-selected': 0,
7086 'aria-sort': 0,
7087 'aria-valuemax': 0,
7088 'aria-valuemin': 0,
7089 'aria-valuenow': 0,
7090 'aria-valuetext': 0,
7091 // Live Region Attributes
7092 'aria-atomic': 0,
7093 'aria-busy': 0,
7094 'aria-live': 0,
7095 'aria-relevant': 0,
7096 // Drag-and-Drop Attributes
7097 'aria-dropeffect': 0,
7098 'aria-grabbed': 0,
7099 // Relationship Attributes
7100 'aria-activedescendant': 0,
7101 'aria-colcount': 0,
7102 'aria-colindex': 0,
7103 'aria-colspan': 0,
7104 'aria-controls': 0,
7105 'aria-describedby': 0,
7106 'aria-errormessage': 0,
7107 'aria-flowto': 0,
7108 'aria-labelledby': 0,
7109 'aria-owns': 0,
7110 'aria-posinset': 0,
7111 'aria-rowcount': 0,
7112 'aria-rowindex': 0,
7113 'aria-rowspan': 0,
7114 'aria-setsize': 0
7115};
7116
7117var warnedProperties = {};
7118var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7119var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7120
7121var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
7122
7123function validateProperty(tagName, name) {
7124 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) {
7125 return true;
7126 }
7127
7128 if (rARIACamel.test(name)) {
7129 var ariaName = 'aria-' + name.slice(4).toLowerCase();
7130 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null;
7131
7132 // If this is an aria-* attribute, but is not listed in the known DOM
7133 // DOM properties, then it is an invalid aria-* attribute.
7134 if (correctName == null) {
7135 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
7136 warnedProperties[name] = true;
7137 return true;
7138 }
7139 // aria-* attributes should be lowercase; suggest the lowercase version.
7140 if (name !== correctName) {
7141 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
7142 warnedProperties[name] = true;
7143 return true;
7144 }
7145 }
7146
7147 if (rARIA.test(name)) {
7148 var lowerCasedName = name.toLowerCase();
7149 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null;
7150
7151 // If this is an aria-* attribute, but is not listed in the known DOM
7152 // DOM properties, then it is an invalid aria-* attribute.
7153 if (standardName == null) {
7154 warnedProperties[name] = true;
7155 return false;
7156 }
7157 // aria-* attributes should be lowercase; suggest the lowercase version.
7158 if (name !== standardName) {
7159 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
7160 warnedProperties[name] = true;
7161 return true;
7162 }
7163 }
7164
7165 return true;
7166}
7167
7168function warnInvalidARIAProps(type, props) {
7169 var invalidProps = [];
7170
7171 for (var key in props) {
7172 var isValid = validateProperty(type, key);
7173 if (!isValid) {
7174 invalidProps.push(key);
7175 }
7176 }
7177
7178 var unknownPropString = invalidProps.map(function (prop) {
7179 return '`' + prop + '`';
7180 }).join(', ');
7181
7182 if (invalidProps.length === 1) {
7183 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7184 } else if (invalidProps.length > 1) {
7185 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7186 }
7187}
7188
7189function validateProperties(type, props) {
7190 if (isCustomComponent(type, props)) {
7191 return;
7192 }
7193 warnInvalidARIAProps(type, props);
7194}
7195
7196var didWarnValueNull = false;
7197
7198function validateProperties$1(type, props) {
7199 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
7200 return;
7201 }
7202
7203 if (props != null && props.value === null && !didWarnValueNull) {
7204 didWarnValueNull = true;
7205 if (type === 'select' && props.multiple) {
7206 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);
7207 } else {
7208 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);
7209 }
7210 }
7211}
7212
7213var validateProperty$1 = function () {};
7214
7215{
7216 var warnedProperties$1 = {};
7217 var _hasOwnProperty = Object.prototype.hasOwnProperty;
7218 var EVENT_NAME_REGEX = /^on./;
7219 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
7220 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7221 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7222
7223 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
7224 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
7225 return true;
7226 }
7227
7228 var lowerCasedName = name.toLowerCase();
7229 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
7230 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.');
7231 warnedProperties$1[name] = true;
7232 return true;
7233 }
7234
7235 // We can't rely on the event system being injected on the server.
7236 if (canUseEventSystem) {
7237 if (registrationNameModules.hasOwnProperty(name)) {
7238 return true;
7239 }
7240 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
7241 if (registrationName != null) {
7242 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
7243 warnedProperties$1[name] = true;
7244 return true;
7245 }
7246 if (EVENT_NAME_REGEX.test(name)) {
7247 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name);
7248 warnedProperties$1[name] = true;
7249 return true;
7250 }
7251 } else if (EVENT_NAME_REGEX.test(name)) {
7252 // If no event plugins have been injected, we are in a server environment.
7253 // So we can't tell if the event name is correct for sure, but we can filter
7254 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
7255 if (INVALID_EVENT_NAME_REGEX.test(name)) {
7256 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
7257 }
7258 warnedProperties$1[name] = true;
7259 return true;
7260 }
7261
7262 // Let the ARIA attribute hook validate ARIA attributes
7263 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
7264 return true;
7265 }
7266
7267 if (lowerCasedName === 'innerhtml') {
7268 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
7269 warnedProperties$1[name] = true;
7270 return true;
7271 }
7272
7273 if (lowerCasedName === 'aria') {
7274 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
7275 warnedProperties$1[name] = true;
7276 return true;
7277 }
7278
7279 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
7280 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
7281 warnedProperties$1[name] = true;
7282 return true;
7283 }
7284
7285 if (typeof value === 'number' && isNaN(value)) {
7286 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
7287 warnedProperties$1[name] = true;
7288 return true;
7289 }
7290
7291 var propertyInfo = getPropertyInfo(name);
7292 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED;
7293
7294 // Known attributes should match the casing specified in the property config.
7295 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
7296 var standardName = possibleStandardNames[lowerCasedName];
7297 if (standardName !== name) {
7298 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
7299 warnedProperties$1[name] = true;
7300 return true;
7301 }
7302 } else if (!isReserved && name !== lowerCasedName) {
7303 // Unknown attributes should have lowercase casing since that's how they
7304 // will be cased anyway with server rendering.
7305 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);
7306 warnedProperties$1[name] = true;
7307 return true;
7308 }
7309
7310 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7311 if (value) {
7312 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);
7313 } else {
7314 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);
7315 }
7316 warnedProperties$1[name] = true;
7317 return true;
7318 }
7319
7320 // Now that we've validated casing, do not validate
7321 // data types for reserved props
7322 if (isReserved) {
7323 return true;
7324 }
7325
7326 // Warn when a known attribute is a bad type
7327 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7328 warnedProperties$1[name] = true;
7329 return false;
7330 }
7331
7332 // Warn when passing the strings 'false' or 'true' into a boolean prop
7333 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
7334 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);
7335 warnedProperties$1[name] = true;
7336 return true;
7337 }
7338
7339 return true;
7340 };
7341}
7342
7343var warnUnknownProperties = function (type, props, canUseEventSystem) {
7344 var unknownProps = [];
7345 for (var key in props) {
7346 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
7347 if (!isValid) {
7348 unknownProps.push(key);
7349 }
7350 }
7351
7352 var unknownPropString = unknownProps.map(function (prop) {
7353 return '`' + prop + '`';
7354 }).join(', ');
7355 if (unknownProps.length === 1) {
7356 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);
7357 } else if (unknownProps.length > 1) {
7358 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);
7359 }
7360};
7361
7362function validateProperties$2(type, props, canUseEventSystem) {
7363 if (isCustomComponent(type, props)) {
7364 return;
7365 }
7366 warnUnknownProperties(type, props, canUseEventSystem);
7367}
7368
7369// TODO: direct imports like some-package/src/* are bad. Fix me.
7370var didWarnInvalidHydration = false;
7371var didWarnShadyDOM = false;
7372
7373var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
7374var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
7375var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7376var AUTOFOCUS = 'autoFocus';
7377var CHILDREN = 'children';
7378var STYLE$1 = 'style';
7379var HTML = '__html';
7380
7381var HTML_NAMESPACE = Namespaces.html;
7382
7383
7384var warnedUnknownTags = void 0;
7385var suppressHydrationWarning = void 0;
7386
7387var validatePropertiesInDevelopment = void 0;
7388var warnForTextDifference = void 0;
7389var warnForPropDifference = void 0;
7390var warnForExtraAttributes = void 0;
7391var warnForInvalidEventListener = void 0;
7392var canDiffStyleForHydrationWarning = void 0;
7393
7394var normalizeMarkupForTextOrAttribute = void 0;
7395var normalizeHTML = void 0;
7396
7397{
7398 warnedUnknownTags = {
7399 // Chrome is the only major browser not shipping <time>. But as of July
7400 // 2017 it intends to ship it due to widespread usage. We intentionally
7401 // *don't* warn for <time> even if it's unrecognized by Chrome because
7402 // it soon will be, and many apps have been using it anyway.
7403 time: true,
7404 // There are working polyfills for <dialog>. Let people use it.
7405 dialog: true,
7406 // Electron ships a custom <webview> tag to display external web content in
7407 // an isolated frame and process.
7408 // This tag is not present in non Electron environments such as JSDom which
7409 // is often used for testing purposes.
7410 // @see https://electronjs.org/docs/api/webview-tag
7411 webview: true
7412 };
7413
7414 validatePropertiesInDevelopment = function (type, props) {
7415 validateProperties(type, props);
7416 validateProperties$1(type, props);
7417 validateProperties$2(type, props, /* canUseEventSystem */true);
7418 };
7419
7420 // IE 11 parses & normalizes the style attribute as opposed to other
7421 // browsers. It adds spaces and sorts the properties in some
7422 // non-alphabetical order. Handling that would require sorting CSS
7423 // properties in the client & server versions or applying
7424 // `expectedStyle` to a temporary DOM node to read its `style` attribute
7425 // normalized. Since it only affects IE, we're skipping style warnings
7426 // in that browser completely in favor of doing all that work.
7427 // See https://github.com/facebook/react/issues/11807
7428 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
7429
7430 // HTML parsing normalizes CR and CRLF to LF.
7431 // It also can turn \u0000 into \uFFFD inside attributes.
7432 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
7433 // If we have a mismatch, it might be caused by that.
7434 // We will still patch up in this case but not fire the warning.
7435 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
7436 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
7437
7438 normalizeMarkupForTextOrAttribute = function (markup) {
7439 var markupString = typeof markup === 'string' ? markup : '' + markup;
7440 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
7441 };
7442
7443 warnForTextDifference = function (serverText, clientText) {
7444 if (didWarnInvalidHydration) {
7445 return;
7446 }
7447 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
7448 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
7449 if (normalizedServerText === normalizedClientText) {
7450 return;
7451 }
7452 didWarnInvalidHydration = true;
7453 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
7454 };
7455
7456 warnForPropDifference = function (propName, serverValue, clientValue) {
7457 if (didWarnInvalidHydration) {
7458 return;
7459 }
7460 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
7461 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
7462 if (normalizedServerValue === normalizedClientValue) {
7463 return;
7464 }
7465 didWarnInvalidHydration = true;
7466 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
7467 };
7468
7469 warnForExtraAttributes = function (attributeNames) {
7470 if (didWarnInvalidHydration) {
7471 return;
7472 }
7473 didWarnInvalidHydration = true;
7474 var names = [];
7475 attributeNames.forEach(function (name) {
7476 names.push(name);
7477 });
7478 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names);
7479 };
7480
7481 warnForInvalidEventListener = function (registrationName, listener) {
7482 if (listener === false) {
7483 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);
7484 } else {
7485 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
7486 }
7487 };
7488
7489 // Parse the HTML and read it back to normalize the HTML string so that it
7490 // can be used for comparison.
7491 normalizeHTML = function (parent, html) {
7492 // We could have created a separate document here to avoid
7493 // re-initializing custom elements if they exist. But this breaks
7494 // how <noscript> is being handled. So we use the same document.
7495 // See the discussion in https://github.com/facebook/react/pull/11157.
7496 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
7497 testElement.innerHTML = html;
7498 return testElement.innerHTML;
7499 };
7500}
7501
7502function ensureListeningTo(rootContainerElement, registrationName) {
7503 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
7504 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
7505 listenTo(registrationName, doc);
7506}
7507
7508function getOwnerDocumentFromRootContainer(rootContainerElement) {
7509 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
7510}
7511
7512function noop() {}
7513
7514function trapClickOnNonInteractiveElement(node) {
7515 // Mobile Safari does not fire properly bubble click events on
7516 // non-interactive elements, which means delegated click listeners do not
7517 // fire. The workaround for this bug involves attaching an empty click
7518 // listener on the target node.
7519 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
7520 // Just set it using the onclick property so that we don't have to manage any
7521 // bookkeeping for it. Not sure if we need to clear it when the listener is
7522 // removed.
7523 // TODO: Only do this for the relevant Safaris maybe?
7524 node.onclick = noop;
7525}
7526
7527function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
7528 for (var propKey in nextProps) {
7529 if (!nextProps.hasOwnProperty(propKey)) {
7530 continue;
7531 }
7532 var nextProp = nextProps[propKey];
7533 if (propKey === STYLE$1) {
7534 {
7535 if (nextProp) {
7536 // Freeze the next style object so that we can assume it won't be
7537 // mutated. We have already warned for this in the past.
7538 Object.freeze(nextProp);
7539 }
7540 }
7541 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7542 setValueForStyles(domElement, nextProp);
7543 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7544 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7545 if (nextHtml != null) {
7546 setInnerHTML(domElement, nextHtml);
7547 }
7548 } else if (propKey === CHILDREN) {
7549 if (typeof nextProp === 'string') {
7550 // Avoid setting initial textContent when the text is empty. In IE11 setting
7551 // textContent on a <textarea> will cause the placeholder to not
7552 // show within the <textarea> until it has been focused and blurred again.
7553 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
7554 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
7555 if (canSetTextContent) {
7556 setTextContent(domElement, nextProp);
7557 }
7558 } else if (typeof nextProp === 'number') {
7559 setTextContent(domElement, '' + nextProp);
7560 }
7561 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7562 // Noop
7563 } else if (propKey === AUTOFOCUS) {
7564 // We polyfill it separately on the client during commit.
7565 // We could have excluded it in the property list instead of
7566 // adding a special case here, but then it wouldn't be emitted
7567 // on server rendering (but we *do* want to emit it in SSR).
7568 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7569 if (nextProp != null) {
7570 if (true && typeof nextProp !== 'function') {
7571 warnForInvalidEventListener(propKey, nextProp);
7572 }
7573 ensureListeningTo(rootContainerElement, propKey);
7574 }
7575 } else if (nextProp != null) {
7576 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
7577 }
7578 }
7579}
7580
7581function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
7582 // TODO: Handle wasCustomComponentTag
7583 for (var i = 0; i < updatePayload.length; i += 2) {
7584 var propKey = updatePayload[i];
7585 var propValue = updatePayload[i + 1];
7586 if (propKey === STYLE$1) {
7587 setValueForStyles(domElement, propValue);
7588 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7589 setInnerHTML(domElement, propValue);
7590 } else if (propKey === CHILDREN) {
7591 setTextContent(domElement, propValue);
7592 } else {
7593 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
7594 }
7595 }
7596}
7597
7598function createElement(type, props, rootContainerElement, parentNamespace) {
7599 var isCustomComponentTag = void 0;
7600
7601 // We create tags in the namespace of their parent container, except HTML
7602 // tags get no namespace.
7603 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
7604 var domElement = void 0;
7605 var namespaceURI = parentNamespace;
7606 if (namespaceURI === HTML_NAMESPACE) {
7607 namespaceURI = getIntrinsicNamespace(type);
7608 }
7609 if (namespaceURI === HTML_NAMESPACE) {
7610 {
7611 isCustomComponentTag = isCustomComponent(type, props);
7612 // Should this check be gated by parent namespace? Not sure we want to
7613 // allow <SVG> or <mATH>.
7614 !(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;
7615 }
7616
7617 if (type === 'script') {
7618 // Create the script via .innerHTML so its "parser-inserted" flag is
7619 // set to true and it does not execute
7620 var div = ownerDocument.createElement('div');
7621 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
7622 // This is guaranteed to yield a script element.
7623 var firstChild = div.firstChild;
7624 domElement = div.removeChild(firstChild);
7625 } else if (typeof props.is === 'string') {
7626 // $FlowIssue `createElement` should be updated for Web Components
7627 domElement = ownerDocument.createElement(type, { is: props.is });
7628 } else {
7629 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
7630 // See discussion in https://github.com/facebook/react/pull/6896
7631 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
7632 domElement = ownerDocument.createElement(type);
7633 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple`
7634 // attribute on `select`s needs to be added before `option`s are inserted. This prevents
7635 // a bug where the `select` does not scroll to the correct option because singular
7636 // `select` elements automatically pick the first item.
7637 // See https://github.com/facebook/react/issues/13222
7638 if (type === 'select' && props.multiple) {
7639 var node = domElement;
7640 node.multiple = true;
7641 }
7642 }
7643 } else {
7644 domElement = ownerDocument.createElementNS(namespaceURI, type);
7645 }
7646
7647 {
7648 if (namespaceURI === HTML_NAMESPACE) {
7649 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
7650 warnedUnknownTags[type] = true;
7651 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);
7652 }
7653 }
7654 }
7655
7656 return domElement;
7657}
7658
7659function createTextNode(text, rootContainerElement) {
7660 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
7661}
7662
7663function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
7664 var isCustomComponentTag = isCustomComponent(tag, rawProps);
7665 {
7666 validatePropertiesInDevelopment(tag, rawProps);
7667 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
7668 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
7669 didWarnShadyDOM = true;
7670 }
7671 }
7672
7673 // TODO: Make sure that we check isMounted before firing any of these events.
7674 var props = void 0;
7675 switch (tag) {
7676 case 'iframe':
7677 case 'object':
7678 trapBubbledEvent(TOP_LOAD, domElement);
7679 props = rawProps;
7680 break;
7681 case 'video':
7682 case 'audio':
7683 // Create listener for each media event
7684 for (var i = 0; i < mediaEventTypes.length; i++) {
7685 trapBubbledEvent(mediaEventTypes[i], domElement);
7686 }
7687 props = rawProps;
7688 break;
7689 case 'source':
7690 trapBubbledEvent(TOP_ERROR, domElement);
7691 props = rawProps;
7692 break;
7693 case 'img':
7694 case 'image':
7695 case 'link':
7696 trapBubbledEvent(TOP_ERROR, domElement);
7697 trapBubbledEvent(TOP_LOAD, domElement);
7698 props = rawProps;
7699 break;
7700 case 'form':
7701 trapBubbledEvent(TOP_RESET, domElement);
7702 trapBubbledEvent(TOP_SUBMIT, domElement);
7703 props = rawProps;
7704 break;
7705 case 'details':
7706 trapBubbledEvent(TOP_TOGGLE, domElement);
7707 props = rawProps;
7708 break;
7709 case 'input':
7710 initWrapperState(domElement, rawProps);
7711 props = getHostProps(domElement, rawProps);
7712 trapBubbledEvent(TOP_INVALID, domElement);
7713 // For controlled components we always need to ensure we're listening
7714 // to onChange. Even if there is no listener.
7715 ensureListeningTo(rootContainerElement, 'onChange');
7716 break;
7717 case 'option':
7718 validateProps(domElement, rawProps);
7719 props = getHostProps$1(domElement, rawProps);
7720 break;
7721 case 'select':
7722 initWrapperState$1(domElement, rawProps);
7723 props = getHostProps$2(domElement, rawProps);
7724 trapBubbledEvent(TOP_INVALID, domElement);
7725 // For controlled components we always need to ensure we're listening
7726 // to onChange. Even if there is no listener.
7727 ensureListeningTo(rootContainerElement, 'onChange');
7728 break;
7729 case 'textarea':
7730 initWrapperState$2(domElement, rawProps);
7731 props = getHostProps$3(domElement, rawProps);
7732 trapBubbledEvent(TOP_INVALID, domElement);
7733 // For controlled components we always need to ensure we're listening
7734 // to onChange. Even if there is no listener.
7735 ensureListeningTo(rootContainerElement, 'onChange');
7736 break;
7737 default:
7738 props = rawProps;
7739 }
7740
7741 assertValidProps(tag, props);
7742
7743 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
7744
7745 switch (tag) {
7746 case 'input':
7747 // TODO: Make sure we check if this is still unmounted or do any clean
7748 // up necessary since we never stop tracking anymore.
7749 track(domElement);
7750 postMountWrapper(domElement, rawProps, false);
7751 break;
7752 case 'textarea':
7753 // TODO: Make sure we check if this is still unmounted or do any clean
7754 // up necessary since we never stop tracking anymore.
7755 track(domElement);
7756 postMountWrapper$3(domElement, rawProps);
7757 break;
7758 case 'option':
7759 postMountWrapper$1(domElement, rawProps);
7760 break;
7761 case 'select':
7762 postMountWrapper$2(domElement, rawProps);
7763 break;
7764 default:
7765 if (typeof props.onClick === 'function') {
7766 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7767 trapClickOnNonInteractiveElement(domElement);
7768 }
7769 break;
7770 }
7771}
7772
7773// Calculate the diff between the two objects.
7774function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
7775 {
7776 validatePropertiesInDevelopment(tag, nextRawProps);
7777 }
7778
7779 var updatePayload = null;
7780
7781 var lastProps = void 0;
7782 var nextProps = void 0;
7783 switch (tag) {
7784 case 'input':
7785 lastProps = getHostProps(domElement, lastRawProps);
7786 nextProps = getHostProps(domElement, nextRawProps);
7787 updatePayload = [];
7788 break;
7789 case 'option':
7790 lastProps = getHostProps$1(domElement, lastRawProps);
7791 nextProps = getHostProps$1(domElement, nextRawProps);
7792 updatePayload = [];
7793 break;
7794 case 'select':
7795 lastProps = getHostProps$2(domElement, lastRawProps);
7796 nextProps = getHostProps$2(domElement, nextRawProps);
7797 updatePayload = [];
7798 break;
7799 case 'textarea':
7800 lastProps = getHostProps$3(domElement, lastRawProps);
7801 nextProps = getHostProps$3(domElement, nextRawProps);
7802 updatePayload = [];
7803 break;
7804 default:
7805 lastProps = lastRawProps;
7806 nextProps = nextRawProps;
7807 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
7808 // TODO: This cast may not be sound for SVG, MathML or custom elements.
7809 trapClickOnNonInteractiveElement(domElement);
7810 }
7811 break;
7812 }
7813
7814 assertValidProps(tag, nextProps);
7815
7816 var propKey = void 0;
7817 var styleName = void 0;
7818 var styleUpdates = null;
7819 for (propKey in lastProps) {
7820 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
7821 continue;
7822 }
7823 if (propKey === STYLE$1) {
7824 var lastStyle = lastProps[propKey];
7825 for (styleName in lastStyle) {
7826 if (lastStyle.hasOwnProperty(styleName)) {
7827 if (!styleUpdates) {
7828 styleUpdates = {};
7829 }
7830 styleUpdates[styleName] = '';
7831 }
7832 }
7833 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {
7834 // Noop. This is handled by the clear text mechanism.
7835 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7836 // Noop
7837 } else if (propKey === AUTOFOCUS) {
7838 // Noop. It doesn't work on updates anyway.
7839 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7840 // This is a special case. If any listener updates we need to ensure
7841 // that the "current" fiber pointer gets updated so we need a commit
7842 // to update this element.
7843 if (!updatePayload) {
7844 updatePayload = [];
7845 }
7846 } else {
7847 // For all other deleted properties we add it to the queue. We use
7848 // the whitelist in the commit phase instead.
7849 (updatePayload = updatePayload || []).push(propKey, null);
7850 }
7851 }
7852 for (propKey in nextProps) {
7853 var nextProp = nextProps[propKey];
7854 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
7855 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
7856 continue;
7857 }
7858 if (propKey === STYLE$1) {
7859 {
7860 if (nextProp) {
7861 // Freeze the next style object so that we can assume it won't be
7862 // mutated. We have already warned for this in the past.
7863 Object.freeze(nextProp);
7864 }
7865 }
7866 if (lastProp) {
7867 // Unset styles on `lastProp` but not on `nextProp`.
7868 for (styleName in lastProp) {
7869 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
7870 if (!styleUpdates) {
7871 styleUpdates = {};
7872 }
7873 styleUpdates[styleName] = '';
7874 }
7875 }
7876 // Update styles that changed since `lastProp`.
7877 for (styleName in nextProp) {
7878 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
7879 if (!styleUpdates) {
7880 styleUpdates = {};
7881 }
7882 styleUpdates[styleName] = nextProp[styleName];
7883 }
7884 }
7885 } else {
7886 // Relies on `updateStylesByID` not mutating `styleUpdates`.
7887 if (!styleUpdates) {
7888 if (!updatePayload) {
7889 updatePayload = [];
7890 }
7891 updatePayload.push(propKey, styleUpdates);
7892 }
7893 styleUpdates = nextProp;
7894 }
7895 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7896 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7897 var lastHtml = lastProp ? lastProp[HTML] : undefined;
7898 if (nextHtml != null) {
7899 if (lastHtml !== nextHtml) {
7900 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml);
7901 }
7902 } else {
7903 // TODO: It might be too late to clear this if we have children
7904 // inserted already.
7905 }
7906 } else if (propKey === CHILDREN) {
7907 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
7908 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
7909 }
7910 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {
7911 // Noop
7912 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7913 if (nextProp != null) {
7914 // We eagerly listen to this even though we haven't committed yet.
7915 if (true && typeof nextProp !== 'function') {
7916 warnForInvalidEventListener(propKey, nextProp);
7917 }
7918 ensureListeningTo(rootContainerElement, propKey);
7919 }
7920 if (!updatePayload && lastProp !== nextProp) {
7921 // This is a special case. If any listener updates we need to ensure
7922 // that the "current" props pointer gets updated so we need a commit
7923 // to update this element.
7924 updatePayload = [];
7925 }
7926 } else {
7927 // For any other property we always add it to the queue and then we
7928 // filter it out using the whitelist during the commit.
7929 (updatePayload = updatePayload || []).push(propKey, nextProp);
7930 }
7931 }
7932 if (styleUpdates) {
7933 {
7934 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]);
7935 }
7936 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates);
7937 }
7938 return updatePayload;
7939}
7940
7941// Apply the diff.
7942function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
7943 // Update checked *before* name.
7944 // In the middle of an update, it is possible to have multiple checked.
7945 // When a checked radio tries to change name, browser makes another radio's checked false.
7946 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
7947 updateChecked(domElement, nextRawProps);
7948 }
7949
7950 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
7951 var isCustomComponentTag = isCustomComponent(tag, nextRawProps);
7952 // Apply the diff.
7953 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag);
7954
7955 // TODO: Ensure that an update gets scheduled if any of the special props
7956 // changed.
7957 switch (tag) {
7958 case 'input':
7959 // Update the wrapper around inputs *after* updating props. This has to
7960 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
7961 // raise warnings and prevent the new value from being assigned.
7962 updateWrapper(domElement, nextRawProps);
7963 break;
7964 case 'textarea':
7965 updateWrapper$1(domElement, nextRawProps);
7966 break;
7967 case 'select':
7968 // <select> value update needs to occur after <option> children
7969 // reconciliation
7970 postUpdateWrapper(domElement, nextRawProps);
7971 break;
7972 }
7973}
7974
7975function getPossibleStandardName(propName) {
7976 {
7977 var lowerCasedName = propName.toLowerCase();
7978 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
7979 return null;
7980 }
7981 return possibleStandardNames[lowerCasedName] || null;
7982 }
7983 return null;
7984}
7985
7986function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
7987 var isCustomComponentTag = void 0;
7988 var extraAttributeNames = void 0;
7989
7990 {
7991 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
7992 isCustomComponentTag = isCustomComponent(tag, rawProps);
7993 validatePropertiesInDevelopment(tag, rawProps);
7994 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
7995 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
7996 didWarnShadyDOM = true;
7997 }
7998 }
7999
8000 // TODO: Make sure that we check isMounted before firing any of these events.
8001 switch (tag) {
8002 case 'iframe':
8003 case 'object':
8004 trapBubbledEvent(TOP_LOAD, domElement);
8005 break;
8006 case 'video':
8007 case 'audio':
8008 // Create listener for each media event
8009 for (var i = 0; i < mediaEventTypes.length; i++) {
8010 trapBubbledEvent(mediaEventTypes[i], domElement);
8011 }
8012 break;
8013 case 'source':
8014 trapBubbledEvent(TOP_ERROR, domElement);
8015 break;
8016 case 'img':
8017 case 'image':
8018 case 'link':
8019 trapBubbledEvent(TOP_ERROR, domElement);
8020 trapBubbledEvent(TOP_LOAD, domElement);
8021 break;
8022 case 'form':
8023 trapBubbledEvent(TOP_RESET, domElement);
8024 trapBubbledEvent(TOP_SUBMIT, domElement);
8025 break;
8026 case 'details':
8027 trapBubbledEvent(TOP_TOGGLE, domElement);
8028 break;
8029 case 'input':
8030 initWrapperState(domElement, rawProps);
8031 trapBubbledEvent(TOP_INVALID, domElement);
8032 // For controlled components we always need to ensure we're listening
8033 // to onChange. Even if there is no listener.
8034 ensureListeningTo(rootContainerElement, 'onChange');
8035 break;
8036 case 'option':
8037 validateProps(domElement, rawProps);
8038 break;
8039 case 'select':
8040 initWrapperState$1(domElement, rawProps);
8041 trapBubbledEvent(TOP_INVALID, domElement);
8042 // For controlled components we always need to ensure we're listening
8043 // to onChange. Even if there is no listener.
8044 ensureListeningTo(rootContainerElement, 'onChange');
8045 break;
8046 case 'textarea':
8047 initWrapperState$2(domElement, rawProps);
8048 trapBubbledEvent(TOP_INVALID, domElement);
8049 // For controlled components we always need to ensure we're listening
8050 // to onChange. Even if there is no listener.
8051 ensureListeningTo(rootContainerElement, 'onChange');
8052 break;
8053 }
8054
8055 assertValidProps(tag, rawProps);
8056
8057 {
8058 extraAttributeNames = new Set();
8059 var attributes = domElement.attributes;
8060 for (var _i = 0; _i < attributes.length; _i++) {
8061 var name = attributes[_i].name.toLowerCase();
8062 switch (name) {
8063 // Built-in SSR attribute is whitelisted
8064 case 'data-reactroot':
8065 break;
8066 // Controlled attributes are not validated
8067 // TODO: Only ignore them on controlled tags.
8068 case 'value':
8069 break;
8070 case 'checked':
8071 break;
8072 case 'selected':
8073 break;
8074 default:
8075 // Intentionally use the original name.
8076 // See discussion in https://github.com/facebook/react/pull/10676.
8077 extraAttributeNames.add(attributes[_i].name);
8078 }
8079 }
8080 }
8081
8082 var updatePayload = null;
8083 for (var propKey in rawProps) {
8084 if (!rawProps.hasOwnProperty(propKey)) {
8085 continue;
8086 }
8087 var nextProp = rawProps[propKey];
8088 if (propKey === CHILDREN) {
8089 // For text content children we compare against textContent. This
8090 // might match additional HTML that is hidden when we read it using
8091 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
8092 // satisfies our requirement. Our requirement is not to produce perfect
8093 // HTML and attributes. Ideally we should preserve structure but it's
8094 // ok not to if the visible content is still enough to indicate what
8095 // even listeners these nodes might be wired up to.
8096 // TODO: Warn if there is more than a single textNode as a child.
8097 // TODO: Should we use domElement.firstChild.nodeValue to compare?
8098 if (typeof nextProp === 'string') {
8099 if (domElement.textContent !== nextProp) {
8100 if (true && !suppressHydrationWarning) {
8101 warnForTextDifference(domElement.textContent, nextProp);
8102 }
8103 updatePayload = [CHILDREN, nextProp];
8104 }
8105 } else if (typeof nextProp === 'number') {
8106 if (domElement.textContent !== '' + nextProp) {
8107 if (true && !suppressHydrationWarning) {
8108 warnForTextDifference(domElement.textContent, nextProp);
8109 }
8110 updatePayload = [CHILDREN, '' + nextProp];
8111 }
8112 }
8113 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8114 if (nextProp != null) {
8115 if (true && typeof nextProp !== 'function') {
8116 warnForInvalidEventListener(propKey, nextProp);
8117 }
8118 ensureListeningTo(rootContainerElement, propKey);
8119 }
8120 } else if (true &&
8121 // Convince Flow we've calculated it (it's DEV-only in this method.)
8122 typeof isCustomComponentTag === 'boolean') {
8123 // Validate that the properties correspond to their expected values.
8124 var serverValue = void 0;
8125 var propertyInfo = getPropertyInfo(propKey);
8126 if (suppressHydrationWarning) {
8127 // Don't bother comparing. We're ignoring all these warnings.
8128 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 ||
8129 // Controlled attributes are not validated
8130 // TODO: Only ignore them on controlled tags.
8131 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {
8132 // Noop
8133 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8134 var serverHTML = domElement.innerHTML;
8135 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8136 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
8137 if (expectedHTML !== serverHTML) {
8138 warnForPropDifference(propKey, serverHTML, expectedHTML);
8139 }
8140 } else if (propKey === STYLE$1) {
8141 // $FlowFixMe - Should be inferred as not undefined.
8142 extraAttributeNames.delete(propKey);
8143
8144 if (canDiffStyleForHydrationWarning) {
8145 var expectedStyle = createDangerousStringForStyles(nextProp);
8146 serverValue = domElement.getAttribute('style');
8147 if (expectedStyle !== serverValue) {
8148 warnForPropDifference(propKey, serverValue, expectedStyle);
8149 }
8150 }
8151 } else if (isCustomComponentTag) {
8152 // $FlowFixMe - Should be inferred as not undefined.
8153 extraAttributeNames.delete(propKey.toLowerCase());
8154 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8155
8156 if (nextProp !== serverValue) {
8157 warnForPropDifference(propKey, serverValue, nextProp);
8158 }
8159 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
8160 var isMismatchDueToBadCasing = false;
8161 if (propertyInfo !== null) {
8162 // $FlowFixMe - Should be inferred as not undefined.
8163 extraAttributeNames.delete(propertyInfo.attributeName);
8164 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
8165 } else {
8166 var ownNamespace = parentNamespace;
8167 if (ownNamespace === HTML_NAMESPACE) {
8168 ownNamespace = getIntrinsicNamespace(tag);
8169 }
8170 if (ownNamespace === HTML_NAMESPACE) {
8171 // $FlowFixMe - Should be inferred as not undefined.
8172 extraAttributeNames.delete(propKey.toLowerCase());
8173 } else {
8174 var standardName = getPossibleStandardName(propKey);
8175 if (standardName !== null && standardName !== propKey) {
8176 // If an SVG prop is supplied with bad casing, it will
8177 // be successfully parsed from HTML, but will produce a mismatch
8178 // (and would be incorrectly rendered on the client).
8179 // However, we already warn about bad casing elsewhere.
8180 // So we'll skip the misleading extra mismatch warning in this case.
8181 isMismatchDueToBadCasing = true;
8182 // $FlowFixMe - Should be inferred as not undefined.
8183 extraAttributeNames.delete(standardName);
8184 }
8185 // $FlowFixMe - Should be inferred as not undefined.
8186 extraAttributeNames.delete(propKey);
8187 }
8188 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8189 }
8190
8191 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
8192 warnForPropDifference(propKey, serverValue, nextProp);
8193 }
8194 }
8195 }
8196 }
8197
8198 {
8199 // $FlowFixMe - Should be inferred as not undefined.
8200 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
8201 // $FlowFixMe - Should be inferred as not undefined.
8202 warnForExtraAttributes(extraAttributeNames);
8203 }
8204 }
8205
8206 switch (tag) {
8207 case 'input':
8208 // TODO: Make sure we check if this is still unmounted or do any clean
8209 // up necessary since we never stop tracking anymore.
8210 track(domElement);
8211 postMountWrapper(domElement, rawProps, true);
8212 break;
8213 case 'textarea':
8214 // TODO: Make sure we check if this is still unmounted or do any clean
8215 // up necessary since we never stop tracking anymore.
8216 track(domElement);
8217 postMountWrapper$3(domElement, rawProps);
8218 break;
8219 case 'select':
8220 case 'option':
8221 // For input and textarea we current always set the value property at
8222 // post mount to force it to diverge from attributes. However, for
8223 // option and select we don't quite do the same thing and select
8224 // is not resilient to the DOM state changing so we don't do that here.
8225 // TODO: Consider not doing this for input and textarea.
8226 break;
8227 default:
8228 if (typeof rawProps.onClick === 'function') {
8229 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8230 trapClickOnNonInteractiveElement(domElement);
8231 }
8232 break;
8233 }
8234
8235 return updatePayload;
8236}
8237
8238function diffHydratedText(textNode, text) {
8239 var isDifferent = textNode.nodeValue !== text;
8240 return isDifferent;
8241}
8242
8243function warnForUnmatchedText(textNode, text) {
8244 {
8245 warnForTextDifference(textNode.nodeValue, text);
8246 }
8247}
8248
8249function warnForDeletedHydratableElement(parentNode, child) {
8250 {
8251 if (didWarnInvalidHydration) {
8252 return;
8253 }
8254 didWarnInvalidHydration = true;
8255 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
8256 }
8257}
8258
8259function warnForDeletedHydratableText(parentNode, child) {
8260 {
8261 if (didWarnInvalidHydration) {
8262 return;
8263 }
8264 didWarnInvalidHydration = true;
8265 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
8266 }
8267}
8268
8269function warnForInsertedHydratedElement(parentNode, tag, props) {
8270 {
8271 if (didWarnInvalidHydration) {
8272 return;
8273 }
8274 didWarnInvalidHydration = true;
8275 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
8276 }
8277}
8278
8279function warnForInsertedHydratedText(parentNode, text) {
8280 {
8281 if (text === '') {
8282 // We expect to insert empty text nodes since they're not represented in
8283 // the HTML.
8284 // TODO: Remove this special case if we can just avoid inserting empty
8285 // text nodes.
8286 return;
8287 }
8288 if (didWarnInvalidHydration) {
8289 return;
8290 }
8291 didWarnInvalidHydration = true;
8292 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
8293 }
8294}
8295
8296function restoreControlledState$1(domElement, tag, props) {
8297 switch (tag) {
8298 case 'input':
8299 restoreControlledState(domElement, props);
8300 return;
8301 case 'textarea':
8302 restoreControlledState$3(domElement, props);
8303 return;
8304 case 'select':
8305 restoreControlledState$2(domElement, props);
8306 return;
8307 }
8308}
8309
8310// TODO: direct imports like some-package/src/* are bad. Fix me.
8311var validateDOMNesting = function () {};
8312var updatedAncestorInfo = function () {};
8313
8314{
8315 // This validation code was written based on the HTML5 parsing spec:
8316 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8317 //
8318 // Note: this does not catch all invalid nesting, nor does it try to (as it's
8319 // not clear what practical benefit doing so provides); instead, we warn only
8320 // for cases where the parser will give a parse tree differing from what React
8321 // intended. For example, <b><div></div></b> is invalid but we don't warn
8322 // because it still parses correctly; we do warn for other cases like nested
8323 // <p> tags where the beginning of the second element implicitly closes the
8324 // first, causing a confusing mess.
8325
8326 // https://html.spec.whatwg.org/multipage/syntax.html#special
8327 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'];
8328
8329 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
8330 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
8331
8332 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
8333 // TODO: Distinguish by namespace here -- for <title>, including it here
8334 // errs on the side of fewer warnings
8335 'foreignObject', 'desc', 'title'];
8336
8337 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
8338 var buttonScopeTags = inScopeTags.concat(['button']);
8339
8340 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
8341 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
8342
8343 var emptyAncestorInfo = {
8344 current: null,
8345
8346 formTag: null,
8347 aTagInScope: null,
8348 buttonTagInScope: null,
8349 nobrTagInScope: null,
8350 pTagInButtonScope: null,
8351
8352 listItemTagAutoclosing: null,
8353 dlItemTagAutoclosing: null
8354 };
8355
8356 updatedAncestorInfo = function (oldInfo, tag) {
8357 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
8358 var info = { tag: tag };
8359
8360 if (inScopeTags.indexOf(tag) !== -1) {
8361 ancestorInfo.aTagInScope = null;
8362 ancestorInfo.buttonTagInScope = null;
8363 ancestorInfo.nobrTagInScope = null;
8364 }
8365 if (buttonScopeTags.indexOf(tag) !== -1) {
8366 ancestorInfo.pTagInButtonScope = null;
8367 }
8368
8369 // See rules for 'li', 'dd', 'dt' start tags in
8370 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8371 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
8372 ancestorInfo.listItemTagAutoclosing = null;
8373 ancestorInfo.dlItemTagAutoclosing = null;
8374 }
8375
8376 ancestorInfo.current = info;
8377
8378 if (tag === 'form') {
8379 ancestorInfo.formTag = info;
8380 }
8381 if (tag === 'a') {
8382 ancestorInfo.aTagInScope = info;
8383 }
8384 if (tag === 'button') {
8385 ancestorInfo.buttonTagInScope = info;
8386 }
8387 if (tag === 'nobr') {
8388 ancestorInfo.nobrTagInScope = info;
8389 }
8390 if (tag === 'p') {
8391 ancestorInfo.pTagInButtonScope = info;
8392 }
8393 if (tag === 'li') {
8394 ancestorInfo.listItemTagAutoclosing = info;
8395 }
8396 if (tag === 'dd' || tag === 'dt') {
8397 ancestorInfo.dlItemTagAutoclosing = info;
8398 }
8399
8400 return ancestorInfo;
8401 };
8402
8403 /**
8404 * Returns whether
8405 */
8406 var isTagValidWithParent = function (tag, parentTag) {
8407 // First, let's check if we're in an unusual parsing mode...
8408 switch (parentTag) {
8409 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
8410 case 'select':
8411 return tag === 'option' || tag === 'optgroup' || tag === '#text';
8412 case 'optgroup':
8413 return tag === 'option' || tag === '#text';
8414 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
8415 // but
8416 case 'option':
8417 return tag === '#text';
8418 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
8419 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
8420 // No special behavior since these rules fall back to "in body" mode for
8421 // all except special table nodes which cause bad parsing behavior anyway.
8422
8423 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
8424 case 'tr':
8425 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
8426 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
8427 case 'tbody':
8428 case 'thead':
8429 case 'tfoot':
8430 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
8431 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
8432 case 'colgroup':
8433 return tag === 'col' || tag === 'template';
8434 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
8435 case 'table':
8436 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
8437 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
8438 case 'head':
8439 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
8440 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
8441 case 'html':
8442 return tag === 'head' || tag === 'body';
8443 case '#document':
8444 return tag === 'html';
8445 }
8446
8447 // Probably in the "in body" parsing mode, so we outlaw only tag combos
8448 // where the parsing rules cause implicit opens or closes to be added.
8449 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
8450 switch (tag) {
8451 case 'h1':
8452 case 'h2':
8453 case 'h3':
8454 case 'h4':
8455 case 'h5':
8456 case 'h6':
8457 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
8458
8459 case 'rp':
8460 case 'rt':
8461 return impliedEndTags.indexOf(parentTag) === -1;
8462
8463 case 'body':
8464 case 'caption':
8465 case 'col':
8466 case 'colgroup':
8467 case 'frame':
8468 case 'head':
8469 case 'html':
8470 case 'tbody':
8471 case 'td':
8472 case 'tfoot':
8473 case 'th':
8474 case 'thead':
8475 case 'tr':
8476 // These tags are only valid with a few parents that have special child
8477 // parsing rules -- if we're down here, then none of those matched and
8478 // so we allow it only if we don't know what the parent is, as all other
8479 // cases are invalid.
8480 return parentTag == null;
8481 }
8482
8483 return true;
8484 };
8485
8486 /**
8487 * Returns whether
8488 */
8489 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
8490 switch (tag) {
8491 case 'address':
8492 case 'article':
8493 case 'aside':
8494 case 'blockquote':
8495 case 'center':
8496 case 'details':
8497 case 'dialog':
8498 case 'dir':
8499 case 'div':
8500 case 'dl':
8501 case 'fieldset':
8502 case 'figcaption':
8503 case 'figure':
8504 case 'footer':
8505 case 'header':
8506 case 'hgroup':
8507 case 'main':
8508 case 'menu':
8509 case 'nav':
8510 case 'ol':
8511 case 'p':
8512 case 'section':
8513 case 'summary':
8514 case 'ul':
8515 case 'pre':
8516 case 'listing':
8517 case 'table':
8518 case 'hr':
8519 case 'xmp':
8520 case 'h1':
8521 case 'h2':
8522 case 'h3':
8523 case 'h4':
8524 case 'h5':
8525 case 'h6':
8526 return ancestorInfo.pTagInButtonScope;
8527
8528 case 'form':
8529 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
8530
8531 case 'li':
8532 return ancestorInfo.listItemTagAutoclosing;
8533
8534 case 'dd':
8535 case 'dt':
8536 return ancestorInfo.dlItemTagAutoclosing;
8537
8538 case 'button':
8539 return ancestorInfo.buttonTagInScope;
8540
8541 case 'a':
8542 // Spec says something about storing a list of markers, but it sounds
8543 // equivalent to this check.
8544 return ancestorInfo.aTagInScope;
8545
8546 case 'nobr':
8547 return ancestorInfo.nobrTagInScope;
8548 }
8549
8550 return null;
8551 };
8552
8553 var didWarn = {};
8554
8555 validateDOMNesting = function (childTag, childText, ancestorInfo) {
8556 ancestorInfo = ancestorInfo || emptyAncestorInfo;
8557 var parentInfo = ancestorInfo.current;
8558 var parentTag = parentInfo && parentInfo.tag;
8559
8560 if (childText != null) {
8561 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
8562 childTag = '#text';
8563 }
8564
8565 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
8566 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
8567 var invalidParentOrAncestor = invalidParent || invalidAncestor;
8568 if (!invalidParentOrAncestor) {
8569 return;
8570 }
8571
8572 var ancestorTag = invalidParentOrAncestor.tag;
8573 var addendum = getCurrentFiberStackInDev();
8574
8575 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
8576 if (didWarn[warnKey]) {
8577 return;
8578 }
8579 didWarn[warnKey] = true;
8580
8581 var tagDisplayName = childTag;
8582 var whitespaceInfo = '';
8583 if (childTag === '#text') {
8584 if (/\S/.test(childText)) {
8585 tagDisplayName = 'Text nodes';
8586 } else {
8587 tagDisplayName = 'Whitespace text nodes';
8588 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
8589 }
8590 } else {
8591 tagDisplayName = '<' + childTag + '>';
8592 }
8593
8594 if (invalidParent) {
8595 var info = '';
8596 if (ancestorTag === 'table' && childTag === 'tr') {
8597 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
8598 }
8599 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
8600 } else {
8601 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
8602 }
8603 };
8604}
8605
8606// Renderers that don't support persistence
8607// can re-export everything from this module.
8608
8609function shim() {
8610 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
8611}
8612
8613// Persistence (when unsupported)
8614var supportsPersistence = false;
8615var cloneInstance = shim;
8616var createContainerChildSet = shim;
8617var appendChildToContainerChildSet = shim;
8618var finalizeContainerChildren = shim;
8619var replaceContainerChildren = shim;
8620var cloneHiddenInstance = shim;
8621var cloneUnhiddenInstance = shim;
8622var createHiddenTextInstance = shim;
8623
8624var SUPPRESS_HYDRATION_WARNING = void 0;
8625{
8626 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8627}
8628
8629var SUSPENSE_START_DATA = '$';
8630var SUSPENSE_END_DATA = '/$';
8631
8632var STYLE = 'style';
8633
8634var eventsEnabled = null;
8635var selectionInformation = null;
8636
8637function shouldAutoFocusHostComponent(type, props) {
8638 switch (type) {
8639 case 'button':
8640 case 'input':
8641 case 'select':
8642 case 'textarea':
8643 return !!props.autoFocus;
8644 }
8645 return false;
8646}
8647
8648function getRootHostContext(rootContainerInstance) {
8649 var type = void 0;
8650 var namespace = void 0;
8651 var nodeType = rootContainerInstance.nodeType;
8652 switch (nodeType) {
8653 case DOCUMENT_NODE:
8654 case DOCUMENT_FRAGMENT_NODE:
8655 {
8656 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
8657 var root = rootContainerInstance.documentElement;
8658 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
8659 break;
8660 }
8661 default:
8662 {
8663 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
8664 var ownNamespace = container.namespaceURI || null;
8665 type = container.tagName;
8666 namespace = getChildNamespace(ownNamespace, type);
8667 break;
8668 }
8669 }
8670 {
8671 var validatedTag = type.toLowerCase();
8672 var _ancestorInfo = updatedAncestorInfo(null, validatedTag);
8673 return { namespace: namespace, ancestorInfo: _ancestorInfo };
8674 }
8675 return namespace;
8676}
8677
8678function getChildHostContext(parentHostContext, type, rootContainerInstance) {
8679 {
8680 var parentHostContextDev = parentHostContext;
8681 var _namespace = getChildNamespace(parentHostContextDev.namespace, type);
8682 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
8683 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 };
8684 }
8685 var parentNamespace = parentHostContext;
8686 return getChildNamespace(parentNamespace, type);
8687}
8688
8689function getPublicInstance(instance) {
8690 return instance;
8691}
8692
8693function prepareForCommit(containerInfo) {
8694 eventsEnabled = isEnabled();
8695 selectionInformation = getSelectionInformation();
8696 setEnabled(false);
8697}
8698
8699function resetAfterCommit(containerInfo) {
8700 restoreSelection(selectionInformation);
8701 selectionInformation = null;
8702 setEnabled(eventsEnabled);
8703 eventsEnabled = null;
8704}
8705
8706function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
8707 var parentNamespace = void 0;
8708 {
8709 // TODO: take namespace into account when validating.
8710 var hostContextDev = hostContext;
8711 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
8712 if (typeof props.children === 'string' || typeof props.children === 'number') {
8713 var string = '' + props.children;
8714 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8715 validateDOMNesting(null, string, ownAncestorInfo);
8716 }
8717 parentNamespace = hostContextDev.namespace;
8718 }
8719 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
8720 precacheFiberNode(internalInstanceHandle, domElement);
8721 updateFiberProps(domElement, props);
8722 return domElement;
8723}
8724
8725function appendInitialChild(parentInstance, child) {
8726 parentInstance.appendChild(child);
8727}
8728
8729function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
8730 setInitialProperties(domElement, type, props, rootContainerInstance);
8731 return shouldAutoFocusHostComponent(type, props);
8732}
8733
8734function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
8735 {
8736 var hostContextDev = hostContext;
8737 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
8738 var string = '' + newProps.children;
8739 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
8740 validateDOMNesting(null, string, ownAncestorInfo);
8741 }
8742 }
8743 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
8744}
8745
8746function shouldSetTextContent(type, props) {
8747 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;
8748}
8749
8750function shouldDeprioritizeSubtree(type, props) {
8751 return !!props.hidden;
8752}
8753
8754function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
8755 {
8756 var hostContextDev = hostContext;
8757 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
8758 }
8759 var textNode = createTextNode(text, rootContainerInstance);
8760 precacheFiberNode(internalInstanceHandle, textNode);
8761 return textNode;
8762}
8763
8764var isPrimaryRenderer = true;
8765// This initialization code may run even on server environments
8766// if a component just imports ReactDOM (e.g. for findDOMNode).
8767// Some environments might not have setTimeout or clearTimeout.
8768var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
8769var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
8770var noTimeout = -1;
8771var schedulePassiveEffects = scheduler.unstable_scheduleCallback;
8772var cancelPassiveEffects = scheduler.unstable_cancelCallback;
8773
8774// -------------------
8775// Mutation
8776// -------------------
8777
8778var supportsMutation = true;
8779
8780function commitMount(domElement, type, newProps, internalInstanceHandle) {
8781 // Despite the naming that might imply otherwise, this method only
8782 // fires if there is an `Update` effect scheduled during mounting.
8783 // This happens if `finalizeInitialChildren` returns `true` (which it
8784 // does to implement the `autoFocus` attribute on the client). But
8785 // there are also other cases when this might happen (such as patching
8786 // up text content during hydration mismatch). So we'll check this again.
8787 if (shouldAutoFocusHostComponent(type, newProps)) {
8788 domElement.focus();
8789 }
8790}
8791
8792function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
8793 // Update the props handle so that we know which props are the ones with
8794 // with current event handlers.
8795 updateFiberProps(domElement, newProps);
8796 // Apply the diff to the DOM node.
8797 updateProperties(domElement, updatePayload, type, oldProps, newProps);
8798}
8799
8800function resetTextContent(domElement) {
8801 setTextContent(domElement, '');
8802}
8803
8804function commitTextUpdate(textInstance, oldText, newText) {
8805 textInstance.nodeValue = newText;
8806}
8807
8808function appendChild(parentInstance, child) {
8809 parentInstance.appendChild(child);
8810}
8811
8812function appendChildToContainer(container, child) {
8813 var parentNode = void 0;
8814 if (container.nodeType === COMMENT_NODE) {
8815 parentNode = container.parentNode;
8816 parentNode.insertBefore(child, container);
8817 } else {
8818 parentNode = container;
8819 parentNode.appendChild(child);
8820 }
8821 // This container might be used for a portal.
8822 // If something inside a portal is clicked, that click should bubble
8823 // through the React tree. However, on Mobile Safari the click would
8824 // never bubble through the *DOM* tree unless an ancestor with onclick
8825 // event exists. So we wouldn't see it and dispatch it.
8826 // This is why we ensure that non React root containers have inline onclick
8827 // defined.
8828 // https://github.com/facebook/react/issues/11918
8829 var reactRootContainer = container._reactRootContainer;
8830 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
8831 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8832 trapClickOnNonInteractiveElement(parentNode);
8833 }
8834}
8835
8836function insertBefore(parentInstance, child, beforeChild) {
8837 parentInstance.insertBefore(child, beforeChild);
8838}
8839
8840function insertInContainerBefore(container, child, beforeChild) {
8841 if (container.nodeType === COMMENT_NODE) {
8842 container.parentNode.insertBefore(child, beforeChild);
8843 } else {
8844 container.insertBefore(child, beforeChild);
8845 }
8846}
8847
8848function removeChild(parentInstance, child) {
8849 parentInstance.removeChild(child);
8850}
8851
8852function removeChildFromContainer(container, child) {
8853 if (container.nodeType === COMMENT_NODE) {
8854 container.parentNode.removeChild(child);
8855 } else {
8856 container.removeChild(child);
8857 }
8858}
8859
8860function clearSuspenseBoundary(parentInstance, suspenseInstance) {
8861 var node = suspenseInstance;
8862 // Delete all nodes within this suspense boundary.
8863 // There might be nested nodes so we need to keep track of how
8864 // deep we are and only break out when we're back on top.
8865 var depth = 0;
8866 do {
8867 var nextNode = node.nextSibling;
8868 parentInstance.removeChild(node);
8869 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
8870 var data = nextNode.data;
8871 if (data === SUSPENSE_END_DATA) {
8872 if (depth === 0) {
8873 parentInstance.removeChild(nextNode);
8874 return;
8875 } else {
8876 depth--;
8877 }
8878 } else if (data === SUSPENSE_START_DATA) {
8879 depth++;
8880 }
8881 }
8882 node = nextNode;
8883 } while (node);
8884 // TODO: Warn, we didn't find the end comment boundary.
8885}
8886
8887function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
8888 if (container.nodeType === COMMENT_NODE) {
8889 clearSuspenseBoundary(container.parentNode, suspenseInstance);
8890 } else if (container.nodeType === ELEMENT_NODE) {
8891 clearSuspenseBoundary(container, suspenseInstance);
8892 } else {
8893 // Document nodes should never contain suspense boundaries.
8894 }
8895}
8896
8897function hideInstance(instance) {
8898 // TODO: Does this work for all element types? What about MathML? Should we
8899 // pass host context to this method?
8900 instance = instance;
8901 instance.style.display = 'none';
8902}
8903
8904function hideTextInstance(textInstance) {
8905 textInstance.nodeValue = '';
8906}
8907
8908function unhideInstance(instance, props) {
8909 instance = instance;
8910 var styleProp = props[STYLE];
8911 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
8912 instance.style.display = dangerousStyleValue('display', display);
8913}
8914
8915function unhideTextInstance(textInstance, text) {
8916 textInstance.nodeValue = text;
8917}
8918
8919// -------------------
8920// Hydration
8921// -------------------
8922
8923var supportsHydration = true;
8924
8925function canHydrateInstance(instance, type, props) {
8926 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
8927 return null;
8928 }
8929 // This has now been refined to an element node.
8930 return instance;
8931}
8932
8933function canHydrateTextInstance(instance, text) {
8934 if (text === '' || instance.nodeType !== TEXT_NODE) {
8935 // Empty strings are not parsed by HTML so there won't be a correct match here.
8936 return null;
8937 }
8938 // This has now been refined to a text node.
8939 return instance;
8940}
8941
8942function canHydrateSuspenseInstance(instance) {
8943 if (instance.nodeType !== COMMENT_NODE) {
8944 // Empty strings are not parsed by HTML so there won't be a correct match here.
8945 return null;
8946 }
8947 // This has now been refined to a suspense node.
8948 return instance;
8949}
8950
8951function getNextHydratableSibling(instance) {
8952 var node = instance.nextSibling;
8953 // Skip non-hydratable nodes.
8954 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || node.nodeType !== COMMENT_NODE || node.data !== SUSPENSE_START_DATA)) {
8955 node = node.nextSibling;
8956 }
8957 return node;
8958}
8959
8960function getFirstHydratableChild(parentInstance) {
8961 var next = parentInstance.firstChild;
8962 // Skip non-hydratable nodes.
8963 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || next.nodeType !== COMMENT_NODE || next.data !== SUSPENSE_START_DATA)) {
8964 next = next.nextSibling;
8965 }
8966 return next;
8967}
8968
8969function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
8970 precacheFiberNode(internalInstanceHandle, instance);
8971 // TODO: Possibly defer this until the commit phase where all the events
8972 // get attached.
8973 updateFiberProps(instance, props);
8974 var parentNamespace = void 0;
8975 {
8976 var hostContextDev = hostContext;
8977 parentNamespace = hostContextDev.namespace;
8978 }
8979 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
8980}
8981
8982function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
8983 precacheFiberNode(internalInstanceHandle, textInstance);
8984 return diffHydratedText(textInstance, text);
8985}
8986
8987function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
8988 var node = suspenseInstance.nextSibling;
8989 // Skip past all nodes within this suspense boundary.
8990 // There might be nested nodes so we need to keep track of how
8991 // deep we are and only break out when we're back on top.
8992 var depth = 0;
8993 while (node) {
8994 if (node.nodeType === COMMENT_NODE) {
8995 var data = node.data;
8996 if (data === SUSPENSE_END_DATA) {
8997 if (depth === 0) {
8998 return getNextHydratableSibling(node);
8999 } else {
9000 depth--;
9001 }
9002 } else if (data === SUSPENSE_START_DATA) {
9003 depth++;
9004 }
9005 }
9006 node = node.nextSibling;
9007 }
9008 // TODO: Warn, we didn't find the end comment boundary.
9009 return null;
9010}
9011
9012function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9013 {
9014 warnForUnmatchedText(textInstance, text);
9015 }
9016}
9017
9018function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
9019 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9020 warnForUnmatchedText(textInstance, text);
9021 }
9022}
9023
9024function didNotHydrateContainerInstance(parentContainer, instance) {
9025 {
9026 if (instance.nodeType === ELEMENT_NODE) {
9027 warnForDeletedHydratableElement(parentContainer, instance);
9028 } else if (instance.nodeType === COMMENT_NODE) {
9029 // TODO: warnForDeletedHydratableSuspenseBoundary
9030 } else {
9031 warnForDeletedHydratableText(parentContainer, instance);
9032 }
9033 }
9034}
9035
9036function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
9037 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9038 if (instance.nodeType === ELEMENT_NODE) {
9039 warnForDeletedHydratableElement(parentInstance, instance);
9040 } else if (instance.nodeType === COMMENT_NODE) {
9041 // TODO: warnForDeletedHydratableSuspenseBoundary
9042 } else {
9043 warnForDeletedHydratableText(parentInstance, instance);
9044 }
9045 }
9046}
9047
9048function didNotFindHydratableContainerInstance(parentContainer, type, props) {
9049 {
9050 warnForInsertedHydratedElement(parentContainer, type, props);
9051 }
9052}
9053
9054function didNotFindHydratableContainerTextInstance(parentContainer, text) {
9055 {
9056 warnForInsertedHydratedText(parentContainer, text);
9057 }
9058}
9059
9060
9061
9062function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
9063 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9064 warnForInsertedHydratedElement(parentInstance, type, props);
9065 }
9066}
9067
9068function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
9069 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9070 warnForInsertedHydratedText(parentInstance, text);
9071 }
9072}
9073
9074function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
9075 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9076 // TODO: warnForInsertedHydratedSuspense(parentInstance);
9077 }
9078}
9079
9080// Prefix measurements so that it's possible to filter them.
9081// Longer prefixes are hard to read in DevTools.
9082var reactEmoji = '\u269B';
9083var warningEmoji = '\u26D4';
9084var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
9085
9086// Keep track of current fiber so that we know the path to unwind on pause.
9087// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
9088var currentFiber = null;
9089// If we're in the middle of user code, which fiber and method is it?
9090// Reusing `currentFiber` would be confusing for this because user code fiber
9091// can change during commit phase too, but we don't need to unwind it (since
9092// lifecycles in the commit phase don't resemble a tree).
9093var currentPhase = null;
9094var currentPhaseFiber = null;
9095// Did lifecycle hook schedule an update? This is often a performance problem,
9096// so we will keep track of it, and include it in the report.
9097// Track commits caused by cascading updates.
9098var isCommitting = false;
9099var hasScheduledUpdateInCurrentCommit = false;
9100var hasScheduledUpdateInCurrentPhase = false;
9101var commitCountInCurrentWorkLoop = 0;
9102var effectCountInCurrentCommit = 0;
9103var isWaitingForCallback = false;
9104// During commits, we only show a measurement once per method name
9105// to avoid stretch the commit phase with measurement overhead.
9106var labelsInCurrentCommit = new Set();
9107
9108var formatMarkName = function (markName) {
9109 return reactEmoji + ' ' + markName;
9110};
9111
9112var formatLabel = function (label, warning) {
9113 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
9114 var suffix = warning ? ' Warning: ' + warning : '';
9115 return '' + prefix + label + suffix;
9116};
9117
9118var beginMark = function (markName) {
9119 performance.mark(formatMarkName(markName));
9120};
9121
9122var clearMark = function (markName) {
9123 performance.clearMarks(formatMarkName(markName));
9124};
9125
9126var endMark = function (label, markName, warning) {
9127 var formattedMarkName = formatMarkName(markName);
9128 var formattedLabel = formatLabel(label, warning);
9129 try {
9130 performance.measure(formattedLabel, formattedMarkName);
9131 } catch (err) {}
9132 // If previous mark was missing for some reason, this will throw.
9133 // This could only happen if React crashed in an unexpected place earlier.
9134 // Don't pile on with more errors.
9135
9136 // Clear marks immediately to avoid growing buffer.
9137 performance.clearMarks(formattedMarkName);
9138 performance.clearMeasures(formattedLabel);
9139};
9140
9141var getFiberMarkName = function (label, debugID) {
9142 return label + ' (#' + debugID + ')';
9143};
9144
9145var getFiberLabel = function (componentName, isMounted, phase) {
9146 if (phase === null) {
9147 // These are composite component total time measurements.
9148 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
9149 } else {
9150 // Composite component methods.
9151 return componentName + '.' + phase;
9152 }
9153};
9154
9155var beginFiberMark = function (fiber, phase) {
9156 var componentName = getComponentName(fiber.type) || 'Unknown';
9157 var debugID = fiber._debugID;
9158 var isMounted = fiber.alternate !== null;
9159 var label = getFiberLabel(componentName, isMounted, phase);
9160
9161 if (isCommitting && labelsInCurrentCommit.has(label)) {
9162 // During the commit phase, we don't show duplicate labels because
9163 // there is a fixed overhead for every measurement, and we don't
9164 // want to stretch the commit phase beyond necessary.
9165 return false;
9166 }
9167 labelsInCurrentCommit.add(label);
9168
9169 var markName = getFiberMarkName(label, debugID);
9170 beginMark(markName);
9171 return true;
9172};
9173
9174var clearFiberMark = function (fiber, phase) {
9175 var componentName = getComponentName(fiber.type) || 'Unknown';
9176 var debugID = fiber._debugID;
9177 var isMounted = fiber.alternate !== null;
9178 var label = getFiberLabel(componentName, isMounted, phase);
9179 var markName = getFiberMarkName(label, debugID);
9180 clearMark(markName);
9181};
9182
9183var endFiberMark = function (fiber, phase, warning) {
9184 var componentName = getComponentName(fiber.type) || 'Unknown';
9185 var debugID = fiber._debugID;
9186 var isMounted = fiber.alternate !== null;
9187 var label = getFiberLabel(componentName, isMounted, phase);
9188 var markName = getFiberMarkName(label, debugID);
9189 endMark(label, markName, warning);
9190};
9191
9192var shouldIgnoreFiber = function (fiber) {
9193 // Host components should be skipped in the timeline.
9194 // We could check typeof fiber.type, but does this work with RN?
9195 switch (fiber.tag) {
9196 case HostRoot:
9197 case HostComponent:
9198 case HostText:
9199 case HostPortal:
9200 case Fragment:
9201 case ContextProvider:
9202 case ContextConsumer:
9203 case Mode:
9204 return true;
9205 default:
9206 return false;
9207 }
9208};
9209
9210var clearPendingPhaseMeasurement = function () {
9211 if (currentPhase !== null && currentPhaseFiber !== null) {
9212 clearFiberMark(currentPhaseFiber, currentPhase);
9213 }
9214 currentPhaseFiber = null;
9215 currentPhase = null;
9216 hasScheduledUpdateInCurrentPhase = false;
9217};
9218
9219var pauseTimers = function () {
9220 // Stops all currently active measurements so that they can be resumed
9221 // if we continue in a later deferred loop from the same unit of work.
9222 var fiber = currentFiber;
9223 while (fiber) {
9224 if (fiber._debugIsCurrentlyTiming) {
9225 endFiberMark(fiber, null, null);
9226 }
9227 fiber = fiber.return;
9228 }
9229};
9230
9231var resumeTimersRecursively = function (fiber) {
9232 if (fiber.return !== null) {
9233 resumeTimersRecursively(fiber.return);
9234 }
9235 if (fiber._debugIsCurrentlyTiming) {
9236 beginFiberMark(fiber, null);
9237 }
9238};
9239
9240var resumeTimers = function () {
9241 // Resumes all measurements that were active during the last deferred loop.
9242 if (currentFiber !== null) {
9243 resumeTimersRecursively(currentFiber);
9244 }
9245};
9246
9247function recordEffect() {
9248 if (enableUserTimingAPI) {
9249 effectCountInCurrentCommit++;
9250 }
9251}
9252
9253function recordScheduleUpdate() {
9254 if (enableUserTimingAPI) {
9255 if (isCommitting) {
9256 hasScheduledUpdateInCurrentCommit = true;
9257 }
9258 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
9259 hasScheduledUpdateInCurrentPhase = true;
9260 }
9261 }
9262}
9263
9264function startRequestCallbackTimer() {
9265 if (enableUserTimingAPI) {
9266 if (supportsUserTiming && !isWaitingForCallback) {
9267 isWaitingForCallback = true;
9268 beginMark('(Waiting for async callback...)');
9269 }
9270 }
9271}
9272
9273function stopRequestCallbackTimer(didExpire, expirationTime) {
9274 if (enableUserTimingAPI) {
9275 if (supportsUserTiming) {
9276 isWaitingForCallback = false;
9277 var warning = didExpire ? 'React was blocked by main thread' : null;
9278 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
9279 }
9280 }
9281}
9282
9283function startWorkTimer(fiber) {
9284 if (enableUserTimingAPI) {
9285 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9286 return;
9287 }
9288 // If we pause, this is the fiber to unwind from.
9289 currentFiber = fiber;
9290 if (!beginFiberMark(fiber, null)) {
9291 return;
9292 }
9293 fiber._debugIsCurrentlyTiming = true;
9294 }
9295}
9296
9297function cancelWorkTimer(fiber) {
9298 if (enableUserTimingAPI) {
9299 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9300 return;
9301 }
9302 // Remember we shouldn't complete measurement for this fiber.
9303 // Otherwise flamechart will be deep even for small updates.
9304 fiber._debugIsCurrentlyTiming = false;
9305 clearFiberMark(fiber, null);
9306 }
9307}
9308
9309function stopWorkTimer(fiber) {
9310 if (enableUserTimingAPI) {
9311 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9312 return;
9313 }
9314 // If we pause, its parent is the fiber to unwind from.
9315 currentFiber = fiber.return;
9316 if (!fiber._debugIsCurrentlyTiming) {
9317 return;
9318 }
9319 fiber._debugIsCurrentlyTiming = false;
9320 endFiberMark(fiber, null, null);
9321 }
9322}
9323
9324function stopFailedWorkTimer(fiber) {
9325 if (enableUserTimingAPI) {
9326 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9327 return;
9328 }
9329 // If we pause, its parent is the fiber to unwind from.
9330 currentFiber = fiber.return;
9331 if (!fiber._debugIsCurrentlyTiming) {
9332 return;
9333 }
9334 fiber._debugIsCurrentlyTiming = false;
9335 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9336 endFiberMark(fiber, null, warning);
9337 }
9338}
9339
9340function startPhaseTimer(fiber, phase) {
9341 if (enableUserTimingAPI) {
9342 if (!supportsUserTiming) {
9343 return;
9344 }
9345 clearPendingPhaseMeasurement();
9346 if (!beginFiberMark(fiber, phase)) {
9347 return;
9348 }
9349 currentPhaseFiber = fiber;
9350 currentPhase = phase;
9351 }
9352}
9353
9354function stopPhaseTimer() {
9355 if (enableUserTimingAPI) {
9356 if (!supportsUserTiming) {
9357 return;
9358 }
9359 if (currentPhase !== null && currentPhaseFiber !== null) {
9360 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
9361 endFiberMark(currentPhaseFiber, currentPhase, warning);
9362 }
9363 currentPhase = null;
9364 currentPhaseFiber = null;
9365 }
9366}
9367
9368function startWorkLoopTimer(nextUnitOfWork) {
9369 if (enableUserTimingAPI) {
9370 currentFiber = nextUnitOfWork;
9371 if (!supportsUserTiming) {
9372 return;
9373 }
9374 commitCountInCurrentWorkLoop = 0;
9375 // This is top level call.
9376 // Any other measurements are performed within.
9377 beginMark('(React Tree Reconciliation)');
9378 // Resume any measurements that were in progress during the last loop.
9379 resumeTimers();
9380 }
9381}
9382
9383function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
9384 if (enableUserTimingAPI) {
9385 if (!supportsUserTiming) {
9386 return;
9387 }
9388 var warning = null;
9389 if (interruptedBy !== null) {
9390 if (interruptedBy.tag === HostRoot) {
9391 warning = 'A top-level update interrupted the previous render';
9392 } else {
9393 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
9394 warning = 'An update to ' + componentName + ' interrupted the previous render';
9395 }
9396 } else if (commitCountInCurrentWorkLoop > 1) {
9397 warning = 'There were cascading updates';
9398 }
9399 commitCountInCurrentWorkLoop = 0;
9400 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
9401 // Pause any measurements until the next loop.
9402 pauseTimers();
9403 endMark(label, '(React Tree Reconciliation)', warning);
9404 }
9405}
9406
9407function startCommitTimer() {
9408 if (enableUserTimingAPI) {
9409 if (!supportsUserTiming) {
9410 return;
9411 }
9412 isCommitting = true;
9413 hasScheduledUpdateInCurrentCommit = false;
9414 labelsInCurrentCommit.clear();
9415 beginMark('(Committing Changes)');
9416 }
9417}
9418
9419function stopCommitTimer() {
9420 if (enableUserTimingAPI) {
9421 if (!supportsUserTiming) {
9422 return;
9423 }
9424
9425 var warning = null;
9426 if (hasScheduledUpdateInCurrentCommit) {
9427 warning = 'Lifecycle hook scheduled a cascading update';
9428 } else if (commitCountInCurrentWorkLoop > 0) {
9429 warning = 'Caused by a cascading update in earlier commit';
9430 }
9431 hasScheduledUpdateInCurrentCommit = false;
9432 commitCountInCurrentWorkLoop++;
9433 isCommitting = false;
9434 labelsInCurrentCommit.clear();
9435
9436 endMark('(Committing Changes)', '(Committing Changes)', warning);
9437 }
9438}
9439
9440function startCommitSnapshotEffectsTimer() {
9441 if (enableUserTimingAPI) {
9442 if (!supportsUserTiming) {
9443 return;
9444 }
9445 effectCountInCurrentCommit = 0;
9446 beginMark('(Committing Snapshot Effects)');
9447 }
9448}
9449
9450function stopCommitSnapshotEffectsTimer() {
9451 if (enableUserTimingAPI) {
9452 if (!supportsUserTiming) {
9453 return;
9454 }
9455 var count = effectCountInCurrentCommit;
9456 effectCountInCurrentCommit = 0;
9457 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
9458 }
9459}
9460
9461function startCommitHostEffectsTimer() {
9462 if (enableUserTimingAPI) {
9463 if (!supportsUserTiming) {
9464 return;
9465 }
9466 effectCountInCurrentCommit = 0;
9467 beginMark('(Committing Host Effects)');
9468 }
9469}
9470
9471function stopCommitHostEffectsTimer() {
9472 if (enableUserTimingAPI) {
9473 if (!supportsUserTiming) {
9474 return;
9475 }
9476 var count = effectCountInCurrentCommit;
9477 effectCountInCurrentCommit = 0;
9478 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
9479 }
9480}
9481
9482function startCommitLifeCyclesTimer() {
9483 if (enableUserTimingAPI) {
9484 if (!supportsUserTiming) {
9485 return;
9486 }
9487 effectCountInCurrentCommit = 0;
9488 beginMark('(Calling Lifecycle Methods)');
9489 }
9490}
9491
9492function stopCommitLifeCyclesTimer() {
9493 if (enableUserTimingAPI) {
9494 if (!supportsUserTiming) {
9495 return;
9496 }
9497 var count = effectCountInCurrentCommit;
9498 effectCountInCurrentCommit = 0;
9499 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
9500 }
9501}
9502
9503var valueStack = [];
9504
9505var fiberStack = void 0;
9506
9507{
9508 fiberStack = [];
9509}
9510
9511var index = -1;
9512
9513function createCursor(defaultValue) {
9514 return {
9515 current: defaultValue
9516 };
9517}
9518
9519function pop(cursor, fiber) {
9520 if (index < 0) {
9521 {
9522 warningWithoutStack$1(false, 'Unexpected pop.');
9523 }
9524 return;
9525 }
9526
9527 {
9528 if (fiber !== fiberStack[index]) {
9529 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
9530 }
9531 }
9532
9533 cursor.current = valueStack[index];
9534
9535 valueStack[index] = null;
9536
9537 {
9538 fiberStack[index] = null;
9539 }
9540
9541 index--;
9542}
9543
9544function push(cursor, value, fiber) {
9545 index++;
9546
9547 valueStack[index] = cursor.current;
9548
9549 {
9550 fiberStack[index] = fiber;
9551 }
9552
9553 cursor.current = value;
9554}
9555
9556function checkThatStackIsEmpty() {
9557 {
9558 if (index !== -1) {
9559 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
9560 }
9561 }
9562}
9563
9564function resetStackAfterFatalErrorInDev() {
9565 {
9566 index = -1;
9567 valueStack.length = 0;
9568 fiberStack.length = 0;
9569 }
9570}
9571
9572var warnedAboutMissingGetChildContext = void 0;
9573
9574{
9575 warnedAboutMissingGetChildContext = {};
9576}
9577
9578var emptyContextObject = {};
9579{
9580 Object.freeze(emptyContextObject);
9581}
9582
9583// A cursor to the current merged context object on the stack.
9584var contextStackCursor = createCursor(emptyContextObject);
9585// A cursor to a boolean indicating whether the context has changed.
9586var didPerformWorkStackCursor = createCursor(false);
9587// Keep track of the previous context object that was on the stack.
9588// We use this to get access to the parent context after we have already
9589// pushed the next context provider, and now need to merge their contexts.
9590var previousContext = emptyContextObject;
9591
9592function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
9593 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
9594 // If the fiber is a context provider itself, when we read its context
9595 // we may have already pushed its own child context on the stack. A context
9596 // provider should not "see" its own child context. Therefore we read the
9597 // previous (parent) context instead for a context provider.
9598 return previousContext;
9599 }
9600 return contextStackCursor.current;
9601}
9602
9603function cacheContext(workInProgress, unmaskedContext, maskedContext) {
9604 var instance = workInProgress.stateNode;
9605 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
9606 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
9607}
9608
9609function getMaskedContext(workInProgress, unmaskedContext) {
9610 var type = workInProgress.type;
9611 var contextTypes = type.contextTypes;
9612 if (!contextTypes) {
9613 return emptyContextObject;
9614 }
9615
9616 // Avoid recreating masked context unless unmasked context has changed.
9617 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
9618 // This may trigger infinite loops if componentWillReceiveProps calls setState.
9619 var instance = workInProgress.stateNode;
9620 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
9621 return instance.__reactInternalMemoizedMaskedChildContext;
9622 }
9623
9624 var context = {};
9625 for (var key in contextTypes) {
9626 context[key] = unmaskedContext[key];
9627 }
9628
9629 {
9630 var name = getComponentName(type) || 'Unknown';
9631 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
9632 }
9633
9634 // Cache unmasked context so we can avoid recreating masked context unless necessary.
9635 // Context is created before the class component is instantiated so check for instance.
9636 if (instance) {
9637 cacheContext(workInProgress, unmaskedContext, context);
9638 }
9639
9640 return context;
9641}
9642
9643function hasContextChanged() {
9644 return didPerformWorkStackCursor.current;
9645}
9646
9647function isContextProvider(type) {
9648 var childContextTypes = type.childContextTypes;
9649 return childContextTypes !== null && childContextTypes !== undefined;
9650}
9651
9652function popContext(fiber) {
9653 pop(didPerformWorkStackCursor, fiber);
9654 pop(contextStackCursor, fiber);
9655}
9656
9657function popTopLevelContextObject(fiber) {
9658 pop(didPerformWorkStackCursor, fiber);
9659 pop(contextStackCursor, fiber);
9660}
9661
9662function pushTopLevelContextObject(fiber, context, didChange) {
9663 !(contextStackCursor.current === emptyContextObject) ? invariant(false, 'Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9664
9665 push(contextStackCursor, context, fiber);
9666 push(didPerformWorkStackCursor, didChange, fiber);
9667}
9668
9669function processChildContext(fiber, type, parentContext) {
9670 var instance = fiber.stateNode;
9671 var childContextTypes = type.childContextTypes;
9672
9673 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
9674 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
9675 if (typeof instance.getChildContext !== 'function') {
9676 {
9677 var componentName = getComponentName(type) || 'Unknown';
9678
9679 if (!warnedAboutMissingGetChildContext[componentName]) {
9680 warnedAboutMissingGetChildContext[componentName] = true;
9681 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);
9682 }
9683 }
9684 return parentContext;
9685 }
9686
9687 var childContext = void 0;
9688 {
9689 setCurrentPhase('getChildContext');
9690 }
9691 startPhaseTimer(fiber, 'getChildContext');
9692 childContext = instance.getChildContext();
9693 stopPhaseTimer();
9694 {
9695 setCurrentPhase(null);
9696 }
9697 for (var contextKey in childContext) {
9698 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
9699 }
9700 {
9701 var name = getComponentName(type) || 'Unknown';
9702 checkPropTypes(childContextTypes, childContext, 'child context', name,
9703 // In practice, there is one case in which we won't get a stack. It's when
9704 // somebody calls unstable_renderSubtreeIntoContainer() and we process
9705 // context from the parent component instance. The stack will be missing
9706 // because it's outside of the reconciliation, and so the pointer has not
9707 // been set. This is rare and doesn't matter. We'll also remove that API.
9708 getCurrentFiberStackInDev);
9709 }
9710
9711 return _assign({}, parentContext, childContext);
9712}
9713
9714function pushContextProvider(workInProgress) {
9715 var instance = workInProgress.stateNode;
9716 // We push the context as early as possible to ensure stack integrity.
9717 // If the instance does not exist yet, we will push null at first,
9718 // and replace it on the stack later when invalidating the context.
9719 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
9720
9721 // Remember the parent context so we can merge with it later.
9722 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
9723 previousContext = contextStackCursor.current;
9724 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
9725 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
9726
9727 return true;
9728}
9729
9730function invalidateContextProvider(workInProgress, type, didChange) {
9731 var instance = workInProgress.stateNode;
9732 !instance ? invariant(false, 'Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9733
9734 if (didChange) {
9735 // Merge parent and own context.
9736 // Skip this if we're not updating due to sCU.
9737 // This avoids unnecessarily recomputing memoized values.
9738 var mergedContext = processChildContext(workInProgress, type, previousContext);
9739 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
9740
9741 // Replace the old (or empty) context with the new one.
9742 // It is important to unwind the context in the reverse order.
9743 pop(didPerformWorkStackCursor, workInProgress);
9744 pop(contextStackCursor, workInProgress);
9745 // Now push the new context and mark that it has changed.
9746 push(contextStackCursor, mergedContext, workInProgress);
9747 push(didPerformWorkStackCursor, didChange, workInProgress);
9748 } else {
9749 pop(didPerformWorkStackCursor, workInProgress);
9750 push(didPerformWorkStackCursor, didChange, workInProgress);
9751 }
9752}
9753
9754function findCurrentUnmaskedContext(fiber) {
9755 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
9756 // makes sense elsewhere
9757 !(isFiberMounted(fiber) && fiber.tag === ClassComponent) ? invariant(false, 'Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9758
9759 var node = fiber;
9760 do {
9761 switch (node.tag) {
9762 case HostRoot:
9763 return node.stateNode.context;
9764 case ClassComponent:
9765 {
9766 var Component = node.type;
9767 if (isContextProvider(Component)) {
9768 return node.stateNode.__reactInternalMemoizedMergedChildContext;
9769 }
9770 break;
9771 }
9772 }
9773 node = node.return;
9774 } while (node !== null);
9775 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
9776}
9777
9778var onCommitFiberRoot = null;
9779var onCommitFiberUnmount = null;
9780var hasLoggedError = false;
9781
9782function catchErrors(fn) {
9783 return function (arg) {
9784 try {
9785 return fn(arg);
9786 } catch (err) {
9787 if (true && !hasLoggedError) {
9788 hasLoggedError = true;
9789 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
9790 }
9791 }
9792 };
9793}
9794
9795var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
9796
9797function injectInternals(internals) {
9798 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
9799 // No DevTools
9800 return false;
9801 }
9802 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9803 if (hook.isDisabled) {
9804 // This isn't a real property on the hook, but it can be set to opt out
9805 // of DevTools integration and associated warnings and logs.
9806 // https://github.com/facebook/react/issues/3877
9807 return true;
9808 }
9809 if (!hook.supportsFiber) {
9810 {
9811 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');
9812 }
9813 // DevTools exists, even though it doesn't support Fiber.
9814 return true;
9815 }
9816 try {
9817 var rendererID = hook.inject(internals);
9818 // We have successfully injected, so now it is safe to set up hooks.
9819 onCommitFiberRoot = catchErrors(function (root) {
9820 return hook.onCommitFiberRoot(rendererID, root);
9821 });
9822 onCommitFiberUnmount = catchErrors(function (fiber) {
9823 return hook.onCommitFiberUnmount(rendererID, fiber);
9824 });
9825 } catch (err) {
9826 // Catch all errors because it is unsafe to throw during initialization.
9827 {
9828 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
9829 }
9830 }
9831 // DevTools exists
9832 return true;
9833}
9834
9835function onCommitRoot(root) {
9836 if (typeof onCommitFiberRoot === 'function') {
9837 onCommitFiberRoot(root);
9838 }
9839}
9840
9841function onCommitUnmount(fiber) {
9842 if (typeof onCommitFiberUnmount === 'function') {
9843 onCommitFiberUnmount(fiber);
9844 }
9845}
9846
9847// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
9848// Math.pow(2, 30) - 1
9849// 0b111111111111111111111111111111
9850var maxSigned31BitInt = 1073741823;
9851
9852var NoWork = 0;
9853var Never = 1;
9854var Sync = maxSigned31BitInt;
9855
9856var UNIT_SIZE = 10;
9857var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
9858
9859// 1 unit of expiration time represents 10ms.
9860function msToExpirationTime(ms) {
9861 // Always add an offset so that we don't clash with the magic number for NoWork.
9862 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
9863}
9864
9865function expirationTimeToMs(expirationTime) {
9866 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
9867}
9868
9869function ceiling(num, precision) {
9870 return ((num / precision | 0) + 1) * precision;
9871}
9872
9873function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
9874 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
9875}
9876
9877var LOW_PRIORITY_EXPIRATION = 5000;
9878var LOW_PRIORITY_BATCH_SIZE = 250;
9879
9880function computeAsyncExpiration(currentTime) {
9881 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
9882}
9883
9884// We intentionally set a higher expiration time for interactive updates in
9885// dev than in production.
9886//
9887// If the main thread is being blocked so long that you hit the expiration,
9888// it's a problem that could be solved with better scheduling.
9889//
9890// People will be more likely to notice this and fix it with the long
9891// expiration time in development.
9892//
9893// In production we opt for better UX at the risk of masking scheduling
9894// problems, by expiring fast.
9895var HIGH_PRIORITY_EXPIRATION = 500;
9896var HIGH_PRIORITY_BATCH_SIZE = 100;
9897
9898function computeInteractiveExpiration(currentTime) {
9899 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
9900}
9901
9902var NoContext = 0;
9903var ConcurrentMode = 1;
9904var StrictMode = 2;
9905var ProfileMode = 4;
9906
9907var hasBadMapPolyfill = void 0;
9908
9909{
9910 hasBadMapPolyfill = false;
9911 try {
9912 var nonExtensibleObject = Object.preventExtensions({});
9913 var testMap = new Map([[nonExtensibleObject, null]]);
9914 var testSet = new Set([nonExtensibleObject]);
9915 // This is necessary for Rollup to not consider these unused.
9916 // https://github.com/rollup/rollup/issues/1771
9917 // TODO: we can remove these if Rollup fixes the bug.
9918 testMap.set(0, 0);
9919 testSet.add(0);
9920 } catch (e) {
9921 // TODO: Consider warning about bad polyfills
9922 hasBadMapPolyfill = true;
9923 }
9924}
9925
9926// A Fiber is work on a Component that needs to be done or was done. There can
9927// be more than one per component.
9928
9929
9930var debugCounter = void 0;
9931
9932{
9933 debugCounter = 1;
9934}
9935
9936function FiberNode(tag, pendingProps, key, mode) {
9937 // Instance
9938 this.tag = tag;
9939 this.key = key;
9940 this.elementType = null;
9941 this.type = null;
9942 this.stateNode = null;
9943
9944 // Fiber
9945 this.return = null;
9946 this.child = null;
9947 this.sibling = null;
9948 this.index = 0;
9949
9950 this.ref = null;
9951
9952 this.pendingProps = pendingProps;
9953 this.memoizedProps = null;
9954 this.updateQueue = null;
9955 this.memoizedState = null;
9956 this.contextDependencies = null;
9957
9958 this.mode = mode;
9959
9960 // Effects
9961 this.effectTag = NoEffect;
9962 this.nextEffect = null;
9963
9964 this.firstEffect = null;
9965 this.lastEffect = null;
9966
9967 this.expirationTime = NoWork;
9968 this.childExpirationTime = NoWork;
9969
9970 this.alternate = null;
9971
9972 if (enableProfilerTimer) {
9973 // Note: The following is done to avoid a v8 performance cliff.
9974 //
9975 // Initializing the fields below to smis and later updating them with
9976 // double values will cause Fibers to end up having separate shapes.
9977 // This behavior/bug has something to do with Object.preventExtension().
9978 // Fortunately this only impacts DEV builds.
9979 // Unfortunately it makes React unusably slow for some applications.
9980 // To work around this, initialize the fields below with doubles.
9981 //
9982 // Learn more about this here:
9983 // https://github.com/facebook/react/issues/14365
9984 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
9985 this.actualDuration = Number.NaN;
9986 this.actualStartTime = Number.NaN;
9987 this.selfBaseDuration = Number.NaN;
9988 this.treeBaseDuration = Number.NaN;
9989
9990 // It's okay to replace the initial doubles with smis after initialization.
9991 // This won't trigger the performance cliff mentioned above,
9992 // and it simplifies other profiler code (including DevTools).
9993 this.actualDuration = 0;
9994 this.actualStartTime = -1;
9995 this.selfBaseDuration = 0;
9996 this.treeBaseDuration = 0;
9997 }
9998
9999 {
10000 this._debugID = debugCounter++;
10001 this._debugSource = null;
10002 this._debugOwner = null;
10003 this._debugIsCurrentlyTiming = false;
10004 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10005 Object.preventExtensions(this);
10006 }
10007 }
10008}
10009
10010// This is a constructor function, rather than a POJO constructor, still
10011// please ensure we do the following:
10012// 1) Nobody should add any instance methods on this. Instance methods can be
10013// more difficult to predict when they get optimized and they are almost
10014// never inlined properly in static compilers.
10015// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
10016// always know when it is a fiber.
10017// 3) We might want to experiment with using numeric keys since they are easier
10018// to optimize in a non-JIT environment.
10019// 4) We can easily go from a constructor to a createFiber object literal if that
10020// is faster.
10021// 5) It should be easy to port this to a C struct and keep a C implementation
10022// compatible.
10023var createFiber = function (tag, pendingProps, key, mode) {
10024 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
10025 return new FiberNode(tag, pendingProps, key, mode);
10026};
10027
10028function shouldConstruct(Component) {
10029 var prototype = Component.prototype;
10030 return !!(prototype && prototype.isReactComponent);
10031}
10032
10033function isSimpleFunctionComponent(type) {
10034 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
10035}
10036
10037function resolveLazyComponentTag(Component) {
10038 if (typeof Component === 'function') {
10039 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
10040 } else if (Component !== undefined && Component !== null) {
10041 var $$typeof = Component.$$typeof;
10042 if ($$typeof === REACT_FORWARD_REF_TYPE) {
10043 return ForwardRef;
10044 }
10045 if ($$typeof === REACT_MEMO_TYPE) {
10046 return MemoComponent;
10047 }
10048 }
10049 return IndeterminateComponent;
10050}
10051
10052// This is used to create an alternate fiber to do work on.
10053function createWorkInProgress(current, pendingProps, expirationTime) {
10054 var workInProgress = current.alternate;
10055 if (workInProgress === null) {
10056 // We use a double buffering pooling technique because we know that we'll
10057 // only ever need at most two versions of a tree. We pool the "other" unused
10058 // node that we're free to reuse. This is lazily created to avoid allocating
10059 // extra objects for things that are never updated. It also allow us to
10060 // reclaim the extra memory if needed.
10061 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
10062 workInProgress.elementType = current.elementType;
10063 workInProgress.type = current.type;
10064 workInProgress.stateNode = current.stateNode;
10065
10066 {
10067 // DEV-only fields
10068 workInProgress._debugID = current._debugID;
10069 workInProgress._debugSource = current._debugSource;
10070 workInProgress._debugOwner = current._debugOwner;
10071 }
10072
10073 workInProgress.alternate = current;
10074 current.alternate = workInProgress;
10075 } else {
10076 workInProgress.pendingProps = pendingProps;
10077
10078 // We already have an alternate.
10079 // Reset the effect tag.
10080 workInProgress.effectTag = NoEffect;
10081
10082 // The effect list is no longer valid.
10083 workInProgress.nextEffect = null;
10084 workInProgress.firstEffect = null;
10085 workInProgress.lastEffect = null;
10086
10087 if (enableProfilerTimer) {
10088 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
10089 // This prevents time from endlessly accumulating in new commits.
10090 // This has the downside of resetting values for different priority renders,
10091 // But works for yielding (the common case) and should support resuming.
10092 workInProgress.actualDuration = 0;
10093 workInProgress.actualStartTime = -1;
10094 }
10095 }
10096
10097 workInProgress.childExpirationTime = current.childExpirationTime;
10098 workInProgress.expirationTime = current.expirationTime;
10099
10100 workInProgress.child = current.child;
10101 workInProgress.memoizedProps = current.memoizedProps;
10102 workInProgress.memoizedState = current.memoizedState;
10103 workInProgress.updateQueue = current.updateQueue;
10104 workInProgress.contextDependencies = current.contextDependencies;
10105
10106 // These will be overridden during the parent's reconciliation
10107 workInProgress.sibling = current.sibling;
10108 workInProgress.index = current.index;
10109 workInProgress.ref = current.ref;
10110
10111 if (enableProfilerTimer) {
10112 workInProgress.selfBaseDuration = current.selfBaseDuration;
10113 workInProgress.treeBaseDuration = current.treeBaseDuration;
10114 }
10115
10116 return workInProgress;
10117}
10118
10119function createHostRootFiber(isConcurrent) {
10120 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
10121
10122 if (enableProfilerTimer && isDevToolsPresent) {
10123 // Always collect profile timings when DevTools are present.
10124 // This enables DevTools to start capturing timing at any point–
10125 // Without some nodes in the tree having empty base times.
10126 mode |= ProfileMode;
10127 }
10128
10129 return createFiber(HostRoot, null, null, mode);
10130}
10131
10132function createFiberFromTypeAndProps(type, // React$ElementType
10133key, pendingProps, owner, mode, expirationTime) {
10134 var fiber = void 0;
10135
10136 var fiberTag = IndeterminateComponent;
10137 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
10138 var resolvedType = type;
10139 if (typeof type === 'function') {
10140 if (shouldConstruct(type)) {
10141 fiberTag = ClassComponent;
10142 }
10143 } else if (typeof type === 'string') {
10144 fiberTag = HostComponent;
10145 } else {
10146 getTag: switch (type) {
10147 case REACT_FRAGMENT_TYPE:
10148 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
10149 case REACT_CONCURRENT_MODE_TYPE:
10150 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
10151 case REACT_STRICT_MODE_TYPE:
10152 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
10153 case REACT_PROFILER_TYPE:
10154 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
10155 case REACT_SUSPENSE_TYPE:
10156 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
10157 default:
10158 {
10159 if (typeof type === 'object' && type !== null) {
10160 switch (type.$$typeof) {
10161 case REACT_PROVIDER_TYPE:
10162 fiberTag = ContextProvider;
10163 break getTag;
10164 case REACT_CONTEXT_TYPE:
10165 // This is a consumer
10166 fiberTag = ContextConsumer;
10167 break getTag;
10168 case REACT_FORWARD_REF_TYPE:
10169 fiberTag = ForwardRef;
10170 break getTag;
10171 case REACT_MEMO_TYPE:
10172 fiberTag = MemoComponent;
10173 break getTag;
10174 case REACT_LAZY_TYPE:
10175 fiberTag = LazyComponent;
10176 resolvedType = null;
10177 break getTag;
10178 }
10179 }
10180 var info = '';
10181 {
10182 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
10183 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.';
10184 }
10185 var ownerName = owner ? getComponentName(owner.type) : null;
10186 if (ownerName) {
10187 info += '\n\nCheck the render method of `' + ownerName + '`.';
10188 }
10189 }
10190 invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info);
10191 }
10192 }
10193 }
10194
10195 fiber = createFiber(fiberTag, pendingProps, key, mode);
10196 fiber.elementType = type;
10197 fiber.type = resolvedType;
10198 fiber.expirationTime = expirationTime;
10199
10200 return fiber;
10201}
10202
10203function createFiberFromElement(element, mode, expirationTime) {
10204 var owner = null;
10205 {
10206 owner = element._owner;
10207 }
10208 var type = element.type;
10209 var key = element.key;
10210 var pendingProps = element.props;
10211 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
10212 {
10213 fiber._debugSource = element._source;
10214 fiber._debugOwner = element._owner;
10215 }
10216 return fiber;
10217}
10218
10219function createFiberFromFragment(elements, mode, expirationTime, key) {
10220 var fiber = createFiber(Fragment, elements, key, mode);
10221 fiber.expirationTime = expirationTime;
10222 return fiber;
10223}
10224
10225function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
10226 {
10227 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
10228 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
10229 }
10230 }
10231
10232 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
10233 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
10234 fiber.elementType = REACT_PROFILER_TYPE;
10235 fiber.type = REACT_PROFILER_TYPE;
10236 fiber.expirationTime = expirationTime;
10237
10238 return fiber;
10239}
10240
10241function createFiberFromMode(pendingProps, mode, expirationTime, key) {
10242 var fiber = createFiber(Mode, pendingProps, key, mode);
10243
10244 // TODO: The Mode fiber shouldn't have a type. It has a tag.
10245 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
10246 fiber.elementType = type;
10247 fiber.type = type;
10248
10249 fiber.expirationTime = expirationTime;
10250 return fiber;
10251}
10252
10253function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
10254 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
10255
10256 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
10257 var type = REACT_SUSPENSE_TYPE;
10258 fiber.elementType = type;
10259 fiber.type = type;
10260
10261 fiber.expirationTime = expirationTime;
10262 return fiber;
10263}
10264
10265function createFiberFromText(content, mode, expirationTime) {
10266 var fiber = createFiber(HostText, content, null, mode);
10267 fiber.expirationTime = expirationTime;
10268 return fiber;
10269}
10270
10271function createFiberFromHostInstanceForDeletion() {
10272 var fiber = createFiber(HostComponent, null, null, NoContext);
10273 // TODO: These should not need a type.
10274 fiber.elementType = 'DELETED';
10275 fiber.type = 'DELETED';
10276 return fiber;
10277}
10278
10279function createFiberFromPortal(portal, mode, expirationTime) {
10280 var pendingProps = portal.children !== null ? portal.children : [];
10281 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
10282 fiber.expirationTime = expirationTime;
10283 fiber.stateNode = {
10284 containerInfo: portal.containerInfo,
10285 pendingChildren: null, // Used by persistent updates
10286 implementation: portal.implementation
10287 };
10288 return fiber;
10289}
10290
10291// Used for stashing WIP properties to replay failed work in DEV.
10292function assignFiberPropertiesInDEV(target, source) {
10293 if (target === null) {
10294 // This Fiber's initial properties will always be overwritten.
10295 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
10296 target = createFiber(IndeterminateComponent, null, null, NoContext);
10297 }
10298
10299 // This is intentionally written as a list of all properties.
10300 // We tried to use Object.assign() instead but this is called in
10301 // the hottest path, and Object.assign() was too slow:
10302 // https://github.com/facebook/react/issues/12502
10303 // This code is DEV-only so size is not a concern.
10304
10305 target.tag = source.tag;
10306 target.key = source.key;
10307 target.elementType = source.elementType;
10308 target.type = source.type;
10309 target.stateNode = source.stateNode;
10310 target.return = source.return;
10311 target.child = source.child;
10312 target.sibling = source.sibling;
10313 target.index = source.index;
10314 target.ref = source.ref;
10315 target.pendingProps = source.pendingProps;
10316 target.memoizedProps = source.memoizedProps;
10317 target.updateQueue = source.updateQueue;
10318 target.memoizedState = source.memoizedState;
10319 target.contextDependencies = source.contextDependencies;
10320 target.mode = source.mode;
10321 target.effectTag = source.effectTag;
10322 target.nextEffect = source.nextEffect;
10323 target.firstEffect = source.firstEffect;
10324 target.lastEffect = source.lastEffect;
10325 target.expirationTime = source.expirationTime;
10326 target.childExpirationTime = source.childExpirationTime;
10327 target.alternate = source.alternate;
10328 if (enableProfilerTimer) {
10329 target.actualDuration = source.actualDuration;
10330 target.actualStartTime = source.actualStartTime;
10331 target.selfBaseDuration = source.selfBaseDuration;
10332 target.treeBaseDuration = source.treeBaseDuration;
10333 }
10334 target._debugID = source._debugID;
10335 target._debugSource = source._debugSource;
10336 target._debugOwner = source._debugOwner;
10337 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10338 return target;
10339}
10340
10341// TODO: This should be lifted into the renderer.
10342
10343
10344// The following attributes are only used by interaction tracing builds.
10345// They enable interactions to be associated with their async work,
10346// And expose interaction metadata to the React DevTools Profiler plugin.
10347// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
10348
10349
10350// Exported FiberRoot type includes all properties,
10351// To avoid requiring potentially error-prone :any casts throughout the project.
10352// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
10353// The types are defined separately within this file to ensure they stay in sync.
10354// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
10355
10356
10357function createFiberRoot(containerInfo, isConcurrent, hydrate) {
10358 // Cyclic construction. This cheats the type system right now because
10359 // stateNode is any.
10360 var uninitializedFiber = createHostRootFiber(isConcurrent);
10361
10362 var root = void 0;
10363 if (enableSchedulerTracing) {
10364 root = {
10365 current: uninitializedFiber,
10366 containerInfo: containerInfo,
10367 pendingChildren: null,
10368
10369 earliestPendingTime: NoWork,
10370 latestPendingTime: NoWork,
10371 earliestSuspendedTime: NoWork,
10372 latestSuspendedTime: NoWork,
10373 latestPingedTime: NoWork,
10374
10375 pingCache: null,
10376
10377 didError: false,
10378
10379 pendingCommitExpirationTime: NoWork,
10380 finishedWork: null,
10381 timeoutHandle: noTimeout,
10382 context: null,
10383 pendingContext: null,
10384 hydrate: hydrate,
10385 nextExpirationTimeToWorkOn: NoWork,
10386 expirationTime: NoWork,
10387 firstBatch: null,
10388 nextScheduledRoot: null,
10389
10390 interactionThreadID: tracing.unstable_getThreadID(),
10391 memoizedInteractions: new Set(),
10392 pendingInteractionMap: new Map()
10393 };
10394 } else {
10395 root = {
10396 current: uninitializedFiber,
10397 containerInfo: containerInfo,
10398 pendingChildren: null,
10399
10400 pingCache: null,
10401
10402 earliestPendingTime: NoWork,
10403 latestPendingTime: NoWork,
10404 earliestSuspendedTime: NoWork,
10405 latestSuspendedTime: NoWork,
10406 latestPingedTime: NoWork,
10407
10408 didError: false,
10409
10410 pendingCommitExpirationTime: NoWork,
10411 finishedWork: null,
10412 timeoutHandle: noTimeout,
10413 context: null,
10414 pendingContext: null,
10415 hydrate: hydrate,
10416 nextExpirationTimeToWorkOn: NoWork,
10417 expirationTime: NoWork,
10418 firstBatch: null,
10419 nextScheduledRoot: null
10420 };
10421 }
10422
10423 uninitializedFiber.stateNode = root;
10424
10425 // The reason for the way the Flow types are structured in this file,
10426 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
10427 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
10428 // $FlowFixMe Remove this :any cast and replace it with something better.
10429 return root;
10430}
10431
10432/**
10433 * Forked from fbjs/warning:
10434 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
10435 *
10436 * Only change is we use console.warn instead of console.error,
10437 * and do nothing when 'console' is not supported.
10438 * This really simplifies the code.
10439 * ---
10440 * Similar to invariant but only logs a warning if the condition is not met.
10441 * This can be used to log issues in development environments in critical
10442 * paths. Removing the logging code for production environments will keep the
10443 * same logic and follow the same code paths.
10444 */
10445
10446var lowPriorityWarning = function () {};
10447
10448{
10449 var printWarning = function (format) {
10450 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
10451 args[_key - 1] = arguments[_key];
10452 }
10453
10454 var argIndex = 0;
10455 var message = 'Warning: ' + format.replace(/%s/g, function () {
10456 return args[argIndex++];
10457 });
10458 if (typeof console !== 'undefined') {
10459 console.warn(message);
10460 }
10461 try {
10462 // --- Welcome to debugging React ---
10463 // This error was thrown as a convenience so that you can use this stack
10464 // to find the callsite that caused this warning to fire.
10465 throw new Error(message);
10466 } catch (x) {}
10467 };
10468
10469 lowPriorityWarning = function (condition, format) {
10470 if (format === undefined) {
10471 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
10472 }
10473 if (!condition) {
10474 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
10475 args[_key2 - 2] = arguments[_key2];
10476 }
10477
10478 printWarning.apply(undefined, [format].concat(args));
10479 }
10480 };
10481}
10482
10483var lowPriorityWarning$1 = lowPriorityWarning;
10484
10485var ReactStrictModeWarnings = {
10486 discardPendingWarnings: function () {},
10487 flushPendingDeprecationWarnings: function () {},
10488 flushPendingUnsafeLifecycleWarnings: function () {},
10489 recordDeprecationWarnings: function (fiber, instance) {},
10490 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
10491 recordLegacyContextWarning: function (fiber, instance) {},
10492 flushLegacyContextWarning: function () {}
10493};
10494
10495{
10496 var LIFECYCLE_SUGGESTIONS = {
10497 UNSAFE_componentWillMount: 'componentDidMount',
10498 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
10499 UNSAFE_componentWillUpdate: 'componentDidUpdate'
10500 };
10501
10502 var pendingComponentWillMountWarnings = [];
10503 var pendingComponentWillReceivePropsWarnings = [];
10504 var pendingComponentWillUpdateWarnings = [];
10505 var pendingUnsafeLifecycleWarnings = new Map();
10506 var pendingLegacyContextWarning = new Map();
10507
10508 // Tracks components we have already warned about.
10509 var didWarnAboutDeprecatedLifecycles = new Set();
10510 var didWarnAboutUnsafeLifecycles = new Set();
10511 var didWarnAboutLegacyContext = new Set();
10512
10513 var setToSortedString = function (set) {
10514 var array = [];
10515 set.forEach(function (value) {
10516 array.push(value);
10517 });
10518 return array.sort().join(', ');
10519 };
10520
10521 ReactStrictModeWarnings.discardPendingWarnings = function () {
10522 pendingComponentWillMountWarnings = [];
10523 pendingComponentWillReceivePropsWarnings = [];
10524 pendingComponentWillUpdateWarnings = [];
10525 pendingUnsafeLifecycleWarnings = new Map();
10526 pendingLegacyContextWarning = new Map();
10527 };
10528
10529 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
10530 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
10531 var lifecyclesWarningMessages = [];
10532
10533 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
10534 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
10535 if (lifecycleWarnings.length > 0) {
10536 var componentNames = new Set();
10537 lifecycleWarnings.forEach(function (fiber) {
10538 componentNames.add(getComponentName(fiber.type) || 'Component');
10539 didWarnAboutUnsafeLifecycles.add(fiber.type);
10540 });
10541
10542 var formatted = lifecycle.replace('UNSAFE_', '');
10543 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
10544 var sortedComponentNames = setToSortedString(componentNames);
10545
10546 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
10547 }
10548 });
10549
10550 if (lifecyclesWarningMessages.length > 0) {
10551 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10552
10553 warningWithoutStack$1(false, 'Unsafe lifecycle methods were found within a strict-mode tree:%s' + '\n\n%s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, lifecyclesWarningMessages.join('\n\n'));
10554 }
10555 });
10556
10557 pendingUnsafeLifecycleWarnings = new Map();
10558 };
10559
10560 var findStrictRoot = function (fiber) {
10561 var maybeStrictRoot = null;
10562
10563 var node = fiber;
10564 while (node !== null) {
10565 if (node.mode & StrictMode) {
10566 maybeStrictRoot = node;
10567 }
10568 node = node.return;
10569 }
10570
10571 return maybeStrictRoot;
10572 };
10573
10574 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
10575 if (pendingComponentWillMountWarnings.length > 0) {
10576 var uniqueNames = new Set();
10577 pendingComponentWillMountWarnings.forEach(function (fiber) {
10578 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10579 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10580 });
10581
10582 var sortedNames = setToSortedString(uniqueNames);
10583
10584 lowPriorityWarning$1(false, 'componentWillMount is deprecated and will be removed in the next major version. ' + 'Use componentDidMount instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillMount.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', sortedNames);
10585
10586 pendingComponentWillMountWarnings = [];
10587 }
10588
10589 if (pendingComponentWillReceivePropsWarnings.length > 0) {
10590 var _uniqueNames = new Set();
10591 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
10592 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
10593 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10594 });
10595
10596 var _sortedNames = setToSortedString(_uniqueNames);
10597
10598 lowPriorityWarning$1(false, 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' + 'Use static getDerivedStateFromProps instead.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames);
10599
10600 pendingComponentWillReceivePropsWarnings = [];
10601 }
10602
10603 if (pendingComponentWillUpdateWarnings.length > 0) {
10604 var _uniqueNames2 = new Set();
10605 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
10606 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
10607 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10608 });
10609
10610 var _sortedNames2 = setToSortedString(_uniqueNames2);
10611
10612 lowPriorityWarning$1(false, 'componentWillUpdate is deprecated and will be removed in the next major version. ' + 'Use componentDidUpdate instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillUpdate.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames2);
10613
10614 pendingComponentWillUpdateWarnings = [];
10615 }
10616 };
10617
10618 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
10619 // Dedup strategy: Warn once per component.
10620 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
10621 return;
10622 }
10623
10624 // Don't warn about react-lifecycles-compat polyfilled components.
10625 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
10626 pendingComponentWillMountWarnings.push(fiber);
10627 }
10628 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
10629 pendingComponentWillReceivePropsWarnings.push(fiber);
10630 }
10631 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
10632 pendingComponentWillUpdateWarnings.push(fiber);
10633 }
10634 };
10635
10636 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
10637 var strictRoot = findStrictRoot(fiber);
10638 if (strictRoot === null) {
10639 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.');
10640 return;
10641 }
10642
10643 // Dedup strategy: Warn once per component.
10644 // This is difficult to track any other way since component names
10645 // are often vague and are likely to collide between 3rd party libraries.
10646 // An expand property is probably okay to use here since it's DEV-only,
10647 // and will only be set in the event of serious warnings.
10648 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
10649 return;
10650 }
10651
10652 var warningsForRoot = void 0;
10653 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
10654 warningsForRoot = {
10655 UNSAFE_componentWillMount: [],
10656 UNSAFE_componentWillReceiveProps: [],
10657 UNSAFE_componentWillUpdate: []
10658 };
10659
10660 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
10661 } else {
10662 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
10663 }
10664
10665 var unsafeLifecycles = [];
10666 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
10667 unsafeLifecycles.push('UNSAFE_componentWillMount');
10668 }
10669 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
10670 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
10671 }
10672 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
10673 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
10674 }
10675
10676 if (unsafeLifecycles.length > 0) {
10677 unsafeLifecycles.forEach(function (lifecycle) {
10678 warningsForRoot[lifecycle].push(fiber);
10679 });
10680 }
10681 };
10682
10683 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
10684 var strictRoot = findStrictRoot(fiber);
10685 if (strictRoot === null) {
10686 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.');
10687 return;
10688 }
10689
10690 // Dedup strategy: Warn once per component.
10691 if (didWarnAboutLegacyContext.has(fiber.type)) {
10692 return;
10693 }
10694
10695 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
10696
10697 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
10698 if (warningsForRoot === undefined) {
10699 warningsForRoot = [];
10700 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
10701 }
10702 warningsForRoot.push(fiber);
10703 }
10704 };
10705
10706 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
10707 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
10708 var uniqueNames = new Set();
10709 fiberArray.forEach(function (fiber) {
10710 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10711 didWarnAboutLegacyContext.add(fiber.type);
10712 });
10713
10714 var sortedNames = setToSortedString(uniqueNames);
10715 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10716
10717 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, sortedNames);
10718 });
10719 };
10720}
10721
10722// This lets us hook into Fiber to debug what it's doing.
10723// See https://github.com/facebook/react/pull/8033.
10724// This is not part of the public API, not even for React DevTools.
10725// You may only inject a debugTool if you work on React Fiber itself.
10726var ReactFiberInstrumentation = {
10727 debugTool: null
10728};
10729
10730var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10731
10732// TODO: Offscreen updates should never suspend. However, a promise that
10733// suspended inside an offscreen subtree should be able to ping at the priority
10734// of the outer render.
10735
10736function markPendingPriorityLevel(root, expirationTime) {
10737 // If there's a gap between completing a failed root and retrying it,
10738 // additional updates may be scheduled. Clear `didError`, in case the update
10739 // is sufficient to fix the error.
10740 root.didError = false;
10741
10742 // Update the latest and earliest pending times
10743 var earliestPendingTime = root.earliestPendingTime;
10744 if (earliestPendingTime === NoWork) {
10745 // No other pending updates.
10746 root.earliestPendingTime = root.latestPendingTime = expirationTime;
10747 } else {
10748 if (earliestPendingTime < expirationTime) {
10749 // This is the earliest pending update.
10750 root.earliestPendingTime = expirationTime;
10751 } else {
10752 var latestPendingTime = root.latestPendingTime;
10753 if (latestPendingTime > expirationTime) {
10754 // This is the latest pending update
10755 root.latestPendingTime = expirationTime;
10756 }
10757 }
10758 }
10759 findNextExpirationTimeToWorkOn(expirationTime, root);
10760}
10761
10762function markCommittedPriorityLevels(root, earliestRemainingTime) {
10763 root.didError = false;
10764
10765 if (earliestRemainingTime === NoWork) {
10766 // Fast path. There's no remaining work. Clear everything.
10767 root.earliestPendingTime = NoWork;
10768 root.latestPendingTime = NoWork;
10769 root.earliestSuspendedTime = NoWork;
10770 root.latestSuspendedTime = NoWork;
10771 root.latestPingedTime = NoWork;
10772 findNextExpirationTimeToWorkOn(NoWork, root);
10773 return;
10774 }
10775
10776 if (earliestRemainingTime < root.latestPingedTime) {
10777 root.latestPingedTime = NoWork;
10778 }
10779
10780 // Let's see if the previous latest known pending level was just flushed.
10781 var latestPendingTime = root.latestPendingTime;
10782 if (latestPendingTime !== NoWork) {
10783 if (latestPendingTime > earliestRemainingTime) {
10784 // We've flushed all the known pending levels.
10785 root.earliestPendingTime = root.latestPendingTime = NoWork;
10786 } else {
10787 var earliestPendingTime = root.earliestPendingTime;
10788 if (earliestPendingTime > earliestRemainingTime) {
10789 // We've flushed the earliest known pending level. Set this to the
10790 // latest pending time.
10791 root.earliestPendingTime = root.latestPendingTime;
10792 }
10793 }
10794 }
10795
10796 // Now let's handle the earliest remaining level in the whole tree. We need to
10797 // decide whether to treat it as a pending level or as suspended. Check
10798 // it falls within the range of known suspended levels.
10799
10800 var earliestSuspendedTime = root.earliestSuspendedTime;
10801 if (earliestSuspendedTime === NoWork) {
10802 // There's no suspended work. Treat the earliest remaining level as a
10803 // pending level.
10804 markPendingPriorityLevel(root, earliestRemainingTime);
10805 findNextExpirationTimeToWorkOn(NoWork, root);
10806 return;
10807 }
10808
10809 var latestSuspendedTime = root.latestSuspendedTime;
10810 if (earliestRemainingTime < latestSuspendedTime) {
10811 // The earliest remaining level is later than all the suspended work. That
10812 // means we've flushed all the suspended work.
10813 root.earliestSuspendedTime = NoWork;
10814 root.latestSuspendedTime = NoWork;
10815 root.latestPingedTime = NoWork;
10816
10817 // There's no suspended work. Treat the earliest remaining level as a
10818 // pending level.
10819 markPendingPriorityLevel(root, earliestRemainingTime);
10820 findNextExpirationTimeToWorkOn(NoWork, root);
10821 return;
10822 }
10823
10824 if (earliestRemainingTime > earliestSuspendedTime) {
10825 // The earliest remaining time is earlier than all the suspended work.
10826 // Treat it as a pending update.
10827 markPendingPriorityLevel(root, earliestRemainingTime);
10828 findNextExpirationTimeToWorkOn(NoWork, root);
10829 return;
10830 }
10831
10832 // The earliest remaining time falls within the range of known suspended
10833 // levels. We should treat this as suspended work.
10834 findNextExpirationTimeToWorkOn(NoWork, root);
10835}
10836
10837function hasLowerPriorityWork(root, erroredExpirationTime) {
10838 var latestPendingTime = root.latestPendingTime;
10839 var latestSuspendedTime = root.latestSuspendedTime;
10840 var latestPingedTime = root.latestPingedTime;
10841 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
10842}
10843
10844function isPriorityLevelSuspended(root, expirationTime) {
10845 var earliestSuspendedTime = root.earliestSuspendedTime;
10846 var latestSuspendedTime = root.latestSuspendedTime;
10847 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
10848}
10849
10850function markSuspendedPriorityLevel(root, suspendedTime) {
10851 root.didError = false;
10852 clearPing(root, suspendedTime);
10853
10854 // First, check the known pending levels and update them if needed.
10855 var earliestPendingTime = root.earliestPendingTime;
10856 var latestPendingTime = root.latestPendingTime;
10857 if (earliestPendingTime === suspendedTime) {
10858 if (latestPendingTime === suspendedTime) {
10859 // Both known pending levels were suspended. Clear them.
10860 root.earliestPendingTime = root.latestPendingTime = NoWork;
10861 } else {
10862 // The earliest pending level was suspended. Clear by setting it to the
10863 // latest pending level.
10864 root.earliestPendingTime = latestPendingTime;
10865 }
10866 } else if (latestPendingTime === suspendedTime) {
10867 // The latest pending level was suspended. Clear by setting it to the
10868 // latest pending level.
10869 root.latestPendingTime = earliestPendingTime;
10870 }
10871
10872 // Finally, update the known suspended levels.
10873 var earliestSuspendedTime = root.earliestSuspendedTime;
10874 var latestSuspendedTime = root.latestSuspendedTime;
10875 if (earliestSuspendedTime === NoWork) {
10876 // No other suspended levels.
10877 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
10878 } else {
10879 if (earliestSuspendedTime < suspendedTime) {
10880 // This is the earliest suspended level.
10881 root.earliestSuspendedTime = suspendedTime;
10882 } else if (latestSuspendedTime > suspendedTime) {
10883 // This is the latest suspended level
10884 root.latestSuspendedTime = suspendedTime;
10885 }
10886 }
10887
10888 findNextExpirationTimeToWorkOn(suspendedTime, root);
10889}
10890
10891function markPingedPriorityLevel(root, pingedTime) {
10892 root.didError = false;
10893
10894 // TODO: When we add back resuming, we need to ensure the progressed work
10895 // is thrown out and not reused during the restarted render. One way to
10896 // invalidate the progressed work is to restart at expirationTime + 1.
10897 var latestPingedTime = root.latestPingedTime;
10898 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
10899 root.latestPingedTime = pingedTime;
10900 }
10901 findNextExpirationTimeToWorkOn(pingedTime, root);
10902}
10903
10904function clearPing(root, completedTime) {
10905 var latestPingedTime = root.latestPingedTime;
10906 if (latestPingedTime >= completedTime) {
10907 root.latestPingedTime = NoWork;
10908 }
10909}
10910
10911function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
10912 var earliestExpirationTime = renderExpirationTime;
10913
10914 var earliestPendingTime = root.earliestPendingTime;
10915 var earliestSuspendedTime = root.earliestSuspendedTime;
10916 if (earliestPendingTime > earliestExpirationTime) {
10917 earliestExpirationTime = earliestPendingTime;
10918 }
10919 if (earliestSuspendedTime > earliestExpirationTime) {
10920 earliestExpirationTime = earliestSuspendedTime;
10921 }
10922 return earliestExpirationTime;
10923}
10924
10925function didExpireAtExpirationTime(root, currentTime) {
10926 var expirationTime = root.expirationTime;
10927 if (expirationTime !== NoWork && currentTime <= expirationTime) {
10928 // The root has expired. Flush all work up to the current time.
10929 root.nextExpirationTimeToWorkOn = currentTime;
10930 }
10931}
10932
10933function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
10934 var earliestSuspendedTime = root.earliestSuspendedTime;
10935 var latestSuspendedTime = root.latestSuspendedTime;
10936 var earliestPendingTime = root.earliestPendingTime;
10937 var latestPingedTime = root.latestPingedTime;
10938
10939 // Work on the earliest pending time. Failing that, work on the latest
10940 // pinged time.
10941 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
10942
10943 // If there is no pending or pinged work, check if there's suspended work
10944 // that's lower priority than what we just completed.
10945 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
10946 // The lowest priority suspended work is the work most likely to be
10947 // committed next. Let's start rendering it again, so that if it times out,
10948 // it's ready to commit.
10949 nextExpirationTimeToWorkOn = latestSuspendedTime;
10950 }
10951
10952 var expirationTime = nextExpirationTimeToWorkOn;
10953 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
10954 // Expire using the earliest known expiration time.
10955 expirationTime = earliestSuspendedTime;
10956 }
10957
10958 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
10959 root.expirationTime = expirationTime;
10960}
10961
10962function resolveDefaultProps(Component, baseProps) {
10963 if (Component && Component.defaultProps) {
10964 // Resolve default props. Taken from ReactElement
10965 var props = _assign({}, baseProps);
10966 var defaultProps = Component.defaultProps;
10967 for (var propName in defaultProps) {
10968 if (props[propName] === undefined) {
10969 props[propName] = defaultProps[propName];
10970 }
10971 }
10972 return props;
10973 }
10974 return baseProps;
10975}
10976
10977function readLazyComponentType(lazyComponent) {
10978 var status = lazyComponent._status;
10979 var result = lazyComponent._result;
10980 switch (status) {
10981 case Resolved:
10982 {
10983 var Component = result;
10984 return Component;
10985 }
10986 case Rejected:
10987 {
10988 var error = result;
10989 throw error;
10990 }
10991 case Pending:
10992 {
10993 var thenable = result;
10994 throw thenable;
10995 }
10996 default:
10997 {
10998 lazyComponent._status = Pending;
10999 var ctor = lazyComponent._ctor;
11000 var _thenable = ctor();
11001 _thenable.then(function (moduleObject) {
11002 if (lazyComponent._status === Pending) {
11003 var defaultExport = moduleObject.default;
11004 {
11005 if (defaultExport === undefined) {
11006 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);
11007 }
11008 }
11009 lazyComponent._status = Resolved;
11010 lazyComponent._result = defaultExport;
11011 }
11012 }, function (error) {
11013 if (lazyComponent._status === Pending) {
11014 lazyComponent._status = Rejected;
11015 lazyComponent._result = error;
11016 }
11017 });
11018 // Handle synchronous thenables.
11019 switch (lazyComponent._status) {
11020 case Resolved:
11021 return lazyComponent._result;
11022 case Rejected:
11023 throw lazyComponent._result;
11024 }
11025 lazyComponent._result = _thenable;
11026 throw _thenable;
11027 }
11028 }
11029}
11030
11031var fakeInternalInstance = {};
11032var isArray$1 = Array.isArray;
11033
11034// React.Component uses a shared frozen object by default.
11035// We'll use it to determine whether we need to initialize legacy refs.
11036var emptyRefsObject = new React.Component().refs;
11037
11038var didWarnAboutStateAssignmentForComponent = void 0;
11039var didWarnAboutUninitializedState = void 0;
11040var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
11041var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
11042var didWarnAboutUndefinedDerivedState = void 0;
11043var warnOnUndefinedDerivedState = void 0;
11044var warnOnInvalidCallback$1 = void 0;
11045var didWarnAboutDirectlyAssigningPropsToState = void 0;
11046var didWarnAboutContextTypeAndContextTypes = void 0;
11047var didWarnAboutInvalidateContextType = void 0;
11048
11049{
11050 didWarnAboutStateAssignmentForComponent = new Set();
11051 didWarnAboutUninitializedState = new Set();
11052 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
11053 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
11054 didWarnAboutDirectlyAssigningPropsToState = new Set();
11055 didWarnAboutUndefinedDerivedState = new Set();
11056 didWarnAboutContextTypeAndContextTypes = new Set();
11057 didWarnAboutInvalidateContextType = new Set();
11058
11059 var didWarnOnInvalidCallback = new Set();
11060
11061 warnOnInvalidCallback$1 = function (callback, callerName) {
11062 if (callback === null || typeof callback === 'function') {
11063 return;
11064 }
11065 var key = callerName + '_' + callback;
11066 if (!didWarnOnInvalidCallback.has(key)) {
11067 didWarnOnInvalidCallback.add(key);
11068 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
11069 }
11070 };
11071
11072 warnOnUndefinedDerivedState = function (type, partialState) {
11073 if (partialState === undefined) {
11074 var componentName = getComponentName(type) || 'Component';
11075 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
11076 didWarnAboutUndefinedDerivedState.add(componentName);
11077 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
11078 }
11079 }
11080 };
11081
11082 // This is so gross but it's at least non-critical and can be removed if
11083 // it causes problems. This is meant to give a nicer error message for
11084 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
11085 // ...)) which otherwise throws a "_processChildContext is not a function"
11086 // exception.
11087 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
11088 enumerable: false,
11089 value: function () {
11090 invariant(false, '_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).');
11091 }
11092 });
11093 Object.freeze(fakeInternalInstance);
11094}
11095
11096function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
11097 var prevState = workInProgress.memoizedState;
11098
11099 {
11100 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11101 // Invoke the function an extra time to help detect side-effects.
11102 getDerivedStateFromProps(nextProps, prevState);
11103 }
11104 }
11105
11106 var partialState = getDerivedStateFromProps(nextProps, prevState);
11107
11108 {
11109 warnOnUndefinedDerivedState(ctor, partialState);
11110 }
11111 // Merge the partial state and the previous state.
11112 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
11113 workInProgress.memoizedState = memoizedState;
11114
11115 // Once the update queue is empty, persist the derived state onto the
11116 // base state.
11117 var updateQueue = workInProgress.updateQueue;
11118 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
11119 updateQueue.baseState = memoizedState;
11120 }
11121}
11122
11123var classComponentUpdater = {
11124 isMounted: isMounted,
11125 enqueueSetState: function (inst, payload, callback) {
11126 var fiber = get(inst);
11127 var currentTime = requestCurrentTime();
11128 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11129
11130 var update = createUpdate(expirationTime);
11131 update.payload = payload;
11132 if (callback !== undefined && callback !== null) {
11133 {
11134 warnOnInvalidCallback$1(callback, 'setState');
11135 }
11136 update.callback = callback;
11137 }
11138
11139 flushPassiveEffects();
11140 enqueueUpdate(fiber, update);
11141 scheduleWork(fiber, expirationTime);
11142 },
11143 enqueueReplaceState: function (inst, payload, callback) {
11144 var fiber = get(inst);
11145 var currentTime = requestCurrentTime();
11146 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11147
11148 var update = createUpdate(expirationTime);
11149 update.tag = ReplaceState;
11150 update.payload = payload;
11151
11152 if (callback !== undefined && callback !== null) {
11153 {
11154 warnOnInvalidCallback$1(callback, 'replaceState');
11155 }
11156 update.callback = callback;
11157 }
11158
11159 flushPassiveEffects();
11160 enqueueUpdate(fiber, update);
11161 scheduleWork(fiber, expirationTime);
11162 },
11163 enqueueForceUpdate: function (inst, callback) {
11164 var fiber = get(inst);
11165 var currentTime = requestCurrentTime();
11166 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11167
11168 var update = createUpdate(expirationTime);
11169 update.tag = ForceUpdate;
11170
11171 if (callback !== undefined && callback !== null) {
11172 {
11173 warnOnInvalidCallback$1(callback, 'forceUpdate');
11174 }
11175 update.callback = callback;
11176 }
11177
11178 flushPassiveEffects();
11179 enqueueUpdate(fiber, update);
11180 scheduleWork(fiber, expirationTime);
11181 }
11182};
11183
11184function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
11185 var instance = workInProgress.stateNode;
11186 if (typeof instance.shouldComponentUpdate === 'function') {
11187 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
11188 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
11189 stopPhaseTimer();
11190
11191 {
11192 !(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;
11193 }
11194
11195 return shouldUpdate;
11196 }
11197
11198 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
11199 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
11200 }
11201
11202 return true;
11203}
11204
11205function checkClassInstance(workInProgress, ctor, newProps) {
11206 var instance = workInProgress.stateNode;
11207 {
11208 var name = getComponentName(ctor) || 'Component';
11209 var renderPresent = instance.render;
11210
11211 if (!renderPresent) {
11212 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
11213 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
11214 } else {
11215 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
11216 }
11217 }
11218
11219 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
11220 !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;
11221 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
11222 !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;
11223 var noInstancePropTypes = !instance.propTypes;
11224 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
11225 var noInstanceContextType = !instance.contextType;
11226 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
11227 var noInstanceContextTypes = !instance.contextTypes;
11228 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
11229
11230 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
11231 didWarnAboutContextTypeAndContextTypes.add(ctor);
11232 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
11233 }
11234
11235 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
11236 !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;
11237 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
11238 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');
11239 }
11240 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
11241 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
11242 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
11243 !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;
11244 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
11245 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
11246 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
11247 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
11248 var hasMutatedProps = instance.props !== newProps;
11249 !(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;
11250 var noInstanceDefaultProps = !instance.defaultProps;
11251 !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;
11252
11253 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
11254 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
11255 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
11256 }
11257
11258 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
11259 !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;
11260 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
11261 !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;
11262 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
11263 !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;
11264 var _state = instance.state;
11265 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
11266 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
11267 }
11268 if (typeof instance.getChildContext === 'function') {
11269 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
11270 }
11271 }
11272}
11273
11274function adoptClassInstance(workInProgress, instance) {
11275 instance.updater = classComponentUpdater;
11276 workInProgress.stateNode = instance;
11277 // The instance needs access to the fiber so that it can schedule updates
11278 set(instance, workInProgress);
11279 {
11280 instance._reactInternalInstance = fakeInternalInstance;
11281 }
11282}
11283
11284function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
11285 var isLegacyContextConsumer = false;
11286 var unmaskedContext = emptyContextObject;
11287 var context = null;
11288 var contextType = ctor.contextType;
11289 if (typeof contextType === 'object' && contextType !== null) {
11290 {
11291 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
11292 didWarnAboutInvalidateContextType.add(ctor);
11293 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext(). ' + 'Did you accidentally pass the Context.Provider instead?', getComponentName(ctor) || 'Component');
11294 }
11295 }
11296
11297 context = readContext(contextType);
11298 } else {
11299 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11300 var contextTypes = ctor.contextTypes;
11301 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
11302 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
11303 }
11304
11305 // Instantiate twice to help detect side-effects.
11306 {
11307 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11308 new ctor(props, context); // eslint-disable-line no-new
11309 }
11310 }
11311
11312 var instance = new ctor(props, context);
11313 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
11314 adoptClassInstance(workInProgress, instance);
11315
11316 {
11317 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
11318 var componentName = getComponentName(ctor) || 'Component';
11319 if (!didWarnAboutUninitializedState.has(componentName)) {
11320 didWarnAboutUninitializedState.add(componentName);
11321 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);
11322 }
11323 }
11324
11325 // If new component APIs are defined, "unsafe" lifecycles won't be called.
11326 // Warn about these lifecycles if they are present.
11327 // Don't warn about react-lifecycles-compat polyfilled methods though.
11328 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
11329 var foundWillMountName = null;
11330 var foundWillReceivePropsName = null;
11331 var foundWillUpdateName = null;
11332 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
11333 foundWillMountName = 'componentWillMount';
11334 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
11335 foundWillMountName = 'UNSAFE_componentWillMount';
11336 }
11337 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11338 foundWillReceivePropsName = 'componentWillReceiveProps';
11339 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11340 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
11341 }
11342 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11343 foundWillUpdateName = 'componentWillUpdate';
11344 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11345 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
11346 }
11347 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
11348 var _componentName = getComponentName(ctor) || 'Component';
11349 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
11350 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
11351 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
11352 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 : '');
11353 }
11354 }
11355 }
11356 }
11357
11358 // Cache unmasked context so we can avoid recreating masked context unless necessary.
11359 // ReactFiberContext usually updates this cache but can't for newly-created instances.
11360 if (isLegacyContextConsumer) {
11361 cacheContext(workInProgress, unmaskedContext, context);
11362 }
11363
11364 return instance;
11365}
11366
11367function callComponentWillMount(workInProgress, instance) {
11368 startPhaseTimer(workInProgress, 'componentWillMount');
11369 var oldState = instance.state;
11370
11371 if (typeof instance.componentWillMount === 'function') {
11372 instance.componentWillMount();
11373 }
11374 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11375 instance.UNSAFE_componentWillMount();
11376 }
11377
11378 stopPhaseTimer();
11379
11380 if (oldState !== instance.state) {
11381 {
11382 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');
11383 }
11384 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11385 }
11386}
11387
11388function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
11389 var oldState = instance.state;
11390 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
11391 if (typeof instance.componentWillReceiveProps === 'function') {
11392 instance.componentWillReceiveProps(newProps, nextContext);
11393 }
11394 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11395 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
11396 }
11397 stopPhaseTimer();
11398
11399 if (instance.state !== oldState) {
11400 {
11401 var componentName = getComponentName(workInProgress.type) || 'Component';
11402 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
11403 didWarnAboutStateAssignmentForComponent.add(componentName);
11404 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
11405 }
11406 }
11407 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11408 }
11409}
11410
11411// Invokes the mount life-cycles on a previously never rendered instance.
11412function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11413 {
11414 checkClassInstance(workInProgress, ctor, newProps);
11415 }
11416
11417 var instance = workInProgress.stateNode;
11418 instance.props = newProps;
11419 instance.state = workInProgress.memoizedState;
11420 instance.refs = emptyRefsObject;
11421
11422 var contextType = ctor.contextType;
11423 if (typeof contextType === 'object' && contextType !== null) {
11424 instance.context = readContext(contextType);
11425 } else {
11426 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11427 instance.context = getMaskedContext(workInProgress, unmaskedContext);
11428 }
11429
11430 {
11431 if (instance.state === newProps) {
11432 var componentName = getComponentName(ctor) || 'Component';
11433 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
11434 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
11435 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);
11436 }
11437 }
11438
11439 if (workInProgress.mode & StrictMode) {
11440 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
11441
11442 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
11443 }
11444
11445 if (warnAboutDeprecatedLifecycles) {
11446 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
11447 }
11448 }
11449
11450 var updateQueue = workInProgress.updateQueue;
11451 if (updateQueue !== null) {
11452 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11453 instance.state = workInProgress.memoizedState;
11454 }
11455
11456 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11457 if (typeof getDerivedStateFromProps === 'function') {
11458 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11459 instance.state = workInProgress.memoizedState;
11460 }
11461
11462 // In order to support react-lifecycles-compat polyfilled components,
11463 // Unsafe lifecycles should not be invoked for components using the new APIs.
11464 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11465 callComponentWillMount(workInProgress, instance);
11466 // If we had additional state updates during this life-cycle, let's
11467 // process them now.
11468 updateQueue = workInProgress.updateQueue;
11469 if (updateQueue !== null) {
11470 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11471 instance.state = workInProgress.memoizedState;
11472 }
11473 }
11474
11475 if (typeof instance.componentDidMount === 'function') {
11476 workInProgress.effectTag |= Update;
11477 }
11478}
11479
11480function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11481 var instance = workInProgress.stateNode;
11482
11483 var oldProps = workInProgress.memoizedProps;
11484 instance.props = oldProps;
11485
11486 var oldContext = instance.context;
11487 var contextType = ctor.contextType;
11488 var nextContext = void 0;
11489 if (typeof contextType === 'object' && contextType !== null) {
11490 nextContext = readContext(contextType);
11491 } else {
11492 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11493 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
11494 }
11495
11496 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11497 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11498
11499 // Note: During these life-cycles, instance.props/instance.state are what
11500 // ever the previously attempted to render - not the "current". However,
11501 // during componentDidUpdate we pass the "current" props.
11502
11503 // In order to support react-lifecycles-compat polyfilled components,
11504 // Unsafe lifecycles should not be invoked for components using the new APIs.
11505 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11506 if (oldProps !== newProps || oldContext !== nextContext) {
11507 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11508 }
11509 }
11510
11511 resetHasForceUpdateBeforeProcessing();
11512
11513 var oldState = workInProgress.memoizedState;
11514 var newState = instance.state = oldState;
11515 var updateQueue = workInProgress.updateQueue;
11516 if (updateQueue !== null) {
11517 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11518 newState = workInProgress.memoizedState;
11519 }
11520 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11521 // If an update was already in progress, we should schedule an Update
11522 // effect even though we're bailing out, so that cWU/cDU are called.
11523 if (typeof instance.componentDidMount === 'function') {
11524 workInProgress.effectTag |= Update;
11525 }
11526 return false;
11527 }
11528
11529 if (typeof getDerivedStateFromProps === 'function') {
11530 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11531 newState = workInProgress.memoizedState;
11532 }
11533
11534 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11535
11536 if (shouldUpdate) {
11537 // In order to support react-lifecycles-compat polyfilled components,
11538 // Unsafe lifecycles should not be invoked for components using the new APIs.
11539 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11540 startPhaseTimer(workInProgress, 'componentWillMount');
11541 if (typeof instance.componentWillMount === 'function') {
11542 instance.componentWillMount();
11543 }
11544 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11545 instance.UNSAFE_componentWillMount();
11546 }
11547 stopPhaseTimer();
11548 }
11549 if (typeof instance.componentDidMount === 'function') {
11550 workInProgress.effectTag |= Update;
11551 }
11552 } else {
11553 // If an update was already in progress, we should schedule an Update
11554 // effect even though we're bailing out, so that cWU/cDU are called.
11555 if (typeof instance.componentDidMount === 'function') {
11556 workInProgress.effectTag |= Update;
11557 }
11558
11559 // If shouldComponentUpdate returned false, we should still update the
11560 // memoized state to indicate that this work can be reused.
11561 workInProgress.memoizedProps = newProps;
11562 workInProgress.memoizedState = newState;
11563 }
11564
11565 // Update the existing instance's state, props, and context pointers even
11566 // if shouldComponentUpdate returns false.
11567 instance.props = newProps;
11568 instance.state = newState;
11569 instance.context = nextContext;
11570
11571 return shouldUpdate;
11572}
11573
11574// Invokes the update life-cycles and returns false if it shouldn't rerender.
11575function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
11576 var instance = workInProgress.stateNode;
11577
11578 var oldProps = workInProgress.memoizedProps;
11579 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
11580
11581 var oldContext = instance.context;
11582 var contextType = ctor.contextType;
11583 var nextContext = void 0;
11584 if (typeof contextType === 'object' && contextType !== null) {
11585 nextContext = readContext(contextType);
11586 } else {
11587 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11588 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
11589 }
11590
11591 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11592 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11593
11594 // Note: During these life-cycles, instance.props/instance.state are what
11595 // ever the previously attempted to render - not the "current". However,
11596 // during componentDidUpdate we pass the "current" props.
11597
11598 // In order to support react-lifecycles-compat polyfilled components,
11599 // Unsafe lifecycles should not be invoked for components using the new APIs.
11600 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11601 if (oldProps !== newProps || oldContext !== nextContext) {
11602 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11603 }
11604 }
11605
11606 resetHasForceUpdateBeforeProcessing();
11607
11608 var oldState = workInProgress.memoizedState;
11609 var newState = instance.state = oldState;
11610 var updateQueue = workInProgress.updateQueue;
11611 if (updateQueue !== null) {
11612 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11613 newState = workInProgress.memoizedState;
11614 }
11615
11616 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11617 // If an update was already in progress, we should schedule an Update
11618 // effect even though we're bailing out, so that cWU/cDU are called.
11619 if (typeof instance.componentDidUpdate === 'function') {
11620 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11621 workInProgress.effectTag |= Update;
11622 }
11623 }
11624 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11625 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11626 workInProgress.effectTag |= Snapshot;
11627 }
11628 }
11629 return false;
11630 }
11631
11632 if (typeof getDerivedStateFromProps === 'function') {
11633 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11634 newState = workInProgress.memoizedState;
11635 }
11636
11637 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11638
11639 if (shouldUpdate) {
11640 // In order to support react-lifecycles-compat polyfilled components,
11641 // Unsafe lifecycles should not be invoked for components using the new APIs.
11642 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
11643 startPhaseTimer(workInProgress, 'componentWillUpdate');
11644 if (typeof instance.componentWillUpdate === 'function') {
11645 instance.componentWillUpdate(newProps, newState, nextContext);
11646 }
11647 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11648 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
11649 }
11650 stopPhaseTimer();
11651 }
11652 if (typeof instance.componentDidUpdate === 'function') {
11653 workInProgress.effectTag |= Update;
11654 }
11655 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11656 workInProgress.effectTag |= Snapshot;
11657 }
11658 } else {
11659 // If an update was already in progress, we should schedule an Update
11660 // effect even though we're bailing out, so that cWU/cDU are called.
11661 if (typeof instance.componentDidUpdate === 'function') {
11662 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11663 workInProgress.effectTag |= Update;
11664 }
11665 }
11666 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11667 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11668 workInProgress.effectTag |= Snapshot;
11669 }
11670 }
11671
11672 // If shouldComponentUpdate returned false, we should still update the
11673 // memoized props/state to indicate that this work can be reused.
11674 workInProgress.memoizedProps = newProps;
11675 workInProgress.memoizedState = newState;
11676 }
11677
11678 // Update the existing instance's state, props, and context pointers even
11679 // if shouldComponentUpdate returns false.
11680 instance.props = newProps;
11681 instance.state = newState;
11682 instance.context = nextContext;
11683
11684 return shouldUpdate;
11685}
11686
11687var didWarnAboutMaps = void 0;
11688var didWarnAboutGenerators = void 0;
11689var didWarnAboutStringRefInStrictMode = void 0;
11690var ownerHasKeyUseWarning = void 0;
11691var ownerHasFunctionTypeWarning = void 0;
11692var warnForMissingKey = function (child) {};
11693
11694{
11695 didWarnAboutMaps = false;
11696 didWarnAboutGenerators = false;
11697 didWarnAboutStringRefInStrictMode = {};
11698
11699 /**
11700 * Warn if there's no key explicitly set on dynamic arrays of children or
11701 * object keys are not valid. This allows us to keep track of children between
11702 * updates.
11703 */
11704 ownerHasKeyUseWarning = {};
11705 ownerHasFunctionTypeWarning = {};
11706
11707 warnForMissingKey = function (child) {
11708 if (child === null || typeof child !== 'object') {
11709 return;
11710 }
11711 if (!child._store || child._store.validated || child.key != null) {
11712 return;
11713 }
11714 !(typeof child._store === 'object') ? invariant(false, 'React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11715 child._store.validated = true;
11716
11717 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
11718 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
11719 return;
11720 }
11721 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
11722
11723 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
11724 };
11725}
11726
11727var isArray = Array.isArray;
11728
11729function coerceRef(returnFiber, current$$1, element) {
11730 var mixedRef = element.ref;
11731 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
11732 {
11733 if (returnFiber.mode & StrictMode) {
11734 var componentName = getComponentName(returnFiber.type) || 'Component';
11735 if (!didWarnAboutStringRefInStrictMode[componentName]) {
11736 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));
11737 didWarnAboutStringRefInStrictMode[componentName] = true;
11738 }
11739 }
11740 }
11741
11742 if (element._owner) {
11743 var owner = element._owner;
11744 var inst = void 0;
11745 if (owner) {
11746 var ownerFiber = owner;
11747 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
11748 inst = ownerFiber.stateNode;
11749 }
11750 !inst ? invariant(false, 'Missing owner for string ref %s. This error is likely caused by a bug in React. Please file an issue.', mixedRef) : void 0;
11751 var stringRef = '' + mixedRef;
11752 // Check if previous string ref matches new string ref
11753 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
11754 return current$$1.ref;
11755 }
11756 var ref = function (value) {
11757 var refs = inst.refs;
11758 if (refs === emptyRefsObject) {
11759 // This is a lazy pooled frozen object, so we need to initialize.
11760 refs = inst.refs = {};
11761 }
11762 if (value === null) {
11763 delete refs[stringRef];
11764 } else {
11765 refs[stringRef] = value;
11766 }
11767 };
11768 ref._stringRef = stringRef;
11769 return ref;
11770 } else {
11771 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
11772 !element._owner ? invariant(false, 'Element ref was specified as a string (%s) 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.', mixedRef) : void 0;
11773 }
11774 }
11775 return mixedRef;
11776}
11777
11778function throwOnInvalidObjectType(returnFiber, newChild) {
11779 if (returnFiber.type !== 'textarea') {
11780 var addendum = '';
11781 {
11782 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
11783 }
11784 invariant(false, 'Objects are not valid as a React child (found: %s).%s', Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild, addendum);
11785 }
11786}
11787
11788function warnOnFunctionType() {
11789 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();
11790
11791 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
11792 return;
11793 }
11794 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
11795
11796 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.');
11797}
11798
11799// This wrapper function exists because I expect to clone the code in each path
11800// to be able to optimize each path individually by branching early. This needs
11801// a compiler or we can do it manually. Helpers that don't need this branching
11802// live outside of this function.
11803function ChildReconciler(shouldTrackSideEffects) {
11804 function deleteChild(returnFiber, childToDelete) {
11805 if (!shouldTrackSideEffects) {
11806 // Noop.
11807 return;
11808 }
11809 // Deletions are added in reversed order so we add it to the front.
11810 // At this point, the return fiber's effect list is empty except for
11811 // deletions, so we can just append the deletion to the list. The remaining
11812 // effects aren't added until the complete phase. Once we implement
11813 // resuming, this may not be true.
11814 var last = returnFiber.lastEffect;
11815 if (last !== null) {
11816 last.nextEffect = childToDelete;
11817 returnFiber.lastEffect = childToDelete;
11818 } else {
11819 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
11820 }
11821 childToDelete.nextEffect = null;
11822 childToDelete.effectTag = Deletion;
11823 }
11824
11825 function deleteRemainingChildren(returnFiber, currentFirstChild) {
11826 if (!shouldTrackSideEffects) {
11827 // Noop.
11828 return null;
11829 }
11830
11831 // TODO: For the shouldClone case, this could be micro-optimized a bit by
11832 // assuming that after the first child we've already added everything.
11833 var childToDelete = currentFirstChild;
11834 while (childToDelete !== null) {
11835 deleteChild(returnFiber, childToDelete);
11836 childToDelete = childToDelete.sibling;
11837 }
11838 return null;
11839 }
11840
11841 function mapRemainingChildren(returnFiber, currentFirstChild) {
11842 // Add the remaining children to a temporary map so that we can find them by
11843 // keys quickly. Implicit (null) keys get added to this set with their index
11844 var existingChildren = new Map();
11845
11846 var existingChild = currentFirstChild;
11847 while (existingChild !== null) {
11848 if (existingChild.key !== null) {
11849 existingChildren.set(existingChild.key, existingChild);
11850 } else {
11851 existingChildren.set(existingChild.index, existingChild);
11852 }
11853 existingChild = existingChild.sibling;
11854 }
11855 return existingChildren;
11856 }
11857
11858 function useFiber(fiber, pendingProps, expirationTime) {
11859 // We currently set sibling to null and index to 0 here because it is easy
11860 // to forget to do before returning it. E.g. for the single child case.
11861 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
11862 clone.index = 0;
11863 clone.sibling = null;
11864 return clone;
11865 }
11866
11867 function placeChild(newFiber, lastPlacedIndex, newIndex) {
11868 newFiber.index = newIndex;
11869 if (!shouldTrackSideEffects) {
11870 // Noop.
11871 return lastPlacedIndex;
11872 }
11873 var current$$1 = newFiber.alternate;
11874 if (current$$1 !== null) {
11875 var oldIndex = current$$1.index;
11876 if (oldIndex < lastPlacedIndex) {
11877 // This is a move.
11878 newFiber.effectTag = Placement;
11879 return lastPlacedIndex;
11880 } else {
11881 // This item can stay in place.
11882 return oldIndex;
11883 }
11884 } else {
11885 // This is an insertion.
11886 newFiber.effectTag = Placement;
11887 return lastPlacedIndex;
11888 }
11889 }
11890
11891 function placeSingleChild(newFiber) {
11892 // This is simpler for the single child case. We only need to do a
11893 // placement for inserting new children.
11894 if (shouldTrackSideEffects && newFiber.alternate === null) {
11895 newFiber.effectTag = Placement;
11896 }
11897 return newFiber;
11898 }
11899
11900 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
11901 if (current$$1 === null || current$$1.tag !== HostText) {
11902 // Insert
11903 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
11904 created.return = returnFiber;
11905 return created;
11906 } else {
11907 // Update
11908 var existing = useFiber(current$$1, textContent, expirationTime);
11909 existing.return = returnFiber;
11910 return existing;
11911 }
11912 }
11913
11914 function updateElement(returnFiber, current$$1, element, expirationTime) {
11915 if (current$$1 !== null && current$$1.elementType === element.type) {
11916 // Move based on index
11917 var existing = useFiber(current$$1, element.props, expirationTime);
11918 existing.ref = coerceRef(returnFiber, current$$1, element);
11919 existing.return = returnFiber;
11920 {
11921 existing._debugSource = element._source;
11922 existing._debugOwner = element._owner;
11923 }
11924 return existing;
11925 } else {
11926 // Insert
11927 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
11928 created.ref = coerceRef(returnFiber, current$$1, element);
11929 created.return = returnFiber;
11930 return created;
11931 }
11932 }
11933
11934 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
11935 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
11936 // Insert
11937 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
11938 created.return = returnFiber;
11939 return created;
11940 } else {
11941 // Update
11942 var existing = useFiber(current$$1, portal.children || [], expirationTime);
11943 existing.return = returnFiber;
11944 return existing;
11945 }
11946 }
11947
11948 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
11949 if (current$$1 === null || current$$1.tag !== Fragment) {
11950 // Insert
11951 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
11952 created.return = returnFiber;
11953 return created;
11954 } else {
11955 // Update
11956 var existing = useFiber(current$$1, fragment, expirationTime);
11957 existing.return = returnFiber;
11958 return existing;
11959 }
11960 }
11961
11962 function createChild(returnFiber, newChild, expirationTime) {
11963 if (typeof newChild === 'string' || typeof newChild === 'number') {
11964 // Text nodes don't have keys. If the previous node is implicitly keyed
11965 // we can continue to replace it without aborting even if it is not a text
11966 // node.
11967 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
11968 created.return = returnFiber;
11969 return created;
11970 }
11971
11972 if (typeof newChild === 'object' && newChild !== null) {
11973 switch (newChild.$$typeof) {
11974 case REACT_ELEMENT_TYPE:
11975 {
11976 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
11977 _created.ref = coerceRef(returnFiber, null, newChild);
11978 _created.return = returnFiber;
11979 return _created;
11980 }
11981 case REACT_PORTAL_TYPE:
11982 {
11983 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
11984 _created2.return = returnFiber;
11985 return _created2;
11986 }
11987 }
11988
11989 if (isArray(newChild) || getIteratorFn(newChild)) {
11990 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
11991 _created3.return = returnFiber;
11992 return _created3;
11993 }
11994
11995 throwOnInvalidObjectType(returnFiber, newChild);
11996 }
11997
11998 {
11999 if (typeof newChild === 'function') {
12000 warnOnFunctionType();
12001 }
12002 }
12003
12004 return null;
12005 }
12006
12007 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
12008 // Update the fiber if the keys match, otherwise return null.
12009
12010 var key = oldFiber !== null ? oldFiber.key : null;
12011
12012 if (typeof newChild === 'string' || typeof newChild === 'number') {
12013 // Text nodes don't have keys. If the previous node is implicitly keyed
12014 // we can continue to replace it without aborting even if it is not a text
12015 // node.
12016 if (key !== null) {
12017 return null;
12018 }
12019 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
12020 }
12021
12022 if (typeof newChild === 'object' && newChild !== null) {
12023 switch (newChild.$$typeof) {
12024 case REACT_ELEMENT_TYPE:
12025 {
12026 if (newChild.key === key) {
12027 if (newChild.type === REACT_FRAGMENT_TYPE) {
12028 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
12029 }
12030 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
12031 } else {
12032 return null;
12033 }
12034 }
12035 case REACT_PORTAL_TYPE:
12036 {
12037 if (newChild.key === key) {
12038 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
12039 } else {
12040 return null;
12041 }
12042 }
12043 }
12044
12045 if (isArray(newChild) || getIteratorFn(newChild)) {
12046 if (key !== null) {
12047 return null;
12048 }
12049
12050 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
12051 }
12052
12053 throwOnInvalidObjectType(returnFiber, newChild);
12054 }
12055
12056 {
12057 if (typeof newChild === 'function') {
12058 warnOnFunctionType();
12059 }
12060 }
12061
12062 return null;
12063 }
12064
12065 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
12066 if (typeof newChild === 'string' || typeof newChild === 'number') {
12067 // Text nodes don't have keys, so we neither have to check the old nor
12068 // new node for the key. If both are text nodes, they match.
12069 var matchedFiber = existingChildren.get(newIdx) || null;
12070 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
12071 }
12072
12073 if (typeof newChild === 'object' && newChild !== null) {
12074 switch (newChild.$$typeof) {
12075 case REACT_ELEMENT_TYPE:
12076 {
12077 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12078 if (newChild.type === REACT_FRAGMENT_TYPE) {
12079 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
12080 }
12081 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
12082 }
12083 case REACT_PORTAL_TYPE:
12084 {
12085 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12086 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
12087 }
12088 }
12089
12090 if (isArray(newChild) || getIteratorFn(newChild)) {
12091 var _matchedFiber3 = existingChildren.get(newIdx) || null;
12092 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
12093 }
12094
12095 throwOnInvalidObjectType(returnFiber, newChild);
12096 }
12097
12098 {
12099 if (typeof newChild === 'function') {
12100 warnOnFunctionType();
12101 }
12102 }
12103
12104 return null;
12105 }
12106
12107 /**
12108 * Warns if there is a duplicate or missing key
12109 */
12110 function warnOnInvalidKey(child, knownKeys) {
12111 {
12112 if (typeof child !== 'object' || child === null) {
12113 return knownKeys;
12114 }
12115 switch (child.$$typeof) {
12116 case REACT_ELEMENT_TYPE:
12117 case REACT_PORTAL_TYPE:
12118 warnForMissingKey(child);
12119 var key = child.key;
12120 if (typeof key !== 'string') {
12121 break;
12122 }
12123 if (knownKeys === null) {
12124 knownKeys = new Set();
12125 knownKeys.add(key);
12126 break;
12127 }
12128 if (!knownKeys.has(key)) {
12129 knownKeys.add(key);
12130 break;
12131 }
12132 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);
12133 break;
12134 default:
12135 break;
12136 }
12137 }
12138 return knownKeys;
12139 }
12140
12141 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
12142 // This algorithm can't optimize by searching from both ends since we
12143 // don't have backpointers on fibers. I'm trying to see how far we can get
12144 // with that model. If it ends up not being worth the tradeoffs, we can
12145 // add it later.
12146
12147 // Even with a two ended optimization, we'd want to optimize for the case
12148 // where there are few changes and brute force the comparison instead of
12149 // going for the Map. It'd like to explore hitting that path first in
12150 // forward-only mode and only go for the Map once we notice that we need
12151 // lots of look ahead. This doesn't handle reversal as well as two ended
12152 // search but that's unusual. Besides, for the two ended optimization to
12153 // work on Iterables, we'd need to copy the whole set.
12154
12155 // In this first iteration, we'll just live with hitting the bad case
12156 // (adding everything to a Map) in for every insert/move.
12157
12158 // If you change this code, also update reconcileChildrenIterator() which
12159 // uses the same algorithm.
12160
12161 {
12162 // First, validate keys.
12163 var knownKeys = null;
12164 for (var i = 0; i < newChildren.length; i++) {
12165 var child = newChildren[i];
12166 knownKeys = warnOnInvalidKey(child, knownKeys);
12167 }
12168 }
12169
12170 var resultingFirstChild = null;
12171 var previousNewFiber = null;
12172
12173 var oldFiber = currentFirstChild;
12174 var lastPlacedIndex = 0;
12175 var newIdx = 0;
12176 var nextOldFiber = null;
12177 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
12178 if (oldFiber.index > newIdx) {
12179 nextOldFiber = oldFiber;
12180 oldFiber = null;
12181 } else {
12182 nextOldFiber = oldFiber.sibling;
12183 }
12184 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
12185 if (newFiber === null) {
12186 // TODO: This breaks on empty slots like null children. That's
12187 // unfortunate because it triggers the slow path all the time. We need
12188 // a better way to communicate whether this was a miss or null,
12189 // boolean, undefined, etc.
12190 if (oldFiber === null) {
12191 oldFiber = nextOldFiber;
12192 }
12193 break;
12194 }
12195 if (shouldTrackSideEffects) {
12196 if (oldFiber && newFiber.alternate === null) {
12197 // We matched the slot, but we didn't reuse the existing fiber, so we
12198 // need to delete the existing child.
12199 deleteChild(returnFiber, oldFiber);
12200 }
12201 }
12202 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12203 if (previousNewFiber === null) {
12204 // TODO: Move out of the loop. This only happens for the first run.
12205 resultingFirstChild = newFiber;
12206 } else {
12207 // TODO: Defer siblings if we're not at the right index for this slot.
12208 // I.e. if we had null values before, then we want to defer this
12209 // for each null value. However, we also don't want to call updateSlot
12210 // with the previous one.
12211 previousNewFiber.sibling = newFiber;
12212 }
12213 previousNewFiber = newFiber;
12214 oldFiber = nextOldFiber;
12215 }
12216
12217 if (newIdx === newChildren.length) {
12218 // We've reached the end of the new children. We can delete the rest.
12219 deleteRemainingChildren(returnFiber, oldFiber);
12220 return resultingFirstChild;
12221 }
12222
12223 if (oldFiber === null) {
12224 // If we don't have any more existing children we can choose a fast path
12225 // since the rest will all be insertions.
12226 for (; newIdx < newChildren.length; newIdx++) {
12227 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
12228 if (!_newFiber) {
12229 continue;
12230 }
12231 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
12232 if (previousNewFiber === null) {
12233 // TODO: Move out of the loop. This only happens for the first run.
12234 resultingFirstChild = _newFiber;
12235 } else {
12236 previousNewFiber.sibling = _newFiber;
12237 }
12238 previousNewFiber = _newFiber;
12239 }
12240 return resultingFirstChild;
12241 }
12242
12243 // Add all children to a key map for quick lookups.
12244 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12245
12246 // Keep scanning and use the map to restore deleted items as moves.
12247 for (; newIdx < newChildren.length; newIdx++) {
12248 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
12249 if (_newFiber2) {
12250 if (shouldTrackSideEffects) {
12251 if (_newFiber2.alternate !== null) {
12252 // The new fiber is a work in progress, but if there exists a
12253 // current, that means that we reused the fiber. We need to delete
12254 // it from the child list so that we don't add it to the deletion
12255 // list.
12256 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
12257 }
12258 }
12259 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
12260 if (previousNewFiber === null) {
12261 resultingFirstChild = _newFiber2;
12262 } else {
12263 previousNewFiber.sibling = _newFiber2;
12264 }
12265 previousNewFiber = _newFiber2;
12266 }
12267 }
12268
12269 if (shouldTrackSideEffects) {
12270 // Any existing children that weren't consumed above were deleted. We need
12271 // to add them to the deletion list.
12272 existingChildren.forEach(function (child) {
12273 return deleteChild(returnFiber, child);
12274 });
12275 }
12276
12277 return resultingFirstChild;
12278 }
12279
12280 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
12281 // This is the same implementation as reconcileChildrenArray(),
12282 // but using the iterator instead.
12283
12284 var iteratorFn = getIteratorFn(newChildrenIterable);
12285 !(typeof iteratorFn === 'function') ? invariant(false, 'An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12286
12287 {
12288 // We don't support rendering Generators because it's a mutation.
12289 // See https://github.com/facebook/react/issues/12995
12290 if (typeof Symbol === 'function' &&
12291 // $FlowFixMe Flow doesn't know about toStringTag
12292 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
12293 !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;
12294 didWarnAboutGenerators = true;
12295 }
12296
12297 // Warn about using Maps as children
12298 if (newChildrenIterable.entries === iteratorFn) {
12299 !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;
12300 didWarnAboutMaps = true;
12301 }
12302
12303 // First, validate keys.
12304 // We'll get a different iterator later for the main pass.
12305 var _newChildren = iteratorFn.call(newChildrenIterable);
12306 if (_newChildren) {
12307 var knownKeys = null;
12308 var _step = _newChildren.next();
12309 for (; !_step.done; _step = _newChildren.next()) {
12310 var child = _step.value;
12311 knownKeys = warnOnInvalidKey(child, knownKeys);
12312 }
12313 }
12314 }
12315
12316 var newChildren = iteratorFn.call(newChildrenIterable);
12317 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
12318
12319 var resultingFirstChild = null;
12320 var previousNewFiber = null;
12321
12322 var oldFiber = currentFirstChild;
12323 var lastPlacedIndex = 0;
12324 var newIdx = 0;
12325 var nextOldFiber = null;
12326
12327 var step = newChildren.next();
12328 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
12329 if (oldFiber.index > newIdx) {
12330 nextOldFiber = oldFiber;
12331 oldFiber = null;
12332 } else {
12333 nextOldFiber = oldFiber.sibling;
12334 }
12335 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
12336 if (newFiber === null) {
12337 // TODO: This breaks on empty slots like null children. That's
12338 // unfortunate because it triggers the slow path all the time. We need
12339 // a better way to communicate whether this was a miss or null,
12340 // boolean, undefined, etc.
12341 if (!oldFiber) {
12342 oldFiber = nextOldFiber;
12343 }
12344 break;
12345 }
12346 if (shouldTrackSideEffects) {
12347 if (oldFiber && newFiber.alternate === null) {
12348 // We matched the slot, but we didn't reuse the existing fiber, so we
12349 // need to delete the existing child.
12350 deleteChild(returnFiber, oldFiber);
12351 }
12352 }
12353 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12354 if (previousNewFiber === null) {
12355 // TODO: Move out of the loop. This only happens for the first run.
12356 resultingFirstChild = newFiber;
12357 } else {
12358 // TODO: Defer siblings if we're not at the right index for this slot.
12359 // I.e. if we had null values before, then we want to defer this
12360 // for each null value. However, we also don't want to call updateSlot
12361 // with the previous one.
12362 previousNewFiber.sibling = newFiber;
12363 }
12364 previousNewFiber = newFiber;
12365 oldFiber = nextOldFiber;
12366 }
12367
12368 if (step.done) {
12369 // We've reached the end of the new children. We can delete the rest.
12370 deleteRemainingChildren(returnFiber, oldFiber);
12371 return resultingFirstChild;
12372 }
12373
12374 if (oldFiber === null) {
12375 // If we don't have any more existing children we can choose a fast path
12376 // since the rest will all be insertions.
12377 for (; !step.done; newIdx++, step = newChildren.next()) {
12378 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
12379 if (_newFiber3 === null) {
12380 continue;
12381 }
12382 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
12383 if (previousNewFiber === null) {
12384 // TODO: Move out of the loop. This only happens for the first run.
12385 resultingFirstChild = _newFiber3;
12386 } else {
12387 previousNewFiber.sibling = _newFiber3;
12388 }
12389 previousNewFiber = _newFiber3;
12390 }
12391 return resultingFirstChild;
12392 }
12393
12394 // Add all children to a key map for quick lookups.
12395 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12396
12397 // Keep scanning and use the map to restore deleted items as moves.
12398 for (; !step.done; newIdx++, step = newChildren.next()) {
12399 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
12400 if (_newFiber4 !== null) {
12401 if (shouldTrackSideEffects) {
12402 if (_newFiber4.alternate !== null) {
12403 // The new fiber is a work in progress, but if there exists a
12404 // current, that means that we reused the fiber. We need to delete
12405 // it from the child list so that we don't add it to the deletion
12406 // list.
12407 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
12408 }
12409 }
12410 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
12411 if (previousNewFiber === null) {
12412 resultingFirstChild = _newFiber4;
12413 } else {
12414 previousNewFiber.sibling = _newFiber4;
12415 }
12416 previousNewFiber = _newFiber4;
12417 }
12418 }
12419
12420 if (shouldTrackSideEffects) {
12421 // Any existing children that weren't consumed above were deleted. We need
12422 // to add them to the deletion list.
12423 existingChildren.forEach(function (child) {
12424 return deleteChild(returnFiber, child);
12425 });
12426 }
12427
12428 return resultingFirstChild;
12429 }
12430
12431 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
12432 // There's no need to check for keys on text nodes since we don't have a
12433 // way to define them.
12434 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
12435 // We already have an existing node so let's just update it and delete
12436 // the rest.
12437 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
12438 var existing = useFiber(currentFirstChild, textContent, expirationTime);
12439 existing.return = returnFiber;
12440 return existing;
12441 }
12442 // The existing first child is not a text node so we need to create one
12443 // and delete the existing ones.
12444 deleteRemainingChildren(returnFiber, currentFirstChild);
12445 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
12446 created.return = returnFiber;
12447 return created;
12448 }
12449
12450 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
12451 var key = element.key;
12452 var child = currentFirstChild;
12453 while (child !== null) {
12454 // TODO: If key === null and child.key === null, then this only applies to
12455 // the first item in the list.
12456 if (child.key === key) {
12457 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
12458 deleteRemainingChildren(returnFiber, child.sibling);
12459 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
12460 existing.ref = coerceRef(returnFiber, child, element);
12461 existing.return = returnFiber;
12462 {
12463 existing._debugSource = element._source;
12464 existing._debugOwner = element._owner;
12465 }
12466 return existing;
12467 } else {
12468 deleteRemainingChildren(returnFiber, child);
12469 break;
12470 }
12471 } else {
12472 deleteChild(returnFiber, child);
12473 }
12474 child = child.sibling;
12475 }
12476
12477 if (element.type === REACT_FRAGMENT_TYPE) {
12478 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
12479 created.return = returnFiber;
12480 return created;
12481 } else {
12482 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
12483 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
12484 _created4.return = returnFiber;
12485 return _created4;
12486 }
12487 }
12488
12489 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
12490 var key = portal.key;
12491 var child = currentFirstChild;
12492 while (child !== null) {
12493 // TODO: If key === null and child.key === null, then this only applies to
12494 // the first item in the list.
12495 if (child.key === key) {
12496 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
12497 deleteRemainingChildren(returnFiber, child.sibling);
12498 var existing = useFiber(child, portal.children || [], expirationTime);
12499 existing.return = returnFiber;
12500 return existing;
12501 } else {
12502 deleteRemainingChildren(returnFiber, child);
12503 break;
12504 }
12505 } else {
12506 deleteChild(returnFiber, child);
12507 }
12508 child = child.sibling;
12509 }
12510
12511 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
12512 created.return = returnFiber;
12513 return created;
12514 }
12515
12516 // This API will tag the children with the side-effect of the reconciliation
12517 // itself. They will be added to the side-effect list as we pass through the
12518 // children and the parent.
12519 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
12520 // This function is not recursive.
12521 // If the top level item is an array, we treat it as a set of children,
12522 // not as a fragment. Nested arrays on the other hand will be treated as
12523 // fragment nodes. Recursion happens at the normal flow.
12524
12525 // Handle top level unkeyed fragments as if they were arrays.
12526 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
12527 // We treat the ambiguous cases above the same.
12528 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
12529 if (isUnkeyedTopLevelFragment) {
12530 newChild = newChild.props.children;
12531 }
12532
12533 // Handle object types
12534 var isObject = typeof newChild === 'object' && newChild !== null;
12535
12536 if (isObject) {
12537 switch (newChild.$$typeof) {
12538 case REACT_ELEMENT_TYPE:
12539 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
12540 case REACT_PORTAL_TYPE:
12541 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
12542 }
12543 }
12544
12545 if (typeof newChild === 'string' || typeof newChild === 'number') {
12546 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
12547 }
12548
12549 if (isArray(newChild)) {
12550 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
12551 }
12552
12553 if (getIteratorFn(newChild)) {
12554 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
12555 }
12556
12557 if (isObject) {
12558 throwOnInvalidObjectType(returnFiber, newChild);
12559 }
12560
12561 {
12562 if (typeof newChild === 'function') {
12563 warnOnFunctionType();
12564 }
12565 }
12566 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
12567 // If the new child is undefined, and the return fiber is a composite
12568 // component, throw an error. If Fiber return types are disabled,
12569 // we already threw above.
12570 switch (returnFiber.tag) {
12571 case ClassComponent:
12572 {
12573 {
12574 var instance = returnFiber.stateNode;
12575 if (instance.render._isMockFunction) {
12576 // We allow auto-mocks to proceed as if they're returning null.
12577 break;
12578 }
12579 }
12580 }
12581 // Intentionally fall through to the next case, which handles both
12582 // functions and classes
12583 // eslint-disable-next-lined no-fallthrough
12584 case FunctionComponent:
12585 {
12586 var Component = returnFiber.type;
12587 invariant(false, '%s(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.', Component.displayName || Component.name || 'Component');
12588 }
12589 }
12590 }
12591
12592 // Remaining cases are all treated as empty.
12593 return deleteRemainingChildren(returnFiber, currentFirstChild);
12594 }
12595
12596 return reconcileChildFibers;
12597}
12598
12599var reconcileChildFibers = ChildReconciler(true);
12600var mountChildFibers = ChildReconciler(false);
12601
12602function cloneChildFibers(current$$1, workInProgress) {
12603 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
12604
12605 if (workInProgress.child === null) {
12606 return;
12607 }
12608
12609 var currentChild = workInProgress.child;
12610 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12611 workInProgress.child = newChild;
12612
12613 newChild.return = workInProgress;
12614 while (currentChild.sibling !== null) {
12615 currentChild = currentChild.sibling;
12616 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12617 newChild.return = workInProgress;
12618 }
12619 newChild.sibling = null;
12620}
12621
12622var NO_CONTEXT = {};
12623
12624var contextStackCursor$1 = createCursor(NO_CONTEXT);
12625var contextFiberStackCursor = createCursor(NO_CONTEXT);
12626var rootInstanceStackCursor = createCursor(NO_CONTEXT);
12627
12628function requiredContext(c) {
12629 !(c !== NO_CONTEXT) ? invariant(false, 'Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12630 return c;
12631}
12632
12633function getRootHostContainer() {
12634 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12635 return rootInstance;
12636}
12637
12638function pushHostContainer(fiber, nextRootInstance) {
12639 // Push current root instance onto the stack;
12640 // This allows us to reset root when portals are popped.
12641 push(rootInstanceStackCursor, nextRootInstance, fiber);
12642 // Track the context and the Fiber that provided it.
12643 // This enables us to pop only Fibers that provide unique contexts.
12644 push(contextFiberStackCursor, fiber, fiber);
12645
12646 // Finally, we need to push the host context to the stack.
12647 // However, we can't just call getRootHostContext() and push it because
12648 // we'd have a different number of entries on the stack depending on
12649 // whether getRootHostContext() throws somewhere in renderer code or not.
12650 // So we push an empty value first. This lets us safely unwind on errors.
12651 push(contextStackCursor$1, NO_CONTEXT, fiber);
12652 var nextRootContext = getRootHostContext(nextRootInstance);
12653 // Now that we know this function doesn't throw, replace it.
12654 pop(contextStackCursor$1, fiber);
12655 push(contextStackCursor$1, nextRootContext, fiber);
12656}
12657
12658function popHostContainer(fiber) {
12659 pop(contextStackCursor$1, fiber);
12660 pop(contextFiberStackCursor, fiber);
12661 pop(rootInstanceStackCursor, fiber);
12662}
12663
12664function getHostContext() {
12665 var context = requiredContext(contextStackCursor$1.current);
12666 return context;
12667}
12668
12669function pushHostContext(fiber) {
12670 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12671 var context = requiredContext(contextStackCursor$1.current);
12672 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
12673
12674 // Don't push this Fiber's context unless it's unique.
12675 if (context === nextContext) {
12676 return;
12677 }
12678
12679 // Track the context and the Fiber that provided it.
12680 // This enables us to pop only Fibers that provide unique contexts.
12681 push(contextFiberStackCursor, fiber, fiber);
12682 push(contextStackCursor$1, nextContext, fiber);
12683}
12684
12685function popHostContext(fiber) {
12686 // Do not pop unless this Fiber provided the current context.
12687 // pushHostContext() only pushes Fibers that provide unique contexts.
12688 if (contextFiberStackCursor.current !== fiber) {
12689 return;
12690 }
12691
12692 pop(contextStackCursor$1, fiber);
12693 pop(contextFiberStackCursor, fiber);
12694}
12695
12696var NoEffect$1 = /* */0;
12697var UnmountSnapshot = /* */2;
12698var UnmountMutation = /* */4;
12699var MountMutation = /* */8;
12700var UnmountLayout = /* */16;
12701var MountLayout = /* */32;
12702var MountPassive = /* */64;
12703var UnmountPassive = /* */128;
12704
12705var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
12706
12707
12708var didWarnAboutMismatchedHooksForComponent = void 0;
12709{
12710 didWarnAboutMismatchedHooksForComponent = new Set();
12711}
12712
12713// These are set right before calling the component.
12714var renderExpirationTime = NoWork;
12715// The work-in-progress fiber. I've named it differently to distinguish it from
12716// the work-in-progress hook.
12717var currentlyRenderingFiber$1 = null;
12718
12719// Hooks are stored as a linked list on the fiber's memoizedState field. The
12720// current hook list is the list that belongs to the current fiber. The
12721// work-in-progress hook list is a new list that will be added to the
12722// work-in-progress fiber.
12723var firstCurrentHook = null;
12724var currentHook = null;
12725var nextCurrentHook = null;
12726var firstWorkInProgressHook = null;
12727var workInProgressHook = null;
12728var nextWorkInProgressHook = null;
12729
12730var remainingExpirationTime = NoWork;
12731var componentUpdateQueue = null;
12732var sideEffectTag = 0;
12733
12734// Updates scheduled during render will trigger an immediate re-render at the
12735// end of the current pass. We can't store these updates on the normal queue,
12736// because if the work is aborted, they should be discarded. Because this is
12737// a relatively rare case, we also don't want to add an additional field to
12738// either the hook or queue object types. So we store them in a lazily create
12739// map of queue -> render-phase updates, which are discarded once the component
12740// completes without re-rendering.
12741
12742// Whether an update was scheduled during the currently executing render pass.
12743var didScheduleRenderPhaseUpdate = false;
12744// Lazily created map of render-phase updates
12745var renderPhaseUpdates = null;
12746// Counter to prevent infinite loops.
12747var numberOfReRenders = 0;
12748var RE_RENDER_LIMIT = 25;
12749
12750// In DEV, this is the name of the currently executing primitive hook
12751var currentHookNameInDev = null;
12752
12753function warnOnHookMismatchInDev() {
12754 {
12755 var componentName = getComponentName(currentlyRenderingFiber$1.type);
12756 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
12757 didWarnAboutMismatchedHooksForComponent.add(componentName);
12758
12759 var secondColumnStart = 22;
12760
12761 var table = '';
12762 var prevHook = firstCurrentHook;
12763 var nextHook = firstWorkInProgressHook;
12764 var n = 1;
12765 while (prevHook !== null && nextHook !== null) {
12766 var oldHookName = prevHook._debugType;
12767 var newHookName = nextHook._debugType;
12768
12769 var row = n + '. ' + oldHookName;
12770
12771 // Extra space so second column lines up
12772 // lol @ IE not supporting String#repeat
12773 while (row.length < secondColumnStart) {
12774 row += ' ';
12775 }
12776
12777 row += newHookName + '\n';
12778
12779 table += row;
12780 prevHook = prevHook.next;
12781 nextHook = nextHook.next;
12782 n++;
12783 }
12784
12785 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);
12786 }
12787 }
12788}
12789
12790function throwInvalidHookError() {
12791 invariant(false, 'Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)');
12792}
12793
12794function areHookInputsEqual(nextDeps, prevDeps) {
12795 if (prevDeps === null) {
12796 {
12797 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);
12798 }
12799 return false;
12800 }
12801
12802 {
12803 // Don't bother comparing lengths in prod because these arrays should be
12804 // passed inline.
12805 if (nextDeps.length !== prevDeps.length) {
12806 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, '[' + nextDeps.join(', ') + ']', '[' + prevDeps.join(', ') + ']');
12807 }
12808 }
12809 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
12810 if (is(nextDeps[i], prevDeps[i])) {
12811 continue;
12812 }
12813 return false;
12814 }
12815 return true;
12816}
12817
12818function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
12819 renderExpirationTime = nextRenderExpirationTime;
12820 currentlyRenderingFiber$1 = workInProgress;
12821 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
12822
12823 // The following should have already been reset
12824 // currentHook = null;
12825 // workInProgressHook = null;
12826
12827 // remainingExpirationTime = NoWork;
12828 // componentUpdateQueue = null;
12829
12830 // didScheduleRenderPhaseUpdate = false;
12831 // renderPhaseUpdates = null;
12832 // numberOfReRenders = 0;
12833 // sideEffectTag = 0;
12834
12835 {
12836 ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
12837 }
12838
12839 var children = Component(props, refOrContext);
12840
12841 if (didScheduleRenderPhaseUpdate) {
12842 do {
12843 didScheduleRenderPhaseUpdate = false;
12844 numberOfReRenders += 1;
12845
12846 // Start over from the beginning of the list
12847 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
12848 nextWorkInProgressHook = firstWorkInProgressHook;
12849
12850 currentHook = null;
12851 workInProgressHook = null;
12852 componentUpdateQueue = null;
12853
12854 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12855
12856 children = Component(props, refOrContext);
12857 } while (didScheduleRenderPhaseUpdate);
12858
12859 renderPhaseUpdates = null;
12860 numberOfReRenders = 0;
12861 }
12862
12863 {
12864 currentHookNameInDev = null;
12865 }
12866
12867 // We can assume the previous dispatcher is always this one, since we set it
12868 // at the beginning of the render phase and there's no re-entrancy.
12869 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12870
12871 var renderedWork = currentlyRenderingFiber$1;
12872
12873 renderedWork.memoizedState = firstWorkInProgressHook;
12874 renderedWork.expirationTime = remainingExpirationTime;
12875 renderedWork.updateQueue = componentUpdateQueue;
12876 renderedWork.effectTag |= sideEffectTag;
12877
12878 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
12879
12880 renderExpirationTime = NoWork;
12881 currentlyRenderingFiber$1 = null;
12882
12883 firstCurrentHook = null;
12884 currentHook = null;
12885 nextCurrentHook = null;
12886 firstWorkInProgressHook = null;
12887 workInProgressHook = null;
12888 nextWorkInProgressHook = null;
12889
12890 remainingExpirationTime = NoWork;
12891 componentUpdateQueue = null;
12892 sideEffectTag = 0;
12893
12894 // These were reset above
12895 // didScheduleRenderPhaseUpdate = false;
12896 // renderPhaseUpdates = null;
12897 // numberOfReRenders = 0;
12898
12899 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
12900
12901 return children;
12902}
12903
12904function bailoutHooks(current, workInProgress, expirationTime) {
12905 workInProgress.updateQueue = current.updateQueue;
12906 workInProgress.effectTag &= ~(Passive | Update);
12907 if (current.expirationTime <= expirationTime) {
12908 current.expirationTime = NoWork;
12909 }
12910}
12911
12912function resetHooks() {
12913 // We can assume the previous dispatcher is always this one, since we set it
12914 // at the beginning of the render phase and there's no re-entrancy.
12915 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12916
12917 // This is used to reset the state of this module when a component throws.
12918 // It's also called inside mountIndeterminateComponent if we determine the
12919 // component is a module-style component.
12920 renderExpirationTime = NoWork;
12921 currentlyRenderingFiber$1 = null;
12922
12923 firstCurrentHook = null;
12924 currentHook = null;
12925 nextCurrentHook = null;
12926 firstWorkInProgressHook = null;
12927 workInProgressHook = null;
12928 nextWorkInProgressHook = null;
12929
12930 remainingExpirationTime = NoWork;
12931 componentUpdateQueue = null;
12932 sideEffectTag = 0;
12933
12934 {
12935 currentHookNameInDev = null;
12936 }
12937
12938 didScheduleRenderPhaseUpdate = false;
12939 renderPhaseUpdates = null;
12940 numberOfReRenders = 0;
12941}
12942
12943function mountWorkInProgressHook() {
12944 var hook = {
12945 memoizedState: null,
12946
12947 baseState: null,
12948 queue: null,
12949 baseUpdate: null,
12950
12951 next: null
12952 };
12953
12954 {
12955 hook._debugType = currentHookNameInDev;
12956 }
12957 if (workInProgressHook === null) {
12958 // This is the first hook in the list
12959 firstWorkInProgressHook = workInProgressHook = hook;
12960 } else {
12961 // Append to the end of the list
12962 workInProgressHook = workInProgressHook.next = hook;
12963 }
12964 return workInProgressHook;
12965}
12966
12967function updateWorkInProgressHook() {
12968 // This function is used both for updates and for re-renders triggered by a
12969 // render phase update. It assumes there is either a current hook we can
12970 // clone, or a work-in-progress hook from a previous render pass that we can
12971 // use as a base. When we reach the end of the base list, we must switch to
12972 // the dispatcher used for mounts.
12973 if (nextWorkInProgressHook !== null) {
12974 // There's already a work-in-progress. Reuse it.
12975 workInProgressHook = nextWorkInProgressHook;
12976 nextWorkInProgressHook = workInProgressHook.next;
12977
12978 currentHook = nextCurrentHook;
12979 nextCurrentHook = currentHook !== null ? currentHook.next : null;
12980 } else {
12981 // Clone from the current hook.
12982 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
12983 currentHook = nextCurrentHook;
12984
12985 var newHook = {
12986 memoizedState: currentHook.memoizedState,
12987
12988 baseState: currentHook.baseState,
12989 queue: currentHook.queue,
12990 baseUpdate: currentHook.baseUpdate,
12991
12992 next: null
12993 };
12994
12995 if (workInProgressHook === null) {
12996 // This is the first hook in the list.
12997 workInProgressHook = firstWorkInProgressHook = newHook;
12998 } else {
12999 // Append to the end of the list.
13000 workInProgressHook = workInProgressHook.next = newHook;
13001 }
13002 nextCurrentHook = currentHook.next;
13003
13004 {
13005 newHook._debugType = currentHookNameInDev;
13006 if (currentHookNameInDev !== currentHook._debugType) {
13007 warnOnHookMismatchInDev();
13008 }
13009 }
13010 }
13011 return workInProgressHook;
13012}
13013
13014function createFunctionComponentUpdateQueue() {
13015 return {
13016 lastEffect: null
13017 };
13018}
13019
13020function basicStateReducer(state, action) {
13021 return typeof action === 'function' ? action(state) : action;
13022}
13023
13024function mountContext(context, observedBits) {
13025 {
13026 mountWorkInProgressHook();
13027 }
13028 return readContext(context, observedBits);
13029}
13030
13031function updateContext(context, observedBits) {
13032 {
13033 updateWorkInProgressHook();
13034 }
13035 return readContext(context, observedBits);
13036}
13037
13038function mountReducer(reducer, initialArg, init) {
13039 var hook = mountWorkInProgressHook();
13040 var initialState = void 0;
13041 if (init !== undefined) {
13042 initialState = init(initialArg);
13043 } else {
13044 initialState = initialArg;
13045 }
13046 hook.memoizedState = hook.baseState = initialState;
13047 var queue = hook.queue = {
13048 last: null,
13049 dispatch: null,
13050 eagerReducer: reducer,
13051 eagerState: initialState
13052 };
13053 var dispatch = queue.dispatch = dispatchAction.bind(null,
13054 // Flow doesn't know this is non-null, but we do.
13055 currentlyRenderingFiber$1, queue);
13056 return [hook.memoizedState, dispatch];
13057}
13058
13059function updateReducer(reducer, initialArg, init) {
13060 var hook = updateWorkInProgressHook();
13061 var queue = hook.queue;
13062 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
13063
13064 if (numberOfReRenders > 0) {
13065 // This is a re-render. Apply the new render phase updates to the previous
13066 var _dispatch = queue.dispatch;
13067 if (renderPhaseUpdates !== null) {
13068 // Render phase updates are stored in a map of queue -> linked list
13069 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13070 if (firstRenderPhaseUpdate !== undefined) {
13071 renderPhaseUpdates.delete(queue);
13072 var newState = hook.memoizedState;
13073 var update = firstRenderPhaseUpdate;
13074 do {
13075 // Process this render phase update. We don't have to check the
13076 // priority because it will always be the same as the current
13077 // render's.
13078 var _action = update.action;
13079 newState = reducer(newState, _action);
13080 update = update.next;
13081 } while (update !== null);
13082
13083 // Mark that the fiber performed work, but only if the new state is
13084 // different from the current state.
13085 if (!is(newState, hook.memoizedState)) {
13086 markWorkInProgressReceivedUpdate();
13087 }
13088
13089 hook.memoizedState = newState;
13090
13091 // Don't persist the state accumlated from the render phase updates to
13092 // the base state unless the queue is empty.
13093 // TODO: Not sure if this is the desired semantics, but it's what we
13094 // do for gDSFP. I can't remember why.
13095 if (hook.baseUpdate === queue.last) {
13096 hook.baseState = newState;
13097 }
13098
13099 return [newState, _dispatch];
13100 }
13101 }
13102 return [hook.memoizedState, _dispatch];
13103 }
13104
13105 // The last update in the entire queue
13106 var last = queue.last;
13107 // The last update that is part of the base state.
13108 var baseUpdate = hook.baseUpdate;
13109 var baseState = hook.baseState;
13110
13111 // Find the first unprocessed update.
13112 var first = void 0;
13113 if (baseUpdate !== null) {
13114 if (last !== null) {
13115 // For the first update, the queue is a circular linked list where
13116 // `queue.last.next = queue.first`. Once the first update commits, and
13117 // the `baseUpdate` is no longer empty, we can unravel the list.
13118 last.next = null;
13119 }
13120 first = baseUpdate.next;
13121 } else {
13122 first = last !== null ? last.next : null;
13123 }
13124 if (first !== null) {
13125 var _newState = baseState;
13126 var newBaseState = null;
13127 var newBaseUpdate = null;
13128 var prevUpdate = baseUpdate;
13129 var _update = first;
13130 var didSkip = false;
13131 do {
13132 var updateExpirationTime = _update.expirationTime;
13133 if (updateExpirationTime < renderExpirationTime) {
13134 // Priority is insufficient. Skip this update. If this is the first
13135 // skipped update, the previous update/state is the new base
13136 // update/state.
13137 if (!didSkip) {
13138 didSkip = true;
13139 newBaseUpdate = prevUpdate;
13140 newBaseState = _newState;
13141 }
13142 // Update the remaining priority in the queue.
13143 if (updateExpirationTime > remainingExpirationTime) {
13144 remainingExpirationTime = updateExpirationTime;
13145 }
13146 } else {
13147 // Process this update.
13148 if (_update.eagerReducer === reducer) {
13149 // If this update was processed eagerly, and its reducer matches the
13150 // current reducer, we can use the eagerly computed state.
13151 _newState = _update.eagerState;
13152 } else {
13153 var _action2 = _update.action;
13154 _newState = reducer(_newState, _action2);
13155 }
13156 }
13157 prevUpdate = _update;
13158 _update = _update.next;
13159 } while (_update !== null && _update !== first);
13160
13161 if (!didSkip) {
13162 newBaseUpdate = prevUpdate;
13163 newBaseState = _newState;
13164 }
13165
13166 // Mark that the fiber performed work, but only if the new state is
13167 // different from the current state.
13168 if (!is(_newState, hook.memoizedState)) {
13169 markWorkInProgressReceivedUpdate();
13170 }
13171
13172 hook.memoizedState = _newState;
13173 hook.baseUpdate = newBaseUpdate;
13174 hook.baseState = newBaseState;
13175
13176 queue.eagerReducer = reducer;
13177 queue.eagerState = _newState;
13178 }
13179
13180 var dispatch = queue.dispatch;
13181 return [hook.memoizedState, dispatch];
13182}
13183
13184function mountState(initialState) {
13185 var hook = mountWorkInProgressHook();
13186 if (typeof initialState === 'function') {
13187 initialState = initialState();
13188 }
13189 hook.memoizedState = hook.baseState = initialState;
13190 var queue = hook.queue = {
13191 last: null,
13192 dispatch: null,
13193 eagerReducer: basicStateReducer,
13194 eagerState: initialState
13195 };
13196 var dispatch = queue.dispatch = dispatchAction.bind(null,
13197 // Flow doesn't know this is non-null, but we do.
13198 currentlyRenderingFiber$1, queue);
13199 return [hook.memoizedState, dispatch];
13200}
13201
13202function updateState(initialState) {
13203 return updateReducer(basicStateReducer, initialState);
13204}
13205
13206function pushEffect(tag, create, destroy, deps) {
13207 var effect = {
13208 tag: tag,
13209 create: create,
13210 destroy: destroy,
13211 deps: deps,
13212 // Circular
13213 next: null
13214 };
13215 if (componentUpdateQueue === null) {
13216 componentUpdateQueue = createFunctionComponentUpdateQueue();
13217 componentUpdateQueue.lastEffect = effect.next = effect;
13218 } else {
13219 var _lastEffect = componentUpdateQueue.lastEffect;
13220 if (_lastEffect === null) {
13221 componentUpdateQueue.lastEffect = effect.next = effect;
13222 } else {
13223 var firstEffect = _lastEffect.next;
13224 _lastEffect.next = effect;
13225 effect.next = firstEffect;
13226 componentUpdateQueue.lastEffect = effect;
13227 }
13228 }
13229 return effect;
13230}
13231
13232function mountRef(initialValue) {
13233 var hook = mountWorkInProgressHook();
13234 var ref = { current: initialValue };
13235 {
13236 Object.seal(ref);
13237 }
13238 hook.memoizedState = ref;
13239 return ref;
13240}
13241
13242function updateRef(initialValue) {
13243 var hook = updateWorkInProgressHook();
13244 return hook.memoizedState;
13245}
13246
13247function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13248 var hook = mountWorkInProgressHook();
13249 var nextDeps = deps === undefined ? null : deps;
13250 sideEffectTag |= fiberEffectTag;
13251 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
13252}
13253
13254function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13255 var hook = updateWorkInProgressHook();
13256 var nextDeps = deps === undefined ? null : deps;
13257 var destroy = undefined;
13258
13259 if (currentHook !== null) {
13260 var prevEffect = currentHook.memoizedState;
13261 destroy = prevEffect.destroy;
13262 if (nextDeps !== null) {
13263 var prevDeps = prevEffect.deps;
13264 if (areHookInputsEqual(nextDeps, prevDeps)) {
13265 pushEffect(NoEffect$1, create, destroy, nextDeps);
13266 return;
13267 }
13268 }
13269 }
13270
13271 sideEffectTag |= fiberEffectTag;
13272 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
13273}
13274
13275function mountEffect(create, deps) {
13276 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13277}
13278
13279function updateEffect(create, deps) {
13280 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13281}
13282
13283function mountLayoutEffect(create, deps) {
13284 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13285}
13286
13287function updateLayoutEffect(create, deps) {
13288 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13289}
13290
13291function imperativeHandleEffect(create, ref) {
13292 if (typeof ref === 'function') {
13293 var refCallback = ref;
13294 var _inst = create();
13295 refCallback(_inst);
13296 return function () {
13297 refCallback(null);
13298 };
13299 } else if (ref !== null && ref !== undefined) {
13300 var refObject = ref;
13301 {
13302 !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;
13303 }
13304 var _inst2 = create();
13305 refObject.current = _inst2;
13306 return function () {
13307 refObject.current = null;
13308 };
13309 }
13310}
13311
13312function mountImperativeHandle(ref, create, deps) {
13313 {
13314 !(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;
13315 }
13316
13317 // TODO: If deps are provided, should we skip comparing the ref itself?
13318 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13319
13320 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13321}
13322
13323function updateImperativeHandle(ref, create, deps) {
13324 {
13325 !(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;
13326 }
13327
13328 // TODO: If deps are provided, should we skip comparing the ref itself?
13329 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13330
13331 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13332}
13333
13334function mountDebugValue(value, formatterFn) {
13335 // This hook is normally a no-op.
13336 // The react-debug-hooks package injects its own implementation
13337 // so that e.g. DevTools can display custom hook values.
13338}
13339
13340var updateDebugValue = mountDebugValue;
13341
13342function mountCallback(callback, deps) {
13343 var hook = mountWorkInProgressHook();
13344 var nextDeps = deps === undefined ? null : deps;
13345 hook.memoizedState = [callback, nextDeps];
13346 return callback;
13347}
13348
13349function updateCallback(callback, deps) {
13350 var hook = updateWorkInProgressHook();
13351 var nextDeps = deps === undefined ? null : deps;
13352 var prevState = hook.memoizedState;
13353 if (prevState !== null) {
13354 if (nextDeps !== null) {
13355 var prevDeps = prevState[1];
13356 if (areHookInputsEqual(nextDeps, prevDeps)) {
13357 return prevState[0];
13358 }
13359 }
13360 }
13361 hook.memoizedState = [callback, nextDeps];
13362 return callback;
13363}
13364
13365function mountMemo(nextCreate, deps) {
13366 var hook = mountWorkInProgressHook();
13367 var nextDeps = deps === undefined ? null : deps;
13368 var nextValue = nextCreate();
13369 hook.memoizedState = [nextValue, nextDeps];
13370 return nextValue;
13371}
13372
13373function updateMemo(nextCreate, deps) {
13374 var hook = updateWorkInProgressHook();
13375 var nextDeps = deps === undefined ? null : deps;
13376 var prevState = hook.memoizedState;
13377 if (prevState !== null) {
13378 // Assume these are defined. If they're not, areHookInputsEqual will warn.
13379 if (nextDeps !== null) {
13380 var prevDeps = prevState[1];
13381 if (areHookInputsEqual(nextDeps, prevDeps)) {
13382 return prevState[0];
13383 }
13384 }
13385 }
13386 var nextValue = nextCreate();
13387 hook.memoizedState = [nextValue, nextDeps];
13388 return nextValue;
13389}
13390
13391// in a test-like environment, we want to warn if dispatchAction()
13392// is called outside of a batchedUpdates/TestUtils.act(...) call.
13393var shouldWarnForUnbatchedSetState = false;
13394
13395{
13396 // jest isn't a 'global', it's just exposed to tests via a wrapped function
13397 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
13398 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
13399 if ('undefined' !== typeof jest) {
13400 shouldWarnForUnbatchedSetState = true;
13401 }
13402}
13403
13404function dispatchAction(fiber, queue, action) {
13405 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
13406
13407 {
13408 !(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;
13409 }
13410
13411 var alternate = fiber.alternate;
13412 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
13413 // This is a render phase update. Stash it in a lazily-created map of
13414 // queue -> linked list of updates. After this render pass, we'll restart
13415 // and apply the stashed updates on top of the work-in-progress hook.
13416 didScheduleRenderPhaseUpdate = true;
13417 var update = {
13418 expirationTime: renderExpirationTime,
13419 action: action,
13420 eagerReducer: null,
13421 eagerState: null,
13422 next: null
13423 };
13424 if (renderPhaseUpdates === null) {
13425 renderPhaseUpdates = new Map();
13426 }
13427 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13428 if (firstRenderPhaseUpdate === undefined) {
13429 renderPhaseUpdates.set(queue, update);
13430 } else {
13431 // Append the update to the end of the list.
13432 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
13433 while (lastRenderPhaseUpdate.next !== null) {
13434 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
13435 }
13436 lastRenderPhaseUpdate.next = update;
13437 }
13438 } else {
13439 flushPassiveEffects();
13440
13441 var currentTime = requestCurrentTime();
13442 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
13443
13444 var _update2 = {
13445 expirationTime: _expirationTime,
13446 action: action,
13447 eagerReducer: null,
13448 eagerState: null,
13449 next: null
13450 };
13451
13452 // Append the update to the end of the list.
13453 var _last = queue.last;
13454 if (_last === null) {
13455 // This is the first update. Create a circular list.
13456 _update2.next = _update2;
13457 } else {
13458 var first = _last.next;
13459 if (first !== null) {
13460 // Still circular.
13461 _update2.next = first;
13462 }
13463 _last.next = _update2;
13464 }
13465 queue.last = _update2;
13466
13467 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
13468 // The queue is currently empty, which means we can eagerly compute the
13469 // next state before entering the render phase. If the new state is the
13470 // same as the current state, we may be able to bail out entirely.
13471 var _eagerReducer = queue.eagerReducer;
13472 if (_eagerReducer !== null) {
13473 var prevDispatcher = void 0;
13474 {
13475 prevDispatcher = ReactCurrentDispatcher$1.current;
13476 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13477 }
13478 try {
13479 var currentState = queue.eagerState;
13480 var _eagerState = _eagerReducer(currentState, action);
13481 // Stash the eagerly computed state, and the reducer used to compute
13482 // it, on the update object. If the reducer hasn't changed by the
13483 // time we enter the render phase, then the eager state can be used
13484 // without calling the reducer again.
13485 _update2.eagerReducer = _eagerReducer;
13486 _update2.eagerState = _eagerState;
13487 if (is(_eagerState, currentState)) {
13488 // Fast path. We can bail out without scheduling React to re-render.
13489 // It's still possible that we'll need to rebase this update later,
13490 // if the component re-renders for a different reason and by that
13491 // time the reducer has changed.
13492 return;
13493 }
13494 } catch (error) {
13495 // Suppress the error. It will throw again in the render phase.
13496 } finally {
13497 {
13498 ReactCurrentDispatcher$1.current = prevDispatcher;
13499 }
13500 }
13501 }
13502 }
13503 {
13504 if (shouldWarnForUnbatchedSetState === true) {
13505 warnIfNotCurrentlyBatchingInDev(fiber);
13506 }
13507 }
13508 scheduleWork(fiber, _expirationTime);
13509 }
13510}
13511
13512var ContextOnlyDispatcher = {
13513 readContext: readContext,
13514
13515 useCallback: throwInvalidHookError,
13516 useContext: throwInvalidHookError,
13517 useEffect: throwInvalidHookError,
13518 useImperativeHandle: throwInvalidHookError,
13519 useLayoutEffect: throwInvalidHookError,
13520 useMemo: throwInvalidHookError,
13521 useReducer: throwInvalidHookError,
13522 useRef: throwInvalidHookError,
13523 useState: throwInvalidHookError,
13524 useDebugValue: throwInvalidHookError
13525};
13526
13527var HooksDispatcherOnMountInDEV = null;
13528var HooksDispatcherOnUpdateInDEV = null;
13529var InvalidNestedHooksDispatcherOnMountInDEV = null;
13530var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13531
13532{
13533 var warnInvalidContextAccess = function () {
13534 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().');
13535 };
13536
13537 var warnInvalidHookAccess = function () {
13538 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');
13539 };
13540
13541 HooksDispatcherOnMountInDEV = {
13542 readContext: function (context, observedBits) {
13543 return readContext(context, observedBits);
13544 },
13545 useCallback: function (callback, deps) {
13546 currentHookNameInDev = 'useCallback';
13547 return mountCallback(callback, deps);
13548 },
13549 useContext: function (context, observedBits) {
13550 currentHookNameInDev = 'useContext';
13551 return mountContext(context, observedBits);
13552 },
13553 useEffect: function (create, deps) {
13554 currentHookNameInDev = 'useEffect';
13555 return mountEffect(create, deps);
13556 },
13557 useImperativeHandle: function (ref, create, deps) {
13558 currentHookNameInDev = 'useImperativeHandle';
13559 return mountImperativeHandle(ref, create, deps);
13560 },
13561 useLayoutEffect: function (create, deps) {
13562 currentHookNameInDev = 'useLayoutEffect';
13563 return mountLayoutEffect(create, deps);
13564 },
13565 useMemo: function (create, deps) {
13566 currentHookNameInDev = 'useMemo';
13567 var prevDispatcher = ReactCurrentDispatcher$1.current;
13568 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13569 try {
13570 return mountMemo(create, deps);
13571 } finally {
13572 ReactCurrentDispatcher$1.current = prevDispatcher;
13573 }
13574 },
13575 useReducer: function (reducer, initialArg, init) {
13576 currentHookNameInDev = 'useReducer';
13577 var prevDispatcher = ReactCurrentDispatcher$1.current;
13578 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13579 try {
13580 return mountReducer(reducer, initialArg, init);
13581 } finally {
13582 ReactCurrentDispatcher$1.current = prevDispatcher;
13583 }
13584 },
13585 useRef: function (initialValue) {
13586 currentHookNameInDev = 'useRef';
13587 return mountRef(initialValue);
13588 },
13589 useState: function (initialState) {
13590 currentHookNameInDev = 'useState';
13591 var prevDispatcher = ReactCurrentDispatcher$1.current;
13592 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13593 try {
13594 return mountState(initialState);
13595 } finally {
13596 ReactCurrentDispatcher$1.current = prevDispatcher;
13597 }
13598 },
13599 useDebugValue: function (value, formatterFn) {
13600 currentHookNameInDev = 'useDebugValue';
13601 return mountDebugValue(value, formatterFn);
13602 }
13603 };
13604
13605 HooksDispatcherOnUpdateInDEV = {
13606 readContext: function (context, observedBits) {
13607 return readContext(context, observedBits);
13608 },
13609 useCallback: function (callback, deps) {
13610 currentHookNameInDev = 'useCallback';
13611 return updateCallback(callback, deps);
13612 },
13613 useContext: function (context, observedBits) {
13614 currentHookNameInDev = 'useContext';
13615 return updateContext(context, observedBits);
13616 },
13617 useEffect: function (create, deps) {
13618 currentHookNameInDev = 'useEffect';
13619 return updateEffect(create, deps);
13620 },
13621 useImperativeHandle: function (ref, create, deps) {
13622 currentHookNameInDev = 'useImperativeHandle';
13623 return updateImperativeHandle(ref, create, deps);
13624 },
13625 useLayoutEffect: function (create, deps) {
13626 currentHookNameInDev = 'useLayoutEffect';
13627 return updateLayoutEffect(create, deps);
13628 },
13629 useMemo: function (create, deps) {
13630 currentHookNameInDev = 'useMemo';
13631 var prevDispatcher = ReactCurrentDispatcher$1.current;
13632 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13633 try {
13634 return updateMemo(create, deps);
13635 } finally {
13636 ReactCurrentDispatcher$1.current = prevDispatcher;
13637 }
13638 },
13639 useReducer: function (reducer, initialArg, init) {
13640 currentHookNameInDev = 'useReducer';
13641 var prevDispatcher = ReactCurrentDispatcher$1.current;
13642 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13643 try {
13644 return updateReducer(reducer, initialArg, init);
13645 } finally {
13646 ReactCurrentDispatcher$1.current = prevDispatcher;
13647 }
13648 },
13649 useRef: function (initialValue) {
13650 currentHookNameInDev = 'useRef';
13651 return updateRef(initialValue);
13652 },
13653 useState: function (initialState) {
13654 currentHookNameInDev = 'useState';
13655 var prevDispatcher = ReactCurrentDispatcher$1.current;
13656 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13657 try {
13658 return updateState(initialState);
13659 } finally {
13660 ReactCurrentDispatcher$1.current = prevDispatcher;
13661 }
13662 },
13663 useDebugValue: function (value, formatterFn) {
13664 currentHookNameInDev = 'useDebugValue';
13665 return updateDebugValue(value, formatterFn);
13666 }
13667 };
13668
13669 InvalidNestedHooksDispatcherOnMountInDEV = {
13670 readContext: function (context, observedBits) {
13671 warnInvalidContextAccess();
13672 return readContext(context, observedBits);
13673 },
13674 useCallback: function (callback, deps) {
13675 currentHookNameInDev = 'useCallback';
13676 warnInvalidHookAccess();
13677 return mountCallback(callback, deps);
13678 },
13679 useContext: function (context, observedBits) {
13680 currentHookNameInDev = 'useContext';
13681 warnInvalidHookAccess();
13682 return mountContext(context, observedBits);
13683 },
13684 useEffect: function (create, deps) {
13685 currentHookNameInDev = 'useEffect';
13686 warnInvalidHookAccess();
13687 return mountEffect(create, deps);
13688 },
13689 useImperativeHandle: function (ref, create, deps) {
13690 currentHookNameInDev = 'useImperativeHandle';
13691 warnInvalidHookAccess();
13692 return mountImperativeHandle(ref, create, deps);
13693 },
13694 useLayoutEffect: function (create, deps) {
13695 currentHookNameInDev = 'useLayoutEffect';
13696 warnInvalidHookAccess();
13697 return mountLayoutEffect(create, deps);
13698 },
13699 useMemo: function (create, deps) {
13700 currentHookNameInDev = 'useMemo';
13701 warnInvalidHookAccess();
13702 var prevDispatcher = ReactCurrentDispatcher$1.current;
13703 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13704 try {
13705 return mountMemo(create, deps);
13706 } finally {
13707 ReactCurrentDispatcher$1.current = prevDispatcher;
13708 }
13709 },
13710 useReducer: function (reducer, initialArg, init) {
13711 currentHookNameInDev = 'useReducer';
13712 warnInvalidHookAccess();
13713 var prevDispatcher = ReactCurrentDispatcher$1.current;
13714 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13715 try {
13716 return mountReducer(reducer, initialArg, init);
13717 } finally {
13718 ReactCurrentDispatcher$1.current = prevDispatcher;
13719 }
13720 },
13721 useRef: function (initialValue) {
13722 currentHookNameInDev = 'useRef';
13723 warnInvalidHookAccess();
13724 return mountRef(initialValue);
13725 },
13726 useState: function (initialState) {
13727 currentHookNameInDev = 'useState';
13728 warnInvalidHookAccess();
13729 var prevDispatcher = ReactCurrentDispatcher$1.current;
13730 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13731 try {
13732 return mountState(initialState);
13733 } finally {
13734 ReactCurrentDispatcher$1.current = prevDispatcher;
13735 }
13736 },
13737 useDebugValue: function (value, formatterFn) {
13738 currentHookNameInDev = 'useDebugValue';
13739 warnInvalidHookAccess();
13740 return mountDebugValue(value, formatterFn);
13741 }
13742 };
13743
13744 InvalidNestedHooksDispatcherOnUpdateInDEV = {
13745 readContext: function (context, observedBits) {
13746 warnInvalidContextAccess();
13747 return readContext(context, observedBits);
13748 },
13749 useCallback: function (callback, deps) {
13750 currentHookNameInDev = 'useCallback';
13751 warnInvalidHookAccess();
13752 return updateCallback(callback, deps);
13753 },
13754 useContext: function (context, observedBits) {
13755 currentHookNameInDev = 'useContext';
13756 warnInvalidHookAccess();
13757 return updateContext(context, observedBits);
13758 },
13759 useEffect: function (create, deps) {
13760 currentHookNameInDev = 'useEffect';
13761 warnInvalidHookAccess();
13762 return updateEffect(create, deps);
13763 },
13764 useImperativeHandle: function (ref, create, deps) {
13765 currentHookNameInDev = 'useImperativeHandle';
13766 warnInvalidHookAccess();
13767 return updateImperativeHandle(ref, create, deps);
13768 },
13769 useLayoutEffect: function (create, deps) {
13770 currentHookNameInDev = 'useLayoutEffect';
13771 warnInvalidHookAccess();
13772 return updateLayoutEffect(create, deps);
13773 },
13774 useMemo: function (create, deps) {
13775 currentHookNameInDev = 'useMemo';
13776 warnInvalidHookAccess();
13777 var prevDispatcher = ReactCurrentDispatcher$1.current;
13778 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13779 try {
13780 return updateMemo(create, deps);
13781 } finally {
13782 ReactCurrentDispatcher$1.current = prevDispatcher;
13783 }
13784 },
13785 useReducer: function (reducer, initialArg, init) {
13786 currentHookNameInDev = 'useReducer';
13787 warnInvalidHookAccess();
13788 var prevDispatcher = ReactCurrentDispatcher$1.current;
13789 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13790 try {
13791 return updateReducer(reducer, initialArg, init);
13792 } finally {
13793 ReactCurrentDispatcher$1.current = prevDispatcher;
13794 }
13795 },
13796 useRef: function (initialValue) {
13797 currentHookNameInDev = 'useRef';
13798 warnInvalidHookAccess();
13799 return updateRef(initialValue);
13800 },
13801 useState: function (initialState) {
13802 currentHookNameInDev = 'useState';
13803 warnInvalidHookAccess();
13804 var prevDispatcher = ReactCurrentDispatcher$1.current;
13805 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13806 try {
13807 return updateState(initialState);
13808 } finally {
13809 ReactCurrentDispatcher$1.current = prevDispatcher;
13810 }
13811 },
13812 useDebugValue: function (value, formatterFn) {
13813 currentHookNameInDev = 'useDebugValue';
13814 warnInvalidHookAccess();
13815 return updateDebugValue(value, formatterFn);
13816 }
13817 };
13818}
13819
13820var commitTime = 0;
13821var profilerStartTime = -1;
13822
13823function getCommitTime() {
13824 return commitTime;
13825}
13826
13827function recordCommitTime() {
13828 if (!enableProfilerTimer) {
13829 return;
13830 }
13831 commitTime = scheduler.unstable_now();
13832}
13833
13834function startProfilerTimer(fiber) {
13835 if (!enableProfilerTimer) {
13836 return;
13837 }
13838
13839 profilerStartTime = scheduler.unstable_now();
13840
13841 if (fiber.actualStartTime < 0) {
13842 fiber.actualStartTime = scheduler.unstable_now();
13843 }
13844}
13845
13846function stopProfilerTimerIfRunning(fiber) {
13847 if (!enableProfilerTimer) {
13848 return;
13849 }
13850 profilerStartTime = -1;
13851}
13852
13853function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
13854 if (!enableProfilerTimer) {
13855 return;
13856 }
13857
13858 if (profilerStartTime >= 0) {
13859 var elapsedTime = scheduler.unstable_now() - profilerStartTime;
13860 fiber.actualDuration += elapsedTime;
13861 if (overrideBaseTime) {
13862 fiber.selfBaseDuration = elapsedTime;
13863 }
13864 profilerStartTime = -1;
13865 }
13866}
13867
13868// The deepest Fiber on the stack involved in a hydration context.
13869// This may have been an insertion or a hydration.
13870var hydrationParentFiber = null;
13871var nextHydratableInstance = null;
13872var isHydrating = false;
13873
13874function enterHydrationState(fiber) {
13875 if (!supportsHydration) {
13876 return false;
13877 }
13878
13879 var parentInstance = fiber.stateNode.containerInfo;
13880 nextHydratableInstance = getFirstHydratableChild(parentInstance);
13881 hydrationParentFiber = fiber;
13882 isHydrating = true;
13883 return true;
13884}
13885
13886function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
13887 if (!supportsHydration) {
13888 return false;
13889 }
13890
13891 var suspenseInstance = fiber.stateNode;
13892 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
13893 popToNextHostParent(fiber);
13894 isHydrating = true;
13895 return true;
13896}
13897
13898function deleteHydratableInstance(returnFiber, instance) {
13899 {
13900 switch (returnFiber.tag) {
13901 case HostRoot:
13902 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
13903 break;
13904 case HostComponent:
13905 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
13906 break;
13907 }
13908 }
13909
13910 var childToDelete = createFiberFromHostInstanceForDeletion();
13911 childToDelete.stateNode = instance;
13912 childToDelete.return = returnFiber;
13913 childToDelete.effectTag = Deletion;
13914
13915 // This might seem like it belongs on progressedFirstDeletion. However,
13916 // these children are not part of the reconciliation list of children.
13917 // Even if we abort and rereconcile the children, that will try to hydrate
13918 // again and the nodes are still in the host tree so these will be
13919 // recreated.
13920 if (returnFiber.lastEffect !== null) {
13921 returnFiber.lastEffect.nextEffect = childToDelete;
13922 returnFiber.lastEffect = childToDelete;
13923 } else {
13924 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13925 }
13926}
13927
13928function insertNonHydratedInstance(returnFiber, fiber) {
13929 fiber.effectTag |= Placement;
13930 {
13931 switch (returnFiber.tag) {
13932 case HostRoot:
13933 {
13934 var parentContainer = returnFiber.stateNode.containerInfo;
13935 switch (fiber.tag) {
13936 case HostComponent:
13937 var type = fiber.type;
13938 var props = fiber.pendingProps;
13939 didNotFindHydratableContainerInstance(parentContainer, type, props);
13940 break;
13941 case HostText:
13942 var text = fiber.pendingProps;
13943 didNotFindHydratableContainerTextInstance(parentContainer, text);
13944 break;
13945 case SuspenseComponent:
13946
13947 break;
13948 }
13949 break;
13950 }
13951 case HostComponent:
13952 {
13953 var parentType = returnFiber.type;
13954 var parentProps = returnFiber.memoizedProps;
13955 var parentInstance = returnFiber.stateNode;
13956 switch (fiber.tag) {
13957 case HostComponent:
13958 var _type = fiber.type;
13959 var _props = fiber.pendingProps;
13960 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
13961 break;
13962 case HostText:
13963 var _text = fiber.pendingProps;
13964 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
13965 break;
13966 case SuspenseComponent:
13967 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
13968 break;
13969 }
13970 break;
13971 }
13972 default:
13973 return;
13974 }
13975 }
13976}
13977
13978function tryHydrate(fiber, nextInstance) {
13979 switch (fiber.tag) {
13980 case HostComponent:
13981 {
13982 var type = fiber.type;
13983 var props = fiber.pendingProps;
13984 var instance = canHydrateInstance(nextInstance, type, props);
13985 if (instance !== null) {
13986 fiber.stateNode = instance;
13987 return true;
13988 }
13989 return false;
13990 }
13991 case HostText:
13992 {
13993 var text = fiber.pendingProps;
13994 var textInstance = canHydrateTextInstance(nextInstance, text);
13995 if (textInstance !== null) {
13996 fiber.stateNode = textInstance;
13997 return true;
13998 }
13999 return false;
14000 }
14001 case SuspenseComponent:
14002 {
14003 if (enableSuspenseServerRenderer) {
14004 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
14005 if (suspenseInstance !== null) {
14006 // Downgrade the tag to a dehydrated component until we've hydrated it.
14007 fiber.tag = DehydratedSuspenseComponent;
14008 fiber.stateNode = suspenseInstance;
14009 return true;
14010 }
14011 }
14012 return false;
14013 }
14014 default:
14015 return false;
14016 }
14017}
14018
14019function tryToClaimNextHydratableInstance(fiber) {
14020 if (!isHydrating) {
14021 return;
14022 }
14023 var nextInstance = nextHydratableInstance;
14024 if (!nextInstance) {
14025 // Nothing to hydrate. Make it an insertion.
14026 insertNonHydratedInstance(hydrationParentFiber, fiber);
14027 isHydrating = false;
14028 hydrationParentFiber = fiber;
14029 return;
14030 }
14031 var firstAttemptedInstance = nextInstance;
14032 if (!tryHydrate(fiber, nextInstance)) {
14033 // If we can't hydrate this instance let's try the next one.
14034 // We use this as a heuristic. It's based on intuition and not data so it
14035 // might be flawed or unnecessary.
14036 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14037 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14038 // Nothing to hydrate. Make it an insertion.
14039 insertNonHydratedInstance(hydrationParentFiber, fiber);
14040 isHydrating = false;
14041 hydrationParentFiber = fiber;
14042 return;
14043 }
14044 // We matched the next one, we'll now assume that the first one was
14045 // superfluous and we'll delete it. Since we can't eagerly delete it
14046 // we'll have to schedule a deletion. To do that, this node needs a dummy
14047 // fiber associated with it.
14048 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14049 }
14050 hydrationParentFiber = fiber;
14051 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14052}
14053
14054function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14055 if (!supportsHydration) {
14056 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14057 }
14058
14059 var instance = fiber.stateNode;
14060 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
14061 // TODO: Type this specific to this type of component.
14062 fiber.updateQueue = updatePayload;
14063 // If the update payload indicates that there is a change or if there
14064 // is a new ref we mark this as an update.
14065 if (updatePayload !== null) {
14066 return true;
14067 }
14068 return false;
14069}
14070
14071function prepareToHydrateHostTextInstance(fiber) {
14072 if (!supportsHydration) {
14073 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14074 }
14075
14076 var textInstance = fiber.stateNode;
14077 var textContent = fiber.memoizedProps;
14078 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14079 {
14080 if (shouldUpdate) {
14081 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14082 // hydration parent is the parent host component of this host text.
14083 var returnFiber = hydrationParentFiber;
14084 if (returnFiber !== null) {
14085 switch (returnFiber.tag) {
14086 case HostRoot:
14087 {
14088 var parentContainer = returnFiber.stateNode.containerInfo;
14089 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14090 break;
14091 }
14092 case HostComponent:
14093 {
14094 var parentType = returnFiber.type;
14095 var parentProps = returnFiber.memoizedProps;
14096 var parentInstance = returnFiber.stateNode;
14097 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14098 break;
14099 }
14100 }
14101 }
14102 }
14103 }
14104 return shouldUpdate;
14105}
14106
14107function skipPastDehydratedSuspenseInstance(fiber) {
14108 if (!supportsHydration) {
14109 invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14110 }
14111 var suspenseInstance = fiber.stateNode;
14112 !suspenseInstance ? invariant(false, 'Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.') : void 0;
14113 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14114}
14115
14116function popToNextHostParent(fiber) {
14117 var parent = fiber.return;
14118 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
14119 parent = parent.return;
14120 }
14121 hydrationParentFiber = parent;
14122}
14123
14124function popHydrationState(fiber) {
14125 if (!supportsHydration) {
14126 return false;
14127 }
14128 if (fiber !== hydrationParentFiber) {
14129 // We're deeper than the current hydration context, inside an inserted
14130 // tree.
14131 return false;
14132 }
14133 if (!isHydrating) {
14134 // If we're not currently hydrating but we're in a hydration context, then
14135 // we were an insertion and now need to pop up reenter hydration of our
14136 // siblings.
14137 popToNextHostParent(fiber);
14138 isHydrating = true;
14139 return false;
14140 }
14141
14142 var type = fiber.type;
14143
14144 // If we have any remaining hydratable nodes, we need to delete them now.
14145 // We only do this deeper than head and body since they tend to have random
14146 // other nodes in them. We also ignore components with pure text content in
14147 // side of them.
14148 // TODO: Better heuristic.
14149 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14150 var nextInstance = nextHydratableInstance;
14151 while (nextInstance) {
14152 deleteHydratableInstance(fiber, nextInstance);
14153 nextInstance = getNextHydratableSibling(nextInstance);
14154 }
14155 }
14156
14157 popToNextHostParent(fiber);
14158 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14159 return true;
14160}
14161
14162function resetHydrationState() {
14163 if (!supportsHydration) {
14164 return;
14165 }
14166
14167 hydrationParentFiber = null;
14168 nextHydratableInstance = null;
14169 isHydrating = false;
14170}
14171
14172var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
14173
14174var didReceiveUpdate = false;
14175
14176var didWarnAboutBadClass = void 0;
14177var didWarnAboutContextTypeOnFunctionComponent = void 0;
14178var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
14179var didWarnAboutFunctionRefs = void 0;
14180var didWarnAboutReassigningProps = void 0;
14181
14182{
14183 didWarnAboutBadClass = {};
14184 didWarnAboutContextTypeOnFunctionComponent = {};
14185 didWarnAboutGetDerivedStateOnFunctionComponent = {};
14186 didWarnAboutFunctionRefs = {};
14187 didWarnAboutReassigningProps = false;
14188}
14189
14190function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14191 if (current$$1 === null) {
14192 // If this is a fresh new component that hasn't been rendered yet, we
14193 // won't update its child set by applying minimal side-effects. Instead,
14194 // we will add them all to the child before it gets rendered. That means
14195 // we can optimize this reconciliation pass by not tracking side-effects.
14196 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14197 } else {
14198 // If the current child is the same as the work in progress, it means that
14199 // we haven't yet started any work on these children. Therefore, we use
14200 // the clone algorithm to create a copy of all the current children.
14201
14202 // If we had any progressed work already, that is invalid at this point so
14203 // let's throw it out.
14204 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
14205 }
14206}
14207
14208function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14209 // This function is fork of reconcileChildren. It's used in cases where we
14210 // want to reconcile without matching against the existing set. This has the
14211 // effect of all current children being unmounted; even if the type and key
14212 // are the same, the old child is unmounted and a new child is created.
14213 //
14214 // To do this, we're going to go through the reconcile algorithm twice. In
14215 // the first pass, we schedule a deletion for all the current children by
14216 // passing null.
14217 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
14218 // In the second pass, we mount the new children. The trick here is that we
14219 // pass null in place of where we usually pass the current child set. This has
14220 // the effect of remounting all children regardless of whether their their
14221 // identity matches.
14222 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14223}
14224
14225function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14226 // TODO: current can be non-null here even if the component
14227 // hasn't yet mounted. This happens after the first render suspends.
14228 // We'll need to figure out if this is fine or can cause issues.
14229
14230 {
14231 if (workInProgress.type !== workInProgress.elementType) {
14232 // Lazy component props can't be validated in createElement
14233 // because they're only guaranteed to be resolved here.
14234 var innerPropTypes = Component.propTypes;
14235 if (innerPropTypes) {
14236 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14237 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14238 }
14239 }
14240 }
14241
14242 var render = Component.render;
14243 var ref = workInProgress.ref;
14244
14245 // The rest is a fork of updateFunctionComponent
14246 var nextChildren = void 0;
14247 prepareToReadContext(workInProgress, renderExpirationTime);
14248 {
14249 ReactCurrentOwner$3.current = workInProgress;
14250 setCurrentPhase('render');
14251 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14252 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14253 // Only double-render components with Hooks
14254 if (workInProgress.memoizedState !== null) {
14255 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14256 }
14257 }
14258 setCurrentPhase(null);
14259 }
14260
14261 if (current$$1 !== null && !didReceiveUpdate) {
14262 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14263 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14264 }
14265
14266 // React DevTools reads this flag.
14267 workInProgress.effectTag |= PerformedWork;
14268 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14269 return workInProgress.child;
14270}
14271
14272function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14273 if (current$$1 === null) {
14274 var type = Component.type;
14275 if (isSimpleFunctionComponent(type) && Component.compare === null &&
14276 // SimpleMemoComponent codepath doesn't resolve outer props either.
14277 Component.defaultProps === undefined) {
14278 // If this is a plain function component without default props,
14279 // and with only the default shallow comparison, we upgrade it
14280 // to a SimpleMemoComponent to allow fast path updates.
14281 workInProgress.tag = SimpleMemoComponent;
14282 workInProgress.type = type;
14283 {
14284 validateFunctionComponentInDev(workInProgress, type);
14285 }
14286 return updateSimpleMemoComponent(current$$1, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
14287 }
14288 {
14289 var innerPropTypes = type.propTypes;
14290 if (innerPropTypes) {
14291 // Inner memo component props aren't currently validated in createElement.
14292 // We could move it there, but we'd still need this for lazy code path.
14293 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14294 'prop', getComponentName(type), getCurrentFiberStackInDev);
14295 }
14296 }
14297 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
14298 child.ref = workInProgress.ref;
14299 child.return = workInProgress;
14300 workInProgress.child = child;
14301 return child;
14302 }
14303 {
14304 var _type = Component.type;
14305 var _innerPropTypes = _type.propTypes;
14306 if (_innerPropTypes) {
14307 // Inner memo component props aren't currently validated in createElement.
14308 // We could move it there, but we'd still need this for lazy code path.
14309 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
14310 'prop', getComponentName(_type), getCurrentFiberStackInDev);
14311 }
14312 }
14313 var currentChild = current$$1.child; // This is always exactly one child
14314 if (updateExpirationTime < renderExpirationTime) {
14315 // This will be the props with resolved defaultProps,
14316 // unlike current.memoizedProps which will be the unresolved ones.
14317 var prevProps = currentChild.memoizedProps;
14318 // Default to shallow comparison
14319 var compare = Component.compare;
14320 compare = compare !== null ? compare : shallowEqual;
14321 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14322 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14323 }
14324 }
14325 // React DevTools reads this flag.
14326 workInProgress.effectTag |= PerformedWork;
14327 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
14328 newChild.ref = workInProgress.ref;
14329 newChild.return = workInProgress;
14330 workInProgress.child = newChild;
14331 return newChild;
14332}
14333
14334function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14335 // TODO: current can be non-null here even if the component
14336 // hasn't yet mounted. This happens when the inner render suspends.
14337 // We'll need to figure out if this is fine or can cause issues.
14338
14339 {
14340 if (workInProgress.type !== workInProgress.elementType) {
14341 // Lazy component props can't be validated in createElement
14342 // because they're only guaranteed to be resolved here.
14343 var outerMemoType = workInProgress.elementType;
14344 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
14345 // We warn when you define propTypes on lazy()
14346 // so let's just skip over it to find memo() outer wrapper.
14347 // Inner props for memo are validated later.
14348 outerMemoType = refineResolvedLazyComponent(outerMemoType);
14349 }
14350 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
14351 if (outerPropTypes) {
14352 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
14353 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
14354 }
14355 // Inner propTypes will be validated in the function component path.
14356 }
14357 }
14358 if (current$$1 !== null) {
14359 var prevProps = current$$1.memoizedProps;
14360 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14361 didReceiveUpdate = false;
14362 if (updateExpirationTime < renderExpirationTime) {
14363 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14364 }
14365 }
14366 }
14367 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14368}
14369
14370function updateFragment(current$$1, workInProgress, renderExpirationTime) {
14371 var nextChildren = workInProgress.pendingProps;
14372 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14373 return workInProgress.child;
14374}
14375
14376function updateMode(current$$1, workInProgress, renderExpirationTime) {
14377 var nextChildren = workInProgress.pendingProps.children;
14378 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14379 return workInProgress.child;
14380}
14381
14382function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
14383 if (enableProfilerTimer) {
14384 workInProgress.effectTag |= Update;
14385 }
14386 var nextProps = workInProgress.pendingProps;
14387 var nextChildren = nextProps.children;
14388 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14389 return workInProgress.child;
14390}
14391
14392function markRef(current$$1, workInProgress) {
14393 var ref = workInProgress.ref;
14394 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
14395 // Schedule a Ref effect
14396 workInProgress.effectTag |= Ref;
14397 }
14398}
14399
14400function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14401 {
14402 if (workInProgress.type !== workInProgress.elementType) {
14403 // Lazy component props can't be validated in createElement
14404 // because they're only guaranteed to be resolved here.
14405 var innerPropTypes = Component.propTypes;
14406 if (innerPropTypes) {
14407 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14408 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14409 }
14410 }
14411 }
14412
14413 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
14414 var context = getMaskedContext(workInProgress, unmaskedContext);
14415
14416 var nextChildren = void 0;
14417 prepareToReadContext(workInProgress, renderExpirationTime);
14418 {
14419 ReactCurrentOwner$3.current = workInProgress;
14420 setCurrentPhase('render');
14421 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14422 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14423 // Only double-render components with Hooks
14424 if (workInProgress.memoizedState !== null) {
14425 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14426 }
14427 }
14428 setCurrentPhase(null);
14429 }
14430
14431 if (current$$1 !== null && !didReceiveUpdate) {
14432 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14433 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14434 }
14435
14436 // React DevTools reads this flag.
14437 workInProgress.effectTag |= PerformedWork;
14438 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14439 return workInProgress.child;
14440}
14441
14442function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14443 {
14444 if (workInProgress.type !== workInProgress.elementType) {
14445 // Lazy component props can't be validated in createElement
14446 // because they're only guaranteed to be resolved here.
14447 var innerPropTypes = Component.propTypes;
14448 if (innerPropTypes) {
14449 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14450 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14451 }
14452 }
14453 }
14454
14455 // Push context providers early to prevent context stack mismatches.
14456 // During mounting we don't know the child context yet as the instance doesn't exist.
14457 // We will invalidate the child context in finishClassComponent() right after rendering.
14458 var hasContext = void 0;
14459 if (isContextProvider(Component)) {
14460 hasContext = true;
14461 pushContextProvider(workInProgress);
14462 } else {
14463 hasContext = false;
14464 }
14465 prepareToReadContext(workInProgress, renderExpirationTime);
14466
14467 var instance = workInProgress.stateNode;
14468 var shouldUpdate = void 0;
14469 if (instance === null) {
14470 if (current$$1 !== null) {
14471 // An class component without an instance only mounts if it suspended
14472 // inside a non- concurrent tree, in an inconsistent state. We want to
14473 // tree it like a new mount, even though an empty version of it already
14474 // committed. Disconnect the alternate pointers.
14475 current$$1.alternate = null;
14476 workInProgress.alternate = null;
14477 // Since this is conceptually a new fiber, schedule a Placement effect
14478 workInProgress.effectTag |= Placement;
14479 }
14480 // In the initial pass we might need to construct the instance.
14481 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14482 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14483 shouldUpdate = true;
14484 } else if (current$$1 === null) {
14485 // In a resume, we'll already have an instance we can reuse.
14486 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14487 } else {
14488 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14489 }
14490 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
14491 {
14492 var inst = workInProgress.stateNode;
14493 if (inst.props !== nextProps) {
14494 !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;
14495 didWarnAboutReassigningProps = true;
14496 }
14497 }
14498 return nextUnitOfWork;
14499}
14500
14501function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
14502 // Refs should update even if shouldComponentUpdate returns false
14503 markRef(current$$1, workInProgress);
14504
14505 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
14506
14507 if (!shouldUpdate && !didCaptureError) {
14508 // Context providers should defer to sCU for rendering
14509 if (hasContext) {
14510 invalidateContextProvider(workInProgress, Component, false);
14511 }
14512
14513 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14514 }
14515
14516 var instance = workInProgress.stateNode;
14517
14518 // Rerender
14519 ReactCurrentOwner$3.current = workInProgress;
14520 var nextChildren = void 0;
14521 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
14522 // If we captured an error, but getDerivedStateFrom catch is not defined,
14523 // unmount all the children. componentDidCatch will schedule an update to
14524 // re-render a fallback. This is temporary until we migrate everyone to
14525 // the new API.
14526 // TODO: Warn in a future release.
14527 nextChildren = null;
14528
14529 if (enableProfilerTimer) {
14530 stopProfilerTimerIfRunning(workInProgress);
14531 }
14532 } else {
14533 {
14534 setCurrentPhase('render');
14535 nextChildren = instance.render();
14536 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14537 instance.render();
14538 }
14539 setCurrentPhase(null);
14540 }
14541 }
14542
14543 // React DevTools reads this flag.
14544 workInProgress.effectTag |= PerformedWork;
14545 if (current$$1 !== null && didCaptureError) {
14546 // If we're recovering from an error, reconcile without reusing any of
14547 // the existing children. Conceptually, the normal children and the children
14548 // that are shown on error are two different sets, so we shouldn't reuse
14549 // normal children even if their identities match.
14550 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
14551 } else {
14552 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14553 }
14554
14555 // Memoize state using the values we just used to render.
14556 // TODO: Restructure so we never read values from the instance.
14557 workInProgress.memoizedState = instance.state;
14558
14559 // The context might have changed so we need to recalculate it.
14560 if (hasContext) {
14561 invalidateContextProvider(workInProgress, Component, true);
14562 }
14563
14564 return workInProgress.child;
14565}
14566
14567function pushHostRootContext(workInProgress) {
14568 var root = workInProgress.stateNode;
14569 if (root.pendingContext) {
14570 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
14571 } else if (root.context) {
14572 // Should always be set
14573 pushTopLevelContextObject(workInProgress, root.context, false);
14574 }
14575 pushHostContainer(workInProgress, root.containerInfo);
14576}
14577
14578function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
14579 pushHostRootContext(workInProgress);
14580 var updateQueue = workInProgress.updateQueue;
14581 !(updateQueue !== null) ? invariant(false, '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.') : void 0;
14582 var nextProps = workInProgress.pendingProps;
14583 var prevState = workInProgress.memoizedState;
14584 var prevChildren = prevState !== null ? prevState.element : null;
14585 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
14586 var nextState = workInProgress.memoizedState;
14587 // Caution: React DevTools currently depends on this property
14588 // being called "element".
14589 var nextChildren = nextState.element;
14590 if (nextChildren === prevChildren) {
14591 // If the state is the same as before, that's a bailout because we had
14592 // no work that expires at this time.
14593 resetHydrationState();
14594 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14595 }
14596 var root = workInProgress.stateNode;
14597 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
14598 // If we don't have any current children this might be the first pass.
14599 // We always try to hydrate. If this isn't a hydration pass there won't
14600 // be any children to hydrate which is effectively the same thing as
14601 // not hydrating.
14602
14603 // This is a bit of a hack. We track the host root as a placement to
14604 // know that we're currently in a mounting state. That way isMounted
14605 // works as expected. We must reset this before committing.
14606 // TODO: Delete this when we delete isMounted and findDOMNode.
14607 workInProgress.effectTag |= Placement;
14608
14609 // Ensure that children mount into this root without tracking
14610 // side-effects. This ensures that we don't store Placement effects on
14611 // nodes that will be hydrated.
14612 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14613 } else {
14614 // Otherwise reset hydration state in case we aborted and resumed another
14615 // root.
14616 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14617 resetHydrationState();
14618 }
14619 return workInProgress.child;
14620}
14621
14622function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
14623 pushHostContext(workInProgress);
14624
14625 if (current$$1 === null) {
14626 tryToClaimNextHydratableInstance(workInProgress);
14627 }
14628
14629 var type = workInProgress.type;
14630 var nextProps = workInProgress.pendingProps;
14631 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
14632
14633 var nextChildren = nextProps.children;
14634 var isDirectTextChild = shouldSetTextContent(type, nextProps);
14635
14636 if (isDirectTextChild) {
14637 // We special case a direct text child of a host node. This is a common
14638 // case. We won't handle it as a reified child. We will instead handle
14639 // this in the host environment that also have access to this prop. That
14640 // avoids allocating another HostText fiber and traversing it.
14641 nextChildren = null;
14642 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
14643 // If we're switching from a direct text child to a normal child, or to
14644 // empty, we need to schedule the text content to be reset.
14645 workInProgress.effectTag |= ContentReset;
14646 }
14647
14648 markRef(current$$1, workInProgress);
14649
14650 // Check the host config to see if the children are offscreen/hidden.
14651 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
14652 // Schedule this fiber to re-render at offscreen priority. Then bailout.
14653 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
14654 return null;
14655 }
14656
14657 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14658 return workInProgress.child;
14659}
14660
14661function updateHostText(current$$1, workInProgress) {
14662 if (current$$1 === null) {
14663 tryToClaimNextHydratableInstance(workInProgress);
14664 }
14665 // Nothing to do here. This is terminal. We'll do the completion step
14666 // immediately after.
14667 return null;
14668}
14669
14670function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
14671 if (_current !== null) {
14672 // An lazy component only mounts if it suspended inside a non-
14673 // concurrent tree, in an inconsistent state. We want to treat it like
14674 // a new mount, even though an empty version of it already committed.
14675 // Disconnect the alternate pointers.
14676 _current.alternate = null;
14677 workInProgress.alternate = null;
14678 // Since this is conceptually a new fiber, schedule a Placement effect
14679 workInProgress.effectTag |= Placement;
14680 }
14681
14682 var props = workInProgress.pendingProps;
14683 // We can't start a User Timing measurement with correct label yet.
14684 // Cancel and resume right after we know the tag.
14685 cancelWorkTimer(workInProgress);
14686 var Component = readLazyComponentType(elementType);
14687 // Store the unwrapped component in the type.
14688 workInProgress.type = Component;
14689 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
14690 startWorkTimer(workInProgress);
14691 var resolvedProps = resolveDefaultProps(Component, props);
14692 var child = void 0;
14693 switch (resolvedTag) {
14694 case FunctionComponent:
14695 {
14696 {
14697 validateFunctionComponentInDev(workInProgress, Component);
14698 }
14699 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14700 break;
14701 }
14702 case ClassComponent:
14703 {
14704 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14705 break;
14706 }
14707 case ForwardRef:
14708 {
14709 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14710 break;
14711 }
14712 case MemoComponent:
14713 {
14714 {
14715 if (workInProgress.type !== workInProgress.elementType) {
14716 var outerPropTypes = Component.propTypes;
14717 if (outerPropTypes) {
14718 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
14719 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14720 }
14721 }
14722 }
14723 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
14724 updateExpirationTime, renderExpirationTime);
14725 break;
14726 }
14727 default:
14728 {
14729 var hint = '';
14730 {
14731 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
14732 hint = ' Did you wrap a component in React.lazy() more than once?';
14733 }
14734 }
14735 // This message intentionally doesn't mention ForwardRef or MemoComponent
14736 // because the fact that it's a separate type of work is an
14737 // implementation detail.
14738 invariant(false, 'Element type is invalid. Received a promise that resolves to: %s. Lazy element type must resolve to a class or function.%s', Component, hint);
14739 }
14740 }
14741 return child;
14742}
14743
14744function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
14745 if (_current !== null) {
14746 // An incomplete component only mounts if it suspended inside a non-
14747 // concurrent tree, in an inconsistent state. We want to treat it like
14748 // a new mount, even though an empty version of it already committed.
14749 // Disconnect the alternate pointers.
14750 _current.alternate = null;
14751 workInProgress.alternate = null;
14752 // Since this is conceptually a new fiber, schedule a Placement effect
14753 workInProgress.effectTag |= Placement;
14754 }
14755
14756 // Promote the fiber to a class and try rendering again.
14757 workInProgress.tag = ClassComponent;
14758
14759 // The rest of this function is a fork of `updateClassComponent`
14760
14761 // Push context providers early to prevent context stack mismatches.
14762 // During mounting we don't know the child context yet as the instance doesn't exist.
14763 // We will invalidate the child context in finishClassComponent() right after rendering.
14764 var hasContext = void 0;
14765 if (isContextProvider(Component)) {
14766 hasContext = true;
14767 pushContextProvider(workInProgress);
14768 } else {
14769 hasContext = false;
14770 }
14771 prepareToReadContext(workInProgress, renderExpirationTime);
14772
14773 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14774 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14775
14776 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14777}
14778
14779function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
14780 if (_current !== null) {
14781 // An indeterminate component only mounts if it suspended inside a non-
14782 // concurrent tree, in an inconsistent state. We want to treat it like
14783 // a new mount, even though an empty version of it already committed.
14784 // Disconnect the alternate pointers.
14785 _current.alternate = null;
14786 workInProgress.alternate = null;
14787 // Since this is conceptually a new fiber, schedule a Placement effect
14788 workInProgress.effectTag |= Placement;
14789 }
14790
14791 var props = workInProgress.pendingProps;
14792 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
14793 var context = getMaskedContext(workInProgress, unmaskedContext);
14794
14795 prepareToReadContext(workInProgress, renderExpirationTime);
14796
14797 var value = void 0;
14798
14799 {
14800 if (Component.prototype && typeof Component.prototype.render === 'function') {
14801 var componentName = getComponentName(Component) || 'Unknown';
14802
14803 if (!didWarnAboutBadClass[componentName]) {
14804 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);
14805 didWarnAboutBadClass[componentName] = true;
14806 }
14807 }
14808
14809 if (workInProgress.mode & StrictMode) {
14810 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
14811 }
14812
14813 ReactCurrentOwner$3.current = workInProgress;
14814 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
14815 }
14816 // React DevTools reads this flag.
14817 workInProgress.effectTag |= PerformedWork;
14818
14819 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
14820 // Proceed under the assumption that this is a class instance
14821 workInProgress.tag = ClassComponent;
14822
14823 // Throw out any hooks that were used.
14824 resetHooks();
14825
14826 // Push context providers early to prevent context stack mismatches.
14827 // During mounting we don't know the child context yet as the instance doesn't exist.
14828 // We will invalidate the child context in finishClassComponent() right after rendering.
14829 var hasContext = false;
14830 if (isContextProvider(Component)) {
14831 hasContext = true;
14832 pushContextProvider(workInProgress);
14833 } else {
14834 hasContext = false;
14835 }
14836
14837 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
14838
14839 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
14840 if (typeof getDerivedStateFromProps === 'function') {
14841 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
14842 }
14843
14844 adoptClassInstance(workInProgress, value);
14845 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
14846 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14847 } else {
14848 // Proceed under the assumption that this is a function component
14849 workInProgress.tag = FunctionComponent;
14850 {
14851 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14852 // Only double-render components with Hooks
14853 if (workInProgress.memoizedState !== null) {
14854 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
14855 }
14856 }
14857 }
14858 reconcileChildren(null, workInProgress, value, renderExpirationTime);
14859 {
14860 validateFunctionComponentInDev(workInProgress, Component);
14861 }
14862 return workInProgress.child;
14863 }
14864}
14865
14866function validateFunctionComponentInDev(workInProgress, Component) {
14867 if (Component) {
14868 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
14869 }
14870 if (workInProgress.ref !== null) {
14871 var info = '';
14872 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
14873 if (ownerName) {
14874 info += '\n\nCheck the render method of `' + ownerName + '`.';
14875 }
14876
14877 var warningKey = ownerName || workInProgress._debugID || '';
14878 var debugSource = workInProgress._debugSource;
14879 if (debugSource) {
14880 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
14881 }
14882 if (!didWarnAboutFunctionRefs[warningKey]) {
14883 didWarnAboutFunctionRefs[warningKey] = true;
14884 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);
14885 }
14886 }
14887
14888 if (typeof Component.getDerivedStateFromProps === 'function') {
14889 var componentName = getComponentName(Component) || 'Unknown';
14890
14891 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
14892 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
14893 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
14894 }
14895 }
14896
14897 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
14898 var _componentName = getComponentName(Component) || 'Unknown';
14899
14900 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
14901 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
14902 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
14903 }
14904 }
14905}
14906
14907function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
14908 var mode = workInProgress.mode;
14909 var nextProps = workInProgress.pendingProps;
14910
14911 // We should attempt to render the primary children unless this boundary
14912 // already suspended during this render (`alreadyCaptured` is true).
14913 var nextState = workInProgress.memoizedState;
14914
14915 var nextDidTimeout = void 0;
14916 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
14917 // This is the first attempt.
14918 nextState = null;
14919 nextDidTimeout = false;
14920 } else {
14921 // Something in this boundary's subtree already suspended. Switch to
14922 // rendering the fallback children.
14923 nextState = {
14924 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
14925 };
14926 nextDidTimeout = true;
14927 workInProgress.effectTag &= ~DidCapture;
14928 }
14929
14930 // This next part is a bit confusing. If the children timeout, we switch to
14931 // showing the fallback children in place of the "primary" children.
14932 // However, we don't want to delete the primary children because then their
14933 // state will be lost (both the React state and the host state, e.g.
14934 // uncontrolled form inputs). Instead we keep them mounted and hide them.
14935 // Both the fallback children AND the primary children are rendered at the
14936 // same time. Once the primary children are un-suspended, we can delete
14937 // the fallback children — don't need to preserve their state.
14938 //
14939 // The two sets of children are siblings in the host environment, but
14940 // semantically, for purposes of reconciliation, they are two separate sets.
14941 // So we store them using two fragment fibers.
14942 //
14943 // However, we want to avoid allocating extra fibers for every placeholder.
14944 // They're only necessary when the children time out, because that's the
14945 // only time when both sets are mounted.
14946 //
14947 // So, the extra fragment fibers are only used if the children time out.
14948 // Otherwise, we render the primary children directly. This requires some
14949 // custom reconciliation logic to preserve the state of the primary
14950 // children. It's essentially a very basic form of re-parenting.
14951
14952 // `child` points to the child fiber. In the normal case, this is the first
14953 // fiber of the primary children set. In the timed-out case, it's a
14954 // a fragment fiber containing the primary children.
14955 var child = void 0;
14956 // `next` points to the next fiber React should render. In the normal case,
14957 // it's the same as `child`: the first fiber of the primary children set.
14958 // In the timed-out case, it's a fragment fiber containing the *fallback*
14959 // children -- we skip over the primary children entirely.
14960 var next = void 0;
14961 if (current$$1 === null) {
14962 if (enableSuspenseServerRenderer) {
14963 // If we're currently hydrating, try to hydrate this boundary.
14964 // But only if this has a fallback.
14965 if (nextProps.fallback !== undefined) {
14966 tryToClaimNextHydratableInstance(workInProgress);
14967 // This could've changed the tag if this was a dehydrated suspense component.
14968 if (workInProgress.tag === DehydratedSuspenseComponent) {
14969 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
14970 }
14971 }
14972 }
14973
14974 // This is the initial mount. This branch is pretty simple because there's
14975 // no previous state that needs to be preserved.
14976 if (nextDidTimeout) {
14977 // Mount separate fragments for primary and fallback children.
14978 var nextFallbackChildren = nextProps.fallback;
14979 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
14980
14981 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
14982 // Outside of concurrent mode, we commit the effects from the
14983 var progressedState = workInProgress.memoizedState;
14984 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
14985 primaryChildFragment.child = progressedPrimaryChild;
14986 }
14987
14988 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
14989 primaryChildFragment.sibling = fallbackChildFragment;
14990 child = primaryChildFragment;
14991 // Skip the primary children, and continue working on the
14992 // fallback children.
14993 next = fallbackChildFragment;
14994 child.return = next.return = workInProgress;
14995 } else {
14996 // Mount the primary children without an intermediate fragment fiber.
14997 var nextPrimaryChildren = nextProps.children;
14998 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
14999 }
15000 } else {
15001 // This is an update. This branch is more complicated because we need to
15002 // ensure the state of the primary children is preserved.
15003 var prevState = current$$1.memoizedState;
15004 var prevDidTimeout = prevState !== null;
15005 if (prevDidTimeout) {
15006 // The current tree already timed out. That means each child set is
15007 var currentPrimaryChildFragment = current$$1.child;
15008 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
15009 if (nextDidTimeout) {
15010 // Still timed out. Reuse the current primary children by cloning
15011 // its fragment. We're going to skip over these entirely.
15012 var _nextFallbackChildren = nextProps.fallback;
15013 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
15014
15015 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15016 // Outside of concurrent mode, we commit the effects from the
15017 var _progressedState = workInProgress.memoizedState;
15018 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
15019 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
15020 _primaryChildFragment.child = _progressedPrimaryChild;
15021 }
15022 }
15023
15024 // Because primaryChildFragment is a new fiber that we're inserting as the
15025 // parent of a new tree, we need to set its treeBaseDuration.
15026 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15027 // treeBaseDuration is the sum of all the child tree base durations.
15028 var treeBaseDuration = 0;
15029 var hiddenChild = _primaryChildFragment.child;
15030 while (hiddenChild !== null) {
15031 treeBaseDuration += hiddenChild.treeBaseDuration;
15032 hiddenChild = hiddenChild.sibling;
15033 }
15034 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
15035 }
15036
15037 // Clone the fallback child fragment, too. These we'll continue
15038 // working on.
15039 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
15040 child = _primaryChildFragment;
15041 _primaryChildFragment.childExpirationTime = NoWork;
15042 // Skip the primary children, and continue working on the
15043 // fallback children.
15044 next = _fallbackChildFragment;
15045 child.return = next.return = workInProgress;
15046 } else {
15047 // No longer suspended. Switch back to showing the primary children,
15048 // and remove the intermediate fragment fiber.
15049 var _nextPrimaryChildren = nextProps.children;
15050 var currentPrimaryChild = currentPrimaryChildFragment.child;
15051 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
15052
15053 // If this render doesn't suspend, we need to delete the fallback
15054 // children. Wait until the complete phase, after we've confirmed the
15055 // fallback is no longer needed.
15056 // TODO: Would it be better to store the fallback fragment on
15057 // the stateNode?
15058
15059 // Continue rendering the children, like we normally do.
15060 child = next = primaryChild;
15061 }
15062 } else {
15063 // The current tree has not already timed out. That means the primary
15064 // children are not wrapped in a fragment fiber.
15065 var _currentPrimaryChild = current$$1.child;
15066 if (nextDidTimeout) {
15067 // Timed out. Wrap the children in a fragment fiber to keep them
15068 // separate from the fallback children.
15069 var _nextFallbackChildren2 = nextProps.fallback;
15070 var _primaryChildFragment2 = createFiberFromFragment(
15071 // It shouldn't matter what the pending props are because we aren't
15072 // going to render this fragment.
15073 null, mode, NoWork, null);
15074 _primaryChildFragment2.child = _currentPrimaryChild;
15075
15076 // Even though we're creating a new fiber, there are no new children,
15077 // because we're reusing an already mounted tree. So we don't need to
15078 // schedule a placement.
15079 // primaryChildFragment.effectTag |= Placement;
15080
15081 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15082 // Outside of concurrent mode, we commit the effects from the
15083 var _progressedState2 = workInProgress.memoizedState;
15084 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
15085 _primaryChildFragment2.child = _progressedPrimaryChild2;
15086 }
15087
15088 // Because primaryChildFragment is a new fiber that we're inserting as the
15089 // parent of a new tree, we need to set its treeBaseDuration.
15090 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15091 // treeBaseDuration is the sum of all the child tree base durations.
15092 var _treeBaseDuration = 0;
15093 var _hiddenChild = _primaryChildFragment2.child;
15094 while (_hiddenChild !== null) {
15095 _treeBaseDuration += _hiddenChild.treeBaseDuration;
15096 _hiddenChild = _hiddenChild.sibling;
15097 }
15098 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
15099 }
15100
15101 // Create a fragment from the fallback children, too.
15102 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
15103 _fallbackChildFragment2.effectTag |= Placement;
15104 child = _primaryChildFragment2;
15105 _primaryChildFragment2.childExpirationTime = NoWork;
15106 // Skip the primary children, and continue working on the
15107 // fallback children.
15108 next = _fallbackChildFragment2;
15109 child.return = next.return = workInProgress;
15110 } else {
15111 // Still haven't timed out. Continue rendering the children, like we
15112 // normally do.
15113 var _nextPrimaryChildren2 = nextProps.children;
15114 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
15115 }
15116 }
15117 workInProgress.stateNode = current$$1.stateNode;
15118 }
15119
15120 workInProgress.memoizedState = nextState;
15121 workInProgress.child = child;
15122 return next;
15123}
15124
15125function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15126 if (current$$1 === null) {
15127 // During the first pass, we'll bail out and not drill into the children.
15128 // Instead, we'll leave the content in place and try to hydrate it later.
15129 workInProgress.expirationTime = Never;
15130 return null;
15131 }
15132 // We use childExpirationTime to indicate that a child might depend on context, so if
15133 // any context has changed, we need to treat is as if the input might have changed.
15134 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
15135 if (didReceiveUpdate || hasContextChanged$$1) {
15136 // This boundary has changed since the first render. This means that we are now unable to
15137 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
15138 // during this render we can't. Instead, we're going to delete the whole subtree and
15139 // instead inject a new real Suspense boundary to take its place, which may render content
15140 // or fallback. The real Suspense boundary will suspend for a while so we have some time
15141 // to ensure it can produce real content, but all state and pending events will be lost.
15142
15143 // Detach from the current dehydrated boundary.
15144 current$$1.alternate = null;
15145 workInProgress.alternate = null;
15146
15147 // Insert a deletion in the effect list.
15148 var returnFiber = workInProgress.return;
15149 !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
15150 var last = returnFiber.lastEffect;
15151 if (last !== null) {
15152 last.nextEffect = current$$1;
15153 returnFiber.lastEffect = current$$1;
15154 } else {
15155 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
15156 }
15157 current$$1.nextEffect = null;
15158 current$$1.effectTag = Deletion;
15159
15160 // Upgrade this work in progress to a real Suspense component.
15161 workInProgress.tag = SuspenseComponent;
15162 workInProgress.stateNode = null;
15163 workInProgress.memoizedState = null;
15164 // This is now an insertion.
15165 workInProgress.effectTag |= Placement;
15166 // Retry as a real Suspense component.
15167 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
15168 }
15169 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15170 // This is the first attempt.
15171 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
15172 var nextProps = workInProgress.pendingProps;
15173 var nextChildren = nextProps.children;
15174 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15175 return workInProgress.child;
15176 } else {
15177 // Something suspended. Leave the existing children in place.
15178 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
15179 workInProgress.child = null;
15180 return null;
15181 }
15182}
15183
15184function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15185 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15186 var nextChildren = workInProgress.pendingProps;
15187 if (current$$1 === null) {
15188 // Portals are special because we don't append the children during mount
15189 // but at commit. Therefore we need to track insertions which the normal
15190 // flow doesn't do during mount. This doesn't happen at the root because
15191 // the root always starts with a "current" with a null child.
15192 // TODO: Consider unifying this with how the root works.
15193 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15194 } else {
15195 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
15196 }
15197 return workInProgress.child;
15198}
15199
15200function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
15201 var providerType = workInProgress.type;
15202 var context = providerType._context;
15203
15204 var newProps = workInProgress.pendingProps;
15205 var oldProps = workInProgress.memoizedProps;
15206
15207 var newValue = newProps.value;
15208
15209 {
15210 var providerPropTypes = workInProgress.type.propTypes;
15211
15212 if (providerPropTypes) {
15213 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
15214 }
15215 }
15216
15217 pushProvider(workInProgress, newValue);
15218
15219 if (oldProps !== null) {
15220 var oldValue = oldProps.value;
15221 var changedBits = calculateChangedBits(context, newValue, oldValue);
15222 if (changedBits === 0) {
15223 // No change. Bailout early if children are the same.
15224 if (oldProps.children === newProps.children && !hasContextChanged()) {
15225 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15226 }
15227 } else {
15228 // The context value changed. Search for matching consumers and schedule
15229 // them to update.
15230 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
15231 }
15232 }
15233
15234 var newChildren = newProps.children;
15235 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15236 return workInProgress.child;
15237}
15238
15239var hasWarnedAboutUsingContextAsConsumer = false;
15240
15241function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
15242 var context = workInProgress.type;
15243 // The logic below for Context differs depending on PROD or DEV mode. In
15244 // DEV mode, we create a separate object for Context.Consumer that acts
15245 // like a proxy to Context. This proxy object adds unnecessary code in PROD
15246 // so we use the old behaviour (Context.Consumer references Context) to
15247 // reduce size and overhead. The separate object references context via
15248 // a property called "_context", which also gives us the ability to check
15249 // in DEV mode if this property exists or not and warn if it does not.
15250 {
15251 if (context._context === undefined) {
15252 // This may be because it's a Context (rather than a Consumer).
15253 // Or it may be because it's older React where they're the same thing.
15254 // We only want to warn if we're sure it's a new React.
15255 if (context !== context.Consumer) {
15256 if (!hasWarnedAboutUsingContextAsConsumer) {
15257 hasWarnedAboutUsingContextAsConsumer = true;
15258 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?');
15259 }
15260 }
15261 } else {
15262 context = context._context;
15263 }
15264 }
15265 var newProps = workInProgress.pendingProps;
15266 var render = newProps.children;
15267
15268 {
15269 !(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;
15270 }
15271
15272 prepareToReadContext(workInProgress, renderExpirationTime);
15273 var newValue = readContext(context, newProps.unstable_observedBits);
15274 var newChildren = void 0;
15275 {
15276 ReactCurrentOwner$3.current = workInProgress;
15277 setCurrentPhase('render');
15278 newChildren = render(newValue);
15279 setCurrentPhase(null);
15280 }
15281
15282 // React DevTools reads this flag.
15283 workInProgress.effectTag |= PerformedWork;
15284 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15285 return workInProgress.child;
15286}
15287
15288function markWorkInProgressReceivedUpdate() {
15289 didReceiveUpdate = true;
15290}
15291
15292function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
15293 cancelWorkTimer(workInProgress);
15294
15295 if (current$$1 !== null) {
15296 // Reuse previous context list
15297 workInProgress.contextDependencies = current$$1.contextDependencies;
15298 }
15299
15300 if (enableProfilerTimer) {
15301 // Don't update "base" render times for bailouts.
15302 stopProfilerTimerIfRunning(workInProgress);
15303 }
15304
15305 // Check if the children have any pending work.
15306 var childExpirationTime = workInProgress.childExpirationTime;
15307 if (childExpirationTime < renderExpirationTime) {
15308 // The children don't have any work either. We can skip them.
15309 // TODO: Once we add back resuming, we should check if the children are
15310 // a work-in-progress set. If so, we need to transfer their effects.
15311 return null;
15312 } else {
15313 // This fiber doesn't have work, but its subtree does. Clone the child
15314 // fibers and continue.
15315 cloneChildFibers(current$$1, workInProgress);
15316 return workInProgress.child;
15317 }
15318}
15319
15320function beginWork(current$$1, workInProgress, renderExpirationTime) {
15321 var updateExpirationTime = workInProgress.expirationTime;
15322
15323 if (current$$1 !== null) {
15324 var oldProps = current$$1.memoizedProps;
15325 var newProps = workInProgress.pendingProps;
15326
15327 if (oldProps !== newProps || hasContextChanged()) {
15328 // If props or context changed, mark the fiber as having performed work.
15329 // This may be unset if the props are determined to be equal later (memo).
15330 didReceiveUpdate = true;
15331 } else if (updateExpirationTime < renderExpirationTime) {
15332 didReceiveUpdate = false;
15333 // This fiber does not have any pending work. Bailout without entering
15334 // the begin phase. There's still some bookkeeping we that needs to be done
15335 // in this optimized path, mostly pushing stuff onto the stack.
15336 switch (workInProgress.tag) {
15337 case HostRoot:
15338 pushHostRootContext(workInProgress);
15339 resetHydrationState();
15340 break;
15341 case HostComponent:
15342 pushHostContext(workInProgress);
15343 break;
15344 case ClassComponent:
15345 {
15346 var Component = workInProgress.type;
15347 if (isContextProvider(Component)) {
15348 pushContextProvider(workInProgress);
15349 }
15350 break;
15351 }
15352 case HostPortal:
15353 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15354 break;
15355 case ContextProvider:
15356 {
15357 var newValue = workInProgress.memoizedProps.value;
15358 pushProvider(workInProgress, newValue);
15359 break;
15360 }
15361 case Profiler:
15362 if (enableProfilerTimer) {
15363 workInProgress.effectTag |= Update;
15364 }
15365 break;
15366 case SuspenseComponent:
15367 {
15368 var state = workInProgress.memoizedState;
15369 var didTimeout = state !== null;
15370 if (didTimeout) {
15371 // If this boundary is currently timed out, we need to decide
15372 // whether to retry the primary children, or to skip over it and
15373 // go straight to the fallback. Check the priority of the primary
15374 var primaryChildFragment = workInProgress.child;
15375 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
15376 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
15377 // The primary children have pending work. Use the normal path
15378 // to attempt to render the primary children again.
15379 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15380 } else {
15381 // The primary children do not have pending work with sufficient
15382 // priority. Bailout.
15383 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15384 if (child !== null) {
15385 // The fallback children have pending work. Skip over the
15386 // primary children and work on the fallback.
15387 return child.sibling;
15388 } else {
15389 return null;
15390 }
15391 }
15392 }
15393 break;
15394 }
15395 case DehydratedSuspenseComponent:
15396 {
15397 if (enableSuspenseServerRenderer) {
15398 // We know that this component will suspend again because if it has
15399 // been unsuspended it has committed as a regular Suspense component.
15400 // If it needs to be retried, it should have work scheduled on it.
15401 workInProgress.effectTag |= DidCapture;
15402 break;
15403 }
15404 }
15405 }
15406 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15407 }
15408 } else {
15409 didReceiveUpdate = false;
15410 }
15411
15412 // Before entering the begin phase, clear the expiration time.
15413 workInProgress.expirationTime = NoWork;
15414
15415 switch (workInProgress.tag) {
15416 case IndeterminateComponent:
15417 {
15418 var elementType = workInProgress.elementType;
15419 return mountIndeterminateComponent(current$$1, workInProgress, elementType, renderExpirationTime);
15420 }
15421 case LazyComponent:
15422 {
15423 var _elementType = workInProgress.elementType;
15424 return mountLazyComponent(current$$1, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
15425 }
15426 case FunctionComponent:
15427 {
15428 var _Component = workInProgress.type;
15429 var unresolvedProps = workInProgress.pendingProps;
15430 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
15431 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
15432 }
15433 case ClassComponent:
15434 {
15435 var _Component2 = workInProgress.type;
15436 var _unresolvedProps = workInProgress.pendingProps;
15437 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
15438 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
15439 }
15440 case HostRoot:
15441 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
15442 case HostComponent:
15443 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
15444 case HostText:
15445 return updateHostText(current$$1, workInProgress);
15446 case SuspenseComponent:
15447 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15448 case HostPortal:
15449 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
15450 case ForwardRef:
15451 {
15452 var type = workInProgress.type;
15453 var _unresolvedProps2 = workInProgress.pendingProps;
15454 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
15455 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
15456 }
15457 case Fragment:
15458 return updateFragment(current$$1, workInProgress, renderExpirationTime);
15459 case Mode:
15460 return updateMode(current$$1, workInProgress, renderExpirationTime);
15461 case Profiler:
15462 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
15463 case ContextProvider:
15464 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
15465 case ContextConsumer:
15466 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
15467 case MemoComponent:
15468 {
15469 var _type2 = workInProgress.type;
15470 var _unresolvedProps3 = workInProgress.pendingProps;
15471 // Resolve outer props first, then resolve inner props.
15472 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
15473 {
15474 if (workInProgress.type !== workInProgress.elementType) {
15475 var outerPropTypes = _type2.propTypes;
15476 if (outerPropTypes) {
15477 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
15478 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
15479 }
15480 }
15481 }
15482 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
15483 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
15484 }
15485 case SimpleMemoComponent:
15486 {
15487 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
15488 }
15489 case IncompleteClassComponent:
15490 {
15491 var _Component3 = workInProgress.type;
15492 var _unresolvedProps4 = workInProgress.pendingProps;
15493 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15494 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15495 }
15496 case DehydratedSuspenseComponent:
15497 {
15498 if (enableSuspenseServerRenderer) {
15499 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15500 }
15501 break;
15502 }
15503 }
15504 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15505}
15506
15507var valueCursor = createCursor(null);
15508
15509var rendererSigil = void 0;
15510{
15511 // Use this to detect multiple renderers using the same context
15512 rendererSigil = {};
15513}
15514
15515var currentlyRenderingFiber = null;
15516var lastContextDependency = null;
15517var lastContextWithAllBitsObserved = null;
15518
15519var isDisallowedContextReadInDEV = false;
15520
15521function resetContextDependences() {
15522 // This is called right before React yields execution, to ensure `readContext`
15523 // cannot be called outside the render phase.
15524 currentlyRenderingFiber = null;
15525 lastContextDependency = null;
15526 lastContextWithAllBitsObserved = null;
15527 {
15528 isDisallowedContextReadInDEV = false;
15529 }
15530}
15531
15532function enterDisallowedContextReadInDEV() {
15533 {
15534 isDisallowedContextReadInDEV = true;
15535 }
15536}
15537
15538function exitDisallowedContextReadInDEV() {
15539 {
15540 isDisallowedContextReadInDEV = false;
15541 }
15542}
15543
15544function pushProvider(providerFiber, nextValue) {
15545 var context = providerFiber.type._context;
15546
15547 if (isPrimaryRenderer) {
15548 push(valueCursor, context._currentValue, providerFiber);
15549
15550 context._currentValue = nextValue;
15551 {
15552 !(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;
15553 context._currentRenderer = rendererSigil;
15554 }
15555 } else {
15556 push(valueCursor, context._currentValue2, providerFiber);
15557
15558 context._currentValue2 = nextValue;
15559 {
15560 !(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;
15561 context._currentRenderer2 = rendererSigil;
15562 }
15563 }
15564}
15565
15566function popProvider(providerFiber) {
15567 var currentValue = valueCursor.current;
15568
15569 pop(valueCursor, providerFiber);
15570
15571 var context = providerFiber.type._context;
15572 if (isPrimaryRenderer) {
15573 context._currentValue = currentValue;
15574 } else {
15575 context._currentValue2 = currentValue;
15576 }
15577}
15578
15579function calculateChangedBits(context, newValue, oldValue) {
15580 if (is(oldValue, newValue)) {
15581 // No change
15582 return 0;
15583 } else {
15584 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
15585
15586 {
15587 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
15588 }
15589 return changedBits | 0;
15590 }
15591}
15592
15593function scheduleWorkOnParentPath(parent, renderExpirationTime) {
15594 // Update the child expiration time of all the ancestors, including
15595 // the alternates.
15596 var node = parent;
15597 while (node !== null) {
15598 var alternate = node.alternate;
15599 if (node.childExpirationTime < renderExpirationTime) {
15600 node.childExpirationTime = renderExpirationTime;
15601 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15602 alternate.childExpirationTime = renderExpirationTime;
15603 }
15604 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15605 alternate.childExpirationTime = renderExpirationTime;
15606 } else {
15607 // Neither alternate was updated, which means the rest of the
15608 // ancestor path already has sufficient priority.
15609 break;
15610 }
15611 node = node.return;
15612 }
15613}
15614
15615function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
15616 var fiber = workInProgress.child;
15617 if (fiber !== null) {
15618 // Set the return pointer of the child to the work-in-progress fiber.
15619 fiber.return = workInProgress;
15620 }
15621 while (fiber !== null) {
15622 var nextFiber = void 0;
15623
15624 // Visit this fiber.
15625 var list = fiber.contextDependencies;
15626 if (list !== null) {
15627 nextFiber = fiber.child;
15628
15629 var dependency = list.first;
15630 while (dependency !== null) {
15631 // Check if the context matches.
15632 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
15633 // Match! Schedule an update on this fiber.
15634
15635 if (fiber.tag === ClassComponent) {
15636 // Schedule a force update on the work-in-progress.
15637 var update = createUpdate(renderExpirationTime);
15638 update.tag = ForceUpdate;
15639 // TODO: Because we don't have a work-in-progress, this will add the
15640 // update to the current fiber, too, which means it will persist even if
15641 // this render is thrown away. Since it's a race condition, not sure it's
15642 // worth fixing.
15643 enqueueUpdate(fiber, update);
15644 }
15645
15646 if (fiber.expirationTime < renderExpirationTime) {
15647 fiber.expirationTime = renderExpirationTime;
15648 }
15649 var alternate = fiber.alternate;
15650 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
15651 alternate.expirationTime = renderExpirationTime;
15652 }
15653
15654 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
15655
15656 // Mark the expiration time on the list, too.
15657 if (list.expirationTime < renderExpirationTime) {
15658 list.expirationTime = renderExpirationTime;
15659 }
15660
15661 // Since we already found a match, we can stop traversing the
15662 // dependency list.
15663 break;
15664 }
15665 dependency = dependency.next;
15666 }
15667 } else if (fiber.tag === ContextProvider) {
15668 // Don't scan deeper if this is a matching provider
15669 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
15670 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
15671 // If a dehydrated suspense component is in this subtree, we don't know
15672 // if it will have any context consumers in it. The best we can do is
15673 // mark it as having updates on its children.
15674 if (fiber.expirationTime < renderExpirationTime) {
15675 fiber.expirationTime = renderExpirationTime;
15676 }
15677 var _alternate = fiber.alternate;
15678 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
15679 _alternate.expirationTime = renderExpirationTime;
15680 }
15681 // This is intentionally passing this fiber as the parent
15682 // because we want to schedule this fiber as having work
15683 // on its children. We'll use the childExpirationTime on
15684 // this fiber to indicate that a context has changed.
15685 scheduleWorkOnParentPath(fiber, renderExpirationTime);
15686 nextFiber = fiber.sibling;
15687 } else {
15688 // Traverse down.
15689 nextFiber = fiber.child;
15690 }
15691
15692 if (nextFiber !== null) {
15693 // Set the return pointer of the child to the work-in-progress fiber.
15694 nextFiber.return = fiber;
15695 } else {
15696 // No child. Traverse to next sibling.
15697 nextFiber = fiber;
15698 while (nextFiber !== null) {
15699 if (nextFiber === workInProgress) {
15700 // We're back to the root of this subtree. Exit.
15701 nextFiber = null;
15702 break;
15703 }
15704 var sibling = nextFiber.sibling;
15705 if (sibling !== null) {
15706 // Set the return pointer of the sibling to the work-in-progress fiber.
15707 sibling.return = nextFiber.return;
15708 nextFiber = sibling;
15709 break;
15710 }
15711 // No more siblings. Traverse up.
15712 nextFiber = nextFiber.return;
15713 }
15714 }
15715 fiber = nextFiber;
15716 }
15717}
15718
15719function prepareToReadContext(workInProgress, renderExpirationTime) {
15720 currentlyRenderingFiber = workInProgress;
15721 lastContextDependency = null;
15722 lastContextWithAllBitsObserved = null;
15723
15724 var currentDependencies = workInProgress.contextDependencies;
15725 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
15726 // Context list has a pending update. Mark that this fiber performed work.
15727 markWorkInProgressReceivedUpdate();
15728 }
15729
15730 // Reset the work-in-progress list
15731 workInProgress.contextDependencies = null;
15732}
15733
15734function readContext(context, observedBits) {
15735 {
15736 // This warning would fire if you read context inside a Hook like useMemo.
15737 // Unlike the class check below, it's not enforced in production for perf.
15738 !!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;
15739 }
15740
15741 if (lastContextWithAllBitsObserved === context) {
15742 // Nothing to do. We already observe everything in this context.
15743 } else if (observedBits === false || observedBits === 0) {
15744 // Do not observe any updates.
15745 } else {
15746 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
15747 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
15748 // Observe all updates.
15749 lastContextWithAllBitsObserved = context;
15750 resolvedObservedBits = maxSigned31BitInt;
15751 } else {
15752 resolvedObservedBits = observedBits;
15753 }
15754
15755 var contextItem = {
15756 context: context,
15757 observedBits: resolvedObservedBits,
15758 next: null
15759 };
15760
15761 if (lastContextDependency === null) {
15762 !(currentlyRenderingFiber !== null) ? invariant(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;
15763
15764 // This is the first dependency for this component. Create a new list.
15765 lastContextDependency = contextItem;
15766 currentlyRenderingFiber.contextDependencies = {
15767 first: contextItem,
15768 expirationTime: NoWork
15769 };
15770 } else {
15771 // Append a new context item.
15772 lastContextDependency = lastContextDependency.next = contextItem;
15773 }
15774 }
15775 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
15776}
15777
15778// UpdateQueue is a linked list of prioritized updates.
15779//
15780// Like fibers, update queues come in pairs: a current queue, which represents
15781// the visible state of the screen, and a work-in-progress queue, which can be
15782// mutated and processed asynchronously before it is committed — a form of
15783// double buffering. If a work-in-progress render is discarded before finishing,
15784// we create a new work-in-progress by cloning the current queue.
15785//
15786// Both queues share a persistent, singly-linked list structure. To schedule an
15787// update, we append it to the end of both queues. Each queue maintains a
15788// pointer to first update in the persistent list that hasn't been processed.
15789// The work-in-progress pointer always has a position equal to or greater than
15790// the current queue, since we always work on that one. The current queue's
15791// pointer is only updated during the commit phase, when we swap in the
15792// work-in-progress.
15793//
15794// For example:
15795//
15796// Current pointer: A - B - C - D - E - F
15797// Work-in-progress pointer: D - E - F
15798// ^
15799// The work-in-progress queue has
15800// processed more updates than current.
15801//
15802// The reason we append to both queues is because otherwise we might drop
15803// updates without ever processing them. For example, if we only add updates to
15804// the work-in-progress queue, some updates could be lost whenever a work-in
15805// -progress render restarts by cloning from current. Similarly, if we only add
15806// updates to the current queue, the updates will be lost whenever an already
15807// in-progress queue commits and swaps with the current queue. However, by
15808// adding to both queues, we guarantee that the update will be part of the next
15809// work-in-progress. (And because the work-in-progress queue becomes the
15810// current queue once it commits, there's no danger of applying the same
15811// update twice.)
15812//
15813// Prioritization
15814// --------------
15815//
15816// Updates are not sorted by priority, but by insertion; new updates are always
15817// appended to the end of the list.
15818//
15819// The priority is still important, though. When processing the update queue
15820// during the render phase, only the updates with sufficient priority are
15821// included in the result. If we skip an update because it has insufficient
15822// priority, it remains in the queue to be processed later, during a lower
15823// priority render. Crucially, all updates subsequent to a skipped update also
15824// remain in the queue *regardless of their priority*. That means high priority
15825// updates are sometimes processed twice, at two separate priorities. We also
15826// keep track of a base state, that represents the state before the first
15827// update in the queue is applied.
15828//
15829// For example:
15830//
15831// Given a base state of '', and the following queue of updates
15832//
15833// A1 - B2 - C1 - D2
15834//
15835// where the number indicates the priority, and the update is applied to the
15836// previous state by appending a letter, React will process these updates as
15837// two separate renders, one per distinct priority level:
15838//
15839// First render, at priority 1:
15840// Base state: ''
15841// Updates: [A1, C1]
15842// Result state: 'AC'
15843//
15844// Second render, at priority 2:
15845// Base state: 'A' <- The base state does not include C1,
15846// because B2 was skipped.
15847// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
15848// Result state: 'ABCD'
15849//
15850// Because we process updates in insertion order, and rebase high priority
15851// updates when preceding updates are skipped, the final result is deterministic
15852// regardless of priority. Intermediate state may vary according to system
15853// resources, but the final state is always the same.
15854
15855var UpdateState = 0;
15856var ReplaceState = 1;
15857var ForceUpdate = 2;
15858var CaptureUpdate = 3;
15859
15860// Global state that is reset at the beginning of calling `processUpdateQueue`.
15861// It should only be read right after calling `processUpdateQueue`, via
15862// `checkHasForceUpdateAfterProcessing`.
15863var hasForceUpdate = false;
15864
15865var didWarnUpdateInsideUpdate = void 0;
15866var currentlyProcessingQueue = void 0;
15867var resetCurrentlyProcessingQueue = void 0;
15868{
15869 didWarnUpdateInsideUpdate = false;
15870 currentlyProcessingQueue = null;
15871 resetCurrentlyProcessingQueue = function () {
15872 currentlyProcessingQueue = null;
15873 };
15874}
15875
15876function createUpdateQueue(baseState) {
15877 var queue = {
15878 baseState: baseState,
15879 firstUpdate: null,
15880 lastUpdate: null,
15881 firstCapturedUpdate: null,
15882 lastCapturedUpdate: null,
15883 firstEffect: null,
15884 lastEffect: null,
15885 firstCapturedEffect: null,
15886 lastCapturedEffect: null
15887 };
15888 return queue;
15889}
15890
15891function cloneUpdateQueue(currentQueue) {
15892 var queue = {
15893 baseState: currentQueue.baseState,
15894 firstUpdate: currentQueue.firstUpdate,
15895 lastUpdate: currentQueue.lastUpdate,
15896
15897 // TODO: With resuming, if we bail out and resuse the child tree, we should
15898 // keep these effects.
15899 firstCapturedUpdate: null,
15900 lastCapturedUpdate: null,
15901
15902 firstEffect: null,
15903 lastEffect: null,
15904
15905 firstCapturedEffect: null,
15906 lastCapturedEffect: null
15907 };
15908 return queue;
15909}
15910
15911function createUpdate(expirationTime) {
15912 return {
15913 expirationTime: expirationTime,
15914
15915 tag: UpdateState,
15916 payload: null,
15917 callback: null,
15918
15919 next: null,
15920 nextEffect: null
15921 };
15922}
15923
15924function appendUpdateToQueue(queue, update) {
15925 // Append the update to the end of the list.
15926 if (queue.lastUpdate === null) {
15927 // Queue is empty
15928 queue.firstUpdate = queue.lastUpdate = update;
15929 } else {
15930 queue.lastUpdate.next = update;
15931 queue.lastUpdate = update;
15932 }
15933}
15934
15935function enqueueUpdate(fiber, update) {
15936 // Update queues are created lazily.
15937 var alternate = fiber.alternate;
15938 var queue1 = void 0;
15939 var queue2 = void 0;
15940 if (alternate === null) {
15941 // There's only one fiber.
15942 queue1 = fiber.updateQueue;
15943 queue2 = null;
15944 if (queue1 === null) {
15945 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
15946 }
15947 } else {
15948 // There are two owners.
15949 queue1 = fiber.updateQueue;
15950 queue2 = alternate.updateQueue;
15951 if (queue1 === null) {
15952 if (queue2 === null) {
15953 // Neither fiber has an update queue. Create new ones.
15954 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
15955 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
15956 } else {
15957 // Only one fiber has an update queue. Clone to create a new one.
15958 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
15959 }
15960 } else {
15961 if (queue2 === null) {
15962 // Only one fiber has an update queue. Clone to create a new one.
15963 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
15964 } else {
15965 // Both owners have an update queue.
15966 }
15967 }
15968 }
15969 if (queue2 === null || queue1 === queue2) {
15970 // There's only a single queue.
15971 appendUpdateToQueue(queue1, update);
15972 } else {
15973 // There are two queues. We need to append the update to both queues,
15974 // while accounting for the persistent structure of the list — we don't
15975 // want the same update to be added multiple times.
15976 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
15977 // One of the queues is not empty. We must add the update to both queues.
15978 appendUpdateToQueue(queue1, update);
15979 appendUpdateToQueue(queue2, update);
15980 } else {
15981 // Both queues are non-empty. The last update is the same in both lists,
15982 // because of structural sharing. So, only append to one of the lists.
15983 appendUpdateToQueue(queue1, update);
15984 // But we still need to update the `lastUpdate` pointer of queue2.
15985 queue2.lastUpdate = update;
15986 }
15987 }
15988
15989 {
15990 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
15991 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.');
15992 didWarnUpdateInsideUpdate = true;
15993 }
15994 }
15995}
15996
15997function enqueueCapturedUpdate(workInProgress, update) {
15998 // Captured updates go into a separate list, and only on the work-in-
15999 // progress queue.
16000 var workInProgressQueue = workInProgress.updateQueue;
16001 if (workInProgressQueue === null) {
16002 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
16003 } else {
16004 // TODO: I put this here rather than createWorkInProgress so that we don't
16005 // clone the queue unnecessarily. There's probably a better way to
16006 // structure this.
16007 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
16008 }
16009
16010 // Append the update to the end of the list.
16011 if (workInProgressQueue.lastCapturedUpdate === null) {
16012 // This is the first render phase update
16013 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
16014 } else {
16015 workInProgressQueue.lastCapturedUpdate.next = update;
16016 workInProgressQueue.lastCapturedUpdate = update;
16017 }
16018}
16019
16020function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
16021 var current = workInProgress.alternate;
16022 if (current !== null) {
16023 // If the work-in-progress queue is equal to the current queue,
16024 // we need to clone it first.
16025 if (queue === current.updateQueue) {
16026 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
16027 }
16028 }
16029 return queue;
16030}
16031
16032function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
16033 switch (update.tag) {
16034 case ReplaceState:
16035 {
16036 var _payload = update.payload;
16037 if (typeof _payload === 'function') {
16038 // Updater function
16039 {
16040 enterDisallowedContextReadInDEV();
16041 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16042 _payload.call(instance, prevState, nextProps);
16043 }
16044 }
16045 var nextState = _payload.call(instance, prevState, nextProps);
16046 {
16047 exitDisallowedContextReadInDEV();
16048 }
16049 return nextState;
16050 }
16051 // State object
16052 return _payload;
16053 }
16054 case CaptureUpdate:
16055 {
16056 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
16057 }
16058 // Intentional fallthrough
16059 case UpdateState:
16060 {
16061 var _payload2 = update.payload;
16062 var partialState = void 0;
16063 if (typeof _payload2 === 'function') {
16064 // Updater function
16065 {
16066 enterDisallowedContextReadInDEV();
16067 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16068 _payload2.call(instance, prevState, nextProps);
16069 }
16070 }
16071 partialState = _payload2.call(instance, prevState, nextProps);
16072 {
16073 exitDisallowedContextReadInDEV();
16074 }
16075 } else {
16076 // Partial state object
16077 partialState = _payload2;
16078 }
16079 if (partialState === null || partialState === undefined) {
16080 // Null and undefined are treated as no-ops.
16081 return prevState;
16082 }
16083 // Merge the partial state and the previous state.
16084 return _assign({}, prevState, partialState);
16085 }
16086 case ForceUpdate:
16087 {
16088 hasForceUpdate = true;
16089 return prevState;
16090 }
16091 }
16092 return prevState;
16093}
16094
16095function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
16096 hasForceUpdate = false;
16097
16098 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
16099
16100 {
16101 currentlyProcessingQueue = queue;
16102 }
16103
16104 // These values may change as we process the queue.
16105 var newBaseState = queue.baseState;
16106 var newFirstUpdate = null;
16107 var newExpirationTime = NoWork;
16108
16109 // Iterate through the list of updates to compute the result.
16110 var update = queue.firstUpdate;
16111 var resultState = newBaseState;
16112 while (update !== null) {
16113 var updateExpirationTime = update.expirationTime;
16114 if (updateExpirationTime < renderExpirationTime) {
16115 // This update does not have sufficient priority. Skip it.
16116 if (newFirstUpdate === null) {
16117 // This is the first skipped update. It will be the first update in
16118 // the new list.
16119 newFirstUpdate = update;
16120 // Since this is the first update that was skipped, the current result
16121 // is the new base state.
16122 newBaseState = resultState;
16123 }
16124 // Since this update will remain in the list, update the remaining
16125 // expiration time.
16126 if (newExpirationTime < updateExpirationTime) {
16127 newExpirationTime = updateExpirationTime;
16128 }
16129 } else {
16130 // This update does have sufficient priority. Process it and compute
16131 // a new result.
16132 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16133 var _callback = update.callback;
16134 if (_callback !== null) {
16135 workInProgress.effectTag |= Callback;
16136 // Set this to null, in case it was mutated during an aborted render.
16137 update.nextEffect = null;
16138 if (queue.lastEffect === null) {
16139 queue.firstEffect = queue.lastEffect = update;
16140 } else {
16141 queue.lastEffect.nextEffect = update;
16142 queue.lastEffect = update;
16143 }
16144 }
16145 }
16146 // Continue to the next update.
16147 update = update.next;
16148 }
16149
16150 // Separately, iterate though the list of captured updates.
16151 var newFirstCapturedUpdate = null;
16152 update = queue.firstCapturedUpdate;
16153 while (update !== null) {
16154 var _updateExpirationTime = update.expirationTime;
16155 if (_updateExpirationTime < renderExpirationTime) {
16156 // This update does not have sufficient priority. Skip it.
16157 if (newFirstCapturedUpdate === null) {
16158 // This is the first skipped captured update. It will be the first
16159 // update in the new list.
16160 newFirstCapturedUpdate = update;
16161 // If this is the first update that was skipped, the current result is
16162 // the new base state.
16163 if (newFirstUpdate === null) {
16164 newBaseState = resultState;
16165 }
16166 }
16167 // Since this update will remain in the list, update the remaining
16168 // expiration time.
16169 if (newExpirationTime < _updateExpirationTime) {
16170 newExpirationTime = _updateExpirationTime;
16171 }
16172 } else {
16173 // This update does have sufficient priority. Process it and compute
16174 // a new result.
16175 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16176 var _callback2 = update.callback;
16177 if (_callback2 !== null) {
16178 workInProgress.effectTag |= Callback;
16179 // Set this to null, in case it was mutated during an aborted render.
16180 update.nextEffect = null;
16181 if (queue.lastCapturedEffect === null) {
16182 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
16183 } else {
16184 queue.lastCapturedEffect.nextEffect = update;
16185 queue.lastCapturedEffect = update;
16186 }
16187 }
16188 }
16189 update = update.next;
16190 }
16191
16192 if (newFirstUpdate === null) {
16193 queue.lastUpdate = null;
16194 }
16195 if (newFirstCapturedUpdate === null) {
16196 queue.lastCapturedUpdate = null;
16197 } else {
16198 workInProgress.effectTag |= Callback;
16199 }
16200 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
16201 // We processed every update, without skipping. That means the new base
16202 // state is the same as the result state.
16203 newBaseState = resultState;
16204 }
16205
16206 queue.baseState = newBaseState;
16207 queue.firstUpdate = newFirstUpdate;
16208 queue.firstCapturedUpdate = newFirstCapturedUpdate;
16209
16210 // Set the remaining expiration time to be whatever is remaining in the queue.
16211 // This should be fine because the only two other things that contribute to
16212 // expiration time are props and context. We're already in the middle of the
16213 // begin phase by the time we start processing the queue, so we've already
16214 // dealt with the props. Context in components that specify
16215 // shouldComponentUpdate is tricky; but we'll have to account for
16216 // that regardless.
16217 workInProgress.expirationTime = newExpirationTime;
16218 workInProgress.memoizedState = resultState;
16219
16220 {
16221 currentlyProcessingQueue = null;
16222 }
16223}
16224
16225function callCallback(callback, context) {
16226 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
16227 callback.call(context);
16228}
16229
16230function resetHasForceUpdateBeforeProcessing() {
16231 hasForceUpdate = false;
16232}
16233
16234function checkHasForceUpdateAfterProcessing() {
16235 return hasForceUpdate;
16236}
16237
16238function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
16239 // If the finished render included captured updates, and there are still
16240 // lower priority updates left over, we need to keep the captured updates
16241 // in the queue so that they are rebased and not dropped once we process the
16242 // queue again at the lower priority.
16243 if (finishedQueue.firstCapturedUpdate !== null) {
16244 // Join the captured update list to the end of the normal list.
16245 if (finishedQueue.lastUpdate !== null) {
16246 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
16247 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
16248 }
16249 // Clear the list of captured updates.
16250 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
16251 }
16252
16253 // Commit the effects
16254 commitUpdateEffects(finishedQueue.firstEffect, instance);
16255 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
16256
16257 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
16258 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
16259}
16260
16261function commitUpdateEffects(effect, instance) {
16262 while (effect !== null) {
16263 var _callback3 = effect.callback;
16264 if (_callback3 !== null) {
16265 effect.callback = null;
16266 callCallback(_callback3, instance);
16267 }
16268 effect = effect.nextEffect;
16269 }
16270}
16271
16272function createCapturedValue(value, source) {
16273 // If the value is an error, call this function immediately after it is thrown
16274 // so the stack is accurate.
16275 return {
16276 value: value,
16277 source: source,
16278 stack: getStackByFiberInDevAndProd(source)
16279 };
16280}
16281
16282function markUpdate(workInProgress) {
16283 // Tag the fiber with an update effect. This turns a Placement into
16284 // a PlacementAndUpdate.
16285 workInProgress.effectTag |= Update;
16286}
16287
16288function markRef$1(workInProgress) {
16289 workInProgress.effectTag |= Ref;
16290}
16291
16292var appendAllChildren = void 0;
16293var updateHostContainer = void 0;
16294var updateHostComponent$1 = void 0;
16295var updateHostText$1 = void 0;
16296if (supportsMutation) {
16297 // Mutation mode
16298
16299 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16300 // We only have the top Fiber that was created but we need recurse down its
16301 // children to find all the terminal nodes.
16302 var node = workInProgress.child;
16303 while (node !== null) {
16304 if (node.tag === HostComponent || node.tag === HostText) {
16305 appendInitialChild(parent, node.stateNode);
16306 } else if (node.tag === HostPortal) {
16307 // If we have a portal child, then we don't want to traverse
16308 // down its children. Instead, we'll get insertions from each child in
16309 // the portal directly.
16310 } else if (node.child !== null) {
16311 node.child.return = node;
16312 node = node.child;
16313 continue;
16314 }
16315 if (node === workInProgress) {
16316 return;
16317 }
16318 while (node.sibling === null) {
16319 if (node.return === null || node.return === workInProgress) {
16320 return;
16321 }
16322 node = node.return;
16323 }
16324 node.sibling.return = node.return;
16325 node = node.sibling;
16326 }
16327 };
16328
16329 updateHostContainer = function (workInProgress) {
16330 // Noop
16331 };
16332 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16333 // If we have an alternate, that means this is an update and we need to
16334 // schedule a side-effect to do the updates.
16335 var oldProps = current.memoizedProps;
16336 if (oldProps === newProps) {
16337 // In mutation mode, this is sufficient for a bailout because
16338 // we won't touch this node even if children changed.
16339 return;
16340 }
16341
16342 // If we get updated because one of our children updated, we don't
16343 // have newProps so we'll have to reuse them.
16344 // TODO: Split the update API as separate for the props vs. children.
16345 // Even better would be if children weren't special cased at all tho.
16346 var instance = workInProgress.stateNode;
16347 var currentHostContext = getHostContext();
16348 // TODO: Experiencing an error where oldProps is null. Suggests a host
16349 // component is hitting the resume path. Figure out why. Possibly
16350 // related to `hidden`.
16351 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16352 // TODO: Type this specific to this type of component.
16353 workInProgress.updateQueue = updatePayload;
16354 // If the update payload indicates that there is a change or if there
16355 // is a new ref we mark this as an update. All the work is done in commitWork.
16356 if (updatePayload) {
16357 markUpdate(workInProgress);
16358 }
16359 };
16360 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16361 // If the text differs, mark it as an update. All the work in done in commitWork.
16362 if (oldText !== newText) {
16363 markUpdate(workInProgress);
16364 }
16365 };
16366} else if (supportsPersistence) {
16367 // Persistent host tree mode
16368
16369 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16370 // We only have the top Fiber that was created but we need recurse down its
16371 // children to find all the terminal nodes.
16372 var node = workInProgress.child;
16373 while (node !== null) {
16374 // eslint-disable-next-line no-labels
16375 branches: if (node.tag === HostComponent) {
16376 var instance = node.stateNode;
16377 if (needsVisibilityToggle) {
16378 var props = node.memoizedProps;
16379 var type = node.type;
16380 if (isHidden) {
16381 // This child is inside a timed out tree. Hide it.
16382 instance = cloneHiddenInstance(instance, type, props, node);
16383 } else {
16384 // This child was previously inside a timed out tree. If it was not
16385 // updated during this render, it may need to be unhidden. Clone
16386 // again to be sure.
16387 instance = cloneUnhiddenInstance(instance, type, props, node);
16388 }
16389 node.stateNode = instance;
16390 }
16391 appendInitialChild(parent, instance);
16392 } else if (node.tag === HostText) {
16393 var _instance = node.stateNode;
16394 if (needsVisibilityToggle) {
16395 var text = node.memoizedProps;
16396 var rootContainerInstance = getRootHostContainer();
16397 var currentHostContext = getHostContext();
16398 if (isHidden) {
16399 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16400 } else {
16401 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16402 }
16403 node.stateNode = _instance;
16404 }
16405 appendInitialChild(parent, _instance);
16406 } else if (node.tag === HostPortal) {
16407 // If we have a portal child, then we don't want to traverse
16408 // down its children. Instead, we'll get insertions from each child in
16409 // the portal directly.
16410 } else if (node.tag === SuspenseComponent) {
16411 var current = node.alternate;
16412 if (current !== null) {
16413 var oldState = current.memoizedState;
16414 var newState = node.memoizedState;
16415 var oldIsHidden = oldState !== null;
16416 var newIsHidden = newState !== null;
16417 if (oldIsHidden !== newIsHidden) {
16418 // The placeholder either just timed out or switched back to the normal
16419 // children after having previously timed out. Toggle the visibility of
16420 // the direct host children.
16421 var primaryChildParent = newIsHidden ? node.child : node;
16422 if (primaryChildParent !== null) {
16423 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
16424 }
16425 // eslint-disable-next-line no-labels
16426 break branches;
16427 }
16428 }
16429 if (node.child !== null) {
16430 // Continue traversing like normal
16431 node.child.return = node;
16432 node = node.child;
16433 continue;
16434 }
16435 } else if (node.child !== null) {
16436 node.child.return = node;
16437 node = node.child;
16438 continue;
16439 }
16440 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16441 node = node;
16442 if (node === workInProgress) {
16443 return;
16444 }
16445 while (node.sibling === null) {
16446 if (node.return === null || node.return === workInProgress) {
16447 return;
16448 }
16449 node = node.return;
16450 }
16451 node.sibling.return = node.return;
16452 node = node.sibling;
16453 }
16454 };
16455
16456 // An unfortunate fork of appendAllChildren because we have two different parent types.
16457 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
16458 // We only have the top Fiber that was created but we need recurse down its
16459 // children to find all the terminal nodes.
16460 var node = workInProgress.child;
16461 while (node !== null) {
16462 // eslint-disable-next-line no-labels
16463 branches: if (node.tag === HostComponent) {
16464 var instance = node.stateNode;
16465 if (needsVisibilityToggle) {
16466 var props = node.memoizedProps;
16467 var type = node.type;
16468 if (isHidden) {
16469 // This child is inside a timed out tree. Hide it.
16470 instance = cloneHiddenInstance(instance, type, props, node);
16471 } else {
16472 // This child was previously inside a timed out tree. If it was not
16473 // updated during this render, it may need to be unhidden. Clone
16474 // again to be sure.
16475 instance = cloneUnhiddenInstance(instance, type, props, node);
16476 }
16477 node.stateNode = instance;
16478 }
16479 appendChildToContainerChildSet(containerChildSet, instance);
16480 } else if (node.tag === HostText) {
16481 var _instance2 = node.stateNode;
16482 if (needsVisibilityToggle) {
16483 var text = node.memoizedProps;
16484 var rootContainerInstance = getRootHostContainer();
16485 var currentHostContext = getHostContext();
16486 if (isHidden) {
16487 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16488 } else {
16489 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16490 }
16491 node.stateNode = _instance2;
16492 }
16493 appendChildToContainerChildSet(containerChildSet, _instance2);
16494 } else if (node.tag === HostPortal) {
16495 // If we have a portal child, then we don't want to traverse
16496 // down its children. Instead, we'll get insertions from each child in
16497 // the portal directly.
16498 } else if (node.tag === SuspenseComponent) {
16499 var current = node.alternate;
16500 if (current !== null) {
16501 var oldState = current.memoizedState;
16502 var newState = node.memoizedState;
16503 var oldIsHidden = oldState !== null;
16504 var newIsHidden = newState !== null;
16505 if (oldIsHidden !== newIsHidden) {
16506 // The placeholder either just timed out or switched back to the normal
16507 // children after having previously timed out. Toggle the visibility of
16508 // the direct host children.
16509 var primaryChildParent = newIsHidden ? node.child : node;
16510 if (primaryChildParent !== null) {
16511 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
16512 }
16513 // eslint-disable-next-line no-labels
16514 break branches;
16515 }
16516 }
16517 if (node.child !== null) {
16518 // Continue traversing like normal
16519 node.child.return = node;
16520 node = node.child;
16521 continue;
16522 }
16523 } else if (node.child !== null) {
16524 node.child.return = node;
16525 node = node.child;
16526 continue;
16527 }
16528 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16529 node = node;
16530 if (node === workInProgress) {
16531 return;
16532 }
16533 while (node.sibling === null) {
16534 if (node.return === null || node.return === workInProgress) {
16535 return;
16536 }
16537 node = node.return;
16538 }
16539 node.sibling.return = node.return;
16540 node = node.sibling;
16541 }
16542 };
16543 updateHostContainer = function (workInProgress) {
16544 var portalOrRoot = workInProgress.stateNode;
16545 var childrenUnchanged = workInProgress.firstEffect === null;
16546 if (childrenUnchanged) {
16547 // No changes, just reuse the existing instance.
16548 } else {
16549 var container = portalOrRoot.containerInfo;
16550 var newChildSet = createContainerChildSet(container);
16551 // If children might have changed, we have to add them all to the set.
16552 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
16553 portalOrRoot.pendingChildren = newChildSet;
16554 // Schedule an update on the container to swap out the container.
16555 markUpdate(workInProgress);
16556 finalizeContainerChildren(container, newChildSet);
16557 }
16558 };
16559 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16560 var currentInstance = current.stateNode;
16561 var oldProps = current.memoizedProps;
16562 // If there are no effects associated with this node, then none of our children had any updates.
16563 // This guarantees that we can reuse all of them.
16564 var childrenUnchanged = workInProgress.firstEffect === null;
16565 if (childrenUnchanged && oldProps === newProps) {
16566 // No changes, just reuse the existing instance.
16567 // Note that this might release a previous clone.
16568 workInProgress.stateNode = currentInstance;
16569 return;
16570 }
16571 var recyclableInstance = workInProgress.stateNode;
16572 var currentHostContext = getHostContext();
16573 var updatePayload = null;
16574 if (oldProps !== newProps) {
16575 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16576 }
16577 if (childrenUnchanged && updatePayload === null) {
16578 // No changes, just reuse the existing instance.
16579 // Note that this might release a previous clone.
16580 workInProgress.stateNode = currentInstance;
16581 return;
16582 }
16583 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
16584 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
16585 markUpdate(workInProgress);
16586 }
16587 workInProgress.stateNode = newInstance;
16588 if (childrenUnchanged) {
16589 // If there are no other effects in this tree, we need to flag this node as having one.
16590 // Even though we're not going to use it for anything.
16591 // Otherwise parents won't know that there are new children to propagate upwards.
16592 markUpdate(workInProgress);
16593 } else {
16594 // If children might have changed, we have to add them all to the set.
16595 appendAllChildren(newInstance, workInProgress, false, false);
16596 }
16597 };
16598 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16599 if (oldText !== newText) {
16600 // If the text content differs, we'll create a new text instance for it.
16601 var rootContainerInstance = getRootHostContainer();
16602 var currentHostContext = getHostContext();
16603 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
16604 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
16605 // This lets the parents know that at least one of their children has changed.
16606 markUpdate(workInProgress);
16607 }
16608 };
16609} else {
16610 // No host operations
16611 updateHostContainer = function (workInProgress) {
16612 // Noop
16613 };
16614 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16615 // Noop
16616 };
16617 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16618 // Noop
16619 };
16620}
16621
16622function completeWork(current, workInProgress, renderExpirationTime) {
16623 var newProps = workInProgress.pendingProps;
16624
16625 switch (workInProgress.tag) {
16626 case IndeterminateComponent:
16627 break;
16628 case LazyComponent:
16629 break;
16630 case SimpleMemoComponent:
16631 case FunctionComponent:
16632 break;
16633 case ClassComponent:
16634 {
16635 var Component = workInProgress.type;
16636 if (isContextProvider(Component)) {
16637 popContext(workInProgress);
16638 }
16639 break;
16640 }
16641 case HostRoot:
16642 {
16643 popHostContainer(workInProgress);
16644 popTopLevelContextObject(workInProgress);
16645 var fiberRoot = workInProgress.stateNode;
16646 if (fiberRoot.pendingContext) {
16647 fiberRoot.context = fiberRoot.pendingContext;
16648 fiberRoot.pendingContext = null;
16649 }
16650 if (current === null || current.child === null) {
16651 // If we hydrated, pop so that we can delete any remaining children
16652 // that weren't hydrated.
16653 popHydrationState(workInProgress);
16654 // This resets the hacky state to fix isMounted before committing.
16655 // TODO: Delete this when we delete isMounted and findDOMNode.
16656 workInProgress.effectTag &= ~Placement;
16657 }
16658 updateHostContainer(workInProgress);
16659 break;
16660 }
16661 case HostComponent:
16662 {
16663 popHostContext(workInProgress);
16664 var rootContainerInstance = getRootHostContainer();
16665 var type = workInProgress.type;
16666 if (current !== null && workInProgress.stateNode != null) {
16667 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
16668
16669 if (current.ref !== workInProgress.ref) {
16670 markRef$1(workInProgress);
16671 }
16672 } else {
16673 if (!newProps) {
16674 !(workInProgress.stateNode !== null) ? invariant(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0;
16675 // This can happen when we abort work.
16676 break;
16677 }
16678
16679 var currentHostContext = getHostContext();
16680 // TODO: Move createInstance to beginWork and keep it on a context
16681 // "stack" as the parent. Then append children as we go in beginWork
16682 // or completeWork depending on we want to add then top->down or
16683 // bottom->up. Top->down is faster in IE11.
16684 var wasHydrated = popHydrationState(workInProgress);
16685 if (wasHydrated) {
16686 // TODO: Move this and createInstance step into the beginPhase
16687 // to consolidate.
16688 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
16689 // If changes to the hydrated node needs to be applied at the
16690 // commit-phase we mark this as such.
16691 markUpdate(workInProgress);
16692 }
16693 } else {
16694 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
16695
16696 appendAllChildren(instance, workInProgress, false, false);
16697
16698 // Certain renderers require commit-time effects for initial mount.
16699 // (eg DOM renderer supports auto-focus for certain elements).
16700 // Make sure such renderers get scheduled for later work.
16701 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
16702 markUpdate(workInProgress);
16703 }
16704 workInProgress.stateNode = instance;
16705 }
16706
16707 if (workInProgress.ref !== null) {
16708 // If there is a ref on a host node we need to schedule a callback
16709 markRef$1(workInProgress);
16710 }
16711 }
16712 break;
16713 }
16714 case HostText:
16715 {
16716 var newText = newProps;
16717 if (current && workInProgress.stateNode != null) {
16718 var oldText = current.memoizedProps;
16719 // If we have an alternate, that means this is an update and we need
16720 // to schedule a side-effect to do the updates.
16721 updateHostText$1(current, workInProgress, oldText, newText);
16722 } else {
16723 if (typeof newText !== 'string') {
16724 !(workInProgress.stateNode !== null) ? invariant(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0;
16725 // This can happen when we abort work.
16726 }
16727 var _rootContainerInstance = getRootHostContainer();
16728 var _currentHostContext = getHostContext();
16729 var _wasHydrated = popHydrationState(workInProgress);
16730 if (_wasHydrated) {
16731 if (prepareToHydrateHostTextInstance(workInProgress)) {
16732 markUpdate(workInProgress);
16733 }
16734 } else {
16735 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
16736 }
16737 }
16738 break;
16739 }
16740 case ForwardRef:
16741 break;
16742 case SuspenseComponent:
16743 {
16744 var nextState = workInProgress.memoizedState;
16745 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
16746 // Something suspended. Re-render with the fallback children.
16747 workInProgress.expirationTime = renderExpirationTime;
16748 // Do not reset the effect list.
16749 return workInProgress;
16750 }
16751
16752 var nextDidTimeout = nextState !== null;
16753 var prevDidTimeout = current !== null && current.memoizedState !== null;
16754
16755 if (current !== null && !nextDidTimeout && prevDidTimeout) {
16756 // We just switched from the fallback to the normal children. Delete
16757 // the fallback.
16758 // TODO: Would it be better to store the fallback fragment on
16759 var currentFallbackChild = current.child.sibling;
16760 if (currentFallbackChild !== null) {
16761 // Deletions go at the beginning of the return fiber's effect list
16762 var first = workInProgress.firstEffect;
16763 if (first !== null) {
16764 workInProgress.firstEffect = currentFallbackChild;
16765 currentFallbackChild.nextEffect = first;
16766 } else {
16767 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
16768 currentFallbackChild.nextEffect = null;
16769 }
16770 currentFallbackChild.effectTag = Deletion;
16771 }
16772 }
16773
16774 if (nextDidTimeout || prevDidTimeout) {
16775 // If the children are hidden, or if they were previous hidden, schedule
16776 // an effect to toggle their visibility. This is also used to attach a
16777 // retry listener to the promise.
16778 workInProgress.effectTag |= Update;
16779 }
16780 break;
16781 }
16782 case Fragment:
16783 break;
16784 case Mode:
16785 break;
16786 case Profiler:
16787 break;
16788 case HostPortal:
16789 popHostContainer(workInProgress);
16790 updateHostContainer(workInProgress);
16791 break;
16792 case ContextProvider:
16793 // Pop provider fiber
16794 popProvider(workInProgress);
16795 break;
16796 case ContextConsumer:
16797 break;
16798 case MemoComponent:
16799 break;
16800 case IncompleteClassComponent:
16801 {
16802 // Same as class component case. I put it down here so that the tags are
16803 // sequential to ensure this switch is compiled to a jump table.
16804 var _Component = workInProgress.type;
16805 if (isContextProvider(_Component)) {
16806 popContext(workInProgress);
16807 }
16808 break;
16809 }
16810 case DehydratedSuspenseComponent:
16811 {
16812 if (enableSuspenseServerRenderer) {
16813 if (current === null) {
16814 var _wasHydrated2 = popHydrationState(workInProgress);
16815 !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
16816 skipPastDehydratedSuspenseInstance(workInProgress);
16817 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
16818 // This boundary did not suspend so it's now hydrated.
16819 // To handle any future suspense cases, we're going to now upgrade it
16820 // to a Suspense component. We detach it from the existing current fiber.
16821 current.alternate = null;
16822 workInProgress.alternate = null;
16823 workInProgress.tag = SuspenseComponent;
16824 workInProgress.memoizedState = null;
16825 workInProgress.stateNode = null;
16826 }
16827 }
16828 break;
16829 }
16830 default:
16831 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
16832 }
16833
16834 return null;
16835}
16836
16837function shouldCaptureSuspense(workInProgress) {
16838 // In order to capture, the Suspense component must have a fallback prop.
16839 if (workInProgress.memoizedProps.fallback === undefined) {
16840 return false;
16841 }
16842 // If it was the primary children that just suspended, capture and render the
16843 // fallback. Otherwise, don't capture and bubble to the next boundary.
16844 var nextState = workInProgress.memoizedState;
16845 return nextState === null;
16846}
16847
16848// This module is forked in different environments.
16849// By default, return `true` to log errors to the console.
16850// Forks can return `false` if this isn't desirable.
16851function showErrorDialog(capturedError) {
16852 return true;
16853}
16854
16855function logCapturedError(capturedError) {
16856 var logError = showErrorDialog(capturedError);
16857
16858 // Allow injected showErrorDialog() to prevent default console.error logging.
16859 // This enables renderers like ReactNative to better manage redbox behavior.
16860 if (logError === false) {
16861 return;
16862 }
16863
16864 var error = capturedError.error;
16865 {
16866 var componentName = capturedError.componentName,
16867 componentStack = capturedError.componentStack,
16868 errorBoundaryName = capturedError.errorBoundaryName,
16869 errorBoundaryFound = capturedError.errorBoundaryFound,
16870 willRetry = capturedError.willRetry;
16871
16872 // Browsers support silencing uncaught errors by calling
16873 // `preventDefault()` in window `error` handler.
16874 // We record this information as an expando on the error.
16875
16876 if (error != null && error._suppressLogging) {
16877 if (errorBoundaryFound && willRetry) {
16878 // The error is recoverable and was silenced.
16879 // Ignore it and don't print the stack addendum.
16880 // This is handy for testing error boundaries without noise.
16881 return;
16882 }
16883 // The error is fatal. Since the silencing might have
16884 // been accidental, we'll surface it anyway.
16885 // However, the browser would have silenced the original error
16886 // so we'll print it first, and then print the stack addendum.
16887 console.error(error);
16888 // For a more detailed description of this block, see:
16889 // https://github.com/facebook/react/pull/13384
16890 }
16891
16892 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
16893
16894 var errorBoundaryMessage = void 0;
16895 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
16896 if (errorBoundaryFound && errorBoundaryName) {
16897 if (willRetry) {
16898 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
16899 } else {
16900 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
16901 }
16902 } else {
16903 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.';
16904 }
16905 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
16906
16907 // In development, we provide our own message with just the component stack.
16908 // We don't include the original error message and JS stack because the browser
16909 // has already printed it. Even if the application swallows the error, it is still
16910 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
16911 console.error(combinedMessage);
16912 }
16913}
16914
16915var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
16916{
16917 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
16918}
16919
16920var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
16921
16922function logError(boundary, errorInfo) {
16923 var source = errorInfo.source;
16924 var stack = errorInfo.stack;
16925 if (stack === null && source !== null) {
16926 stack = getStackByFiberInDevAndProd(source);
16927 }
16928
16929 var capturedError = {
16930 componentName: source !== null ? getComponentName(source.type) : null,
16931 componentStack: stack !== null ? stack : '',
16932 error: errorInfo.value,
16933 errorBoundary: null,
16934 errorBoundaryName: null,
16935 errorBoundaryFound: false,
16936 willRetry: false
16937 };
16938
16939 if (boundary !== null && boundary.tag === ClassComponent) {
16940 capturedError.errorBoundary = boundary.stateNode;
16941 capturedError.errorBoundaryName = getComponentName(boundary.type);
16942 capturedError.errorBoundaryFound = true;
16943 capturedError.willRetry = true;
16944 }
16945
16946 try {
16947 logCapturedError(capturedError);
16948 } catch (e) {
16949 // This method must not throw, or React internal state will get messed up.
16950 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
16951 // we want to report this error outside of the normal stack as a last resort.
16952 // https://github.com/facebook/react/issues/13188
16953 setTimeout(function () {
16954 throw e;
16955 });
16956 }
16957}
16958
16959var callComponentWillUnmountWithTimer = function (current$$1, instance) {
16960 startPhaseTimer(current$$1, 'componentWillUnmount');
16961 instance.props = current$$1.memoizedProps;
16962 instance.state = current$$1.memoizedState;
16963 instance.componentWillUnmount();
16964 stopPhaseTimer();
16965};
16966
16967// Capture errors so they don't interrupt unmounting.
16968function safelyCallComponentWillUnmount(current$$1, instance) {
16969 {
16970 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
16971 if (hasCaughtError()) {
16972 var unmountError = clearCaughtError();
16973 captureCommitPhaseError(current$$1, unmountError);
16974 }
16975 }
16976}
16977
16978function safelyDetachRef(current$$1) {
16979 var ref = current$$1.ref;
16980 if (ref !== null) {
16981 if (typeof ref === 'function') {
16982 {
16983 invokeGuardedCallback(null, ref, null, null);
16984 if (hasCaughtError()) {
16985 var refError = clearCaughtError();
16986 captureCommitPhaseError(current$$1, refError);
16987 }
16988 }
16989 } else {
16990 ref.current = null;
16991 }
16992 }
16993}
16994
16995function safelyCallDestroy(current$$1, destroy) {
16996 {
16997 invokeGuardedCallback(null, destroy, null);
16998 if (hasCaughtError()) {
16999 var error = clearCaughtError();
17000 captureCommitPhaseError(current$$1, error);
17001 }
17002 }
17003}
17004
17005function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
17006 switch (finishedWork.tag) {
17007 case FunctionComponent:
17008 case ForwardRef:
17009 case SimpleMemoComponent:
17010 {
17011 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
17012 return;
17013 }
17014 case ClassComponent:
17015 {
17016 if (finishedWork.effectTag & Snapshot) {
17017 if (current$$1 !== null) {
17018 var prevProps = current$$1.memoizedProps;
17019 var prevState = current$$1.memoizedState;
17020 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
17021 var instance = finishedWork.stateNode;
17022 // We could update instance props and state here,
17023 // but instead we rely on them being set during last render.
17024 // TODO: revisit this when we implement resuming.
17025 {
17026 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17027 !(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;
17028 !(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;
17029 }
17030 }
17031 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
17032 {
17033 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
17034 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
17035 didWarnSet.add(finishedWork.type);
17036 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
17037 }
17038 }
17039 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
17040 stopPhaseTimer();
17041 }
17042 }
17043 return;
17044 }
17045 case HostRoot:
17046 case HostComponent:
17047 case HostText:
17048 case HostPortal:
17049 case IncompleteClassComponent:
17050 // Nothing to do for these component types
17051 return;
17052 default:
17053 {
17054 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
17055 }
17056 }
17057}
17058
17059function commitHookEffectList(unmountTag, mountTag, finishedWork) {
17060 var updateQueue = finishedWork.updateQueue;
17061 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
17062 if (lastEffect !== null) {
17063 var firstEffect = lastEffect.next;
17064 var effect = firstEffect;
17065 do {
17066 if ((effect.tag & unmountTag) !== NoEffect$1) {
17067 // Unmount
17068 var destroy = effect.destroy;
17069 effect.destroy = undefined;
17070 if (destroy !== undefined) {
17071 destroy();
17072 }
17073 }
17074 if ((effect.tag & mountTag) !== NoEffect$1) {
17075 // Mount
17076 var create = effect.create;
17077 effect.destroy = create();
17078
17079 {
17080 var _destroy = effect.destroy;
17081 if (_destroy !== undefined && typeof _destroy !== 'function') {
17082 var addendum = void 0;
17083 if (_destroy === null) {
17084 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
17085 } else if (typeof _destroy.then === 'function') {
17086 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, you may write an async function separately ' + 'and then call it from inside the effect:\n\n' + 'async function fetchComment(commentId) {\n' + ' // You can await here\n' + '}\n\n' + 'useEffect(() => {\n' + ' fetchComment(commentId);\n' + '}, [commentId]);\n\n' + 'In the future, React will provide a more idiomatic solution for data fetching ' + "that doesn't involve writing effects manually.";
17087 } else {
17088 addendum = ' You returned: ' + _destroy;
17089 }
17090 warningWithoutStack$1(false, 'An Effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
17091 }
17092 }
17093 }
17094 effect = effect.next;
17095 } while (effect !== firstEffect);
17096 }
17097}
17098
17099function commitPassiveHookEffects(finishedWork) {
17100 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
17101 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
17102}
17103
17104function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
17105 switch (finishedWork.tag) {
17106 case FunctionComponent:
17107 case ForwardRef:
17108 case SimpleMemoComponent:
17109 {
17110 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
17111 break;
17112 }
17113 case ClassComponent:
17114 {
17115 var instance = finishedWork.stateNode;
17116 if (finishedWork.effectTag & Update) {
17117 if (current$$1 === null) {
17118 startPhaseTimer(finishedWork, 'componentDidMount');
17119 // We could update instance props and state here,
17120 // but instead we rely on them being set during last render.
17121 // TODO: revisit this when we implement resuming.
17122 {
17123 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17124 !(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;
17125 !(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;
17126 }
17127 }
17128 instance.componentDidMount();
17129 stopPhaseTimer();
17130 } else {
17131 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
17132 var prevState = current$$1.memoizedState;
17133 startPhaseTimer(finishedWork, 'componentDidUpdate');
17134 // We could update instance props and state here,
17135 // but instead we rely on them being set during last render.
17136 // TODO: revisit this when we implement resuming.
17137 {
17138 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17139 !(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;
17140 !(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;
17141 }
17142 }
17143 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
17144 stopPhaseTimer();
17145 }
17146 }
17147 var updateQueue = finishedWork.updateQueue;
17148 if (updateQueue !== null) {
17149 {
17150 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17151 !(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;
17152 !(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;
17153 }
17154 }
17155 // We could update instance props and state here,
17156 // but instead we rely on them being set during last render.
17157 // TODO: revisit this when we implement resuming.
17158 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
17159 }
17160 return;
17161 }
17162 case HostRoot:
17163 {
17164 var _updateQueue = finishedWork.updateQueue;
17165 if (_updateQueue !== null) {
17166 var _instance = null;
17167 if (finishedWork.child !== null) {
17168 switch (finishedWork.child.tag) {
17169 case HostComponent:
17170 _instance = getPublicInstance(finishedWork.child.stateNode);
17171 break;
17172 case ClassComponent:
17173 _instance = finishedWork.child.stateNode;
17174 break;
17175 }
17176 }
17177 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
17178 }
17179 return;
17180 }
17181 case HostComponent:
17182 {
17183 var _instance2 = finishedWork.stateNode;
17184
17185 // Renderers may schedule work to be done after host components are mounted
17186 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
17187 // These effects should only be committed when components are first mounted,
17188 // aka when there is no current/alternate.
17189 if (current$$1 === null && finishedWork.effectTag & Update) {
17190 var type = finishedWork.type;
17191 var props = finishedWork.memoizedProps;
17192 commitMount(_instance2, type, props, finishedWork);
17193 }
17194
17195 return;
17196 }
17197 case HostText:
17198 {
17199 // We have no life-cycles associated with text.
17200 return;
17201 }
17202 case HostPortal:
17203 {
17204 // We have no life-cycles associated with portals.
17205 return;
17206 }
17207 case Profiler:
17208 {
17209 if (enableProfilerTimer) {
17210 var onRender = finishedWork.memoizedProps.onRender;
17211
17212 if (enableSchedulerTracing) {
17213 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
17214 } else {
17215 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
17216 }
17217 }
17218 return;
17219 }
17220 case SuspenseComponent:
17221 break;
17222 case IncompleteClassComponent:
17223 break;
17224 default:
17225 {
17226 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
17227 }
17228 }
17229}
17230
17231function hideOrUnhideAllChildren(finishedWork, isHidden) {
17232 if (supportsMutation) {
17233 // We only have the top Fiber that was inserted but we need to recurse down its
17234 var node = finishedWork;
17235 while (true) {
17236 if (node.tag === HostComponent) {
17237 var instance = node.stateNode;
17238 if (isHidden) {
17239 hideInstance(instance);
17240 } else {
17241 unhideInstance(node.stateNode, node.memoizedProps);
17242 }
17243 } else if (node.tag === HostText) {
17244 var _instance3 = node.stateNode;
17245 if (isHidden) {
17246 hideTextInstance(_instance3);
17247 } else {
17248 unhideTextInstance(_instance3, node.memoizedProps);
17249 }
17250 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
17251 // Found a nested Suspense component that timed out. Skip over the
17252 var fallbackChildFragment = node.child.sibling;
17253 fallbackChildFragment.return = node;
17254 node = fallbackChildFragment;
17255 continue;
17256 } else if (node.child !== null) {
17257 node.child.return = node;
17258 node = node.child;
17259 continue;
17260 }
17261 if (node === finishedWork) {
17262 return;
17263 }
17264 while (node.sibling === null) {
17265 if (node.return === null || node.return === finishedWork) {
17266 return;
17267 }
17268 node = node.return;
17269 }
17270 node.sibling.return = node.return;
17271 node = node.sibling;
17272 }
17273 }
17274}
17275
17276function commitAttachRef(finishedWork) {
17277 var ref = finishedWork.ref;
17278 if (ref !== null) {
17279 var instance = finishedWork.stateNode;
17280 var instanceToUse = void 0;
17281 switch (finishedWork.tag) {
17282 case HostComponent:
17283 instanceToUse = getPublicInstance(instance);
17284 break;
17285 default:
17286 instanceToUse = instance;
17287 }
17288 if (typeof ref === 'function') {
17289 ref(instanceToUse);
17290 } else {
17291 {
17292 if (!ref.hasOwnProperty('current')) {
17293 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
17294 }
17295 }
17296
17297 ref.current = instanceToUse;
17298 }
17299 }
17300}
17301
17302function commitDetachRef(current$$1) {
17303 var currentRef = current$$1.ref;
17304 if (currentRef !== null) {
17305 if (typeof currentRef === 'function') {
17306 currentRef(null);
17307 } else {
17308 currentRef.current = null;
17309 }
17310 }
17311}
17312
17313// User-originating errors (lifecycles and refs) should not interrupt
17314// deletion, so don't let them throw. Host-originating errors should
17315// interrupt deletion, so it's okay
17316function commitUnmount(current$$1) {
17317 onCommitUnmount(current$$1);
17318
17319 switch (current$$1.tag) {
17320 case FunctionComponent:
17321 case ForwardRef:
17322 case MemoComponent:
17323 case SimpleMemoComponent:
17324 {
17325 var updateQueue = current$$1.updateQueue;
17326 if (updateQueue !== null) {
17327 var lastEffect = updateQueue.lastEffect;
17328 if (lastEffect !== null) {
17329 var firstEffect = lastEffect.next;
17330 var effect = firstEffect;
17331 do {
17332 var destroy = effect.destroy;
17333 if (destroy !== undefined) {
17334 safelyCallDestroy(current$$1, destroy);
17335 }
17336 effect = effect.next;
17337 } while (effect !== firstEffect);
17338 }
17339 }
17340 break;
17341 }
17342 case ClassComponent:
17343 {
17344 safelyDetachRef(current$$1);
17345 var instance = current$$1.stateNode;
17346 if (typeof instance.componentWillUnmount === 'function') {
17347 safelyCallComponentWillUnmount(current$$1, instance);
17348 }
17349 return;
17350 }
17351 case HostComponent:
17352 {
17353 safelyDetachRef(current$$1);
17354 return;
17355 }
17356 case HostPortal:
17357 {
17358 // TODO: this is recursive.
17359 // We are also not using this parent because
17360 // the portal will get pushed immediately.
17361 if (supportsMutation) {
17362 unmountHostComponents(current$$1);
17363 } else if (supportsPersistence) {
17364 emptyPortalContainer(current$$1);
17365 }
17366 return;
17367 }
17368 }
17369}
17370
17371function commitNestedUnmounts(root) {
17372 // While we're inside a removed host node we don't want to call
17373 // removeChild on the inner nodes because they're removed by the top
17374 // call anyway. We also want to call componentWillUnmount on all
17375 // composites before this host node is removed from the tree. Therefore
17376 var node = root;
17377 while (true) {
17378 commitUnmount(node);
17379 // Visit children because they may contain more composite or host nodes.
17380 // Skip portals because commitUnmount() currently visits them recursively.
17381 if (node.child !== null && (
17382 // If we use mutation we drill down into portals using commitUnmount above.
17383 // If we don't use mutation we drill down into portals here instead.
17384 !supportsMutation || node.tag !== HostPortal)) {
17385 node.child.return = node;
17386 node = node.child;
17387 continue;
17388 }
17389 if (node === root) {
17390 return;
17391 }
17392 while (node.sibling === null) {
17393 if (node.return === null || node.return === root) {
17394 return;
17395 }
17396 node = node.return;
17397 }
17398 node.sibling.return = node.return;
17399 node = node.sibling;
17400 }
17401}
17402
17403function detachFiber(current$$1) {
17404 // Cut off the return pointers to disconnect it from the tree. Ideally, we
17405 // should clear the child pointer of the parent alternate to let this
17406 // get GC:ed but we don't know which for sure which parent is the current
17407 // one so we'll settle for GC:ing the subtree of this child. This child
17408 // itself will be GC:ed when the parent updates the next time.
17409 current$$1.return = null;
17410 current$$1.child = null;
17411 current$$1.memoizedState = null;
17412 current$$1.updateQueue = null;
17413 var alternate = current$$1.alternate;
17414 if (alternate !== null) {
17415 alternate.return = null;
17416 alternate.child = null;
17417 alternate.memoizedState = null;
17418 alternate.updateQueue = null;
17419 }
17420}
17421
17422function emptyPortalContainer(current$$1) {
17423 if (!supportsPersistence) {
17424 return;
17425 }
17426
17427 var portal = current$$1.stateNode;
17428 var containerInfo = portal.containerInfo;
17429
17430 var emptyChildSet = createContainerChildSet(containerInfo);
17431 replaceContainerChildren(containerInfo, emptyChildSet);
17432}
17433
17434function commitContainer(finishedWork) {
17435 if (!supportsPersistence) {
17436 return;
17437 }
17438
17439 switch (finishedWork.tag) {
17440 case ClassComponent:
17441 {
17442 return;
17443 }
17444 case HostComponent:
17445 {
17446 return;
17447 }
17448 case HostText:
17449 {
17450 return;
17451 }
17452 case HostRoot:
17453 case HostPortal:
17454 {
17455 var portalOrRoot = finishedWork.stateNode;
17456 var containerInfo = portalOrRoot.containerInfo,
17457 _pendingChildren = portalOrRoot.pendingChildren;
17458
17459 replaceContainerChildren(containerInfo, _pendingChildren);
17460 return;
17461 }
17462 default:
17463 {
17464 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
17465 }
17466 }
17467}
17468
17469function getHostParentFiber(fiber) {
17470 var parent = fiber.return;
17471 while (parent !== null) {
17472 if (isHostParent(parent)) {
17473 return parent;
17474 }
17475 parent = parent.return;
17476 }
17477 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
17478}
17479
17480function isHostParent(fiber) {
17481 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
17482}
17483
17484function getHostSibling(fiber) {
17485 // We're going to search forward into the tree until we find a sibling host
17486 // node. Unfortunately, if multiple insertions are done in a row we have to
17487 // search past them. This leads to exponential search for the next sibling.
17488 var node = fiber;
17489 siblings: while (true) {
17490 // If we didn't find anything, let's try the next sibling.
17491 while (node.sibling === null) {
17492 if (node.return === null || isHostParent(node.return)) {
17493 // If we pop out of the root or hit the parent the fiber we are the
17494 // last sibling.
17495 return null;
17496 }
17497 node = node.return;
17498 }
17499 node.sibling.return = node.return;
17500 node = node.sibling;
17501 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
17502 // If it is not host node and, we might have a host node inside it.
17503 // Try to search down until we find one.
17504 if (node.effectTag & Placement) {
17505 // If we don't have a child, try the siblings instead.
17506 continue siblings;
17507 }
17508 // If we don't have a child, try the siblings instead.
17509 // We also skip portals because they are not part of this host tree.
17510 if (node.child === null || node.tag === HostPortal) {
17511 continue siblings;
17512 } else {
17513 node.child.return = node;
17514 node = node.child;
17515 }
17516 }
17517 // Check if this host node is stable or about to be placed.
17518 if (!(node.effectTag & Placement)) {
17519 // Found it!
17520 return node.stateNode;
17521 }
17522 }
17523}
17524
17525function commitPlacement(finishedWork) {
17526 if (!supportsMutation) {
17527 return;
17528 }
17529
17530 // Recursively insert all host nodes into the parent.
17531 var parentFiber = getHostParentFiber(finishedWork);
17532
17533 // Note: these two variables *must* always be updated together.
17534 var parent = void 0;
17535 var isContainer = void 0;
17536
17537 switch (parentFiber.tag) {
17538 case HostComponent:
17539 parent = parentFiber.stateNode;
17540 isContainer = false;
17541 break;
17542 case HostRoot:
17543 parent = parentFiber.stateNode.containerInfo;
17544 isContainer = true;
17545 break;
17546 case HostPortal:
17547 parent = parentFiber.stateNode.containerInfo;
17548 isContainer = true;
17549 break;
17550 default:
17551 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
17552 }
17553 if (parentFiber.effectTag & ContentReset) {
17554 // Reset the text content of the parent before doing any insertions
17555 resetTextContent(parent);
17556 // Clear ContentReset from the effect tag
17557 parentFiber.effectTag &= ~ContentReset;
17558 }
17559
17560 var before = getHostSibling(finishedWork);
17561 // We only have the top Fiber that was inserted but we need to recurse down its
17562 // children to find all the terminal nodes.
17563 var node = finishedWork;
17564 while (true) {
17565 if (node.tag === HostComponent || node.tag === HostText) {
17566 if (before) {
17567 if (isContainer) {
17568 insertInContainerBefore(parent, node.stateNode, before);
17569 } else {
17570 insertBefore(parent, node.stateNode, before);
17571 }
17572 } else {
17573 if (isContainer) {
17574 appendChildToContainer(parent, node.stateNode);
17575 } else {
17576 appendChild(parent, node.stateNode);
17577 }
17578 }
17579 } else if (node.tag === HostPortal) {
17580 // If the insertion itself is a portal, then we don't want to traverse
17581 // down its children. Instead, we'll get insertions from each child in
17582 // the portal directly.
17583 } else if (node.child !== null) {
17584 node.child.return = node;
17585 node = node.child;
17586 continue;
17587 }
17588 if (node === finishedWork) {
17589 return;
17590 }
17591 while (node.sibling === null) {
17592 if (node.return === null || node.return === finishedWork) {
17593 return;
17594 }
17595 node = node.return;
17596 }
17597 node.sibling.return = node.return;
17598 node = node.sibling;
17599 }
17600}
17601
17602function unmountHostComponents(current$$1) {
17603 // We only have the top Fiber that was deleted but we need to recurse down its
17604 var node = current$$1;
17605
17606 // Each iteration, currentParent is populated with node's host parent if not
17607 // currentParentIsValid.
17608 var currentParentIsValid = false;
17609
17610 // Note: these two variables *must* always be updated together.
17611 var currentParent = void 0;
17612 var currentParentIsContainer = void 0;
17613
17614 while (true) {
17615 if (!currentParentIsValid) {
17616 var parent = node.return;
17617 findParent: while (true) {
17618 !(parent !== null) ? invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.') : void 0;
17619 switch (parent.tag) {
17620 case HostComponent:
17621 currentParent = parent.stateNode;
17622 currentParentIsContainer = false;
17623 break findParent;
17624 case HostRoot:
17625 currentParent = parent.stateNode.containerInfo;
17626 currentParentIsContainer = true;
17627 break findParent;
17628 case HostPortal:
17629 currentParent = parent.stateNode.containerInfo;
17630 currentParentIsContainer = true;
17631 break findParent;
17632 }
17633 parent = parent.return;
17634 }
17635 currentParentIsValid = true;
17636 }
17637
17638 if (node.tag === HostComponent || node.tag === HostText) {
17639 commitNestedUnmounts(node);
17640 // After all the children have unmounted, it is now safe to remove the
17641 // node from the tree.
17642 if (currentParentIsContainer) {
17643 removeChildFromContainer(currentParent, node.stateNode);
17644 } else {
17645 removeChild(currentParent, node.stateNode);
17646 }
17647 // Don't visit children because we already visited them.
17648 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
17649 // Delete the dehydrated suspense boundary and all of its content.
17650 if (currentParentIsContainer) {
17651 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
17652 } else {
17653 clearSuspenseBoundary(currentParent, node.stateNode);
17654 }
17655 } else if (node.tag === HostPortal) {
17656 if (node.child !== null) {
17657 // When we go into a portal, it becomes the parent to remove from.
17658 // We will reassign it back when we pop the portal on the way up.
17659 currentParent = node.stateNode.containerInfo;
17660 currentParentIsContainer = true;
17661 // Visit children because portals might contain host components.
17662 node.child.return = node;
17663 node = node.child;
17664 continue;
17665 }
17666 } else {
17667 commitUnmount(node);
17668 // Visit children because we may find more host components below.
17669 if (node.child !== null) {
17670 node.child.return = node;
17671 node = node.child;
17672 continue;
17673 }
17674 }
17675 if (node === current$$1) {
17676 return;
17677 }
17678 while (node.sibling === null) {
17679 if (node.return === null || node.return === current$$1) {
17680 return;
17681 }
17682 node = node.return;
17683 if (node.tag === HostPortal) {
17684 // When we go out of the portal, we need to restore the parent.
17685 // Since we don't keep a stack of them, we will search for it.
17686 currentParentIsValid = false;
17687 }
17688 }
17689 node.sibling.return = node.return;
17690 node = node.sibling;
17691 }
17692}
17693
17694function commitDeletion(current$$1) {
17695 if (supportsMutation) {
17696 // Recursively delete all host nodes from the parent.
17697 // Detach refs and call componentWillUnmount() on the whole subtree.
17698 unmountHostComponents(current$$1);
17699 } else {
17700 // Detach refs and call componentWillUnmount() on the whole subtree.
17701 commitNestedUnmounts(current$$1);
17702 }
17703 detachFiber(current$$1);
17704}
17705
17706function commitWork(current$$1, finishedWork) {
17707 if (!supportsMutation) {
17708 switch (finishedWork.tag) {
17709 case FunctionComponent:
17710 case ForwardRef:
17711 case MemoComponent:
17712 case SimpleMemoComponent:
17713 {
17714 // Note: We currently never use MountMutation, but useLayout uses
17715 // UnmountMutation.
17716 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17717 return;
17718 }
17719 }
17720
17721 commitContainer(finishedWork);
17722 return;
17723 }
17724
17725 switch (finishedWork.tag) {
17726 case FunctionComponent:
17727 case ForwardRef:
17728 case MemoComponent:
17729 case SimpleMemoComponent:
17730 {
17731 // Note: We currently never use MountMutation, but useLayout uses
17732 // UnmountMutation.
17733 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17734 return;
17735 }
17736 case ClassComponent:
17737 {
17738 return;
17739 }
17740 case HostComponent:
17741 {
17742 var instance = finishedWork.stateNode;
17743 if (instance != null) {
17744 // Commit the work prepared earlier.
17745 var newProps = finishedWork.memoizedProps;
17746 // For hydration we reuse the update path but we treat the oldProps
17747 // as the newProps. The updatePayload will contain the real change in
17748 // this case.
17749 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
17750 var type = finishedWork.type;
17751 // TODO: Type the updateQueue to be specific to host components.
17752 var updatePayload = finishedWork.updateQueue;
17753 finishedWork.updateQueue = null;
17754 if (updatePayload !== null) {
17755 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
17756 }
17757 }
17758 return;
17759 }
17760 case HostText:
17761 {
17762 !(finishedWork.stateNode !== null) ? invariant(false, 'This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.') : void 0;
17763 var textInstance = finishedWork.stateNode;
17764 var newText = finishedWork.memoizedProps;
17765 // For hydration we reuse the update path but we treat the oldProps
17766 // as the newProps. The updatePayload will contain the real change in
17767 // this case.
17768 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
17769 commitTextUpdate(textInstance, oldText, newText);
17770 return;
17771 }
17772 case HostRoot:
17773 {
17774 return;
17775 }
17776 case Profiler:
17777 {
17778 return;
17779 }
17780 case SuspenseComponent:
17781 {
17782 var newState = finishedWork.memoizedState;
17783
17784 var newDidTimeout = void 0;
17785 var primaryChildParent = finishedWork;
17786 if (newState === null) {
17787 newDidTimeout = false;
17788 } else {
17789 newDidTimeout = true;
17790 primaryChildParent = finishedWork.child;
17791 if (newState.timedOutAt === NoWork) {
17792 // If the children had not already timed out, record the time.
17793 // This is used to compute the elapsed time during subsequent
17794 // attempts to render the children.
17795 newState.timedOutAt = requestCurrentTime();
17796 }
17797 }
17798
17799 if (primaryChildParent !== null) {
17800 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
17801 }
17802
17803 // If this boundary just timed out, then it will have a set of thenables.
17804 // For each thenable, attach a listener so that when it resolves, React
17805 // attempts to re-render the boundary in the primary (pre-timeout) state.
17806 var thenables = finishedWork.updateQueue;
17807 if (thenables !== null) {
17808 finishedWork.updateQueue = null;
17809 var retryCache = finishedWork.stateNode;
17810 if (retryCache === null) {
17811 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
17812 }
17813 thenables.forEach(function (thenable) {
17814 // Memoize using the boundary fiber to prevent redundant listeners.
17815 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
17816 if (enableSchedulerTracing) {
17817 retry = tracing.unstable_wrap(retry);
17818 }
17819 if (!retryCache.has(thenable)) {
17820 retryCache.add(thenable);
17821 thenable.then(retry, retry);
17822 }
17823 });
17824 }
17825
17826 return;
17827 }
17828 case IncompleteClassComponent:
17829 {
17830 return;
17831 }
17832 default:
17833 {
17834 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
17835 }
17836 }
17837}
17838
17839function commitResetTextContent(current$$1) {
17840 if (!supportsMutation) {
17841 return;
17842 }
17843 resetTextContent(current$$1.stateNode);
17844}
17845
17846var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
17847var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
17848
17849function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
17850 var update = createUpdate(expirationTime);
17851 // Unmount the root by rendering null.
17852 update.tag = CaptureUpdate;
17853 // Caution: React DevTools currently depends on this property
17854 // being called "element".
17855 update.payload = { element: null };
17856 var error = errorInfo.value;
17857 update.callback = function () {
17858 onUncaughtError(error);
17859 logError(fiber, errorInfo);
17860 };
17861 return update;
17862}
17863
17864function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
17865 var update = createUpdate(expirationTime);
17866 update.tag = CaptureUpdate;
17867 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
17868 if (typeof getDerivedStateFromError === 'function') {
17869 var error = errorInfo.value;
17870 update.payload = function () {
17871 return getDerivedStateFromError(error);
17872 };
17873 }
17874
17875 var inst = fiber.stateNode;
17876 if (inst !== null && typeof inst.componentDidCatch === 'function') {
17877 update.callback = function callback() {
17878 if (typeof getDerivedStateFromError !== 'function') {
17879 // To preserve the preexisting retry behavior of error boundaries,
17880 // we keep track of which ones already failed during this batch.
17881 // This gets reset before we yield back to the browser.
17882 // TODO: Warn in strict mode if getDerivedStateFromError is
17883 // not defined.
17884 markLegacyErrorBoundaryAsFailed(this);
17885 }
17886 var error = errorInfo.value;
17887 var stack = errorInfo.stack;
17888 logError(fiber, errorInfo);
17889 this.componentDidCatch(error, {
17890 componentStack: stack !== null ? stack : ''
17891 });
17892 {
17893 if (typeof getDerivedStateFromError !== 'function') {
17894 // If componentDidCatch is the only error boundary method defined,
17895 // then it needs to call setState to recover from errors.
17896 // If no state update is scheduled then the boundary will swallow the error.
17897 !(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;
17898 }
17899 }
17900 };
17901 }
17902 return update;
17903}
17904
17905function attachPingListener(root, renderExpirationTime, thenable) {
17906 // Attach a listener to the promise to "ping" the root and retry. But
17907 // only if one does not already exist for the current render expiration
17908 // time (which acts like a "thread ID" here).
17909 var pingCache = root.pingCache;
17910 var threadIDs = void 0;
17911 if (pingCache === null) {
17912 pingCache = root.pingCache = new PossiblyWeakMap();
17913 threadIDs = new Set();
17914 pingCache.set(thenable, threadIDs);
17915 } else {
17916 threadIDs = pingCache.get(thenable);
17917 if (threadIDs === undefined) {
17918 threadIDs = new Set();
17919 pingCache.set(thenable, threadIDs);
17920 }
17921 }
17922 if (!threadIDs.has(renderExpirationTime)) {
17923 // Memoize using the thread ID to prevent redundant listeners.
17924 threadIDs.add(renderExpirationTime);
17925 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
17926 if (enableSchedulerTracing) {
17927 ping = tracing.unstable_wrap(ping);
17928 }
17929 thenable.then(ping, ping);
17930 }
17931}
17932
17933function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
17934 // The source fiber did not complete.
17935 sourceFiber.effectTag |= Incomplete;
17936 // Its effect list is no longer valid.
17937 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
17938
17939 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
17940 // This is a thenable.
17941 var thenable = value;
17942
17943 // Find the earliest timeout threshold of all the placeholders in the
17944 // ancestor path. We could avoid this traversal by storing the thresholds on
17945 // the stack, but we choose not to because we only hit this path if we're
17946 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
17947 // the non-IO- bound case.
17948 var _workInProgress = returnFiber;
17949 var earliestTimeoutMs = -1;
17950 var startTimeMs = -1;
17951 do {
17952 if (_workInProgress.tag === SuspenseComponent) {
17953 var current$$1 = _workInProgress.alternate;
17954 if (current$$1 !== null) {
17955 var currentState = current$$1.memoizedState;
17956 if (currentState !== null) {
17957 // Reached a boundary that already timed out. Do not search
17958 // any further.
17959 var timedOutAt = currentState.timedOutAt;
17960 startTimeMs = expirationTimeToMs(timedOutAt);
17961 // Do not search any further.
17962 break;
17963 }
17964 }
17965 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
17966 if (typeof timeoutPropMs === 'number') {
17967 if (timeoutPropMs <= 0) {
17968 earliestTimeoutMs = 0;
17969 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
17970 earliestTimeoutMs = timeoutPropMs;
17971 }
17972 }
17973 }
17974 // If there is a DehydratedSuspenseComponent we don't have to do anything because
17975 // if something suspends inside it, we will simply leave that as dehydrated. It
17976 // will never timeout.
17977 _workInProgress = _workInProgress.return;
17978 } while (_workInProgress !== null);
17979
17980 // Schedule the nearest Suspense to re-render the timed out view.
17981 _workInProgress = returnFiber;
17982 do {
17983 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
17984 // Found the nearest boundary.
17985
17986 // Stash the promise on the boundary fiber. If the boundary times out, we'll
17987 var thenables = _workInProgress.updateQueue;
17988 if (thenables === null) {
17989 var updateQueue = new Set();
17990 updateQueue.add(thenable);
17991 _workInProgress.updateQueue = updateQueue;
17992 } else {
17993 thenables.add(thenable);
17994 }
17995
17996 // If the boundary is outside of concurrent mode, we should *not*
17997 // suspend the commit. Pretend as if the suspended component rendered
17998 // null and keep rendering. In the commit phase, we'll schedule a
17999 // subsequent synchronous update to re-render the Suspense.
18000 //
18001 // Note: It doesn't matter whether the component that suspended was
18002 // inside a concurrent mode tree. If the Suspense is outside of it, we
18003 // should *not* suspend the commit.
18004 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
18005 _workInProgress.effectTag |= DidCapture;
18006
18007 // We're going to commit this fiber even though it didn't complete.
18008 // But we shouldn't call any lifecycle methods or callbacks. Remove
18009 // all lifecycle effect tags.
18010 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
18011
18012 if (sourceFiber.tag === ClassComponent) {
18013 var currentSourceFiber = sourceFiber.alternate;
18014 if (currentSourceFiber === null) {
18015 // This is a new mount. Change the tag so it's not mistaken for a
18016 // completed class component. For example, we should not call
18017 // componentWillUnmount if it is deleted.
18018 sourceFiber.tag = IncompleteClassComponent;
18019 } else {
18020 // When we try rendering again, we should not reuse the current fiber,
18021 // since it's known to be in an inconsistent state. Use a force updte to
18022 // prevent a bail out.
18023 var update = createUpdate(Sync);
18024 update.tag = ForceUpdate;
18025 enqueueUpdate(sourceFiber, update);
18026 }
18027 }
18028
18029 // The source fiber did not complete. Mark it with Sync priority to
18030 // indicate that it still has pending work.
18031 sourceFiber.expirationTime = Sync;
18032
18033 // Exit without suspending.
18034 return;
18035 }
18036
18037 // Confirmed that the boundary is in a concurrent mode tree. Continue
18038 // with the normal suspend path.
18039
18040 attachPingListener(root, renderExpirationTime, thenable);
18041
18042 var absoluteTimeoutMs = void 0;
18043 if (earliestTimeoutMs === -1) {
18044 // If no explicit threshold is given, default to an arbitrarily large
18045 // value. The actual size doesn't matter because the threshold for the
18046 // whole tree will be clamped to the expiration time.
18047 absoluteTimeoutMs = maxSigned31BitInt;
18048 } else {
18049 if (startTimeMs === -1) {
18050 // This suspend happened outside of any already timed-out
18051 // placeholders. We don't know exactly when the update was
18052 // scheduled, but we can infer an approximate start time from the
18053 // expiration time. First, find the earliest uncommitted expiration
18054 // time in the tree, including work that is suspended. Then subtract
18055 // the offset used to compute an async update's expiration time.
18056 // This will cause high priority (interactive) work to expire
18057 // earlier than necessary, but we can account for this by adjusting
18058 // for the Just Noticeable Difference.
18059 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
18060 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
18061 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
18062 }
18063 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
18064 }
18065
18066 // Mark the earliest timeout in the suspended fiber's ancestor path.
18067 // After completing the root, we'll take the largest of all the
18068 // suspended fiber's timeouts and use it to compute a timeout for the
18069 // whole tree.
18070 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
18071
18072 _workInProgress.effectTag |= ShouldCapture;
18073 _workInProgress.expirationTime = renderExpirationTime;
18074 return;
18075 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
18076 attachPingListener(root, renderExpirationTime, thenable);
18077
18078 // Since we already have a current fiber, we can eagerly add a retry listener.
18079 var retryCache = _workInProgress.memoizedState;
18080 if (retryCache === null) {
18081 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
18082 var _current = _workInProgress.alternate;
18083 !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
18084 _current.memoizedState = retryCache;
18085 }
18086 // Memoize using the boundary fiber to prevent redundant listeners.
18087 if (!retryCache.has(thenable)) {
18088 retryCache.add(thenable);
18089 var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
18090 if (enableSchedulerTracing) {
18091 retry = tracing.unstable_wrap(retry);
18092 }
18093 thenable.then(retry, retry);
18094 }
18095 _workInProgress.effectTag |= ShouldCapture;
18096 _workInProgress.expirationTime = renderExpirationTime;
18097 return;
18098 }
18099 // This boundary already captured during this render. Continue to the next
18100 // boundary.
18101 _workInProgress = _workInProgress.return;
18102 } while (_workInProgress !== null);
18103 // No boundary was found. Fallthrough to error mode.
18104 // TODO: Use invariant so the message is stripped in prod?
18105 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));
18106 }
18107
18108 // We didn't find a boundary that could handle this type of exception. Start
18109 // over and traverse parent path again, this time treating the exception
18110 // as an error.
18111 renderDidError();
18112 value = createCapturedValue(value, sourceFiber);
18113 var workInProgress = returnFiber;
18114 do {
18115 switch (workInProgress.tag) {
18116 case HostRoot:
18117 {
18118 var _errorInfo = value;
18119 workInProgress.effectTag |= ShouldCapture;
18120 workInProgress.expirationTime = renderExpirationTime;
18121 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
18122 enqueueCapturedUpdate(workInProgress, _update);
18123 return;
18124 }
18125 case ClassComponent:
18126 // Capture and retry
18127 var errorInfo = value;
18128 var ctor = workInProgress.type;
18129 var instance = workInProgress.stateNode;
18130 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
18131 workInProgress.effectTag |= ShouldCapture;
18132 workInProgress.expirationTime = renderExpirationTime;
18133 // Schedule the error boundary to re-render using updated state
18134 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
18135 enqueueCapturedUpdate(workInProgress, _update2);
18136 return;
18137 }
18138 break;
18139 default:
18140 break;
18141 }
18142 workInProgress = workInProgress.return;
18143 } while (workInProgress !== null);
18144}
18145
18146function unwindWork(workInProgress, renderExpirationTime) {
18147 switch (workInProgress.tag) {
18148 case ClassComponent:
18149 {
18150 var Component = workInProgress.type;
18151 if (isContextProvider(Component)) {
18152 popContext(workInProgress);
18153 }
18154 var effectTag = workInProgress.effectTag;
18155 if (effectTag & ShouldCapture) {
18156 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
18157 return workInProgress;
18158 }
18159 return null;
18160 }
18161 case HostRoot:
18162 {
18163 popHostContainer(workInProgress);
18164 popTopLevelContextObject(workInProgress);
18165 var _effectTag = workInProgress.effectTag;
18166 !((_effectTag & DidCapture) === NoEffect) ? invariant(false, 'The root failed to unmount after an error. This is likely a bug in React. Please file an issue.') : void 0;
18167 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
18168 return workInProgress;
18169 }
18170 case HostComponent:
18171 {
18172 // TODO: popHydrationState
18173 popHostContext(workInProgress);
18174 return null;
18175 }
18176 case SuspenseComponent:
18177 {
18178 var _effectTag2 = workInProgress.effectTag;
18179 if (_effectTag2 & ShouldCapture) {
18180 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
18181 // Captured a suspense effect. Re-render the boundary.
18182 return workInProgress;
18183 }
18184 return null;
18185 }
18186 case DehydratedSuspenseComponent:
18187 {
18188 if (enableSuspenseServerRenderer) {
18189 // TODO: popHydrationState
18190 var _effectTag3 = workInProgress.effectTag;
18191 if (_effectTag3 & ShouldCapture) {
18192 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
18193 // Captured a suspense effect. Re-render the boundary.
18194 return workInProgress;
18195 }
18196 }
18197 return null;
18198 }
18199 case HostPortal:
18200 popHostContainer(workInProgress);
18201 return null;
18202 case ContextProvider:
18203 popProvider(workInProgress);
18204 return null;
18205 default:
18206 return null;
18207 }
18208}
18209
18210function unwindInterruptedWork(interruptedWork) {
18211 switch (interruptedWork.tag) {
18212 case ClassComponent:
18213 {
18214 var childContextTypes = interruptedWork.type.childContextTypes;
18215 if (childContextTypes !== null && childContextTypes !== undefined) {
18216 popContext(interruptedWork);
18217 }
18218 break;
18219 }
18220 case HostRoot:
18221 {
18222 popHostContainer(interruptedWork);
18223 popTopLevelContextObject(interruptedWork);
18224 break;
18225 }
18226 case HostComponent:
18227 {
18228 popHostContext(interruptedWork);
18229 break;
18230 }
18231 case HostPortal:
18232 popHostContainer(interruptedWork);
18233 break;
18234 case ContextProvider:
18235 popProvider(interruptedWork);
18236 break;
18237 default:
18238 break;
18239 }
18240}
18241
18242var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
18243var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
18244
18245
18246var didWarnAboutStateTransition = void 0;
18247var didWarnSetStateChildContext = void 0;
18248var warnAboutUpdateOnUnmounted = void 0;
18249var warnAboutInvalidUpdates = void 0;
18250
18251if (enableSchedulerTracing) {
18252 // Provide explicit error message when production+profiling bundle of e.g. react-dom
18253 // is used with production (non-profiling) bundle of scheduler/tracing
18254 !(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null) ? invariant(false, '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') : void 0;
18255}
18256
18257{
18258 didWarnAboutStateTransition = false;
18259 didWarnSetStateChildContext = false;
18260 var didWarnStateUpdateForUnmountedComponent = {};
18261
18262 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
18263 // We show the whole stack but dedupe on the top component's name because
18264 // the problematic code almost always lies inside that component.
18265 var componentName = getComponentName(fiber.type) || 'ReactComponent';
18266 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
18267 return;
18268 }
18269 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', isClass ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
18270 didWarnStateUpdateForUnmountedComponent[componentName] = true;
18271 };
18272
18273 warnAboutInvalidUpdates = function (instance) {
18274 switch (phase) {
18275 case 'getChildContext':
18276 if (didWarnSetStateChildContext) {
18277 return;
18278 }
18279 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
18280 didWarnSetStateChildContext = true;
18281 break;
18282 case 'render':
18283 if (didWarnAboutStateTransition) {
18284 return;
18285 }
18286 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.');
18287 didWarnAboutStateTransition = true;
18288 break;
18289 }
18290 };
18291}
18292
18293// Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
18294var lastUniqueAsyncExpiration = Sync - 1;
18295
18296var isWorking = false;
18297
18298// The next work in progress fiber that we're currently working on.
18299var nextUnitOfWork = null;
18300var nextRoot = null;
18301// The time at which we're currently rendering work.
18302var nextRenderExpirationTime = NoWork;
18303var nextLatestAbsoluteTimeoutMs = -1;
18304var nextRenderDidError = false;
18305
18306// The next fiber with an effect that we're currently committing.
18307var nextEffect = null;
18308
18309var isCommitting$1 = false;
18310var rootWithPendingPassiveEffects = null;
18311var passiveEffectCallbackHandle = null;
18312var passiveEffectCallback = null;
18313
18314var legacyErrorBoundariesThatAlreadyFailed = null;
18315
18316// Used for performance tracking.
18317var interruptedBy = null;
18318
18319var stashedWorkInProgressProperties = void 0;
18320var replayUnitOfWork = void 0;
18321var mayReplayFailedUnitOfWork = void 0;
18322var isReplayingFailedUnitOfWork = void 0;
18323var originalReplayError = void 0;
18324var rethrowOriginalError = void 0;
18325if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18326 stashedWorkInProgressProperties = null;
18327 mayReplayFailedUnitOfWork = true;
18328 isReplayingFailedUnitOfWork = false;
18329 originalReplayError = null;
18330 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
18331 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
18332 // Don't replay promises. Treat everything else like an error.
18333 // TODO: Need to figure out a different strategy if/when we add
18334 // support for catching other types.
18335 return;
18336 }
18337
18338 // Restore the original state of the work-in-progress
18339 if (stashedWorkInProgressProperties === null) {
18340 // This should never happen. Don't throw because this code is DEV-only.
18341 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
18342 return;
18343 }
18344 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
18345
18346 switch (failedUnitOfWork.tag) {
18347 case HostRoot:
18348 popHostContainer(failedUnitOfWork);
18349 popTopLevelContextObject(failedUnitOfWork);
18350 break;
18351 case HostComponent:
18352 popHostContext(failedUnitOfWork);
18353 break;
18354 case ClassComponent:
18355 {
18356 var Component = failedUnitOfWork.type;
18357 if (isContextProvider(Component)) {
18358 popContext(failedUnitOfWork);
18359 }
18360 break;
18361 }
18362 case HostPortal:
18363 popHostContainer(failedUnitOfWork);
18364 break;
18365 case ContextProvider:
18366 popProvider(failedUnitOfWork);
18367 break;
18368 }
18369 // Replay the begin phase.
18370 isReplayingFailedUnitOfWork = true;
18371 originalReplayError = thrownValue;
18372 invokeGuardedCallback(null, workLoop, null, isYieldy);
18373 isReplayingFailedUnitOfWork = false;
18374 originalReplayError = null;
18375 if (hasCaughtError()) {
18376 var replayError = clearCaughtError();
18377 if (replayError != null && thrownValue != null) {
18378 try {
18379 // Reading the expando property is intentionally
18380 // inside `try` because it might be a getter or Proxy.
18381 if (replayError._suppressLogging) {
18382 // Also suppress logging for the original error.
18383 thrownValue._suppressLogging = true;
18384 }
18385 } catch (inner) {
18386 // Ignore.
18387 }
18388 }
18389 } else {
18390 // If the begin phase did not fail the second time, set this pointer
18391 // back to the original value.
18392 nextUnitOfWork = failedUnitOfWork;
18393 }
18394 };
18395 rethrowOriginalError = function () {
18396 throw originalReplayError;
18397 };
18398}
18399
18400function resetStack() {
18401 if (nextUnitOfWork !== null) {
18402 var interruptedWork = nextUnitOfWork.return;
18403 while (interruptedWork !== null) {
18404 unwindInterruptedWork(interruptedWork);
18405 interruptedWork = interruptedWork.return;
18406 }
18407 }
18408
18409 {
18410 ReactStrictModeWarnings.discardPendingWarnings();
18411 checkThatStackIsEmpty();
18412 }
18413
18414 nextRoot = null;
18415 nextRenderExpirationTime = NoWork;
18416 nextLatestAbsoluteTimeoutMs = -1;
18417 nextRenderDidError = false;
18418 nextUnitOfWork = null;
18419}
18420
18421function commitAllHostEffects() {
18422 while (nextEffect !== null) {
18423 {
18424 setCurrentFiber(nextEffect);
18425 }
18426 recordEffect();
18427
18428 var effectTag = nextEffect.effectTag;
18429
18430 if (effectTag & ContentReset) {
18431 commitResetTextContent(nextEffect);
18432 }
18433
18434 if (effectTag & Ref) {
18435 var current$$1 = nextEffect.alternate;
18436 if (current$$1 !== null) {
18437 commitDetachRef(current$$1);
18438 }
18439 }
18440
18441 // The following switch statement is only concerned about placement,
18442 // updates, and deletions. To avoid needing to add a case for every
18443 // possible bitmap value, we remove the secondary effects from the
18444 // effect tag and switch on that value.
18445 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
18446 switch (primaryEffectTag) {
18447 case Placement:
18448 {
18449 commitPlacement(nextEffect);
18450 // Clear the "placement" from effect tag so that we know that this is inserted, before
18451 // any life-cycles like componentDidMount gets called.
18452 // TODO: findDOMNode doesn't rely on this any more but isMounted
18453 // does and isMounted is deprecated anyway so we should be able
18454 // to kill this.
18455 nextEffect.effectTag &= ~Placement;
18456 break;
18457 }
18458 case PlacementAndUpdate:
18459 {
18460 // Placement
18461 commitPlacement(nextEffect);
18462 // Clear the "placement" from effect tag so that we know that this is inserted, before
18463 // any life-cycles like componentDidMount gets called.
18464 nextEffect.effectTag &= ~Placement;
18465
18466 // Update
18467 var _current = nextEffect.alternate;
18468 commitWork(_current, nextEffect);
18469 break;
18470 }
18471 case Update:
18472 {
18473 var _current2 = nextEffect.alternate;
18474 commitWork(_current2, nextEffect);
18475 break;
18476 }
18477 case Deletion:
18478 {
18479 commitDeletion(nextEffect);
18480 break;
18481 }
18482 }
18483 nextEffect = nextEffect.nextEffect;
18484 }
18485
18486 {
18487 resetCurrentFiber();
18488 }
18489}
18490
18491function commitBeforeMutationLifecycles() {
18492 while (nextEffect !== null) {
18493 {
18494 setCurrentFiber(nextEffect);
18495 }
18496
18497 var effectTag = nextEffect.effectTag;
18498 if (effectTag & Snapshot) {
18499 recordEffect();
18500 var current$$1 = nextEffect.alternate;
18501 commitBeforeMutationLifeCycles(current$$1, nextEffect);
18502 }
18503
18504 nextEffect = nextEffect.nextEffect;
18505 }
18506
18507 {
18508 resetCurrentFiber();
18509 }
18510}
18511
18512function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
18513 {
18514 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
18515 ReactStrictModeWarnings.flushLegacyContextWarning();
18516
18517 if (warnAboutDeprecatedLifecycles) {
18518 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
18519 }
18520 }
18521 while (nextEffect !== null) {
18522 {
18523 setCurrentFiber(nextEffect);
18524 }
18525 var effectTag = nextEffect.effectTag;
18526
18527 if (effectTag & (Update | Callback)) {
18528 recordEffect();
18529 var current$$1 = nextEffect.alternate;
18530 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime);
18531 }
18532
18533 if (effectTag & Ref) {
18534 recordEffect();
18535 commitAttachRef(nextEffect);
18536 }
18537
18538 if (effectTag & Passive) {
18539 rootWithPendingPassiveEffects = finishedRoot;
18540 }
18541
18542 nextEffect = nextEffect.nextEffect;
18543 }
18544 {
18545 resetCurrentFiber();
18546 }
18547}
18548
18549function commitPassiveEffects(root, firstEffect) {
18550 rootWithPendingPassiveEffects = null;
18551 passiveEffectCallbackHandle = null;
18552 passiveEffectCallback = null;
18553
18554 // Set this to true to prevent re-entrancy
18555 var previousIsRendering = isRendering;
18556 isRendering = true;
18557
18558 var effect = firstEffect;
18559 do {
18560 {
18561 setCurrentFiber(effect);
18562 }
18563
18564 if (effect.effectTag & Passive) {
18565 var didError = false;
18566 var error = void 0;
18567 {
18568 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
18569 if (hasCaughtError()) {
18570 didError = true;
18571 error = clearCaughtError();
18572 }
18573 }
18574 if (didError) {
18575 captureCommitPhaseError(effect, error);
18576 }
18577 }
18578 effect = effect.nextEffect;
18579 } while (effect !== null);
18580 {
18581 resetCurrentFiber();
18582 }
18583
18584 isRendering = previousIsRendering;
18585
18586 // Check if work was scheduled by one of the effects
18587 var rootExpirationTime = root.expirationTime;
18588 if (rootExpirationTime !== NoWork) {
18589 requestWork(root, rootExpirationTime);
18590 }
18591 // Flush any sync work that was scheduled by effects
18592 if (!isBatchingUpdates && !isRendering) {
18593 performSyncWork();
18594 }
18595}
18596
18597function isAlreadyFailedLegacyErrorBoundary(instance) {
18598 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
18599}
18600
18601function markLegacyErrorBoundaryAsFailed(instance) {
18602 if (legacyErrorBoundariesThatAlreadyFailed === null) {
18603 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
18604 } else {
18605 legacyErrorBoundariesThatAlreadyFailed.add(instance);
18606 }
18607}
18608
18609function flushPassiveEffects() {
18610 if (passiveEffectCallbackHandle !== null) {
18611 cancelPassiveEffects(passiveEffectCallbackHandle);
18612 }
18613 if (passiveEffectCallback !== null) {
18614 // We call the scheduled callback instead of commitPassiveEffects directly
18615 // to ensure tracing works correctly.
18616 passiveEffectCallback();
18617 }
18618}
18619
18620function commitRoot(root, finishedWork) {
18621 isWorking = true;
18622 isCommitting$1 = true;
18623 startCommitTimer();
18624
18625 !(root.current !== finishedWork) ? invariant(false, 'Cannot commit the same tree as before. This is probably a bug related to the return field. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18626 var committedExpirationTime = root.pendingCommitExpirationTime;
18627 !(committedExpirationTime !== NoWork) ? invariant(false, 'Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18628 root.pendingCommitExpirationTime = NoWork;
18629
18630 // Update the pending priority levels to account for the work that we are
18631 // about to commit. This needs to happen before calling the lifecycles, since
18632 // they may schedule additional updates.
18633 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
18634 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
18635 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
18636 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
18637
18638 var prevInteractions = null;
18639 if (enableSchedulerTracing) {
18640 // Restore any pending interactions at this point,
18641 // So that cascading work triggered during the render phase will be accounted for.
18642 prevInteractions = tracing.__interactionsRef.current;
18643 tracing.__interactionsRef.current = root.memoizedInteractions;
18644 }
18645
18646 // Reset this to null before calling lifecycles
18647 ReactCurrentOwner$2.current = null;
18648
18649 var firstEffect = void 0;
18650 if (finishedWork.effectTag > PerformedWork) {
18651 // A fiber's effect list consists only of its children, not itself. So if
18652 // the root has an effect, we need to add it to the end of the list. The
18653 // resulting list is the set that would belong to the root's parent, if
18654 // it had one; that is, all the effects in the tree including the root.
18655 if (finishedWork.lastEffect !== null) {
18656 finishedWork.lastEffect.nextEffect = finishedWork;
18657 firstEffect = finishedWork.firstEffect;
18658 } else {
18659 firstEffect = finishedWork;
18660 }
18661 } else {
18662 // There is no effect on the root.
18663 firstEffect = finishedWork.firstEffect;
18664 }
18665
18666 prepareForCommit(root.containerInfo);
18667
18668 // Invoke instances of getSnapshotBeforeUpdate before mutation.
18669 nextEffect = firstEffect;
18670 startCommitSnapshotEffectsTimer();
18671 while (nextEffect !== null) {
18672 var didError = false;
18673 var error = void 0;
18674 {
18675 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
18676 if (hasCaughtError()) {
18677 didError = true;
18678 error = clearCaughtError();
18679 }
18680 }
18681 if (didError) {
18682 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18683 captureCommitPhaseError(nextEffect, error);
18684 // Clean-up
18685 if (nextEffect !== null) {
18686 nextEffect = nextEffect.nextEffect;
18687 }
18688 }
18689 }
18690 stopCommitSnapshotEffectsTimer();
18691
18692 if (enableProfilerTimer) {
18693 // Mark the current commit time to be shared by all Profilers in this batch.
18694 // This enables them to be grouped later.
18695 recordCommitTime();
18696 }
18697
18698 // Commit all the side-effects within a tree. We'll do this in two passes.
18699 // The first pass performs all the host insertions, updates, deletions and
18700 // ref unmounts.
18701 nextEffect = firstEffect;
18702 startCommitHostEffectsTimer();
18703 while (nextEffect !== null) {
18704 var _didError = false;
18705 var _error = void 0;
18706 {
18707 invokeGuardedCallback(null, commitAllHostEffects, null);
18708 if (hasCaughtError()) {
18709 _didError = true;
18710 _error = clearCaughtError();
18711 }
18712 }
18713 if (_didError) {
18714 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18715 captureCommitPhaseError(nextEffect, _error);
18716 // Clean-up
18717 if (nextEffect !== null) {
18718 nextEffect = nextEffect.nextEffect;
18719 }
18720 }
18721 }
18722 stopCommitHostEffectsTimer();
18723
18724 resetAfterCommit(root.containerInfo);
18725
18726 // The work-in-progress tree is now the current tree. This must come after
18727 // the first pass of the commit phase, so that the previous tree is still
18728 // current during componentWillUnmount, but before the second pass, so that
18729 // the finished work is current during componentDidMount/Update.
18730 root.current = finishedWork;
18731
18732 // In the second pass we'll perform all life-cycles and ref callbacks.
18733 // Life-cycles happen as a separate pass so that all placements, updates,
18734 // and deletions in the entire tree have already been invoked.
18735 // This pass also triggers any renderer-specific initial effects.
18736 nextEffect = firstEffect;
18737 startCommitLifeCyclesTimer();
18738 while (nextEffect !== null) {
18739 var _didError2 = false;
18740 var _error2 = void 0;
18741 {
18742 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
18743 if (hasCaughtError()) {
18744 _didError2 = true;
18745 _error2 = clearCaughtError();
18746 }
18747 }
18748 if (_didError2) {
18749 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18750 captureCommitPhaseError(nextEffect, _error2);
18751 if (nextEffect !== null) {
18752 nextEffect = nextEffect.nextEffect;
18753 }
18754 }
18755 }
18756
18757 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
18758 // This commit included a passive effect. These do not need to fire until
18759 // after the next paint. Schedule an callback to fire them in an async
18760 // event. To ensure serial execution, the callback will be flushed early if
18761 // we enter rootWithPendingPassiveEffects commit phase before then.
18762 var callback = commitPassiveEffects.bind(null, root, firstEffect);
18763 if (enableSchedulerTracing) {
18764 // TODO: Avoid this extra callback by mutating the tracing ref directly,
18765 // like we do at the beginning of commitRoot. I've opted not to do that
18766 // here because that code is still in flux.
18767 callback = tracing.unstable_wrap(callback);
18768 }
18769 passiveEffectCallbackHandle = scheduler.unstable_runWithPriority(scheduler.unstable_NormalPriority, function () {
18770 return schedulePassiveEffects(callback);
18771 });
18772 passiveEffectCallback = callback;
18773 }
18774
18775 isCommitting$1 = false;
18776 isWorking = false;
18777 stopCommitLifeCyclesTimer();
18778 stopCommitTimer();
18779 onCommitRoot(finishedWork.stateNode);
18780 if (true && ReactFiberInstrumentation_1.debugTool) {
18781 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
18782 }
18783
18784 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
18785 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
18786 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
18787 if (earliestRemainingTimeAfterCommit === NoWork) {
18788 // If there's no remaining work, we can clear the set of already failed
18789 // error boundaries.
18790 legacyErrorBoundariesThatAlreadyFailed = null;
18791 }
18792 onCommit(root, earliestRemainingTimeAfterCommit);
18793
18794 if (enableSchedulerTracing) {
18795 tracing.__interactionsRef.current = prevInteractions;
18796
18797 var subscriber = void 0;
18798
18799 try {
18800 subscriber = tracing.__subscriberRef.current;
18801 if (subscriber !== null && root.memoizedInteractions.size > 0) {
18802 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
18803 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
18804 }
18805 } catch (error) {
18806 // It's not safe for commitRoot() to throw.
18807 // Store the error for now and we'll re-throw in finishRendering().
18808 if (!hasUnhandledError) {
18809 hasUnhandledError = true;
18810 unhandledError = error;
18811 }
18812 } finally {
18813 // Clear completed interactions from the pending Map.
18814 // Unless the render was suspended or cascading work was scheduled,
18815 // In which case– leave pending interactions until the subsequent render.
18816 var pendingInteractionMap = root.pendingInteractionMap;
18817 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
18818 // Only decrement the pending interaction count if we're done.
18819 // If there's still work at the current priority,
18820 // That indicates that we are waiting for suspense data.
18821 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
18822 pendingInteractionMap.delete(scheduledExpirationTime);
18823
18824 scheduledInteractions.forEach(function (interaction) {
18825 interaction.__count--;
18826
18827 if (subscriber !== null && interaction.__count === 0) {
18828 try {
18829 subscriber.onInteractionScheduledWorkCompleted(interaction);
18830 } catch (error) {
18831 // It's not safe for commitRoot() to throw.
18832 // Store the error for now and we'll re-throw in finishRendering().
18833 if (!hasUnhandledError) {
18834 hasUnhandledError = true;
18835 unhandledError = error;
18836 }
18837 }
18838 }
18839 });
18840 }
18841 });
18842 }
18843 }
18844}
18845
18846function resetChildExpirationTime(workInProgress, renderTime) {
18847 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
18848 // The children of this component are hidden. Don't bubble their
18849 // expiration times.
18850 return;
18851 }
18852
18853 var newChildExpirationTime = NoWork;
18854
18855 // Bubble up the earliest expiration time.
18856 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
18857 // We're in profiling mode.
18858 // Let's use this same traversal to update the render durations.
18859 var actualDuration = workInProgress.actualDuration;
18860 var treeBaseDuration = workInProgress.selfBaseDuration;
18861
18862 // When a fiber is cloned, its actualDuration is reset to 0.
18863 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
18864 // When work is done, it should bubble to the parent's actualDuration.
18865 // If the fiber has not been cloned though, (meaning no work was done),
18866 // Then this value will reflect the amount of time spent working on a previous render.
18867 // In that case it should not bubble.
18868 // We determine whether it was cloned by comparing the child pointer.
18869 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
18870
18871 var child = workInProgress.child;
18872 while (child !== null) {
18873 var childUpdateExpirationTime = child.expirationTime;
18874 var childChildExpirationTime = child.childExpirationTime;
18875 if (childUpdateExpirationTime > newChildExpirationTime) {
18876 newChildExpirationTime = childUpdateExpirationTime;
18877 }
18878 if (childChildExpirationTime > newChildExpirationTime) {
18879 newChildExpirationTime = childChildExpirationTime;
18880 }
18881 if (shouldBubbleActualDurations) {
18882 actualDuration += child.actualDuration;
18883 }
18884 treeBaseDuration += child.treeBaseDuration;
18885 child = child.sibling;
18886 }
18887 workInProgress.actualDuration = actualDuration;
18888 workInProgress.treeBaseDuration = treeBaseDuration;
18889 } else {
18890 var _child = workInProgress.child;
18891 while (_child !== null) {
18892 var _childUpdateExpirationTime = _child.expirationTime;
18893 var _childChildExpirationTime = _child.childExpirationTime;
18894 if (_childUpdateExpirationTime > newChildExpirationTime) {
18895 newChildExpirationTime = _childUpdateExpirationTime;
18896 }
18897 if (_childChildExpirationTime > newChildExpirationTime) {
18898 newChildExpirationTime = _childChildExpirationTime;
18899 }
18900 _child = _child.sibling;
18901 }
18902 }
18903
18904 workInProgress.childExpirationTime = newChildExpirationTime;
18905}
18906
18907function completeUnitOfWork(workInProgress) {
18908 // Attempt to complete the current unit of work, then move to the
18909 // next sibling. If there are no more siblings, return to the
18910 // parent fiber.
18911 while (true) {
18912 // The current, flushed, state of this fiber is the alternate.
18913 // Ideally nothing should rely on this, but relying on it here
18914 // means that we don't need an additional field on the work in
18915 // progress.
18916 var current$$1 = workInProgress.alternate;
18917 {
18918 setCurrentFiber(workInProgress);
18919 }
18920
18921 var returnFiber = workInProgress.return;
18922 var siblingFiber = workInProgress.sibling;
18923
18924 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
18925 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18926 // Don't replay if it fails during completion phase.
18927 mayReplayFailedUnitOfWork = false;
18928 }
18929 // This fiber completed.
18930 // Remember we're completing this unit so we can find a boundary if it fails.
18931 nextUnitOfWork = workInProgress;
18932 if (enableProfilerTimer) {
18933 if (workInProgress.mode & ProfileMode) {
18934 startProfilerTimer(workInProgress);
18935 }
18936 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18937 if (workInProgress.mode & ProfileMode) {
18938 // Update render duration assuming we didn't error.
18939 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
18940 }
18941 } else {
18942 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18943 }
18944 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18945 // We're out of completion phase so replaying is fine now.
18946 mayReplayFailedUnitOfWork = true;
18947 }
18948 stopWorkTimer(workInProgress);
18949 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
18950 {
18951 resetCurrentFiber();
18952 }
18953
18954 if (nextUnitOfWork !== null) {
18955 // Completing this fiber spawned new work. Work on that next.
18956 return nextUnitOfWork;
18957 }
18958
18959 if (returnFiber !== null &&
18960 // Do not append effects to parents if a sibling failed to complete
18961 (returnFiber.effectTag & Incomplete) === NoEffect) {
18962 // Append all the effects of the subtree and this fiber onto the effect
18963 // list of the parent. The completion order of the children affects the
18964 // side-effect order.
18965 if (returnFiber.firstEffect === null) {
18966 returnFiber.firstEffect = workInProgress.firstEffect;
18967 }
18968 if (workInProgress.lastEffect !== null) {
18969 if (returnFiber.lastEffect !== null) {
18970 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
18971 }
18972 returnFiber.lastEffect = workInProgress.lastEffect;
18973 }
18974
18975 // If this fiber had side-effects, we append it AFTER the children's
18976 // side-effects. We can perform certain side-effects earlier if
18977 // needed, by doing multiple passes over the effect list. We don't want
18978 // to schedule our own side-effect on our own list because if end up
18979 // reusing children we'll schedule this effect onto itself since we're
18980 // at the end.
18981 var effectTag = workInProgress.effectTag;
18982 // Skip both NoWork and PerformedWork tags when creating the effect list.
18983 // PerformedWork effect is read by React DevTools but shouldn't be committed.
18984 if (effectTag > PerformedWork) {
18985 if (returnFiber.lastEffect !== null) {
18986 returnFiber.lastEffect.nextEffect = workInProgress;
18987 } else {
18988 returnFiber.firstEffect = workInProgress;
18989 }
18990 returnFiber.lastEffect = workInProgress;
18991 }
18992 }
18993
18994 if (true && ReactFiberInstrumentation_1.debugTool) {
18995 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
18996 }
18997
18998 if (siblingFiber !== null) {
18999 // If there is more work to do in this returnFiber, do that next.
19000 return siblingFiber;
19001 } else if (returnFiber !== null) {
19002 // If there's no more work in this returnFiber. Complete the returnFiber.
19003 workInProgress = returnFiber;
19004 continue;
19005 } else {
19006 // We've reached the root.
19007 return null;
19008 }
19009 } else {
19010 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19011 // Record the render duration for the fiber that errored.
19012 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
19013
19014 // Include the time spent working on failed children before continuing.
19015 var actualDuration = workInProgress.actualDuration;
19016 var child = workInProgress.child;
19017 while (child !== null) {
19018 actualDuration += child.actualDuration;
19019 child = child.sibling;
19020 }
19021 workInProgress.actualDuration = actualDuration;
19022 }
19023
19024 // This fiber did not complete because something threw. Pop values off
19025 // the stack without entering the complete phase. If this is a boundary,
19026 // capture values if possible.
19027 var next = unwindWork(workInProgress, nextRenderExpirationTime);
19028 // Because this fiber did not complete, don't reset its expiration time.
19029 if (workInProgress.effectTag & DidCapture) {
19030 // Restarting an error boundary
19031 stopFailedWorkTimer(workInProgress);
19032 } else {
19033 stopWorkTimer(workInProgress);
19034 }
19035
19036 {
19037 resetCurrentFiber();
19038 }
19039
19040 if (next !== null) {
19041 stopWorkTimer(workInProgress);
19042 if (true && ReactFiberInstrumentation_1.debugTool) {
19043 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19044 }
19045
19046 // If completing this work spawned new work, do that next. We'll come
19047 // back here again.
19048 // Since we're restarting, remove anything that is not a host effect
19049 // from the effect tag.
19050 next.effectTag &= HostEffectMask;
19051 return next;
19052 }
19053
19054 if (returnFiber !== null) {
19055 // Mark the parent fiber as incomplete and clear its effect list.
19056 returnFiber.firstEffect = returnFiber.lastEffect = null;
19057 returnFiber.effectTag |= Incomplete;
19058 }
19059
19060 if (true && ReactFiberInstrumentation_1.debugTool) {
19061 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19062 }
19063
19064 if (siblingFiber !== null) {
19065 // If there is more work to do in this returnFiber, do that next.
19066 return siblingFiber;
19067 } else if (returnFiber !== null) {
19068 // If there's no more work in this returnFiber. Complete the returnFiber.
19069 workInProgress = returnFiber;
19070 continue;
19071 } else {
19072 return null;
19073 }
19074 }
19075 }
19076
19077 // Without this explicit null return Flow complains of invalid return type
19078 // TODO Remove the above while(true) loop
19079 // eslint-disable-next-line no-unreachable
19080 return null;
19081}
19082
19083function performUnitOfWork(workInProgress) {
19084 // The current, flushed, state of this fiber is the alternate.
19085 // Ideally nothing should rely on this, but relying on it here
19086 // means that we don't need an additional field on the work in
19087 // progress.
19088 var current$$1 = workInProgress.alternate;
19089
19090 // See if beginning this work spawns more work.
19091 startWorkTimer(workInProgress);
19092 {
19093 setCurrentFiber(workInProgress);
19094 }
19095
19096 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19097 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
19098 }
19099
19100 var next = void 0;
19101 if (enableProfilerTimer) {
19102 if (workInProgress.mode & ProfileMode) {
19103 startProfilerTimer(workInProgress);
19104 }
19105
19106 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
19107 workInProgress.memoizedProps = workInProgress.pendingProps;
19108
19109 if (workInProgress.mode & ProfileMode) {
19110 // Record the render duration assuming we didn't bailout (or error).
19111 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
19112 }
19113 } else {
19114 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
19115 workInProgress.memoizedProps = workInProgress.pendingProps;
19116 }
19117
19118 {
19119 resetCurrentFiber();
19120 if (isReplayingFailedUnitOfWork) {
19121 // Currently replaying a failed unit of work. This should be unreachable,
19122 // because the render phase is meant to be idempotent, and it should
19123 // have thrown again. Since it didn't, rethrow the original error, so
19124 // React's internal stack is not misaligned.
19125 rethrowOriginalError();
19126 }
19127 }
19128 if (true && ReactFiberInstrumentation_1.debugTool) {
19129 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
19130 }
19131
19132 if (next === null) {
19133 // If this doesn't spawn new work, complete the current work.
19134 next = completeUnitOfWork(workInProgress);
19135 }
19136
19137 ReactCurrentOwner$2.current = null;
19138
19139 return next;
19140}
19141
19142function workLoop(isYieldy) {
19143 if (!isYieldy) {
19144 // Flush work without yielding
19145 while (nextUnitOfWork !== null) {
19146 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
19147 }
19148 } else {
19149 // Flush asynchronous work until there's a higher priority event
19150 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
19151 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
19152 }
19153 }
19154}
19155
19156function renderRoot(root, isYieldy) {
19157 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19158
19159 flushPassiveEffects();
19160
19161 isWorking = true;
19162 var previousDispatcher = ReactCurrentDispatcher.current;
19163 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
19164
19165 var expirationTime = root.nextExpirationTimeToWorkOn;
19166
19167 // Check if we're starting from a fresh stack, or if we're resuming from
19168 // previously yielded work.
19169 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
19170 // Reset the stack and start working from the root.
19171 resetStack();
19172 nextRoot = root;
19173 nextRenderExpirationTime = expirationTime;
19174 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
19175 root.pendingCommitExpirationTime = NoWork;
19176
19177 if (enableSchedulerTracing) {
19178 // Determine which interactions this batch of work currently includes,
19179 // So that we can accurately attribute time spent working on it,
19180 var interactions = new Set();
19181 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
19182 if (scheduledExpirationTime >= expirationTime) {
19183 scheduledInteractions.forEach(function (interaction) {
19184 return interactions.add(interaction);
19185 });
19186 }
19187 });
19188
19189 // Store the current set of interactions on the FiberRoot for a few reasons:
19190 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
19191 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
19192 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
19193 root.memoizedInteractions = interactions;
19194
19195 if (interactions.size > 0) {
19196 var subscriber = tracing.__subscriberRef.current;
19197 if (subscriber !== null) {
19198 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19199 try {
19200 subscriber.onWorkStarted(interactions, threadID);
19201 } catch (error) {
19202 // Work thrown by an interaction tracing subscriber should be rethrown,
19203 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
19204 // Store the error for now and we'll re-throw in finishRendering().
19205 if (!hasUnhandledError) {
19206 hasUnhandledError = true;
19207 unhandledError = error;
19208 }
19209 }
19210 }
19211 }
19212 }
19213 }
19214
19215 var prevInteractions = null;
19216 if (enableSchedulerTracing) {
19217 // We're about to start new traced work.
19218 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
19219 prevInteractions = tracing.__interactionsRef.current;
19220 tracing.__interactionsRef.current = root.memoizedInteractions;
19221 }
19222
19223 var didFatal = false;
19224
19225 startWorkLoopTimer(nextUnitOfWork);
19226
19227 do {
19228 try {
19229 workLoop(isYieldy);
19230 } catch (thrownValue) {
19231 resetContextDependences();
19232 resetHooks();
19233
19234 // Reset in case completion throws.
19235 // This is only used in DEV and when replaying is on.
19236 var mayReplay = void 0;
19237 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19238 mayReplay = mayReplayFailedUnitOfWork;
19239 mayReplayFailedUnitOfWork = true;
19240 }
19241
19242 if (nextUnitOfWork === null) {
19243 // This is a fatal error.
19244 didFatal = true;
19245 onUncaughtError(thrownValue);
19246 } else {
19247 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
19248 // Record the time spent rendering before an error was thrown.
19249 // This avoids inaccurate Profiler durations in the case of a suspended render.
19250 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
19251 }
19252
19253 {
19254 // Reset global debug state
19255 // We assume this is defined in DEV
19256 resetCurrentlyProcessingQueue();
19257 }
19258
19259 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19260 if (mayReplay) {
19261 var failedUnitOfWork = nextUnitOfWork;
19262 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
19263 }
19264 }
19265
19266 // TODO: we already know this isn't true in some cases.
19267 // At least this shows a nicer error message until we figure out the cause.
19268 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
19269 !(nextUnitOfWork !== null) ? invariant(false, 'Failed to replay rendering after an error. This is likely caused by a bug in React. Please file an issue with a reproducing case to help us find it.') : void 0;
19270
19271 var sourceFiber = nextUnitOfWork;
19272 var returnFiber = sourceFiber.return;
19273 if (returnFiber === null) {
19274 // This is the root. The root could capture its own errors. However,
19275 // we don't know if it errors before or after we pushed the host
19276 // context. This information is needed to avoid a stack mismatch.
19277 // Because we're not sure, treat this as a fatal error. We could track
19278 // which phase it fails in, but doesn't seem worth it. At least
19279 // for now.
19280 didFatal = true;
19281 onUncaughtError(thrownValue);
19282 } else {
19283 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
19284 nextUnitOfWork = completeUnitOfWork(sourceFiber);
19285 continue;
19286 }
19287 }
19288 }
19289 break;
19290 } while (true);
19291
19292 if (enableSchedulerTracing) {
19293 // Traced work is done for now; restore the previous interactions.
19294 tracing.__interactionsRef.current = prevInteractions;
19295 }
19296
19297 // We're done performing work. Time to clean up.
19298 isWorking = false;
19299 ReactCurrentDispatcher.current = previousDispatcher;
19300 resetContextDependences();
19301 resetHooks();
19302
19303 // Yield back to main thread.
19304 if (didFatal) {
19305 var _didCompleteRoot = false;
19306 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
19307 interruptedBy = null;
19308 // There was a fatal error.
19309 {
19310 resetStackAfterFatalErrorInDev();
19311 }
19312 // `nextRoot` points to the in-progress root. A non-null value indicates
19313 // that we're in the middle of an async render. Set it to null to indicate
19314 // there's no more work to be done in the current batch.
19315 nextRoot = null;
19316 onFatal(root);
19317 return;
19318 }
19319
19320 if (nextUnitOfWork !== null) {
19321 // There's still remaining async work in this tree, but we ran out of time
19322 // in the current frame. Yield back to the renderer. Unless we're
19323 // interrupted by a higher priority update, we'll continue later from where
19324 // we left off.
19325 var _didCompleteRoot2 = false;
19326 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
19327 interruptedBy = null;
19328 onYield(root);
19329 return;
19330 }
19331
19332 // We completed the whole tree.
19333 var didCompleteRoot = true;
19334 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
19335 var rootWorkInProgress = root.current.alternate;
19336 !(rootWorkInProgress !== null) ? invariant(false, 'Finished root should have a work-in-progress. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19337
19338 // `nextRoot` points to the in-progress root. A non-null value indicates
19339 // that we're in the middle of an async render. Set it to null to indicate
19340 // there's no more work to be done in the current batch.
19341 nextRoot = null;
19342 interruptedBy = null;
19343
19344 if (nextRenderDidError) {
19345 // There was an error
19346 if (hasLowerPriorityWork(root, expirationTime)) {
19347 // There's lower priority work. If so, it may have the effect of fixing
19348 // the exception that was just thrown. Exit without committing. This is
19349 // similar to a suspend, but without a timeout because we're not waiting
19350 // for a promise to resolve. React will restart at the lower
19351 // priority level.
19352 markSuspendedPriorityLevel(root, expirationTime);
19353 var suspendedExpirationTime = expirationTime;
19354 var rootExpirationTime = root.expirationTime;
19355 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
19356 );
19357 return;
19358 } else if (
19359 // There's no lower priority work, but we're rendering asynchronously.
19360 // Synchronously attempt to render the same level one more time. This is
19361 // similar to a suspend, but without a timeout because we're not waiting
19362 // for a promise to resolve.
19363 !root.didError && isYieldy) {
19364 root.didError = true;
19365 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
19366 var _rootExpirationTime = root.expirationTime = Sync;
19367 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
19368 );
19369 return;
19370 }
19371 }
19372
19373 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
19374 // The tree was suspended.
19375 var _suspendedExpirationTime2 = expirationTime;
19376 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
19377
19378 // Find the earliest uncommitted expiration time in the tree, including
19379 // work that is suspended. The timeout threshold cannot be longer than
19380 // the overall expiration.
19381 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
19382 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
19383 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
19384 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
19385 }
19386
19387 // Subtract the current time from the absolute timeout to get the number
19388 // of milliseconds until the timeout. In other words, convert an absolute
19389 // timestamp to a relative time. This is the value that is passed
19390 // to `setTimeout`.
19391 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
19392 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
19393 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
19394
19395 // TODO: Account for the Just Noticeable Difference
19396
19397 var _rootExpirationTime2 = root.expirationTime;
19398 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
19399 return;
19400 }
19401
19402 // Ready to commit.
19403 onComplete(root, rootWorkInProgress, expirationTime);
19404}
19405
19406function captureCommitPhaseError(sourceFiber, value) {
19407 var expirationTime = Sync;
19408 var fiber = sourceFiber.return;
19409 while (fiber !== null) {
19410 switch (fiber.tag) {
19411 case ClassComponent:
19412 var ctor = fiber.type;
19413 var instance = fiber.stateNode;
19414 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
19415 var errorInfo = createCapturedValue(value, sourceFiber);
19416 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
19417 enqueueUpdate(fiber, update);
19418 scheduleWork(fiber, expirationTime);
19419 return;
19420 }
19421 break;
19422 case HostRoot:
19423 {
19424 var _errorInfo = createCapturedValue(value, sourceFiber);
19425 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
19426 enqueueUpdate(fiber, _update);
19427 scheduleWork(fiber, expirationTime);
19428 return;
19429 }
19430 }
19431 fiber = fiber.return;
19432 }
19433
19434 if (sourceFiber.tag === HostRoot) {
19435 // Error was thrown at the root. There is no parent, so the root
19436 // itself should capture it.
19437 var rootFiber = sourceFiber;
19438 var _errorInfo2 = createCapturedValue(value, rootFiber);
19439 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
19440 enqueueUpdate(rootFiber, _update2);
19441 scheduleWork(rootFiber, expirationTime);
19442 }
19443}
19444
19445function computeThreadID(expirationTime, interactionThreadID) {
19446 // Interaction threads are unique per root and expiration time.
19447 return expirationTime * 1000 + interactionThreadID;
19448}
19449
19450// Creates a unique async expiration time.
19451function computeUniqueAsyncExpiration() {
19452 var currentTime = requestCurrentTime();
19453 var result = computeAsyncExpiration(currentTime);
19454 if (result >= lastUniqueAsyncExpiration) {
19455 // Since we assume the current time monotonically increases, we only hit
19456 // this branch when computeUniqueAsyncExpiration is fired multiple times
19457 // within a 200ms window (or whatever the async bucket size is).
19458 result = lastUniqueAsyncExpiration - 1;
19459 }
19460 lastUniqueAsyncExpiration = result;
19461 return lastUniqueAsyncExpiration;
19462}
19463
19464function computeExpirationForFiber(currentTime, fiber) {
19465 var priorityLevel = scheduler.unstable_getCurrentPriorityLevel();
19466
19467 var expirationTime = void 0;
19468 if ((fiber.mode & ConcurrentMode) === NoContext) {
19469 // Outside of concurrent mode, updates are always synchronous.
19470 expirationTime = Sync;
19471 } else if (isWorking && !isCommitting$1) {
19472 // During render phase, updates expire during as the current render.
19473 expirationTime = nextRenderExpirationTime;
19474 } else {
19475 switch (priorityLevel) {
19476 case scheduler.unstable_ImmediatePriority:
19477 expirationTime = Sync;
19478 break;
19479 case scheduler.unstable_UserBlockingPriority:
19480 expirationTime = computeInteractiveExpiration(currentTime);
19481 break;
19482 case scheduler.unstable_NormalPriority:
19483 // This is a normal, concurrent update
19484 expirationTime = computeAsyncExpiration(currentTime);
19485 break;
19486 case scheduler.unstable_LowPriority:
19487 case scheduler.unstable_IdlePriority:
19488 expirationTime = Never;
19489 break;
19490 default:
19491 invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
19492 }
19493
19494 // If we're in the middle of rendering a tree, do not update at the same
19495 // expiration time that is already rendering.
19496 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19497 expirationTime -= 1;
19498 }
19499 }
19500
19501 // Keep track of the lowest pending interactive expiration time. This
19502 // allows us to synchronously flush all interactive updates
19503 // when needed.
19504 // TODO: Move this to renderer?
19505 if (priorityLevel === scheduler.unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) {
19506 lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19507 }
19508
19509 return expirationTime;
19510}
19511
19512function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
19513 // Schedule the timeout.
19514 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
19515 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
19516 }
19517}
19518
19519function renderDidError() {
19520 nextRenderDidError = true;
19521}
19522
19523function pingSuspendedRoot(root, thenable, pingTime) {
19524 // A promise that previously suspended React from committing has resolved.
19525 // If React is still suspended, try again at the previous level (pingTime).
19526
19527 var pingCache = root.pingCache;
19528 if (pingCache !== null) {
19529 // The thenable resolved, so we no longer need to memoize, because it will
19530 // never be thrown again.
19531 pingCache.delete(thenable);
19532 }
19533
19534 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
19535 // Received a ping at the same priority level at which we're currently
19536 // rendering. Restart from the root.
19537 nextRoot = null;
19538 } else {
19539 // Confirm that the root is still suspended at this level. Otherwise exit.
19540 if (isPriorityLevelSuspended(root, pingTime)) {
19541 // Ping at the original level
19542 markPingedPriorityLevel(root, pingTime);
19543 var rootExpirationTime = root.expirationTime;
19544 if (rootExpirationTime !== NoWork) {
19545 requestWork(root, rootExpirationTime);
19546 }
19547 }
19548 }
19549}
19550
19551function retryTimedOutBoundary(boundaryFiber, thenable) {
19552 // The boundary fiber (a Suspense component) previously timed out and was
19553 // rendered in its fallback state. One of the promises that suspended it has
19554 // resolved, which means at least part of the tree was likely unblocked. Try
19555 var retryCache = void 0;
19556 if (enableSuspenseServerRenderer) {
19557 switch (boundaryFiber.tag) {
19558 case SuspenseComponent:
19559 retryCache = boundaryFiber.stateNode;
19560 break;
19561 case DehydratedSuspenseComponent:
19562 retryCache = boundaryFiber.memoizedState;
19563 break;
19564 default:
19565 invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
19566 }
19567 } else {
19568 retryCache = boundaryFiber.stateNode;
19569 }
19570 if (retryCache !== null) {
19571 // The thenable resolved, so we no longer need to memoize, because it will
19572 // never be thrown again.
19573 retryCache.delete(thenable);
19574 }
19575
19576 var currentTime = requestCurrentTime();
19577 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
19578 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
19579 if (root !== null) {
19580 markPendingPriorityLevel(root, retryTime);
19581 var rootExpirationTime = root.expirationTime;
19582 if (rootExpirationTime !== NoWork) {
19583 requestWork(root, rootExpirationTime);
19584 }
19585 }
19586}
19587
19588function scheduleWorkToRoot(fiber, expirationTime) {
19589 recordScheduleUpdate();
19590
19591 {
19592 if (fiber.tag === ClassComponent) {
19593 var instance = fiber.stateNode;
19594 warnAboutInvalidUpdates(instance);
19595 }
19596 }
19597
19598 // Update the source fiber's expiration time
19599 if (fiber.expirationTime < expirationTime) {
19600 fiber.expirationTime = expirationTime;
19601 }
19602 var alternate = fiber.alternate;
19603 if (alternate !== null && alternate.expirationTime < expirationTime) {
19604 alternate.expirationTime = expirationTime;
19605 }
19606 // Walk the parent path to the root and update the child expiration time.
19607 var node = fiber.return;
19608 var root = null;
19609 if (node === null && fiber.tag === HostRoot) {
19610 root = fiber.stateNode;
19611 } else {
19612 while (node !== null) {
19613 alternate = node.alternate;
19614 if (node.childExpirationTime < expirationTime) {
19615 node.childExpirationTime = expirationTime;
19616 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19617 alternate.childExpirationTime = expirationTime;
19618 }
19619 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19620 alternate.childExpirationTime = expirationTime;
19621 }
19622 if (node.return === null && node.tag === HostRoot) {
19623 root = node.stateNode;
19624 break;
19625 }
19626 node = node.return;
19627 }
19628 }
19629
19630 if (enableSchedulerTracing) {
19631 if (root !== null) {
19632 var interactions = tracing.__interactionsRef.current;
19633 if (interactions.size > 0) {
19634 var pendingInteractionMap = root.pendingInteractionMap;
19635 var pendingInteractions = pendingInteractionMap.get(expirationTime);
19636 if (pendingInteractions != null) {
19637 interactions.forEach(function (interaction) {
19638 if (!pendingInteractions.has(interaction)) {
19639 // Update the pending async work count for previously unscheduled interaction.
19640 interaction.__count++;
19641 }
19642
19643 pendingInteractions.add(interaction);
19644 });
19645 } else {
19646 pendingInteractionMap.set(expirationTime, new Set(interactions));
19647
19648 // Update the pending async work count for the current interactions.
19649 interactions.forEach(function (interaction) {
19650 interaction.__count++;
19651 });
19652 }
19653
19654 var subscriber = tracing.__subscriberRef.current;
19655 if (subscriber !== null) {
19656 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19657 subscriber.onWorkScheduled(interactions, threadID);
19658 }
19659 }
19660 }
19661 }
19662 return root;
19663}
19664
19665function warnIfNotCurrentlyBatchingInDev(fiber) {
19666 {
19667 if (isRendering === false && isBatchingUpdates === false) {
19668 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));
19669 }
19670 }
19671}
19672
19673function scheduleWork(fiber, expirationTime) {
19674 var root = scheduleWorkToRoot(fiber, expirationTime);
19675 if (root === null) {
19676 {
19677 switch (fiber.tag) {
19678 case ClassComponent:
19679 warnAboutUpdateOnUnmounted(fiber, true);
19680 break;
19681 case FunctionComponent:
19682 case ForwardRef:
19683 case MemoComponent:
19684 case SimpleMemoComponent:
19685 warnAboutUpdateOnUnmounted(fiber, false);
19686 break;
19687 }
19688 }
19689 return;
19690 }
19691
19692 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
19693 // This is an interruption. (Used for performance tracking.)
19694 interruptedBy = fiber;
19695 resetStack();
19696 }
19697 markPendingPriorityLevel(root, expirationTime);
19698 if (
19699 // If we're in the render phase, we don't need to schedule this root
19700 // for an update, because we'll do it before we exit...
19701 !isWorking || isCommitting$1 ||
19702 // ...unless this is a different root than the one we're rendering.
19703 nextRoot !== root) {
19704 var rootExpirationTime = root.expirationTime;
19705 requestWork(root, rootExpirationTime);
19706 }
19707 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
19708 // Reset this back to zero so subsequent updates don't throw.
19709 nestedUpdateCount = 0;
19710 invariant(false, '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.');
19711 }
19712}
19713
19714function syncUpdates(fn, a, b, c, d) {
19715 return scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
19716 return fn(a, b, c, d);
19717 });
19718}
19719
19720// TODO: Everything below this is written as if it has been lifted to the
19721// renderers. I'll do this in a follow-up.
19722
19723// Linked-list of roots
19724var firstScheduledRoot = null;
19725var lastScheduledRoot = null;
19726
19727var callbackExpirationTime = NoWork;
19728var callbackID = void 0;
19729var isRendering = false;
19730var nextFlushedRoot = null;
19731var nextFlushedExpirationTime = NoWork;
19732var lowestPriorityPendingInteractiveExpirationTime = NoWork;
19733var hasUnhandledError = false;
19734var unhandledError = null;
19735
19736var isBatchingUpdates = false;
19737var isUnbatchingUpdates = false;
19738
19739var completedBatches = null;
19740
19741var originalStartTimeMs = scheduler.unstable_now();
19742var currentRendererTime = msToExpirationTime(originalStartTimeMs);
19743var currentSchedulerTime = currentRendererTime;
19744
19745// Use these to prevent an infinite loop of nested updates
19746var NESTED_UPDATE_LIMIT = 50;
19747var nestedUpdateCount = 0;
19748var lastCommittedRootDuringThisBatch = null;
19749
19750function recomputeCurrentRendererTime() {
19751 var currentTimeMs = scheduler.unstable_now() - originalStartTimeMs;
19752 currentRendererTime = msToExpirationTime(currentTimeMs);
19753}
19754
19755function scheduleCallbackWithExpirationTime(root, expirationTime) {
19756 if (callbackExpirationTime !== NoWork) {
19757 // A callback is already scheduled. Check its expiration time (timeout).
19758 if (expirationTime < callbackExpirationTime) {
19759 // Existing callback has sufficient timeout. Exit.
19760 return;
19761 } else {
19762 if (callbackID !== null) {
19763 // Existing callback has insufficient timeout. Cancel and schedule a
19764 // new one.
19765 scheduler.unstable_cancelCallback(callbackID);
19766 }
19767 }
19768 // The request callback timer is already running. Don't start a new one.
19769 } else {
19770 startRequestCallbackTimer();
19771 }
19772
19773 callbackExpirationTime = expirationTime;
19774 var currentMs = scheduler.unstable_now() - originalStartTimeMs;
19775 var expirationTimeMs = expirationTimeToMs(expirationTime);
19776 var timeout = expirationTimeMs - currentMs;
19777 callbackID = scheduler.unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
19778}
19779
19780// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
19781// onYield is called upon exiting. We use these in lieu of returning a tuple.
19782// I've also chosen not to inline them into renderRoot because these will
19783// eventually be lifted into the renderer.
19784function onFatal(root) {
19785 root.finishedWork = null;
19786}
19787
19788function onComplete(root, finishedWork, expirationTime) {
19789 root.pendingCommitExpirationTime = expirationTime;
19790 root.finishedWork = finishedWork;
19791}
19792
19793function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
19794 root.expirationTime = rootExpirationTime;
19795 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
19796 // Don't wait an additional tick. Commit the tree immediately.
19797 root.pendingCommitExpirationTime = suspendedExpirationTime;
19798 root.finishedWork = finishedWork;
19799 } else if (msUntilTimeout > 0) {
19800 // Wait `msUntilTimeout` milliseconds before committing.
19801 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
19802 }
19803}
19804
19805function onYield(root) {
19806 root.finishedWork = null;
19807}
19808
19809function onTimeout(root, finishedWork, suspendedExpirationTime) {
19810 // The root timed out. Commit it.
19811 root.pendingCommitExpirationTime = suspendedExpirationTime;
19812 root.finishedWork = finishedWork;
19813 // Read the current time before entering the commit phase. We can be
19814 // certain this won't cause tearing related to batching of event updates
19815 // because we're at the top of a timer event.
19816 recomputeCurrentRendererTime();
19817 currentSchedulerTime = currentRendererTime;
19818 flushRoot(root, suspendedExpirationTime);
19819}
19820
19821function onCommit(root, expirationTime) {
19822 root.expirationTime = expirationTime;
19823 root.finishedWork = null;
19824}
19825
19826function requestCurrentTime() {
19827 // requestCurrentTime is called by the scheduler to compute an expiration
19828 // time.
19829 //
19830 // Expiration times are computed by adding to the current time (the start
19831 // time). However, if two updates are scheduled within the same event, we
19832 // should treat their start times as simultaneous, even if the actual clock
19833 // time has advanced between the first and second call.
19834
19835 // In other words, because expiration times determine how updates are batched,
19836 // we want all updates of like priority that occur within the same event to
19837 // receive the same expiration time. Otherwise we get tearing.
19838 //
19839 // We keep track of two separate times: the current "renderer" time and the
19840 // current "scheduler" time. The renderer time can be updated whenever; it
19841 // only exists to minimize the calls performance.now.
19842 //
19843 // But the scheduler time can only be updated if there's no pending work, or
19844 // if we know for certain that we're not in the middle of an event.
19845
19846 if (isRendering) {
19847 // We're already rendering. Return the most recently read time.
19848 return currentSchedulerTime;
19849 }
19850 // Check if there's pending work.
19851 findHighestPriorityRoot();
19852 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
19853 // If there's no pending work, or if the pending work is offscreen, we can
19854 // read the current time without risk of tearing.
19855 recomputeCurrentRendererTime();
19856 currentSchedulerTime = currentRendererTime;
19857 return currentSchedulerTime;
19858 }
19859 // There's already pending work. We might be in the middle of a browser
19860 // event. If we were to read the current time, it could cause multiple updates
19861 // within the same event to receive different expiration times, leading to
19862 // tearing. Return the last read time. During the next idle callback, the
19863 // time will be updated.
19864 return currentSchedulerTime;
19865}
19866
19867// requestWork is called by the scheduler whenever a root receives an update.
19868// It's up to the renderer to call renderRoot at some point in the future.
19869function requestWork(root, expirationTime) {
19870 addRootToSchedule(root, expirationTime);
19871 if (isRendering) {
19872 // Prevent reentrancy. Remaining work will be scheduled at the end of
19873 // the currently rendering batch.
19874 return;
19875 }
19876
19877 if (isBatchingUpdates) {
19878 // Flush work at the end of the batch.
19879 if (isUnbatchingUpdates) {
19880 // ...unless we're inside unbatchedUpdates, in which case we should
19881 // flush it now.
19882 nextFlushedRoot = root;
19883 nextFlushedExpirationTime = Sync;
19884 performWorkOnRoot(root, Sync, false);
19885 }
19886 return;
19887 }
19888
19889 // TODO: Get rid of Sync and use current time?
19890 if (expirationTime === Sync) {
19891 performSyncWork();
19892 } else {
19893 scheduleCallbackWithExpirationTime(root, expirationTime);
19894 }
19895}
19896
19897function addRootToSchedule(root, expirationTime) {
19898 // Add the root to the schedule.
19899 // Check if this root is already part of the schedule.
19900 if (root.nextScheduledRoot === null) {
19901 // This root is not already scheduled. Add it.
19902 root.expirationTime = expirationTime;
19903 if (lastScheduledRoot === null) {
19904 firstScheduledRoot = lastScheduledRoot = root;
19905 root.nextScheduledRoot = root;
19906 } else {
19907 lastScheduledRoot.nextScheduledRoot = root;
19908 lastScheduledRoot = root;
19909 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19910 }
19911 } else {
19912 // This root is already scheduled, but its priority may have increased.
19913 var remainingExpirationTime = root.expirationTime;
19914 if (expirationTime > remainingExpirationTime) {
19915 // Update the priority.
19916 root.expirationTime = expirationTime;
19917 }
19918 }
19919}
19920
19921function findHighestPriorityRoot() {
19922 var highestPriorityWork = NoWork;
19923 var highestPriorityRoot = null;
19924 if (lastScheduledRoot !== null) {
19925 var previousScheduledRoot = lastScheduledRoot;
19926 var root = firstScheduledRoot;
19927 while (root !== null) {
19928 var remainingExpirationTime = root.expirationTime;
19929 if (remainingExpirationTime === NoWork) {
19930 // This root no longer has work. Remove it from the scheduler.
19931
19932 // TODO: This check is redudant, but Flow is confused by the branch
19933 // below where we set lastScheduledRoot to null, even though we break
19934 // from the loop right after.
19935 !(previousScheduledRoot !== null && lastScheduledRoot !== null) ? invariant(false, 'Should have a previous and last root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19936 if (root === root.nextScheduledRoot) {
19937 // This is the only root in the list.
19938 root.nextScheduledRoot = null;
19939 firstScheduledRoot = lastScheduledRoot = null;
19940 break;
19941 } else if (root === firstScheduledRoot) {
19942 // This is the first root in the list.
19943 var next = root.nextScheduledRoot;
19944 firstScheduledRoot = next;
19945 lastScheduledRoot.nextScheduledRoot = next;
19946 root.nextScheduledRoot = null;
19947 } else if (root === lastScheduledRoot) {
19948 // This is the last root in the list.
19949 lastScheduledRoot = previousScheduledRoot;
19950 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19951 root.nextScheduledRoot = null;
19952 break;
19953 } else {
19954 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
19955 root.nextScheduledRoot = null;
19956 }
19957 root = previousScheduledRoot.nextScheduledRoot;
19958 } else {
19959 if (remainingExpirationTime > highestPriorityWork) {
19960 // Update the priority, if it's higher
19961 highestPriorityWork = remainingExpirationTime;
19962 highestPriorityRoot = root;
19963 }
19964 if (root === lastScheduledRoot) {
19965 break;
19966 }
19967 if (highestPriorityWork === Sync) {
19968 // Sync is highest priority by definition so
19969 // we can stop searching.
19970 break;
19971 }
19972 previousScheduledRoot = root;
19973 root = root.nextScheduledRoot;
19974 }
19975 }
19976 }
19977
19978 nextFlushedRoot = highestPriorityRoot;
19979 nextFlushedExpirationTime = highestPriorityWork;
19980}
19981
19982// TODO: This wrapper exists because many of the older tests (the ones that use
19983// flushDeferredPri) rely on the number of times `shouldYield` is called. We
19984// should get rid of it.
19985var didYield = false;
19986function shouldYieldToRenderer() {
19987 if (didYield) {
19988 return true;
19989 }
19990 if (scheduler.unstable_shouldYield()) {
19991 didYield = true;
19992 return true;
19993 }
19994 return false;
19995}
19996
19997function performAsyncWork() {
19998 try {
19999 if (!shouldYieldToRenderer()) {
20000 // The callback timed out. That means at least one update has expired.
20001 // Iterate through the root schedule. If they contain expired work, set
20002 // the next render expiration time to the current time. This has the effect
20003 // of flushing all expired work in a single batch, instead of flushing each
20004 // level one at a time.
20005 if (firstScheduledRoot !== null) {
20006 recomputeCurrentRendererTime();
20007 var root = firstScheduledRoot;
20008 do {
20009 didExpireAtExpirationTime(root, currentRendererTime);
20010 // The root schedule is circular, so this is never null.
20011 root = root.nextScheduledRoot;
20012 } while (root !== firstScheduledRoot);
20013 }
20014 }
20015 performWork(NoWork, true);
20016 } finally {
20017 didYield = false;
20018 }
20019}
20020
20021function performSyncWork() {
20022 performWork(Sync, false);
20023}
20024
20025function performWork(minExpirationTime, isYieldy) {
20026 // Keep working on roots until there's no more work, or until there's a higher
20027 // priority event.
20028 findHighestPriorityRoot();
20029
20030 if (isYieldy) {
20031 recomputeCurrentRendererTime();
20032 currentSchedulerTime = currentRendererTime;
20033
20034 if (enableUserTimingAPI) {
20035 var didExpire = nextFlushedExpirationTime > currentRendererTime;
20036 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
20037 stopRequestCallbackTimer(didExpire, timeout);
20038 }
20039
20040 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
20041 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
20042 findHighestPriorityRoot();
20043 recomputeCurrentRendererTime();
20044 currentSchedulerTime = currentRendererTime;
20045 }
20046 } else {
20047 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
20048 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
20049 findHighestPriorityRoot();
20050 }
20051 }
20052
20053 // We're done flushing work. Either we ran out of time in this callback,
20054 // or there's no more work left with sufficient priority.
20055
20056 // If we're inside a callback, set this to false since we just completed it.
20057 if (isYieldy) {
20058 callbackExpirationTime = NoWork;
20059 callbackID = null;
20060 }
20061 // If there's work left over, schedule a new callback.
20062 if (nextFlushedExpirationTime !== NoWork) {
20063 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
20064 }
20065
20066 // Clean-up.
20067 finishRendering();
20068}
20069
20070function flushRoot(root, expirationTime) {
20071 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
20072 // Perform work on root as if the given expiration time is the current time.
20073 // This has the effect of synchronously flushing all work up to and
20074 // including the given time.
20075 nextFlushedRoot = root;
20076 nextFlushedExpirationTime = expirationTime;
20077 performWorkOnRoot(root, expirationTime, false);
20078 // Flush any sync work that was scheduled by lifecycles
20079 performSyncWork();
20080}
20081
20082function finishRendering() {
20083 nestedUpdateCount = 0;
20084 lastCommittedRootDuringThisBatch = null;
20085
20086 if (completedBatches !== null) {
20087 var batches = completedBatches;
20088 completedBatches = null;
20089 for (var i = 0; i < batches.length; i++) {
20090 var batch = batches[i];
20091 try {
20092 batch._onComplete();
20093 } catch (error) {
20094 if (!hasUnhandledError) {
20095 hasUnhandledError = true;
20096 unhandledError = error;
20097 }
20098 }
20099 }
20100 }
20101
20102 if (hasUnhandledError) {
20103 var error = unhandledError;
20104 unhandledError = null;
20105 hasUnhandledError = false;
20106 throw error;
20107 }
20108}
20109
20110function performWorkOnRoot(root, expirationTime, isYieldy) {
20111 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
20112
20113 isRendering = true;
20114
20115 // Check if this is async work or sync/expired work.
20116 if (!isYieldy) {
20117 // Flush work without yielding.
20118 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
20119 // may want to perform some work without yielding, but also without
20120 // requiring the root to complete (by triggering placeholders).
20121
20122 var finishedWork = root.finishedWork;
20123 if (finishedWork !== null) {
20124 // This root is already complete. We can commit it.
20125 completeRoot(root, finishedWork, expirationTime);
20126 } else {
20127 root.finishedWork = null;
20128 // If this root previously suspended, clear its existing timeout, since
20129 // we're about to try rendering again.
20130 var timeoutHandle = root.timeoutHandle;
20131 if (timeoutHandle !== noTimeout) {
20132 root.timeoutHandle = noTimeout;
20133 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
20134 cancelTimeout(timeoutHandle);
20135 }
20136 renderRoot(root, isYieldy);
20137 finishedWork = root.finishedWork;
20138 if (finishedWork !== null) {
20139 // We've completed the root. Commit it.
20140 completeRoot(root, finishedWork, expirationTime);
20141 }
20142 }
20143 } else {
20144 // Flush async work.
20145 var _finishedWork = root.finishedWork;
20146 if (_finishedWork !== null) {
20147 // This root is already complete. We can commit it.
20148 completeRoot(root, _finishedWork, expirationTime);
20149 } else {
20150 root.finishedWork = null;
20151 // If this root previously suspended, clear its existing timeout, since
20152 // we're about to try rendering again.
20153 var _timeoutHandle = root.timeoutHandle;
20154 if (_timeoutHandle !== noTimeout) {
20155 root.timeoutHandle = noTimeout;
20156 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
20157 cancelTimeout(_timeoutHandle);
20158 }
20159 renderRoot(root, isYieldy);
20160 _finishedWork = root.finishedWork;
20161 if (_finishedWork !== null) {
20162 // We've completed the root. Check the if we should yield one more time
20163 // before committing.
20164 if (!shouldYieldToRenderer()) {
20165 // Still time left. Commit the root.
20166 completeRoot(root, _finishedWork, expirationTime);
20167 } else {
20168 // There's no time left. Mark this root as complete. We'll come
20169 // back and commit it later.
20170 root.finishedWork = _finishedWork;
20171 }
20172 }
20173 }
20174 }
20175
20176 isRendering = false;
20177}
20178
20179function completeRoot(root, finishedWork, expirationTime) {
20180 // Check if there's a batch that matches this expiration time.
20181 var firstBatch = root.firstBatch;
20182 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
20183 if (completedBatches === null) {
20184 completedBatches = [firstBatch];
20185 } else {
20186 completedBatches.push(firstBatch);
20187 }
20188 if (firstBatch._defer) {
20189 // This root is blocked from committing by a batch. Unschedule it until
20190 // we receive another update.
20191 root.finishedWork = finishedWork;
20192 root.expirationTime = NoWork;
20193 return;
20194 }
20195 }
20196
20197 // Commit the root.
20198 root.finishedWork = null;
20199
20200 // Check if this is a nested update (a sync update scheduled during the
20201 // commit phase).
20202 if (root === lastCommittedRootDuringThisBatch) {
20203 // If the next root is the same as the previous root, this is a nested
20204 // update. To prevent an infinite loop, increment the nested update count.
20205 nestedUpdateCount++;
20206 } else {
20207 // Reset whenever we switch roots.
20208 lastCommittedRootDuringThisBatch = root;
20209 nestedUpdateCount = 0;
20210 }
20211 scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
20212 commitRoot(root, finishedWork);
20213 });
20214}
20215
20216function onUncaughtError(error) {
20217 !(nextFlushedRoot !== null) ? invariant(false, 'Should be working on a root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
20218 // Unschedule this root so we don't work on it again until there's
20219 // another update.
20220 nextFlushedRoot.expirationTime = NoWork;
20221 if (!hasUnhandledError) {
20222 hasUnhandledError = true;
20223 unhandledError = error;
20224 }
20225}
20226
20227// TODO: Batching should be implemented at the renderer level, not inside
20228// the reconciler.
20229function batchedUpdates$1(fn, a) {
20230 var previousIsBatchingUpdates = isBatchingUpdates;
20231 isBatchingUpdates = true;
20232 try {
20233 return fn(a);
20234 } finally {
20235 isBatchingUpdates = previousIsBatchingUpdates;
20236 if (!isBatchingUpdates && !isRendering) {
20237 performSyncWork();
20238 }
20239 }
20240}
20241
20242// TODO: Batching should be implemented at the renderer level, not inside
20243// the reconciler.
20244function unbatchedUpdates(fn, a) {
20245 if (isBatchingUpdates && !isUnbatchingUpdates) {
20246 isUnbatchingUpdates = true;
20247 try {
20248 return fn(a);
20249 } finally {
20250 isUnbatchingUpdates = false;
20251 }
20252 }
20253 return fn(a);
20254}
20255
20256// TODO: Batching should be implemented at the renderer level, not within
20257// the reconciler.
20258function flushSync(fn, a) {
20259 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
20260 var previousIsBatchingUpdates = isBatchingUpdates;
20261 isBatchingUpdates = true;
20262 try {
20263 return syncUpdates(fn, a);
20264 } finally {
20265 isBatchingUpdates = previousIsBatchingUpdates;
20266 performSyncWork();
20267 }
20268}
20269
20270function interactiveUpdates$1(fn, a, b) {
20271 // If there are any pending interactive updates, synchronously flush them.
20272 // This needs to happen before we read any handlers, because the effect of
20273 // the previous event may influence which handlers are called during
20274 // this event.
20275 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20276 // Synchronously flush pending interactive updates.
20277 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20278 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20279 }
20280 var previousIsBatchingUpdates = isBatchingUpdates;
20281 isBatchingUpdates = true;
20282 try {
20283 return scheduler.unstable_runWithPriority(scheduler.unstable_UserBlockingPriority, function () {
20284 return fn(a, b);
20285 });
20286 } finally {
20287 isBatchingUpdates = previousIsBatchingUpdates;
20288 if (!isBatchingUpdates && !isRendering) {
20289 performSyncWork();
20290 }
20291 }
20292}
20293
20294function flushInteractiveUpdates$1() {
20295 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20296 // Synchronously flush pending interactive updates.
20297 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20298 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20299 }
20300}
20301
20302function flushControlled(fn) {
20303 var previousIsBatchingUpdates = isBatchingUpdates;
20304 isBatchingUpdates = true;
20305 try {
20306 syncUpdates(fn);
20307 } finally {
20308 isBatchingUpdates = previousIsBatchingUpdates;
20309 if (!isBatchingUpdates && !isRendering) {
20310 performSyncWork();
20311 }
20312 }
20313}
20314
20315// 0 is PROD, 1 is DEV.
20316// Might add PROFILE later.
20317
20318
20319var didWarnAboutNestedUpdates = void 0;
20320var didWarnAboutFindNodeInStrictMode = void 0;
20321
20322{
20323 didWarnAboutNestedUpdates = false;
20324 didWarnAboutFindNodeInStrictMode = {};
20325}
20326
20327function getContextForSubtree(parentComponent) {
20328 if (!parentComponent) {
20329 return emptyContextObject;
20330 }
20331
20332 var fiber = get(parentComponent);
20333 var parentContext = findCurrentUnmaskedContext(fiber);
20334
20335 if (fiber.tag === ClassComponent) {
20336 var Component = fiber.type;
20337 if (isContextProvider(Component)) {
20338 return processChildContext(fiber, Component, parentContext);
20339 }
20340 }
20341
20342 return parentContext;
20343}
20344
20345function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
20346 {
20347 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
20348 didWarnAboutNestedUpdates = true;
20349 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');
20350 }
20351 }
20352
20353 var update = createUpdate(expirationTime);
20354 // Caution: React DevTools currently depends on this property
20355 // being called "element".
20356 update.payload = { element: element };
20357
20358 callback = callback === undefined ? null : callback;
20359 if (callback !== null) {
20360 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
20361 update.callback = callback;
20362 }
20363
20364 flushPassiveEffects();
20365 enqueueUpdate(current$$1, update);
20366 scheduleWork(current$$1, expirationTime);
20367
20368 return expirationTime;
20369}
20370
20371function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
20372 // TODO: If this is a nested container, this won't be the root.
20373 var current$$1 = container.current;
20374
20375 {
20376 if (ReactFiberInstrumentation_1.debugTool) {
20377 if (current$$1.alternate === null) {
20378 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
20379 } else if (element === null) {
20380 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
20381 } else {
20382 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
20383 }
20384 }
20385 }
20386
20387 var context = getContextForSubtree(parentComponent);
20388 if (container.context === null) {
20389 container.context = context;
20390 } else {
20391 container.pendingContext = context;
20392 }
20393
20394 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
20395}
20396
20397function findHostInstance(component) {
20398 var fiber = get(component);
20399 if (fiber === undefined) {
20400 if (typeof component.render === 'function') {
20401 invariant(false, 'Unable to find node on an unmounted component.');
20402 } else {
20403 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20404 }
20405 }
20406 var hostFiber = findCurrentHostFiber(fiber);
20407 if (hostFiber === null) {
20408 return null;
20409 }
20410 return hostFiber.stateNode;
20411}
20412
20413function findHostInstanceWithWarning(component, methodName) {
20414 {
20415 var fiber = get(component);
20416 if (fiber === undefined) {
20417 if (typeof component.render === 'function') {
20418 invariant(false, 'Unable to find node on an unmounted component.');
20419 } else {
20420 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20421 }
20422 }
20423 var hostFiber = findCurrentHostFiber(fiber);
20424 if (hostFiber === null) {
20425 return null;
20426 }
20427 if (hostFiber.mode & StrictMode) {
20428 var componentName = getComponentName(fiber.type) || 'Component';
20429 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
20430 didWarnAboutFindNodeInStrictMode[componentName] = true;
20431 if (fiber.mode & StrictMode) {
20432 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));
20433 } else {
20434 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));
20435 }
20436 }
20437 }
20438 return hostFiber.stateNode;
20439 }
20440 return findHostInstance(component);
20441}
20442
20443function createContainer(containerInfo, isConcurrent, hydrate) {
20444 return createFiberRoot(containerInfo, isConcurrent, hydrate);
20445}
20446
20447function updateContainer(element, container, parentComponent, callback) {
20448 var current$$1 = container.current;
20449 var currentTime = requestCurrentTime();
20450 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
20451 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
20452}
20453
20454function getPublicRootInstance(container) {
20455 var containerFiber = container.current;
20456 if (!containerFiber.child) {
20457 return null;
20458 }
20459 switch (containerFiber.child.tag) {
20460 case HostComponent:
20461 return getPublicInstance(containerFiber.child.stateNode);
20462 default:
20463 return containerFiber.child.stateNode;
20464 }
20465}
20466
20467function findHostInstanceWithNoPortals(fiber) {
20468 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
20469 if (hostFiber === null) {
20470 return null;
20471 }
20472 return hostFiber.stateNode;
20473}
20474
20475var overrideProps = null;
20476
20477{
20478 var copyWithSetImpl = function (obj, path, idx, value) {
20479 if (idx >= path.length) {
20480 return value;
20481 }
20482 var key = path[idx];
20483 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
20484 // $FlowFixMe number or string is fine here
20485 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
20486 return updated;
20487 };
20488
20489 var copyWithSet = function (obj, path, value) {
20490 return copyWithSetImpl(obj, path, 0, value);
20491 };
20492
20493 // Support DevTools props for function components, forwardRef, memo, host components, etc.
20494 overrideProps = function (fiber, path, value) {
20495 flushPassiveEffects();
20496 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
20497 if (fiber.alternate) {
20498 fiber.alternate.pendingProps = fiber.pendingProps;
20499 }
20500 scheduleWork(fiber, Sync);
20501 };
20502}
20503
20504function injectIntoDevTools(devToolsConfig) {
20505 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
20506 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
20507
20508
20509 return injectInternals(_assign({}, devToolsConfig, {
20510 overrideProps: overrideProps,
20511 currentDispatcherRef: ReactCurrentDispatcher,
20512 findHostInstanceByFiber: function (fiber) {
20513 var hostFiber = findCurrentHostFiber(fiber);
20514 if (hostFiber === null) {
20515 return null;
20516 }
20517 return hostFiber.stateNode;
20518 },
20519 findFiberByHostInstance: function (instance) {
20520 if (!findFiberByHostInstance) {
20521 // Might not be implemented by the renderer.
20522 return null;
20523 }
20524 return findFiberByHostInstance(instance);
20525 }
20526 }));
20527}
20528
20529// This file intentionally does *not* have the Flow annotation.
20530// Don't add it. See `./inline-typed.js` for an explanation.
20531
20532function createPortal$1(children, containerInfo,
20533// TODO: figure out the API for cross-renderer implementation.
20534implementation) {
20535 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
20536
20537 return {
20538 // This tag allow us to uniquely identify this as a React Portal
20539 $$typeof: REACT_PORTAL_TYPE,
20540 key: key == null ? null : '' + key,
20541 children: children,
20542 containerInfo: containerInfo,
20543 implementation: implementation
20544 };
20545}
20546
20547// TODO: this is special because it gets imported during build.
20548
20549var ReactVersion = '16.8.2';
20550
20551// TODO: This type is shared between the reconciler and ReactDOM, but will
20552// eventually be lifted out to the renderer.
20553
20554var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
20555
20556var topLevelUpdateWarnings = void 0;
20557var warnOnInvalidCallback = void 0;
20558var didWarnAboutUnstableCreatePortal = false;
20559
20560{
20561 if (typeof Map !== 'function' ||
20562 // $FlowIssue Flow incorrectly thinks Map has no prototype
20563 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
20564 // $FlowIssue Flow incorrectly thinks Set has no prototype
20565 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
20566 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');
20567 }
20568
20569 topLevelUpdateWarnings = function (container) {
20570 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
20571 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
20572 if (hostInstance) {
20573 !(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;
20574 }
20575 }
20576
20577 var isRootRenderedBySomeReact = !!container._reactRootContainer;
20578 var rootEl = getReactRootElementInContainer(container);
20579 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
20580
20581 !(!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;
20582
20583 !(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;
20584 };
20585
20586 warnOnInvalidCallback = function (callback, callerName) {
20587 !(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;
20588 };
20589}
20590
20591setRestoreImplementation(restoreControlledState$1);
20592
20593function ReactBatch(root) {
20594 var expirationTime = computeUniqueAsyncExpiration();
20595 this._expirationTime = expirationTime;
20596 this._root = root;
20597 this._next = null;
20598 this._callbacks = null;
20599 this._didComplete = false;
20600 this._hasChildren = false;
20601 this._children = null;
20602 this._defer = true;
20603}
20604ReactBatch.prototype.render = function (children) {
20605 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
20606 this._hasChildren = true;
20607 this._children = children;
20608 var internalRoot = this._root._internalRoot;
20609 var expirationTime = this._expirationTime;
20610 var work = new ReactWork();
20611 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
20612 return work;
20613};
20614ReactBatch.prototype.then = function (onComplete) {
20615 if (this._didComplete) {
20616 onComplete();
20617 return;
20618 }
20619 var callbacks = this._callbacks;
20620 if (callbacks === null) {
20621 callbacks = this._callbacks = [];
20622 }
20623 callbacks.push(onComplete);
20624};
20625ReactBatch.prototype.commit = function () {
20626 var internalRoot = this._root._internalRoot;
20627 var firstBatch = internalRoot.firstBatch;
20628 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20629
20630 if (!this._hasChildren) {
20631 // This batch is empty. Return.
20632 this._next = null;
20633 this._defer = false;
20634 return;
20635 }
20636
20637 var expirationTime = this._expirationTime;
20638
20639 // Ensure this is the first batch in the list.
20640 if (firstBatch !== this) {
20641 // This batch is not the earliest batch. We need to move it to the front.
20642 // Update its expiration time to be the expiration time of the earliest
20643 // batch, so that we can flush it without flushing the other batches.
20644 if (this._hasChildren) {
20645 expirationTime = this._expirationTime = firstBatch._expirationTime;
20646 // Rendering this batch again ensures its children will be the final state
20647 // when we flush (updates are processed in insertion order: last
20648 // update wins).
20649 // TODO: This forces a restart. Should we print a warning?
20650 this.render(this._children);
20651 }
20652
20653 // Remove the batch from the list.
20654 var previous = null;
20655 var batch = firstBatch;
20656 while (batch !== this) {
20657 previous = batch;
20658 batch = batch._next;
20659 }
20660 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20661 previous._next = batch._next;
20662
20663 // Add it to the front.
20664 this._next = firstBatch;
20665 firstBatch = internalRoot.firstBatch = this;
20666 }
20667
20668 // Synchronously flush all the work up to this batch's expiration time.
20669 this._defer = false;
20670 flushRoot(internalRoot, expirationTime);
20671
20672 // Pop the batch from the list.
20673 var next = this._next;
20674 this._next = null;
20675 firstBatch = internalRoot.firstBatch = next;
20676
20677 // Append the next earliest batch's children to the update queue.
20678 if (firstBatch !== null && firstBatch._hasChildren) {
20679 firstBatch.render(firstBatch._children);
20680 }
20681};
20682ReactBatch.prototype._onComplete = function () {
20683 if (this._didComplete) {
20684 return;
20685 }
20686 this._didComplete = true;
20687 var callbacks = this._callbacks;
20688 if (callbacks === null) {
20689 return;
20690 }
20691 // TODO: Error handling.
20692 for (var i = 0; i < callbacks.length; i++) {
20693 var _callback = callbacks[i];
20694 _callback();
20695 }
20696};
20697
20698function ReactWork() {
20699 this._callbacks = null;
20700 this._didCommit = false;
20701 // TODO: Avoid need to bind by replacing callbacks in the update queue with
20702 // list of Work objects.
20703 this._onCommit = this._onCommit.bind(this);
20704}
20705ReactWork.prototype.then = function (onCommit) {
20706 if (this._didCommit) {
20707 onCommit();
20708 return;
20709 }
20710 var callbacks = this._callbacks;
20711 if (callbacks === null) {
20712 callbacks = this._callbacks = [];
20713 }
20714 callbacks.push(onCommit);
20715};
20716ReactWork.prototype._onCommit = function () {
20717 if (this._didCommit) {
20718 return;
20719 }
20720 this._didCommit = true;
20721 var callbacks = this._callbacks;
20722 if (callbacks === null) {
20723 return;
20724 }
20725 // TODO: Error handling.
20726 for (var i = 0; i < callbacks.length; i++) {
20727 var _callback2 = callbacks[i];
20728 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
20729 _callback2();
20730 }
20731};
20732
20733function ReactRoot(container, isConcurrent, hydrate) {
20734 var root = createContainer(container, isConcurrent, hydrate);
20735 this._internalRoot = root;
20736}
20737ReactRoot.prototype.render = function (children, callback) {
20738 var root = this._internalRoot;
20739 var work = new ReactWork();
20740 callback = callback === undefined ? null : callback;
20741 {
20742 warnOnInvalidCallback(callback, 'render');
20743 }
20744 if (callback !== null) {
20745 work.then(callback);
20746 }
20747 updateContainer(children, root, null, work._onCommit);
20748 return work;
20749};
20750ReactRoot.prototype.unmount = function (callback) {
20751 var root = this._internalRoot;
20752 var work = new ReactWork();
20753 callback = callback === undefined ? null : callback;
20754 {
20755 warnOnInvalidCallback(callback, 'render');
20756 }
20757 if (callback !== null) {
20758 work.then(callback);
20759 }
20760 updateContainer(null, root, null, work._onCommit);
20761 return work;
20762};
20763ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
20764 var root = this._internalRoot;
20765 var work = new ReactWork();
20766 callback = callback === undefined ? null : callback;
20767 {
20768 warnOnInvalidCallback(callback, 'render');
20769 }
20770 if (callback !== null) {
20771 work.then(callback);
20772 }
20773 updateContainer(children, root, parentComponent, work._onCommit);
20774 return work;
20775};
20776ReactRoot.prototype.createBatch = function () {
20777 var batch = new ReactBatch(this);
20778 var expirationTime = batch._expirationTime;
20779
20780 var internalRoot = this._internalRoot;
20781 var firstBatch = internalRoot.firstBatch;
20782 if (firstBatch === null) {
20783 internalRoot.firstBatch = batch;
20784 batch._next = null;
20785 } else {
20786 // Insert sorted by expiration time then insertion order
20787 var insertAfter = null;
20788 var insertBefore = firstBatch;
20789 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
20790 insertAfter = insertBefore;
20791 insertBefore = insertBefore._next;
20792 }
20793 batch._next = insertBefore;
20794 if (insertAfter !== null) {
20795 insertAfter._next = batch;
20796 }
20797 }
20798
20799 return batch;
20800};
20801
20802/**
20803 * True if the supplied DOM node is a valid node element.
20804 *
20805 * @param {?DOMElement} node The candidate DOM node.
20806 * @return {boolean} True if the DOM is a valid DOM node.
20807 * @internal
20808 */
20809function isValidContainer(node) {
20810 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 '));
20811}
20812
20813function getReactRootElementInContainer(container) {
20814 if (!container) {
20815 return null;
20816 }
20817
20818 if (container.nodeType === DOCUMENT_NODE) {
20819 return container.documentElement;
20820 } else {
20821 return container.firstChild;
20822 }
20823}
20824
20825function shouldHydrateDueToLegacyHeuristic(container) {
20826 var rootElement = getReactRootElementInContainer(container);
20827 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
20828}
20829
20830setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1);
20831
20832var warnedAboutHydrateAPI = false;
20833
20834function legacyCreateRootFromDOMContainer(container, forceHydrate) {
20835 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
20836 // First clear any existing content.
20837 if (!shouldHydrate) {
20838 var warned = false;
20839 var rootSibling = void 0;
20840 while (rootSibling = container.lastChild) {
20841 {
20842 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
20843 warned = true;
20844 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.');
20845 }
20846 }
20847 container.removeChild(rootSibling);
20848 }
20849 }
20850 {
20851 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
20852 warnedAboutHydrateAPI = true;
20853 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.');
20854 }
20855 }
20856 // Legacy roots are not async by default.
20857 var isConcurrent = false;
20858 return new ReactRoot(container, isConcurrent, shouldHydrate);
20859}
20860
20861function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
20862 {
20863 topLevelUpdateWarnings(container);
20864 }
20865
20866 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
20867 // member of intersection type." Whyyyyyy.
20868 var root = container._reactRootContainer;
20869 if (!root) {
20870 // Initial mount
20871 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
20872 if (typeof callback === 'function') {
20873 var originalCallback = callback;
20874 callback = function () {
20875 var instance = getPublicRootInstance(root._internalRoot);
20876 originalCallback.call(instance);
20877 };
20878 }
20879 // Initial mount should not be batched.
20880 unbatchedUpdates(function () {
20881 if (parentComponent != null) {
20882 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20883 } else {
20884 root.render(children, callback);
20885 }
20886 });
20887 } else {
20888 if (typeof callback === 'function') {
20889 var _originalCallback = callback;
20890 callback = function () {
20891 var instance = getPublicRootInstance(root._internalRoot);
20892 _originalCallback.call(instance);
20893 };
20894 }
20895 // Update
20896 if (parentComponent != null) {
20897 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20898 } else {
20899 root.render(children, callback);
20900 }
20901 }
20902 return getPublicRootInstance(root._internalRoot);
20903}
20904
20905function createPortal$$1(children, container) {
20906 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
20907
20908 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20909 // TODO: pass ReactDOM portal implementation as third argument
20910 return createPortal$1(children, container, null, key);
20911}
20912
20913var ReactDOM = {
20914 createPortal: createPortal$$1,
20915
20916 findDOMNode: function (componentOrElement) {
20917 {
20918 var owner = ReactCurrentOwner.current;
20919 if (owner !== null && owner.stateNode !== null) {
20920 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
20921 !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;
20922 owner.stateNode._warnedAboutRefsInRender = true;
20923 }
20924 }
20925 if (componentOrElement == null) {
20926 return null;
20927 }
20928 if (componentOrElement.nodeType === ELEMENT_NODE) {
20929 return componentOrElement;
20930 }
20931 {
20932 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
20933 }
20934 return findHostInstance(componentOrElement);
20935 },
20936 hydrate: function (element, container, callback) {
20937 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20938 {
20939 !!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;
20940 }
20941 // TODO: throw or warn if we couldn't hydrate?
20942 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
20943 },
20944 render: function (element, container, callback) {
20945 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20946 {
20947 !!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;
20948 }
20949 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
20950 },
20951 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
20952 !isValidContainer(containerNode) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20953 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0;
20954 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
20955 },
20956 unmountComponentAtNode: function (container) {
20957 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
20958
20959 {
20960 !!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;
20961 }
20962
20963 if (container._reactRootContainer) {
20964 {
20965 var rootEl = getReactRootElementInContainer(container);
20966 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
20967 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
20968 }
20969
20970 // Unmount should not be batched.
20971 unbatchedUpdates(function () {
20972 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
20973 container._reactRootContainer = null;
20974 });
20975 });
20976 // If you call unmountComponentAtNode twice in quick succession, you'll
20977 // get `true` twice. That's probably fine?
20978 return true;
20979 } else {
20980 {
20981 var _rootEl = getReactRootElementInContainer(container);
20982 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
20983
20984 // Check if the container itself is a React root node.
20985 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
20986
20987 !!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;
20988 }
20989
20990 return false;
20991 }
20992 },
20993
20994
20995 // Temporary alias since we already shipped React 16 RC with it.
20996 // TODO: remove in React 17.
20997 unstable_createPortal: function () {
20998 if (!didWarnAboutUnstableCreatePortal) {
20999 didWarnAboutUnstableCreatePortal = true;
21000 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.');
21001 }
21002 return createPortal$$1.apply(undefined, arguments);
21003 },
21004
21005
21006 unstable_batchedUpdates: batchedUpdates$1,
21007
21008 unstable_interactiveUpdates: interactiveUpdates$1,
21009
21010 flushSync: flushSync,
21011
21012 unstable_createRoot: createRoot,
21013 unstable_flushControlled: flushControlled,
21014
21015 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
21016 // Keep in sync with ReactDOMUnstableNativeDependencies.js
21017 // and ReactTestUtils.js. This is an array for better minification.
21018 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch]
21019 }
21020};
21021
21022function createRoot(container, options) {
21023 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
21024 !isValidContainer(container) ? invariant(false, '%s(...): Target container is not a DOM element.', functionName) : void 0;
21025 {
21026 !!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;
21027 container._reactHasBeenPassedToCreateRootDEV = true;
21028 }
21029 var hydrate = options != null && options.hydrate === true;
21030 return new ReactRoot(container, true, hydrate);
21031}
21032
21033if (enableStableConcurrentModeAPIs) {
21034 ReactDOM.createRoot = createRoot;
21035 ReactDOM.unstable_createRoot = undefined;
21036}
21037
21038var foundDevTools = injectIntoDevTools({
21039 findFiberByHostInstance: getClosestInstanceFromNode,
21040 bundleType: 1,
21041 version: ReactVersion,
21042 rendererPackageName: 'react-dom'
21043});
21044
21045{
21046 if (!foundDevTools && canUseDOM && window.top === window.self) {
21047 // If we're in Chrome or Firefox, provide a download link if not installed.
21048 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
21049 var protocol = window.location.protocol;
21050 // Don't warn in exotic cases like chrome-extension://.
21051 if (/^(https?|file):$/.test(protocol)) {
21052 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');
21053 }
21054 }
21055 }
21056}
21057
21058
21059
21060var ReactDOM$2 = Object.freeze({
21061 default: ReactDOM
21062});
21063
21064var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
21065
21066// TODO: decide on the top-level export form.
21067// This is hacky but makes it work with both Rollup and Jest.
21068var reactDom = ReactDOM$3.default || ReactDOM$3;
21069
21070module.exports = reactDom;
21071 })();
21072}