UNPKG

779 kBJavaScriptView Raw
1/** @license React v16.8.2
2 * react-dom-unstable-fire.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// This is just to get the setup running.
9081// TODO: real implementation.
9082// console.log('Hello from Fire host config.');
9083
9084// Prefix measurements so that it's possible to filter them.
9085// Longer prefixes are hard to read in DevTools.
9086var reactEmoji = '\u269B';
9087var warningEmoji = '\u26D4';
9088var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
9089
9090// Keep track of current fiber so that we know the path to unwind on pause.
9091// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
9092var currentFiber = null;
9093// If we're in the middle of user code, which fiber and method is it?
9094// Reusing `currentFiber` would be confusing for this because user code fiber
9095// can change during commit phase too, but we don't need to unwind it (since
9096// lifecycles in the commit phase don't resemble a tree).
9097var currentPhase = null;
9098var currentPhaseFiber = null;
9099// Did lifecycle hook schedule an update? This is often a performance problem,
9100// so we will keep track of it, and include it in the report.
9101// Track commits caused by cascading updates.
9102var isCommitting = false;
9103var hasScheduledUpdateInCurrentCommit = false;
9104var hasScheduledUpdateInCurrentPhase = false;
9105var commitCountInCurrentWorkLoop = 0;
9106var effectCountInCurrentCommit = 0;
9107var isWaitingForCallback = false;
9108// During commits, we only show a measurement once per method name
9109// to avoid stretch the commit phase with measurement overhead.
9110var labelsInCurrentCommit = new Set();
9111
9112var formatMarkName = function (markName) {
9113 return reactEmoji + ' ' + markName;
9114};
9115
9116var formatLabel = function (label, warning) {
9117 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
9118 var suffix = warning ? ' Warning: ' + warning : '';
9119 return '' + prefix + label + suffix;
9120};
9121
9122var beginMark = function (markName) {
9123 performance.mark(formatMarkName(markName));
9124};
9125
9126var clearMark = function (markName) {
9127 performance.clearMarks(formatMarkName(markName));
9128};
9129
9130var endMark = function (label, markName, warning) {
9131 var formattedMarkName = formatMarkName(markName);
9132 var formattedLabel = formatLabel(label, warning);
9133 try {
9134 performance.measure(formattedLabel, formattedMarkName);
9135 } catch (err) {}
9136 // If previous mark was missing for some reason, this will throw.
9137 // This could only happen if React crashed in an unexpected place earlier.
9138 // Don't pile on with more errors.
9139
9140 // Clear marks immediately to avoid growing buffer.
9141 performance.clearMarks(formattedMarkName);
9142 performance.clearMeasures(formattedLabel);
9143};
9144
9145var getFiberMarkName = function (label, debugID) {
9146 return label + ' (#' + debugID + ')';
9147};
9148
9149var getFiberLabel = function (componentName, isMounted, phase) {
9150 if (phase === null) {
9151 // These are composite component total time measurements.
9152 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
9153 } else {
9154 // Composite component methods.
9155 return componentName + '.' + phase;
9156 }
9157};
9158
9159var beginFiberMark = function (fiber, phase) {
9160 var componentName = getComponentName(fiber.type) || 'Unknown';
9161 var debugID = fiber._debugID;
9162 var isMounted = fiber.alternate !== null;
9163 var label = getFiberLabel(componentName, isMounted, phase);
9164
9165 if (isCommitting && labelsInCurrentCommit.has(label)) {
9166 // During the commit phase, we don't show duplicate labels because
9167 // there is a fixed overhead for every measurement, and we don't
9168 // want to stretch the commit phase beyond necessary.
9169 return false;
9170 }
9171 labelsInCurrentCommit.add(label);
9172
9173 var markName = getFiberMarkName(label, debugID);
9174 beginMark(markName);
9175 return true;
9176};
9177
9178var clearFiberMark = function (fiber, phase) {
9179 var componentName = getComponentName(fiber.type) || 'Unknown';
9180 var debugID = fiber._debugID;
9181 var isMounted = fiber.alternate !== null;
9182 var label = getFiberLabel(componentName, isMounted, phase);
9183 var markName = getFiberMarkName(label, debugID);
9184 clearMark(markName);
9185};
9186
9187var endFiberMark = function (fiber, phase, warning) {
9188 var componentName = getComponentName(fiber.type) || 'Unknown';
9189 var debugID = fiber._debugID;
9190 var isMounted = fiber.alternate !== null;
9191 var label = getFiberLabel(componentName, isMounted, phase);
9192 var markName = getFiberMarkName(label, debugID);
9193 endMark(label, markName, warning);
9194};
9195
9196var shouldIgnoreFiber = function (fiber) {
9197 // Host components should be skipped in the timeline.
9198 // We could check typeof fiber.type, but does this work with RN?
9199 switch (fiber.tag) {
9200 case HostRoot:
9201 case HostComponent:
9202 case HostText:
9203 case HostPortal:
9204 case Fragment:
9205 case ContextProvider:
9206 case ContextConsumer:
9207 case Mode:
9208 return true;
9209 default:
9210 return false;
9211 }
9212};
9213
9214var clearPendingPhaseMeasurement = function () {
9215 if (currentPhase !== null && currentPhaseFiber !== null) {
9216 clearFiberMark(currentPhaseFiber, currentPhase);
9217 }
9218 currentPhaseFiber = null;
9219 currentPhase = null;
9220 hasScheduledUpdateInCurrentPhase = false;
9221};
9222
9223var pauseTimers = function () {
9224 // Stops all currently active measurements so that they can be resumed
9225 // if we continue in a later deferred loop from the same unit of work.
9226 var fiber = currentFiber;
9227 while (fiber) {
9228 if (fiber._debugIsCurrentlyTiming) {
9229 endFiberMark(fiber, null, null);
9230 }
9231 fiber = fiber.return;
9232 }
9233};
9234
9235var resumeTimersRecursively = function (fiber) {
9236 if (fiber.return !== null) {
9237 resumeTimersRecursively(fiber.return);
9238 }
9239 if (fiber._debugIsCurrentlyTiming) {
9240 beginFiberMark(fiber, null);
9241 }
9242};
9243
9244var resumeTimers = function () {
9245 // Resumes all measurements that were active during the last deferred loop.
9246 if (currentFiber !== null) {
9247 resumeTimersRecursively(currentFiber);
9248 }
9249};
9250
9251function recordEffect() {
9252 if (enableUserTimingAPI) {
9253 effectCountInCurrentCommit++;
9254 }
9255}
9256
9257function recordScheduleUpdate() {
9258 if (enableUserTimingAPI) {
9259 if (isCommitting) {
9260 hasScheduledUpdateInCurrentCommit = true;
9261 }
9262 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
9263 hasScheduledUpdateInCurrentPhase = true;
9264 }
9265 }
9266}
9267
9268function startRequestCallbackTimer() {
9269 if (enableUserTimingAPI) {
9270 if (supportsUserTiming && !isWaitingForCallback) {
9271 isWaitingForCallback = true;
9272 beginMark('(Waiting for async callback...)');
9273 }
9274 }
9275}
9276
9277function stopRequestCallbackTimer(didExpire, expirationTime) {
9278 if (enableUserTimingAPI) {
9279 if (supportsUserTiming) {
9280 isWaitingForCallback = false;
9281 var warning = didExpire ? 'React was blocked by main thread' : null;
9282 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
9283 }
9284 }
9285}
9286
9287function startWorkTimer(fiber) {
9288 if (enableUserTimingAPI) {
9289 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9290 return;
9291 }
9292 // If we pause, this is the fiber to unwind from.
9293 currentFiber = fiber;
9294 if (!beginFiberMark(fiber, null)) {
9295 return;
9296 }
9297 fiber._debugIsCurrentlyTiming = true;
9298 }
9299}
9300
9301function cancelWorkTimer(fiber) {
9302 if (enableUserTimingAPI) {
9303 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9304 return;
9305 }
9306 // Remember we shouldn't complete measurement for this fiber.
9307 // Otherwise flamechart will be deep even for small updates.
9308 fiber._debugIsCurrentlyTiming = false;
9309 clearFiberMark(fiber, null);
9310 }
9311}
9312
9313function stopWorkTimer(fiber) {
9314 if (enableUserTimingAPI) {
9315 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9316 return;
9317 }
9318 // If we pause, its parent is the fiber to unwind from.
9319 currentFiber = fiber.return;
9320 if (!fiber._debugIsCurrentlyTiming) {
9321 return;
9322 }
9323 fiber._debugIsCurrentlyTiming = false;
9324 endFiberMark(fiber, null, null);
9325 }
9326}
9327
9328function stopFailedWorkTimer(fiber) {
9329 if (enableUserTimingAPI) {
9330 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
9331 return;
9332 }
9333 // If we pause, its parent is the fiber to unwind from.
9334 currentFiber = fiber.return;
9335 if (!fiber._debugIsCurrentlyTiming) {
9336 return;
9337 }
9338 fiber._debugIsCurrentlyTiming = false;
9339 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9340 endFiberMark(fiber, null, warning);
9341 }
9342}
9343
9344function startPhaseTimer(fiber, phase) {
9345 if (enableUserTimingAPI) {
9346 if (!supportsUserTiming) {
9347 return;
9348 }
9349 clearPendingPhaseMeasurement();
9350 if (!beginFiberMark(fiber, phase)) {
9351 return;
9352 }
9353 currentPhaseFiber = fiber;
9354 currentPhase = phase;
9355 }
9356}
9357
9358function stopPhaseTimer() {
9359 if (enableUserTimingAPI) {
9360 if (!supportsUserTiming) {
9361 return;
9362 }
9363 if (currentPhase !== null && currentPhaseFiber !== null) {
9364 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
9365 endFiberMark(currentPhaseFiber, currentPhase, warning);
9366 }
9367 currentPhase = null;
9368 currentPhaseFiber = null;
9369 }
9370}
9371
9372function startWorkLoopTimer(nextUnitOfWork) {
9373 if (enableUserTimingAPI) {
9374 currentFiber = nextUnitOfWork;
9375 if (!supportsUserTiming) {
9376 return;
9377 }
9378 commitCountInCurrentWorkLoop = 0;
9379 // This is top level call.
9380 // Any other measurements are performed within.
9381 beginMark('(React Tree Reconciliation)');
9382 // Resume any measurements that were in progress during the last loop.
9383 resumeTimers();
9384 }
9385}
9386
9387function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
9388 if (enableUserTimingAPI) {
9389 if (!supportsUserTiming) {
9390 return;
9391 }
9392 var warning = null;
9393 if (interruptedBy !== null) {
9394 if (interruptedBy.tag === HostRoot) {
9395 warning = 'A top-level update interrupted the previous render';
9396 } else {
9397 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
9398 warning = 'An update to ' + componentName + ' interrupted the previous render';
9399 }
9400 } else if (commitCountInCurrentWorkLoop > 1) {
9401 warning = 'There were cascading updates';
9402 }
9403 commitCountInCurrentWorkLoop = 0;
9404 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
9405 // Pause any measurements until the next loop.
9406 pauseTimers();
9407 endMark(label, '(React Tree Reconciliation)', warning);
9408 }
9409}
9410
9411function startCommitTimer() {
9412 if (enableUserTimingAPI) {
9413 if (!supportsUserTiming) {
9414 return;
9415 }
9416 isCommitting = true;
9417 hasScheduledUpdateInCurrentCommit = false;
9418 labelsInCurrentCommit.clear();
9419 beginMark('(Committing Changes)');
9420 }
9421}
9422
9423function stopCommitTimer() {
9424 if (enableUserTimingAPI) {
9425 if (!supportsUserTiming) {
9426 return;
9427 }
9428
9429 var warning = null;
9430 if (hasScheduledUpdateInCurrentCommit) {
9431 warning = 'Lifecycle hook scheduled a cascading update';
9432 } else if (commitCountInCurrentWorkLoop > 0) {
9433 warning = 'Caused by a cascading update in earlier commit';
9434 }
9435 hasScheduledUpdateInCurrentCommit = false;
9436 commitCountInCurrentWorkLoop++;
9437 isCommitting = false;
9438 labelsInCurrentCommit.clear();
9439
9440 endMark('(Committing Changes)', '(Committing Changes)', warning);
9441 }
9442}
9443
9444function startCommitSnapshotEffectsTimer() {
9445 if (enableUserTimingAPI) {
9446 if (!supportsUserTiming) {
9447 return;
9448 }
9449 effectCountInCurrentCommit = 0;
9450 beginMark('(Committing Snapshot Effects)');
9451 }
9452}
9453
9454function stopCommitSnapshotEffectsTimer() {
9455 if (enableUserTimingAPI) {
9456 if (!supportsUserTiming) {
9457 return;
9458 }
9459 var count = effectCountInCurrentCommit;
9460 effectCountInCurrentCommit = 0;
9461 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
9462 }
9463}
9464
9465function startCommitHostEffectsTimer() {
9466 if (enableUserTimingAPI) {
9467 if (!supportsUserTiming) {
9468 return;
9469 }
9470 effectCountInCurrentCommit = 0;
9471 beginMark('(Committing Host Effects)');
9472 }
9473}
9474
9475function stopCommitHostEffectsTimer() {
9476 if (enableUserTimingAPI) {
9477 if (!supportsUserTiming) {
9478 return;
9479 }
9480 var count = effectCountInCurrentCommit;
9481 effectCountInCurrentCommit = 0;
9482 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
9483 }
9484}
9485
9486function startCommitLifeCyclesTimer() {
9487 if (enableUserTimingAPI) {
9488 if (!supportsUserTiming) {
9489 return;
9490 }
9491 effectCountInCurrentCommit = 0;
9492 beginMark('(Calling Lifecycle Methods)');
9493 }
9494}
9495
9496function stopCommitLifeCyclesTimer() {
9497 if (enableUserTimingAPI) {
9498 if (!supportsUserTiming) {
9499 return;
9500 }
9501 var count = effectCountInCurrentCommit;
9502 effectCountInCurrentCommit = 0;
9503 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
9504 }
9505}
9506
9507var valueStack = [];
9508
9509var fiberStack = void 0;
9510
9511{
9512 fiberStack = [];
9513}
9514
9515var index = -1;
9516
9517function createCursor(defaultValue) {
9518 return {
9519 current: defaultValue
9520 };
9521}
9522
9523function pop(cursor, fiber) {
9524 if (index < 0) {
9525 {
9526 warningWithoutStack$1(false, 'Unexpected pop.');
9527 }
9528 return;
9529 }
9530
9531 {
9532 if (fiber !== fiberStack[index]) {
9533 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
9534 }
9535 }
9536
9537 cursor.current = valueStack[index];
9538
9539 valueStack[index] = null;
9540
9541 {
9542 fiberStack[index] = null;
9543 }
9544
9545 index--;
9546}
9547
9548function push(cursor, value, fiber) {
9549 index++;
9550
9551 valueStack[index] = cursor.current;
9552
9553 {
9554 fiberStack[index] = fiber;
9555 }
9556
9557 cursor.current = value;
9558}
9559
9560function checkThatStackIsEmpty() {
9561 {
9562 if (index !== -1) {
9563 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
9564 }
9565 }
9566}
9567
9568function resetStackAfterFatalErrorInDev() {
9569 {
9570 index = -1;
9571 valueStack.length = 0;
9572 fiberStack.length = 0;
9573 }
9574}
9575
9576var warnedAboutMissingGetChildContext = void 0;
9577
9578{
9579 warnedAboutMissingGetChildContext = {};
9580}
9581
9582var emptyContextObject = {};
9583{
9584 Object.freeze(emptyContextObject);
9585}
9586
9587// A cursor to the current merged context object on the stack.
9588var contextStackCursor = createCursor(emptyContextObject);
9589// A cursor to a boolean indicating whether the context has changed.
9590var didPerformWorkStackCursor = createCursor(false);
9591// Keep track of the previous context object that was on the stack.
9592// We use this to get access to the parent context after we have already
9593// pushed the next context provider, and now need to merge their contexts.
9594var previousContext = emptyContextObject;
9595
9596function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
9597 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
9598 // If the fiber is a context provider itself, when we read its context
9599 // we may have already pushed its own child context on the stack. A context
9600 // provider should not "see" its own child context. Therefore we read the
9601 // previous (parent) context instead for a context provider.
9602 return previousContext;
9603 }
9604 return contextStackCursor.current;
9605}
9606
9607function cacheContext(workInProgress, unmaskedContext, maskedContext) {
9608 var instance = workInProgress.stateNode;
9609 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
9610 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
9611}
9612
9613function getMaskedContext(workInProgress, unmaskedContext) {
9614 var type = workInProgress.type;
9615 var contextTypes = type.contextTypes;
9616 if (!contextTypes) {
9617 return emptyContextObject;
9618 }
9619
9620 // Avoid recreating masked context unless unmasked context has changed.
9621 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
9622 // This may trigger infinite loops if componentWillReceiveProps calls setState.
9623 var instance = workInProgress.stateNode;
9624 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
9625 return instance.__reactInternalMemoizedMaskedChildContext;
9626 }
9627
9628 var context = {};
9629 for (var key in contextTypes) {
9630 context[key] = unmaskedContext[key];
9631 }
9632
9633 {
9634 var name = getComponentName(type) || 'Unknown';
9635 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
9636 }
9637
9638 // Cache unmasked context so we can avoid recreating masked context unless necessary.
9639 // Context is created before the class component is instantiated so check for instance.
9640 if (instance) {
9641 cacheContext(workInProgress, unmaskedContext, context);
9642 }
9643
9644 return context;
9645}
9646
9647function hasContextChanged() {
9648 return didPerformWorkStackCursor.current;
9649}
9650
9651function isContextProvider(type) {
9652 var childContextTypes = type.childContextTypes;
9653 return childContextTypes !== null && childContextTypes !== undefined;
9654}
9655
9656function popContext(fiber) {
9657 pop(didPerformWorkStackCursor, fiber);
9658 pop(contextStackCursor, fiber);
9659}
9660
9661function popTopLevelContextObject(fiber) {
9662 pop(didPerformWorkStackCursor, fiber);
9663 pop(contextStackCursor, fiber);
9664}
9665
9666function pushTopLevelContextObject(fiber, context, didChange) {
9667 !(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;
9668
9669 push(contextStackCursor, context, fiber);
9670 push(didPerformWorkStackCursor, didChange, fiber);
9671}
9672
9673function processChildContext(fiber, type, parentContext) {
9674 var instance = fiber.stateNode;
9675 var childContextTypes = type.childContextTypes;
9676
9677 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
9678 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
9679 if (typeof instance.getChildContext !== 'function') {
9680 {
9681 var componentName = getComponentName(type) || 'Unknown';
9682
9683 if (!warnedAboutMissingGetChildContext[componentName]) {
9684 warnedAboutMissingGetChildContext[componentName] = true;
9685 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);
9686 }
9687 }
9688 return parentContext;
9689 }
9690
9691 var childContext = void 0;
9692 {
9693 setCurrentPhase('getChildContext');
9694 }
9695 startPhaseTimer(fiber, 'getChildContext');
9696 childContext = instance.getChildContext();
9697 stopPhaseTimer();
9698 {
9699 setCurrentPhase(null);
9700 }
9701 for (var contextKey in childContext) {
9702 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
9703 }
9704 {
9705 var name = getComponentName(type) || 'Unknown';
9706 checkPropTypes(childContextTypes, childContext, 'child context', name,
9707 // In practice, there is one case in which we won't get a stack. It's when
9708 // somebody calls unstable_renderSubtreeIntoContainer() and we process
9709 // context from the parent component instance. The stack will be missing
9710 // because it's outside of the reconciliation, and so the pointer has not
9711 // been set. This is rare and doesn't matter. We'll also remove that API.
9712 getCurrentFiberStackInDev);
9713 }
9714
9715 return _assign({}, parentContext, childContext);
9716}
9717
9718function pushContextProvider(workInProgress) {
9719 var instance = workInProgress.stateNode;
9720 // We push the context as early as possible to ensure stack integrity.
9721 // If the instance does not exist yet, we will push null at first,
9722 // and replace it on the stack later when invalidating the context.
9723 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
9724
9725 // Remember the parent context so we can merge with it later.
9726 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
9727 previousContext = contextStackCursor.current;
9728 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
9729 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
9730
9731 return true;
9732}
9733
9734function invalidateContextProvider(workInProgress, type, didChange) {
9735 var instance = workInProgress.stateNode;
9736 !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;
9737
9738 if (didChange) {
9739 // Merge parent and own context.
9740 // Skip this if we're not updating due to sCU.
9741 // This avoids unnecessarily recomputing memoized values.
9742 var mergedContext = processChildContext(workInProgress, type, previousContext);
9743 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
9744
9745 // Replace the old (or empty) context with the new one.
9746 // It is important to unwind the context in the reverse order.
9747 pop(didPerformWorkStackCursor, workInProgress);
9748 pop(contextStackCursor, workInProgress);
9749 // Now push the new context and mark that it has changed.
9750 push(contextStackCursor, mergedContext, workInProgress);
9751 push(didPerformWorkStackCursor, didChange, workInProgress);
9752 } else {
9753 pop(didPerformWorkStackCursor, workInProgress);
9754 push(didPerformWorkStackCursor, didChange, workInProgress);
9755 }
9756}
9757
9758function findCurrentUnmaskedContext(fiber) {
9759 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
9760 // makes sense elsewhere
9761 !(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;
9762
9763 var node = fiber;
9764 do {
9765 switch (node.tag) {
9766 case HostRoot:
9767 return node.stateNode.context;
9768 case ClassComponent:
9769 {
9770 var Component = node.type;
9771 if (isContextProvider(Component)) {
9772 return node.stateNode.__reactInternalMemoizedMergedChildContext;
9773 }
9774 break;
9775 }
9776 }
9777 node = node.return;
9778 } while (node !== null);
9779 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
9780}
9781
9782var onCommitFiberRoot = null;
9783var onCommitFiberUnmount = null;
9784var hasLoggedError = false;
9785
9786function catchErrors(fn) {
9787 return function (arg) {
9788 try {
9789 return fn(arg);
9790 } catch (err) {
9791 if (true && !hasLoggedError) {
9792 hasLoggedError = true;
9793 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
9794 }
9795 }
9796 };
9797}
9798
9799var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
9800
9801function injectInternals(internals) {
9802 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
9803 // No DevTools
9804 return false;
9805 }
9806 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9807 if (hook.isDisabled) {
9808 // This isn't a real property on the hook, but it can be set to opt out
9809 // of DevTools integration and associated warnings and logs.
9810 // https://github.com/facebook/react/issues/3877
9811 return true;
9812 }
9813 if (!hook.supportsFiber) {
9814 {
9815 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');
9816 }
9817 // DevTools exists, even though it doesn't support Fiber.
9818 return true;
9819 }
9820 try {
9821 var rendererID = hook.inject(internals);
9822 // We have successfully injected, so now it is safe to set up hooks.
9823 onCommitFiberRoot = catchErrors(function (root) {
9824 return hook.onCommitFiberRoot(rendererID, root);
9825 });
9826 onCommitFiberUnmount = catchErrors(function (fiber) {
9827 return hook.onCommitFiberUnmount(rendererID, fiber);
9828 });
9829 } catch (err) {
9830 // Catch all errors because it is unsafe to throw during initialization.
9831 {
9832 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
9833 }
9834 }
9835 // DevTools exists
9836 return true;
9837}
9838
9839function onCommitRoot(root) {
9840 if (typeof onCommitFiberRoot === 'function') {
9841 onCommitFiberRoot(root);
9842 }
9843}
9844
9845function onCommitUnmount(fiber) {
9846 if (typeof onCommitFiberUnmount === 'function') {
9847 onCommitFiberUnmount(fiber);
9848 }
9849}
9850
9851// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
9852// Math.pow(2, 30) - 1
9853// 0b111111111111111111111111111111
9854var maxSigned31BitInt = 1073741823;
9855
9856var NoWork = 0;
9857var Never = 1;
9858var Sync = maxSigned31BitInt;
9859
9860var UNIT_SIZE = 10;
9861var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
9862
9863// 1 unit of expiration time represents 10ms.
9864function msToExpirationTime(ms) {
9865 // Always add an offset so that we don't clash with the magic number for NoWork.
9866 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
9867}
9868
9869function expirationTimeToMs(expirationTime) {
9870 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
9871}
9872
9873function ceiling(num, precision) {
9874 return ((num / precision | 0) + 1) * precision;
9875}
9876
9877function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
9878 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
9879}
9880
9881var LOW_PRIORITY_EXPIRATION = 5000;
9882var LOW_PRIORITY_BATCH_SIZE = 250;
9883
9884function computeAsyncExpiration(currentTime) {
9885 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
9886}
9887
9888// We intentionally set a higher expiration time for interactive updates in
9889// dev than in production.
9890//
9891// If the main thread is being blocked so long that you hit the expiration,
9892// it's a problem that could be solved with better scheduling.
9893//
9894// People will be more likely to notice this and fix it with the long
9895// expiration time in development.
9896//
9897// In production we opt for better UX at the risk of masking scheduling
9898// problems, by expiring fast.
9899var HIGH_PRIORITY_EXPIRATION = 500;
9900var HIGH_PRIORITY_BATCH_SIZE = 100;
9901
9902function computeInteractiveExpiration(currentTime) {
9903 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
9904}
9905
9906var NoContext = 0;
9907var ConcurrentMode = 1;
9908var StrictMode = 2;
9909var ProfileMode = 4;
9910
9911var hasBadMapPolyfill = void 0;
9912
9913{
9914 hasBadMapPolyfill = false;
9915 try {
9916 var nonExtensibleObject = Object.preventExtensions({});
9917 var testMap = new Map([[nonExtensibleObject, null]]);
9918 var testSet = new Set([nonExtensibleObject]);
9919 // This is necessary for Rollup to not consider these unused.
9920 // https://github.com/rollup/rollup/issues/1771
9921 // TODO: we can remove these if Rollup fixes the bug.
9922 testMap.set(0, 0);
9923 testSet.add(0);
9924 } catch (e) {
9925 // TODO: Consider warning about bad polyfills
9926 hasBadMapPolyfill = true;
9927 }
9928}
9929
9930// A Fiber is work on a Component that needs to be done or was done. There can
9931// be more than one per component.
9932
9933
9934var debugCounter = void 0;
9935
9936{
9937 debugCounter = 1;
9938}
9939
9940function FiberNode(tag, pendingProps, key, mode) {
9941 // Instance
9942 this.tag = tag;
9943 this.key = key;
9944 this.elementType = null;
9945 this.type = null;
9946 this.stateNode = null;
9947
9948 // Fiber
9949 this.return = null;
9950 this.child = null;
9951 this.sibling = null;
9952 this.index = 0;
9953
9954 this.ref = null;
9955
9956 this.pendingProps = pendingProps;
9957 this.memoizedProps = null;
9958 this.updateQueue = null;
9959 this.memoizedState = null;
9960 this.contextDependencies = null;
9961
9962 this.mode = mode;
9963
9964 // Effects
9965 this.effectTag = NoEffect;
9966 this.nextEffect = null;
9967
9968 this.firstEffect = null;
9969 this.lastEffect = null;
9970
9971 this.expirationTime = NoWork;
9972 this.childExpirationTime = NoWork;
9973
9974 this.alternate = null;
9975
9976 if (enableProfilerTimer) {
9977 // Note: The following is done to avoid a v8 performance cliff.
9978 //
9979 // Initializing the fields below to smis and later updating them with
9980 // double values will cause Fibers to end up having separate shapes.
9981 // This behavior/bug has something to do with Object.preventExtension().
9982 // Fortunately this only impacts DEV builds.
9983 // Unfortunately it makes React unusably slow for some applications.
9984 // To work around this, initialize the fields below with doubles.
9985 //
9986 // Learn more about this here:
9987 // https://github.com/facebook/react/issues/14365
9988 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
9989 this.actualDuration = Number.NaN;
9990 this.actualStartTime = Number.NaN;
9991 this.selfBaseDuration = Number.NaN;
9992 this.treeBaseDuration = Number.NaN;
9993
9994 // It's okay to replace the initial doubles with smis after initialization.
9995 // This won't trigger the performance cliff mentioned above,
9996 // and it simplifies other profiler code (including DevTools).
9997 this.actualDuration = 0;
9998 this.actualStartTime = -1;
9999 this.selfBaseDuration = 0;
10000 this.treeBaseDuration = 0;
10001 }
10002
10003 {
10004 this._debugID = debugCounter++;
10005 this._debugSource = null;
10006 this._debugOwner = null;
10007 this._debugIsCurrentlyTiming = false;
10008 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10009 Object.preventExtensions(this);
10010 }
10011 }
10012}
10013
10014// This is a constructor function, rather than a POJO constructor, still
10015// please ensure we do the following:
10016// 1) Nobody should add any instance methods on this. Instance methods can be
10017// more difficult to predict when they get optimized and they are almost
10018// never inlined properly in static compilers.
10019// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
10020// always know when it is a fiber.
10021// 3) We might want to experiment with using numeric keys since they are easier
10022// to optimize in a non-JIT environment.
10023// 4) We can easily go from a constructor to a createFiber object literal if that
10024// is faster.
10025// 5) It should be easy to port this to a C struct and keep a C implementation
10026// compatible.
10027var createFiber = function (tag, pendingProps, key, mode) {
10028 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
10029 return new FiberNode(tag, pendingProps, key, mode);
10030};
10031
10032function shouldConstruct(Component) {
10033 var prototype = Component.prototype;
10034 return !!(prototype && prototype.isReactComponent);
10035}
10036
10037function isSimpleFunctionComponent(type) {
10038 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
10039}
10040
10041function resolveLazyComponentTag(Component) {
10042 if (typeof Component === 'function') {
10043 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
10044 } else if (Component !== undefined && Component !== null) {
10045 var $$typeof = Component.$$typeof;
10046 if ($$typeof === REACT_FORWARD_REF_TYPE) {
10047 return ForwardRef;
10048 }
10049 if ($$typeof === REACT_MEMO_TYPE) {
10050 return MemoComponent;
10051 }
10052 }
10053 return IndeterminateComponent;
10054}
10055
10056// This is used to create an alternate fiber to do work on.
10057function createWorkInProgress(current, pendingProps, expirationTime) {
10058 var workInProgress = current.alternate;
10059 if (workInProgress === null) {
10060 // We use a double buffering pooling technique because we know that we'll
10061 // only ever need at most two versions of a tree. We pool the "other" unused
10062 // node that we're free to reuse. This is lazily created to avoid allocating
10063 // extra objects for things that are never updated. It also allow us to
10064 // reclaim the extra memory if needed.
10065 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
10066 workInProgress.elementType = current.elementType;
10067 workInProgress.type = current.type;
10068 workInProgress.stateNode = current.stateNode;
10069
10070 {
10071 // DEV-only fields
10072 workInProgress._debugID = current._debugID;
10073 workInProgress._debugSource = current._debugSource;
10074 workInProgress._debugOwner = current._debugOwner;
10075 }
10076
10077 workInProgress.alternate = current;
10078 current.alternate = workInProgress;
10079 } else {
10080 workInProgress.pendingProps = pendingProps;
10081
10082 // We already have an alternate.
10083 // Reset the effect tag.
10084 workInProgress.effectTag = NoEffect;
10085
10086 // The effect list is no longer valid.
10087 workInProgress.nextEffect = null;
10088 workInProgress.firstEffect = null;
10089 workInProgress.lastEffect = null;
10090
10091 if (enableProfilerTimer) {
10092 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
10093 // This prevents time from endlessly accumulating in new commits.
10094 // This has the downside of resetting values for different priority renders,
10095 // But works for yielding (the common case) and should support resuming.
10096 workInProgress.actualDuration = 0;
10097 workInProgress.actualStartTime = -1;
10098 }
10099 }
10100
10101 workInProgress.childExpirationTime = current.childExpirationTime;
10102 workInProgress.expirationTime = current.expirationTime;
10103
10104 workInProgress.child = current.child;
10105 workInProgress.memoizedProps = current.memoizedProps;
10106 workInProgress.memoizedState = current.memoizedState;
10107 workInProgress.updateQueue = current.updateQueue;
10108 workInProgress.contextDependencies = current.contextDependencies;
10109
10110 // These will be overridden during the parent's reconciliation
10111 workInProgress.sibling = current.sibling;
10112 workInProgress.index = current.index;
10113 workInProgress.ref = current.ref;
10114
10115 if (enableProfilerTimer) {
10116 workInProgress.selfBaseDuration = current.selfBaseDuration;
10117 workInProgress.treeBaseDuration = current.treeBaseDuration;
10118 }
10119
10120 return workInProgress;
10121}
10122
10123function createHostRootFiber(isConcurrent) {
10124 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
10125
10126 if (enableProfilerTimer && isDevToolsPresent) {
10127 // Always collect profile timings when DevTools are present.
10128 // This enables DevTools to start capturing timing at any point–
10129 // Without some nodes in the tree having empty base times.
10130 mode |= ProfileMode;
10131 }
10132
10133 return createFiber(HostRoot, null, null, mode);
10134}
10135
10136function createFiberFromTypeAndProps(type, // React$ElementType
10137key, pendingProps, owner, mode, expirationTime) {
10138 var fiber = void 0;
10139
10140 var fiberTag = IndeterminateComponent;
10141 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
10142 var resolvedType = type;
10143 if (typeof type === 'function') {
10144 if (shouldConstruct(type)) {
10145 fiberTag = ClassComponent;
10146 }
10147 } else if (typeof type === 'string') {
10148 fiberTag = HostComponent;
10149 } else {
10150 getTag: switch (type) {
10151 case REACT_FRAGMENT_TYPE:
10152 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
10153 case REACT_CONCURRENT_MODE_TYPE:
10154 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
10155 case REACT_STRICT_MODE_TYPE:
10156 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
10157 case REACT_PROFILER_TYPE:
10158 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
10159 case REACT_SUSPENSE_TYPE:
10160 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
10161 default:
10162 {
10163 if (typeof type === 'object' && type !== null) {
10164 switch (type.$$typeof) {
10165 case REACT_PROVIDER_TYPE:
10166 fiberTag = ContextProvider;
10167 break getTag;
10168 case REACT_CONTEXT_TYPE:
10169 // This is a consumer
10170 fiberTag = ContextConsumer;
10171 break getTag;
10172 case REACT_FORWARD_REF_TYPE:
10173 fiberTag = ForwardRef;
10174 break getTag;
10175 case REACT_MEMO_TYPE:
10176 fiberTag = MemoComponent;
10177 break getTag;
10178 case REACT_LAZY_TYPE:
10179 fiberTag = LazyComponent;
10180 resolvedType = null;
10181 break getTag;
10182 }
10183 }
10184 var info = '';
10185 {
10186 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
10187 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.';
10188 }
10189 var ownerName = owner ? getComponentName(owner.type) : null;
10190 if (ownerName) {
10191 info += '\n\nCheck the render method of `' + ownerName + '`.';
10192 }
10193 }
10194 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);
10195 }
10196 }
10197 }
10198
10199 fiber = createFiber(fiberTag, pendingProps, key, mode);
10200 fiber.elementType = type;
10201 fiber.type = resolvedType;
10202 fiber.expirationTime = expirationTime;
10203
10204 return fiber;
10205}
10206
10207function createFiberFromElement(element, mode, expirationTime) {
10208 var owner = null;
10209 {
10210 owner = element._owner;
10211 }
10212 var type = element.type;
10213 var key = element.key;
10214 var pendingProps = element.props;
10215 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
10216 {
10217 fiber._debugSource = element._source;
10218 fiber._debugOwner = element._owner;
10219 }
10220 return fiber;
10221}
10222
10223function createFiberFromFragment(elements, mode, expirationTime, key) {
10224 var fiber = createFiber(Fragment, elements, key, mode);
10225 fiber.expirationTime = expirationTime;
10226 return fiber;
10227}
10228
10229function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
10230 {
10231 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
10232 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
10233 }
10234 }
10235
10236 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
10237 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
10238 fiber.elementType = REACT_PROFILER_TYPE;
10239 fiber.type = REACT_PROFILER_TYPE;
10240 fiber.expirationTime = expirationTime;
10241
10242 return fiber;
10243}
10244
10245function createFiberFromMode(pendingProps, mode, expirationTime, key) {
10246 var fiber = createFiber(Mode, pendingProps, key, mode);
10247
10248 // TODO: The Mode fiber shouldn't have a type. It has a tag.
10249 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
10250 fiber.elementType = type;
10251 fiber.type = type;
10252
10253 fiber.expirationTime = expirationTime;
10254 return fiber;
10255}
10256
10257function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
10258 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
10259
10260 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
10261 var type = REACT_SUSPENSE_TYPE;
10262 fiber.elementType = type;
10263 fiber.type = type;
10264
10265 fiber.expirationTime = expirationTime;
10266 return fiber;
10267}
10268
10269function createFiberFromText(content, mode, expirationTime) {
10270 var fiber = createFiber(HostText, content, null, mode);
10271 fiber.expirationTime = expirationTime;
10272 return fiber;
10273}
10274
10275function createFiberFromHostInstanceForDeletion() {
10276 var fiber = createFiber(HostComponent, null, null, NoContext);
10277 // TODO: These should not need a type.
10278 fiber.elementType = 'DELETED';
10279 fiber.type = 'DELETED';
10280 return fiber;
10281}
10282
10283function createFiberFromPortal(portal, mode, expirationTime) {
10284 var pendingProps = portal.children !== null ? portal.children : [];
10285 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
10286 fiber.expirationTime = expirationTime;
10287 fiber.stateNode = {
10288 containerInfo: portal.containerInfo,
10289 pendingChildren: null, // Used by persistent updates
10290 implementation: portal.implementation
10291 };
10292 return fiber;
10293}
10294
10295// Used for stashing WIP properties to replay failed work in DEV.
10296function assignFiberPropertiesInDEV(target, source) {
10297 if (target === null) {
10298 // This Fiber's initial properties will always be overwritten.
10299 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
10300 target = createFiber(IndeterminateComponent, null, null, NoContext);
10301 }
10302
10303 // This is intentionally written as a list of all properties.
10304 // We tried to use Object.assign() instead but this is called in
10305 // the hottest path, and Object.assign() was too slow:
10306 // https://github.com/facebook/react/issues/12502
10307 // This code is DEV-only so size is not a concern.
10308
10309 target.tag = source.tag;
10310 target.key = source.key;
10311 target.elementType = source.elementType;
10312 target.type = source.type;
10313 target.stateNode = source.stateNode;
10314 target.return = source.return;
10315 target.child = source.child;
10316 target.sibling = source.sibling;
10317 target.index = source.index;
10318 target.ref = source.ref;
10319 target.pendingProps = source.pendingProps;
10320 target.memoizedProps = source.memoizedProps;
10321 target.updateQueue = source.updateQueue;
10322 target.memoizedState = source.memoizedState;
10323 target.contextDependencies = source.contextDependencies;
10324 target.mode = source.mode;
10325 target.effectTag = source.effectTag;
10326 target.nextEffect = source.nextEffect;
10327 target.firstEffect = source.firstEffect;
10328 target.lastEffect = source.lastEffect;
10329 target.expirationTime = source.expirationTime;
10330 target.childExpirationTime = source.childExpirationTime;
10331 target.alternate = source.alternate;
10332 if (enableProfilerTimer) {
10333 target.actualDuration = source.actualDuration;
10334 target.actualStartTime = source.actualStartTime;
10335 target.selfBaseDuration = source.selfBaseDuration;
10336 target.treeBaseDuration = source.treeBaseDuration;
10337 }
10338 target._debugID = source._debugID;
10339 target._debugSource = source._debugSource;
10340 target._debugOwner = source._debugOwner;
10341 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10342 return target;
10343}
10344
10345// TODO: This should be lifted into the renderer.
10346
10347
10348// The following attributes are only used by interaction tracing builds.
10349// They enable interactions to be associated with their async work,
10350// And expose interaction metadata to the React DevTools Profiler plugin.
10351// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
10352
10353
10354// Exported FiberRoot type includes all properties,
10355// To avoid requiring potentially error-prone :any casts throughout the project.
10356// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
10357// The types are defined separately within this file to ensure they stay in sync.
10358// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
10359
10360
10361function createFiberRoot(containerInfo, isConcurrent, hydrate) {
10362 // Cyclic construction. This cheats the type system right now because
10363 // stateNode is any.
10364 var uninitializedFiber = createHostRootFiber(isConcurrent);
10365
10366 var root = void 0;
10367 if (enableSchedulerTracing) {
10368 root = {
10369 current: uninitializedFiber,
10370 containerInfo: containerInfo,
10371 pendingChildren: null,
10372
10373 earliestPendingTime: NoWork,
10374 latestPendingTime: NoWork,
10375 earliestSuspendedTime: NoWork,
10376 latestSuspendedTime: NoWork,
10377 latestPingedTime: NoWork,
10378
10379 pingCache: null,
10380
10381 didError: false,
10382
10383 pendingCommitExpirationTime: NoWork,
10384 finishedWork: null,
10385 timeoutHandle: noTimeout,
10386 context: null,
10387 pendingContext: null,
10388 hydrate: hydrate,
10389 nextExpirationTimeToWorkOn: NoWork,
10390 expirationTime: NoWork,
10391 firstBatch: null,
10392 nextScheduledRoot: null,
10393
10394 interactionThreadID: tracing.unstable_getThreadID(),
10395 memoizedInteractions: new Set(),
10396 pendingInteractionMap: new Map()
10397 };
10398 } else {
10399 root = {
10400 current: uninitializedFiber,
10401 containerInfo: containerInfo,
10402 pendingChildren: null,
10403
10404 pingCache: null,
10405
10406 earliestPendingTime: NoWork,
10407 latestPendingTime: NoWork,
10408 earliestSuspendedTime: NoWork,
10409 latestSuspendedTime: NoWork,
10410 latestPingedTime: NoWork,
10411
10412 didError: false,
10413
10414 pendingCommitExpirationTime: NoWork,
10415 finishedWork: null,
10416 timeoutHandle: noTimeout,
10417 context: null,
10418 pendingContext: null,
10419 hydrate: hydrate,
10420 nextExpirationTimeToWorkOn: NoWork,
10421 expirationTime: NoWork,
10422 firstBatch: null,
10423 nextScheduledRoot: null
10424 };
10425 }
10426
10427 uninitializedFiber.stateNode = root;
10428
10429 // The reason for the way the Flow types are structured in this file,
10430 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
10431 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
10432 // $FlowFixMe Remove this :any cast and replace it with something better.
10433 return root;
10434}
10435
10436/**
10437 * Forked from fbjs/warning:
10438 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
10439 *
10440 * Only change is we use console.warn instead of console.error,
10441 * and do nothing when 'console' is not supported.
10442 * This really simplifies the code.
10443 * ---
10444 * Similar to invariant but only logs a warning if the condition is not met.
10445 * This can be used to log issues in development environments in critical
10446 * paths. Removing the logging code for production environments will keep the
10447 * same logic and follow the same code paths.
10448 */
10449
10450var lowPriorityWarning = function () {};
10451
10452{
10453 var printWarning = function (format) {
10454 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
10455 args[_key - 1] = arguments[_key];
10456 }
10457
10458 var argIndex = 0;
10459 var message = 'Warning: ' + format.replace(/%s/g, function () {
10460 return args[argIndex++];
10461 });
10462 if (typeof console !== 'undefined') {
10463 console.warn(message);
10464 }
10465 try {
10466 // --- Welcome to debugging React ---
10467 // This error was thrown as a convenience so that you can use this stack
10468 // to find the callsite that caused this warning to fire.
10469 throw new Error(message);
10470 } catch (x) {}
10471 };
10472
10473 lowPriorityWarning = function (condition, format) {
10474 if (format === undefined) {
10475 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
10476 }
10477 if (!condition) {
10478 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
10479 args[_key2 - 2] = arguments[_key2];
10480 }
10481
10482 printWarning.apply(undefined, [format].concat(args));
10483 }
10484 };
10485}
10486
10487var lowPriorityWarning$1 = lowPriorityWarning;
10488
10489var ReactStrictModeWarnings = {
10490 discardPendingWarnings: function () {},
10491 flushPendingDeprecationWarnings: function () {},
10492 flushPendingUnsafeLifecycleWarnings: function () {},
10493 recordDeprecationWarnings: function (fiber, instance) {},
10494 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
10495 recordLegacyContextWarning: function (fiber, instance) {},
10496 flushLegacyContextWarning: function () {}
10497};
10498
10499{
10500 var LIFECYCLE_SUGGESTIONS = {
10501 UNSAFE_componentWillMount: 'componentDidMount',
10502 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
10503 UNSAFE_componentWillUpdate: 'componentDidUpdate'
10504 };
10505
10506 var pendingComponentWillMountWarnings = [];
10507 var pendingComponentWillReceivePropsWarnings = [];
10508 var pendingComponentWillUpdateWarnings = [];
10509 var pendingUnsafeLifecycleWarnings = new Map();
10510 var pendingLegacyContextWarning = new Map();
10511
10512 // Tracks components we have already warned about.
10513 var didWarnAboutDeprecatedLifecycles = new Set();
10514 var didWarnAboutUnsafeLifecycles = new Set();
10515 var didWarnAboutLegacyContext = new Set();
10516
10517 var setToSortedString = function (set) {
10518 var array = [];
10519 set.forEach(function (value) {
10520 array.push(value);
10521 });
10522 return array.sort().join(', ');
10523 };
10524
10525 ReactStrictModeWarnings.discardPendingWarnings = function () {
10526 pendingComponentWillMountWarnings = [];
10527 pendingComponentWillReceivePropsWarnings = [];
10528 pendingComponentWillUpdateWarnings = [];
10529 pendingUnsafeLifecycleWarnings = new Map();
10530 pendingLegacyContextWarning = new Map();
10531 };
10532
10533 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
10534 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
10535 var lifecyclesWarningMessages = [];
10536
10537 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
10538 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
10539 if (lifecycleWarnings.length > 0) {
10540 var componentNames = new Set();
10541 lifecycleWarnings.forEach(function (fiber) {
10542 componentNames.add(getComponentName(fiber.type) || 'Component');
10543 didWarnAboutUnsafeLifecycles.add(fiber.type);
10544 });
10545
10546 var formatted = lifecycle.replace('UNSAFE_', '');
10547 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
10548 var sortedComponentNames = setToSortedString(componentNames);
10549
10550 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
10551 }
10552 });
10553
10554 if (lifecyclesWarningMessages.length > 0) {
10555 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10556
10557 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'));
10558 }
10559 });
10560
10561 pendingUnsafeLifecycleWarnings = new Map();
10562 };
10563
10564 var findStrictRoot = function (fiber) {
10565 var maybeStrictRoot = null;
10566
10567 var node = fiber;
10568 while (node !== null) {
10569 if (node.mode & StrictMode) {
10570 maybeStrictRoot = node;
10571 }
10572 node = node.return;
10573 }
10574
10575 return maybeStrictRoot;
10576 };
10577
10578 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
10579 if (pendingComponentWillMountWarnings.length > 0) {
10580 var uniqueNames = new Set();
10581 pendingComponentWillMountWarnings.forEach(function (fiber) {
10582 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10583 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10584 });
10585
10586 var sortedNames = setToSortedString(uniqueNames);
10587
10588 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);
10589
10590 pendingComponentWillMountWarnings = [];
10591 }
10592
10593 if (pendingComponentWillReceivePropsWarnings.length > 0) {
10594 var _uniqueNames = new Set();
10595 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
10596 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
10597 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10598 });
10599
10600 var _sortedNames = setToSortedString(_uniqueNames);
10601
10602 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);
10603
10604 pendingComponentWillReceivePropsWarnings = [];
10605 }
10606
10607 if (pendingComponentWillUpdateWarnings.length > 0) {
10608 var _uniqueNames2 = new Set();
10609 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
10610 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
10611 didWarnAboutDeprecatedLifecycles.add(fiber.type);
10612 });
10613
10614 var _sortedNames2 = setToSortedString(_uniqueNames2);
10615
10616 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);
10617
10618 pendingComponentWillUpdateWarnings = [];
10619 }
10620 };
10621
10622 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
10623 // Dedup strategy: Warn once per component.
10624 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
10625 return;
10626 }
10627
10628 // Don't warn about react-lifecycles-compat polyfilled components.
10629 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
10630 pendingComponentWillMountWarnings.push(fiber);
10631 }
10632 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
10633 pendingComponentWillReceivePropsWarnings.push(fiber);
10634 }
10635 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
10636 pendingComponentWillUpdateWarnings.push(fiber);
10637 }
10638 };
10639
10640 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
10641 var strictRoot = findStrictRoot(fiber);
10642 if (strictRoot === null) {
10643 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.');
10644 return;
10645 }
10646
10647 // Dedup strategy: Warn once per component.
10648 // This is difficult to track any other way since component names
10649 // are often vague and are likely to collide between 3rd party libraries.
10650 // An expand property is probably okay to use here since it's DEV-only,
10651 // and will only be set in the event of serious warnings.
10652 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
10653 return;
10654 }
10655
10656 var warningsForRoot = void 0;
10657 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
10658 warningsForRoot = {
10659 UNSAFE_componentWillMount: [],
10660 UNSAFE_componentWillReceiveProps: [],
10661 UNSAFE_componentWillUpdate: []
10662 };
10663
10664 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
10665 } else {
10666 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
10667 }
10668
10669 var unsafeLifecycles = [];
10670 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
10671 unsafeLifecycles.push('UNSAFE_componentWillMount');
10672 }
10673 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
10674 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
10675 }
10676 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
10677 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
10678 }
10679
10680 if (unsafeLifecycles.length > 0) {
10681 unsafeLifecycles.forEach(function (lifecycle) {
10682 warningsForRoot[lifecycle].push(fiber);
10683 });
10684 }
10685 };
10686
10687 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
10688 var strictRoot = findStrictRoot(fiber);
10689 if (strictRoot === null) {
10690 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.');
10691 return;
10692 }
10693
10694 // Dedup strategy: Warn once per component.
10695 if (didWarnAboutLegacyContext.has(fiber.type)) {
10696 return;
10697 }
10698
10699 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
10700
10701 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
10702 if (warningsForRoot === undefined) {
10703 warningsForRoot = [];
10704 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
10705 }
10706 warningsForRoot.push(fiber);
10707 }
10708 };
10709
10710 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
10711 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
10712 var uniqueNames = new Set();
10713 fiberArray.forEach(function (fiber) {
10714 uniqueNames.add(getComponentName(fiber.type) || 'Component');
10715 didWarnAboutLegacyContext.add(fiber.type);
10716 });
10717
10718 var sortedNames = setToSortedString(uniqueNames);
10719 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
10720
10721 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);
10722 });
10723 };
10724}
10725
10726// This lets us hook into Fiber to debug what it's doing.
10727// See https://github.com/facebook/react/pull/8033.
10728// This is not part of the public API, not even for React DevTools.
10729// You may only inject a debugTool if you work on React Fiber itself.
10730var ReactFiberInstrumentation = {
10731 debugTool: null
10732};
10733
10734var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
10735
10736// TODO: Offscreen updates should never suspend. However, a promise that
10737// suspended inside an offscreen subtree should be able to ping at the priority
10738// of the outer render.
10739
10740function markPendingPriorityLevel(root, expirationTime) {
10741 // If there's a gap between completing a failed root and retrying it,
10742 // additional updates may be scheduled. Clear `didError`, in case the update
10743 // is sufficient to fix the error.
10744 root.didError = false;
10745
10746 // Update the latest and earliest pending times
10747 var earliestPendingTime = root.earliestPendingTime;
10748 if (earliestPendingTime === NoWork) {
10749 // No other pending updates.
10750 root.earliestPendingTime = root.latestPendingTime = expirationTime;
10751 } else {
10752 if (earliestPendingTime < expirationTime) {
10753 // This is the earliest pending update.
10754 root.earliestPendingTime = expirationTime;
10755 } else {
10756 var latestPendingTime = root.latestPendingTime;
10757 if (latestPendingTime > expirationTime) {
10758 // This is the latest pending update
10759 root.latestPendingTime = expirationTime;
10760 }
10761 }
10762 }
10763 findNextExpirationTimeToWorkOn(expirationTime, root);
10764}
10765
10766function markCommittedPriorityLevels(root, earliestRemainingTime) {
10767 root.didError = false;
10768
10769 if (earliestRemainingTime === NoWork) {
10770 // Fast path. There's no remaining work. Clear everything.
10771 root.earliestPendingTime = NoWork;
10772 root.latestPendingTime = NoWork;
10773 root.earliestSuspendedTime = NoWork;
10774 root.latestSuspendedTime = NoWork;
10775 root.latestPingedTime = NoWork;
10776 findNextExpirationTimeToWorkOn(NoWork, root);
10777 return;
10778 }
10779
10780 if (earliestRemainingTime < root.latestPingedTime) {
10781 root.latestPingedTime = NoWork;
10782 }
10783
10784 // Let's see if the previous latest known pending level was just flushed.
10785 var latestPendingTime = root.latestPendingTime;
10786 if (latestPendingTime !== NoWork) {
10787 if (latestPendingTime > earliestRemainingTime) {
10788 // We've flushed all the known pending levels.
10789 root.earliestPendingTime = root.latestPendingTime = NoWork;
10790 } else {
10791 var earliestPendingTime = root.earliestPendingTime;
10792 if (earliestPendingTime > earliestRemainingTime) {
10793 // We've flushed the earliest known pending level. Set this to the
10794 // latest pending time.
10795 root.earliestPendingTime = root.latestPendingTime;
10796 }
10797 }
10798 }
10799
10800 // Now let's handle the earliest remaining level in the whole tree. We need to
10801 // decide whether to treat it as a pending level or as suspended. Check
10802 // it falls within the range of known suspended levels.
10803
10804 var earliestSuspendedTime = root.earliestSuspendedTime;
10805 if (earliestSuspendedTime === NoWork) {
10806 // There's no suspended work. Treat the earliest remaining level as a
10807 // pending level.
10808 markPendingPriorityLevel(root, earliestRemainingTime);
10809 findNextExpirationTimeToWorkOn(NoWork, root);
10810 return;
10811 }
10812
10813 var latestSuspendedTime = root.latestSuspendedTime;
10814 if (earliestRemainingTime < latestSuspendedTime) {
10815 // The earliest remaining level is later than all the suspended work. That
10816 // means we've flushed all the suspended work.
10817 root.earliestSuspendedTime = NoWork;
10818 root.latestSuspendedTime = NoWork;
10819 root.latestPingedTime = NoWork;
10820
10821 // There's no suspended work. Treat the earliest remaining level as a
10822 // pending level.
10823 markPendingPriorityLevel(root, earliestRemainingTime);
10824 findNextExpirationTimeToWorkOn(NoWork, root);
10825 return;
10826 }
10827
10828 if (earliestRemainingTime > earliestSuspendedTime) {
10829 // The earliest remaining time is earlier than all the suspended work.
10830 // Treat it as a pending update.
10831 markPendingPriorityLevel(root, earliestRemainingTime);
10832 findNextExpirationTimeToWorkOn(NoWork, root);
10833 return;
10834 }
10835
10836 // The earliest remaining time falls within the range of known suspended
10837 // levels. We should treat this as suspended work.
10838 findNextExpirationTimeToWorkOn(NoWork, root);
10839}
10840
10841function hasLowerPriorityWork(root, erroredExpirationTime) {
10842 var latestPendingTime = root.latestPendingTime;
10843 var latestSuspendedTime = root.latestSuspendedTime;
10844 var latestPingedTime = root.latestPingedTime;
10845 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
10846}
10847
10848function isPriorityLevelSuspended(root, expirationTime) {
10849 var earliestSuspendedTime = root.earliestSuspendedTime;
10850 var latestSuspendedTime = root.latestSuspendedTime;
10851 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
10852}
10853
10854function markSuspendedPriorityLevel(root, suspendedTime) {
10855 root.didError = false;
10856 clearPing(root, suspendedTime);
10857
10858 // First, check the known pending levels and update them if needed.
10859 var earliestPendingTime = root.earliestPendingTime;
10860 var latestPendingTime = root.latestPendingTime;
10861 if (earliestPendingTime === suspendedTime) {
10862 if (latestPendingTime === suspendedTime) {
10863 // Both known pending levels were suspended. Clear them.
10864 root.earliestPendingTime = root.latestPendingTime = NoWork;
10865 } else {
10866 // The earliest pending level was suspended. Clear by setting it to the
10867 // latest pending level.
10868 root.earliestPendingTime = latestPendingTime;
10869 }
10870 } else if (latestPendingTime === suspendedTime) {
10871 // The latest pending level was suspended. Clear by setting it to the
10872 // latest pending level.
10873 root.latestPendingTime = earliestPendingTime;
10874 }
10875
10876 // Finally, update the known suspended levels.
10877 var earliestSuspendedTime = root.earliestSuspendedTime;
10878 var latestSuspendedTime = root.latestSuspendedTime;
10879 if (earliestSuspendedTime === NoWork) {
10880 // No other suspended levels.
10881 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
10882 } else {
10883 if (earliestSuspendedTime < suspendedTime) {
10884 // This is the earliest suspended level.
10885 root.earliestSuspendedTime = suspendedTime;
10886 } else if (latestSuspendedTime > suspendedTime) {
10887 // This is the latest suspended level
10888 root.latestSuspendedTime = suspendedTime;
10889 }
10890 }
10891
10892 findNextExpirationTimeToWorkOn(suspendedTime, root);
10893}
10894
10895function markPingedPriorityLevel(root, pingedTime) {
10896 root.didError = false;
10897
10898 // TODO: When we add back resuming, we need to ensure the progressed work
10899 // is thrown out and not reused during the restarted render. One way to
10900 // invalidate the progressed work is to restart at expirationTime + 1.
10901 var latestPingedTime = root.latestPingedTime;
10902 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
10903 root.latestPingedTime = pingedTime;
10904 }
10905 findNextExpirationTimeToWorkOn(pingedTime, root);
10906}
10907
10908function clearPing(root, completedTime) {
10909 var latestPingedTime = root.latestPingedTime;
10910 if (latestPingedTime >= completedTime) {
10911 root.latestPingedTime = NoWork;
10912 }
10913}
10914
10915function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
10916 var earliestExpirationTime = renderExpirationTime;
10917
10918 var earliestPendingTime = root.earliestPendingTime;
10919 var earliestSuspendedTime = root.earliestSuspendedTime;
10920 if (earliestPendingTime > earliestExpirationTime) {
10921 earliestExpirationTime = earliestPendingTime;
10922 }
10923 if (earliestSuspendedTime > earliestExpirationTime) {
10924 earliestExpirationTime = earliestSuspendedTime;
10925 }
10926 return earliestExpirationTime;
10927}
10928
10929function didExpireAtExpirationTime(root, currentTime) {
10930 var expirationTime = root.expirationTime;
10931 if (expirationTime !== NoWork && currentTime <= expirationTime) {
10932 // The root has expired. Flush all work up to the current time.
10933 root.nextExpirationTimeToWorkOn = currentTime;
10934 }
10935}
10936
10937function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
10938 var earliestSuspendedTime = root.earliestSuspendedTime;
10939 var latestSuspendedTime = root.latestSuspendedTime;
10940 var earliestPendingTime = root.earliestPendingTime;
10941 var latestPingedTime = root.latestPingedTime;
10942
10943 // Work on the earliest pending time. Failing that, work on the latest
10944 // pinged time.
10945 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
10946
10947 // If there is no pending or pinged work, check if there's suspended work
10948 // that's lower priority than what we just completed.
10949 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
10950 // The lowest priority suspended work is the work most likely to be
10951 // committed next. Let's start rendering it again, so that if it times out,
10952 // it's ready to commit.
10953 nextExpirationTimeToWorkOn = latestSuspendedTime;
10954 }
10955
10956 var expirationTime = nextExpirationTimeToWorkOn;
10957 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
10958 // Expire using the earliest known expiration time.
10959 expirationTime = earliestSuspendedTime;
10960 }
10961
10962 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
10963 root.expirationTime = expirationTime;
10964}
10965
10966function resolveDefaultProps(Component, baseProps) {
10967 if (Component && Component.defaultProps) {
10968 // Resolve default props. Taken from ReactElement
10969 var props = _assign({}, baseProps);
10970 var defaultProps = Component.defaultProps;
10971 for (var propName in defaultProps) {
10972 if (props[propName] === undefined) {
10973 props[propName] = defaultProps[propName];
10974 }
10975 }
10976 return props;
10977 }
10978 return baseProps;
10979}
10980
10981function readLazyComponentType(lazyComponent) {
10982 var status = lazyComponent._status;
10983 var result = lazyComponent._result;
10984 switch (status) {
10985 case Resolved:
10986 {
10987 var Component = result;
10988 return Component;
10989 }
10990 case Rejected:
10991 {
10992 var error = result;
10993 throw error;
10994 }
10995 case Pending:
10996 {
10997 var thenable = result;
10998 throw thenable;
10999 }
11000 default:
11001 {
11002 lazyComponent._status = Pending;
11003 var ctor = lazyComponent._ctor;
11004 var _thenable = ctor();
11005 _thenable.then(function (moduleObject) {
11006 if (lazyComponent._status === Pending) {
11007 var defaultExport = moduleObject.default;
11008 {
11009 if (defaultExport === undefined) {
11010 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);
11011 }
11012 }
11013 lazyComponent._status = Resolved;
11014 lazyComponent._result = defaultExport;
11015 }
11016 }, function (error) {
11017 if (lazyComponent._status === Pending) {
11018 lazyComponent._status = Rejected;
11019 lazyComponent._result = error;
11020 }
11021 });
11022 // Handle synchronous thenables.
11023 switch (lazyComponent._status) {
11024 case Resolved:
11025 return lazyComponent._result;
11026 case Rejected:
11027 throw lazyComponent._result;
11028 }
11029 lazyComponent._result = _thenable;
11030 throw _thenable;
11031 }
11032 }
11033}
11034
11035var fakeInternalInstance = {};
11036var isArray$1 = Array.isArray;
11037
11038// React.Component uses a shared frozen object by default.
11039// We'll use it to determine whether we need to initialize legacy refs.
11040var emptyRefsObject = new React.Component().refs;
11041
11042var didWarnAboutStateAssignmentForComponent = void 0;
11043var didWarnAboutUninitializedState = void 0;
11044var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
11045var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
11046var didWarnAboutUndefinedDerivedState = void 0;
11047var warnOnUndefinedDerivedState = void 0;
11048var warnOnInvalidCallback$1 = void 0;
11049var didWarnAboutDirectlyAssigningPropsToState = void 0;
11050var didWarnAboutContextTypeAndContextTypes = void 0;
11051var didWarnAboutInvalidateContextType = void 0;
11052
11053{
11054 didWarnAboutStateAssignmentForComponent = new Set();
11055 didWarnAboutUninitializedState = new Set();
11056 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
11057 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
11058 didWarnAboutDirectlyAssigningPropsToState = new Set();
11059 didWarnAboutUndefinedDerivedState = new Set();
11060 didWarnAboutContextTypeAndContextTypes = new Set();
11061 didWarnAboutInvalidateContextType = new Set();
11062
11063 var didWarnOnInvalidCallback = new Set();
11064
11065 warnOnInvalidCallback$1 = function (callback, callerName) {
11066 if (callback === null || typeof callback === 'function') {
11067 return;
11068 }
11069 var key = callerName + '_' + callback;
11070 if (!didWarnOnInvalidCallback.has(key)) {
11071 didWarnOnInvalidCallback.add(key);
11072 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
11073 }
11074 };
11075
11076 warnOnUndefinedDerivedState = function (type, partialState) {
11077 if (partialState === undefined) {
11078 var componentName = getComponentName(type) || 'Component';
11079 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
11080 didWarnAboutUndefinedDerivedState.add(componentName);
11081 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
11082 }
11083 }
11084 };
11085
11086 // This is so gross but it's at least non-critical and can be removed if
11087 // it causes problems. This is meant to give a nicer error message for
11088 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
11089 // ...)) which otherwise throws a "_processChildContext is not a function"
11090 // exception.
11091 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
11092 enumerable: false,
11093 value: function () {
11094 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).');
11095 }
11096 });
11097 Object.freeze(fakeInternalInstance);
11098}
11099
11100function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
11101 var prevState = workInProgress.memoizedState;
11102
11103 {
11104 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11105 // Invoke the function an extra time to help detect side-effects.
11106 getDerivedStateFromProps(nextProps, prevState);
11107 }
11108 }
11109
11110 var partialState = getDerivedStateFromProps(nextProps, prevState);
11111
11112 {
11113 warnOnUndefinedDerivedState(ctor, partialState);
11114 }
11115 // Merge the partial state and the previous state.
11116 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
11117 workInProgress.memoizedState = memoizedState;
11118
11119 // Once the update queue is empty, persist the derived state onto the
11120 // base state.
11121 var updateQueue = workInProgress.updateQueue;
11122 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
11123 updateQueue.baseState = memoizedState;
11124 }
11125}
11126
11127var classComponentUpdater = {
11128 isMounted: isMounted,
11129 enqueueSetState: function (inst, payload, callback) {
11130 var fiber = get(inst);
11131 var currentTime = requestCurrentTime();
11132 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11133
11134 var update = createUpdate(expirationTime);
11135 update.payload = payload;
11136 if (callback !== undefined && callback !== null) {
11137 {
11138 warnOnInvalidCallback$1(callback, 'setState');
11139 }
11140 update.callback = callback;
11141 }
11142
11143 flushPassiveEffects();
11144 enqueueUpdate(fiber, update);
11145 scheduleWork(fiber, expirationTime);
11146 },
11147 enqueueReplaceState: function (inst, payload, callback) {
11148 var fiber = get(inst);
11149 var currentTime = requestCurrentTime();
11150 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11151
11152 var update = createUpdate(expirationTime);
11153 update.tag = ReplaceState;
11154 update.payload = payload;
11155
11156 if (callback !== undefined && callback !== null) {
11157 {
11158 warnOnInvalidCallback$1(callback, 'replaceState');
11159 }
11160 update.callback = callback;
11161 }
11162
11163 flushPassiveEffects();
11164 enqueueUpdate(fiber, update);
11165 scheduleWork(fiber, expirationTime);
11166 },
11167 enqueueForceUpdate: function (inst, callback) {
11168 var fiber = get(inst);
11169 var currentTime = requestCurrentTime();
11170 var expirationTime = computeExpirationForFiber(currentTime, fiber);
11171
11172 var update = createUpdate(expirationTime);
11173 update.tag = ForceUpdate;
11174
11175 if (callback !== undefined && callback !== null) {
11176 {
11177 warnOnInvalidCallback$1(callback, 'forceUpdate');
11178 }
11179 update.callback = callback;
11180 }
11181
11182 flushPassiveEffects();
11183 enqueueUpdate(fiber, update);
11184 scheduleWork(fiber, expirationTime);
11185 }
11186};
11187
11188function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
11189 var instance = workInProgress.stateNode;
11190 if (typeof instance.shouldComponentUpdate === 'function') {
11191 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
11192 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
11193 stopPhaseTimer();
11194
11195 {
11196 !(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;
11197 }
11198
11199 return shouldUpdate;
11200 }
11201
11202 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
11203 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
11204 }
11205
11206 return true;
11207}
11208
11209function checkClassInstance(workInProgress, ctor, newProps) {
11210 var instance = workInProgress.stateNode;
11211 {
11212 var name = getComponentName(ctor) || 'Component';
11213 var renderPresent = instance.render;
11214
11215 if (!renderPresent) {
11216 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
11217 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
11218 } else {
11219 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
11220 }
11221 }
11222
11223 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
11224 !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;
11225 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
11226 !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;
11227 var noInstancePropTypes = !instance.propTypes;
11228 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
11229 var noInstanceContextType = !instance.contextType;
11230 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
11231 var noInstanceContextTypes = !instance.contextTypes;
11232 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
11233
11234 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
11235 didWarnAboutContextTypeAndContextTypes.add(ctor);
11236 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
11237 }
11238
11239 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
11240 !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;
11241 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
11242 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');
11243 }
11244 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
11245 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
11246 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
11247 !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;
11248 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
11249 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
11250 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
11251 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
11252 var hasMutatedProps = instance.props !== newProps;
11253 !(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;
11254 var noInstanceDefaultProps = !instance.defaultProps;
11255 !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;
11256
11257 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
11258 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
11259 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
11260 }
11261
11262 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
11263 !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;
11264 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
11265 !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;
11266 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
11267 !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;
11268 var _state = instance.state;
11269 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
11270 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
11271 }
11272 if (typeof instance.getChildContext === 'function') {
11273 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
11274 }
11275 }
11276}
11277
11278function adoptClassInstance(workInProgress, instance) {
11279 instance.updater = classComponentUpdater;
11280 workInProgress.stateNode = instance;
11281 // The instance needs access to the fiber so that it can schedule updates
11282 set(instance, workInProgress);
11283 {
11284 instance._reactInternalInstance = fakeInternalInstance;
11285 }
11286}
11287
11288function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
11289 var isLegacyContextConsumer = false;
11290 var unmaskedContext = emptyContextObject;
11291 var context = null;
11292 var contextType = ctor.contextType;
11293 if (typeof contextType === 'object' && contextType !== null) {
11294 {
11295 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
11296 didWarnAboutInvalidateContextType.add(ctor);
11297 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');
11298 }
11299 }
11300
11301 context = readContext(contextType);
11302 } else {
11303 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11304 var contextTypes = ctor.contextTypes;
11305 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
11306 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
11307 }
11308
11309 // Instantiate twice to help detect side-effects.
11310 {
11311 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
11312 new ctor(props, context); // eslint-disable-line no-new
11313 }
11314 }
11315
11316 var instance = new ctor(props, context);
11317 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
11318 adoptClassInstance(workInProgress, instance);
11319
11320 {
11321 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
11322 var componentName = getComponentName(ctor) || 'Component';
11323 if (!didWarnAboutUninitializedState.has(componentName)) {
11324 didWarnAboutUninitializedState.add(componentName);
11325 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);
11326 }
11327 }
11328
11329 // If new component APIs are defined, "unsafe" lifecycles won't be called.
11330 // Warn about these lifecycles if they are present.
11331 // Don't warn about react-lifecycles-compat polyfilled methods though.
11332 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
11333 var foundWillMountName = null;
11334 var foundWillReceivePropsName = null;
11335 var foundWillUpdateName = null;
11336 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
11337 foundWillMountName = 'componentWillMount';
11338 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
11339 foundWillMountName = 'UNSAFE_componentWillMount';
11340 }
11341 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
11342 foundWillReceivePropsName = 'componentWillReceiveProps';
11343 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11344 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
11345 }
11346 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
11347 foundWillUpdateName = 'componentWillUpdate';
11348 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11349 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
11350 }
11351 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
11352 var _componentName = getComponentName(ctor) || 'Component';
11353 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
11354 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
11355 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
11356 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 : '');
11357 }
11358 }
11359 }
11360 }
11361
11362 // Cache unmasked context so we can avoid recreating masked context unless necessary.
11363 // ReactFiberContext usually updates this cache but can't for newly-created instances.
11364 if (isLegacyContextConsumer) {
11365 cacheContext(workInProgress, unmaskedContext, context);
11366 }
11367
11368 return instance;
11369}
11370
11371function callComponentWillMount(workInProgress, instance) {
11372 startPhaseTimer(workInProgress, 'componentWillMount');
11373 var oldState = instance.state;
11374
11375 if (typeof instance.componentWillMount === 'function') {
11376 instance.componentWillMount();
11377 }
11378 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11379 instance.UNSAFE_componentWillMount();
11380 }
11381
11382 stopPhaseTimer();
11383
11384 if (oldState !== instance.state) {
11385 {
11386 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');
11387 }
11388 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11389 }
11390}
11391
11392function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
11393 var oldState = instance.state;
11394 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
11395 if (typeof instance.componentWillReceiveProps === 'function') {
11396 instance.componentWillReceiveProps(newProps, nextContext);
11397 }
11398 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
11399 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
11400 }
11401 stopPhaseTimer();
11402
11403 if (instance.state !== oldState) {
11404 {
11405 var componentName = getComponentName(workInProgress.type) || 'Component';
11406 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
11407 didWarnAboutStateAssignmentForComponent.add(componentName);
11408 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
11409 }
11410 }
11411 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
11412 }
11413}
11414
11415// Invokes the mount life-cycles on a previously never rendered instance.
11416function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11417 {
11418 checkClassInstance(workInProgress, ctor, newProps);
11419 }
11420
11421 var instance = workInProgress.stateNode;
11422 instance.props = newProps;
11423 instance.state = workInProgress.memoizedState;
11424 instance.refs = emptyRefsObject;
11425
11426 var contextType = ctor.contextType;
11427 if (typeof contextType === 'object' && contextType !== null) {
11428 instance.context = readContext(contextType);
11429 } else {
11430 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11431 instance.context = getMaskedContext(workInProgress, unmaskedContext);
11432 }
11433
11434 {
11435 if (instance.state === newProps) {
11436 var componentName = getComponentName(ctor) || 'Component';
11437 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
11438 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
11439 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);
11440 }
11441 }
11442
11443 if (workInProgress.mode & StrictMode) {
11444 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
11445
11446 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
11447 }
11448
11449 if (warnAboutDeprecatedLifecycles) {
11450 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
11451 }
11452 }
11453
11454 var updateQueue = workInProgress.updateQueue;
11455 if (updateQueue !== null) {
11456 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11457 instance.state = workInProgress.memoizedState;
11458 }
11459
11460 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11461 if (typeof getDerivedStateFromProps === 'function') {
11462 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11463 instance.state = workInProgress.memoizedState;
11464 }
11465
11466 // In order to support react-lifecycles-compat polyfilled components,
11467 // Unsafe lifecycles should not be invoked for components using the new APIs.
11468 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11469 callComponentWillMount(workInProgress, instance);
11470 // If we had additional state updates during this life-cycle, let's
11471 // process them now.
11472 updateQueue = workInProgress.updateQueue;
11473 if (updateQueue !== null) {
11474 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11475 instance.state = workInProgress.memoizedState;
11476 }
11477 }
11478
11479 if (typeof instance.componentDidMount === 'function') {
11480 workInProgress.effectTag |= Update;
11481 }
11482}
11483
11484function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
11485 var instance = workInProgress.stateNode;
11486
11487 var oldProps = workInProgress.memoizedProps;
11488 instance.props = oldProps;
11489
11490 var oldContext = instance.context;
11491 var contextType = ctor.contextType;
11492 var nextContext = void 0;
11493 if (typeof contextType === 'object' && contextType !== null) {
11494 nextContext = readContext(contextType);
11495 } else {
11496 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11497 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
11498 }
11499
11500 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11501 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11502
11503 // Note: During these life-cycles, instance.props/instance.state are what
11504 // ever the previously attempted to render - not the "current". However,
11505 // during componentDidUpdate we pass the "current" props.
11506
11507 // In order to support react-lifecycles-compat polyfilled components,
11508 // Unsafe lifecycles should not be invoked for components using the new APIs.
11509 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11510 if (oldProps !== newProps || oldContext !== nextContext) {
11511 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11512 }
11513 }
11514
11515 resetHasForceUpdateBeforeProcessing();
11516
11517 var oldState = workInProgress.memoizedState;
11518 var newState = instance.state = oldState;
11519 var updateQueue = workInProgress.updateQueue;
11520 if (updateQueue !== null) {
11521 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11522 newState = workInProgress.memoizedState;
11523 }
11524 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11525 // If an update was already in progress, we should schedule an Update
11526 // effect even though we're bailing out, so that cWU/cDU are called.
11527 if (typeof instance.componentDidMount === 'function') {
11528 workInProgress.effectTag |= Update;
11529 }
11530 return false;
11531 }
11532
11533 if (typeof getDerivedStateFromProps === 'function') {
11534 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11535 newState = workInProgress.memoizedState;
11536 }
11537
11538 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11539
11540 if (shouldUpdate) {
11541 // In order to support react-lifecycles-compat polyfilled components,
11542 // Unsafe lifecycles should not be invoked for components using the new APIs.
11543 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
11544 startPhaseTimer(workInProgress, 'componentWillMount');
11545 if (typeof instance.componentWillMount === 'function') {
11546 instance.componentWillMount();
11547 }
11548 if (typeof instance.UNSAFE_componentWillMount === 'function') {
11549 instance.UNSAFE_componentWillMount();
11550 }
11551 stopPhaseTimer();
11552 }
11553 if (typeof instance.componentDidMount === 'function') {
11554 workInProgress.effectTag |= Update;
11555 }
11556 } else {
11557 // If an update was already in progress, we should schedule an Update
11558 // effect even though we're bailing out, so that cWU/cDU are called.
11559 if (typeof instance.componentDidMount === 'function') {
11560 workInProgress.effectTag |= Update;
11561 }
11562
11563 // If shouldComponentUpdate returned false, we should still update the
11564 // memoized state to indicate that this work can be reused.
11565 workInProgress.memoizedProps = newProps;
11566 workInProgress.memoizedState = newState;
11567 }
11568
11569 // Update the existing instance's state, props, and context pointers even
11570 // if shouldComponentUpdate returns false.
11571 instance.props = newProps;
11572 instance.state = newState;
11573 instance.context = nextContext;
11574
11575 return shouldUpdate;
11576}
11577
11578// Invokes the update life-cycles and returns false if it shouldn't rerender.
11579function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
11580 var instance = workInProgress.stateNode;
11581
11582 var oldProps = workInProgress.memoizedProps;
11583 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
11584
11585 var oldContext = instance.context;
11586 var contextType = ctor.contextType;
11587 var nextContext = void 0;
11588 if (typeof contextType === 'object' && contextType !== null) {
11589 nextContext = readContext(contextType);
11590 } else {
11591 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
11592 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
11593 }
11594
11595 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
11596 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
11597
11598 // Note: During these life-cycles, instance.props/instance.state are what
11599 // ever the previously attempted to render - not the "current". However,
11600 // during componentDidUpdate we pass the "current" props.
11601
11602 // In order to support react-lifecycles-compat polyfilled components,
11603 // Unsafe lifecycles should not be invoked for components using the new APIs.
11604 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
11605 if (oldProps !== newProps || oldContext !== nextContext) {
11606 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
11607 }
11608 }
11609
11610 resetHasForceUpdateBeforeProcessing();
11611
11612 var oldState = workInProgress.memoizedState;
11613 var newState = instance.state = oldState;
11614 var updateQueue = workInProgress.updateQueue;
11615 if (updateQueue !== null) {
11616 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
11617 newState = workInProgress.memoizedState;
11618 }
11619
11620 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
11621 // If an update was already in progress, we should schedule an Update
11622 // effect even though we're bailing out, so that cWU/cDU are called.
11623 if (typeof instance.componentDidUpdate === 'function') {
11624 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11625 workInProgress.effectTag |= Update;
11626 }
11627 }
11628 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11629 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11630 workInProgress.effectTag |= Snapshot;
11631 }
11632 }
11633 return false;
11634 }
11635
11636 if (typeof getDerivedStateFromProps === 'function') {
11637 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
11638 newState = workInProgress.memoizedState;
11639 }
11640
11641 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
11642
11643 if (shouldUpdate) {
11644 // In order to support react-lifecycles-compat polyfilled components,
11645 // Unsafe lifecycles should not be invoked for components using the new APIs.
11646 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
11647 startPhaseTimer(workInProgress, 'componentWillUpdate');
11648 if (typeof instance.componentWillUpdate === 'function') {
11649 instance.componentWillUpdate(newProps, newState, nextContext);
11650 }
11651 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
11652 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
11653 }
11654 stopPhaseTimer();
11655 }
11656 if (typeof instance.componentDidUpdate === 'function') {
11657 workInProgress.effectTag |= Update;
11658 }
11659 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11660 workInProgress.effectTag |= Snapshot;
11661 }
11662 } else {
11663 // If an update was already in progress, we should schedule an Update
11664 // effect even though we're bailing out, so that cWU/cDU are called.
11665 if (typeof instance.componentDidUpdate === 'function') {
11666 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11667 workInProgress.effectTag |= Update;
11668 }
11669 }
11670 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
11671 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
11672 workInProgress.effectTag |= Snapshot;
11673 }
11674 }
11675
11676 // If shouldComponentUpdate returned false, we should still update the
11677 // memoized props/state to indicate that this work can be reused.
11678 workInProgress.memoizedProps = newProps;
11679 workInProgress.memoizedState = newState;
11680 }
11681
11682 // Update the existing instance's state, props, and context pointers even
11683 // if shouldComponentUpdate returns false.
11684 instance.props = newProps;
11685 instance.state = newState;
11686 instance.context = nextContext;
11687
11688 return shouldUpdate;
11689}
11690
11691var didWarnAboutMaps = void 0;
11692var didWarnAboutGenerators = void 0;
11693var didWarnAboutStringRefInStrictMode = void 0;
11694var ownerHasKeyUseWarning = void 0;
11695var ownerHasFunctionTypeWarning = void 0;
11696var warnForMissingKey = function (child) {};
11697
11698{
11699 didWarnAboutMaps = false;
11700 didWarnAboutGenerators = false;
11701 didWarnAboutStringRefInStrictMode = {};
11702
11703 /**
11704 * Warn if there's no key explicitly set on dynamic arrays of children or
11705 * object keys are not valid. This allows us to keep track of children between
11706 * updates.
11707 */
11708 ownerHasKeyUseWarning = {};
11709 ownerHasFunctionTypeWarning = {};
11710
11711 warnForMissingKey = function (child) {
11712 if (child === null || typeof child !== 'object') {
11713 return;
11714 }
11715 if (!child._store || child._store.validated || child.key != null) {
11716 return;
11717 }
11718 !(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;
11719 child._store.validated = true;
11720
11721 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
11722 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
11723 return;
11724 }
11725 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
11726
11727 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
11728 };
11729}
11730
11731var isArray = Array.isArray;
11732
11733function coerceRef(returnFiber, current$$1, element) {
11734 var mixedRef = element.ref;
11735 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
11736 {
11737 if (returnFiber.mode & StrictMode) {
11738 var componentName = getComponentName(returnFiber.type) || 'Component';
11739 if (!didWarnAboutStringRefInStrictMode[componentName]) {
11740 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));
11741 didWarnAboutStringRefInStrictMode[componentName] = true;
11742 }
11743 }
11744 }
11745
11746 if (element._owner) {
11747 var owner = element._owner;
11748 var inst = void 0;
11749 if (owner) {
11750 var ownerFiber = owner;
11751 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
11752 inst = ownerFiber.stateNode;
11753 }
11754 !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;
11755 var stringRef = '' + mixedRef;
11756 // Check if previous string ref matches new string ref
11757 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
11758 return current$$1.ref;
11759 }
11760 var ref = function (value) {
11761 var refs = inst.refs;
11762 if (refs === emptyRefsObject) {
11763 // This is a lazy pooled frozen object, so we need to initialize.
11764 refs = inst.refs = {};
11765 }
11766 if (value === null) {
11767 delete refs[stringRef];
11768 } else {
11769 refs[stringRef] = value;
11770 }
11771 };
11772 ref._stringRef = stringRef;
11773 return ref;
11774 } else {
11775 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
11776 !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;
11777 }
11778 }
11779 return mixedRef;
11780}
11781
11782function throwOnInvalidObjectType(returnFiber, newChild) {
11783 if (returnFiber.type !== 'textarea') {
11784 var addendum = '';
11785 {
11786 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
11787 }
11788 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);
11789 }
11790}
11791
11792function warnOnFunctionType() {
11793 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();
11794
11795 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
11796 return;
11797 }
11798 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
11799
11800 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.');
11801}
11802
11803// This wrapper function exists because I expect to clone the code in each path
11804// to be able to optimize each path individually by branching early. This needs
11805// a compiler or we can do it manually. Helpers that don't need this branching
11806// live outside of this function.
11807function ChildReconciler(shouldTrackSideEffects) {
11808 function deleteChild(returnFiber, childToDelete) {
11809 if (!shouldTrackSideEffects) {
11810 // Noop.
11811 return;
11812 }
11813 // Deletions are added in reversed order so we add it to the front.
11814 // At this point, the return fiber's effect list is empty except for
11815 // deletions, so we can just append the deletion to the list. The remaining
11816 // effects aren't added until the complete phase. Once we implement
11817 // resuming, this may not be true.
11818 var last = returnFiber.lastEffect;
11819 if (last !== null) {
11820 last.nextEffect = childToDelete;
11821 returnFiber.lastEffect = childToDelete;
11822 } else {
11823 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
11824 }
11825 childToDelete.nextEffect = null;
11826 childToDelete.effectTag = Deletion;
11827 }
11828
11829 function deleteRemainingChildren(returnFiber, currentFirstChild) {
11830 if (!shouldTrackSideEffects) {
11831 // Noop.
11832 return null;
11833 }
11834
11835 // TODO: For the shouldClone case, this could be micro-optimized a bit by
11836 // assuming that after the first child we've already added everything.
11837 var childToDelete = currentFirstChild;
11838 while (childToDelete !== null) {
11839 deleteChild(returnFiber, childToDelete);
11840 childToDelete = childToDelete.sibling;
11841 }
11842 return null;
11843 }
11844
11845 function mapRemainingChildren(returnFiber, currentFirstChild) {
11846 // Add the remaining children to a temporary map so that we can find them by
11847 // keys quickly. Implicit (null) keys get added to this set with their index
11848 var existingChildren = new Map();
11849
11850 var existingChild = currentFirstChild;
11851 while (existingChild !== null) {
11852 if (existingChild.key !== null) {
11853 existingChildren.set(existingChild.key, existingChild);
11854 } else {
11855 existingChildren.set(existingChild.index, existingChild);
11856 }
11857 existingChild = existingChild.sibling;
11858 }
11859 return existingChildren;
11860 }
11861
11862 function useFiber(fiber, pendingProps, expirationTime) {
11863 // We currently set sibling to null and index to 0 here because it is easy
11864 // to forget to do before returning it. E.g. for the single child case.
11865 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
11866 clone.index = 0;
11867 clone.sibling = null;
11868 return clone;
11869 }
11870
11871 function placeChild(newFiber, lastPlacedIndex, newIndex) {
11872 newFiber.index = newIndex;
11873 if (!shouldTrackSideEffects) {
11874 // Noop.
11875 return lastPlacedIndex;
11876 }
11877 var current$$1 = newFiber.alternate;
11878 if (current$$1 !== null) {
11879 var oldIndex = current$$1.index;
11880 if (oldIndex < lastPlacedIndex) {
11881 // This is a move.
11882 newFiber.effectTag = Placement;
11883 return lastPlacedIndex;
11884 } else {
11885 // This item can stay in place.
11886 return oldIndex;
11887 }
11888 } else {
11889 // This is an insertion.
11890 newFiber.effectTag = Placement;
11891 return lastPlacedIndex;
11892 }
11893 }
11894
11895 function placeSingleChild(newFiber) {
11896 // This is simpler for the single child case. We only need to do a
11897 // placement for inserting new children.
11898 if (shouldTrackSideEffects && newFiber.alternate === null) {
11899 newFiber.effectTag = Placement;
11900 }
11901 return newFiber;
11902 }
11903
11904 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
11905 if (current$$1 === null || current$$1.tag !== HostText) {
11906 // Insert
11907 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
11908 created.return = returnFiber;
11909 return created;
11910 } else {
11911 // Update
11912 var existing = useFiber(current$$1, textContent, expirationTime);
11913 existing.return = returnFiber;
11914 return existing;
11915 }
11916 }
11917
11918 function updateElement(returnFiber, current$$1, element, expirationTime) {
11919 if (current$$1 !== null && current$$1.elementType === element.type) {
11920 // Move based on index
11921 var existing = useFiber(current$$1, element.props, expirationTime);
11922 existing.ref = coerceRef(returnFiber, current$$1, element);
11923 existing.return = returnFiber;
11924 {
11925 existing._debugSource = element._source;
11926 existing._debugOwner = element._owner;
11927 }
11928 return existing;
11929 } else {
11930 // Insert
11931 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
11932 created.ref = coerceRef(returnFiber, current$$1, element);
11933 created.return = returnFiber;
11934 return created;
11935 }
11936 }
11937
11938 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
11939 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
11940 // Insert
11941 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
11942 created.return = returnFiber;
11943 return created;
11944 } else {
11945 // Update
11946 var existing = useFiber(current$$1, portal.children || [], expirationTime);
11947 existing.return = returnFiber;
11948 return existing;
11949 }
11950 }
11951
11952 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
11953 if (current$$1 === null || current$$1.tag !== Fragment) {
11954 // Insert
11955 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
11956 created.return = returnFiber;
11957 return created;
11958 } else {
11959 // Update
11960 var existing = useFiber(current$$1, fragment, expirationTime);
11961 existing.return = returnFiber;
11962 return existing;
11963 }
11964 }
11965
11966 function createChild(returnFiber, newChild, expirationTime) {
11967 if (typeof newChild === 'string' || typeof newChild === 'number') {
11968 // Text nodes don't have keys. If the previous node is implicitly keyed
11969 // we can continue to replace it without aborting even if it is not a text
11970 // node.
11971 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
11972 created.return = returnFiber;
11973 return created;
11974 }
11975
11976 if (typeof newChild === 'object' && newChild !== null) {
11977 switch (newChild.$$typeof) {
11978 case REACT_ELEMENT_TYPE:
11979 {
11980 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
11981 _created.ref = coerceRef(returnFiber, null, newChild);
11982 _created.return = returnFiber;
11983 return _created;
11984 }
11985 case REACT_PORTAL_TYPE:
11986 {
11987 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
11988 _created2.return = returnFiber;
11989 return _created2;
11990 }
11991 }
11992
11993 if (isArray(newChild) || getIteratorFn(newChild)) {
11994 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
11995 _created3.return = returnFiber;
11996 return _created3;
11997 }
11998
11999 throwOnInvalidObjectType(returnFiber, newChild);
12000 }
12001
12002 {
12003 if (typeof newChild === 'function') {
12004 warnOnFunctionType();
12005 }
12006 }
12007
12008 return null;
12009 }
12010
12011 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
12012 // Update the fiber if the keys match, otherwise return null.
12013
12014 var key = oldFiber !== null ? oldFiber.key : null;
12015
12016 if (typeof newChild === 'string' || typeof newChild === 'number') {
12017 // Text nodes don't have keys. If the previous node is implicitly keyed
12018 // we can continue to replace it without aborting even if it is not a text
12019 // node.
12020 if (key !== null) {
12021 return null;
12022 }
12023 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
12024 }
12025
12026 if (typeof newChild === 'object' && newChild !== null) {
12027 switch (newChild.$$typeof) {
12028 case REACT_ELEMENT_TYPE:
12029 {
12030 if (newChild.key === key) {
12031 if (newChild.type === REACT_FRAGMENT_TYPE) {
12032 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
12033 }
12034 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
12035 } else {
12036 return null;
12037 }
12038 }
12039 case REACT_PORTAL_TYPE:
12040 {
12041 if (newChild.key === key) {
12042 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
12043 } else {
12044 return null;
12045 }
12046 }
12047 }
12048
12049 if (isArray(newChild) || getIteratorFn(newChild)) {
12050 if (key !== null) {
12051 return null;
12052 }
12053
12054 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
12055 }
12056
12057 throwOnInvalidObjectType(returnFiber, newChild);
12058 }
12059
12060 {
12061 if (typeof newChild === 'function') {
12062 warnOnFunctionType();
12063 }
12064 }
12065
12066 return null;
12067 }
12068
12069 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
12070 if (typeof newChild === 'string' || typeof newChild === 'number') {
12071 // Text nodes don't have keys, so we neither have to check the old nor
12072 // new node for the key. If both are text nodes, they match.
12073 var matchedFiber = existingChildren.get(newIdx) || null;
12074 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
12075 }
12076
12077 if (typeof newChild === 'object' && newChild !== null) {
12078 switch (newChild.$$typeof) {
12079 case REACT_ELEMENT_TYPE:
12080 {
12081 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12082 if (newChild.type === REACT_FRAGMENT_TYPE) {
12083 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
12084 }
12085 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
12086 }
12087 case REACT_PORTAL_TYPE:
12088 {
12089 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
12090 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
12091 }
12092 }
12093
12094 if (isArray(newChild) || getIteratorFn(newChild)) {
12095 var _matchedFiber3 = existingChildren.get(newIdx) || null;
12096 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
12097 }
12098
12099 throwOnInvalidObjectType(returnFiber, newChild);
12100 }
12101
12102 {
12103 if (typeof newChild === 'function') {
12104 warnOnFunctionType();
12105 }
12106 }
12107
12108 return null;
12109 }
12110
12111 /**
12112 * Warns if there is a duplicate or missing key
12113 */
12114 function warnOnInvalidKey(child, knownKeys) {
12115 {
12116 if (typeof child !== 'object' || child === null) {
12117 return knownKeys;
12118 }
12119 switch (child.$$typeof) {
12120 case REACT_ELEMENT_TYPE:
12121 case REACT_PORTAL_TYPE:
12122 warnForMissingKey(child);
12123 var key = child.key;
12124 if (typeof key !== 'string') {
12125 break;
12126 }
12127 if (knownKeys === null) {
12128 knownKeys = new Set();
12129 knownKeys.add(key);
12130 break;
12131 }
12132 if (!knownKeys.has(key)) {
12133 knownKeys.add(key);
12134 break;
12135 }
12136 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);
12137 break;
12138 default:
12139 break;
12140 }
12141 }
12142 return knownKeys;
12143 }
12144
12145 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
12146 // This algorithm can't optimize by searching from both ends since we
12147 // don't have backpointers on fibers. I'm trying to see how far we can get
12148 // with that model. If it ends up not being worth the tradeoffs, we can
12149 // add it later.
12150
12151 // Even with a two ended optimization, we'd want to optimize for the case
12152 // where there are few changes and brute force the comparison instead of
12153 // going for the Map. It'd like to explore hitting that path first in
12154 // forward-only mode and only go for the Map once we notice that we need
12155 // lots of look ahead. This doesn't handle reversal as well as two ended
12156 // search but that's unusual. Besides, for the two ended optimization to
12157 // work on Iterables, we'd need to copy the whole set.
12158
12159 // In this first iteration, we'll just live with hitting the bad case
12160 // (adding everything to a Map) in for every insert/move.
12161
12162 // If you change this code, also update reconcileChildrenIterator() which
12163 // uses the same algorithm.
12164
12165 {
12166 // First, validate keys.
12167 var knownKeys = null;
12168 for (var i = 0; i < newChildren.length; i++) {
12169 var child = newChildren[i];
12170 knownKeys = warnOnInvalidKey(child, knownKeys);
12171 }
12172 }
12173
12174 var resultingFirstChild = null;
12175 var previousNewFiber = null;
12176
12177 var oldFiber = currentFirstChild;
12178 var lastPlacedIndex = 0;
12179 var newIdx = 0;
12180 var nextOldFiber = null;
12181 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
12182 if (oldFiber.index > newIdx) {
12183 nextOldFiber = oldFiber;
12184 oldFiber = null;
12185 } else {
12186 nextOldFiber = oldFiber.sibling;
12187 }
12188 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
12189 if (newFiber === null) {
12190 // TODO: This breaks on empty slots like null children. That's
12191 // unfortunate because it triggers the slow path all the time. We need
12192 // a better way to communicate whether this was a miss or null,
12193 // boolean, undefined, etc.
12194 if (oldFiber === null) {
12195 oldFiber = nextOldFiber;
12196 }
12197 break;
12198 }
12199 if (shouldTrackSideEffects) {
12200 if (oldFiber && newFiber.alternate === null) {
12201 // We matched the slot, but we didn't reuse the existing fiber, so we
12202 // need to delete the existing child.
12203 deleteChild(returnFiber, oldFiber);
12204 }
12205 }
12206 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12207 if (previousNewFiber === null) {
12208 // TODO: Move out of the loop. This only happens for the first run.
12209 resultingFirstChild = newFiber;
12210 } else {
12211 // TODO: Defer siblings if we're not at the right index for this slot.
12212 // I.e. if we had null values before, then we want to defer this
12213 // for each null value. However, we also don't want to call updateSlot
12214 // with the previous one.
12215 previousNewFiber.sibling = newFiber;
12216 }
12217 previousNewFiber = newFiber;
12218 oldFiber = nextOldFiber;
12219 }
12220
12221 if (newIdx === newChildren.length) {
12222 // We've reached the end of the new children. We can delete the rest.
12223 deleteRemainingChildren(returnFiber, oldFiber);
12224 return resultingFirstChild;
12225 }
12226
12227 if (oldFiber === null) {
12228 // If we don't have any more existing children we can choose a fast path
12229 // since the rest will all be insertions.
12230 for (; newIdx < newChildren.length; newIdx++) {
12231 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
12232 if (!_newFiber) {
12233 continue;
12234 }
12235 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
12236 if (previousNewFiber === null) {
12237 // TODO: Move out of the loop. This only happens for the first run.
12238 resultingFirstChild = _newFiber;
12239 } else {
12240 previousNewFiber.sibling = _newFiber;
12241 }
12242 previousNewFiber = _newFiber;
12243 }
12244 return resultingFirstChild;
12245 }
12246
12247 // Add all children to a key map for quick lookups.
12248 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12249
12250 // Keep scanning and use the map to restore deleted items as moves.
12251 for (; newIdx < newChildren.length; newIdx++) {
12252 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
12253 if (_newFiber2) {
12254 if (shouldTrackSideEffects) {
12255 if (_newFiber2.alternate !== null) {
12256 // The new fiber is a work in progress, but if there exists a
12257 // current, that means that we reused the fiber. We need to delete
12258 // it from the child list so that we don't add it to the deletion
12259 // list.
12260 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
12261 }
12262 }
12263 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
12264 if (previousNewFiber === null) {
12265 resultingFirstChild = _newFiber2;
12266 } else {
12267 previousNewFiber.sibling = _newFiber2;
12268 }
12269 previousNewFiber = _newFiber2;
12270 }
12271 }
12272
12273 if (shouldTrackSideEffects) {
12274 // Any existing children that weren't consumed above were deleted. We need
12275 // to add them to the deletion list.
12276 existingChildren.forEach(function (child) {
12277 return deleteChild(returnFiber, child);
12278 });
12279 }
12280
12281 return resultingFirstChild;
12282 }
12283
12284 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
12285 // This is the same implementation as reconcileChildrenArray(),
12286 // but using the iterator instead.
12287
12288 var iteratorFn = getIteratorFn(newChildrenIterable);
12289 !(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;
12290
12291 {
12292 // We don't support rendering Generators because it's a mutation.
12293 // See https://github.com/facebook/react/issues/12995
12294 if (typeof Symbol === 'function' &&
12295 // $FlowFixMe Flow doesn't know about toStringTag
12296 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
12297 !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;
12298 didWarnAboutGenerators = true;
12299 }
12300
12301 // Warn about using Maps as children
12302 if (newChildrenIterable.entries === iteratorFn) {
12303 !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;
12304 didWarnAboutMaps = true;
12305 }
12306
12307 // First, validate keys.
12308 // We'll get a different iterator later for the main pass.
12309 var _newChildren = iteratorFn.call(newChildrenIterable);
12310 if (_newChildren) {
12311 var knownKeys = null;
12312 var _step = _newChildren.next();
12313 for (; !_step.done; _step = _newChildren.next()) {
12314 var child = _step.value;
12315 knownKeys = warnOnInvalidKey(child, knownKeys);
12316 }
12317 }
12318 }
12319
12320 var newChildren = iteratorFn.call(newChildrenIterable);
12321 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
12322
12323 var resultingFirstChild = null;
12324 var previousNewFiber = null;
12325
12326 var oldFiber = currentFirstChild;
12327 var lastPlacedIndex = 0;
12328 var newIdx = 0;
12329 var nextOldFiber = null;
12330
12331 var step = newChildren.next();
12332 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
12333 if (oldFiber.index > newIdx) {
12334 nextOldFiber = oldFiber;
12335 oldFiber = null;
12336 } else {
12337 nextOldFiber = oldFiber.sibling;
12338 }
12339 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
12340 if (newFiber === null) {
12341 // TODO: This breaks on empty slots like null children. That's
12342 // unfortunate because it triggers the slow path all the time. We need
12343 // a better way to communicate whether this was a miss or null,
12344 // boolean, undefined, etc.
12345 if (!oldFiber) {
12346 oldFiber = nextOldFiber;
12347 }
12348 break;
12349 }
12350 if (shouldTrackSideEffects) {
12351 if (oldFiber && newFiber.alternate === null) {
12352 // We matched the slot, but we didn't reuse the existing fiber, so we
12353 // need to delete the existing child.
12354 deleteChild(returnFiber, oldFiber);
12355 }
12356 }
12357 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
12358 if (previousNewFiber === null) {
12359 // TODO: Move out of the loop. This only happens for the first run.
12360 resultingFirstChild = newFiber;
12361 } else {
12362 // TODO: Defer siblings if we're not at the right index for this slot.
12363 // I.e. if we had null values before, then we want to defer this
12364 // for each null value. However, we also don't want to call updateSlot
12365 // with the previous one.
12366 previousNewFiber.sibling = newFiber;
12367 }
12368 previousNewFiber = newFiber;
12369 oldFiber = nextOldFiber;
12370 }
12371
12372 if (step.done) {
12373 // We've reached the end of the new children. We can delete the rest.
12374 deleteRemainingChildren(returnFiber, oldFiber);
12375 return resultingFirstChild;
12376 }
12377
12378 if (oldFiber === null) {
12379 // If we don't have any more existing children we can choose a fast path
12380 // since the rest will all be insertions.
12381 for (; !step.done; newIdx++, step = newChildren.next()) {
12382 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
12383 if (_newFiber3 === null) {
12384 continue;
12385 }
12386 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
12387 if (previousNewFiber === null) {
12388 // TODO: Move out of the loop. This only happens for the first run.
12389 resultingFirstChild = _newFiber3;
12390 } else {
12391 previousNewFiber.sibling = _newFiber3;
12392 }
12393 previousNewFiber = _newFiber3;
12394 }
12395 return resultingFirstChild;
12396 }
12397
12398 // Add all children to a key map for quick lookups.
12399 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
12400
12401 // Keep scanning and use the map to restore deleted items as moves.
12402 for (; !step.done; newIdx++, step = newChildren.next()) {
12403 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
12404 if (_newFiber4 !== null) {
12405 if (shouldTrackSideEffects) {
12406 if (_newFiber4.alternate !== null) {
12407 // The new fiber is a work in progress, but if there exists a
12408 // current, that means that we reused the fiber. We need to delete
12409 // it from the child list so that we don't add it to the deletion
12410 // list.
12411 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
12412 }
12413 }
12414 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
12415 if (previousNewFiber === null) {
12416 resultingFirstChild = _newFiber4;
12417 } else {
12418 previousNewFiber.sibling = _newFiber4;
12419 }
12420 previousNewFiber = _newFiber4;
12421 }
12422 }
12423
12424 if (shouldTrackSideEffects) {
12425 // Any existing children that weren't consumed above were deleted. We need
12426 // to add them to the deletion list.
12427 existingChildren.forEach(function (child) {
12428 return deleteChild(returnFiber, child);
12429 });
12430 }
12431
12432 return resultingFirstChild;
12433 }
12434
12435 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
12436 // There's no need to check for keys on text nodes since we don't have a
12437 // way to define them.
12438 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
12439 // We already have an existing node so let's just update it and delete
12440 // the rest.
12441 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
12442 var existing = useFiber(currentFirstChild, textContent, expirationTime);
12443 existing.return = returnFiber;
12444 return existing;
12445 }
12446 // The existing first child is not a text node so we need to create one
12447 // and delete the existing ones.
12448 deleteRemainingChildren(returnFiber, currentFirstChild);
12449 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
12450 created.return = returnFiber;
12451 return created;
12452 }
12453
12454 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
12455 var key = element.key;
12456 var child = currentFirstChild;
12457 while (child !== null) {
12458 // TODO: If key === null and child.key === null, then this only applies to
12459 // the first item in the list.
12460 if (child.key === key) {
12461 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
12462 deleteRemainingChildren(returnFiber, child.sibling);
12463 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
12464 existing.ref = coerceRef(returnFiber, child, element);
12465 existing.return = returnFiber;
12466 {
12467 existing._debugSource = element._source;
12468 existing._debugOwner = element._owner;
12469 }
12470 return existing;
12471 } else {
12472 deleteRemainingChildren(returnFiber, child);
12473 break;
12474 }
12475 } else {
12476 deleteChild(returnFiber, child);
12477 }
12478 child = child.sibling;
12479 }
12480
12481 if (element.type === REACT_FRAGMENT_TYPE) {
12482 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
12483 created.return = returnFiber;
12484 return created;
12485 } else {
12486 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
12487 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
12488 _created4.return = returnFiber;
12489 return _created4;
12490 }
12491 }
12492
12493 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
12494 var key = portal.key;
12495 var child = currentFirstChild;
12496 while (child !== null) {
12497 // TODO: If key === null and child.key === null, then this only applies to
12498 // the first item in the list.
12499 if (child.key === key) {
12500 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
12501 deleteRemainingChildren(returnFiber, child.sibling);
12502 var existing = useFiber(child, portal.children || [], expirationTime);
12503 existing.return = returnFiber;
12504 return existing;
12505 } else {
12506 deleteRemainingChildren(returnFiber, child);
12507 break;
12508 }
12509 } else {
12510 deleteChild(returnFiber, child);
12511 }
12512 child = child.sibling;
12513 }
12514
12515 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
12516 created.return = returnFiber;
12517 return created;
12518 }
12519
12520 // This API will tag the children with the side-effect of the reconciliation
12521 // itself. They will be added to the side-effect list as we pass through the
12522 // children and the parent.
12523 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
12524 // This function is not recursive.
12525 // If the top level item is an array, we treat it as a set of children,
12526 // not as a fragment. Nested arrays on the other hand will be treated as
12527 // fragment nodes. Recursion happens at the normal flow.
12528
12529 // Handle top level unkeyed fragments as if they were arrays.
12530 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
12531 // We treat the ambiguous cases above the same.
12532 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
12533 if (isUnkeyedTopLevelFragment) {
12534 newChild = newChild.props.children;
12535 }
12536
12537 // Handle object types
12538 var isObject = typeof newChild === 'object' && newChild !== null;
12539
12540 if (isObject) {
12541 switch (newChild.$$typeof) {
12542 case REACT_ELEMENT_TYPE:
12543 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
12544 case REACT_PORTAL_TYPE:
12545 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
12546 }
12547 }
12548
12549 if (typeof newChild === 'string' || typeof newChild === 'number') {
12550 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
12551 }
12552
12553 if (isArray(newChild)) {
12554 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
12555 }
12556
12557 if (getIteratorFn(newChild)) {
12558 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
12559 }
12560
12561 if (isObject) {
12562 throwOnInvalidObjectType(returnFiber, newChild);
12563 }
12564
12565 {
12566 if (typeof newChild === 'function') {
12567 warnOnFunctionType();
12568 }
12569 }
12570 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
12571 // If the new child is undefined, and the return fiber is a composite
12572 // component, throw an error. If Fiber return types are disabled,
12573 // we already threw above.
12574 switch (returnFiber.tag) {
12575 case ClassComponent:
12576 {
12577 {
12578 var instance = returnFiber.stateNode;
12579 if (instance.render._isMockFunction) {
12580 // We allow auto-mocks to proceed as if they're returning null.
12581 break;
12582 }
12583 }
12584 }
12585 // Intentionally fall through to the next case, which handles both
12586 // functions and classes
12587 // eslint-disable-next-lined no-fallthrough
12588 case FunctionComponent:
12589 {
12590 var Component = returnFiber.type;
12591 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');
12592 }
12593 }
12594 }
12595
12596 // Remaining cases are all treated as empty.
12597 return deleteRemainingChildren(returnFiber, currentFirstChild);
12598 }
12599
12600 return reconcileChildFibers;
12601}
12602
12603var reconcileChildFibers = ChildReconciler(true);
12604var mountChildFibers = ChildReconciler(false);
12605
12606function cloneChildFibers(current$$1, workInProgress) {
12607 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
12608
12609 if (workInProgress.child === null) {
12610 return;
12611 }
12612
12613 var currentChild = workInProgress.child;
12614 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12615 workInProgress.child = newChild;
12616
12617 newChild.return = workInProgress;
12618 while (currentChild.sibling !== null) {
12619 currentChild = currentChild.sibling;
12620 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
12621 newChild.return = workInProgress;
12622 }
12623 newChild.sibling = null;
12624}
12625
12626var NO_CONTEXT = {};
12627
12628var contextStackCursor$1 = createCursor(NO_CONTEXT);
12629var contextFiberStackCursor = createCursor(NO_CONTEXT);
12630var rootInstanceStackCursor = createCursor(NO_CONTEXT);
12631
12632function requiredContext(c) {
12633 !(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;
12634 return c;
12635}
12636
12637function getRootHostContainer() {
12638 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12639 return rootInstance;
12640}
12641
12642function pushHostContainer(fiber, nextRootInstance) {
12643 // Push current root instance onto the stack;
12644 // This allows us to reset root when portals are popped.
12645 push(rootInstanceStackCursor, nextRootInstance, fiber);
12646 // Track the context and the Fiber that provided it.
12647 // This enables us to pop only Fibers that provide unique contexts.
12648 push(contextFiberStackCursor, fiber, fiber);
12649
12650 // Finally, we need to push the host context to the stack.
12651 // However, we can't just call getRootHostContext() and push it because
12652 // we'd have a different number of entries on the stack depending on
12653 // whether getRootHostContext() throws somewhere in renderer code or not.
12654 // So we push an empty value first. This lets us safely unwind on errors.
12655 push(contextStackCursor$1, NO_CONTEXT, fiber);
12656 var nextRootContext = getRootHostContext(nextRootInstance);
12657 // Now that we know this function doesn't throw, replace it.
12658 pop(contextStackCursor$1, fiber);
12659 push(contextStackCursor$1, nextRootContext, fiber);
12660}
12661
12662function popHostContainer(fiber) {
12663 pop(contextStackCursor$1, fiber);
12664 pop(contextFiberStackCursor, fiber);
12665 pop(rootInstanceStackCursor, fiber);
12666}
12667
12668function getHostContext() {
12669 var context = requiredContext(contextStackCursor$1.current);
12670 return context;
12671}
12672
12673function pushHostContext(fiber) {
12674 var rootInstance = requiredContext(rootInstanceStackCursor.current);
12675 var context = requiredContext(contextStackCursor$1.current);
12676 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
12677
12678 // Don't push this Fiber's context unless it's unique.
12679 if (context === nextContext) {
12680 return;
12681 }
12682
12683 // Track the context and the Fiber that provided it.
12684 // This enables us to pop only Fibers that provide unique contexts.
12685 push(contextFiberStackCursor, fiber, fiber);
12686 push(contextStackCursor$1, nextContext, fiber);
12687}
12688
12689function popHostContext(fiber) {
12690 // Do not pop unless this Fiber provided the current context.
12691 // pushHostContext() only pushes Fibers that provide unique contexts.
12692 if (contextFiberStackCursor.current !== fiber) {
12693 return;
12694 }
12695
12696 pop(contextStackCursor$1, fiber);
12697 pop(contextFiberStackCursor, fiber);
12698}
12699
12700var NoEffect$1 = /* */0;
12701var UnmountSnapshot = /* */2;
12702var UnmountMutation = /* */4;
12703var MountMutation = /* */8;
12704var UnmountLayout = /* */16;
12705var MountLayout = /* */32;
12706var MountPassive = /* */64;
12707var UnmountPassive = /* */128;
12708
12709var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
12710
12711
12712var didWarnAboutMismatchedHooksForComponent = void 0;
12713{
12714 didWarnAboutMismatchedHooksForComponent = new Set();
12715}
12716
12717// These are set right before calling the component.
12718var renderExpirationTime = NoWork;
12719// The work-in-progress fiber. I've named it differently to distinguish it from
12720// the work-in-progress hook.
12721var currentlyRenderingFiber$1 = null;
12722
12723// Hooks are stored as a linked list on the fiber's memoizedState field. The
12724// current hook list is the list that belongs to the current fiber. The
12725// work-in-progress hook list is a new list that will be added to the
12726// work-in-progress fiber.
12727var firstCurrentHook = null;
12728var currentHook = null;
12729var nextCurrentHook = null;
12730var firstWorkInProgressHook = null;
12731var workInProgressHook = null;
12732var nextWorkInProgressHook = null;
12733
12734var remainingExpirationTime = NoWork;
12735var componentUpdateQueue = null;
12736var sideEffectTag = 0;
12737
12738// Updates scheduled during render will trigger an immediate re-render at the
12739// end of the current pass. We can't store these updates on the normal queue,
12740// because if the work is aborted, they should be discarded. Because this is
12741// a relatively rare case, we also don't want to add an additional field to
12742// either the hook or queue object types. So we store them in a lazily create
12743// map of queue -> render-phase updates, which are discarded once the component
12744// completes without re-rendering.
12745
12746// Whether an update was scheduled during the currently executing render pass.
12747var didScheduleRenderPhaseUpdate = false;
12748// Lazily created map of render-phase updates
12749var renderPhaseUpdates = null;
12750// Counter to prevent infinite loops.
12751var numberOfReRenders = 0;
12752var RE_RENDER_LIMIT = 25;
12753
12754// In DEV, this is the name of the currently executing primitive hook
12755var currentHookNameInDev = null;
12756
12757function warnOnHookMismatchInDev() {
12758 {
12759 var componentName = getComponentName(currentlyRenderingFiber$1.type);
12760 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
12761 didWarnAboutMismatchedHooksForComponent.add(componentName);
12762
12763 var secondColumnStart = 22;
12764
12765 var table = '';
12766 var prevHook = firstCurrentHook;
12767 var nextHook = firstWorkInProgressHook;
12768 var n = 1;
12769 while (prevHook !== null && nextHook !== null) {
12770 var oldHookName = prevHook._debugType;
12771 var newHookName = nextHook._debugType;
12772
12773 var row = n + '. ' + oldHookName;
12774
12775 // Extra space so second column lines up
12776 // lol @ IE not supporting String#repeat
12777 while (row.length < secondColumnStart) {
12778 row += ' ';
12779 }
12780
12781 row += newHookName + '\n';
12782
12783 table += row;
12784 prevHook = prevHook.next;
12785 nextHook = nextHook.next;
12786 n++;
12787 }
12788
12789 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);
12790 }
12791 }
12792}
12793
12794function throwInvalidHookError() {
12795 invariant(false, 'Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)');
12796}
12797
12798function areHookInputsEqual(nextDeps, prevDeps) {
12799 if (prevDeps === null) {
12800 {
12801 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);
12802 }
12803 return false;
12804 }
12805
12806 {
12807 // Don't bother comparing lengths in prod because these arrays should be
12808 // passed inline.
12809 if (nextDeps.length !== prevDeps.length) {
12810 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(', ') + ']');
12811 }
12812 }
12813 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
12814 if (is(nextDeps[i], prevDeps[i])) {
12815 continue;
12816 }
12817 return false;
12818 }
12819 return true;
12820}
12821
12822function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
12823 renderExpirationTime = nextRenderExpirationTime;
12824 currentlyRenderingFiber$1 = workInProgress;
12825 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
12826
12827 // The following should have already been reset
12828 // currentHook = null;
12829 // workInProgressHook = null;
12830
12831 // remainingExpirationTime = NoWork;
12832 // componentUpdateQueue = null;
12833
12834 // didScheduleRenderPhaseUpdate = false;
12835 // renderPhaseUpdates = null;
12836 // numberOfReRenders = 0;
12837 // sideEffectTag = 0;
12838
12839 {
12840 ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
12841 }
12842
12843 var children = Component(props, refOrContext);
12844
12845 if (didScheduleRenderPhaseUpdate) {
12846 do {
12847 didScheduleRenderPhaseUpdate = false;
12848 numberOfReRenders += 1;
12849
12850 // Start over from the beginning of the list
12851 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
12852 nextWorkInProgressHook = firstWorkInProgressHook;
12853
12854 currentHook = null;
12855 workInProgressHook = null;
12856 componentUpdateQueue = null;
12857
12858 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12859
12860 children = Component(props, refOrContext);
12861 } while (didScheduleRenderPhaseUpdate);
12862
12863 renderPhaseUpdates = null;
12864 numberOfReRenders = 0;
12865 }
12866
12867 {
12868 currentHookNameInDev = null;
12869 }
12870
12871 // We can assume the previous dispatcher is always this one, since we set it
12872 // at the beginning of the render phase and there's no re-entrancy.
12873 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12874
12875 var renderedWork = currentlyRenderingFiber$1;
12876
12877 renderedWork.memoizedState = firstWorkInProgressHook;
12878 renderedWork.expirationTime = remainingExpirationTime;
12879 renderedWork.updateQueue = componentUpdateQueue;
12880 renderedWork.effectTag |= sideEffectTag;
12881
12882 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
12883
12884 renderExpirationTime = NoWork;
12885 currentlyRenderingFiber$1 = null;
12886
12887 firstCurrentHook = null;
12888 currentHook = null;
12889 nextCurrentHook = null;
12890 firstWorkInProgressHook = null;
12891 workInProgressHook = null;
12892 nextWorkInProgressHook = null;
12893
12894 remainingExpirationTime = NoWork;
12895 componentUpdateQueue = null;
12896 sideEffectTag = 0;
12897
12898 // These were reset above
12899 // didScheduleRenderPhaseUpdate = false;
12900 // renderPhaseUpdates = null;
12901 // numberOfReRenders = 0;
12902
12903 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
12904
12905 return children;
12906}
12907
12908function bailoutHooks(current, workInProgress, expirationTime) {
12909 workInProgress.updateQueue = current.updateQueue;
12910 workInProgress.effectTag &= ~(Passive | Update);
12911 if (current.expirationTime <= expirationTime) {
12912 current.expirationTime = NoWork;
12913 }
12914}
12915
12916function resetHooks() {
12917 // We can assume the previous dispatcher is always this one, since we set it
12918 // at the beginning of the render phase and there's no re-entrancy.
12919 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12920
12921 // This is used to reset the state of this module when a component throws.
12922 // It's also called inside mountIndeterminateComponent if we determine the
12923 // component is a module-style component.
12924 renderExpirationTime = NoWork;
12925 currentlyRenderingFiber$1 = null;
12926
12927 firstCurrentHook = null;
12928 currentHook = null;
12929 nextCurrentHook = null;
12930 firstWorkInProgressHook = null;
12931 workInProgressHook = null;
12932 nextWorkInProgressHook = null;
12933
12934 remainingExpirationTime = NoWork;
12935 componentUpdateQueue = null;
12936 sideEffectTag = 0;
12937
12938 {
12939 currentHookNameInDev = null;
12940 }
12941
12942 didScheduleRenderPhaseUpdate = false;
12943 renderPhaseUpdates = null;
12944 numberOfReRenders = 0;
12945}
12946
12947function mountWorkInProgressHook() {
12948 var hook = {
12949 memoizedState: null,
12950
12951 baseState: null,
12952 queue: null,
12953 baseUpdate: null,
12954
12955 next: null
12956 };
12957
12958 {
12959 hook._debugType = currentHookNameInDev;
12960 }
12961 if (workInProgressHook === null) {
12962 // This is the first hook in the list
12963 firstWorkInProgressHook = workInProgressHook = hook;
12964 } else {
12965 // Append to the end of the list
12966 workInProgressHook = workInProgressHook.next = hook;
12967 }
12968 return workInProgressHook;
12969}
12970
12971function updateWorkInProgressHook() {
12972 // This function is used both for updates and for re-renders triggered by a
12973 // render phase update. It assumes there is either a current hook we can
12974 // clone, or a work-in-progress hook from a previous render pass that we can
12975 // use as a base. When we reach the end of the base list, we must switch to
12976 // the dispatcher used for mounts.
12977 if (nextWorkInProgressHook !== null) {
12978 // There's already a work-in-progress. Reuse it.
12979 workInProgressHook = nextWorkInProgressHook;
12980 nextWorkInProgressHook = workInProgressHook.next;
12981
12982 currentHook = nextCurrentHook;
12983 nextCurrentHook = currentHook !== null ? currentHook.next : null;
12984 } else {
12985 // Clone from the current hook.
12986 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
12987 currentHook = nextCurrentHook;
12988
12989 var newHook = {
12990 memoizedState: currentHook.memoizedState,
12991
12992 baseState: currentHook.baseState,
12993 queue: currentHook.queue,
12994 baseUpdate: currentHook.baseUpdate,
12995
12996 next: null
12997 };
12998
12999 if (workInProgressHook === null) {
13000 // This is the first hook in the list.
13001 workInProgressHook = firstWorkInProgressHook = newHook;
13002 } else {
13003 // Append to the end of the list.
13004 workInProgressHook = workInProgressHook.next = newHook;
13005 }
13006 nextCurrentHook = currentHook.next;
13007
13008 {
13009 newHook._debugType = currentHookNameInDev;
13010 if (currentHookNameInDev !== currentHook._debugType) {
13011 warnOnHookMismatchInDev();
13012 }
13013 }
13014 }
13015 return workInProgressHook;
13016}
13017
13018function createFunctionComponentUpdateQueue() {
13019 return {
13020 lastEffect: null
13021 };
13022}
13023
13024function basicStateReducer(state, action) {
13025 return typeof action === 'function' ? action(state) : action;
13026}
13027
13028function mountContext(context, observedBits) {
13029 {
13030 mountWorkInProgressHook();
13031 }
13032 return readContext(context, observedBits);
13033}
13034
13035function updateContext(context, observedBits) {
13036 {
13037 updateWorkInProgressHook();
13038 }
13039 return readContext(context, observedBits);
13040}
13041
13042function mountReducer(reducer, initialArg, init) {
13043 var hook = mountWorkInProgressHook();
13044 var initialState = void 0;
13045 if (init !== undefined) {
13046 initialState = init(initialArg);
13047 } else {
13048 initialState = initialArg;
13049 }
13050 hook.memoizedState = hook.baseState = initialState;
13051 var queue = hook.queue = {
13052 last: null,
13053 dispatch: null,
13054 eagerReducer: reducer,
13055 eagerState: initialState
13056 };
13057 var dispatch = queue.dispatch = dispatchAction.bind(null,
13058 // Flow doesn't know this is non-null, but we do.
13059 currentlyRenderingFiber$1, queue);
13060 return [hook.memoizedState, dispatch];
13061}
13062
13063function updateReducer(reducer, initialArg, init) {
13064 var hook = updateWorkInProgressHook();
13065 var queue = hook.queue;
13066 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
13067
13068 if (numberOfReRenders > 0) {
13069 // This is a re-render. Apply the new render phase updates to the previous
13070 var _dispatch = queue.dispatch;
13071 if (renderPhaseUpdates !== null) {
13072 // Render phase updates are stored in a map of queue -> linked list
13073 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13074 if (firstRenderPhaseUpdate !== undefined) {
13075 renderPhaseUpdates.delete(queue);
13076 var newState = hook.memoizedState;
13077 var update = firstRenderPhaseUpdate;
13078 do {
13079 // Process this render phase update. We don't have to check the
13080 // priority because it will always be the same as the current
13081 // render's.
13082 var _action = update.action;
13083 newState = reducer(newState, _action);
13084 update = update.next;
13085 } while (update !== null);
13086
13087 // Mark that the fiber performed work, but only if the new state is
13088 // different from the current state.
13089 if (!is(newState, hook.memoizedState)) {
13090 markWorkInProgressReceivedUpdate();
13091 }
13092
13093 hook.memoizedState = newState;
13094
13095 // Don't persist the state accumlated from the render phase updates to
13096 // the base state unless the queue is empty.
13097 // TODO: Not sure if this is the desired semantics, but it's what we
13098 // do for gDSFP. I can't remember why.
13099 if (hook.baseUpdate === queue.last) {
13100 hook.baseState = newState;
13101 }
13102
13103 return [newState, _dispatch];
13104 }
13105 }
13106 return [hook.memoizedState, _dispatch];
13107 }
13108
13109 // The last update in the entire queue
13110 var last = queue.last;
13111 // The last update that is part of the base state.
13112 var baseUpdate = hook.baseUpdate;
13113 var baseState = hook.baseState;
13114
13115 // Find the first unprocessed update.
13116 var first = void 0;
13117 if (baseUpdate !== null) {
13118 if (last !== null) {
13119 // For the first update, the queue is a circular linked list where
13120 // `queue.last.next = queue.first`. Once the first update commits, and
13121 // the `baseUpdate` is no longer empty, we can unravel the list.
13122 last.next = null;
13123 }
13124 first = baseUpdate.next;
13125 } else {
13126 first = last !== null ? last.next : null;
13127 }
13128 if (first !== null) {
13129 var _newState = baseState;
13130 var newBaseState = null;
13131 var newBaseUpdate = null;
13132 var prevUpdate = baseUpdate;
13133 var _update = first;
13134 var didSkip = false;
13135 do {
13136 var updateExpirationTime = _update.expirationTime;
13137 if (updateExpirationTime < renderExpirationTime) {
13138 // Priority is insufficient. Skip this update. If this is the first
13139 // skipped update, the previous update/state is the new base
13140 // update/state.
13141 if (!didSkip) {
13142 didSkip = true;
13143 newBaseUpdate = prevUpdate;
13144 newBaseState = _newState;
13145 }
13146 // Update the remaining priority in the queue.
13147 if (updateExpirationTime > remainingExpirationTime) {
13148 remainingExpirationTime = updateExpirationTime;
13149 }
13150 } else {
13151 // Process this update.
13152 if (_update.eagerReducer === reducer) {
13153 // If this update was processed eagerly, and its reducer matches the
13154 // current reducer, we can use the eagerly computed state.
13155 _newState = _update.eagerState;
13156 } else {
13157 var _action2 = _update.action;
13158 _newState = reducer(_newState, _action2);
13159 }
13160 }
13161 prevUpdate = _update;
13162 _update = _update.next;
13163 } while (_update !== null && _update !== first);
13164
13165 if (!didSkip) {
13166 newBaseUpdate = prevUpdate;
13167 newBaseState = _newState;
13168 }
13169
13170 // Mark that the fiber performed work, but only if the new state is
13171 // different from the current state.
13172 if (!is(_newState, hook.memoizedState)) {
13173 markWorkInProgressReceivedUpdate();
13174 }
13175
13176 hook.memoizedState = _newState;
13177 hook.baseUpdate = newBaseUpdate;
13178 hook.baseState = newBaseState;
13179
13180 queue.eagerReducer = reducer;
13181 queue.eagerState = _newState;
13182 }
13183
13184 var dispatch = queue.dispatch;
13185 return [hook.memoizedState, dispatch];
13186}
13187
13188function mountState(initialState) {
13189 var hook = mountWorkInProgressHook();
13190 if (typeof initialState === 'function') {
13191 initialState = initialState();
13192 }
13193 hook.memoizedState = hook.baseState = initialState;
13194 var queue = hook.queue = {
13195 last: null,
13196 dispatch: null,
13197 eagerReducer: basicStateReducer,
13198 eagerState: initialState
13199 };
13200 var dispatch = queue.dispatch = dispatchAction.bind(null,
13201 // Flow doesn't know this is non-null, but we do.
13202 currentlyRenderingFiber$1, queue);
13203 return [hook.memoizedState, dispatch];
13204}
13205
13206function updateState(initialState) {
13207 return updateReducer(basicStateReducer, initialState);
13208}
13209
13210function pushEffect(tag, create, destroy, deps) {
13211 var effect = {
13212 tag: tag,
13213 create: create,
13214 destroy: destroy,
13215 deps: deps,
13216 // Circular
13217 next: null
13218 };
13219 if (componentUpdateQueue === null) {
13220 componentUpdateQueue = createFunctionComponentUpdateQueue();
13221 componentUpdateQueue.lastEffect = effect.next = effect;
13222 } else {
13223 var _lastEffect = componentUpdateQueue.lastEffect;
13224 if (_lastEffect === null) {
13225 componentUpdateQueue.lastEffect = effect.next = effect;
13226 } else {
13227 var firstEffect = _lastEffect.next;
13228 _lastEffect.next = effect;
13229 effect.next = firstEffect;
13230 componentUpdateQueue.lastEffect = effect;
13231 }
13232 }
13233 return effect;
13234}
13235
13236function mountRef(initialValue) {
13237 var hook = mountWorkInProgressHook();
13238 var ref = { current: initialValue };
13239 {
13240 Object.seal(ref);
13241 }
13242 hook.memoizedState = ref;
13243 return ref;
13244}
13245
13246function updateRef(initialValue) {
13247 var hook = updateWorkInProgressHook();
13248 return hook.memoizedState;
13249}
13250
13251function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13252 var hook = mountWorkInProgressHook();
13253 var nextDeps = deps === undefined ? null : deps;
13254 sideEffectTag |= fiberEffectTag;
13255 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
13256}
13257
13258function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
13259 var hook = updateWorkInProgressHook();
13260 var nextDeps = deps === undefined ? null : deps;
13261 var destroy = undefined;
13262
13263 if (currentHook !== null) {
13264 var prevEffect = currentHook.memoizedState;
13265 destroy = prevEffect.destroy;
13266 if (nextDeps !== null) {
13267 var prevDeps = prevEffect.deps;
13268 if (areHookInputsEqual(nextDeps, prevDeps)) {
13269 pushEffect(NoEffect$1, create, destroy, nextDeps);
13270 return;
13271 }
13272 }
13273 }
13274
13275 sideEffectTag |= fiberEffectTag;
13276 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
13277}
13278
13279function mountEffect(create, deps) {
13280 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13281}
13282
13283function updateEffect(create, deps) {
13284 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
13285}
13286
13287function mountLayoutEffect(create, deps) {
13288 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13289}
13290
13291function updateLayoutEffect(create, deps) {
13292 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
13293}
13294
13295function imperativeHandleEffect(create, ref) {
13296 if (typeof ref === 'function') {
13297 var refCallback = ref;
13298 var _inst = create();
13299 refCallback(_inst);
13300 return function () {
13301 refCallback(null);
13302 };
13303 } else if (ref !== null && ref !== undefined) {
13304 var refObject = ref;
13305 {
13306 !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;
13307 }
13308 var _inst2 = create();
13309 refObject.current = _inst2;
13310 return function () {
13311 refObject.current = null;
13312 };
13313 }
13314}
13315
13316function mountImperativeHandle(ref, create, deps) {
13317 {
13318 !(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;
13319 }
13320
13321 // TODO: If deps are provided, should we skip comparing the ref itself?
13322 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13323
13324 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13325}
13326
13327function updateImperativeHandle(ref, create, deps) {
13328 {
13329 !(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;
13330 }
13331
13332 // TODO: If deps are provided, should we skip comparing the ref itself?
13333 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13334
13335 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13336}
13337
13338function mountDebugValue(value, formatterFn) {
13339 // This hook is normally a no-op.
13340 // The react-debug-hooks package injects its own implementation
13341 // so that e.g. DevTools can display custom hook values.
13342}
13343
13344var updateDebugValue = mountDebugValue;
13345
13346function mountCallback(callback, deps) {
13347 var hook = mountWorkInProgressHook();
13348 var nextDeps = deps === undefined ? null : deps;
13349 hook.memoizedState = [callback, nextDeps];
13350 return callback;
13351}
13352
13353function updateCallback(callback, deps) {
13354 var hook = updateWorkInProgressHook();
13355 var nextDeps = deps === undefined ? null : deps;
13356 var prevState = hook.memoizedState;
13357 if (prevState !== null) {
13358 if (nextDeps !== null) {
13359 var prevDeps = prevState[1];
13360 if (areHookInputsEqual(nextDeps, prevDeps)) {
13361 return prevState[0];
13362 }
13363 }
13364 }
13365 hook.memoizedState = [callback, nextDeps];
13366 return callback;
13367}
13368
13369function mountMemo(nextCreate, deps) {
13370 var hook = mountWorkInProgressHook();
13371 var nextDeps = deps === undefined ? null : deps;
13372 var nextValue = nextCreate();
13373 hook.memoizedState = [nextValue, nextDeps];
13374 return nextValue;
13375}
13376
13377function updateMemo(nextCreate, deps) {
13378 var hook = updateWorkInProgressHook();
13379 var nextDeps = deps === undefined ? null : deps;
13380 var prevState = hook.memoizedState;
13381 if (prevState !== null) {
13382 // Assume these are defined. If they're not, areHookInputsEqual will warn.
13383 if (nextDeps !== null) {
13384 var prevDeps = prevState[1];
13385 if (areHookInputsEqual(nextDeps, prevDeps)) {
13386 return prevState[0];
13387 }
13388 }
13389 }
13390 var nextValue = nextCreate();
13391 hook.memoizedState = [nextValue, nextDeps];
13392 return nextValue;
13393}
13394
13395// in a test-like environment, we want to warn if dispatchAction()
13396// is called outside of a batchedUpdates/TestUtils.act(...) call.
13397var shouldWarnForUnbatchedSetState = false;
13398
13399{
13400 // jest isn't a 'global', it's just exposed to tests via a wrapped function
13401 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
13402 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
13403 if ('undefined' !== typeof jest) {
13404 shouldWarnForUnbatchedSetState = true;
13405 }
13406}
13407
13408function dispatchAction(fiber, queue, action) {
13409 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
13410
13411 {
13412 !(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;
13413 }
13414
13415 var alternate = fiber.alternate;
13416 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
13417 // This is a render phase update. Stash it in a lazily-created map of
13418 // queue -> linked list of updates. After this render pass, we'll restart
13419 // and apply the stashed updates on top of the work-in-progress hook.
13420 didScheduleRenderPhaseUpdate = true;
13421 var update = {
13422 expirationTime: renderExpirationTime,
13423 action: action,
13424 eagerReducer: null,
13425 eagerState: null,
13426 next: null
13427 };
13428 if (renderPhaseUpdates === null) {
13429 renderPhaseUpdates = new Map();
13430 }
13431 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
13432 if (firstRenderPhaseUpdate === undefined) {
13433 renderPhaseUpdates.set(queue, update);
13434 } else {
13435 // Append the update to the end of the list.
13436 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
13437 while (lastRenderPhaseUpdate.next !== null) {
13438 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
13439 }
13440 lastRenderPhaseUpdate.next = update;
13441 }
13442 } else {
13443 flushPassiveEffects();
13444
13445 var currentTime = requestCurrentTime();
13446 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
13447
13448 var _update2 = {
13449 expirationTime: _expirationTime,
13450 action: action,
13451 eagerReducer: null,
13452 eagerState: null,
13453 next: null
13454 };
13455
13456 // Append the update to the end of the list.
13457 var _last = queue.last;
13458 if (_last === null) {
13459 // This is the first update. Create a circular list.
13460 _update2.next = _update2;
13461 } else {
13462 var first = _last.next;
13463 if (first !== null) {
13464 // Still circular.
13465 _update2.next = first;
13466 }
13467 _last.next = _update2;
13468 }
13469 queue.last = _update2;
13470
13471 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
13472 // The queue is currently empty, which means we can eagerly compute the
13473 // next state before entering the render phase. If the new state is the
13474 // same as the current state, we may be able to bail out entirely.
13475 var _eagerReducer = queue.eagerReducer;
13476 if (_eagerReducer !== null) {
13477 var prevDispatcher = void 0;
13478 {
13479 prevDispatcher = ReactCurrentDispatcher$1.current;
13480 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13481 }
13482 try {
13483 var currentState = queue.eagerState;
13484 var _eagerState = _eagerReducer(currentState, action);
13485 // Stash the eagerly computed state, and the reducer used to compute
13486 // it, on the update object. If the reducer hasn't changed by the
13487 // time we enter the render phase, then the eager state can be used
13488 // without calling the reducer again.
13489 _update2.eagerReducer = _eagerReducer;
13490 _update2.eagerState = _eagerState;
13491 if (is(_eagerState, currentState)) {
13492 // Fast path. We can bail out without scheduling React to re-render.
13493 // It's still possible that we'll need to rebase this update later,
13494 // if the component re-renders for a different reason and by that
13495 // time the reducer has changed.
13496 return;
13497 }
13498 } catch (error) {
13499 // Suppress the error. It will throw again in the render phase.
13500 } finally {
13501 {
13502 ReactCurrentDispatcher$1.current = prevDispatcher;
13503 }
13504 }
13505 }
13506 }
13507 {
13508 if (shouldWarnForUnbatchedSetState === true) {
13509 warnIfNotCurrentlyBatchingInDev(fiber);
13510 }
13511 }
13512 scheduleWork(fiber, _expirationTime);
13513 }
13514}
13515
13516var ContextOnlyDispatcher = {
13517 readContext: readContext,
13518
13519 useCallback: throwInvalidHookError,
13520 useContext: throwInvalidHookError,
13521 useEffect: throwInvalidHookError,
13522 useImperativeHandle: throwInvalidHookError,
13523 useLayoutEffect: throwInvalidHookError,
13524 useMemo: throwInvalidHookError,
13525 useReducer: throwInvalidHookError,
13526 useRef: throwInvalidHookError,
13527 useState: throwInvalidHookError,
13528 useDebugValue: throwInvalidHookError
13529};
13530
13531var HooksDispatcherOnMountInDEV = null;
13532var HooksDispatcherOnUpdateInDEV = null;
13533var InvalidNestedHooksDispatcherOnMountInDEV = null;
13534var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13535
13536{
13537 var warnInvalidContextAccess = function () {
13538 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().');
13539 };
13540
13541 var warnInvalidHookAccess = function () {
13542 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');
13543 };
13544
13545 HooksDispatcherOnMountInDEV = {
13546 readContext: function (context, observedBits) {
13547 return readContext(context, observedBits);
13548 },
13549 useCallback: function (callback, deps) {
13550 currentHookNameInDev = 'useCallback';
13551 return mountCallback(callback, deps);
13552 },
13553 useContext: function (context, observedBits) {
13554 currentHookNameInDev = 'useContext';
13555 return mountContext(context, observedBits);
13556 },
13557 useEffect: function (create, deps) {
13558 currentHookNameInDev = 'useEffect';
13559 return mountEffect(create, deps);
13560 },
13561 useImperativeHandle: function (ref, create, deps) {
13562 currentHookNameInDev = 'useImperativeHandle';
13563 return mountImperativeHandle(ref, create, deps);
13564 },
13565 useLayoutEffect: function (create, deps) {
13566 currentHookNameInDev = 'useLayoutEffect';
13567 return mountLayoutEffect(create, deps);
13568 },
13569 useMemo: function (create, deps) {
13570 currentHookNameInDev = 'useMemo';
13571 var prevDispatcher = ReactCurrentDispatcher$1.current;
13572 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13573 try {
13574 return mountMemo(create, deps);
13575 } finally {
13576 ReactCurrentDispatcher$1.current = prevDispatcher;
13577 }
13578 },
13579 useReducer: function (reducer, initialArg, init) {
13580 currentHookNameInDev = 'useReducer';
13581 var prevDispatcher = ReactCurrentDispatcher$1.current;
13582 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13583 try {
13584 return mountReducer(reducer, initialArg, init);
13585 } finally {
13586 ReactCurrentDispatcher$1.current = prevDispatcher;
13587 }
13588 },
13589 useRef: function (initialValue) {
13590 currentHookNameInDev = 'useRef';
13591 return mountRef(initialValue);
13592 },
13593 useState: function (initialState) {
13594 currentHookNameInDev = 'useState';
13595 var prevDispatcher = ReactCurrentDispatcher$1.current;
13596 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13597 try {
13598 return mountState(initialState);
13599 } finally {
13600 ReactCurrentDispatcher$1.current = prevDispatcher;
13601 }
13602 },
13603 useDebugValue: function (value, formatterFn) {
13604 currentHookNameInDev = 'useDebugValue';
13605 return mountDebugValue(value, formatterFn);
13606 }
13607 };
13608
13609 HooksDispatcherOnUpdateInDEV = {
13610 readContext: function (context, observedBits) {
13611 return readContext(context, observedBits);
13612 },
13613 useCallback: function (callback, deps) {
13614 currentHookNameInDev = 'useCallback';
13615 return updateCallback(callback, deps);
13616 },
13617 useContext: function (context, observedBits) {
13618 currentHookNameInDev = 'useContext';
13619 return updateContext(context, observedBits);
13620 },
13621 useEffect: function (create, deps) {
13622 currentHookNameInDev = 'useEffect';
13623 return updateEffect(create, deps);
13624 },
13625 useImperativeHandle: function (ref, create, deps) {
13626 currentHookNameInDev = 'useImperativeHandle';
13627 return updateImperativeHandle(ref, create, deps);
13628 },
13629 useLayoutEffect: function (create, deps) {
13630 currentHookNameInDev = 'useLayoutEffect';
13631 return updateLayoutEffect(create, deps);
13632 },
13633 useMemo: function (create, deps) {
13634 currentHookNameInDev = 'useMemo';
13635 var prevDispatcher = ReactCurrentDispatcher$1.current;
13636 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13637 try {
13638 return updateMemo(create, deps);
13639 } finally {
13640 ReactCurrentDispatcher$1.current = prevDispatcher;
13641 }
13642 },
13643 useReducer: function (reducer, initialArg, init) {
13644 currentHookNameInDev = 'useReducer';
13645 var prevDispatcher = ReactCurrentDispatcher$1.current;
13646 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13647 try {
13648 return updateReducer(reducer, initialArg, init);
13649 } finally {
13650 ReactCurrentDispatcher$1.current = prevDispatcher;
13651 }
13652 },
13653 useRef: function (initialValue) {
13654 currentHookNameInDev = 'useRef';
13655 return updateRef(initialValue);
13656 },
13657 useState: function (initialState) {
13658 currentHookNameInDev = 'useState';
13659 var prevDispatcher = ReactCurrentDispatcher$1.current;
13660 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13661 try {
13662 return updateState(initialState);
13663 } finally {
13664 ReactCurrentDispatcher$1.current = prevDispatcher;
13665 }
13666 },
13667 useDebugValue: function (value, formatterFn) {
13668 currentHookNameInDev = 'useDebugValue';
13669 return updateDebugValue(value, formatterFn);
13670 }
13671 };
13672
13673 InvalidNestedHooksDispatcherOnMountInDEV = {
13674 readContext: function (context, observedBits) {
13675 warnInvalidContextAccess();
13676 return readContext(context, observedBits);
13677 },
13678 useCallback: function (callback, deps) {
13679 currentHookNameInDev = 'useCallback';
13680 warnInvalidHookAccess();
13681 return mountCallback(callback, deps);
13682 },
13683 useContext: function (context, observedBits) {
13684 currentHookNameInDev = 'useContext';
13685 warnInvalidHookAccess();
13686 return mountContext(context, observedBits);
13687 },
13688 useEffect: function (create, deps) {
13689 currentHookNameInDev = 'useEffect';
13690 warnInvalidHookAccess();
13691 return mountEffect(create, deps);
13692 },
13693 useImperativeHandle: function (ref, create, deps) {
13694 currentHookNameInDev = 'useImperativeHandle';
13695 warnInvalidHookAccess();
13696 return mountImperativeHandle(ref, create, deps);
13697 },
13698 useLayoutEffect: function (create, deps) {
13699 currentHookNameInDev = 'useLayoutEffect';
13700 warnInvalidHookAccess();
13701 return mountLayoutEffect(create, deps);
13702 },
13703 useMemo: function (create, deps) {
13704 currentHookNameInDev = 'useMemo';
13705 warnInvalidHookAccess();
13706 var prevDispatcher = ReactCurrentDispatcher$1.current;
13707 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13708 try {
13709 return mountMemo(create, deps);
13710 } finally {
13711 ReactCurrentDispatcher$1.current = prevDispatcher;
13712 }
13713 },
13714 useReducer: function (reducer, initialArg, init) {
13715 currentHookNameInDev = 'useReducer';
13716 warnInvalidHookAccess();
13717 var prevDispatcher = ReactCurrentDispatcher$1.current;
13718 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13719 try {
13720 return mountReducer(reducer, initialArg, init);
13721 } finally {
13722 ReactCurrentDispatcher$1.current = prevDispatcher;
13723 }
13724 },
13725 useRef: function (initialValue) {
13726 currentHookNameInDev = 'useRef';
13727 warnInvalidHookAccess();
13728 return mountRef(initialValue);
13729 },
13730 useState: function (initialState) {
13731 currentHookNameInDev = 'useState';
13732 warnInvalidHookAccess();
13733 var prevDispatcher = ReactCurrentDispatcher$1.current;
13734 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13735 try {
13736 return mountState(initialState);
13737 } finally {
13738 ReactCurrentDispatcher$1.current = prevDispatcher;
13739 }
13740 },
13741 useDebugValue: function (value, formatterFn) {
13742 currentHookNameInDev = 'useDebugValue';
13743 warnInvalidHookAccess();
13744 return mountDebugValue(value, formatterFn);
13745 }
13746 };
13747
13748 InvalidNestedHooksDispatcherOnUpdateInDEV = {
13749 readContext: function (context, observedBits) {
13750 warnInvalidContextAccess();
13751 return readContext(context, observedBits);
13752 },
13753 useCallback: function (callback, deps) {
13754 currentHookNameInDev = 'useCallback';
13755 warnInvalidHookAccess();
13756 return updateCallback(callback, deps);
13757 },
13758 useContext: function (context, observedBits) {
13759 currentHookNameInDev = 'useContext';
13760 warnInvalidHookAccess();
13761 return updateContext(context, observedBits);
13762 },
13763 useEffect: function (create, deps) {
13764 currentHookNameInDev = 'useEffect';
13765 warnInvalidHookAccess();
13766 return updateEffect(create, deps);
13767 },
13768 useImperativeHandle: function (ref, create, deps) {
13769 currentHookNameInDev = 'useImperativeHandle';
13770 warnInvalidHookAccess();
13771 return updateImperativeHandle(ref, create, deps);
13772 },
13773 useLayoutEffect: function (create, deps) {
13774 currentHookNameInDev = 'useLayoutEffect';
13775 warnInvalidHookAccess();
13776 return updateLayoutEffect(create, deps);
13777 },
13778 useMemo: function (create, deps) {
13779 currentHookNameInDev = 'useMemo';
13780 warnInvalidHookAccess();
13781 var prevDispatcher = ReactCurrentDispatcher$1.current;
13782 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13783 try {
13784 return updateMemo(create, deps);
13785 } finally {
13786 ReactCurrentDispatcher$1.current = prevDispatcher;
13787 }
13788 },
13789 useReducer: function (reducer, initialArg, init) {
13790 currentHookNameInDev = 'useReducer';
13791 warnInvalidHookAccess();
13792 var prevDispatcher = ReactCurrentDispatcher$1.current;
13793 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13794 try {
13795 return updateReducer(reducer, initialArg, init);
13796 } finally {
13797 ReactCurrentDispatcher$1.current = prevDispatcher;
13798 }
13799 },
13800 useRef: function (initialValue) {
13801 currentHookNameInDev = 'useRef';
13802 warnInvalidHookAccess();
13803 return updateRef(initialValue);
13804 },
13805 useState: function (initialState) {
13806 currentHookNameInDev = 'useState';
13807 warnInvalidHookAccess();
13808 var prevDispatcher = ReactCurrentDispatcher$1.current;
13809 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13810 try {
13811 return updateState(initialState);
13812 } finally {
13813 ReactCurrentDispatcher$1.current = prevDispatcher;
13814 }
13815 },
13816 useDebugValue: function (value, formatterFn) {
13817 currentHookNameInDev = 'useDebugValue';
13818 warnInvalidHookAccess();
13819 return updateDebugValue(value, formatterFn);
13820 }
13821 };
13822}
13823
13824var commitTime = 0;
13825var profilerStartTime = -1;
13826
13827function getCommitTime() {
13828 return commitTime;
13829}
13830
13831function recordCommitTime() {
13832 if (!enableProfilerTimer) {
13833 return;
13834 }
13835 commitTime = scheduler.unstable_now();
13836}
13837
13838function startProfilerTimer(fiber) {
13839 if (!enableProfilerTimer) {
13840 return;
13841 }
13842
13843 profilerStartTime = scheduler.unstable_now();
13844
13845 if (fiber.actualStartTime < 0) {
13846 fiber.actualStartTime = scheduler.unstable_now();
13847 }
13848}
13849
13850function stopProfilerTimerIfRunning(fiber) {
13851 if (!enableProfilerTimer) {
13852 return;
13853 }
13854 profilerStartTime = -1;
13855}
13856
13857function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
13858 if (!enableProfilerTimer) {
13859 return;
13860 }
13861
13862 if (profilerStartTime >= 0) {
13863 var elapsedTime = scheduler.unstable_now() - profilerStartTime;
13864 fiber.actualDuration += elapsedTime;
13865 if (overrideBaseTime) {
13866 fiber.selfBaseDuration = elapsedTime;
13867 }
13868 profilerStartTime = -1;
13869 }
13870}
13871
13872// The deepest Fiber on the stack involved in a hydration context.
13873// This may have been an insertion or a hydration.
13874var hydrationParentFiber = null;
13875var nextHydratableInstance = null;
13876var isHydrating = false;
13877
13878function enterHydrationState(fiber) {
13879 if (!supportsHydration) {
13880 return false;
13881 }
13882
13883 var parentInstance = fiber.stateNode.containerInfo;
13884 nextHydratableInstance = getFirstHydratableChild(parentInstance);
13885 hydrationParentFiber = fiber;
13886 isHydrating = true;
13887 return true;
13888}
13889
13890function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
13891 if (!supportsHydration) {
13892 return false;
13893 }
13894
13895 var suspenseInstance = fiber.stateNode;
13896 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
13897 popToNextHostParent(fiber);
13898 isHydrating = true;
13899 return true;
13900}
13901
13902function deleteHydratableInstance(returnFiber, instance) {
13903 {
13904 switch (returnFiber.tag) {
13905 case HostRoot:
13906 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
13907 break;
13908 case HostComponent:
13909 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
13910 break;
13911 }
13912 }
13913
13914 var childToDelete = createFiberFromHostInstanceForDeletion();
13915 childToDelete.stateNode = instance;
13916 childToDelete.return = returnFiber;
13917 childToDelete.effectTag = Deletion;
13918
13919 // This might seem like it belongs on progressedFirstDeletion. However,
13920 // these children are not part of the reconciliation list of children.
13921 // Even if we abort and rereconcile the children, that will try to hydrate
13922 // again and the nodes are still in the host tree so these will be
13923 // recreated.
13924 if (returnFiber.lastEffect !== null) {
13925 returnFiber.lastEffect.nextEffect = childToDelete;
13926 returnFiber.lastEffect = childToDelete;
13927 } else {
13928 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
13929 }
13930}
13931
13932function insertNonHydratedInstance(returnFiber, fiber) {
13933 fiber.effectTag |= Placement;
13934 {
13935 switch (returnFiber.tag) {
13936 case HostRoot:
13937 {
13938 var parentContainer = returnFiber.stateNode.containerInfo;
13939 switch (fiber.tag) {
13940 case HostComponent:
13941 var type = fiber.type;
13942 var props = fiber.pendingProps;
13943 didNotFindHydratableContainerInstance(parentContainer, type, props);
13944 break;
13945 case HostText:
13946 var text = fiber.pendingProps;
13947 didNotFindHydratableContainerTextInstance(parentContainer, text);
13948 break;
13949 case SuspenseComponent:
13950
13951 break;
13952 }
13953 break;
13954 }
13955 case HostComponent:
13956 {
13957 var parentType = returnFiber.type;
13958 var parentProps = returnFiber.memoizedProps;
13959 var parentInstance = returnFiber.stateNode;
13960 switch (fiber.tag) {
13961 case HostComponent:
13962 var _type = fiber.type;
13963 var _props = fiber.pendingProps;
13964 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
13965 break;
13966 case HostText:
13967 var _text = fiber.pendingProps;
13968 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
13969 break;
13970 case SuspenseComponent:
13971 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
13972 break;
13973 }
13974 break;
13975 }
13976 default:
13977 return;
13978 }
13979 }
13980}
13981
13982function tryHydrate(fiber, nextInstance) {
13983 switch (fiber.tag) {
13984 case HostComponent:
13985 {
13986 var type = fiber.type;
13987 var props = fiber.pendingProps;
13988 var instance = canHydrateInstance(nextInstance, type, props);
13989 if (instance !== null) {
13990 fiber.stateNode = instance;
13991 return true;
13992 }
13993 return false;
13994 }
13995 case HostText:
13996 {
13997 var text = fiber.pendingProps;
13998 var textInstance = canHydrateTextInstance(nextInstance, text);
13999 if (textInstance !== null) {
14000 fiber.stateNode = textInstance;
14001 return true;
14002 }
14003 return false;
14004 }
14005 case SuspenseComponent:
14006 {
14007 if (enableSuspenseServerRenderer) {
14008 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
14009 if (suspenseInstance !== null) {
14010 // Downgrade the tag to a dehydrated component until we've hydrated it.
14011 fiber.tag = DehydratedSuspenseComponent;
14012 fiber.stateNode = suspenseInstance;
14013 return true;
14014 }
14015 }
14016 return false;
14017 }
14018 default:
14019 return false;
14020 }
14021}
14022
14023function tryToClaimNextHydratableInstance(fiber) {
14024 if (!isHydrating) {
14025 return;
14026 }
14027 var nextInstance = nextHydratableInstance;
14028 if (!nextInstance) {
14029 // Nothing to hydrate. Make it an insertion.
14030 insertNonHydratedInstance(hydrationParentFiber, fiber);
14031 isHydrating = false;
14032 hydrationParentFiber = fiber;
14033 return;
14034 }
14035 var firstAttemptedInstance = nextInstance;
14036 if (!tryHydrate(fiber, nextInstance)) {
14037 // If we can't hydrate this instance let's try the next one.
14038 // We use this as a heuristic. It's based on intuition and not data so it
14039 // might be flawed or unnecessary.
14040 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14041 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14042 // Nothing to hydrate. Make it an insertion.
14043 insertNonHydratedInstance(hydrationParentFiber, fiber);
14044 isHydrating = false;
14045 hydrationParentFiber = fiber;
14046 return;
14047 }
14048 // We matched the next one, we'll now assume that the first one was
14049 // superfluous and we'll delete it. Since we can't eagerly delete it
14050 // we'll have to schedule a deletion. To do that, this node needs a dummy
14051 // fiber associated with it.
14052 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
14053 }
14054 hydrationParentFiber = fiber;
14055 nextHydratableInstance = getFirstHydratableChild(nextInstance);
14056}
14057
14058function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14059 if (!supportsHydration) {
14060 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14061 }
14062
14063 var instance = fiber.stateNode;
14064 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
14065 // TODO: Type this specific to this type of component.
14066 fiber.updateQueue = updatePayload;
14067 // If the update payload indicates that there is a change or if there
14068 // is a new ref we mark this as an update.
14069 if (updatePayload !== null) {
14070 return true;
14071 }
14072 return false;
14073}
14074
14075function prepareToHydrateHostTextInstance(fiber) {
14076 if (!supportsHydration) {
14077 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14078 }
14079
14080 var textInstance = fiber.stateNode;
14081 var textContent = fiber.memoizedProps;
14082 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14083 {
14084 if (shouldUpdate) {
14085 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14086 // hydration parent is the parent host component of this host text.
14087 var returnFiber = hydrationParentFiber;
14088 if (returnFiber !== null) {
14089 switch (returnFiber.tag) {
14090 case HostRoot:
14091 {
14092 var parentContainer = returnFiber.stateNode.containerInfo;
14093 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
14094 break;
14095 }
14096 case HostComponent:
14097 {
14098 var parentType = returnFiber.type;
14099 var parentProps = returnFiber.memoizedProps;
14100 var parentInstance = returnFiber.stateNode;
14101 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
14102 break;
14103 }
14104 }
14105 }
14106 }
14107 }
14108 return shouldUpdate;
14109}
14110
14111function skipPastDehydratedSuspenseInstance(fiber) {
14112 if (!supportsHydration) {
14113 invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14114 }
14115 var suspenseInstance = fiber.stateNode;
14116 !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;
14117 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14118}
14119
14120function popToNextHostParent(fiber) {
14121 var parent = fiber.return;
14122 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
14123 parent = parent.return;
14124 }
14125 hydrationParentFiber = parent;
14126}
14127
14128function popHydrationState(fiber) {
14129 if (!supportsHydration) {
14130 return false;
14131 }
14132 if (fiber !== hydrationParentFiber) {
14133 // We're deeper than the current hydration context, inside an inserted
14134 // tree.
14135 return false;
14136 }
14137 if (!isHydrating) {
14138 // If we're not currently hydrating but we're in a hydration context, then
14139 // we were an insertion and now need to pop up reenter hydration of our
14140 // siblings.
14141 popToNextHostParent(fiber);
14142 isHydrating = true;
14143 return false;
14144 }
14145
14146 var type = fiber.type;
14147
14148 // If we have any remaining hydratable nodes, we need to delete them now.
14149 // We only do this deeper than head and body since they tend to have random
14150 // other nodes in them. We also ignore components with pure text content in
14151 // side of them.
14152 // TODO: Better heuristic.
14153 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
14154 var nextInstance = nextHydratableInstance;
14155 while (nextInstance) {
14156 deleteHydratableInstance(fiber, nextInstance);
14157 nextInstance = getNextHydratableSibling(nextInstance);
14158 }
14159 }
14160
14161 popToNextHostParent(fiber);
14162 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14163 return true;
14164}
14165
14166function resetHydrationState() {
14167 if (!supportsHydration) {
14168 return;
14169 }
14170
14171 hydrationParentFiber = null;
14172 nextHydratableInstance = null;
14173 isHydrating = false;
14174}
14175
14176var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
14177
14178var didReceiveUpdate = false;
14179
14180var didWarnAboutBadClass = void 0;
14181var didWarnAboutContextTypeOnFunctionComponent = void 0;
14182var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
14183var didWarnAboutFunctionRefs = void 0;
14184var didWarnAboutReassigningProps = void 0;
14185
14186{
14187 didWarnAboutBadClass = {};
14188 didWarnAboutContextTypeOnFunctionComponent = {};
14189 didWarnAboutGetDerivedStateOnFunctionComponent = {};
14190 didWarnAboutFunctionRefs = {};
14191 didWarnAboutReassigningProps = false;
14192}
14193
14194function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14195 if (current$$1 === null) {
14196 // If this is a fresh new component that hasn't been rendered yet, we
14197 // won't update its child set by applying minimal side-effects. Instead,
14198 // we will add them all to the child before it gets rendered. That means
14199 // we can optimize this reconciliation pass by not tracking side-effects.
14200 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14201 } else {
14202 // If the current child is the same as the work in progress, it means that
14203 // we haven't yet started any work on these children. Therefore, we use
14204 // the clone algorithm to create a copy of all the current children.
14205
14206 // If we had any progressed work already, that is invalid at this point so
14207 // let's throw it out.
14208 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
14209 }
14210}
14211
14212function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
14213 // This function is fork of reconcileChildren. It's used in cases where we
14214 // want to reconcile without matching against the existing set. This has the
14215 // effect of all current children being unmounted; even if the type and key
14216 // are the same, the old child is unmounted and a new child is created.
14217 //
14218 // To do this, we're going to go through the reconcile algorithm twice. In
14219 // the first pass, we schedule a deletion for all the current children by
14220 // passing null.
14221 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
14222 // In the second pass, we mount the new children. The trick here is that we
14223 // pass null in place of where we usually pass the current child set. This has
14224 // the effect of remounting all children regardless of whether their their
14225 // identity matches.
14226 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14227}
14228
14229function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14230 // TODO: current can be non-null here even if the component
14231 // hasn't yet mounted. This happens after the first render suspends.
14232 // We'll need to figure out if this is fine or can cause issues.
14233
14234 {
14235 if (workInProgress.type !== workInProgress.elementType) {
14236 // Lazy component props can't be validated in createElement
14237 // because they're only guaranteed to be resolved here.
14238 var innerPropTypes = Component.propTypes;
14239 if (innerPropTypes) {
14240 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14241 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14242 }
14243 }
14244 }
14245
14246 var render = Component.render;
14247 var ref = workInProgress.ref;
14248
14249 // The rest is a fork of updateFunctionComponent
14250 var nextChildren = void 0;
14251 prepareToReadContext(workInProgress, renderExpirationTime);
14252 {
14253 ReactCurrentOwner$3.current = workInProgress;
14254 setCurrentPhase('render');
14255 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14256 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14257 // Only double-render components with Hooks
14258 if (workInProgress.memoizedState !== null) {
14259 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
14260 }
14261 }
14262 setCurrentPhase(null);
14263 }
14264
14265 if (current$$1 !== null && !didReceiveUpdate) {
14266 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14267 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14268 }
14269
14270 // React DevTools reads this flag.
14271 workInProgress.effectTag |= PerformedWork;
14272 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14273 return workInProgress.child;
14274}
14275
14276function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14277 if (current$$1 === null) {
14278 var type = Component.type;
14279 if (isSimpleFunctionComponent(type) && Component.compare === null &&
14280 // SimpleMemoComponent codepath doesn't resolve outer props either.
14281 Component.defaultProps === undefined) {
14282 // If this is a plain function component without default props,
14283 // and with only the default shallow comparison, we upgrade it
14284 // to a SimpleMemoComponent to allow fast path updates.
14285 workInProgress.tag = SimpleMemoComponent;
14286 workInProgress.type = type;
14287 {
14288 validateFunctionComponentInDev(workInProgress, type);
14289 }
14290 return updateSimpleMemoComponent(current$$1, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
14291 }
14292 {
14293 var innerPropTypes = type.propTypes;
14294 if (innerPropTypes) {
14295 // Inner memo component props aren't currently validated in createElement.
14296 // We could move it there, but we'd still need this for lazy code path.
14297 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14298 'prop', getComponentName(type), getCurrentFiberStackInDev);
14299 }
14300 }
14301 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
14302 child.ref = workInProgress.ref;
14303 child.return = workInProgress;
14304 workInProgress.child = child;
14305 return child;
14306 }
14307 {
14308 var _type = Component.type;
14309 var _innerPropTypes = _type.propTypes;
14310 if (_innerPropTypes) {
14311 // Inner memo component props aren't currently validated in createElement.
14312 // We could move it there, but we'd still need this for lazy code path.
14313 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
14314 'prop', getComponentName(_type), getCurrentFiberStackInDev);
14315 }
14316 }
14317 var currentChild = current$$1.child; // This is always exactly one child
14318 if (updateExpirationTime < renderExpirationTime) {
14319 // This will be the props with resolved defaultProps,
14320 // unlike current.memoizedProps which will be the unresolved ones.
14321 var prevProps = currentChild.memoizedProps;
14322 // Default to shallow comparison
14323 var compare = Component.compare;
14324 compare = compare !== null ? compare : shallowEqual;
14325 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14326 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14327 }
14328 }
14329 // React DevTools reads this flag.
14330 workInProgress.effectTag |= PerformedWork;
14331 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
14332 newChild.ref = workInProgress.ref;
14333 newChild.return = workInProgress;
14334 workInProgress.child = newChild;
14335 return newChild;
14336}
14337
14338function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14339 // TODO: current can be non-null here even if the component
14340 // hasn't yet mounted. This happens when the inner render suspends.
14341 // We'll need to figure out if this is fine or can cause issues.
14342
14343 {
14344 if (workInProgress.type !== workInProgress.elementType) {
14345 // Lazy component props can't be validated in createElement
14346 // because they're only guaranteed to be resolved here.
14347 var outerMemoType = workInProgress.elementType;
14348 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
14349 // We warn when you define propTypes on lazy()
14350 // so let's just skip over it to find memo() outer wrapper.
14351 // Inner props for memo are validated later.
14352 outerMemoType = refineResolvedLazyComponent(outerMemoType);
14353 }
14354 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
14355 if (outerPropTypes) {
14356 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
14357 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
14358 }
14359 // Inner propTypes will be validated in the function component path.
14360 }
14361 }
14362 if (current$$1 !== null) {
14363 var prevProps = current$$1.memoizedProps;
14364 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
14365 didReceiveUpdate = false;
14366 if (updateExpirationTime < renderExpirationTime) {
14367 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14368 }
14369 }
14370 }
14371 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14372}
14373
14374function updateFragment(current$$1, workInProgress, renderExpirationTime) {
14375 var nextChildren = workInProgress.pendingProps;
14376 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14377 return workInProgress.child;
14378}
14379
14380function updateMode(current$$1, workInProgress, renderExpirationTime) {
14381 var nextChildren = workInProgress.pendingProps.children;
14382 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14383 return workInProgress.child;
14384}
14385
14386function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
14387 if (enableProfilerTimer) {
14388 workInProgress.effectTag |= Update;
14389 }
14390 var nextProps = workInProgress.pendingProps;
14391 var nextChildren = nextProps.children;
14392 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14393 return workInProgress.child;
14394}
14395
14396function markRef(current$$1, workInProgress) {
14397 var ref = workInProgress.ref;
14398 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
14399 // Schedule a Ref effect
14400 workInProgress.effectTag |= Ref;
14401 }
14402}
14403
14404function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14405 {
14406 if (workInProgress.type !== workInProgress.elementType) {
14407 // Lazy component props can't be validated in createElement
14408 // because they're only guaranteed to be resolved here.
14409 var innerPropTypes = Component.propTypes;
14410 if (innerPropTypes) {
14411 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14412 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14413 }
14414 }
14415 }
14416
14417 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
14418 var context = getMaskedContext(workInProgress, unmaskedContext);
14419
14420 var nextChildren = void 0;
14421 prepareToReadContext(workInProgress, renderExpirationTime);
14422 {
14423 ReactCurrentOwner$3.current = workInProgress;
14424 setCurrentPhase('render');
14425 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14426 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14427 // Only double-render components with Hooks
14428 if (workInProgress.memoizedState !== null) {
14429 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
14430 }
14431 }
14432 setCurrentPhase(null);
14433 }
14434
14435 if (current$$1 !== null && !didReceiveUpdate) {
14436 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
14437 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14438 }
14439
14440 // React DevTools reads this flag.
14441 workInProgress.effectTag |= PerformedWork;
14442 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14443 return workInProgress.child;
14444}
14445
14446function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14447 {
14448 if (workInProgress.type !== workInProgress.elementType) {
14449 // Lazy component props can't be validated in createElement
14450 // because they're only guaranteed to be resolved here.
14451 var innerPropTypes = Component.propTypes;
14452 if (innerPropTypes) {
14453 checkPropTypes(innerPropTypes, nextProps, // Resolved props
14454 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14455 }
14456 }
14457 }
14458
14459 // Push context providers early to prevent context stack mismatches.
14460 // During mounting we don't know the child context yet as the instance doesn't exist.
14461 // We will invalidate the child context in finishClassComponent() right after rendering.
14462 var hasContext = void 0;
14463 if (isContextProvider(Component)) {
14464 hasContext = true;
14465 pushContextProvider(workInProgress);
14466 } else {
14467 hasContext = false;
14468 }
14469 prepareToReadContext(workInProgress, renderExpirationTime);
14470
14471 var instance = workInProgress.stateNode;
14472 var shouldUpdate = void 0;
14473 if (instance === null) {
14474 if (current$$1 !== null) {
14475 // An class component without an instance only mounts if it suspended
14476 // inside a non- concurrent tree, in an inconsistent state. We want to
14477 // tree it like a new mount, even though an empty version of it already
14478 // committed. Disconnect the alternate pointers.
14479 current$$1.alternate = null;
14480 workInProgress.alternate = null;
14481 // Since this is conceptually a new fiber, schedule a Placement effect
14482 workInProgress.effectTag |= Placement;
14483 }
14484 // In the initial pass we might need to construct the instance.
14485 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14486 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14487 shouldUpdate = true;
14488 } else if (current$$1 === null) {
14489 // In a resume, we'll already have an instance we can reuse.
14490 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14491 } else {
14492 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
14493 }
14494 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
14495 {
14496 var inst = workInProgress.stateNode;
14497 if (inst.props !== nextProps) {
14498 !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;
14499 didWarnAboutReassigningProps = true;
14500 }
14501 }
14502 return nextUnitOfWork;
14503}
14504
14505function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
14506 // Refs should update even if shouldComponentUpdate returns false
14507 markRef(current$$1, workInProgress);
14508
14509 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
14510
14511 if (!shouldUpdate && !didCaptureError) {
14512 // Context providers should defer to sCU for rendering
14513 if (hasContext) {
14514 invalidateContextProvider(workInProgress, Component, false);
14515 }
14516
14517 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14518 }
14519
14520 var instance = workInProgress.stateNode;
14521
14522 // Rerender
14523 ReactCurrentOwner$3.current = workInProgress;
14524 var nextChildren = void 0;
14525 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
14526 // If we captured an error, but getDerivedStateFrom catch is not defined,
14527 // unmount all the children. componentDidCatch will schedule an update to
14528 // re-render a fallback. This is temporary until we migrate everyone to
14529 // the new API.
14530 // TODO: Warn in a future release.
14531 nextChildren = null;
14532
14533 if (enableProfilerTimer) {
14534 stopProfilerTimerIfRunning(workInProgress);
14535 }
14536 } else {
14537 {
14538 setCurrentPhase('render');
14539 nextChildren = instance.render();
14540 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14541 instance.render();
14542 }
14543 setCurrentPhase(null);
14544 }
14545 }
14546
14547 // React DevTools reads this flag.
14548 workInProgress.effectTag |= PerformedWork;
14549 if (current$$1 !== null && didCaptureError) {
14550 // If we're recovering from an error, reconcile without reusing any of
14551 // the existing children. Conceptually, the normal children and the children
14552 // that are shown on error are two different sets, so we shouldn't reuse
14553 // normal children even if their identities match.
14554 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
14555 } else {
14556 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14557 }
14558
14559 // Memoize state using the values we just used to render.
14560 // TODO: Restructure so we never read values from the instance.
14561 workInProgress.memoizedState = instance.state;
14562
14563 // The context might have changed so we need to recalculate it.
14564 if (hasContext) {
14565 invalidateContextProvider(workInProgress, Component, true);
14566 }
14567
14568 return workInProgress.child;
14569}
14570
14571function pushHostRootContext(workInProgress) {
14572 var root = workInProgress.stateNode;
14573 if (root.pendingContext) {
14574 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
14575 } else if (root.context) {
14576 // Should always be set
14577 pushTopLevelContextObject(workInProgress, root.context, false);
14578 }
14579 pushHostContainer(workInProgress, root.containerInfo);
14580}
14581
14582function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
14583 pushHostRootContext(workInProgress);
14584 var updateQueue = workInProgress.updateQueue;
14585 !(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;
14586 var nextProps = workInProgress.pendingProps;
14587 var prevState = workInProgress.memoizedState;
14588 var prevChildren = prevState !== null ? prevState.element : null;
14589 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
14590 var nextState = workInProgress.memoizedState;
14591 // Caution: React DevTools currently depends on this property
14592 // being called "element".
14593 var nextChildren = nextState.element;
14594 if (nextChildren === prevChildren) {
14595 // If the state is the same as before, that's a bailout because we had
14596 // no work that expires at this time.
14597 resetHydrationState();
14598 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
14599 }
14600 var root = workInProgress.stateNode;
14601 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
14602 // If we don't have any current children this might be the first pass.
14603 // We always try to hydrate. If this isn't a hydration pass there won't
14604 // be any children to hydrate which is effectively the same thing as
14605 // not hydrating.
14606
14607 // This is a bit of a hack. We track the host root as a placement to
14608 // know that we're currently in a mounting state. That way isMounted
14609 // works as expected. We must reset this before committing.
14610 // TODO: Delete this when we delete isMounted and findDOMNode.
14611 workInProgress.effectTag |= Placement;
14612
14613 // Ensure that children mount into this root without tracking
14614 // side-effects. This ensures that we don't store Placement effects on
14615 // nodes that will be hydrated.
14616 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
14617 } else {
14618 // Otherwise reset hydration state in case we aborted and resumed another
14619 // root.
14620 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14621 resetHydrationState();
14622 }
14623 return workInProgress.child;
14624}
14625
14626function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
14627 pushHostContext(workInProgress);
14628
14629 if (current$$1 === null) {
14630 tryToClaimNextHydratableInstance(workInProgress);
14631 }
14632
14633 var type = workInProgress.type;
14634 var nextProps = workInProgress.pendingProps;
14635 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
14636
14637 var nextChildren = nextProps.children;
14638 var isDirectTextChild = shouldSetTextContent(type, nextProps);
14639
14640 if (isDirectTextChild) {
14641 // We special case a direct text child of a host node. This is a common
14642 // case. We won't handle it as a reified child. We will instead handle
14643 // this in the host environment that also have access to this prop. That
14644 // avoids allocating another HostText fiber and traversing it.
14645 nextChildren = null;
14646 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
14647 // If we're switching from a direct text child to a normal child, or to
14648 // empty, we need to schedule the text content to be reset.
14649 workInProgress.effectTag |= ContentReset;
14650 }
14651
14652 markRef(current$$1, workInProgress);
14653
14654 // Check the host config to see if the children are offscreen/hidden.
14655 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
14656 // Schedule this fiber to re-render at offscreen priority. Then bailout.
14657 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
14658 return null;
14659 }
14660
14661 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
14662 return workInProgress.child;
14663}
14664
14665function updateHostText(current$$1, workInProgress) {
14666 if (current$$1 === null) {
14667 tryToClaimNextHydratableInstance(workInProgress);
14668 }
14669 // Nothing to do here. This is terminal. We'll do the completion step
14670 // immediately after.
14671 return null;
14672}
14673
14674function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
14675 if (_current !== null) {
14676 // An lazy component only mounts if it suspended inside a non-
14677 // concurrent tree, in an inconsistent state. We want to treat it like
14678 // a new mount, even though an empty version of it already committed.
14679 // Disconnect the alternate pointers.
14680 _current.alternate = null;
14681 workInProgress.alternate = null;
14682 // Since this is conceptually a new fiber, schedule a Placement effect
14683 workInProgress.effectTag |= Placement;
14684 }
14685
14686 var props = workInProgress.pendingProps;
14687 // We can't start a User Timing measurement with correct label yet.
14688 // Cancel and resume right after we know the tag.
14689 cancelWorkTimer(workInProgress);
14690 var Component = readLazyComponentType(elementType);
14691 // Store the unwrapped component in the type.
14692 workInProgress.type = Component;
14693 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
14694 startWorkTimer(workInProgress);
14695 var resolvedProps = resolveDefaultProps(Component, props);
14696 var child = void 0;
14697 switch (resolvedTag) {
14698 case FunctionComponent:
14699 {
14700 {
14701 validateFunctionComponentInDev(workInProgress, Component);
14702 }
14703 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14704 break;
14705 }
14706 case ClassComponent:
14707 {
14708 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14709 break;
14710 }
14711 case ForwardRef:
14712 {
14713 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
14714 break;
14715 }
14716 case MemoComponent:
14717 {
14718 {
14719 if (workInProgress.type !== workInProgress.elementType) {
14720 var outerPropTypes = Component.propTypes;
14721 if (outerPropTypes) {
14722 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
14723 'prop', getComponentName(Component), getCurrentFiberStackInDev);
14724 }
14725 }
14726 }
14727 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
14728 updateExpirationTime, renderExpirationTime);
14729 break;
14730 }
14731 default:
14732 {
14733 var hint = '';
14734 {
14735 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
14736 hint = ' Did you wrap a component in React.lazy() more than once?';
14737 }
14738 }
14739 // This message intentionally doesn't mention ForwardRef or MemoComponent
14740 // because the fact that it's a separate type of work is an
14741 // implementation detail.
14742 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);
14743 }
14744 }
14745 return child;
14746}
14747
14748function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
14749 if (_current !== null) {
14750 // An incomplete component only mounts if it suspended inside a non-
14751 // concurrent tree, in an inconsistent state. We want to treat it like
14752 // a new mount, even though an empty version of it already committed.
14753 // Disconnect the alternate pointers.
14754 _current.alternate = null;
14755 workInProgress.alternate = null;
14756 // Since this is conceptually a new fiber, schedule a Placement effect
14757 workInProgress.effectTag |= Placement;
14758 }
14759
14760 // Promote the fiber to a class and try rendering again.
14761 workInProgress.tag = ClassComponent;
14762
14763 // The rest of this function is a fork of `updateClassComponent`
14764
14765 // Push context providers early to prevent context stack mismatches.
14766 // During mounting we don't know the child context yet as the instance doesn't exist.
14767 // We will invalidate the child context in finishClassComponent() right after rendering.
14768 var hasContext = void 0;
14769 if (isContextProvider(Component)) {
14770 hasContext = true;
14771 pushContextProvider(workInProgress);
14772 } else {
14773 hasContext = false;
14774 }
14775 prepareToReadContext(workInProgress, renderExpirationTime);
14776
14777 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14778 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
14779
14780 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14781}
14782
14783function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
14784 if (_current !== null) {
14785 // An indeterminate component only mounts if it suspended inside a non-
14786 // concurrent tree, in an inconsistent state. We want to treat it like
14787 // a new mount, even though an empty version of it already committed.
14788 // Disconnect the alternate pointers.
14789 _current.alternate = null;
14790 workInProgress.alternate = null;
14791 // Since this is conceptually a new fiber, schedule a Placement effect
14792 workInProgress.effectTag |= Placement;
14793 }
14794
14795 var props = workInProgress.pendingProps;
14796 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
14797 var context = getMaskedContext(workInProgress, unmaskedContext);
14798
14799 prepareToReadContext(workInProgress, renderExpirationTime);
14800
14801 var value = void 0;
14802
14803 {
14804 if (Component.prototype && typeof Component.prototype.render === 'function') {
14805 var componentName = getComponentName(Component) || 'Unknown';
14806
14807 if (!didWarnAboutBadClass[componentName]) {
14808 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);
14809 didWarnAboutBadClass[componentName] = true;
14810 }
14811 }
14812
14813 if (workInProgress.mode & StrictMode) {
14814 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
14815 }
14816
14817 ReactCurrentOwner$3.current = workInProgress;
14818 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
14819 }
14820 // React DevTools reads this flag.
14821 workInProgress.effectTag |= PerformedWork;
14822
14823 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
14824 // Proceed under the assumption that this is a class instance
14825 workInProgress.tag = ClassComponent;
14826
14827 // Throw out any hooks that were used.
14828 resetHooks();
14829
14830 // Push context providers early to prevent context stack mismatches.
14831 // During mounting we don't know the child context yet as the instance doesn't exist.
14832 // We will invalidate the child context in finishClassComponent() right after rendering.
14833 var hasContext = false;
14834 if (isContextProvider(Component)) {
14835 hasContext = true;
14836 pushContextProvider(workInProgress);
14837 } else {
14838 hasContext = false;
14839 }
14840
14841 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
14842
14843 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
14844 if (typeof getDerivedStateFromProps === 'function') {
14845 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
14846 }
14847
14848 adoptClassInstance(workInProgress, value);
14849 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
14850 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
14851 } else {
14852 // Proceed under the assumption that this is a function component
14853 workInProgress.tag = FunctionComponent;
14854 {
14855 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14856 // Only double-render components with Hooks
14857 if (workInProgress.memoizedState !== null) {
14858 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
14859 }
14860 }
14861 }
14862 reconcileChildren(null, workInProgress, value, renderExpirationTime);
14863 {
14864 validateFunctionComponentInDev(workInProgress, Component);
14865 }
14866 return workInProgress.child;
14867 }
14868}
14869
14870function validateFunctionComponentInDev(workInProgress, Component) {
14871 if (Component) {
14872 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
14873 }
14874 if (workInProgress.ref !== null) {
14875 var info = '';
14876 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
14877 if (ownerName) {
14878 info += '\n\nCheck the render method of `' + ownerName + '`.';
14879 }
14880
14881 var warningKey = ownerName || workInProgress._debugID || '';
14882 var debugSource = workInProgress._debugSource;
14883 if (debugSource) {
14884 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
14885 }
14886 if (!didWarnAboutFunctionRefs[warningKey]) {
14887 didWarnAboutFunctionRefs[warningKey] = true;
14888 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);
14889 }
14890 }
14891
14892 if (typeof Component.getDerivedStateFromProps === 'function') {
14893 var componentName = getComponentName(Component) || 'Unknown';
14894
14895 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
14896 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
14897 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
14898 }
14899 }
14900
14901 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
14902 var _componentName = getComponentName(Component) || 'Unknown';
14903
14904 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
14905 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
14906 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
14907 }
14908 }
14909}
14910
14911function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
14912 var mode = workInProgress.mode;
14913 var nextProps = workInProgress.pendingProps;
14914
14915 // We should attempt to render the primary children unless this boundary
14916 // already suspended during this render (`alreadyCaptured` is true).
14917 var nextState = workInProgress.memoizedState;
14918
14919 var nextDidTimeout = void 0;
14920 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
14921 // This is the first attempt.
14922 nextState = null;
14923 nextDidTimeout = false;
14924 } else {
14925 // Something in this boundary's subtree already suspended. Switch to
14926 // rendering the fallback children.
14927 nextState = {
14928 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
14929 };
14930 nextDidTimeout = true;
14931 workInProgress.effectTag &= ~DidCapture;
14932 }
14933
14934 // This next part is a bit confusing. If the children timeout, we switch to
14935 // showing the fallback children in place of the "primary" children.
14936 // However, we don't want to delete the primary children because then their
14937 // state will be lost (both the React state and the host state, e.g.
14938 // uncontrolled form inputs). Instead we keep them mounted and hide them.
14939 // Both the fallback children AND the primary children are rendered at the
14940 // same time. Once the primary children are un-suspended, we can delete
14941 // the fallback children — don't need to preserve their state.
14942 //
14943 // The two sets of children are siblings in the host environment, but
14944 // semantically, for purposes of reconciliation, they are two separate sets.
14945 // So we store them using two fragment fibers.
14946 //
14947 // However, we want to avoid allocating extra fibers for every placeholder.
14948 // They're only necessary when the children time out, because that's the
14949 // only time when both sets are mounted.
14950 //
14951 // So, the extra fragment fibers are only used if the children time out.
14952 // Otherwise, we render the primary children directly. This requires some
14953 // custom reconciliation logic to preserve the state of the primary
14954 // children. It's essentially a very basic form of re-parenting.
14955
14956 // `child` points to the child fiber. In the normal case, this is the first
14957 // fiber of the primary children set. In the timed-out case, it's a
14958 // a fragment fiber containing the primary children.
14959 var child = void 0;
14960 // `next` points to the next fiber React should render. In the normal case,
14961 // it's the same as `child`: the first fiber of the primary children set.
14962 // In the timed-out case, it's a fragment fiber containing the *fallback*
14963 // children -- we skip over the primary children entirely.
14964 var next = void 0;
14965 if (current$$1 === null) {
14966 if (enableSuspenseServerRenderer) {
14967 // If we're currently hydrating, try to hydrate this boundary.
14968 // But only if this has a fallback.
14969 if (nextProps.fallback !== undefined) {
14970 tryToClaimNextHydratableInstance(workInProgress);
14971 // This could've changed the tag if this was a dehydrated suspense component.
14972 if (workInProgress.tag === DehydratedSuspenseComponent) {
14973 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
14974 }
14975 }
14976 }
14977
14978 // This is the initial mount. This branch is pretty simple because there's
14979 // no previous state that needs to be preserved.
14980 if (nextDidTimeout) {
14981 // Mount separate fragments for primary and fallback children.
14982 var nextFallbackChildren = nextProps.fallback;
14983 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
14984
14985 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
14986 // Outside of concurrent mode, we commit the effects from the
14987 var progressedState = workInProgress.memoizedState;
14988 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
14989 primaryChildFragment.child = progressedPrimaryChild;
14990 }
14991
14992 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
14993 primaryChildFragment.sibling = fallbackChildFragment;
14994 child = primaryChildFragment;
14995 // Skip the primary children, and continue working on the
14996 // fallback children.
14997 next = fallbackChildFragment;
14998 child.return = next.return = workInProgress;
14999 } else {
15000 // Mount the primary children without an intermediate fragment fiber.
15001 var nextPrimaryChildren = nextProps.children;
15002 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
15003 }
15004 } else {
15005 // This is an update. This branch is more complicated because we need to
15006 // ensure the state of the primary children is preserved.
15007 var prevState = current$$1.memoizedState;
15008 var prevDidTimeout = prevState !== null;
15009 if (prevDidTimeout) {
15010 // The current tree already timed out. That means each child set is
15011 var currentPrimaryChildFragment = current$$1.child;
15012 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
15013 if (nextDidTimeout) {
15014 // Still timed out. Reuse the current primary children by cloning
15015 // its fragment. We're going to skip over these entirely.
15016 var _nextFallbackChildren = nextProps.fallback;
15017 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
15018
15019 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15020 // Outside of concurrent mode, we commit the effects from the
15021 var _progressedState = workInProgress.memoizedState;
15022 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
15023 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
15024 _primaryChildFragment.child = _progressedPrimaryChild;
15025 }
15026 }
15027
15028 // Because primaryChildFragment is a new fiber that we're inserting as the
15029 // parent of a new tree, we need to set its treeBaseDuration.
15030 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15031 // treeBaseDuration is the sum of all the child tree base durations.
15032 var treeBaseDuration = 0;
15033 var hiddenChild = _primaryChildFragment.child;
15034 while (hiddenChild !== null) {
15035 treeBaseDuration += hiddenChild.treeBaseDuration;
15036 hiddenChild = hiddenChild.sibling;
15037 }
15038 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
15039 }
15040
15041 // Clone the fallback child fragment, too. These we'll continue
15042 // working on.
15043 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
15044 child = _primaryChildFragment;
15045 _primaryChildFragment.childExpirationTime = NoWork;
15046 // Skip the primary children, and continue working on the
15047 // fallback children.
15048 next = _fallbackChildFragment;
15049 child.return = next.return = workInProgress;
15050 } else {
15051 // No longer suspended. Switch back to showing the primary children,
15052 // and remove the intermediate fragment fiber.
15053 var _nextPrimaryChildren = nextProps.children;
15054 var currentPrimaryChild = currentPrimaryChildFragment.child;
15055 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
15056
15057 // If this render doesn't suspend, we need to delete the fallback
15058 // children. Wait until the complete phase, after we've confirmed the
15059 // fallback is no longer needed.
15060 // TODO: Would it be better to store the fallback fragment on
15061 // the stateNode?
15062
15063 // Continue rendering the children, like we normally do.
15064 child = next = primaryChild;
15065 }
15066 } else {
15067 // The current tree has not already timed out. That means the primary
15068 // children are not wrapped in a fragment fiber.
15069 var _currentPrimaryChild = current$$1.child;
15070 if (nextDidTimeout) {
15071 // Timed out. Wrap the children in a fragment fiber to keep them
15072 // separate from the fallback children.
15073 var _nextFallbackChildren2 = nextProps.fallback;
15074 var _primaryChildFragment2 = createFiberFromFragment(
15075 // It shouldn't matter what the pending props are because we aren't
15076 // going to render this fragment.
15077 null, mode, NoWork, null);
15078 _primaryChildFragment2.child = _currentPrimaryChild;
15079
15080 // Even though we're creating a new fiber, there are no new children,
15081 // because we're reusing an already mounted tree. So we don't need to
15082 // schedule a placement.
15083 // primaryChildFragment.effectTag |= Placement;
15084
15085 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
15086 // Outside of concurrent mode, we commit the effects from the
15087 var _progressedState2 = workInProgress.memoizedState;
15088 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
15089 _primaryChildFragment2.child = _progressedPrimaryChild2;
15090 }
15091
15092 // Because primaryChildFragment is a new fiber that we're inserting as the
15093 // parent of a new tree, we need to set its treeBaseDuration.
15094 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15095 // treeBaseDuration is the sum of all the child tree base durations.
15096 var _treeBaseDuration = 0;
15097 var _hiddenChild = _primaryChildFragment2.child;
15098 while (_hiddenChild !== null) {
15099 _treeBaseDuration += _hiddenChild.treeBaseDuration;
15100 _hiddenChild = _hiddenChild.sibling;
15101 }
15102 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
15103 }
15104
15105 // Create a fragment from the fallback children, too.
15106 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
15107 _fallbackChildFragment2.effectTag |= Placement;
15108 child = _primaryChildFragment2;
15109 _primaryChildFragment2.childExpirationTime = NoWork;
15110 // Skip the primary children, and continue working on the
15111 // fallback children.
15112 next = _fallbackChildFragment2;
15113 child.return = next.return = workInProgress;
15114 } else {
15115 // Still haven't timed out. Continue rendering the children, like we
15116 // normally do.
15117 var _nextPrimaryChildren2 = nextProps.children;
15118 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
15119 }
15120 }
15121 workInProgress.stateNode = current$$1.stateNode;
15122 }
15123
15124 workInProgress.memoizedState = nextState;
15125 workInProgress.child = child;
15126 return next;
15127}
15128
15129function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15130 if (current$$1 === null) {
15131 // During the first pass, we'll bail out and not drill into the children.
15132 // Instead, we'll leave the content in place and try to hydrate it later.
15133 workInProgress.expirationTime = Never;
15134 return null;
15135 }
15136 // We use childExpirationTime to indicate that a child might depend on context, so if
15137 // any context has changed, we need to treat is as if the input might have changed.
15138 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
15139 if (didReceiveUpdate || hasContextChanged$$1) {
15140 // This boundary has changed since the first render. This means that we are now unable to
15141 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
15142 // during this render we can't. Instead, we're going to delete the whole subtree and
15143 // instead inject a new real Suspense boundary to take its place, which may render content
15144 // or fallback. The real Suspense boundary will suspend for a while so we have some time
15145 // to ensure it can produce real content, but all state and pending events will be lost.
15146
15147 // Detach from the current dehydrated boundary.
15148 current$$1.alternate = null;
15149 workInProgress.alternate = null;
15150
15151 // Insert a deletion in the effect list.
15152 var returnFiber = workInProgress.return;
15153 !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
15154 var last = returnFiber.lastEffect;
15155 if (last !== null) {
15156 last.nextEffect = current$$1;
15157 returnFiber.lastEffect = current$$1;
15158 } else {
15159 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
15160 }
15161 current$$1.nextEffect = null;
15162 current$$1.effectTag = Deletion;
15163
15164 // Upgrade this work in progress to a real Suspense component.
15165 workInProgress.tag = SuspenseComponent;
15166 workInProgress.stateNode = null;
15167 workInProgress.memoizedState = null;
15168 // This is now an insertion.
15169 workInProgress.effectTag |= Placement;
15170 // Retry as a real Suspense component.
15171 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
15172 }
15173 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15174 // This is the first attempt.
15175 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
15176 var nextProps = workInProgress.pendingProps;
15177 var nextChildren = nextProps.children;
15178 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15179 return workInProgress.child;
15180 } else {
15181 // Something suspended. Leave the existing children in place.
15182 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
15183 workInProgress.child = null;
15184 return null;
15185 }
15186}
15187
15188function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15189 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15190 var nextChildren = workInProgress.pendingProps;
15191 if (current$$1 === null) {
15192 // Portals are special because we don't append the children during mount
15193 // but at commit. Therefore we need to track insertions which the normal
15194 // flow doesn't do during mount. This doesn't happen at the root because
15195 // the root always starts with a "current" with a null child.
15196 // TODO: Consider unifying this with how the root works.
15197 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15198 } else {
15199 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
15200 }
15201 return workInProgress.child;
15202}
15203
15204function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
15205 var providerType = workInProgress.type;
15206 var context = providerType._context;
15207
15208 var newProps = workInProgress.pendingProps;
15209 var oldProps = workInProgress.memoizedProps;
15210
15211 var newValue = newProps.value;
15212
15213 {
15214 var providerPropTypes = workInProgress.type.propTypes;
15215
15216 if (providerPropTypes) {
15217 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
15218 }
15219 }
15220
15221 pushProvider(workInProgress, newValue);
15222
15223 if (oldProps !== null) {
15224 var oldValue = oldProps.value;
15225 var changedBits = calculateChangedBits(context, newValue, oldValue);
15226 if (changedBits === 0) {
15227 // No change. Bailout early if children are the same.
15228 if (oldProps.children === newProps.children && !hasContextChanged()) {
15229 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15230 }
15231 } else {
15232 // The context value changed. Search for matching consumers and schedule
15233 // them to update.
15234 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
15235 }
15236 }
15237
15238 var newChildren = newProps.children;
15239 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15240 return workInProgress.child;
15241}
15242
15243var hasWarnedAboutUsingContextAsConsumer = false;
15244
15245function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
15246 var context = workInProgress.type;
15247 // The logic below for Context differs depending on PROD or DEV mode. In
15248 // DEV mode, we create a separate object for Context.Consumer that acts
15249 // like a proxy to Context. This proxy object adds unnecessary code in PROD
15250 // so we use the old behaviour (Context.Consumer references Context) to
15251 // reduce size and overhead. The separate object references context via
15252 // a property called "_context", which also gives us the ability to check
15253 // in DEV mode if this property exists or not and warn if it does not.
15254 {
15255 if (context._context === undefined) {
15256 // This may be because it's a Context (rather than a Consumer).
15257 // Or it may be because it's older React where they're the same thing.
15258 // We only want to warn if we're sure it's a new React.
15259 if (context !== context.Consumer) {
15260 if (!hasWarnedAboutUsingContextAsConsumer) {
15261 hasWarnedAboutUsingContextAsConsumer = true;
15262 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?');
15263 }
15264 }
15265 } else {
15266 context = context._context;
15267 }
15268 }
15269 var newProps = workInProgress.pendingProps;
15270 var render = newProps.children;
15271
15272 {
15273 !(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;
15274 }
15275
15276 prepareToReadContext(workInProgress, renderExpirationTime);
15277 var newValue = readContext(context, newProps.unstable_observedBits);
15278 var newChildren = void 0;
15279 {
15280 ReactCurrentOwner$3.current = workInProgress;
15281 setCurrentPhase('render');
15282 newChildren = render(newValue);
15283 setCurrentPhase(null);
15284 }
15285
15286 // React DevTools reads this flag.
15287 workInProgress.effectTag |= PerformedWork;
15288 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
15289 return workInProgress.child;
15290}
15291
15292function markWorkInProgressReceivedUpdate() {
15293 didReceiveUpdate = true;
15294}
15295
15296function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
15297 cancelWorkTimer(workInProgress);
15298
15299 if (current$$1 !== null) {
15300 // Reuse previous context list
15301 workInProgress.contextDependencies = current$$1.contextDependencies;
15302 }
15303
15304 if (enableProfilerTimer) {
15305 // Don't update "base" render times for bailouts.
15306 stopProfilerTimerIfRunning(workInProgress);
15307 }
15308
15309 // Check if the children have any pending work.
15310 var childExpirationTime = workInProgress.childExpirationTime;
15311 if (childExpirationTime < renderExpirationTime) {
15312 // The children don't have any work either. We can skip them.
15313 // TODO: Once we add back resuming, we should check if the children are
15314 // a work-in-progress set. If so, we need to transfer their effects.
15315 return null;
15316 } else {
15317 // This fiber doesn't have work, but its subtree does. Clone the child
15318 // fibers and continue.
15319 cloneChildFibers(current$$1, workInProgress);
15320 return workInProgress.child;
15321 }
15322}
15323
15324function beginWork(current$$1, workInProgress, renderExpirationTime) {
15325 var updateExpirationTime = workInProgress.expirationTime;
15326
15327 if (current$$1 !== null) {
15328 var oldProps = current$$1.memoizedProps;
15329 var newProps = workInProgress.pendingProps;
15330
15331 if (oldProps !== newProps || hasContextChanged()) {
15332 // If props or context changed, mark the fiber as having performed work.
15333 // This may be unset if the props are determined to be equal later (memo).
15334 didReceiveUpdate = true;
15335 } else if (updateExpirationTime < renderExpirationTime) {
15336 didReceiveUpdate = false;
15337 // This fiber does not have any pending work. Bailout without entering
15338 // the begin phase. There's still some bookkeeping we that needs to be done
15339 // in this optimized path, mostly pushing stuff onto the stack.
15340 switch (workInProgress.tag) {
15341 case HostRoot:
15342 pushHostRootContext(workInProgress);
15343 resetHydrationState();
15344 break;
15345 case HostComponent:
15346 pushHostContext(workInProgress);
15347 break;
15348 case ClassComponent:
15349 {
15350 var Component = workInProgress.type;
15351 if (isContextProvider(Component)) {
15352 pushContextProvider(workInProgress);
15353 }
15354 break;
15355 }
15356 case HostPortal:
15357 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15358 break;
15359 case ContextProvider:
15360 {
15361 var newValue = workInProgress.memoizedProps.value;
15362 pushProvider(workInProgress, newValue);
15363 break;
15364 }
15365 case Profiler:
15366 if (enableProfilerTimer) {
15367 workInProgress.effectTag |= Update;
15368 }
15369 break;
15370 case SuspenseComponent:
15371 {
15372 var state = workInProgress.memoizedState;
15373 var didTimeout = state !== null;
15374 if (didTimeout) {
15375 // If this boundary is currently timed out, we need to decide
15376 // whether to retry the primary children, or to skip over it and
15377 // go straight to the fallback. Check the priority of the primary
15378 var primaryChildFragment = workInProgress.child;
15379 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
15380 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
15381 // The primary children have pending work. Use the normal path
15382 // to attempt to render the primary children again.
15383 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15384 } else {
15385 // The primary children do not have pending work with sufficient
15386 // priority. Bailout.
15387 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15388 if (child !== null) {
15389 // The fallback children have pending work. Skip over the
15390 // primary children and work on the fallback.
15391 return child.sibling;
15392 } else {
15393 return null;
15394 }
15395 }
15396 }
15397 break;
15398 }
15399 case DehydratedSuspenseComponent:
15400 {
15401 if (enableSuspenseServerRenderer) {
15402 // We know that this component will suspend again because if it has
15403 // been unsuspended it has committed as a regular Suspense component.
15404 // If it needs to be retried, it should have work scheduled on it.
15405 workInProgress.effectTag |= DidCapture;
15406 break;
15407 }
15408 }
15409 }
15410 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15411 }
15412 } else {
15413 didReceiveUpdate = false;
15414 }
15415
15416 // Before entering the begin phase, clear the expiration time.
15417 workInProgress.expirationTime = NoWork;
15418
15419 switch (workInProgress.tag) {
15420 case IndeterminateComponent:
15421 {
15422 var elementType = workInProgress.elementType;
15423 return mountIndeterminateComponent(current$$1, workInProgress, elementType, renderExpirationTime);
15424 }
15425 case LazyComponent:
15426 {
15427 var _elementType = workInProgress.elementType;
15428 return mountLazyComponent(current$$1, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
15429 }
15430 case FunctionComponent:
15431 {
15432 var _Component = workInProgress.type;
15433 var unresolvedProps = workInProgress.pendingProps;
15434 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
15435 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
15436 }
15437 case ClassComponent:
15438 {
15439 var _Component2 = workInProgress.type;
15440 var _unresolvedProps = workInProgress.pendingProps;
15441 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
15442 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
15443 }
15444 case HostRoot:
15445 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
15446 case HostComponent:
15447 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
15448 case HostText:
15449 return updateHostText(current$$1, workInProgress);
15450 case SuspenseComponent:
15451 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15452 case HostPortal:
15453 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
15454 case ForwardRef:
15455 {
15456 var type = workInProgress.type;
15457 var _unresolvedProps2 = workInProgress.pendingProps;
15458 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
15459 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
15460 }
15461 case Fragment:
15462 return updateFragment(current$$1, workInProgress, renderExpirationTime);
15463 case Mode:
15464 return updateMode(current$$1, workInProgress, renderExpirationTime);
15465 case Profiler:
15466 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
15467 case ContextProvider:
15468 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
15469 case ContextConsumer:
15470 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
15471 case MemoComponent:
15472 {
15473 var _type2 = workInProgress.type;
15474 var _unresolvedProps3 = workInProgress.pendingProps;
15475 // Resolve outer props first, then resolve inner props.
15476 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
15477 {
15478 if (workInProgress.type !== workInProgress.elementType) {
15479 var outerPropTypes = _type2.propTypes;
15480 if (outerPropTypes) {
15481 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
15482 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
15483 }
15484 }
15485 }
15486 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
15487 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
15488 }
15489 case SimpleMemoComponent:
15490 {
15491 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
15492 }
15493 case IncompleteClassComponent:
15494 {
15495 var _Component3 = workInProgress.type;
15496 var _unresolvedProps4 = workInProgress.pendingProps;
15497 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15498 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15499 }
15500 case DehydratedSuspenseComponent:
15501 {
15502 if (enableSuspenseServerRenderer) {
15503 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15504 }
15505 break;
15506 }
15507 }
15508 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15509}
15510
15511var valueCursor = createCursor(null);
15512
15513var rendererSigil = void 0;
15514{
15515 // Use this to detect multiple renderers using the same context
15516 rendererSigil = {};
15517}
15518
15519var currentlyRenderingFiber = null;
15520var lastContextDependency = null;
15521var lastContextWithAllBitsObserved = null;
15522
15523var isDisallowedContextReadInDEV = false;
15524
15525function resetContextDependences() {
15526 // This is called right before React yields execution, to ensure `readContext`
15527 // cannot be called outside the render phase.
15528 currentlyRenderingFiber = null;
15529 lastContextDependency = null;
15530 lastContextWithAllBitsObserved = null;
15531 {
15532 isDisallowedContextReadInDEV = false;
15533 }
15534}
15535
15536function enterDisallowedContextReadInDEV() {
15537 {
15538 isDisallowedContextReadInDEV = true;
15539 }
15540}
15541
15542function exitDisallowedContextReadInDEV() {
15543 {
15544 isDisallowedContextReadInDEV = false;
15545 }
15546}
15547
15548function pushProvider(providerFiber, nextValue) {
15549 var context = providerFiber.type._context;
15550
15551 if (isPrimaryRenderer) {
15552 push(valueCursor, context._currentValue, providerFiber);
15553
15554 context._currentValue = nextValue;
15555 {
15556 !(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;
15557 context._currentRenderer = rendererSigil;
15558 }
15559 } else {
15560 push(valueCursor, context._currentValue2, providerFiber);
15561
15562 context._currentValue2 = nextValue;
15563 {
15564 !(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;
15565 context._currentRenderer2 = rendererSigil;
15566 }
15567 }
15568}
15569
15570function popProvider(providerFiber) {
15571 var currentValue = valueCursor.current;
15572
15573 pop(valueCursor, providerFiber);
15574
15575 var context = providerFiber.type._context;
15576 if (isPrimaryRenderer) {
15577 context._currentValue = currentValue;
15578 } else {
15579 context._currentValue2 = currentValue;
15580 }
15581}
15582
15583function calculateChangedBits(context, newValue, oldValue) {
15584 if (is(oldValue, newValue)) {
15585 // No change
15586 return 0;
15587 } else {
15588 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
15589
15590 {
15591 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
15592 }
15593 return changedBits | 0;
15594 }
15595}
15596
15597function scheduleWorkOnParentPath(parent, renderExpirationTime) {
15598 // Update the child expiration time of all the ancestors, including
15599 // the alternates.
15600 var node = parent;
15601 while (node !== null) {
15602 var alternate = node.alternate;
15603 if (node.childExpirationTime < renderExpirationTime) {
15604 node.childExpirationTime = renderExpirationTime;
15605 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15606 alternate.childExpirationTime = renderExpirationTime;
15607 }
15608 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15609 alternate.childExpirationTime = renderExpirationTime;
15610 } else {
15611 // Neither alternate was updated, which means the rest of the
15612 // ancestor path already has sufficient priority.
15613 break;
15614 }
15615 node = node.return;
15616 }
15617}
15618
15619function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
15620 var fiber = workInProgress.child;
15621 if (fiber !== null) {
15622 // Set the return pointer of the child to the work-in-progress fiber.
15623 fiber.return = workInProgress;
15624 }
15625 while (fiber !== null) {
15626 var nextFiber = void 0;
15627
15628 // Visit this fiber.
15629 var list = fiber.contextDependencies;
15630 if (list !== null) {
15631 nextFiber = fiber.child;
15632
15633 var dependency = list.first;
15634 while (dependency !== null) {
15635 // Check if the context matches.
15636 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
15637 // Match! Schedule an update on this fiber.
15638
15639 if (fiber.tag === ClassComponent) {
15640 // Schedule a force update on the work-in-progress.
15641 var update = createUpdate(renderExpirationTime);
15642 update.tag = ForceUpdate;
15643 // TODO: Because we don't have a work-in-progress, this will add the
15644 // update to the current fiber, too, which means it will persist even if
15645 // this render is thrown away. Since it's a race condition, not sure it's
15646 // worth fixing.
15647 enqueueUpdate(fiber, update);
15648 }
15649
15650 if (fiber.expirationTime < renderExpirationTime) {
15651 fiber.expirationTime = renderExpirationTime;
15652 }
15653 var alternate = fiber.alternate;
15654 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
15655 alternate.expirationTime = renderExpirationTime;
15656 }
15657
15658 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
15659
15660 // Mark the expiration time on the list, too.
15661 if (list.expirationTime < renderExpirationTime) {
15662 list.expirationTime = renderExpirationTime;
15663 }
15664
15665 // Since we already found a match, we can stop traversing the
15666 // dependency list.
15667 break;
15668 }
15669 dependency = dependency.next;
15670 }
15671 } else if (fiber.tag === ContextProvider) {
15672 // Don't scan deeper if this is a matching provider
15673 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
15674 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
15675 // If a dehydrated suspense component is in this subtree, we don't know
15676 // if it will have any context consumers in it. The best we can do is
15677 // mark it as having updates on its children.
15678 if (fiber.expirationTime < renderExpirationTime) {
15679 fiber.expirationTime = renderExpirationTime;
15680 }
15681 var _alternate = fiber.alternate;
15682 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
15683 _alternate.expirationTime = renderExpirationTime;
15684 }
15685 // This is intentionally passing this fiber as the parent
15686 // because we want to schedule this fiber as having work
15687 // on its children. We'll use the childExpirationTime on
15688 // this fiber to indicate that a context has changed.
15689 scheduleWorkOnParentPath(fiber, renderExpirationTime);
15690 nextFiber = fiber.sibling;
15691 } else {
15692 // Traverse down.
15693 nextFiber = fiber.child;
15694 }
15695
15696 if (nextFiber !== null) {
15697 // Set the return pointer of the child to the work-in-progress fiber.
15698 nextFiber.return = fiber;
15699 } else {
15700 // No child. Traverse to next sibling.
15701 nextFiber = fiber;
15702 while (nextFiber !== null) {
15703 if (nextFiber === workInProgress) {
15704 // We're back to the root of this subtree. Exit.
15705 nextFiber = null;
15706 break;
15707 }
15708 var sibling = nextFiber.sibling;
15709 if (sibling !== null) {
15710 // Set the return pointer of the sibling to the work-in-progress fiber.
15711 sibling.return = nextFiber.return;
15712 nextFiber = sibling;
15713 break;
15714 }
15715 // No more siblings. Traverse up.
15716 nextFiber = nextFiber.return;
15717 }
15718 }
15719 fiber = nextFiber;
15720 }
15721}
15722
15723function prepareToReadContext(workInProgress, renderExpirationTime) {
15724 currentlyRenderingFiber = workInProgress;
15725 lastContextDependency = null;
15726 lastContextWithAllBitsObserved = null;
15727
15728 var currentDependencies = workInProgress.contextDependencies;
15729 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
15730 // Context list has a pending update. Mark that this fiber performed work.
15731 markWorkInProgressReceivedUpdate();
15732 }
15733
15734 // Reset the work-in-progress list
15735 workInProgress.contextDependencies = null;
15736}
15737
15738function readContext(context, observedBits) {
15739 {
15740 // This warning would fire if you read context inside a Hook like useMemo.
15741 // Unlike the class check below, it's not enforced in production for perf.
15742 !!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;
15743 }
15744
15745 if (lastContextWithAllBitsObserved === context) {
15746 // Nothing to do. We already observe everything in this context.
15747 } else if (observedBits === false || observedBits === 0) {
15748 // Do not observe any updates.
15749 } else {
15750 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
15751 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
15752 // Observe all updates.
15753 lastContextWithAllBitsObserved = context;
15754 resolvedObservedBits = maxSigned31BitInt;
15755 } else {
15756 resolvedObservedBits = observedBits;
15757 }
15758
15759 var contextItem = {
15760 context: context,
15761 observedBits: resolvedObservedBits,
15762 next: null
15763 };
15764
15765 if (lastContextDependency === null) {
15766 !(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;
15767
15768 // This is the first dependency for this component. Create a new list.
15769 lastContextDependency = contextItem;
15770 currentlyRenderingFiber.contextDependencies = {
15771 first: contextItem,
15772 expirationTime: NoWork
15773 };
15774 } else {
15775 // Append a new context item.
15776 lastContextDependency = lastContextDependency.next = contextItem;
15777 }
15778 }
15779 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
15780}
15781
15782// UpdateQueue is a linked list of prioritized updates.
15783//
15784// Like fibers, update queues come in pairs: a current queue, which represents
15785// the visible state of the screen, and a work-in-progress queue, which can be
15786// mutated and processed asynchronously before it is committed — a form of
15787// double buffering. If a work-in-progress render is discarded before finishing,
15788// we create a new work-in-progress by cloning the current queue.
15789//
15790// Both queues share a persistent, singly-linked list structure. To schedule an
15791// update, we append it to the end of both queues. Each queue maintains a
15792// pointer to first update in the persistent list that hasn't been processed.
15793// The work-in-progress pointer always has a position equal to or greater than
15794// the current queue, since we always work on that one. The current queue's
15795// pointer is only updated during the commit phase, when we swap in the
15796// work-in-progress.
15797//
15798// For example:
15799//
15800// Current pointer: A - B - C - D - E - F
15801// Work-in-progress pointer: D - E - F
15802// ^
15803// The work-in-progress queue has
15804// processed more updates than current.
15805//
15806// The reason we append to both queues is because otherwise we might drop
15807// updates without ever processing them. For example, if we only add updates to
15808// the work-in-progress queue, some updates could be lost whenever a work-in
15809// -progress render restarts by cloning from current. Similarly, if we only add
15810// updates to the current queue, the updates will be lost whenever an already
15811// in-progress queue commits and swaps with the current queue. However, by
15812// adding to both queues, we guarantee that the update will be part of the next
15813// work-in-progress. (And because the work-in-progress queue becomes the
15814// current queue once it commits, there's no danger of applying the same
15815// update twice.)
15816//
15817// Prioritization
15818// --------------
15819//
15820// Updates are not sorted by priority, but by insertion; new updates are always
15821// appended to the end of the list.
15822//
15823// The priority is still important, though. When processing the update queue
15824// during the render phase, only the updates with sufficient priority are
15825// included in the result. If we skip an update because it has insufficient
15826// priority, it remains in the queue to be processed later, during a lower
15827// priority render. Crucially, all updates subsequent to a skipped update also
15828// remain in the queue *regardless of their priority*. That means high priority
15829// updates are sometimes processed twice, at two separate priorities. We also
15830// keep track of a base state, that represents the state before the first
15831// update in the queue is applied.
15832//
15833// For example:
15834//
15835// Given a base state of '', and the following queue of updates
15836//
15837// A1 - B2 - C1 - D2
15838//
15839// where the number indicates the priority, and the update is applied to the
15840// previous state by appending a letter, React will process these updates as
15841// two separate renders, one per distinct priority level:
15842//
15843// First render, at priority 1:
15844// Base state: ''
15845// Updates: [A1, C1]
15846// Result state: 'AC'
15847//
15848// Second render, at priority 2:
15849// Base state: 'A' <- The base state does not include C1,
15850// because B2 was skipped.
15851// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
15852// Result state: 'ABCD'
15853//
15854// Because we process updates in insertion order, and rebase high priority
15855// updates when preceding updates are skipped, the final result is deterministic
15856// regardless of priority. Intermediate state may vary according to system
15857// resources, but the final state is always the same.
15858
15859var UpdateState = 0;
15860var ReplaceState = 1;
15861var ForceUpdate = 2;
15862var CaptureUpdate = 3;
15863
15864// Global state that is reset at the beginning of calling `processUpdateQueue`.
15865// It should only be read right after calling `processUpdateQueue`, via
15866// `checkHasForceUpdateAfterProcessing`.
15867var hasForceUpdate = false;
15868
15869var didWarnUpdateInsideUpdate = void 0;
15870var currentlyProcessingQueue = void 0;
15871var resetCurrentlyProcessingQueue = void 0;
15872{
15873 didWarnUpdateInsideUpdate = false;
15874 currentlyProcessingQueue = null;
15875 resetCurrentlyProcessingQueue = function () {
15876 currentlyProcessingQueue = null;
15877 };
15878}
15879
15880function createUpdateQueue(baseState) {
15881 var queue = {
15882 baseState: baseState,
15883 firstUpdate: null,
15884 lastUpdate: null,
15885 firstCapturedUpdate: null,
15886 lastCapturedUpdate: null,
15887 firstEffect: null,
15888 lastEffect: null,
15889 firstCapturedEffect: null,
15890 lastCapturedEffect: null
15891 };
15892 return queue;
15893}
15894
15895function cloneUpdateQueue(currentQueue) {
15896 var queue = {
15897 baseState: currentQueue.baseState,
15898 firstUpdate: currentQueue.firstUpdate,
15899 lastUpdate: currentQueue.lastUpdate,
15900
15901 // TODO: With resuming, if we bail out and resuse the child tree, we should
15902 // keep these effects.
15903 firstCapturedUpdate: null,
15904 lastCapturedUpdate: null,
15905
15906 firstEffect: null,
15907 lastEffect: null,
15908
15909 firstCapturedEffect: null,
15910 lastCapturedEffect: null
15911 };
15912 return queue;
15913}
15914
15915function createUpdate(expirationTime) {
15916 return {
15917 expirationTime: expirationTime,
15918
15919 tag: UpdateState,
15920 payload: null,
15921 callback: null,
15922
15923 next: null,
15924 nextEffect: null
15925 };
15926}
15927
15928function appendUpdateToQueue(queue, update) {
15929 // Append the update to the end of the list.
15930 if (queue.lastUpdate === null) {
15931 // Queue is empty
15932 queue.firstUpdate = queue.lastUpdate = update;
15933 } else {
15934 queue.lastUpdate.next = update;
15935 queue.lastUpdate = update;
15936 }
15937}
15938
15939function enqueueUpdate(fiber, update) {
15940 // Update queues are created lazily.
15941 var alternate = fiber.alternate;
15942 var queue1 = void 0;
15943 var queue2 = void 0;
15944 if (alternate === null) {
15945 // There's only one fiber.
15946 queue1 = fiber.updateQueue;
15947 queue2 = null;
15948 if (queue1 === null) {
15949 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
15950 }
15951 } else {
15952 // There are two owners.
15953 queue1 = fiber.updateQueue;
15954 queue2 = alternate.updateQueue;
15955 if (queue1 === null) {
15956 if (queue2 === null) {
15957 // Neither fiber has an update queue. Create new ones.
15958 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
15959 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
15960 } else {
15961 // Only one fiber has an update queue. Clone to create a new one.
15962 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
15963 }
15964 } else {
15965 if (queue2 === null) {
15966 // Only one fiber has an update queue. Clone to create a new one.
15967 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
15968 } else {
15969 // Both owners have an update queue.
15970 }
15971 }
15972 }
15973 if (queue2 === null || queue1 === queue2) {
15974 // There's only a single queue.
15975 appendUpdateToQueue(queue1, update);
15976 } else {
15977 // There are two queues. We need to append the update to both queues,
15978 // while accounting for the persistent structure of the list — we don't
15979 // want the same update to be added multiple times.
15980 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
15981 // One of the queues is not empty. We must add the update to both queues.
15982 appendUpdateToQueue(queue1, update);
15983 appendUpdateToQueue(queue2, update);
15984 } else {
15985 // Both queues are non-empty. The last update is the same in both lists,
15986 // because of structural sharing. So, only append to one of the lists.
15987 appendUpdateToQueue(queue1, update);
15988 // But we still need to update the `lastUpdate` pointer of queue2.
15989 queue2.lastUpdate = update;
15990 }
15991 }
15992
15993 {
15994 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
15995 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.');
15996 didWarnUpdateInsideUpdate = true;
15997 }
15998 }
15999}
16000
16001function enqueueCapturedUpdate(workInProgress, update) {
16002 // Captured updates go into a separate list, and only on the work-in-
16003 // progress queue.
16004 var workInProgressQueue = workInProgress.updateQueue;
16005 if (workInProgressQueue === null) {
16006 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
16007 } else {
16008 // TODO: I put this here rather than createWorkInProgress so that we don't
16009 // clone the queue unnecessarily. There's probably a better way to
16010 // structure this.
16011 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
16012 }
16013
16014 // Append the update to the end of the list.
16015 if (workInProgressQueue.lastCapturedUpdate === null) {
16016 // This is the first render phase update
16017 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
16018 } else {
16019 workInProgressQueue.lastCapturedUpdate.next = update;
16020 workInProgressQueue.lastCapturedUpdate = update;
16021 }
16022}
16023
16024function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
16025 var current = workInProgress.alternate;
16026 if (current !== null) {
16027 // If the work-in-progress queue is equal to the current queue,
16028 // we need to clone it first.
16029 if (queue === current.updateQueue) {
16030 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
16031 }
16032 }
16033 return queue;
16034}
16035
16036function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
16037 switch (update.tag) {
16038 case ReplaceState:
16039 {
16040 var _payload = update.payload;
16041 if (typeof _payload === 'function') {
16042 // Updater function
16043 {
16044 enterDisallowedContextReadInDEV();
16045 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16046 _payload.call(instance, prevState, nextProps);
16047 }
16048 }
16049 var nextState = _payload.call(instance, prevState, nextProps);
16050 {
16051 exitDisallowedContextReadInDEV();
16052 }
16053 return nextState;
16054 }
16055 // State object
16056 return _payload;
16057 }
16058 case CaptureUpdate:
16059 {
16060 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
16061 }
16062 // Intentional fallthrough
16063 case UpdateState:
16064 {
16065 var _payload2 = update.payload;
16066 var partialState = void 0;
16067 if (typeof _payload2 === 'function') {
16068 // Updater function
16069 {
16070 enterDisallowedContextReadInDEV();
16071 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
16072 _payload2.call(instance, prevState, nextProps);
16073 }
16074 }
16075 partialState = _payload2.call(instance, prevState, nextProps);
16076 {
16077 exitDisallowedContextReadInDEV();
16078 }
16079 } else {
16080 // Partial state object
16081 partialState = _payload2;
16082 }
16083 if (partialState === null || partialState === undefined) {
16084 // Null and undefined are treated as no-ops.
16085 return prevState;
16086 }
16087 // Merge the partial state and the previous state.
16088 return _assign({}, prevState, partialState);
16089 }
16090 case ForceUpdate:
16091 {
16092 hasForceUpdate = true;
16093 return prevState;
16094 }
16095 }
16096 return prevState;
16097}
16098
16099function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
16100 hasForceUpdate = false;
16101
16102 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
16103
16104 {
16105 currentlyProcessingQueue = queue;
16106 }
16107
16108 // These values may change as we process the queue.
16109 var newBaseState = queue.baseState;
16110 var newFirstUpdate = null;
16111 var newExpirationTime = NoWork;
16112
16113 // Iterate through the list of updates to compute the result.
16114 var update = queue.firstUpdate;
16115 var resultState = newBaseState;
16116 while (update !== null) {
16117 var updateExpirationTime = update.expirationTime;
16118 if (updateExpirationTime < renderExpirationTime) {
16119 // This update does not have sufficient priority. Skip it.
16120 if (newFirstUpdate === null) {
16121 // This is the first skipped update. It will be the first update in
16122 // the new list.
16123 newFirstUpdate = update;
16124 // Since this is the first update that was skipped, the current result
16125 // is the new base state.
16126 newBaseState = resultState;
16127 }
16128 // Since this update will remain in the list, update the remaining
16129 // expiration time.
16130 if (newExpirationTime < updateExpirationTime) {
16131 newExpirationTime = updateExpirationTime;
16132 }
16133 } else {
16134 // This update does have sufficient priority. Process it and compute
16135 // a new result.
16136 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16137 var _callback = update.callback;
16138 if (_callback !== null) {
16139 workInProgress.effectTag |= Callback;
16140 // Set this to null, in case it was mutated during an aborted render.
16141 update.nextEffect = null;
16142 if (queue.lastEffect === null) {
16143 queue.firstEffect = queue.lastEffect = update;
16144 } else {
16145 queue.lastEffect.nextEffect = update;
16146 queue.lastEffect = update;
16147 }
16148 }
16149 }
16150 // Continue to the next update.
16151 update = update.next;
16152 }
16153
16154 // Separately, iterate though the list of captured updates.
16155 var newFirstCapturedUpdate = null;
16156 update = queue.firstCapturedUpdate;
16157 while (update !== null) {
16158 var _updateExpirationTime = update.expirationTime;
16159 if (_updateExpirationTime < renderExpirationTime) {
16160 // This update does not have sufficient priority. Skip it.
16161 if (newFirstCapturedUpdate === null) {
16162 // This is the first skipped captured update. It will be the first
16163 // update in the new list.
16164 newFirstCapturedUpdate = update;
16165 // If this is the first update that was skipped, the current result is
16166 // the new base state.
16167 if (newFirstUpdate === null) {
16168 newBaseState = resultState;
16169 }
16170 }
16171 // Since this update will remain in the list, update the remaining
16172 // expiration time.
16173 if (newExpirationTime < _updateExpirationTime) {
16174 newExpirationTime = _updateExpirationTime;
16175 }
16176 } else {
16177 // This update does have sufficient priority. Process it and compute
16178 // a new result.
16179 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
16180 var _callback2 = update.callback;
16181 if (_callback2 !== null) {
16182 workInProgress.effectTag |= Callback;
16183 // Set this to null, in case it was mutated during an aborted render.
16184 update.nextEffect = null;
16185 if (queue.lastCapturedEffect === null) {
16186 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
16187 } else {
16188 queue.lastCapturedEffect.nextEffect = update;
16189 queue.lastCapturedEffect = update;
16190 }
16191 }
16192 }
16193 update = update.next;
16194 }
16195
16196 if (newFirstUpdate === null) {
16197 queue.lastUpdate = null;
16198 }
16199 if (newFirstCapturedUpdate === null) {
16200 queue.lastCapturedUpdate = null;
16201 } else {
16202 workInProgress.effectTag |= Callback;
16203 }
16204 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
16205 // We processed every update, without skipping. That means the new base
16206 // state is the same as the result state.
16207 newBaseState = resultState;
16208 }
16209
16210 queue.baseState = newBaseState;
16211 queue.firstUpdate = newFirstUpdate;
16212 queue.firstCapturedUpdate = newFirstCapturedUpdate;
16213
16214 // Set the remaining expiration time to be whatever is remaining in the queue.
16215 // This should be fine because the only two other things that contribute to
16216 // expiration time are props and context. We're already in the middle of the
16217 // begin phase by the time we start processing the queue, so we've already
16218 // dealt with the props. Context in components that specify
16219 // shouldComponentUpdate is tricky; but we'll have to account for
16220 // that regardless.
16221 workInProgress.expirationTime = newExpirationTime;
16222 workInProgress.memoizedState = resultState;
16223
16224 {
16225 currentlyProcessingQueue = null;
16226 }
16227}
16228
16229function callCallback(callback, context) {
16230 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
16231 callback.call(context);
16232}
16233
16234function resetHasForceUpdateBeforeProcessing() {
16235 hasForceUpdate = false;
16236}
16237
16238function checkHasForceUpdateAfterProcessing() {
16239 return hasForceUpdate;
16240}
16241
16242function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
16243 // If the finished render included captured updates, and there are still
16244 // lower priority updates left over, we need to keep the captured updates
16245 // in the queue so that they are rebased and not dropped once we process the
16246 // queue again at the lower priority.
16247 if (finishedQueue.firstCapturedUpdate !== null) {
16248 // Join the captured update list to the end of the normal list.
16249 if (finishedQueue.lastUpdate !== null) {
16250 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
16251 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
16252 }
16253 // Clear the list of captured updates.
16254 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
16255 }
16256
16257 // Commit the effects
16258 commitUpdateEffects(finishedQueue.firstEffect, instance);
16259 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
16260
16261 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
16262 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
16263}
16264
16265function commitUpdateEffects(effect, instance) {
16266 while (effect !== null) {
16267 var _callback3 = effect.callback;
16268 if (_callback3 !== null) {
16269 effect.callback = null;
16270 callCallback(_callback3, instance);
16271 }
16272 effect = effect.nextEffect;
16273 }
16274}
16275
16276function createCapturedValue(value, source) {
16277 // If the value is an error, call this function immediately after it is thrown
16278 // so the stack is accurate.
16279 return {
16280 value: value,
16281 source: source,
16282 stack: getStackByFiberInDevAndProd(source)
16283 };
16284}
16285
16286function markUpdate(workInProgress) {
16287 // Tag the fiber with an update effect. This turns a Placement into
16288 // a PlacementAndUpdate.
16289 workInProgress.effectTag |= Update;
16290}
16291
16292function markRef$1(workInProgress) {
16293 workInProgress.effectTag |= Ref;
16294}
16295
16296var appendAllChildren = void 0;
16297var updateHostContainer = void 0;
16298var updateHostComponent$1 = void 0;
16299var updateHostText$1 = void 0;
16300if (supportsMutation) {
16301 // Mutation mode
16302
16303 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16304 // We only have the top Fiber that was created but we need recurse down its
16305 // children to find all the terminal nodes.
16306 var node = workInProgress.child;
16307 while (node !== null) {
16308 if (node.tag === HostComponent || node.tag === HostText) {
16309 appendInitialChild(parent, node.stateNode);
16310 } else if (node.tag === HostPortal) {
16311 // If we have a portal child, then we don't want to traverse
16312 // down its children. Instead, we'll get insertions from each child in
16313 // the portal directly.
16314 } else if (node.child !== null) {
16315 node.child.return = node;
16316 node = node.child;
16317 continue;
16318 }
16319 if (node === workInProgress) {
16320 return;
16321 }
16322 while (node.sibling === null) {
16323 if (node.return === null || node.return === workInProgress) {
16324 return;
16325 }
16326 node = node.return;
16327 }
16328 node.sibling.return = node.return;
16329 node = node.sibling;
16330 }
16331 };
16332
16333 updateHostContainer = function (workInProgress) {
16334 // Noop
16335 };
16336 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16337 // If we have an alternate, that means this is an update and we need to
16338 // schedule a side-effect to do the updates.
16339 var oldProps = current.memoizedProps;
16340 if (oldProps === newProps) {
16341 // In mutation mode, this is sufficient for a bailout because
16342 // we won't touch this node even if children changed.
16343 return;
16344 }
16345
16346 // If we get updated because one of our children updated, we don't
16347 // have newProps so we'll have to reuse them.
16348 // TODO: Split the update API as separate for the props vs. children.
16349 // Even better would be if children weren't special cased at all tho.
16350 var instance = workInProgress.stateNode;
16351 var currentHostContext = getHostContext();
16352 // TODO: Experiencing an error where oldProps is null. Suggests a host
16353 // component is hitting the resume path. Figure out why. Possibly
16354 // related to `hidden`.
16355 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16356 // TODO: Type this specific to this type of component.
16357 workInProgress.updateQueue = updatePayload;
16358 // If the update payload indicates that there is a change or if there
16359 // is a new ref we mark this as an update. All the work is done in commitWork.
16360 if (updatePayload) {
16361 markUpdate(workInProgress);
16362 }
16363 };
16364 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16365 // If the text differs, mark it as an update. All the work in done in commitWork.
16366 if (oldText !== newText) {
16367 markUpdate(workInProgress);
16368 }
16369 };
16370} else if (supportsPersistence) {
16371 // Persistent host tree mode
16372
16373 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
16374 // We only have the top Fiber that was created but we need recurse down its
16375 // children to find all the terminal nodes.
16376 var node = workInProgress.child;
16377 while (node !== null) {
16378 // eslint-disable-next-line no-labels
16379 branches: if (node.tag === HostComponent) {
16380 var instance = node.stateNode;
16381 if (needsVisibilityToggle) {
16382 var props = node.memoizedProps;
16383 var type = node.type;
16384 if (isHidden) {
16385 // This child is inside a timed out tree. Hide it.
16386 instance = cloneHiddenInstance(instance, type, props, node);
16387 } else {
16388 // This child was previously inside a timed out tree. If it was not
16389 // updated during this render, it may need to be unhidden. Clone
16390 // again to be sure.
16391 instance = cloneUnhiddenInstance(instance, type, props, node);
16392 }
16393 node.stateNode = instance;
16394 }
16395 appendInitialChild(parent, instance);
16396 } else if (node.tag === HostText) {
16397 var _instance = node.stateNode;
16398 if (needsVisibilityToggle) {
16399 var text = node.memoizedProps;
16400 var rootContainerInstance = getRootHostContainer();
16401 var currentHostContext = getHostContext();
16402 if (isHidden) {
16403 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16404 } else {
16405 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16406 }
16407 node.stateNode = _instance;
16408 }
16409 appendInitialChild(parent, _instance);
16410 } else if (node.tag === HostPortal) {
16411 // If we have a portal child, then we don't want to traverse
16412 // down its children. Instead, we'll get insertions from each child in
16413 // the portal directly.
16414 } else if (node.tag === SuspenseComponent) {
16415 var current = node.alternate;
16416 if (current !== null) {
16417 var oldState = current.memoizedState;
16418 var newState = node.memoizedState;
16419 var oldIsHidden = oldState !== null;
16420 var newIsHidden = newState !== null;
16421 if (oldIsHidden !== newIsHidden) {
16422 // The placeholder either just timed out or switched back to the normal
16423 // children after having previously timed out. Toggle the visibility of
16424 // the direct host children.
16425 var primaryChildParent = newIsHidden ? node.child : node;
16426 if (primaryChildParent !== null) {
16427 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
16428 }
16429 // eslint-disable-next-line no-labels
16430 break branches;
16431 }
16432 }
16433 if (node.child !== null) {
16434 // Continue traversing like normal
16435 node.child.return = node;
16436 node = node.child;
16437 continue;
16438 }
16439 } else if (node.child !== null) {
16440 node.child.return = node;
16441 node = node.child;
16442 continue;
16443 }
16444 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16445 node = node;
16446 if (node === workInProgress) {
16447 return;
16448 }
16449 while (node.sibling === null) {
16450 if (node.return === null || node.return === workInProgress) {
16451 return;
16452 }
16453 node = node.return;
16454 }
16455 node.sibling.return = node.return;
16456 node = node.sibling;
16457 }
16458 };
16459
16460 // An unfortunate fork of appendAllChildren because we have two different parent types.
16461 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
16462 // We only have the top Fiber that was created but we need recurse down its
16463 // children to find all the terminal nodes.
16464 var node = workInProgress.child;
16465 while (node !== null) {
16466 // eslint-disable-next-line no-labels
16467 branches: if (node.tag === HostComponent) {
16468 var instance = node.stateNode;
16469 if (needsVisibilityToggle) {
16470 var props = node.memoizedProps;
16471 var type = node.type;
16472 if (isHidden) {
16473 // This child is inside a timed out tree. Hide it.
16474 instance = cloneHiddenInstance(instance, type, props, node);
16475 } else {
16476 // This child was previously inside a timed out tree. If it was not
16477 // updated during this render, it may need to be unhidden. Clone
16478 // again to be sure.
16479 instance = cloneUnhiddenInstance(instance, type, props, node);
16480 }
16481 node.stateNode = instance;
16482 }
16483 appendChildToContainerChildSet(containerChildSet, instance);
16484 } else if (node.tag === HostText) {
16485 var _instance2 = node.stateNode;
16486 if (needsVisibilityToggle) {
16487 var text = node.memoizedProps;
16488 var rootContainerInstance = getRootHostContainer();
16489 var currentHostContext = getHostContext();
16490 if (isHidden) {
16491 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16492 } else {
16493 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
16494 }
16495 node.stateNode = _instance2;
16496 }
16497 appendChildToContainerChildSet(containerChildSet, _instance2);
16498 } else if (node.tag === HostPortal) {
16499 // If we have a portal child, then we don't want to traverse
16500 // down its children. Instead, we'll get insertions from each child in
16501 // the portal directly.
16502 } else if (node.tag === SuspenseComponent) {
16503 var current = node.alternate;
16504 if (current !== null) {
16505 var oldState = current.memoizedState;
16506 var newState = node.memoizedState;
16507 var oldIsHidden = oldState !== null;
16508 var newIsHidden = newState !== null;
16509 if (oldIsHidden !== newIsHidden) {
16510 // The placeholder either just timed out or switched back to the normal
16511 // children after having previously timed out. Toggle the visibility of
16512 // the direct host children.
16513 var primaryChildParent = newIsHidden ? node.child : node;
16514 if (primaryChildParent !== null) {
16515 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
16516 }
16517 // eslint-disable-next-line no-labels
16518 break branches;
16519 }
16520 }
16521 if (node.child !== null) {
16522 // Continue traversing like normal
16523 node.child.return = node;
16524 node = node.child;
16525 continue;
16526 }
16527 } else if (node.child !== null) {
16528 node.child.return = node;
16529 node = node.child;
16530 continue;
16531 }
16532 // $FlowFixMe This is correct but Flow is confused by the labeled break.
16533 node = node;
16534 if (node === workInProgress) {
16535 return;
16536 }
16537 while (node.sibling === null) {
16538 if (node.return === null || node.return === workInProgress) {
16539 return;
16540 }
16541 node = node.return;
16542 }
16543 node.sibling.return = node.return;
16544 node = node.sibling;
16545 }
16546 };
16547 updateHostContainer = function (workInProgress) {
16548 var portalOrRoot = workInProgress.stateNode;
16549 var childrenUnchanged = workInProgress.firstEffect === null;
16550 if (childrenUnchanged) {
16551 // No changes, just reuse the existing instance.
16552 } else {
16553 var container = portalOrRoot.containerInfo;
16554 var newChildSet = createContainerChildSet(container);
16555 // If children might have changed, we have to add them all to the set.
16556 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
16557 portalOrRoot.pendingChildren = newChildSet;
16558 // Schedule an update on the container to swap out the container.
16559 markUpdate(workInProgress);
16560 finalizeContainerChildren(container, newChildSet);
16561 }
16562 };
16563 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16564 var currentInstance = current.stateNode;
16565 var oldProps = current.memoizedProps;
16566 // If there are no effects associated with this node, then none of our children had any updates.
16567 // This guarantees that we can reuse all of them.
16568 var childrenUnchanged = workInProgress.firstEffect === null;
16569 if (childrenUnchanged && oldProps === newProps) {
16570 // No changes, just reuse the existing instance.
16571 // Note that this might release a previous clone.
16572 workInProgress.stateNode = currentInstance;
16573 return;
16574 }
16575 var recyclableInstance = workInProgress.stateNode;
16576 var currentHostContext = getHostContext();
16577 var updatePayload = null;
16578 if (oldProps !== newProps) {
16579 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
16580 }
16581 if (childrenUnchanged && updatePayload === null) {
16582 // No changes, just reuse the existing instance.
16583 // Note that this might release a previous clone.
16584 workInProgress.stateNode = currentInstance;
16585 return;
16586 }
16587 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
16588 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
16589 markUpdate(workInProgress);
16590 }
16591 workInProgress.stateNode = newInstance;
16592 if (childrenUnchanged) {
16593 // If there are no other effects in this tree, we need to flag this node as having one.
16594 // Even though we're not going to use it for anything.
16595 // Otherwise parents won't know that there are new children to propagate upwards.
16596 markUpdate(workInProgress);
16597 } else {
16598 // If children might have changed, we have to add them all to the set.
16599 appendAllChildren(newInstance, workInProgress, false, false);
16600 }
16601 };
16602 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16603 if (oldText !== newText) {
16604 // If the text content differs, we'll create a new text instance for it.
16605 var rootContainerInstance = getRootHostContainer();
16606 var currentHostContext = getHostContext();
16607 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
16608 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
16609 // This lets the parents know that at least one of their children has changed.
16610 markUpdate(workInProgress);
16611 }
16612 };
16613} else {
16614 // No host operations
16615 updateHostContainer = function (workInProgress) {
16616 // Noop
16617 };
16618 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
16619 // Noop
16620 };
16621 updateHostText$1 = function (current, workInProgress, oldText, newText) {
16622 // Noop
16623 };
16624}
16625
16626function completeWork(current, workInProgress, renderExpirationTime) {
16627 var newProps = workInProgress.pendingProps;
16628
16629 switch (workInProgress.tag) {
16630 case IndeterminateComponent:
16631 break;
16632 case LazyComponent:
16633 break;
16634 case SimpleMemoComponent:
16635 case FunctionComponent:
16636 break;
16637 case ClassComponent:
16638 {
16639 var Component = workInProgress.type;
16640 if (isContextProvider(Component)) {
16641 popContext(workInProgress);
16642 }
16643 break;
16644 }
16645 case HostRoot:
16646 {
16647 popHostContainer(workInProgress);
16648 popTopLevelContextObject(workInProgress);
16649 var fiberRoot = workInProgress.stateNode;
16650 if (fiberRoot.pendingContext) {
16651 fiberRoot.context = fiberRoot.pendingContext;
16652 fiberRoot.pendingContext = null;
16653 }
16654 if (current === null || current.child === null) {
16655 // If we hydrated, pop so that we can delete any remaining children
16656 // that weren't hydrated.
16657 popHydrationState(workInProgress);
16658 // This resets the hacky state to fix isMounted before committing.
16659 // TODO: Delete this when we delete isMounted and findDOMNode.
16660 workInProgress.effectTag &= ~Placement;
16661 }
16662 updateHostContainer(workInProgress);
16663 break;
16664 }
16665 case HostComponent:
16666 {
16667 popHostContext(workInProgress);
16668 var rootContainerInstance = getRootHostContainer();
16669 var type = workInProgress.type;
16670 if (current !== null && workInProgress.stateNode != null) {
16671 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
16672
16673 if (current.ref !== workInProgress.ref) {
16674 markRef$1(workInProgress);
16675 }
16676 } else {
16677 if (!newProps) {
16678 !(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;
16679 // This can happen when we abort work.
16680 break;
16681 }
16682
16683 var currentHostContext = getHostContext();
16684 // TODO: Move createInstance to beginWork and keep it on a context
16685 // "stack" as the parent. Then append children as we go in beginWork
16686 // or completeWork depending on we want to add then top->down or
16687 // bottom->up. Top->down is faster in IE11.
16688 var wasHydrated = popHydrationState(workInProgress);
16689 if (wasHydrated) {
16690 // TODO: Move this and createInstance step into the beginPhase
16691 // to consolidate.
16692 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
16693 // If changes to the hydrated node needs to be applied at the
16694 // commit-phase we mark this as such.
16695 markUpdate(workInProgress);
16696 }
16697 } else {
16698 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
16699
16700 appendAllChildren(instance, workInProgress, false, false);
16701
16702 // Certain renderers require commit-time effects for initial mount.
16703 // (eg DOM renderer supports auto-focus for certain elements).
16704 // Make sure such renderers get scheduled for later work.
16705 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
16706 markUpdate(workInProgress);
16707 }
16708 workInProgress.stateNode = instance;
16709 }
16710
16711 if (workInProgress.ref !== null) {
16712 // If there is a ref on a host node we need to schedule a callback
16713 markRef$1(workInProgress);
16714 }
16715 }
16716 break;
16717 }
16718 case HostText:
16719 {
16720 var newText = newProps;
16721 if (current && workInProgress.stateNode != null) {
16722 var oldText = current.memoizedProps;
16723 // If we have an alternate, that means this is an update and we need
16724 // to schedule a side-effect to do the updates.
16725 updateHostText$1(current, workInProgress, oldText, newText);
16726 } else {
16727 if (typeof newText !== 'string') {
16728 !(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;
16729 // This can happen when we abort work.
16730 }
16731 var _rootContainerInstance = getRootHostContainer();
16732 var _currentHostContext = getHostContext();
16733 var _wasHydrated = popHydrationState(workInProgress);
16734 if (_wasHydrated) {
16735 if (prepareToHydrateHostTextInstance(workInProgress)) {
16736 markUpdate(workInProgress);
16737 }
16738 } else {
16739 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
16740 }
16741 }
16742 break;
16743 }
16744 case ForwardRef:
16745 break;
16746 case SuspenseComponent:
16747 {
16748 var nextState = workInProgress.memoizedState;
16749 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
16750 // Something suspended. Re-render with the fallback children.
16751 workInProgress.expirationTime = renderExpirationTime;
16752 // Do not reset the effect list.
16753 return workInProgress;
16754 }
16755
16756 var nextDidTimeout = nextState !== null;
16757 var prevDidTimeout = current !== null && current.memoizedState !== null;
16758
16759 if (current !== null && !nextDidTimeout && prevDidTimeout) {
16760 // We just switched from the fallback to the normal children. Delete
16761 // the fallback.
16762 // TODO: Would it be better to store the fallback fragment on
16763 var currentFallbackChild = current.child.sibling;
16764 if (currentFallbackChild !== null) {
16765 // Deletions go at the beginning of the return fiber's effect list
16766 var first = workInProgress.firstEffect;
16767 if (first !== null) {
16768 workInProgress.firstEffect = currentFallbackChild;
16769 currentFallbackChild.nextEffect = first;
16770 } else {
16771 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
16772 currentFallbackChild.nextEffect = null;
16773 }
16774 currentFallbackChild.effectTag = Deletion;
16775 }
16776 }
16777
16778 if (nextDidTimeout || prevDidTimeout) {
16779 // If the children are hidden, or if they were previous hidden, schedule
16780 // an effect to toggle their visibility. This is also used to attach a
16781 // retry listener to the promise.
16782 workInProgress.effectTag |= Update;
16783 }
16784 break;
16785 }
16786 case Fragment:
16787 break;
16788 case Mode:
16789 break;
16790 case Profiler:
16791 break;
16792 case HostPortal:
16793 popHostContainer(workInProgress);
16794 updateHostContainer(workInProgress);
16795 break;
16796 case ContextProvider:
16797 // Pop provider fiber
16798 popProvider(workInProgress);
16799 break;
16800 case ContextConsumer:
16801 break;
16802 case MemoComponent:
16803 break;
16804 case IncompleteClassComponent:
16805 {
16806 // Same as class component case. I put it down here so that the tags are
16807 // sequential to ensure this switch is compiled to a jump table.
16808 var _Component = workInProgress.type;
16809 if (isContextProvider(_Component)) {
16810 popContext(workInProgress);
16811 }
16812 break;
16813 }
16814 case DehydratedSuspenseComponent:
16815 {
16816 if (enableSuspenseServerRenderer) {
16817 if (current === null) {
16818 var _wasHydrated2 = popHydrationState(workInProgress);
16819 !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
16820 skipPastDehydratedSuspenseInstance(workInProgress);
16821 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
16822 // This boundary did not suspend so it's now hydrated.
16823 // To handle any future suspense cases, we're going to now upgrade it
16824 // to a Suspense component. We detach it from the existing current fiber.
16825 current.alternate = null;
16826 workInProgress.alternate = null;
16827 workInProgress.tag = SuspenseComponent;
16828 workInProgress.memoizedState = null;
16829 workInProgress.stateNode = null;
16830 }
16831 }
16832 break;
16833 }
16834 default:
16835 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
16836 }
16837
16838 return null;
16839}
16840
16841function shouldCaptureSuspense(workInProgress) {
16842 // In order to capture, the Suspense component must have a fallback prop.
16843 if (workInProgress.memoizedProps.fallback === undefined) {
16844 return false;
16845 }
16846 // If it was the primary children that just suspended, capture and render the
16847 // fallback. Otherwise, don't capture and bubble to the next boundary.
16848 var nextState = workInProgress.memoizedState;
16849 return nextState === null;
16850}
16851
16852// This module is forked in different environments.
16853// By default, return `true` to log errors to the console.
16854// Forks can return `false` if this isn't desirable.
16855function showErrorDialog(capturedError) {
16856 return true;
16857}
16858
16859function logCapturedError(capturedError) {
16860 var logError = showErrorDialog(capturedError);
16861
16862 // Allow injected showErrorDialog() to prevent default console.error logging.
16863 // This enables renderers like ReactNative to better manage redbox behavior.
16864 if (logError === false) {
16865 return;
16866 }
16867
16868 var error = capturedError.error;
16869 {
16870 var componentName = capturedError.componentName,
16871 componentStack = capturedError.componentStack,
16872 errorBoundaryName = capturedError.errorBoundaryName,
16873 errorBoundaryFound = capturedError.errorBoundaryFound,
16874 willRetry = capturedError.willRetry;
16875
16876 // Browsers support silencing uncaught errors by calling
16877 // `preventDefault()` in window `error` handler.
16878 // We record this information as an expando on the error.
16879
16880 if (error != null && error._suppressLogging) {
16881 if (errorBoundaryFound && willRetry) {
16882 // The error is recoverable and was silenced.
16883 // Ignore it and don't print the stack addendum.
16884 // This is handy for testing error boundaries without noise.
16885 return;
16886 }
16887 // The error is fatal. Since the silencing might have
16888 // been accidental, we'll surface it anyway.
16889 // However, the browser would have silenced the original error
16890 // so we'll print it first, and then print the stack addendum.
16891 console.error(error);
16892 // For a more detailed description of this block, see:
16893 // https://github.com/facebook/react/pull/13384
16894 }
16895
16896 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
16897
16898 var errorBoundaryMessage = void 0;
16899 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
16900 if (errorBoundaryFound && errorBoundaryName) {
16901 if (willRetry) {
16902 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
16903 } else {
16904 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
16905 }
16906 } else {
16907 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.';
16908 }
16909 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
16910
16911 // In development, we provide our own message with just the component stack.
16912 // We don't include the original error message and JS stack because the browser
16913 // has already printed it. Even if the application swallows the error, it is still
16914 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
16915 console.error(combinedMessage);
16916 }
16917}
16918
16919var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
16920{
16921 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
16922}
16923
16924var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
16925
16926function logError(boundary, errorInfo) {
16927 var source = errorInfo.source;
16928 var stack = errorInfo.stack;
16929 if (stack === null && source !== null) {
16930 stack = getStackByFiberInDevAndProd(source);
16931 }
16932
16933 var capturedError = {
16934 componentName: source !== null ? getComponentName(source.type) : null,
16935 componentStack: stack !== null ? stack : '',
16936 error: errorInfo.value,
16937 errorBoundary: null,
16938 errorBoundaryName: null,
16939 errorBoundaryFound: false,
16940 willRetry: false
16941 };
16942
16943 if (boundary !== null && boundary.tag === ClassComponent) {
16944 capturedError.errorBoundary = boundary.stateNode;
16945 capturedError.errorBoundaryName = getComponentName(boundary.type);
16946 capturedError.errorBoundaryFound = true;
16947 capturedError.willRetry = true;
16948 }
16949
16950 try {
16951 logCapturedError(capturedError);
16952 } catch (e) {
16953 // This method must not throw, or React internal state will get messed up.
16954 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
16955 // we want to report this error outside of the normal stack as a last resort.
16956 // https://github.com/facebook/react/issues/13188
16957 setTimeout(function () {
16958 throw e;
16959 });
16960 }
16961}
16962
16963var callComponentWillUnmountWithTimer = function (current$$1, instance) {
16964 startPhaseTimer(current$$1, 'componentWillUnmount');
16965 instance.props = current$$1.memoizedProps;
16966 instance.state = current$$1.memoizedState;
16967 instance.componentWillUnmount();
16968 stopPhaseTimer();
16969};
16970
16971// Capture errors so they don't interrupt unmounting.
16972function safelyCallComponentWillUnmount(current$$1, instance) {
16973 {
16974 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
16975 if (hasCaughtError()) {
16976 var unmountError = clearCaughtError();
16977 captureCommitPhaseError(current$$1, unmountError);
16978 }
16979 }
16980}
16981
16982function safelyDetachRef(current$$1) {
16983 var ref = current$$1.ref;
16984 if (ref !== null) {
16985 if (typeof ref === 'function') {
16986 {
16987 invokeGuardedCallback(null, ref, null, null);
16988 if (hasCaughtError()) {
16989 var refError = clearCaughtError();
16990 captureCommitPhaseError(current$$1, refError);
16991 }
16992 }
16993 } else {
16994 ref.current = null;
16995 }
16996 }
16997}
16998
16999function safelyCallDestroy(current$$1, destroy) {
17000 {
17001 invokeGuardedCallback(null, destroy, null);
17002 if (hasCaughtError()) {
17003 var error = clearCaughtError();
17004 captureCommitPhaseError(current$$1, error);
17005 }
17006 }
17007}
17008
17009function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
17010 switch (finishedWork.tag) {
17011 case FunctionComponent:
17012 case ForwardRef:
17013 case SimpleMemoComponent:
17014 {
17015 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
17016 return;
17017 }
17018 case ClassComponent:
17019 {
17020 if (finishedWork.effectTag & Snapshot) {
17021 if (current$$1 !== null) {
17022 var prevProps = current$$1.memoizedProps;
17023 var prevState = current$$1.memoizedState;
17024 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
17025 var instance = finishedWork.stateNode;
17026 // We could update instance props and state here,
17027 // but instead we rely on them being set during last render.
17028 // TODO: revisit this when we implement resuming.
17029 {
17030 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17031 !(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;
17032 !(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;
17033 }
17034 }
17035 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
17036 {
17037 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
17038 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
17039 didWarnSet.add(finishedWork.type);
17040 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
17041 }
17042 }
17043 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
17044 stopPhaseTimer();
17045 }
17046 }
17047 return;
17048 }
17049 case HostRoot:
17050 case HostComponent:
17051 case HostText:
17052 case HostPortal:
17053 case IncompleteClassComponent:
17054 // Nothing to do for these component types
17055 return;
17056 default:
17057 {
17058 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.');
17059 }
17060 }
17061}
17062
17063function commitHookEffectList(unmountTag, mountTag, finishedWork) {
17064 var updateQueue = finishedWork.updateQueue;
17065 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
17066 if (lastEffect !== null) {
17067 var firstEffect = lastEffect.next;
17068 var effect = firstEffect;
17069 do {
17070 if ((effect.tag & unmountTag) !== NoEffect$1) {
17071 // Unmount
17072 var destroy = effect.destroy;
17073 effect.destroy = undefined;
17074 if (destroy !== undefined) {
17075 destroy();
17076 }
17077 }
17078 if ((effect.tag & mountTag) !== NoEffect$1) {
17079 // Mount
17080 var create = effect.create;
17081 effect.destroy = create();
17082
17083 {
17084 var _destroy = effect.destroy;
17085 if (_destroy !== undefined && typeof _destroy !== 'function') {
17086 var addendum = void 0;
17087 if (_destroy === null) {
17088 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
17089 } else if (typeof _destroy.then === 'function') {
17090 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.";
17091 } else {
17092 addendum = ' You returned: ' + _destroy;
17093 }
17094 warningWithoutStack$1(false, 'An Effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
17095 }
17096 }
17097 }
17098 effect = effect.next;
17099 } while (effect !== firstEffect);
17100 }
17101}
17102
17103function commitPassiveHookEffects(finishedWork) {
17104 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
17105 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
17106}
17107
17108function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
17109 switch (finishedWork.tag) {
17110 case FunctionComponent:
17111 case ForwardRef:
17112 case SimpleMemoComponent:
17113 {
17114 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
17115 break;
17116 }
17117 case ClassComponent:
17118 {
17119 var instance = finishedWork.stateNode;
17120 if (finishedWork.effectTag & Update) {
17121 if (current$$1 === null) {
17122 startPhaseTimer(finishedWork, 'componentDidMount');
17123 // We could update instance props and state here,
17124 // but instead we rely on them being set during last render.
17125 // TODO: revisit this when we implement resuming.
17126 {
17127 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17128 !(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;
17129 !(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;
17130 }
17131 }
17132 instance.componentDidMount();
17133 stopPhaseTimer();
17134 } else {
17135 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
17136 var prevState = current$$1.memoizedState;
17137 startPhaseTimer(finishedWork, 'componentDidUpdate');
17138 // We could update instance props and state here,
17139 // but instead we rely on them being set during last render.
17140 // TODO: revisit this when we implement resuming.
17141 {
17142 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17143 !(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;
17144 !(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;
17145 }
17146 }
17147 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
17148 stopPhaseTimer();
17149 }
17150 }
17151 var updateQueue = finishedWork.updateQueue;
17152 if (updateQueue !== null) {
17153 {
17154 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
17155 !(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;
17156 !(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;
17157 }
17158 }
17159 // We could update instance props and state here,
17160 // but instead we rely on them being set during last render.
17161 // TODO: revisit this when we implement resuming.
17162 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
17163 }
17164 return;
17165 }
17166 case HostRoot:
17167 {
17168 var _updateQueue = finishedWork.updateQueue;
17169 if (_updateQueue !== null) {
17170 var _instance = null;
17171 if (finishedWork.child !== null) {
17172 switch (finishedWork.child.tag) {
17173 case HostComponent:
17174 _instance = getPublicInstance(finishedWork.child.stateNode);
17175 break;
17176 case ClassComponent:
17177 _instance = finishedWork.child.stateNode;
17178 break;
17179 }
17180 }
17181 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
17182 }
17183 return;
17184 }
17185 case HostComponent:
17186 {
17187 var _instance2 = finishedWork.stateNode;
17188
17189 // Renderers may schedule work to be done after host components are mounted
17190 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
17191 // These effects should only be committed when components are first mounted,
17192 // aka when there is no current/alternate.
17193 if (current$$1 === null && finishedWork.effectTag & Update) {
17194 var type = finishedWork.type;
17195 var props = finishedWork.memoizedProps;
17196 commitMount(_instance2, type, props, finishedWork);
17197 }
17198
17199 return;
17200 }
17201 case HostText:
17202 {
17203 // We have no life-cycles associated with text.
17204 return;
17205 }
17206 case HostPortal:
17207 {
17208 // We have no life-cycles associated with portals.
17209 return;
17210 }
17211 case Profiler:
17212 {
17213 if (enableProfilerTimer) {
17214 var onRender = finishedWork.memoizedProps.onRender;
17215
17216 if (enableSchedulerTracing) {
17217 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
17218 } else {
17219 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
17220 }
17221 }
17222 return;
17223 }
17224 case SuspenseComponent:
17225 break;
17226 case IncompleteClassComponent:
17227 break;
17228 default:
17229 {
17230 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.');
17231 }
17232 }
17233}
17234
17235function hideOrUnhideAllChildren(finishedWork, isHidden) {
17236 if (supportsMutation) {
17237 // We only have the top Fiber that was inserted but we need to recurse down its
17238 var node = finishedWork;
17239 while (true) {
17240 if (node.tag === HostComponent) {
17241 var instance = node.stateNode;
17242 if (isHidden) {
17243 hideInstance(instance);
17244 } else {
17245 unhideInstance(node.stateNode, node.memoizedProps);
17246 }
17247 } else if (node.tag === HostText) {
17248 var _instance3 = node.stateNode;
17249 if (isHidden) {
17250 hideTextInstance(_instance3);
17251 } else {
17252 unhideTextInstance(_instance3, node.memoizedProps);
17253 }
17254 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
17255 // Found a nested Suspense component that timed out. Skip over the
17256 var fallbackChildFragment = node.child.sibling;
17257 fallbackChildFragment.return = node;
17258 node = fallbackChildFragment;
17259 continue;
17260 } else if (node.child !== null) {
17261 node.child.return = node;
17262 node = node.child;
17263 continue;
17264 }
17265 if (node === finishedWork) {
17266 return;
17267 }
17268 while (node.sibling === null) {
17269 if (node.return === null || node.return === finishedWork) {
17270 return;
17271 }
17272 node = node.return;
17273 }
17274 node.sibling.return = node.return;
17275 node = node.sibling;
17276 }
17277 }
17278}
17279
17280function commitAttachRef(finishedWork) {
17281 var ref = finishedWork.ref;
17282 if (ref !== null) {
17283 var instance = finishedWork.stateNode;
17284 var instanceToUse = void 0;
17285 switch (finishedWork.tag) {
17286 case HostComponent:
17287 instanceToUse = getPublicInstance(instance);
17288 break;
17289 default:
17290 instanceToUse = instance;
17291 }
17292 if (typeof ref === 'function') {
17293 ref(instanceToUse);
17294 } else {
17295 {
17296 if (!ref.hasOwnProperty('current')) {
17297 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
17298 }
17299 }
17300
17301 ref.current = instanceToUse;
17302 }
17303 }
17304}
17305
17306function commitDetachRef(current$$1) {
17307 var currentRef = current$$1.ref;
17308 if (currentRef !== null) {
17309 if (typeof currentRef === 'function') {
17310 currentRef(null);
17311 } else {
17312 currentRef.current = null;
17313 }
17314 }
17315}
17316
17317// User-originating errors (lifecycles and refs) should not interrupt
17318// deletion, so don't let them throw. Host-originating errors should
17319// interrupt deletion, so it's okay
17320function commitUnmount(current$$1) {
17321 onCommitUnmount(current$$1);
17322
17323 switch (current$$1.tag) {
17324 case FunctionComponent:
17325 case ForwardRef:
17326 case MemoComponent:
17327 case SimpleMemoComponent:
17328 {
17329 var updateQueue = current$$1.updateQueue;
17330 if (updateQueue !== null) {
17331 var lastEffect = updateQueue.lastEffect;
17332 if (lastEffect !== null) {
17333 var firstEffect = lastEffect.next;
17334 var effect = firstEffect;
17335 do {
17336 var destroy = effect.destroy;
17337 if (destroy !== undefined) {
17338 safelyCallDestroy(current$$1, destroy);
17339 }
17340 effect = effect.next;
17341 } while (effect !== firstEffect);
17342 }
17343 }
17344 break;
17345 }
17346 case ClassComponent:
17347 {
17348 safelyDetachRef(current$$1);
17349 var instance = current$$1.stateNode;
17350 if (typeof instance.componentWillUnmount === 'function') {
17351 safelyCallComponentWillUnmount(current$$1, instance);
17352 }
17353 return;
17354 }
17355 case HostComponent:
17356 {
17357 safelyDetachRef(current$$1);
17358 return;
17359 }
17360 case HostPortal:
17361 {
17362 // TODO: this is recursive.
17363 // We are also not using this parent because
17364 // the portal will get pushed immediately.
17365 if (supportsMutation) {
17366 unmountHostComponents(current$$1);
17367 } else if (supportsPersistence) {
17368 emptyPortalContainer(current$$1);
17369 }
17370 return;
17371 }
17372 }
17373}
17374
17375function commitNestedUnmounts(root) {
17376 // While we're inside a removed host node we don't want to call
17377 // removeChild on the inner nodes because they're removed by the top
17378 // call anyway. We also want to call componentWillUnmount on all
17379 // composites before this host node is removed from the tree. Therefore
17380 var node = root;
17381 while (true) {
17382 commitUnmount(node);
17383 // Visit children because they may contain more composite or host nodes.
17384 // Skip portals because commitUnmount() currently visits them recursively.
17385 if (node.child !== null && (
17386 // If we use mutation we drill down into portals using commitUnmount above.
17387 // If we don't use mutation we drill down into portals here instead.
17388 !supportsMutation || node.tag !== HostPortal)) {
17389 node.child.return = node;
17390 node = node.child;
17391 continue;
17392 }
17393 if (node === root) {
17394 return;
17395 }
17396 while (node.sibling === null) {
17397 if (node.return === null || node.return === root) {
17398 return;
17399 }
17400 node = node.return;
17401 }
17402 node.sibling.return = node.return;
17403 node = node.sibling;
17404 }
17405}
17406
17407function detachFiber(current$$1) {
17408 // Cut off the return pointers to disconnect it from the tree. Ideally, we
17409 // should clear the child pointer of the parent alternate to let this
17410 // get GC:ed but we don't know which for sure which parent is the current
17411 // one so we'll settle for GC:ing the subtree of this child. This child
17412 // itself will be GC:ed when the parent updates the next time.
17413 current$$1.return = null;
17414 current$$1.child = null;
17415 current$$1.memoizedState = null;
17416 current$$1.updateQueue = null;
17417 var alternate = current$$1.alternate;
17418 if (alternate !== null) {
17419 alternate.return = null;
17420 alternate.child = null;
17421 alternate.memoizedState = null;
17422 alternate.updateQueue = null;
17423 }
17424}
17425
17426function emptyPortalContainer(current$$1) {
17427 if (!supportsPersistence) {
17428 return;
17429 }
17430
17431 var portal = current$$1.stateNode;
17432 var containerInfo = portal.containerInfo;
17433
17434 var emptyChildSet = createContainerChildSet(containerInfo);
17435 replaceContainerChildren(containerInfo, emptyChildSet);
17436}
17437
17438function commitContainer(finishedWork) {
17439 if (!supportsPersistence) {
17440 return;
17441 }
17442
17443 switch (finishedWork.tag) {
17444 case ClassComponent:
17445 {
17446 return;
17447 }
17448 case HostComponent:
17449 {
17450 return;
17451 }
17452 case HostText:
17453 {
17454 return;
17455 }
17456 case HostRoot:
17457 case HostPortal:
17458 {
17459 var portalOrRoot = finishedWork.stateNode;
17460 var containerInfo = portalOrRoot.containerInfo,
17461 _pendingChildren = portalOrRoot.pendingChildren;
17462
17463 replaceContainerChildren(containerInfo, _pendingChildren);
17464 return;
17465 }
17466 default:
17467 {
17468 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.');
17469 }
17470 }
17471}
17472
17473function getHostParentFiber(fiber) {
17474 var parent = fiber.return;
17475 while (parent !== null) {
17476 if (isHostParent(parent)) {
17477 return parent;
17478 }
17479 parent = parent.return;
17480 }
17481 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
17482}
17483
17484function isHostParent(fiber) {
17485 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
17486}
17487
17488function getHostSibling(fiber) {
17489 // We're going to search forward into the tree until we find a sibling host
17490 // node. Unfortunately, if multiple insertions are done in a row we have to
17491 // search past them. This leads to exponential search for the next sibling.
17492 var node = fiber;
17493 siblings: while (true) {
17494 // If we didn't find anything, let's try the next sibling.
17495 while (node.sibling === null) {
17496 if (node.return === null || isHostParent(node.return)) {
17497 // If we pop out of the root or hit the parent the fiber we are the
17498 // last sibling.
17499 return null;
17500 }
17501 node = node.return;
17502 }
17503 node.sibling.return = node.return;
17504 node = node.sibling;
17505 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
17506 // If it is not host node and, we might have a host node inside it.
17507 // Try to search down until we find one.
17508 if (node.effectTag & Placement) {
17509 // If we don't have a child, try the siblings instead.
17510 continue siblings;
17511 }
17512 // If we don't have a child, try the siblings instead.
17513 // We also skip portals because they are not part of this host tree.
17514 if (node.child === null || node.tag === HostPortal) {
17515 continue siblings;
17516 } else {
17517 node.child.return = node;
17518 node = node.child;
17519 }
17520 }
17521 // Check if this host node is stable or about to be placed.
17522 if (!(node.effectTag & Placement)) {
17523 // Found it!
17524 return node.stateNode;
17525 }
17526 }
17527}
17528
17529function commitPlacement(finishedWork) {
17530 if (!supportsMutation) {
17531 return;
17532 }
17533
17534 // Recursively insert all host nodes into the parent.
17535 var parentFiber = getHostParentFiber(finishedWork);
17536
17537 // Note: these two variables *must* always be updated together.
17538 var parent = void 0;
17539 var isContainer = void 0;
17540
17541 switch (parentFiber.tag) {
17542 case HostComponent:
17543 parent = parentFiber.stateNode;
17544 isContainer = false;
17545 break;
17546 case HostRoot:
17547 parent = parentFiber.stateNode.containerInfo;
17548 isContainer = true;
17549 break;
17550 case HostPortal:
17551 parent = parentFiber.stateNode.containerInfo;
17552 isContainer = true;
17553 break;
17554 default:
17555 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
17556 }
17557 if (parentFiber.effectTag & ContentReset) {
17558 // Reset the text content of the parent before doing any insertions
17559 resetTextContent(parent);
17560 // Clear ContentReset from the effect tag
17561 parentFiber.effectTag &= ~ContentReset;
17562 }
17563
17564 var before = getHostSibling(finishedWork);
17565 // We only have the top Fiber that was inserted but we need to recurse down its
17566 // children to find all the terminal nodes.
17567 var node = finishedWork;
17568 while (true) {
17569 if (node.tag === HostComponent || node.tag === HostText) {
17570 if (before) {
17571 if (isContainer) {
17572 insertInContainerBefore(parent, node.stateNode, before);
17573 } else {
17574 insertBefore(parent, node.stateNode, before);
17575 }
17576 } else {
17577 if (isContainer) {
17578 appendChildToContainer(parent, node.stateNode);
17579 } else {
17580 appendChild(parent, node.stateNode);
17581 }
17582 }
17583 } else if (node.tag === HostPortal) {
17584 // If the insertion itself is a portal, then we don't want to traverse
17585 // down its children. Instead, we'll get insertions from each child in
17586 // the portal directly.
17587 } else if (node.child !== null) {
17588 node.child.return = node;
17589 node = node.child;
17590 continue;
17591 }
17592 if (node === finishedWork) {
17593 return;
17594 }
17595 while (node.sibling === null) {
17596 if (node.return === null || node.return === finishedWork) {
17597 return;
17598 }
17599 node = node.return;
17600 }
17601 node.sibling.return = node.return;
17602 node = node.sibling;
17603 }
17604}
17605
17606function unmountHostComponents(current$$1) {
17607 // We only have the top Fiber that was deleted but we need to recurse down its
17608 var node = current$$1;
17609
17610 // Each iteration, currentParent is populated with node's host parent if not
17611 // currentParentIsValid.
17612 var currentParentIsValid = false;
17613
17614 // Note: these two variables *must* always be updated together.
17615 var currentParent = void 0;
17616 var currentParentIsContainer = void 0;
17617
17618 while (true) {
17619 if (!currentParentIsValid) {
17620 var parent = node.return;
17621 findParent: while (true) {
17622 !(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;
17623 switch (parent.tag) {
17624 case HostComponent:
17625 currentParent = parent.stateNode;
17626 currentParentIsContainer = false;
17627 break findParent;
17628 case HostRoot:
17629 currentParent = parent.stateNode.containerInfo;
17630 currentParentIsContainer = true;
17631 break findParent;
17632 case HostPortal:
17633 currentParent = parent.stateNode.containerInfo;
17634 currentParentIsContainer = true;
17635 break findParent;
17636 }
17637 parent = parent.return;
17638 }
17639 currentParentIsValid = true;
17640 }
17641
17642 if (node.tag === HostComponent || node.tag === HostText) {
17643 commitNestedUnmounts(node);
17644 // After all the children have unmounted, it is now safe to remove the
17645 // node from the tree.
17646 if (currentParentIsContainer) {
17647 removeChildFromContainer(currentParent, node.stateNode);
17648 } else {
17649 removeChild(currentParent, node.stateNode);
17650 }
17651 // Don't visit children because we already visited them.
17652 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
17653 // Delete the dehydrated suspense boundary and all of its content.
17654 if (currentParentIsContainer) {
17655 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
17656 } else {
17657 clearSuspenseBoundary(currentParent, node.stateNode);
17658 }
17659 } else if (node.tag === HostPortal) {
17660 if (node.child !== null) {
17661 // When we go into a portal, it becomes the parent to remove from.
17662 // We will reassign it back when we pop the portal on the way up.
17663 currentParent = node.stateNode.containerInfo;
17664 currentParentIsContainer = true;
17665 // Visit children because portals might contain host components.
17666 node.child.return = node;
17667 node = node.child;
17668 continue;
17669 }
17670 } else {
17671 commitUnmount(node);
17672 // Visit children because we may find more host components below.
17673 if (node.child !== null) {
17674 node.child.return = node;
17675 node = node.child;
17676 continue;
17677 }
17678 }
17679 if (node === current$$1) {
17680 return;
17681 }
17682 while (node.sibling === null) {
17683 if (node.return === null || node.return === current$$1) {
17684 return;
17685 }
17686 node = node.return;
17687 if (node.tag === HostPortal) {
17688 // When we go out of the portal, we need to restore the parent.
17689 // Since we don't keep a stack of them, we will search for it.
17690 currentParentIsValid = false;
17691 }
17692 }
17693 node.sibling.return = node.return;
17694 node = node.sibling;
17695 }
17696}
17697
17698function commitDeletion(current$$1) {
17699 if (supportsMutation) {
17700 // Recursively delete all host nodes from the parent.
17701 // Detach refs and call componentWillUnmount() on the whole subtree.
17702 unmountHostComponents(current$$1);
17703 } else {
17704 // Detach refs and call componentWillUnmount() on the whole subtree.
17705 commitNestedUnmounts(current$$1);
17706 }
17707 detachFiber(current$$1);
17708}
17709
17710function commitWork(current$$1, finishedWork) {
17711 if (!supportsMutation) {
17712 switch (finishedWork.tag) {
17713 case FunctionComponent:
17714 case ForwardRef:
17715 case MemoComponent:
17716 case SimpleMemoComponent:
17717 {
17718 // Note: We currently never use MountMutation, but useLayout uses
17719 // UnmountMutation.
17720 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17721 return;
17722 }
17723 }
17724
17725 commitContainer(finishedWork);
17726 return;
17727 }
17728
17729 switch (finishedWork.tag) {
17730 case FunctionComponent:
17731 case ForwardRef:
17732 case MemoComponent:
17733 case SimpleMemoComponent:
17734 {
17735 // Note: We currently never use MountMutation, but useLayout uses
17736 // UnmountMutation.
17737 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
17738 return;
17739 }
17740 case ClassComponent:
17741 {
17742 return;
17743 }
17744 case HostComponent:
17745 {
17746 var instance = finishedWork.stateNode;
17747 if (instance != null) {
17748 // Commit the work prepared earlier.
17749 var newProps = finishedWork.memoizedProps;
17750 // For hydration we reuse the update path but we treat the oldProps
17751 // as the newProps. The updatePayload will contain the real change in
17752 // this case.
17753 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
17754 var type = finishedWork.type;
17755 // TODO: Type the updateQueue to be specific to host components.
17756 var updatePayload = finishedWork.updateQueue;
17757 finishedWork.updateQueue = null;
17758 if (updatePayload !== null) {
17759 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
17760 }
17761 }
17762 return;
17763 }
17764 case HostText:
17765 {
17766 !(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;
17767 var textInstance = finishedWork.stateNode;
17768 var newText = finishedWork.memoizedProps;
17769 // For hydration we reuse the update path but we treat the oldProps
17770 // as the newProps. The updatePayload will contain the real change in
17771 // this case.
17772 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
17773 commitTextUpdate(textInstance, oldText, newText);
17774 return;
17775 }
17776 case HostRoot:
17777 {
17778 return;
17779 }
17780 case Profiler:
17781 {
17782 return;
17783 }
17784 case SuspenseComponent:
17785 {
17786 var newState = finishedWork.memoizedState;
17787
17788 var newDidTimeout = void 0;
17789 var primaryChildParent = finishedWork;
17790 if (newState === null) {
17791 newDidTimeout = false;
17792 } else {
17793 newDidTimeout = true;
17794 primaryChildParent = finishedWork.child;
17795 if (newState.timedOutAt === NoWork) {
17796 // If the children had not already timed out, record the time.
17797 // This is used to compute the elapsed time during subsequent
17798 // attempts to render the children.
17799 newState.timedOutAt = requestCurrentTime();
17800 }
17801 }
17802
17803 if (primaryChildParent !== null) {
17804 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
17805 }
17806
17807 // If this boundary just timed out, then it will have a set of thenables.
17808 // For each thenable, attach a listener so that when it resolves, React
17809 // attempts to re-render the boundary in the primary (pre-timeout) state.
17810 var thenables = finishedWork.updateQueue;
17811 if (thenables !== null) {
17812 finishedWork.updateQueue = null;
17813 var retryCache = finishedWork.stateNode;
17814 if (retryCache === null) {
17815 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
17816 }
17817 thenables.forEach(function (thenable) {
17818 // Memoize using the boundary fiber to prevent redundant listeners.
17819 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
17820 if (enableSchedulerTracing) {
17821 retry = tracing.unstable_wrap(retry);
17822 }
17823 if (!retryCache.has(thenable)) {
17824 retryCache.add(thenable);
17825 thenable.then(retry, retry);
17826 }
17827 });
17828 }
17829
17830 return;
17831 }
17832 case IncompleteClassComponent:
17833 {
17834 return;
17835 }
17836 default:
17837 {
17838 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.');
17839 }
17840 }
17841}
17842
17843function commitResetTextContent(current$$1) {
17844 if (!supportsMutation) {
17845 return;
17846 }
17847 resetTextContent(current$$1.stateNode);
17848}
17849
17850var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
17851var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
17852
17853function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
17854 var update = createUpdate(expirationTime);
17855 // Unmount the root by rendering null.
17856 update.tag = CaptureUpdate;
17857 // Caution: React DevTools currently depends on this property
17858 // being called "element".
17859 update.payload = { element: null };
17860 var error = errorInfo.value;
17861 update.callback = function () {
17862 onUncaughtError(error);
17863 logError(fiber, errorInfo);
17864 };
17865 return update;
17866}
17867
17868function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
17869 var update = createUpdate(expirationTime);
17870 update.tag = CaptureUpdate;
17871 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
17872 if (typeof getDerivedStateFromError === 'function') {
17873 var error = errorInfo.value;
17874 update.payload = function () {
17875 return getDerivedStateFromError(error);
17876 };
17877 }
17878
17879 var inst = fiber.stateNode;
17880 if (inst !== null && typeof inst.componentDidCatch === 'function') {
17881 update.callback = function callback() {
17882 if (typeof getDerivedStateFromError !== 'function') {
17883 // To preserve the preexisting retry behavior of error boundaries,
17884 // we keep track of which ones already failed during this batch.
17885 // This gets reset before we yield back to the browser.
17886 // TODO: Warn in strict mode if getDerivedStateFromError is
17887 // not defined.
17888 markLegacyErrorBoundaryAsFailed(this);
17889 }
17890 var error = errorInfo.value;
17891 var stack = errorInfo.stack;
17892 logError(fiber, errorInfo);
17893 this.componentDidCatch(error, {
17894 componentStack: stack !== null ? stack : ''
17895 });
17896 {
17897 if (typeof getDerivedStateFromError !== 'function') {
17898 // If componentDidCatch is the only error boundary method defined,
17899 // then it needs to call setState to recover from errors.
17900 // If no state update is scheduled then the boundary will swallow the error.
17901 !(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;
17902 }
17903 }
17904 };
17905 }
17906 return update;
17907}
17908
17909function attachPingListener(root, renderExpirationTime, thenable) {
17910 // Attach a listener to the promise to "ping" the root and retry. But
17911 // only if one does not already exist for the current render expiration
17912 // time (which acts like a "thread ID" here).
17913 var pingCache = root.pingCache;
17914 var threadIDs = void 0;
17915 if (pingCache === null) {
17916 pingCache = root.pingCache = new PossiblyWeakMap();
17917 threadIDs = new Set();
17918 pingCache.set(thenable, threadIDs);
17919 } else {
17920 threadIDs = pingCache.get(thenable);
17921 if (threadIDs === undefined) {
17922 threadIDs = new Set();
17923 pingCache.set(thenable, threadIDs);
17924 }
17925 }
17926 if (!threadIDs.has(renderExpirationTime)) {
17927 // Memoize using the thread ID to prevent redundant listeners.
17928 threadIDs.add(renderExpirationTime);
17929 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
17930 if (enableSchedulerTracing) {
17931 ping = tracing.unstable_wrap(ping);
17932 }
17933 thenable.then(ping, ping);
17934 }
17935}
17936
17937function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
17938 // The source fiber did not complete.
17939 sourceFiber.effectTag |= Incomplete;
17940 // Its effect list is no longer valid.
17941 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
17942
17943 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
17944 // This is a thenable.
17945 var thenable = value;
17946
17947 // Find the earliest timeout threshold of all the placeholders in the
17948 // ancestor path. We could avoid this traversal by storing the thresholds on
17949 // the stack, but we choose not to because we only hit this path if we're
17950 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
17951 // the non-IO- bound case.
17952 var _workInProgress = returnFiber;
17953 var earliestTimeoutMs = -1;
17954 var startTimeMs = -1;
17955 do {
17956 if (_workInProgress.tag === SuspenseComponent) {
17957 var current$$1 = _workInProgress.alternate;
17958 if (current$$1 !== null) {
17959 var currentState = current$$1.memoizedState;
17960 if (currentState !== null) {
17961 // Reached a boundary that already timed out. Do not search
17962 // any further.
17963 var timedOutAt = currentState.timedOutAt;
17964 startTimeMs = expirationTimeToMs(timedOutAt);
17965 // Do not search any further.
17966 break;
17967 }
17968 }
17969 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
17970 if (typeof timeoutPropMs === 'number') {
17971 if (timeoutPropMs <= 0) {
17972 earliestTimeoutMs = 0;
17973 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
17974 earliestTimeoutMs = timeoutPropMs;
17975 }
17976 }
17977 }
17978 // If there is a DehydratedSuspenseComponent we don't have to do anything because
17979 // if something suspends inside it, we will simply leave that as dehydrated. It
17980 // will never timeout.
17981 _workInProgress = _workInProgress.return;
17982 } while (_workInProgress !== null);
17983
17984 // Schedule the nearest Suspense to re-render the timed out view.
17985 _workInProgress = returnFiber;
17986 do {
17987 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
17988 // Found the nearest boundary.
17989
17990 // Stash the promise on the boundary fiber. If the boundary times out, we'll
17991 var thenables = _workInProgress.updateQueue;
17992 if (thenables === null) {
17993 var updateQueue = new Set();
17994 updateQueue.add(thenable);
17995 _workInProgress.updateQueue = updateQueue;
17996 } else {
17997 thenables.add(thenable);
17998 }
17999
18000 // If the boundary is outside of concurrent mode, we should *not*
18001 // suspend the commit. Pretend as if the suspended component rendered
18002 // null and keep rendering. In the commit phase, we'll schedule a
18003 // subsequent synchronous update to re-render the Suspense.
18004 //
18005 // Note: It doesn't matter whether the component that suspended was
18006 // inside a concurrent mode tree. If the Suspense is outside of it, we
18007 // should *not* suspend the commit.
18008 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
18009 _workInProgress.effectTag |= DidCapture;
18010
18011 // We're going to commit this fiber even though it didn't complete.
18012 // But we shouldn't call any lifecycle methods or callbacks. Remove
18013 // all lifecycle effect tags.
18014 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
18015
18016 if (sourceFiber.tag === ClassComponent) {
18017 var currentSourceFiber = sourceFiber.alternate;
18018 if (currentSourceFiber === null) {
18019 // This is a new mount. Change the tag so it's not mistaken for a
18020 // completed class component. For example, we should not call
18021 // componentWillUnmount if it is deleted.
18022 sourceFiber.tag = IncompleteClassComponent;
18023 } else {
18024 // When we try rendering again, we should not reuse the current fiber,
18025 // since it's known to be in an inconsistent state. Use a force updte to
18026 // prevent a bail out.
18027 var update = createUpdate(Sync);
18028 update.tag = ForceUpdate;
18029 enqueueUpdate(sourceFiber, update);
18030 }
18031 }
18032
18033 // The source fiber did not complete. Mark it with Sync priority to
18034 // indicate that it still has pending work.
18035 sourceFiber.expirationTime = Sync;
18036
18037 // Exit without suspending.
18038 return;
18039 }
18040
18041 // Confirmed that the boundary is in a concurrent mode tree. Continue
18042 // with the normal suspend path.
18043
18044 attachPingListener(root, renderExpirationTime, thenable);
18045
18046 var absoluteTimeoutMs = void 0;
18047 if (earliestTimeoutMs === -1) {
18048 // If no explicit threshold is given, default to an arbitrarily large
18049 // value. The actual size doesn't matter because the threshold for the
18050 // whole tree will be clamped to the expiration time.
18051 absoluteTimeoutMs = maxSigned31BitInt;
18052 } else {
18053 if (startTimeMs === -1) {
18054 // This suspend happened outside of any already timed-out
18055 // placeholders. We don't know exactly when the update was
18056 // scheduled, but we can infer an approximate start time from the
18057 // expiration time. First, find the earliest uncommitted expiration
18058 // time in the tree, including work that is suspended. Then subtract
18059 // the offset used to compute an async update's expiration time.
18060 // This will cause high priority (interactive) work to expire
18061 // earlier than necessary, but we can account for this by adjusting
18062 // for the Just Noticeable Difference.
18063 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
18064 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
18065 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
18066 }
18067 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
18068 }
18069
18070 // Mark the earliest timeout in the suspended fiber's ancestor path.
18071 // After completing the root, we'll take the largest of all the
18072 // suspended fiber's timeouts and use it to compute a timeout for the
18073 // whole tree.
18074 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
18075
18076 _workInProgress.effectTag |= ShouldCapture;
18077 _workInProgress.expirationTime = renderExpirationTime;
18078 return;
18079 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
18080 attachPingListener(root, renderExpirationTime, thenable);
18081
18082 // Since we already have a current fiber, we can eagerly add a retry listener.
18083 var retryCache = _workInProgress.memoizedState;
18084 if (retryCache === null) {
18085 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
18086 var _current = _workInProgress.alternate;
18087 !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
18088 _current.memoizedState = retryCache;
18089 }
18090 // Memoize using the boundary fiber to prevent redundant listeners.
18091 if (!retryCache.has(thenable)) {
18092 retryCache.add(thenable);
18093 var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
18094 if (enableSchedulerTracing) {
18095 retry = tracing.unstable_wrap(retry);
18096 }
18097 thenable.then(retry, retry);
18098 }
18099 _workInProgress.effectTag |= ShouldCapture;
18100 _workInProgress.expirationTime = renderExpirationTime;
18101 return;
18102 }
18103 // This boundary already captured during this render. Continue to the next
18104 // boundary.
18105 _workInProgress = _workInProgress.return;
18106 } while (_workInProgress !== null);
18107 // No boundary was found. Fallthrough to error mode.
18108 // TODO: Use invariant so the message is stripped in prod?
18109 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));
18110 }
18111
18112 // We didn't find a boundary that could handle this type of exception. Start
18113 // over and traverse parent path again, this time treating the exception
18114 // as an error.
18115 renderDidError();
18116 value = createCapturedValue(value, sourceFiber);
18117 var workInProgress = returnFiber;
18118 do {
18119 switch (workInProgress.tag) {
18120 case HostRoot:
18121 {
18122 var _errorInfo = value;
18123 workInProgress.effectTag |= ShouldCapture;
18124 workInProgress.expirationTime = renderExpirationTime;
18125 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
18126 enqueueCapturedUpdate(workInProgress, _update);
18127 return;
18128 }
18129 case ClassComponent:
18130 // Capture and retry
18131 var errorInfo = value;
18132 var ctor = workInProgress.type;
18133 var instance = workInProgress.stateNode;
18134 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
18135 workInProgress.effectTag |= ShouldCapture;
18136 workInProgress.expirationTime = renderExpirationTime;
18137 // Schedule the error boundary to re-render using updated state
18138 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
18139 enqueueCapturedUpdate(workInProgress, _update2);
18140 return;
18141 }
18142 break;
18143 default:
18144 break;
18145 }
18146 workInProgress = workInProgress.return;
18147 } while (workInProgress !== null);
18148}
18149
18150function unwindWork(workInProgress, renderExpirationTime) {
18151 switch (workInProgress.tag) {
18152 case ClassComponent:
18153 {
18154 var Component = workInProgress.type;
18155 if (isContextProvider(Component)) {
18156 popContext(workInProgress);
18157 }
18158 var effectTag = workInProgress.effectTag;
18159 if (effectTag & ShouldCapture) {
18160 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
18161 return workInProgress;
18162 }
18163 return null;
18164 }
18165 case HostRoot:
18166 {
18167 popHostContainer(workInProgress);
18168 popTopLevelContextObject(workInProgress);
18169 var _effectTag = workInProgress.effectTag;
18170 !((_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;
18171 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
18172 return workInProgress;
18173 }
18174 case HostComponent:
18175 {
18176 // TODO: popHydrationState
18177 popHostContext(workInProgress);
18178 return null;
18179 }
18180 case SuspenseComponent:
18181 {
18182 var _effectTag2 = workInProgress.effectTag;
18183 if (_effectTag2 & ShouldCapture) {
18184 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
18185 // Captured a suspense effect. Re-render the boundary.
18186 return workInProgress;
18187 }
18188 return null;
18189 }
18190 case DehydratedSuspenseComponent:
18191 {
18192 if (enableSuspenseServerRenderer) {
18193 // TODO: popHydrationState
18194 var _effectTag3 = workInProgress.effectTag;
18195 if (_effectTag3 & ShouldCapture) {
18196 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
18197 // Captured a suspense effect. Re-render the boundary.
18198 return workInProgress;
18199 }
18200 }
18201 return null;
18202 }
18203 case HostPortal:
18204 popHostContainer(workInProgress);
18205 return null;
18206 case ContextProvider:
18207 popProvider(workInProgress);
18208 return null;
18209 default:
18210 return null;
18211 }
18212}
18213
18214function unwindInterruptedWork(interruptedWork) {
18215 switch (interruptedWork.tag) {
18216 case ClassComponent:
18217 {
18218 var childContextTypes = interruptedWork.type.childContextTypes;
18219 if (childContextTypes !== null && childContextTypes !== undefined) {
18220 popContext(interruptedWork);
18221 }
18222 break;
18223 }
18224 case HostRoot:
18225 {
18226 popHostContainer(interruptedWork);
18227 popTopLevelContextObject(interruptedWork);
18228 break;
18229 }
18230 case HostComponent:
18231 {
18232 popHostContext(interruptedWork);
18233 break;
18234 }
18235 case HostPortal:
18236 popHostContainer(interruptedWork);
18237 break;
18238 case ContextProvider:
18239 popProvider(interruptedWork);
18240 break;
18241 default:
18242 break;
18243 }
18244}
18245
18246var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
18247var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
18248
18249
18250var didWarnAboutStateTransition = void 0;
18251var didWarnSetStateChildContext = void 0;
18252var warnAboutUpdateOnUnmounted = void 0;
18253var warnAboutInvalidUpdates = void 0;
18254
18255if (enableSchedulerTracing) {
18256 // Provide explicit error message when production+profiling bundle of e.g. react-dom
18257 // is used with production (non-profiling) bundle of scheduler/tracing
18258 !(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;
18259}
18260
18261{
18262 didWarnAboutStateTransition = false;
18263 didWarnSetStateChildContext = false;
18264 var didWarnStateUpdateForUnmountedComponent = {};
18265
18266 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
18267 // We show the whole stack but dedupe on the top component's name because
18268 // the problematic code almost always lies inside that component.
18269 var componentName = getComponentName(fiber.type) || 'ReactComponent';
18270 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
18271 return;
18272 }
18273 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));
18274 didWarnStateUpdateForUnmountedComponent[componentName] = true;
18275 };
18276
18277 warnAboutInvalidUpdates = function (instance) {
18278 switch (phase) {
18279 case 'getChildContext':
18280 if (didWarnSetStateChildContext) {
18281 return;
18282 }
18283 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
18284 didWarnSetStateChildContext = true;
18285 break;
18286 case 'render':
18287 if (didWarnAboutStateTransition) {
18288 return;
18289 }
18290 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.');
18291 didWarnAboutStateTransition = true;
18292 break;
18293 }
18294 };
18295}
18296
18297// Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
18298var lastUniqueAsyncExpiration = Sync - 1;
18299
18300var isWorking = false;
18301
18302// The next work in progress fiber that we're currently working on.
18303var nextUnitOfWork = null;
18304var nextRoot = null;
18305// The time at which we're currently rendering work.
18306var nextRenderExpirationTime = NoWork;
18307var nextLatestAbsoluteTimeoutMs = -1;
18308var nextRenderDidError = false;
18309
18310// The next fiber with an effect that we're currently committing.
18311var nextEffect = null;
18312
18313var isCommitting$1 = false;
18314var rootWithPendingPassiveEffects = null;
18315var passiveEffectCallbackHandle = null;
18316var passiveEffectCallback = null;
18317
18318var legacyErrorBoundariesThatAlreadyFailed = null;
18319
18320// Used for performance tracking.
18321var interruptedBy = null;
18322
18323var stashedWorkInProgressProperties = void 0;
18324var replayUnitOfWork = void 0;
18325var mayReplayFailedUnitOfWork = void 0;
18326var isReplayingFailedUnitOfWork = void 0;
18327var originalReplayError = void 0;
18328var rethrowOriginalError = void 0;
18329if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18330 stashedWorkInProgressProperties = null;
18331 mayReplayFailedUnitOfWork = true;
18332 isReplayingFailedUnitOfWork = false;
18333 originalReplayError = null;
18334 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
18335 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
18336 // Don't replay promises. Treat everything else like an error.
18337 // TODO: Need to figure out a different strategy if/when we add
18338 // support for catching other types.
18339 return;
18340 }
18341
18342 // Restore the original state of the work-in-progress
18343 if (stashedWorkInProgressProperties === null) {
18344 // This should never happen. Don't throw because this code is DEV-only.
18345 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
18346 return;
18347 }
18348 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
18349
18350 switch (failedUnitOfWork.tag) {
18351 case HostRoot:
18352 popHostContainer(failedUnitOfWork);
18353 popTopLevelContextObject(failedUnitOfWork);
18354 break;
18355 case HostComponent:
18356 popHostContext(failedUnitOfWork);
18357 break;
18358 case ClassComponent:
18359 {
18360 var Component = failedUnitOfWork.type;
18361 if (isContextProvider(Component)) {
18362 popContext(failedUnitOfWork);
18363 }
18364 break;
18365 }
18366 case HostPortal:
18367 popHostContainer(failedUnitOfWork);
18368 break;
18369 case ContextProvider:
18370 popProvider(failedUnitOfWork);
18371 break;
18372 }
18373 // Replay the begin phase.
18374 isReplayingFailedUnitOfWork = true;
18375 originalReplayError = thrownValue;
18376 invokeGuardedCallback(null, workLoop, null, isYieldy);
18377 isReplayingFailedUnitOfWork = false;
18378 originalReplayError = null;
18379 if (hasCaughtError()) {
18380 var replayError = clearCaughtError();
18381 if (replayError != null && thrownValue != null) {
18382 try {
18383 // Reading the expando property is intentionally
18384 // inside `try` because it might be a getter or Proxy.
18385 if (replayError._suppressLogging) {
18386 // Also suppress logging for the original error.
18387 thrownValue._suppressLogging = true;
18388 }
18389 } catch (inner) {
18390 // Ignore.
18391 }
18392 }
18393 } else {
18394 // If the begin phase did not fail the second time, set this pointer
18395 // back to the original value.
18396 nextUnitOfWork = failedUnitOfWork;
18397 }
18398 };
18399 rethrowOriginalError = function () {
18400 throw originalReplayError;
18401 };
18402}
18403
18404function resetStack() {
18405 if (nextUnitOfWork !== null) {
18406 var interruptedWork = nextUnitOfWork.return;
18407 while (interruptedWork !== null) {
18408 unwindInterruptedWork(interruptedWork);
18409 interruptedWork = interruptedWork.return;
18410 }
18411 }
18412
18413 {
18414 ReactStrictModeWarnings.discardPendingWarnings();
18415 checkThatStackIsEmpty();
18416 }
18417
18418 nextRoot = null;
18419 nextRenderExpirationTime = NoWork;
18420 nextLatestAbsoluteTimeoutMs = -1;
18421 nextRenderDidError = false;
18422 nextUnitOfWork = null;
18423}
18424
18425function commitAllHostEffects() {
18426 while (nextEffect !== null) {
18427 {
18428 setCurrentFiber(nextEffect);
18429 }
18430 recordEffect();
18431
18432 var effectTag = nextEffect.effectTag;
18433
18434 if (effectTag & ContentReset) {
18435 commitResetTextContent(nextEffect);
18436 }
18437
18438 if (effectTag & Ref) {
18439 var current$$1 = nextEffect.alternate;
18440 if (current$$1 !== null) {
18441 commitDetachRef(current$$1);
18442 }
18443 }
18444
18445 // The following switch statement is only concerned about placement,
18446 // updates, and deletions. To avoid needing to add a case for every
18447 // possible bitmap value, we remove the secondary effects from the
18448 // effect tag and switch on that value.
18449 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
18450 switch (primaryEffectTag) {
18451 case Placement:
18452 {
18453 commitPlacement(nextEffect);
18454 // Clear the "placement" from effect tag so that we know that this is inserted, before
18455 // any life-cycles like componentDidMount gets called.
18456 // TODO: findDOMNode doesn't rely on this any more but isMounted
18457 // does and isMounted is deprecated anyway so we should be able
18458 // to kill this.
18459 nextEffect.effectTag &= ~Placement;
18460 break;
18461 }
18462 case PlacementAndUpdate:
18463 {
18464 // Placement
18465 commitPlacement(nextEffect);
18466 // Clear the "placement" from effect tag so that we know that this is inserted, before
18467 // any life-cycles like componentDidMount gets called.
18468 nextEffect.effectTag &= ~Placement;
18469
18470 // Update
18471 var _current = nextEffect.alternate;
18472 commitWork(_current, nextEffect);
18473 break;
18474 }
18475 case Update:
18476 {
18477 var _current2 = nextEffect.alternate;
18478 commitWork(_current2, nextEffect);
18479 break;
18480 }
18481 case Deletion:
18482 {
18483 commitDeletion(nextEffect);
18484 break;
18485 }
18486 }
18487 nextEffect = nextEffect.nextEffect;
18488 }
18489
18490 {
18491 resetCurrentFiber();
18492 }
18493}
18494
18495function commitBeforeMutationLifecycles() {
18496 while (nextEffect !== null) {
18497 {
18498 setCurrentFiber(nextEffect);
18499 }
18500
18501 var effectTag = nextEffect.effectTag;
18502 if (effectTag & Snapshot) {
18503 recordEffect();
18504 var current$$1 = nextEffect.alternate;
18505 commitBeforeMutationLifeCycles(current$$1, nextEffect);
18506 }
18507
18508 nextEffect = nextEffect.nextEffect;
18509 }
18510
18511 {
18512 resetCurrentFiber();
18513 }
18514}
18515
18516function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
18517 {
18518 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
18519 ReactStrictModeWarnings.flushLegacyContextWarning();
18520
18521 if (warnAboutDeprecatedLifecycles) {
18522 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
18523 }
18524 }
18525 while (nextEffect !== null) {
18526 {
18527 setCurrentFiber(nextEffect);
18528 }
18529 var effectTag = nextEffect.effectTag;
18530
18531 if (effectTag & (Update | Callback)) {
18532 recordEffect();
18533 var current$$1 = nextEffect.alternate;
18534 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime);
18535 }
18536
18537 if (effectTag & Ref) {
18538 recordEffect();
18539 commitAttachRef(nextEffect);
18540 }
18541
18542 if (effectTag & Passive) {
18543 rootWithPendingPassiveEffects = finishedRoot;
18544 }
18545
18546 nextEffect = nextEffect.nextEffect;
18547 }
18548 {
18549 resetCurrentFiber();
18550 }
18551}
18552
18553function commitPassiveEffects(root, firstEffect) {
18554 rootWithPendingPassiveEffects = null;
18555 passiveEffectCallbackHandle = null;
18556 passiveEffectCallback = null;
18557
18558 // Set this to true to prevent re-entrancy
18559 var previousIsRendering = isRendering;
18560 isRendering = true;
18561
18562 var effect = firstEffect;
18563 do {
18564 {
18565 setCurrentFiber(effect);
18566 }
18567
18568 if (effect.effectTag & Passive) {
18569 var didError = false;
18570 var error = void 0;
18571 {
18572 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
18573 if (hasCaughtError()) {
18574 didError = true;
18575 error = clearCaughtError();
18576 }
18577 }
18578 if (didError) {
18579 captureCommitPhaseError(effect, error);
18580 }
18581 }
18582 effect = effect.nextEffect;
18583 } while (effect !== null);
18584 {
18585 resetCurrentFiber();
18586 }
18587
18588 isRendering = previousIsRendering;
18589
18590 // Check if work was scheduled by one of the effects
18591 var rootExpirationTime = root.expirationTime;
18592 if (rootExpirationTime !== NoWork) {
18593 requestWork(root, rootExpirationTime);
18594 }
18595 // Flush any sync work that was scheduled by effects
18596 if (!isBatchingUpdates && !isRendering) {
18597 performSyncWork();
18598 }
18599}
18600
18601function isAlreadyFailedLegacyErrorBoundary(instance) {
18602 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
18603}
18604
18605function markLegacyErrorBoundaryAsFailed(instance) {
18606 if (legacyErrorBoundariesThatAlreadyFailed === null) {
18607 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
18608 } else {
18609 legacyErrorBoundariesThatAlreadyFailed.add(instance);
18610 }
18611}
18612
18613function flushPassiveEffects() {
18614 if (passiveEffectCallbackHandle !== null) {
18615 cancelPassiveEffects(passiveEffectCallbackHandle);
18616 }
18617 if (passiveEffectCallback !== null) {
18618 // We call the scheduled callback instead of commitPassiveEffects directly
18619 // to ensure tracing works correctly.
18620 passiveEffectCallback();
18621 }
18622}
18623
18624function commitRoot(root, finishedWork) {
18625 isWorking = true;
18626 isCommitting$1 = true;
18627 startCommitTimer();
18628
18629 !(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;
18630 var committedExpirationTime = root.pendingCommitExpirationTime;
18631 !(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;
18632 root.pendingCommitExpirationTime = NoWork;
18633
18634 // Update the pending priority levels to account for the work that we are
18635 // about to commit. This needs to happen before calling the lifecycles, since
18636 // they may schedule additional updates.
18637 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
18638 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
18639 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
18640 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
18641
18642 var prevInteractions = null;
18643 if (enableSchedulerTracing) {
18644 // Restore any pending interactions at this point,
18645 // So that cascading work triggered during the render phase will be accounted for.
18646 prevInteractions = tracing.__interactionsRef.current;
18647 tracing.__interactionsRef.current = root.memoizedInteractions;
18648 }
18649
18650 // Reset this to null before calling lifecycles
18651 ReactCurrentOwner$2.current = null;
18652
18653 var firstEffect = void 0;
18654 if (finishedWork.effectTag > PerformedWork) {
18655 // A fiber's effect list consists only of its children, not itself. So if
18656 // the root has an effect, we need to add it to the end of the list. The
18657 // resulting list is the set that would belong to the root's parent, if
18658 // it had one; that is, all the effects in the tree including the root.
18659 if (finishedWork.lastEffect !== null) {
18660 finishedWork.lastEffect.nextEffect = finishedWork;
18661 firstEffect = finishedWork.firstEffect;
18662 } else {
18663 firstEffect = finishedWork;
18664 }
18665 } else {
18666 // There is no effect on the root.
18667 firstEffect = finishedWork.firstEffect;
18668 }
18669
18670 prepareForCommit(root.containerInfo);
18671
18672 // Invoke instances of getSnapshotBeforeUpdate before mutation.
18673 nextEffect = firstEffect;
18674 startCommitSnapshotEffectsTimer();
18675 while (nextEffect !== null) {
18676 var didError = false;
18677 var error = void 0;
18678 {
18679 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
18680 if (hasCaughtError()) {
18681 didError = true;
18682 error = clearCaughtError();
18683 }
18684 }
18685 if (didError) {
18686 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18687 captureCommitPhaseError(nextEffect, error);
18688 // Clean-up
18689 if (nextEffect !== null) {
18690 nextEffect = nextEffect.nextEffect;
18691 }
18692 }
18693 }
18694 stopCommitSnapshotEffectsTimer();
18695
18696 if (enableProfilerTimer) {
18697 // Mark the current commit time to be shared by all Profilers in this batch.
18698 // This enables them to be grouped later.
18699 recordCommitTime();
18700 }
18701
18702 // Commit all the side-effects within a tree. We'll do this in two passes.
18703 // The first pass performs all the host insertions, updates, deletions and
18704 // ref unmounts.
18705 nextEffect = firstEffect;
18706 startCommitHostEffectsTimer();
18707 while (nextEffect !== null) {
18708 var _didError = false;
18709 var _error = void 0;
18710 {
18711 invokeGuardedCallback(null, commitAllHostEffects, null);
18712 if (hasCaughtError()) {
18713 _didError = true;
18714 _error = clearCaughtError();
18715 }
18716 }
18717 if (_didError) {
18718 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18719 captureCommitPhaseError(nextEffect, _error);
18720 // Clean-up
18721 if (nextEffect !== null) {
18722 nextEffect = nextEffect.nextEffect;
18723 }
18724 }
18725 }
18726 stopCommitHostEffectsTimer();
18727
18728 resetAfterCommit(root.containerInfo);
18729
18730 // The work-in-progress tree is now the current tree. This must come after
18731 // the first pass of the commit phase, so that the previous tree is still
18732 // current during componentWillUnmount, but before the second pass, so that
18733 // the finished work is current during componentDidMount/Update.
18734 root.current = finishedWork;
18735
18736 // In the second pass we'll perform all life-cycles and ref callbacks.
18737 // Life-cycles happen as a separate pass so that all placements, updates,
18738 // and deletions in the entire tree have already been invoked.
18739 // This pass also triggers any renderer-specific initial effects.
18740 nextEffect = firstEffect;
18741 startCommitLifeCyclesTimer();
18742 while (nextEffect !== null) {
18743 var _didError2 = false;
18744 var _error2 = void 0;
18745 {
18746 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
18747 if (hasCaughtError()) {
18748 _didError2 = true;
18749 _error2 = clearCaughtError();
18750 }
18751 }
18752 if (_didError2) {
18753 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
18754 captureCommitPhaseError(nextEffect, _error2);
18755 if (nextEffect !== null) {
18756 nextEffect = nextEffect.nextEffect;
18757 }
18758 }
18759 }
18760
18761 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
18762 // This commit included a passive effect. These do not need to fire until
18763 // after the next paint. Schedule an callback to fire them in an async
18764 // event. To ensure serial execution, the callback will be flushed early if
18765 // we enter rootWithPendingPassiveEffects commit phase before then.
18766 var callback = commitPassiveEffects.bind(null, root, firstEffect);
18767 if (enableSchedulerTracing) {
18768 // TODO: Avoid this extra callback by mutating the tracing ref directly,
18769 // like we do at the beginning of commitRoot. I've opted not to do that
18770 // here because that code is still in flux.
18771 callback = tracing.unstable_wrap(callback);
18772 }
18773 passiveEffectCallbackHandle = scheduler.unstable_runWithPriority(scheduler.unstable_NormalPriority, function () {
18774 return schedulePassiveEffects(callback);
18775 });
18776 passiveEffectCallback = callback;
18777 }
18778
18779 isCommitting$1 = false;
18780 isWorking = false;
18781 stopCommitLifeCyclesTimer();
18782 stopCommitTimer();
18783 onCommitRoot(finishedWork.stateNode);
18784 if (true && ReactFiberInstrumentation_1.debugTool) {
18785 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
18786 }
18787
18788 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
18789 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
18790 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
18791 if (earliestRemainingTimeAfterCommit === NoWork) {
18792 // If there's no remaining work, we can clear the set of already failed
18793 // error boundaries.
18794 legacyErrorBoundariesThatAlreadyFailed = null;
18795 }
18796 onCommit(root, earliestRemainingTimeAfterCommit);
18797
18798 if (enableSchedulerTracing) {
18799 tracing.__interactionsRef.current = prevInteractions;
18800
18801 var subscriber = void 0;
18802
18803 try {
18804 subscriber = tracing.__subscriberRef.current;
18805 if (subscriber !== null && root.memoizedInteractions.size > 0) {
18806 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
18807 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
18808 }
18809 } catch (error) {
18810 // It's not safe for commitRoot() to throw.
18811 // Store the error for now and we'll re-throw in finishRendering().
18812 if (!hasUnhandledError) {
18813 hasUnhandledError = true;
18814 unhandledError = error;
18815 }
18816 } finally {
18817 // Clear completed interactions from the pending Map.
18818 // Unless the render was suspended or cascading work was scheduled,
18819 // In which case– leave pending interactions until the subsequent render.
18820 var pendingInteractionMap = root.pendingInteractionMap;
18821 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
18822 // Only decrement the pending interaction count if we're done.
18823 // If there's still work at the current priority,
18824 // That indicates that we are waiting for suspense data.
18825 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
18826 pendingInteractionMap.delete(scheduledExpirationTime);
18827
18828 scheduledInteractions.forEach(function (interaction) {
18829 interaction.__count--;
18830
18831 if (subscriber !== null && interaction.__count === 0) {
18832 try {
18833 subscriber.onInteractionScheduledWorkCompleted(interaction);
18834 } catch (error) {
18835 // It's not safe for commitRoot() to throw.
18836 // Store the error for now and we'll re-throw in finishRendering().
18837 if (!hasUnhandledError) {
18838 hasUnhandledError = true;
18839 unhandledError = error;
18840 }
18841 }
18842 }
18843 });
18844 }
18845 });
18846 }
18847 }
18848}
18849
18850function resetChildExpirationTime(workInProgress, renderTime) {
18851 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
18852 // The children of this component are hidden. Don't bubble their
18853 // expiration times.
18854 return;
18855 }
18856
18857 var newChildExpirationTime = NoWork;
18858
18859 // Bubble up the earliest expiration time.
18860 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
18861 // We're in profiling mode.
18862 // Let's use this same traversal to update the render durations.
18863 var actualDuration = workInProgress.actualDuration;
18864 var treeBaseDuration = workInProgress.selfBaseDuration;
18865
18866 // When a fiber is cloned, its actualDuration is reset to 0.
18867 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
18868 // When work is done, it should bubble to the parent's actualDuration.
18869 // If the fiber has not been cloned though, (meaning no work was done),
18870 // Then this value will reflect the amount of time spent working on a previous render.
18871 // In that case it should not bubble.
18872 // We determine whether it was cloned by comparing the child pointer.
18873 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
18874
18875 var child = workInProgress.child;
18876 while (child !== null) {
18877 var childUpdateExpirationTime = child.expirationTime;
18878 var childChildExpirationTime = child.childExpirationTime;
18879 if (childUpdateExpirationTime > newChildExpirationTime) {
18880 newChildExpirationTime = childUpdateExpirationTime;
18881 }
18882 if (childChildExpirationTime > newChildExpirationTime) {
18883 newChildExpirationTime = childChildExpirationTime;
18884 }
18885 if (shouldBubbleActualDurations) {
18886 actualDuration += child.actualDuration;
18887 }
18888 treeBaseDuration += child.treeBaseDuration;
18889 child = child.sibling;
18890 }
18891 workInProgress.actualDuration = actualDuration;
18892 workInProgress.treeBaseDuration = treeBaseDuration;
18893 } else {
18894 var _child = workInProgress.child;
18895 while (_child !== null) {
18896 var _childUpdateExpirationTime = _child.expirationTime;
18897 var _childChildExpirationTime = _child.childExpirationTime;
18898 if (_childUpdateExpirationTime > newChildExpirationTime) {
18899 newChildExpirationTime = _childUpdateExpirationTime;
18900 }
18901 if (_childChildExpirationTime > newChildExpirationTime) {
18902 newChildExpirationTime = _childChildExpirationTime;
18903 }
18904 _child = _child.sibling;
18905 }
18906 }
18907
18908 workInProgress.childExpirationTime = newChildExpirationTime;
18909}
18910
18911function completeUnitOfWork(workInProgress) {
18912 // Attempt to complete the current unit of work, then move to the
18913 // next sibling. If there are no more siblings, return to the
18914 // parent fiber.
18915 while (true) {
18916 // The current, flushed, state of this fiber is the alternate.
18917 // Ideally nothing should rely on this, but relying on it here
18918 // means that we don't need an additional field on the work in
18919 // progress.
18920 var current$$1 = workInProgress.alternate;
18921 {
18922 setCurrentFiber(workInProgress);
18923 }
18924
18925 var returnFiber = workInProgress.return;
18926 var siblingFiber = workInProgress.sibling;
18927
18928 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
18929 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18930 // Don't replay if it fails during completion phase.
18931 mayReplayFailedUnitOfWork = false;
18932 }
18933 // This fiber completed.
18934 // Remember we're completing this unit so we can find a boundary if it fails.
18935 nextUnitOfWork = workInProgress;
18936 if (enableProfilerTimer) {
18937 if (workInProgress.mode & ProfileMode) {
18938 startProfilerTimer(workInProgress);
18939 }
18940 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18941 if (workInProgress.mode & ProfileMode) {
18942 // Update render duration assuming we didn't error.
18943 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
18944 }
18945 } else {
18946 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime);
18947 }
18948 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
18949 // We're out of completion phase so replaying is fine now.
18950 mayReplayFailedUnitOfWork = true;
18951 }
18952 stopWorkTimer(workInProgress);
18953 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
18954 {
18955 resetCurrentFiber();
18956 }
18957
18958 if (nextUnitOfWork !== null) {
18959 // Completing this fiber spawned new work. Work on that next.
18960 return nextUnitOfWork;
18961 }
18962
18963 if (returnFiber !== null &&
18964 // Do not append effects to parents if a sibling failed to complete
18965 (returnFiber.effectTag & Incomplete) === NoEffect) {
18966 // Append all the effects of the subtree and this fiber onto the effect
18967 // list of the parent. The completion order of the children affects the
18968 // side-effect order.
18969 if (returnFiber.firstEffect === null) {
18970 returnFiber.firstEffect = workInProgress.firstEffect;
18971 }
18972 if (workInProgress.lastEffect !== null) {
18973 if (returnFiber.lastEffect !== null) {
18974 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
18975 }
18976 returnFiber.lastEffect = workInProgress.lastEffect;
18977 }
18978
18979 // If this fiber had side-effects, we append it AFTER the children's
18980 // side-effects. We can perform certain side-effects earlier if
18981 // needed, by doing multiple passes over the effect list. We don't want
18982 // to schedule our own side-effect on our own list because if end up
18983 // reusing children we'll schedule this effect onto itself since we're
18984 // at the end.
18985 var effectTag = workInProgress.effectTag;
18986 // Skip both NoWork and PerformedWork tags when creating the effect list.
18987 // PerformedWork effect is read by React DevTools but shouldn't be committed.
18988 if (effectTag > PerformedWork) {
18989 if (returnFiber.lastEffect !== null) {
18990 returnFiber.lastEffect.nextEffect = workInProgress;
18991 } else {
18992 returnFiber.firstEffect = workInProgress;
18993 }
18994 returnFiber.lastEffect = workInProgress;
18995 }
18996 }
18997
18998 if (true && ReactFiberInstrumentation_1.debugTool) {
18999 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19000 }
19001
19002 if (siblingFiber !== null) {
19003 // If there is more work to do in this returnFiber, do that next.
19004 return siblingFiber;
19005 } else if (returnFiber !== null) {
19006 // If there's no more work in this returnFiber. Complete the returnFiber.
19007 workInProgress = returnFiber;
19008 continue;
19009 } else {
19010 // We've reached the root.
19011 return null;
19012 }
19013 } else {
19014 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19015 // Record the render duration for the fiber that errored.
19016 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
19017
19018 // Include the time spent working on failed children before continuing.
19019 var actualDuration = workInProgress.actualDuration;
19020 var child = workInProgress.child;
19021 while (child !== null) {
19022 actualDuration += child.actualDuration;
19023 child = child.sibling;
19024 }
19025 workInProgress.actualDuration = actualDuration;
19026 }
19027
19028 // This fiber did not complete because something threw. Pop values off
19029 // the stack without entering the complete phase. If this is a boundary,
19030 // capture values if possible.
19031 var next = unwindWork(workInProgress, nextRenderExpirationTime);
19032 // Because this fiber did not complete, don't reset its expiration time.
19033 if (workInProgress.effectTag & DidCapture) {
19034 // Restarting an error boundary
19035 stopFailedWorkTimer(workInProgress);
19036 } else {
19037 stopWorkTimer(workInProgress);
19038 }
19039
19040 {
19041 resetCurrentFiber();
19042 }
19043
19044 if (next !== null) {
19045 stopWorkTimer(workInProgress);
19046 if (true && ReactFiberInstrumentation_1.debugTool) {
19047 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19048 }
19049
19050 // If completing this work spawned new work, do that next. We'll come
19051 // back here again.
19052 // Since we're restarting, remove anything that is not a host effect
19053 // from the effect tag.
19054 next.effectTag &= HostEffectMask;
19055 return next;
19056 }
19057
19058 if (returnFiber !== null) {
19059 // Mark the parent fiber as incomplete and clear its effect list.
19060 returnFiber.firstEffect = returnFiber.lastEffect = null;
19061 returnFiber.effectTag |= Incomplete;
19062 }
19063
19064 if (true && ReactFiberInstrumentation_1.debugTool) {
19065 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
19066 }
19067
19068 if (siblingFiber !== null) {
19069 // If there is more work to do in this returnFiber, do that next.
19070 return siblingFiber;
19071 } else if (returnFiber !== null) {
19072 // If there's no more work in this returnFiber. Complete the returnFiber.
19073 workInProgress = returnFiber;
19074 continue;
19075 } else {
19076 return null;
19077 }
19078 }
19079 }
19080
19081 // Without this explicit null return Flow complains of invalid return type
19082 // TODO Remove the above while(true) loop
19083 // eslint-disable-next-line no-unreachable
19084 return null;
19085}
19086
19087function performUnitOfWork(workInProgress) {
19088 // The current, flushed, state of this fiber is the alternate.
19089 // Ideally nothing should rely on this, but relying on it here
19090 // means that we don't need an additional field on the work in
19091 // progress.
19092 var current$$1 = workInProgress.alternate;
19093
19094 // See if beginning this work spawns more work.
19095 startWorkTimer(workInProgress);
19096 {
19097 setCurrentFiber(workInProgress);
19098 }
19099
19100 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19101 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
19102 }
19103
19104 var next = void 0;
19105 if (enableProfilerTimer) {
19106 if (workInProgress.mode & ProfileMode) {
19107 startProfilerTimer(workInProgress);
19108 }
19109
19110 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
19111 workInProgress.memoizedProps = workInProgress.pendingProps;
19112
19113 if (workInProgress.mode & ProfileMode) {
19114 // Record the render duration assuming we didn't bailout (or error).
19115 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
19116 }
19117 } else {
19118 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime);
19119 workInProgress.memoizedProps = workInProgress.pendingProps;
19120 }
19121
19122 {
19123 resetCurrentFiber();
19124 if (isReplayingFailedUnitOfWork) {
19125 // Currently replaying a failed unit of work. This should be unreachable,
19126 // because the render phase is meant to be idempotent, and it should
19127 // have thrown again. Since it didn't, rethrow the original error, so
19128 // React's internal stack is not misaligned.
19129 rethrowOriginalError();
19130 }
19131 }
19132 if (true && ReactFiberInstrumentation_1.debugTool) {
19133 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
19134 }
19135
19136 if (next === null) {
19137 // If this doesn't spawn new work, complete the current work.
19138 next = completeUnitOfWork(workInProgress);
19139 }
19140
19141 ReactCurrentOwner$2.current = null;
19142
19143 return next;
19144}
19145
19146function workLoop(isYieldy) {
19147 if (!isYieldy) {
19148 // Flush work without yielding
19149 while (nextUnitOfWork !== null) {
19150 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
19151 }
19152 } else {
19153 // Flush asynchronous work until there's a higher priority event
19154 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
19155 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
19156 }
19157 }
19158}
19159
19160function renderRoot(root, isYieldy) {
19161 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
19162
19163 flushPassiveEffects();
19164
19165 isWorking = true;
19166 var previousDispatcher = ReactCurrentDispatcher.current;
19167 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
19168
19169 var expirationTime = root.nextExpirationTimeToWorkOn;
19170
19171 // Check if we're starting from a fresh stack, or if we're resuming from
19172 // previously yielded work.
19173 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
19174 // Reset the stack and start working from the root.
19175 resetStack();
19176 nextRoot = root;
19177 nextRenderExpirationTime = expirationTime;
19178 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
19179 root.pendingCommitExpirationTime = NoWork;
19180
19181 if (enableSchedulerTracing) {
19182 // Determine which interactions this batch of work currently includes,
19183 // So that we can accurately attribute time spent working on it,
19184 var interactions = new Set();
19185 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
19186 if (scheduledExpirationTime >= expirationTime) {
19187 scheduledInteractions.forEach(function (interaction) {
19188 return interactions.add(interaction);
19189 });
19190 }
19191 });
19192
19193 // Store the current set of interactions on the FiberRoot for a few reasons:
19194 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
19195 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
19196 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
19197 root.memoizedInteractions = interactions;
19198
19199 if (interactions.size > 0) {
19200 var subscriber = tracing.__subscriberRef.current;
19201 if (subscriber !== null) {
19202 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19203 try {
19204 subscriber.onWorkStarted(interactions, threadID);
19205 } catch (error) {
19206 // Work thrown by an interaction tracing subscriber should be rethrown,
19207 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
19208 // Store the error for now and we'll re-throw in finishRendering().
19209 if (!hasUnhandledError) {
19210 hasUnhandledError = true;
19211 unhandledError = error;
19212 }
19213 }
19214 }
19215 }
19216 }
19217 }
19218
19219 var prevInteractions = null;
19220 if (enableSchedulerTracing) {
19221 // We're about to start new traced work.
19222 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
19223 prevInteractions = tracing.__interactionsRef.current;
19224 tracing.__interactionsRef.current = root.memoizedInteractions;
19225 }
19226
19227 var didFatal = false;
19228
19229 startWorkLoopTimer(nextUnitOfWork);
19230
19231 do {
19232 try {
19233 workLoop(isYieldy);
19234 } catch (thrownValue) {
19235 resetContextDependences();
19236 resetHooks();
19237
19238 // Reset in case completion throws.
19239 // This is only used in DEV and when replaying is on.
19240 var mayReplay = void 0;
19241 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19242 mayReplay = mayReplayFailedUnitOfWork;
19243 mayReplayFailedUnitOfWork = true;
19244 }
19245
19246 if (nextUnitOfWork === null) {
19247 // This is a fatal error.
19248 didFatal = true;
19249 onUncaughtError(thrownValue);
19250 } else {
19251 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
19252 // Record the time spent rendering before an error was thrown.
19253 // This avoids inaccurate Profiler durations in the case of a suspended render.
19254 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
19255 }
19256
19257 {
19258 // Reset global debug state
19259 // We assume this is defined in DEV
19260 resetCurrentlyProcessingQueue();
19261 }
19262
19263 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
19264 if (mayReplay) {
19265 var failedUnitOfWork = nextUnitOfWork;
19266 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
19267 }
19268 }
19269
19270 // TODO: we already know this isn't true in some cases.
19271 // At least this shows a nicer error message until we figure out the cause.
19272 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
19273 !(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;
19274
19275 var sourceFiber = nextUnitOfWork;
19276 var returnFiber = sourceFiber.return;
19277 if (returnFiber === null) {
19278 // This is the root. The root could capture its own errors. However,
19279 // we don't know if it errors before or after we pushed the host
19280 // context. This information is needed to avoid a stack mismatch.
19281 // Because we're not sure, treat this as a fatal error. We could track
19282 // which phase it fails in, but doesn't seem worth it. At least
19283 // for now.
19284 didFatal = true;
19285 onUncaughtError(thrownValue);
19286 } else {
19287 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
19288 nextUnitOfWork = completeUnitOfWork(sourceFiber);
19289 continue;
19290 }
19291 }
19292 }
19293 break;
19294 } while (true);
19295
19296 if (enableSchedulerTracing) {
19297 // Traced work is done for now; restore the previous interactions.
19298 tracing.__interactionsRef.current = prevInteractions;
19299 }
19300
19301 // We're done performing work. Time to clean up.
19302 isWorking = false;
19303 ReactCurrentDispatcher.current = previousDispatcher;
19304 resetContextDependences();
19305 resetHooks();
19306
19307 // Yield back to main thread.
19308 if (didFatal) {
19309 var _didCompleteRoot = false;
19310 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
19311 interruptedBy = null;
19312 // There was a fatal error.
19313 {
19314 resetStackAfterFatalErrorInDev();
19315 }
19316 // `nextRoot` points to the in-progress root. A non-null value indicates
19317 // that we're in the middle of an async render. Set it to null to indicate
19318 // there's no more work to be done in the current batch.
19319 nextRoot = null;
19320 onFatal(root);
19321 return;
19322 }
19323
19324 if (nextUnitOfWork !== null) {
19325 // There's still remaining async work in this tree, but we ran out of time
19326 // in the current frame. Yield back to the renderer. Unless we're
19327 // interrupted by a higher priority update, we'll continue later from where
19328 // we left off.
19329 var _didCompleteRoot2 = false;
19330 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
19331 interruptedBy = null;
19332 onYield(root);
19333 return;
19334 }
19335
19336 // We completed the whole tree.
19337 var didCompleteRoot = true;
19338 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
19339 var rootWorkInProgress = root.current.alternate;
19340 !(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;
19341
19342 // `nextRoot` points to the in-progress root. A non-null value indicates
19343 // that we're in the middle of an async render. Set it to null to indicate
19344 // there's no more work to be done in the current batch.
19345 nextRoot = null;
19346 interruptedBy = null;
19347
19348 if (nextRenderDidError) {
19349 // There was an error
19350 if (hasLowerPriorityWork(root, expirationTime)) {
19351 // There's lower priority work. If so, it may have the effect of fixing
19352 // the exception that was just thrown. Exit without committing. This is
19353 // similar to a suspend, but without a timeout because we're not waiting
19354 // for a promise to resolve. React will restart at the lower
19355 // priority level.
19356 markSuspendedPriorityLevel(root, expirationTime);
19357 var suspendedExpirationTime = expirationTime;
19358 var rootExpirationTime = root.expirationTime;
19359 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
19360 );
19361 return;
19362 } else if (
19363 // There's no lower priority work, but we're rendering asynchronously.
19364 // Synchronously attempt to render the same level one more time. This is
19365 // similar to a suspend, but without a timeout because we're not waiting
19366 // for a promise to resolve.
19367 !root.didError && isYieldy) {
19368 root.didError = true;
19369 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
19370 var _rootExpirationTime = root.expirationTime = Sync;
19371 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
19372 );
19373 return;
19374 }
19375 }
19376
19377 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
19378 // The tree was suspended.
19379 var _suspendedExpirationTime2 = expirationTime;
19380 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
19381
19382 // Find the earliest uncommitted expiration time in the tree, including
19383 // work that is suspended. The timeout threshold cannot be longer than
19384 // the overall expiration.
19385 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
19386 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
19387 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
19388 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
19389 }
19390
19391 // Subtract the current time from the absolute timeout to get the number
19392 // of milliseconds until the timeout. In other words, convert an absolute
19393 // timestamp to a relative time. This is the value that is passed
19394 // to `setTimeout`.
19395 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
19396 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
19397 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
19398
19399 // TODO: Account for the Just Noticeable Difference
19400
19401 var _rootExpirationTime2 = root.expirationTime;
19402 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
19403 return;
19404 }
19405
19406 // Ready to commit.
19407 onComplete(root, rootWorkInProgress, expirationTime);
19408}
19409
19410function captureCommitPhaseError(sourceFiber, value) {
19411 var expirationTime = Sync;
19412 var fiber = sourceFiber.return;
19413 while (fiber !== null) {
19414 switch (fiber.tag) {
19415 case ClassComponent:
19416 var ctor = fiber.type;
19417 var instance = fiber.stateNode;
19418 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
19419 var errorInfo = createCapturedValue(value, sourceFiber);
19420 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
19421 enqueueUpdate(fiber, update);
19422 scheduleWork(fiber, expirationTime);
19423 return;
19424 }
19425 break;
19426 case HostRoot:
19427 {
19428 var _errorInfo = createCapturedValue(value, sourceFiber);
19429 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
19430 enqueueUpdate(fiber, _update);
19431 scheduleWork(fiber, expirationTime);
19432 return;
19433 }
19434 }
19435 fiber = fiber.return;
19436 }
19437
19438 if (sourceFiber.tag === HostRoot) {
19439 // Error was thrown at the root. There is no parent, so the root
19440 // itself should capture it.
19441 var rootFiber = sourceFiber;
19442 var _errorInfo2 = createCapturedValue(value, rootFiber);
19443 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
19444 enqueueUpdate(rootFiber, _update2);
19445 scheduleWork(rootFiber, expirationTime);
19446 }
19447}
19448
19449function computeThreadID(expirationTime, interactionThreadID) {
19450 // Interaction threads are unique per root and expiration time.
19451 return expirationTime * 1000 + interactionThreadID;
19452}
19453
19454// Creates a unique async expiration time.
19455function computeUniqueAsyncExpiration() {
19456 var currentTime = requestCurrentTime();
19457 var result = computeAsyncExpiration(currentTime);
19458 if (result >= lastUniqueAsyncExpiration) {
19459 // Since we assume the current time monotonically increases, we only hit
19460 // this branch when computeUniqueAsyncExpiration is fired multiple times
19461 // within a 200ms window (or whatever the async bucket size is).
19462 result = lastUniqueAsyncExpiration - 1;
19463 }
19464 lastUniqueAsyncExpiration = result;
19465 return lastUniqueAsyncExpiration;
19466}
19467
19468function computeExpirationForFiber(currentTime, fiber) {
19469 var priorityLevel = scheduler.unstable_getCurrentPriorityLevel();
19470
19471 var expirationTime = void 0;
19472 if ((fiber.mode & ConcurrentMode) === NoContext) {
19473 // Outside of concurrent mode, updates are always synchronous.
19474 expirationTime = Sync;
19475 } else if (isWorking && !isCommitting$1) {
19476 // During render phase, updates expire during as the current render.
19477 expirationTime = nextRenderExpirationTime;
19478 } else {
19479 switch (priorityLevel) {
19480 case scheduler.unstable_ImmediatePriority:
19481 expirationTime = Sync;
19482 break;
19483 case scheduler.unstable_UserBlockingPriority:
19484 expirationTime = computeInteractiveExpiration(currentTime);
19485 break;
19486 case scheduler.unstable_NormalPriority:
19487 // This is a normal, concurrent update
19488 expirationTime = computeAsyncExpiration(currentTime);
19489 break;
19490 case scheduler.unstable_LowPriority:
19491 case scheduler.unstable_IdlePriority:
19492 expirationTime = Never;
19493 break;
19494 default:
19495 invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
19496 }
19497
19498 // If we're in the middle of rendering a tree, do not update at the same
19499 // expiration time that is already rendering.
19500 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19501 expirationTime -= 1;
19502 }
19503 }
19504
19505 // Keep track of the lowest pending interactive expiration time. This
19506 // allows us to synchronously flush all interactive updates
19507 // when needed.
19508 // TODO: Move this to renderer?
19509 if (priorityLevel === scheduler.unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) {
19510 lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19511 }
19512
19513 return expirationTime;
19514}
19515
19516function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
19517 // Schedule the timeout.
19518 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
19519 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
19520 }
19521}
19522
19523function renderDidError() {
19524 nextRenderDidError = true;
19525}
19526
19527function pingSuspendedRoot(root, thenable, pingTime) {
19528 // A promise that previously suspended React from committing has resolved.
19529 // If React is still suspended, try again at the previous level (pingTime).
19530
19531 var pingCache = root.pingCache;
19532 if (pingCache !== null) {
19533 // The thenable resolved, so we no longer need to memoize, because it will
19534 // never be thrown again.
19535 pingCache.delete(thenable);
19536 }
19537
19538 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
19539 // Received a ping at the same priority level at which we're currently
19540 // rendering. Restart from the root.
19541 nextRoot = null;
19542 } else {
19543 // Confirm that the root is still suspended at this level. Otherwise exit.
19544 if (isPriorityLevelSuspended(root, pingTime)) {
19545 // Ping at the original level
19546 markPingedPriorityLevel(root, pingTime);
19547 var rootExpirationTime = root.expirationTime;
19548 if (rootExpirationTime !== NoWork) {
19549 requestWork(root, rootExpirationTime);
19550 }
19551 }
19552 }
19553}
19554
19555function retryTimedOutBoundary(boundaryFiber, thenable) {
19556 // The boundary fiber (a Suspense component) previously timed out and was
19557 // rendered in its fallback state. One of the promises that suspended it has
19558 // resolved, which means at least part of the tree was likely unblocked. Try
19559 var retryCache = void 0;
19560 if (enableSuspenseServerRenderer) {
19561 switch (boundaryFiber.tag) {
19562 case SuspenseComponent:
19563 retryCache = boundaryFiber.stateNode;
19564 break;
19565 case DehydratedSuspenseComponent:
19566 retryCache = boundaryFiber.memoizedState;
19567 break;
19568 default:
19569 invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
19570 }
19571 } else {
19572 retryCache = boundaryFiber.stateNode;
19573 }
19574 if (retryCache !== null) {
19575 // The thenable resolved, so we no longer need to memoize, because it will
19576 // never be thrown again.
19577 retryCache.delete(thenable);
19578 }
19579
19580 var currentTime = requestCurrentTime();
19581 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
19582 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
19583 if (root !== null) {
19584 markPendingPriorityLevel(root, retryTime);
19585 var rootExpirationTime = root.expirationTime;
19586 if (rootExpirationTime !== NoWork) {
19587 requestWork(root, rootExpirationTime);
19588 }
19589 }
19590}
19591
19592function scheduleWorkToRoot(fiber, expirationTime) {
19593 recordScheduleUpdate();
19594
19595 {
19596 if (fiber.tag === ClassComponent) {
19597 var instance = fiber.stateNode;
19598 warnAboutInvalidUpdates(instance);
19599 }
19600 }
19601
19602 // Update the source fiber's expiration time
19603 if (fiber.expirationTime < expirationTime) {
19604 fiber.expirationTime = expirationTime;
19605 }
19606 var alternate = fiber.alternate;
19607 if (alternate !== null && alternate.expirationTime < expirationTime) {
19608 alternate.expirationTime = expirationTime;
19609 }
19610 // Walk the parent path to the root and update the child expiration time.
19611 var node = fiber.return;
19612 var root = null;
19613 if (node === null && fiber.tag === HostRoot) {
19614 root = fiber.stateNode;
19615 } else {
19616 while (node !== null) {
19617 alternate = node.alternate;
19618 if (node.childExpirationTime < expirationTime) {
19619 node.childExpirationTime = expirationTime;
19620 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19621 alternate.childExpirationTime = expirationTime;
19622 }
19623 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
19624 alternate.childExpirationTime = expirationTime;
19625 }
19626 if (node.return === null && node.tag === HostRoot) {
19627 root = node.stateNode;
19628 break;
19629 }
19630 node = node.return;
19631 }
19632 }
19633
19634 if (enableSchedulerTracing) {
19635 if (root !== null) {
19636 var interactions = tracing.__interactionsRef.current;
19637 if (interactions.size > 0) {
19638 var pendingInteractionMap = root.pendingInteractionMap;
19639 var pendingInteractions = pendingInteractionMap.get(expirationTime);
19640 if (pendingInteractions != null) {
19641 interactions.forEach(function (interaction) {
19642 if (!pendingInteractions.has(interaction)) {
19643 // Update the pending async work count for previously unscheduled interaction.
19644 interaction.__count++;
19645 }
19646
19647 pendingInteractions.add(interaction);
19648 });
19649 } else {
19650 pendingInteractionMap.set(expirationTime, new Set(interactions));
19651
19652 // Update the pending async work count for the current interactions.
19653 interactions.forEach(function (interaction) {
19654 interaction.__count++;
19655 });
19656 }
19657
19658 var subscriber = tracing.__subscriberRef.current;
19659 if (subscriber !== null) {
19660 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
19661 subscriber.onWorkScheduled(interactions, threadID);
19662 }
19663 }
19664 }
19665 }
19666 return root;
19667}
19668
19669function warnIfNotCurrentlyBatchingInDev(fiber) {
19670 {
19671 if (isRendering === false && isBatchingUpdates === false) {
19672 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));
19673 }
19674 }
19675}
19676
19677function scheduleWork(fiber, expirationTime) {
19678 var root = scheduleWorkToRoot(fiber, expirationTime);
19679 if (root === null) {
19680 {
19681 switch (fiber.tag) {
19682 case ClassComponent:
19683 warnAboutUpdateOnUnmounted(fiber, true);
19684 break;
19685 case FunctionComponent:
19686 case ForwardRef:
19687 case MemoComponent:
19688 case SimpleMemoComponent:
19689 warnAboutUpdateOnUnmounted(fiber, false);
19690 break;
19691 }
19692 }
19693 return;
19694 }
19695
19696 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
19697 // This is an interruption. (Used for performance tracking.)
19698 interruptedBy = fiber;
19699 resetStack();
19700 }
19701 markPendingPriorityLevel(root, expirationTime);
19702 if (
19703 // If we're in the render phase, we don't need to schedule this root
19704 // for an update, because we'll do it before we exit...
19705 !isWorking || isCommitting$1 ||
19706 // ...unless this is a different root than the one we're rendering.
19707 nextRoot !== root) {
19708 var rootExpirationTime = root.expirationTime;
19709 requestWork(root, rootExpirationTime);
19710 }
19711 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
19712 // Reset this back to zero so subsequent updates don't throw.
19713 nestedUpdateCount = 0;
19714 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.');
19715 }
19716}
19717
19718function syncUpdates(fn, a, b, c, d) {
19719 return scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
19720 return fn(a, b, c, d);
19721 });
19722}
19723
19724// TODO: Everything below this is written as if it has been lifted to the
19725// renderers. I'll do this in a follow-up.
19726
19727// Linked-list of roots
19728var firstScheduledRoot = null;
19729var lastScheduledRoot = null;
19730
19731var callbackExpirationTime = NoWork;
19732var callbackID = void 0;
19733var isRendering = false;
19734var nextFlushedRoot = null;
19735var nextFlushedExpirationTime = NoWork;
19736var lowestPriorityPendingInteractiveExpirationTime = NoWork;
19737var hasUnhandledError = false;
19738var unhandledError = null;
19739
19740var isBatchingUpdates = false;
19741var isUnbatchingUpdates = false;
19742
19743var completedBatches = null;
19744
19745var originalStartTimeMs = scheduler.unstable_now();
19746var currentRendererTime = msToExpirationTime(originalStartTimeMs);
19747var currentSchedulerTime = currentRendererTime;
19748
19749// Use these to prevent an infinite loop of nested updates
19750var NESTED_UPDATE_LIMIT = 50;
19751var nestedUpdateCount = 0;
19752var lastCommittedRootDuringThisBatch = null;
19753
19754function recomputeCurrentRendererTime() {
19755 var currentTimeMs = scheduler.unstable_now() - originalStartTimeMs;
19756 currentRendererTime = msToExpirationTime(currentTimeMs);
19757}
19758
19759function scheduleCallbackWithExpirationTime(root, expirationTime) {
19760 if (callbackExpirationTime !== NoWork) {
19761 // A callback is already scheduled. Check its expiration time (timeout).
19762 if (expirationTime < callbackExpirationTime) {
19763 // Existing callback has sufficient timeout. Exit.
19764 return;
19765 } else {
19766 if (callbackID !== null) {
19767 // Existing callback has insufficient timeout. Cancel and schedule a
19768 // new one.
19769 scheduler.unstable_cancelCallback(callbackID);
19770 }
19771 }
19772 // The request callback timer is already running. Don't start a new one.
19773 } else {
19774 startRequestCallbackTimer();
19775 }
19776
19777 callbackExpirationTime = expirationTime;
19778 var currentMs = scheduler.unstable_now() - originalStartTimeMs;
19779 var expirationTimeMs = expirationTimeToMs(expirationTime);
19780 var timeout = expirationTimeMs - currentMs;
19781 callbackID = scheduler.unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
19782}
19783
19784// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
19785// onYield is called upon exiting. We use these in lieu of returning a tuple.
19786// I've also chosen not to inline them into renderRoot because these will
19787// eventually be lifted into the renderer.
19788function onFatal(root) {
19789 root.finishedWork = null;
19790}
19791
19792function onComplete(root, finishedWork, expirationTime) {
19793 root.pendingCommitExpirationTime = expirationTime;
19794 root.finishedWork = finishedWork;
19795}
19796
19797function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
19798 root.expirationTime = rootExpirationTime;
19799 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
19800 // Don't wait an additional tick. Commit the tree immediately.
19801 root.pendingCommitExpirationTime = suspendedExpirationTime;
19802 root.finishedWork = finishedWork;
19803 } else if (msUntilTimeout > 0) {
19804 // Wait `msUntilTimeout` milliseconds before committing.
19805 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
19806 }
19807}
19808
19809function onYield(root) {
19810 root.finishedWork = null;
19811}
19812
19813function onTimeout(root, finishedWork, suspendedExpirationTime) {
19814 // The root timed out. Commit it.
19815 root.pendingCommitExpirationTime = suspendedExpirationTime;
19816 root.finishedWork = finishedWork;
19817 // Read the current time before entering the commit phase. We can be
19818 // certain this won't cause tearing related to batching of event updates
19819 // because we're at the top of a timer event.
19820 recomputeCurrentRendererTime();
19821 currentSchedulerTime = currentRendererTime;
19822 flushRoot(root, suspendedExpirationTime);
19823}
19824
19825function onCommit(root, expirationTime) {
19826 root.expirationTime = expirationTime;
19827 root.finishedWork = null;
19828}
19829
19830function requestCurrentTime() {
19831 // requestCurrentTime is called by the scheduler to compute an expiration
19832 // time.
19833 //
19834 // Expiration times are computed by adding to the current time (the start
19835 // time). However, if two updates are scheduled within the same event, we
19836 // should treat their start times as simultaneous, even if the actual clock
19837 // time has advanced between the first and second call.
19838
19839 // In other words, because expiration times determine how updates are batched,
19840 // we want all updates of like priority that occur within the same event to
19841 // receive the same expiration time. Otherwise we get tearing.
19842 //
19843 // We keep track of two separate times: the current "renderer" time and the
19844 // current "scheduler" time. The renderer time can be updated whenever; it
19845 // only exists to minimize the calls performance.now.
19846 //
19847 // But the scheduler time can only be updated if there's no pending work, or
19848 // if we know for certain that we're not in the middle of an event.
19849
19850 if (isRendering) {
19851 // We're already rendering. Return the most recently read time.
19852 return currentSchedulerTime;
19853 }
19854 // Check if there's pending work.
19855 findHighestPriorityRoot();
19856 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
19857 // If there's no pending work, or if the pending work is offscreen, we can
19858 // read the current time without risk of tearing.
19859 recomputeCurrentRendererTime();
19860 currentSchedulerTime = currentRendererTime;
19861 return currentSchedulerTime;
19862 }
19863 // There's already pending work. We might be in the middle of a browser
19864 // event. If we were to read the current time, it could cause multiple updates
19865 // within the same event to receive different expiration times, leading to
19866 // tearing. Return the last read time. During the next idle callback, the
19867 // time will be updated.
19868 return currentSchedulerTime;
19869}
19870
19871// requestWork is called by the scheduler whenever a root receives an update.
19872// It's up to the renderer to call renderRoot at some point in the future.
19873function requestWork(root, expirationTime) {
19874 addRootToSchedule(root, expirationTime);
19875 if (isRendering) {
19876 // Prevent reentrancy. Remaining work will be scheduled at the end of
19877 // the currently rendering batch.
19878 return;
19879 }
19880
19881 if (isBatchingUpdates) {
19882 // Flush work at the end of the batch.
19883 if (isUnbatchingUpdates) {
19884 // ...unless we're inside unbatchedUpdates, in which case we should
19885 // flush it now.
19886 nextFlushedRoot = root;
19887 nextFlushedExpirationTime = Sync;
19888 performWorkOnRoot(root, Sync, false);
19889 }
19890 return;
19891 }
19892
19893 // TODO: Get rid of Sync and use current time?
19894 if (expirationTime === Sync) {
19895 performSyncWork();
19896 } else {
19897 scheduleCallbackWithExpirationTime(root, expirationTime);
19898 }
19899}
19900
19901function addRootToSchedule(root, expirationTime) {
19902 // Add the root to the schedule.
19903 // Check if this root is already part of the schedule.
19904 if (root.nextScheduledRoot === null) {
19905 // This root is not already scheduled. Add it.
19906 root.expirationTime = expirationTime;
19907 if (lastScheduledRoot === null) {
19908 firstScheduledRoot = lastScheduledRoot = root;
19909 root.nextScheduledRoot = root;
19910 } else {
19911 lastScheduledRoot.nextScheduledRoot = root;
19912 lastScheduledRoot = root;
19913 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19914 }
19915 } else {
19916 // This root is already scheduled, but its priority may have increased.
19917 var remainingExpirationTime = root.expirationTime;
19918 if (expirationTime > remainingExpirationTime) {
19919 // Update the priority.
19920 root.expirationTime = expirationTime;
19921 }
19922 }
19923}
19924
19925function findHighestPriorityRoot() {
19926 var highestPriorityWork = NoWork;
19927 var highestPriorityRoot = null;
19928 if (lastScheduledRoot !== null) {
19929 var previousScheduledRoot = lastScheduledRoot;
19930 var root = firstScheduledRoot;
19931 while (root !== null) {
19932 var remainingExpirationTime = root.expirationTime;
19933 if (remainingExpirationTime === NoWork) {
19934 // This root no longer has work. Remove it from the scheduler.
19935
19936 // TODO: This check is redudant, but Flow is confused by the branch
19937 // below where we set lastScheduledRoot to null, even though we break
19938 // from the loop right after.
19939 !(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;
19940 if (root === root.nextScheduledRoot) {
19941 // This is the only root in the list.
19942 root.nextScheduledRoot = null;
19943 firstScheduledRoot = lastScheduledRoot = null;
19944 break;
19945 } else if (root === firstScheduledRoot) {
19946 // This is the first root in the list.
19947 var next = root.nextScheduledRoot;
19948 firstScheduledRoot = next;
19949 lastScheduledRoot.nextScheduledRoot = next;
19950 root.nextScheduledRoot = null;
19951 } else if (root === lastScheduledRoot) {
19952 // This is the last root in the list.
19953 lastScheduledRoot = previousScheduledRoot;
19954 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
19955 root.nextScheduledRoot = null;
19956 break;
19957 } else {
19958 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
19959 root.nextScheduledRoot = null;
19960 }
19961 root = previousScheduledRoot.nextScheduledRoot;
19962 } else {
19963 if (remainingExpirationTime > highestPriorityWork) {
19964 // Update the priority, if it's higher
19965 highestPriorityWork = remainingExpirationTime;
19966 highestPriorityRoot = root;
19967 }
19968 if (root === lastScheduledRoot) {
19969 break;
19970 }
19971 if (highestPriorityWork === Sync) {
19972 // Sync is highest priority by definition so
19973 // we can stop searching.
19974 break;
19975 }
19976 previousScheduledRoot = root;
19977 root = root.nextScheduledRoot;
19978 }
19979 }
19980 }
19981
19982 nextFlushedRoot = highestPriorityRoot;
19983 nextFlushedExpirationTime = highestPriorityWork;
19984}
19985
19986// TODO: This wrapper exists because many of the older tests (the ones that use
19987// flushDeferredPri) rely on the number of times `shouldYield` is called. We
19988// should get rid of it.
19989var didYield = false;
19990function shouldYieldToRenderer() {
19991 if (didYield) {
19992 return true;
19993 }
19994 if (scheduler.unstable_shouldYield()) {
19995 didYield = true;
19996 return true;
19997 }
19998 return false;
19999}
20000
20001function performAsyncWork() {
20002 try {
20003 if (!shouldYieldToRenderer()) {
20004 // The callback timed out. That means at least one update has expired.
20005 // Iterate through the root schedule. If they contain expired work, set
20006 // the next render expiration time to the current time. This has the effect
20007 // of flushing all expired work in a single batch, instead of flushing each
20008 // level one at a time.
20009 if (firstScheduledRoot !== null) {
20010 recomputeCurrentRendererTime();
20011 var root = firstScheduledRoot;
20012 do {
20013 didExpireAtExpirationTime(root, currentRendererTime);
20014 // The root schedule is circular, so this is never null.
20015 root = root.nextScheduledRoot;
20016 } while (root !== firstScheduledRoot);
20017 }
20018 }
20019 performWork(NoWork, true);
20020 } finally {
20021 didYield = false;
20022 }
20023}
20024
20025function performSyncWork() {
20026 performWork(Sync, false);
20027}
20028
20029function performWork(minExpirationTime, isYieldy) {
20030 // Keep working on roots until there's no more work, or until there's a higher
20031 // priority event.
20032 findHighestPriorityRoot();
20033
20034 if (isYieldy) {
20035 recomputeCurrentRendererTime();
20036 currentSchedulerTime = currentRendererTime;
20037
20038 if (enableUserTimingAPI) {
20039 var didExpire = nextFlushedExpirationTime > currentRendererTime;
20040 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
20041 stopRequestCallbackTimer(didExpire, timeout);
20042 }
20043
20044 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
20045 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
20046 findHighestPriorityRoot();
20047 recomputeCurrentRendererTime();
20048 currentSchedulerTime = currentRendererTime;
20049 }
20050 } else {
20051 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
20052 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
20053 findHighestPriorityRoot();
20054 }
20055 }
20056
20057 // We're done flushing work. Either we ran out of time in this callback,
20058 // or there's no more work left with sufficient priority.
20059
20060 // If we're inside a callback, set this to false since we just completed it.
20061 if (isYieldy) {
20062 callbackExpirationTime = NoWork;
20063 callbackID = null;
20064 }
20065 // If there's work left over, schedule a new callback.
20066 if (nextFlushedExpirationTime !== NoWork) {
20067 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
20068 }
20069
20070 // Clean-up.
20071 finishRendering();
20072}
20073
20074function flushRoot(root, expirationTime) {
20075 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
20076 // Perform work on root as if the given expiration time is the current time.
20077 // This has the effect of synchronously flushing all work up to and
20078 // including the given time.
20079 nextFlushedRoot = root;
20080 nextFlushedExpirationTime = expirationTime;
20081 performWorkOnRoot(root, expirationTime, false);
20082 // Flush any sync work that was scheduled by lifecycles
20083 performSyncWork();
20084}
20085
20086function finishRendering() {
20087 nestedUpdateCount = 0;
20088 lastCommittedRootDuringThisBatch = null;
20089
20090 if (completedBatches !== null) {
20091 var batches = completedBatches;
20092 completedBatches = null;
20093 for (var i = 0; i < batches.length; i++) {
20094 var batch = batches[i];
20095 try {
20096 batch._onComplete();
20097 } catch (error) {
20098 if (!hasUnhandledError) {
20099 hasUnhandledError = true;
20100 unhandledError = error;
20101 }
20102 }
20103 }
20104 }
20105
20106 if (hasUnhandledError) {
20107 var error = unhandledError;
20108 unhandledError = null;
20109 hasUnhandledError = false;
20110 throw error;
20111 }
20112}
20113
20114function performWorkOnRoot(root, expirationTime, isYieldy) {
20115 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
20116
20117 isRendering = true;
20118
20119 // Check if this is async work or sync/expired work.
20120 if (!isYieldy) {
20121 // Flush work without yielding.
20122 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
20123 // may want to perform some work without yielding, but also without
20124 // requiring the root to complete (by triggering placeholders).
20125
20126 var finishedWork = root.finishedWork;
20127 if (finishedWork !== null) {
20128 // This root is already complete. We can commit it.
20129 completeRoot(root, finishedWork, expirationTime);
20130 } else {
20131 root.finishedWork = null;
20132 // If this root previously suspended, clear its existing timeout, since
20133 // we're about to try rendering again.
20134 var timeoutHandle = root.timeoutHandle;
20135 if (timeoutHandle !== noTimeout) {
20136 root.timeoutHandle = noTimeout;
20137 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
20138 cancelTimeout(timeoutHandle);
20139 }
20140 renderRoot(root, isYieldy);
20141 finishedWork = root.finishedWork;
20142 if (finishedWork !== null) {
20143 // We've completed the root. Commit it.
20144 completeRoot(root, finishedWork, expirationTime);
20145 }
20146 }
20147 } else {
20148 // Flush async work.
20149 var _finishedWork = root.finishedWork;
20150 if (_finishedWork !== null) {
20151 // This root is already complete. We can commit it.
20152 completeRoot(root, _finishedWork, expirationTime);
20153 } else {
20154 root.finishedWork = null;
20155 // If this root previously suspended, clear its existing timeout, since
20156 // we're about to try rendering again.
20157 var _timeoutHandle = root.timeoutHandle;
20158 if (_timeoutHandle !== noTimeout) {
20159 root.timeoutHandle = noTimeout;
20160 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
20161 cancelTimeout(_timeoutHandle);
20162 }
20163 renderRoot(root, isYieldy);
20164 _finishedWork = root.finishedWork;
20165 if (_finishedWork !== null) {
20166 // We've completed the root. Check the if we should yield one more time
20167 // before committing.
20168 if (!shouldYieldToRenderer()) {
20169 // Still time left. Commit the root.
20170 completeRoot(root, _finishedWork, expirationTime);
20171 } else {
20172 // There's no time left. Mark this root as complete. We'll come
20173 // back and commit it later.
20174 root.finishedWork = _finishedWork;
20175 }
20176 }
20177 }
20178 }
20179
20180 isRendering = false;
20181}
20182
20183function completeRoot(root, finishedWork, expirationTime) {
20184 // Check if there's a batch that matches this expiration time.
20185 var firstBatch = root.firstBatch;
20186 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
20187 if (completedBatches === null) {
20188 completedBatches = [firstBatch];
20189 } else {
20190 completedBatches.push(firstBatch);
20191 }
20192 if (firstBatch._defer) {
20193 // This root is blocked from committing by a batch. Unschedule it until
20194 // we receive another update.
20195 root.finishedWork = finishedWork;
20196 root.expirationTime = NoWork;
20197 return;
20198 }
20199 }
20200
20201 // Commit the root.
20202 root.finishedWork = null;
20203
20204 // Check if this is a nested update (a sync update scheduled during the
20205 // commit phase).
20206 if (root === lastCommittedRootDuringThisBatch) {
20207 // If the next root is the same as the previous root, this is a nested
20208 // update. To prevent an infinite loop, increment the nested update count.
20209 nestedUpdateCount++;
20210 } else {
20211 // Reset whenever we switch roots.
20212 lastCommittedRootDuringThisBatch = root;
20213 nestedUpdateCount = 0;
20214 }
20215 scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
20216 commitRoot(root, finishedWork);
20217 });
20218}
20219
20220function onUncaughtError(error) {
20221 !(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;
20222 // Unschedule this root so we don't work on it again until there's
20223 // another update.
20224 nextFlushedRoot.expirationTime = NoWork;
20225 if (!hasUnhandledError) {
20226 hasUnhandledError = true;
20227 unhandledError = error;
20228 }
20229}
20230
20231// TODO: Batching should be implemented at the renderer level, not inside
20232// the reconciler.
20233function batchedUpdates$1(fn, a) {
20234 var previousIsBatchingUpdates = isBatchingUpdates;
20235 isBatchingUpdates = true;
20236 try {
20237 return fn(a);
20238 } finally {
20239 isBatchingUpdates = previousIsBatchingUpdates;
20240 if (!isBatchingUpdates && !isRendering) {
20241 performSyncWork();
20242 }
20243 }
20244}
20245
20246// TODO: Batching should be implemented at the renderer level, not inside
20247// the reconciler.
20248function unbatchedUpdates(fn, a) {
20249 if (isBatchingUpdates && !isUnbatchingUpdates) {
20250 isUnbatchingUpdates = true;
20251 try {
20252 return fn(a);
20253 } finally {
20254 isUnbatchingUpdates = false;
20255 }
20256 }
20257 return fn(a);
20258}
20259
20260// TODO: Batching should be implemented at the renderer level, not within
20261// the reconciler.
20262function flushSync(fn, a) {
20263 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0;
20264 var previousIsBatchingUpdates = isBatchingUpdates;
20265 isBatchingUpdates = true;
20266 try {
20267 return syncUpdates(fn, a);
20268 } finally {
20269 isBatchingUpdates = previousIsBatchingUpdates;
20270 performSyncWork();
20271 }
20272}
20273
20274function interactiveUpdates$1(fn, a, b) {
20275 // If there are any pending interactive updates, synchronously flush them.
20276 // This needs to happen before we read any handlers, because the effect of
20277 // the previous event may influence which handlers are called during
20278 // this event.
20279 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20280 // Synchronously flush pending interactive updates.
20281 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20282 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20283 }
20284 var previousIsBatchingUpdates = isBatchingUpdates;
20285 isBatchingUpdates = true;
20286 try {
20287 return scheduler.unstable_runWithPriority(scheduler.unstable_UserBlockingPriority, function () {
20288 return fn(a, b);
20289 });
20290 } finally {
20291 isBatchingUpdates = previousIsBatchingUpdates;
20292 if (!isBatchingUpdates && !isRendering) {
20293 performSyncWork();
20294 }
20295 }
20296}
20297
20298function flushInteractiveUpdates$1() {
20299 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
20300 // Synchronously flush pending interactive updates.
20301 performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20302 lowestPriorityPendingInteractiveExpirationTime = NoWork;
20303 }
20304}
20305
20306function flushControlled(fn) {
20307 var previousIsBatchingUpdates = isBatchingUpdates;
20308 isBatchingUpdates = true;
20309 try {
20310 syncUpdates(fn);
20311 } finally {
20312 isBatchingUpdates = previousIsBatchingUpdates;
20313 if (!isBatchingUpdates && !isRendering) {
20314 performSyncWork();
20315 }
20316 }
20317}
20318
20319// 0 is PROD, 1 is DEV.
20320// Might add PROFILE later.
20321
20322
20323var didWarnAboutNestedUpdates = void 0;
20324var didWarnAboutFindNodeInStrictMode = void 0;
20325
20326{
20327 didWarnAboutNestedUpdates = false;
20328 didWarnAboutFindNodeInStrictMode = {};
20329}
20330
20331function getContextForSubtree(parentComponent) {
20332 if (!parentComponent) {
20333 return emptyContextObject;
20334 }
20335
20336 var fiber = get(parentComponent);
20337 var parentContext = findCurrentUnmaskedContext(fiber);
20338
20339 if (fiber.tag === ClassComponent) {
20340 var Component = fiber.type;
20341 if (isContextProvider(Component)) {
20342 return processChildContext(fiber, Component, parentContext);
20343 }
20344 }
20345
20346 return parentContext;
20347}
20348
20349function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
20350 {
20351 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
20352 didWarnAboutNestedUpdates = true;
20353 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');
20354 }
20355 }
20356
20357 var update = createUpdate(expirationTime);
20358 // Caution: React DevTools currently depends on this property
20359 // being called "element".
20360 update.payload = { element: element };
20361
20362 callback = callback === undefined ? null : callback;
20363 if (callback !== null) {
20364 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
20365 update.callback = callback;
20366 }
20367
20368 flushPassiveEffects();
20369 enqueueUpdate(current$$1, update);
20370 scheduleWork(current$$1, expirationTime);
20371
20372 return expirationTime;
20373}
20374
20375function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
20376 // TODO: If this is a nested container, this won't be the root.
20377 var current$$1 = container.current;
20378
20379 {
20380 if (ReactFiberInstrumentation_1.debugTool) {
20381 if (current$$1.alternate === null) {
20382 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
20383 } else if (element === null) {
20384 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
20385 } else {
20386 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
20387 }
20388 }
20389 }
20390
20391 var context = getContextForSubtree(parentComponent);
20392 if (container.context === null) {
20393 container.context = context;
20394 } else {
20395 container.pendingContext = context;
20396 }
20397
20398 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
20399}
20400
20401function findHostInstance(component) {
20402 var fiber = get(component);
20403 if (fiber === undefined) {
20404 if (typeof component.render === 'function') {
20405 invariant(false, 'Unable to find node on an unmounted component.');
20406 } else {
20407 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20408 }
20409 }
20410 var hostFiber = findCurrentHostFiber(fiber);
20411 if (hostFiber === null) {
20412 return null;
20413 }
20414 return hostFiber.stateNode;
20415}
20416
20417function findHostInstanceWithWarning(component, methodName) {
20418 {
20419 var fiber = get(component);
20420 if (fiber === undefined) {
20421 if (typeof component.render === 'function') {
20422 invariant(false, 'Unable to find node on an unmounted component.');
20423 } else {
20424 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component));
20425 }
20426 }
20427 var hostFiber = findCurrentHostFiber(fiber);
20428 if (hostFiber === null) {
20429 return null;
20430 }
20431 if (hostFiber.mode & StrictMode) {
20432 var componentName = getComponentName(fiber.type) || 'Component';
20433 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
20434 didWarnAboutFindNodeInStrictMode[componentName] = true;
20435 if (fiber.mode & StrictMode) {
20436 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));
20437 } else {
20438 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));
20439 }
20440 }
20441 }
20442 return hostFiber.stateNode;
20443 }
20444 return findHostInstance(component);
20445}
20446
20447function createContainer(containerInfo, isConcurrent, hydrate) {
20448 return createFiberRoot(containerInfo, isConcurrent, hydrate);
20449}
20450
20451function updateContainer(element, container, parentComponent, callback) {
20452 var current$$1 = container.current;
20453 var currentTime = requestCurrentTime();
20454 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
20455 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
20456}
20457
20458function getPublicRootInstance(container) {
20459 var containerFiber = container.current;
20460 if (!containerFiber.child) {
20461 return null;
20462 }
20463 switch (containerFiber.child.tag) {
20464 case HostComponent:
20465 return getPublicInstance(containerFiber.child.stateNode);
20466 default:
20467 return containerFiber.child.stateNode;
20468 }
20469}
20470
20471function findHostInstanceWithNoPortals(fiber) {
20472 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
20473 if (hostFiber === null) {
20474 return null;
20475 }
20476 return hostFiber.stateNode;
20477}
20478
20479var overrideProps = null;
20480
20481{
20482 var copyWithSetImpl = function (obj, path, idx, value) {
20483 if (idx >= path.length) {
20484 return value;
20485 }
20486 var key = path[idx];
20487 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
20488 // $FlowFixMe number or string is fine here
20489 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
20490 return updated;
20491 };
20492
20493 var copyWithSet = function (obj, path, value) {
20494 return copyWithSetImpl(obj, path, 0, value);
20495 };
20496
20497 // Support DevTools props for function components, forwardRef, memo, host components, etc.
20498 overrideProps = function (fiber, path, value) {
20499 flushPassiveEffects();
20500 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
20501 if (fiber.alternate) {
20502 fiber.alternate.pendingProps = fiber.pendingProps;
20503 }
20504 scheduleWork(fiber, Sync);
20505 };
20506}
20507
20508function injectIntoDevTools(devToolsConfig) {
20509 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
20510 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
20511
20512
20513 return injectInternals(_assign({}, devToolsConfig, {
20514 overrideProps: overrideProps,
20515 currentDispatcherRef: ReactCurrentDispatcher,
20516 findHostInstanceByFiber: function (fiber) {
20517 var hostFiber = findCurrentHostFiber(fiber);
20518 if (hostFiber === null) {
20519 return null;
20520 }
20521 return hostFiber.stateNode;
20522 },
20523 findFiberByHostInstance: function (instance) {
20524 if (!findFiberByHostInstance) {
20525 // Might not be implemented by the renderer.
20526 return null;
20527 }
20528 return findFiberByHostInstance(instance);
20529 }
20530 }));
20531}
20532
20533// This file intentionally does *not* have the Flow annotation.
20534// Don't add it. See `./inline-typed.js` for an explanation.
20535
20536function createPortal$1(children, containerInfo,
20537// TODO: figure out the API for cross-renderer implementation.
20538implementation) {
20539 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
20540
20541 return {
20542 // This tag allow us to uniquely identify this as a React Portal
20543 $$typeof: REACT_PORTAL_TYPE,
20544 key: key == null ? null : '' + key,
20545 children: children,
20546 containerInfo: containerInfo,
20547 implementation: implementation
20548 };
20549}
20550
20551// TODO: this is special because it gets imported during build.
20552
20553var ReactVersion = '16.8.2';
20554
20555// This file is copy paste from ReactDOM with adjusted paths
20556// and a different host config import (react-reconciler/inline.fire).
20557// TODO: real implementation.
20558// console.log('Hello from Fire entry point.');
20559
20560// TODO: This type is shared between the reconciler and ReactDOM, but will
20561// eventually be lifted out to the renderer.
20562
20563var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
20564
20565var topLevelUpdateWarnings = void 0;
20566var warnOnInvalidCallback = void 0;
20567var didWarnAboutUnstableCreatePortal = false;
20568
20569{
20570 if (typeof Map !== 'function' ||
20571 // $FlowIssue Flow incorrectly thinks Map has no prototype
20572 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' ||
20573 // $FlowIssue Flow incorrectly thinks Set has no prototype
20574 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
20575 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');
20576 }
20577
20578 topLevelUpdateWarnings = function (container) {
20579 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
20580 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
20581 if (hostInstance) {
20582 !(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;
20583 }
20584 }
20585
20586 var isRootRenderedBySomeReact = !!container._reactRootContainer;
20587 var rootEl = getReactRootElementInContainer(container);
20588 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
20589
20590 !(!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;
20591
20592 !(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;
20593 };
20594
20595 warnOnInvalidCallback = function (callback, callerName) {
20596 !(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;
20597 };
20598}
20599
20600setRestoreImplementation(restoreControlledState$1);
20601
20602function ReactBatch(root) {
20603 var expirationTime = computeUniqueAsyncExpiration();
20604 this._expirationTime = expirationTime;
20605 this._root = root;
20606 this._next = null;
20607 this._callbacks = null;
20608 this._didComplete = false;
20609 this._hasChildren = false;
20610 this._children = null;
20611 this._defer = true;
20612}
20613ReactBatch.prototype.render = function (children) {
20614 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0;
20615 this._hasChildren = true;
20616 this._children = children;
20617 var internalRoot = this._root._internalRoot;
20618 var expirationTime = this._expirationTime;
20619 var work = new ReactWork();
20620 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit);
20621 return work;
20622};
20623ReactBatch.prototype.then = function (onComplete) {
20624 if (this._didComplete) {
20625 onComplete();
20626 return;
20627 }
20628 var callbacks = this._callbacks;
20629 if (callbacks === null) {
20630 callbacks = this._callbacks = [];
20631 }
20632 callbacks.push(onComplete);
20633};
20634ReactBatch.prototype.commit = function () {
20635 var internalRoot = this._root._internalRoot;
20636 var firstBatch = internalRoot.firstBatch;
20637 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20638
20639 if (!this._hasChildren) {
20640 // This batch is empty. Return.
20641 this._next = null;
20642 this._defer = false;
20643 return;
20644 }
20645
20646 var expirationTime = this._expirationTime;
20647
20648 // Ensure this is the first batch in the list.
20649 if (firstBatch !== this) {
20650 // This batch is not the earliest batch. We need to move it to the front.
20651 // Update its expiration time to be the expiration time of the earliest
20652 // batch, so that we can flush it without flushing the other batches.
20653 if (this._hasChildren) {
20654 expirationTime = this._expirationTime = firstBatch._expirationTime;
20655 // Rendering this batch again ensures its children will be the final state
20656 // when we flush (updates are processed in insertion order: last
20657 // update wins).
20658 // TODO: This forces a restart. Should we print a warning?
20659 this.render(this._children);
20660 }
20661
20662 // Remove the batch from the list.
20663 var previous = null;
20664 var batch = firstBatch;
20665 while (batch !== this) {
20666 previous = batch;
20667 batch = batch._next;
20668 }
20669 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0;
20670 previous._next = batch._next;
20671
20672 // Add it to the front.
20673 this._next = firstBatch;
20674 firstBatch = internalRoot.firstBatch = this;
20675 }
20676
20677 // Synchronously flush all the work up to this batch's expiration time.
20678 this._defer = false;
20679 flushRoot(internalRoot, expirationTime);
20680
20681 // Pop the batch from the list.
20682 var next = this._next;
20683 this._next = null;
20684 firstBatch = internalRoot.firstBatch = next;
20685
20686 // Append the next earliest batch's children to the update queue.
20687 if (firstBatch !== null && firstBatch._hasChildren) {
20688 firstBatch.render(firstBatch._children);
20689 }
20690};
20691ReactBatch.prototype._onComplete = function () {
20692 if (this._didComplete) {
20693 return;
20694 }
20695 this._didComplete = true;
20696 var callbacks = this._callbacks;
20697 if (callbacks === null) {
20698 return;
20699 }
20700 // TODO: Error handling.
20701 for (var i = 0; i < callbacks.length; i++) {
20702 var _callback = callbacks[i];
20703 _callback();
20704 }
20705};
20706
20707function ReactWork() {
20708 this._callbacks = null;
20709 this._didCommit = false;
20710 // TODO: Avoid need to bind by replacing callbacks in the update queue with
20711 // list of Work objects.
20712 this._onCommit = this._onCommit.bind(this);
20713}
20714ReactWork.prototype.then = function (onCommit) {
20715 if (this._didCommit) {
20716 onCommit();
20717 return;
20718 }
20719 var callbacks = this._callbacks;
20720 if (callbacks === null) {
20721 callbacks = this._callbacks = [];
20722 }
20723 callbacks.push(onCommit);
20724};
20725ReactWork.prototype._onCommit = function () {
20726 if (this._didCommit) {
20727 return;
20728 }
20729 this._didCommit = true;
20730 var callbacks = this._callbacks;
20731 if (callbacks === null) {
20732 return;
20733 }
20734 // TODO: Error handling.
20735 for (var i = 0; i < callbacks.length; i++) {
20736 var _callback2 = callbacks[i];
20737 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0;
20738 _callback2();
20739 }
20740};
20741
20742function ReactRoot(container, isConcurrent, hydrate) {
20743 var root = createContainer(container, isConcurrent, hydrate);
20744 this._internalRoot = root;
20745}
20746ReactRoot.prototype.render = function (children, callback) {
20747 var root = this._internalRoot;
20748 var work = new ReactWork();
20749 callback = callback === undefined ? null : callback;
20750 {
20751 warnOnInvalidCallback(callback, 'render');
20752 }
20753 if (callback !== null) {
20754 work.then(callback);
20755 }
20756 updateContainer(children, root, null, work._onCommit);
20757 return work;
20758};
20759ReactRoot.prototype.unmount = function (callback) {
20760 var root = this._internalRoot;
20761 var work = new ReactWork();
20762 callback = callback === undefined ? null : callback;
20763 {
20764 warnOnInvalidCallback(callback, 'render');
20765 }
20766 if (callback !== null) {
20767 work.then(callback);
20768 }
20769 updateContainer(null, root, null, work._onCommit);
20770 return work;
20771};
20772ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) {
20773 var root = this._internalRoot;
20774 var work = new ReactWork();
20775 callback = callback === undefined ? null : callback;
20776 {
20777 warnOnInvalidCallback(callback, 'render');
20778 }
20779 if (callback !== null) {
20780 work.then(callback);
20781 }
20782 updateContainer(children, root, parentComponent, work._onCommit);
20783 return work;
20784};
20785ReactRoot.prototype.createBatch = function () {
20786 var batch = new ReactBatch(this);
20787 var expirationTime = batch._expirationTime;
20788
20789 var internalRoot = this._internalRoot;
20790 var firstBatch = internalRoot.firstBatch;
20791 if (firstBatch === null) {
20792 internalRoot.firstBatch = batch;
20793 batch._next = null;
20794 } else {
20795 // Insert sorted by expiration time then insertion order
20796 var insertAfter = null;
20797 var insertBefore = firstBatch;
20798 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) {
20799 insertAfter = insertBefore;
20800 insertBefore = insertBefore._next;
20801 }
20802 batch._next = insertBefore;
20803 if (insertAfter !== null) {
20804 insertAfter._next = batch;
20805 }
20806 }
20807
20808 return batch;
20809};
20810
20811/**
20812 * True if the supplied DOM node is a valid node element.
20813 *
20814 * @param {?DOMElement} node The candidate DOM node.
20815 * @return {boolean} True if the DOM is a valid DOM node.
20816 * @internal
20817 */
20818function isValidContainer(node) {
20819 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 '));
20820}
20821
20822function getReactRootElementInContainer(container) {
20823 if (!container) {
20824 return null;
20825 }
20826
20827 if (container.nodeType === DOCUMENT_NODE) {
20828 return container.documentElement;
20829 } else {
20830 return container.firstChild;
20831 }
20832}
20833
20834function shouldHydrateDueToLegacyHeuristic(container) {
20835 var rootElement = getReactRootElementInContainer(container);
20836 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
20837}
20838
20839setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1);
20840
20841var warnedAboutHydrateAPI = false;
20842
20843function legacyCreateRootFromDOMContainer(container, forceHydrate) {
20844 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container);
20845 // First clear any existing content.
20846 if (!shouldHydrate) {
20847 var warned = false;
20848 var rootSibling = void 0;
20849 while (rootSibling = container.lastChild) {
20850 {
20851 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
20852 warned = true;
20853 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.');
20854 }
20855 }
20856 container.removeChild(rootSibling);
20857 }
20858 }
20859 {
20860 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
20861 warnedAboutHydrateAPI = true;
20862 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.');
20863 }
20864 }
20865 // Legacy roots are not async by default.
20866 var isConcurrent = false;
20867 return new ReactRoot(container, isConcurrent, shouldHydrate);
20868}
20869
20870function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
20871 {
20872 topLevelUpdateWarnings(container);
20873 }
20874
20875 // TODO: Without `any` type, Flow says "Property cannot be accessed on any
20876 // member of intersection type." Whyyyyyy.
20877 var root = container._reactRootContainer;
20878 if (!root) {
20879 // Initial mount
20880 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
20881 if (typeof callback === 'function') {
20882 var originalCallback = callback;
20883 callback = function () {
20884 var instance = getPublicRootInstance(root._internalRoot);
20885 originalCallback.call(instance);
20886 };
20887 }
20888 // Initial mount should not be batched.
20889 unbatchedUpdates(function () {
20890 if (parentComponent != null) {
20891 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20892 } else {
20893 root.render(children, callback);
20894 }
20895 });
20896 } else {
20897 if (typeof callback === 'function') {
20898 var _originalCallback = callback;
20899 callback = function () {
20900 var instance = getPublicRootInstance(root._internalRoot);
20901 _originalCallback.call(instance);
20902 };
20903 }
20904 // Update
20905 if (parentComponent != null) {
20906 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
20907 } else {
20908 root.render(children, callback);
20909 }
20910 }
20911 return getPublicRootInstance(root._internalRoot);
20912}
20913
20914function createPortal$$1(children, container) {
20915 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
20916
20917 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20918 // TODO: pass ReactDOM portal implementation as third argument
20919 return createPortal$1(children, container, null, key);
20920}
20921
20922var ReactDOM = {
20923 createPortal: createPortal$$1,
20924
20925 findDOMNode: function (componentOrElement) {
20926 {
20927 var owner = ReactCurrentOwner.current;
20928 if (owner !== null && owner.stateNode !== null) {
20929 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
20930 !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;
20931 owner.stateNode._warnedAboutRefsInRender = true;
20932 }
20933 }
20934 if (componentOrElement == null) {
20935 return null;
20936 }
20937 if (componentOrElement.nodeType === ELEMENT_NODE) {
20938 return componentOrElement;
20939 }
20940 {
20941 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
20942 }
20943 return findHostInstance(componentOrElement);
20944 },
20945 hydrate: function (element, container, callback) {
20946 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20947 {
20948 !!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;
20949 }
20950 // TODO: throw or warn if we couldn't hydrate?
20951 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
20952 },
20953 render: function (element, container, callback) {
20954 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20955 {
20956 !!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;
20957 }
20958 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
20959 },
20960 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
20961 !isValidContainer(containerNode) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20962 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0;
20963 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
20964 },
20965 unmountComponentAtNode: function (container) {
20966 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0;
20967
20968 {
20969 !!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;
20970 }
20971
20972 if (container._reactRootContainer) {
20973 {
20974 var rootEl = getReactRootElementInContainer(container);
20975 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
20976 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
20977 }
20978
20979 // Unmount should not be batched.
20980 unbatchedUpdates(function () {
20981 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
20982 container._reactRootContainer = null;
20983 });
20984 });
20985 // If you call unmountComponentAtNode twice in quick succession, you'll
20986 // get `true` twice. That's probably fine?
20987 return true;
20988 } else {
20989 {
20990 var _rootEl = getReactRootElementInContainer(container);
20991 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl));
20992
20993 // Check if the container itself is a React root node.
20994 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
20995
20996 !!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;
20997 }
20998
20999 return false;
21000 }
21001 },
21002
21003
21004 // Temporary alias since we already shipped React 16 RC with it.
21005 // TODO: remove in React 17.
21006 unstable_createPortal: function () {
21007 if (!didWarnAboutUnstableCreatePortal) {
21008 didWarnAboutUnstableCreatePortal = true;
21009 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.');
21010 }
21011 return createPortal$$1.apply(undefined, arguments);
21012 },
21013
21014
21015 unstable_batchedUpdates: batchedUpdates$1,
21016
21017 unstable_interactiveUpdates: interactiveUpdates$1,
21018
21019 flushSync: flushSync,
21020
21021 unstable_createRoot: createRoot,
21022 unstable_flushControlled: flushControlled,
21023
21024 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
21025 // Keep in sync with ReactDOMUnstableNativeDependencies.js
21026 // and ReactTestUtils.js. This is an array for better minification.
21027 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch]
21028 }
21029};
21030
21031function createRoot(container, options) {
21032 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot';
21033 !isValidContainer(container) ? invariant(false, '%s(...): Target container is not a DOM element.', functionName) : void 0;
21034 {
21035 !!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;
21036 container._reactHasBeenPassedToCreateRootDEV = true;
21037 }
21038 var hydrate = options != null && options.hydrate === true;
21039 return new ReactRoot(container, true, hydrate);
21040}
21041
21042if (enableStableConcurrentModeAPIs) {
21043 ReactDOM.createRoot = createRoot;
21044 ReactDOM.unstable_createRoot = undefined;
21045}
21046
21047var foundDevTools = injectIntoDevTools({
21048 findFiberByHostInstance: getClosestInstanceFromNode,
21049 bundleType: 1,
21050 version: ReactVersion,
21051 rendererPackageName: 'react-dom'
21052});
21053
21054{
21055 if (!foundDevTools && canUseDOM && window.top === window.self) {
21056 // If we're in Chrome or Firefox, provide a download link if not installed.
21057 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
21058 var protocol = window.location.protocol;
21059 // Don't warn in exotic cases like chrome-extension://.
21060 if (/^(https?|file):$/.test(protocol)) {
21061 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');
21062 }
21063 }
21064 }
21065}
21066
21067
21068
21069var ReactFire = Object.freeze({
21070 default: ReactDOM
21071});
21072
21073var ReactFire$1 = ( ReactFire && ReactDOM ) || ReactFire;
21074
21075// TODO: decide on the top-level export form.
21076// This is hacky but makes it work with both Rollup and Jest.
21077var unstableFire = ReactFire$1.default || ReactFire$1;
21078
21079module.exports = unstableFire;
21080 })();
21081}